@absolutejs/absolute 0.20.0-beta.181 → 0.20.0-beta.183

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. package/CHANGELOG.md +46 -0
  2. package/changelog.json +75 -0
  3. package/dist/angular/browser.js +2 -2
  4. package/dist/angular/browser.js.map +4 -4
  5. package/dist/angular/components/constants.js +4 -0
  6. package/dist/angular/components/core/streamingSlotRegistrar.js +1 -1
  7. package/dist/angular/components/core/streamingSlotRegistry.js +2 -2
  8. package/dist/angular/index.js +520 -84
  9. package/dist/angular/index.js.map +13 -12
  10. package/dist/angular/server.js +520 -84
  11. package/dist/angular/server.js.map +13 -12
  12. package/dist/build.js +452 -85
  13. package/dist/build.js.map +18 -18
  14. package/dist/cli/{add-8gw9mk2b.js → add-jft96bp4.js} +9 -9
  15. package/dist/cli/{analyze-e57zz9x8.js → analyze-5w46d1f0.js} +3 -3
  16. package/dist/cli/{androidEmulatorController-vqc5m2rp.js → androidEmulatorController-gbf9r660.js} +6 -6
  17. package/dist/cli/{androidNativeWatcher-s03aczxv.js → androidNativeWatcher-3astrxxz.js} +6 -6
  18. package/dist/cli/{api-8ppxw487.js → api-zmvnvdsf.js} +8 -8
  19. package/dist/cli/{build-ptx5a72p.js → build-df81wh71.js} +67 -6
  20. package/dist/cli/{build-fz7qbdn3.js → build-mskrk9zb.js} +3 -3
  21. package/dist/cli/{buildDepVendor-qnwfct22.js → buildDepVendor-36d1aa7c.js} +2 -2
  22. package/dist/cli/{buildReactServerComponents-01s87hnk.js → buildReactServerComponents-k6amghrj.js} +5 -5
  23. package/dist/cli/{compile-54rb8szn.js → compile-7mjd739p.js} +10 -6
  24. package/dist/cli/config/server.js +37 -18
  25. package/dist/cli/{db-qbzjw3en.js → db-mpmj37jq.js} +2 -2
  26. package/dist/cli/{dev-6s6g5tnk.js → dev-9d6d7757.js} +14 -14
  27. package/dist/cli/{doctor-m36tmx4d.js → doctor-nng9szw6.js} +3 -3
  28. package/dist/cli/{emulatorDoctor-s1z5tkp7.js → emulatorDoctor-3eszsqs8.js} +5 -5
  29. package/dist/cli/{emulatorInstaller-pgkdswvq.js → emulatorInstaller-1r6cawm0.js} +6 -6
  30. package/dist/cli/{env-5nz1qm8e.js → env-bfa7vs35.js} +3 -3
  31. package/dist/cli/{expoDevController-018anvbm.js → expoDevController-s0msdwbm.js} +6 -6
  32. package/dist/cli/{generate-5vyz1s44.js → generate-xk3a7qnc.js} +8 -8
  33. package/dist/cli/{heapDiff-kncvdtn8.js → heapDiff-3ba8p8wf.js} +3 -3
  34. package/dist/cli/{htmx-26hs6jdm.js → htmx-an2x3gpx.js} +6 -6
  35. package/dist/cli/{index-7854xf0m.js → index-1bszxtdj.js} +1 -1
  36. package/dist/cli/{index-kx2d067c.js → index-3066eqr3.js} +8 -5
  37. package/dist/cli/{index-8khbn8qr.js → index-3a9h87v5.js} +3 -3
  38. package/dist/cli/{index-jkg2h10c.js → index-3dz754hk.js} +3 -3
  39. package/dist/cli/{index-9djrap79.js → index-3pz5sjaz.js} +1 -1
  40. package/dist/cli/{index-50ag35xg.js → index-3ys9tz53.js} +2 -2
  41. package/dist/cli/{index-6f448d7m.js → index-4ynx0cq6.js} +26 -12
  42. package/dist/cli/{index-btp4fyf1.js → index-785hpa2r.js} +2 -2
  43. package/dist/cli/{index-kes8he5s.js → index-9sqqzeq4.js} +1 -1
  44. package/dist/cli/{index-pr1skxen.js → index-akseq9ps.js} +1 -1
  45. package/dist/cli/{index-23hvdyxf.js → index-c6j2727a.js} +1 -1
  46. package/dist/cli/{index-pkw3jktb.js → index-eh786rj4.js} +2 -2
  47. package/dist/cli/{index-aemhvvwb.js → index-eydgkr7w.js} +1 -1
  48. package/dist/cli/{index-rz56x932.js → index-fbmfpqk8.js} +1 -1
  49. package/dist/cli/{index-c8rcfe5a.js → index-fy4th3n0.js} +1 -1
  50. package/dist/cli/{index-prza6tkp.js → index-gx6pjzzk.js} +3 -3
  51. package/dist/cli/{index-125cfzvn.js → index-hker5fs4.js} +2 -2
  52. package/dist/cli/{index-cgmp9d02.js → index-hqkcxa2p.js} +1 -1
  53. package/dist/cli/{index-5w8arh3m.js → index-pq4qqz0r.js} +2 -2
  54. package/dist/cli/{index-enbw9484.js → index-wpgsermq.js} +1 -1
  55. package/dist/cli/{index-0z5fgb80.js → index-wqpg377f.js} +1 -1
  56. package/dist/cli/{index-3sfcmb49.js → index-x7h6w6td.js} +1 -1
  57. package/dist/cli/{index-a6xx0p9e.js → index-ydaxsftq.js} +1 -1
  58. package/dist/cli/{index-3ewt17wm.js → index-yhkg5by0.js} +1 -1
  59. package/dist/cli/{index-aqe25w4h.js → index-zeeep92g.js} +1 -1
  60. package/dist/cli/index.js +32 -32
  61. package/dist/cli/{info-k124sh7g.js → info-5rwsbhe2.js} +4 -4
  62. package/dist/cli/{inspect-n6pcfvfw.js → inspect-nmwb0q5k.js} +5 -5
  63. package/dist/cli/{iosNativeWatcher-wdq2fvj1.js → iosNativeWatcher-7r9gnk87.js} +7 -7
  64. package/dist/cli/{iosSimulatorController-n97dpa8p.js → iosSimulatorController-w963vv9r.js} +7 -7
  65. package/dist/cli/{islands-17tfx8jf.js → islands-w9xrehpk.js} +3 -3
  66. package/dist/cli/{logs-shg23fbt.js → logs-m793x8a7.js} +3 -3
  67. package/dist/cli/{ls-0wr74w0b.js → ls-k31npd5b.js} +3 -3
  68. package/dist/cli/{mem-16sy1707.js → mem-jm6kw6gr.js} +5 -5
  69. package/dist/cli/{migrate-k91k050s.js → migrate-95bjkqkr.js} +2 -2
  70. package/dist/cli/{mobile-hpqpy61f.js → mobile-cpp8vfn7.js} +13 -13
  71. package/dist/cli/prerender-26pzynh4.js +13 -0
  72. package/dist/cli/{prettier-dh5fh786.js → prettier-0ws9pbc1.js} +1 -1
  73. package/dist/cli/{ps-pk7ncjac.js → ps-fx8mz3e3.js} +6 -6
  74. package/dist/cli/{psTui-50wf0b72.js → psTui-0e9c7an6.js} +7 -7
  75. package/dist/cli/{remoteMacProtocol-g10s408w.js → remoteMacProtocol-y7h79gr8.js} +7 -7
  76. package/dist/cli/{remove-x987pvd3.js → remove-xhvph8bz.js} +8 -8
  77. package/dist/cli/{routes-mc3ymp8t.js → routes-hq9yje5z.js} +3 -3
  78. package/dist/cli/{start-mbn2zgs2.js → start-5mjh9hh2.js} +5 -5
  79. package/dist/cli/{typecheck-ynzw2eep.js → typecheck-bvm0ndq4.js} +188 -75
  80. package/dist/cli/{workspace-7sbyyc59.js → workspace-xeb6abxj.js} +5 -5
  81. package/dist/dev/serverBootstrap.js +8 -2
  82. package/dist/index.js +469 -99
  83. package/dist/index.js.map +20 -20
  84. package/dist/islands/index.js +312 -23
  85. package/dist/islands/index.js.map +5 -5
  86. package/dist/mobile/index.js +2 -2
  87. package/dist/mobile/index.js.map +3 -3
  88. package/dist/react/browser.js +18 -1
  89. package/dist/react/browser.js.map +6 -4
  90. package/dist/react/components/index.js +2 -2
  91. package/dist/react/components/index.js.map +3 -3
  92. package/dist/react/index.js +370 -62
  93. package/dist/react/index.js.map +14 -13
  94. package/dist/react/server.js +51 -36
  95. package/dist/react/server.js.map +10 -10
  96. package/dist/src/angular/colocatedRouteMatch.d.ts +23 -0
  97. package/dist/src/angular/components/constants.d.ts +1 -0
  98. package/dist/src/angular/components/defer-slot-payload.d.ts +5 -0
  99. package/dist/src/cli/scripts/manifestKeysEditorHint.d.ts +9 -0
  100. package/dist/src/cli/scripts/typecheck.d.ts +1 -0
  101. package/dist/src/cli/scripts/typecheckDiagnostics.d.ts +41 -0
  102. package/dist/src/constants.d.ts +1 -0
  103. package/dist/src/core/prerender.d.ts +10 -0
  104. package/dist/src/dev/hot/analyze.d.ts +1 -1
  105. package/dist/src/react/browser.d.ts +1 -0
  106. package/dist/src/react/index.d.ts +1 -0
  107. package/dist/src/svelte/lowerAwaitSlotSyntax.d.ts +23 -0
  108. package/dist/src/utils/pageCspNonce.d.ts +14 -0
  109. package/dist/src/utils/spaRouteManifest.d.ts +1 -0
  110. package/dist/svelte/index.js +372 -69
  111. package/dist/svelte/index.js.map +11 -11
  112. package/dist/svelte/server.js +363 -60
  113. package/dist/svelte/server.js.map +11 -11
  114. package/dist/types/manifest.d.ts +3 -2
  115. package/dist/types/svelte.d.ts +3 -0
  116. package/dist/vue/components/Image.js +2 -2
  117. package/dist/vue/components/Image.js.map +3 -3
  118. package/dist/vue/components/index.js +2 -2
  119. package/dist/vue/components/index.js.map +3 -3
  120. package/dist/vue/index.js +364 -61
  121. package/dist/vue/index.js.map +11 -11
  122. package/dist/vue/server.js +54 -40
  123. package/dist/vue/server.js.map +9 -9
  124. package/package.json +1 -1
  125. package/dist/cli/prerender-w65xp6h8.js +0 -11
  126. /package/dist/cli/{index-t8jmj8w1.js → index-fm9x6sjs.js} +0 -0
package/CHANGELOG.md CHANGED
@@ -6,6 +6,52 @@ This file is generated by `absolute-changelog` from the entries in
6
6
  `changelog/`. Edit an entry, not this file — and add new ones under
7
7
  `changelog/unreleased/`.
8
8
 
9
+ ## 0.20.0-beta.183 — 2026-11-15
10
+
11
+ ### Changed
12
+
13
+ - **Angular pages with colocated routes return 404 for unknown sub-paths**
14
+ An Angular page that exports its own `routes` array and is mounted under a wildcard route (such as `.get('/ng/*', ...)`) never returned 404, even for a path none of its routes match. These pages now return 404 for an unknown sub-path, like the other SPA hosts. On each request the handler takes the path below the mount Elysia matched and checks it against the page's `routes` the way Angular's router does: path segments, `:params`, empty paths, `pathMatch: 'full'`, nested `children`, and `redirectTo` sources. A page navigation or HTMX request gets the not-found page (`not-found.html`) and any other client gets Elysia's JSON 404. That JSON rule now covers the React, Svelte, Vue and Angular SPA hosts' 404s too. A route the server can't resolve counts as a match: `loadChildren` matches anything under its path, and a `matcher` function matches everything. To keep the old behaviour for a page, add a `{ path: '**', component: ... }` route, which matches every path.
15
+
16
+ ### Fixed
17
+
18
+ - **Dev SSR recovers when you add a missing import, without restarting the dev server**
19
+ In `absolute dev`, saving a React component that renders another component before its import line exists (`<Card />` with no `import { Card }`), then adding the import, left server rendering failing with `Card is not defined` until the dev server restarted. The server updates edited modules in place and keeps every top-level statement whose text did not change; adding an import changes no statement, so it kept the component created by the previous save, which still looked `Card` up as a global. A statement now also counts as changed when a name it uses gets a different binding (a new or removed import, an import from another module, or an import swapped for a local declaration), so the component is re-created with the import. Separately, a second save of a React file that landed before the client rebuild for the first save ran could be skipped on the server, which kept rendering the first save until the next edit; every save now reaches the server.
20
+ - **An error in a .ts file inside svelteDirectory is reported once, not by both the plain checker and svelte-check**
21
+ svelte-check's program includes a configured svelteDirectory whole, so a plain TypeScript error in a .ts file there was printed under both [bun check] (or [tsc]) and [svelte-check]. `absolute typecheck` now reads svelte-check's machine-readable output and drops the errors the plain checker already reported, matching them by file, line, column and code; errors inside .svelte files stay under svelte-check, and svelte-check passes when every error it found was a duplicate. Its remaining errors are printed in the same shape as tsc's: file:line:column, the TS code, the message and the underlined line.
22
+
23
+ ## 0.20.0-beta.182 — 2026-11-15
24
+
25
+ ### Security
26
+
27
+ - **Escape expressions in streamed Svelte `{#await}` branches, which could run injected script**
28
+ A Svelte `{#await}` block streamed by the server (marked with `<!-- absolute:stream -->`) turned its branches into HTML with every `{expression}` inserted as-is: the pending branch on every render, and the `{:then}` and `{:catch}` branches when the page handler streamed them with `collectStreamingSlots: true`. A value containing markup, such as `<img src=x onerror=…>` coming from a database, an API or an error message, ran as script in the visitor's browser. A strict Content-Security-Policy such as the one `secureHeaders()` sets blocked the injected handler, but pages without one were exposed. Expressions in streamed branches are now escaped exactly as Svelte escapes them when it renders a page itself: text, attribute values, `class` and `style` all match its output, and `{@html value}` is now accepted and stays raw, as in Svelte. An event handler attribute (`onclick={…}`, `onerror="…{value}…"`), a directive (`class:active={…}`) or a spread in a streamed branch is now a build error, because escaping cannot make a value safe inside code. Affects every release with Svelte `{#await}` streaming, from 0.19.0-beta.528 through 0.20.0-beta.181; up to 0.20.0-beta.169 every `{#await}` block with a `{:then}` branch was streamed this way, with no directive needed.
29
+
30
+ ### Added
31
+
32
+ - **`getCspNonce()` from `@absolutejs/absolute/react` gives a page component its CSP nonce on the server and in the browser** (`getCspNonce`)
33
+ The security headers guide showed a React page importing `getCspNonce` from `@absolutejs/absolute`, which is server code: the React client build failed with "Browser build cannot import Node.js builtin". `@absolutejs/absolute/react` now exports a `getCspNonce()` that is safe in page components. During server rendering it returns the request's nonce; in the browser it returns the same value, read from the page's own scripts. The guide now shows `<script nonce={getCspNonce()} suppressHydrationWarning … />`. Browsers hide the nonce attribute after load, so React's development hydration check warns about any element with a nonce unless it has `suppressHydrationWarning`.
34
+
35
+ ### Fixed
36
+
37
+ - **Pages without a `<meta charset>` no longer show non-ASCII text as mojibake: every page response sends `charset=utf-8`**
38
+ React, Svelte, Vue, Angular, Ember, HTML and HTMX page responses, streamed pages, server-component pages, file-route pages, and the error and not-found pages sent `Content-Type: text/html` with no charset. A page without its own `<meta charset>` was decoded as windows-1252, so non-ASCII text (Arabic on a Svelte page, for one) showed as mojibake. Every page response now sends `text/html; charset=utf-8`.
39
+ - **The typecheck manifest-keys note gives a tsconfig.json change that works when `.absolutejs` is excluded, and stops once it is applied**
40
+ The `absolute typecheck` note about manifest keys said to add `.absolutejs/types/manifest.d.ts` to `include` in tsconfig.json. Projects scaffolded before beta.180 exclude `.absolutejs`, and `exclude` removes files from `include`, so following the note did nothing and the editor still never checked `asset(manifest, key)`. When tsconfig.json excludes `.absolutejs`, the note now says to list the file under `files`, which `exclude` doesn't apply to. It no longer prints once tsconfig.json actually puts the file in the program, through `files`, or through `include` with nothing excluding it.
41
+ - **Routes whose static streaming slots resolve asynchronously are pre-rendered again**
42
+ A streaming slot that resolved after the rest of the page had finished rendering (any `StreamSlot` or `SuspenseSlot` with an `async` resolver, in React, Svelte, Vue or Angular) dropped the page's closing `</body></html>`. On a route listed in `static.routes`, pre-rendering then rejected the captured shell as incomplete, so the route quietly went back to rendering on every request. Ordinary streamed responses were missing the closing tags too. The stream now keeps the closing tags until every slot has been patched in, so these routes are pre-rendered with their static slots inlined, and dynamic slots stay holes as before.
43
+ - **`absolute start` and `absolute compile` warn about routes they couldn't pre-render**
44
+ When a route listed in `static.routes` couldn't be pre-rendered, `absolute start` and `absolute compile` said nothing and the route fell back to rendering on every request. Each such route now gets one warning when pre-rendering runs, naming the route and the reason, for example `Could not pre-render /account: the route responded with HTTP 500. It renders on each request instead.` Other reasons are a failed request, a non-HTML response, an incomplete HTML document and a render that threw.
45
+ - **Self-closing <abs-include /> tags expand inside other includes instead of shipping raw tags**
46
+ A self-closing `<abs-include src="…" />` inside another include's content (for example in a page's slot content for a layout) was counted as an unclosed tag, so the outer include never expanded and the page shipped raw `<abs-include>` tags with no error. Self-closing `<abs-include />`, `<abs-slot />` and `<template slot="…" />` now work anywhere: at the top level, nested, inside slot content, mixed with the paired form and several to a line, and quoted attribute values containing `/` or `>` (such as `src="a/b.html"` or `data-x="a>b"`) no longer confuse the parser. An `<abs-include>` or `<abs-slot>` that is never closed, or a stray closing tag, now fails the build (and the dev rebuild) with the file and line instead of shipping raw tags.
47
+ - **A Svelte component's `<style>` now applies inside its streamed `{#await}` branches**
48
+ The branches of a Svelte `{#await}` block streamed by the server (marked with `<!-- absolute:stream -->`) are sent as HTML, and their elements never got the component's scoped-CSS class (`svelte-…`). Svelte also dropped every rule in the component's `<style>` that only matched elements in those branches, reporting it as an unused selector, so a rule such as `p.done { color: red }` styled nothing in the pending, `{:then}` or `{:catch}` branch, in dev and in production builds. Every element in a streamed branch now gets the same scoped class Svelte gives the rest of the component, and the component's rules for those elements are kept, so its `<style>` applies inside streamed branches as it does everywhere else in the component.
49
+
50
+ ### Internal
51
+
52
+ - **Angular `@defer` slot payloads no longer carry unescaped interpolated HTML**
53
+ The streamed payload an Angular `@defer` block produces carries an `html` string that the streaming pipeline only measures (for `maxSlotHtmlSizeBytes` and slot metrics); the slot itself renders from `data` through Angular's own escaping, and the stream-swap runtime never inserts `angular-defer` payloads. That `html` string was built with raw `{{ }}` values, so it held live, unescaped markup that a future change could have turned into XSS. Each interpolated value is now HTML-escaped (`&`, `<`, `>`, `"`, `'`) the way Angular escapes text, and tests pin both the escaping and that the runtime never writes an `angular-defer` payload into the DOM. Rendered output is unchanged.
54
+
9
55
  ## 0.20.0-beta.181 — 2026-11-15
10
56
 
11
57
  ### Fixed
package/changelog.json CHANGED
@@ -2,6 +2,81 @@
2
2
  "contract": 1,
3
3
  "name": "@absolutejs/absolute",
4
4
  "releases": [
5
+ {
6
+ "changes": [
7
+ {
8
+ "detail": "An Angular page that exports its own `routes` array and is mounted under a wildcard route (such as `.get('/ng/*', ...)`) never returned 404, even for a path none of its routes match. These pages now return 404 for an unknown sub-path, like the other SPA hosts. On each request the handler takes the path below the mount Elysia matched and checks it against the page's `routes` the way Angular's router does: path segments, `:params`, empty paths, `pathMatch: 'full'`, nested `children`, and `redirectTo` sources. A page navigation or HTMX request gets the not-found page (`not-found.html`) and any other client gets Elysia's JSON 404. That JSON rule now covers the React, Svelte, Vue and Angular SPA hosts' 404s too. A route the server can't resolve counts as a match: `loadChildren` matches anything under its path, and a `matcher` function matches everything. To keep the old behaviour for a page, add a `{ path: '**', component: ... }` route, which matches every path.",
9
+ "kind": "changed",
10
+ "summary": "Angular pages with colocated routes return 404 for unknown sub-paths"
11
+ },
12
+ {
13
+ "detail": "In `absolute dev`, saving a React component that renders another component before its import line exists (`<Card />` with no `import { Card }`), then adding the import, left server rendering failing with `Card is not defined` until the dev server restarted. The server updates edited modules in place and keeps every top-level statement whose text did not change; adding an import changes no statement, so it kept the component created by the previous save, which still looked `Card` up as a global. A statement now also counts as changed when a name it uses gets a different binding (a new or removed import, an import from another module, or an import swapped for a local declaration), so the component is re-created with the import. Separately, a second save of a React file that landed before the client rebuild for the first save ran could be skipped on the server, which kept rendering the first save until the next edit; every save now reaches the server.",
14
+ "kind": "fixed",
15
+ "summary": "Dev SSR recovers when you add a missing import, without restarting the dev server"
16
+ },
17
+ {
18
+ "detail": "svelte-check's program includes a configured svelteDirectory whole, so a plain TypeScript error in a .ts file there was printed under both [bun check] (or [tsc]) and [svelte-check]. `absolute typecheck` now reads svelte-check's machine-readable output and drops the errors the plain checker already reported, matching them by file, line, column and code; errors inside .svelte files stay under svelte-check, and svelte-check passes when every error it found was a duplicate. Its remaining errors are printed in the same shape as tsc's: file:line:column, the TS code, the message and the underlined line.",
19
+ "kind": "fixed",
20
+ "summary": "An error in a .ts file inside svelteDirectory is reported once, not by both the plain checker and svelte-check"
21
+ }
22
+ ],
23
+ "date": "2026-11-15",
24
+ "version": "0.20.0-beta.183"
25
+ },
26
+ {
27
+ "changes": [
28
+ {
29
+ "detail": "The streamed payload an Angular `@defer` block produces carries an `html` string that the streaming pipeline only measures (for `maxSlotHtmlSizeBytes` and slot metrics); the slot itself renders from `data` through Angular's own escaping, and the stream-swap runtime never inserts `angular-defer` payloads. That `html` string was built with raw `{{ }}` values, so it held live, unescaped markup that a future change could have turned into XSS. Each interpolated value is now HTML-escaped (`&`, `<`, `>`, `\"`, `'`) the way Angular escapes text, and tests pin both the escaping and that the runtime never writes an `angular-defer` payload into the DOM. Rendered output is unchanged.",
30
+ "kind": "internal",
31
+ "summary": "Angular `@defer` slot payloads no longer carry unescaped interpolated HTML"
32
+ },
33
+ {
34
+ "detail": "React, Svelte, Vue, Angular, Ember, HTML and HTMX page responses, streamed pages, server-component pages, file-route pages, and the error and not-found pages sent `Content-Type: text/html` with no charset. A page without its own `<meta charset>` was decoded as windows-1252, so non-ASCII text (Arabic on a Svelte page, for one) showed as mojibake. Every page response now sends `text/html; charset=utf-8`.",
35
+ "kind": "fixed",
36
+ "summary": "Pages without a `<meta charset>` no longer show non-ASCII text as mojibake: every page response sends `charset=utf-8`"
37
+ },
38
+ {
39
+ "detail": "The `absolute typecheck` note about manifest keys said to add `.absolutejs/types/manifest.d.ts` to `include` in tsconfig.json. Projects scaffolded before beta.180 exclude `.absolutejs`, and `exclude` removes files from `include`, so following the note did nothing and the editor still never checked `asset(manifest, key)`. When tsconfig.json excludes `.absolutejs`, the note now says to list the file under `files`, which `exclude` doesn't apply to. It no longer prints once tsconfig.json actually puts the file in the program, through `files`, or through `include` with nothing excluding it.",
40
+ "kind": "fixed",
41
+ "summary": "The typecheck manifest-keys note gives a tsconfig.json change that works when `.absolutejs` is excluded, and stops once it is applied"
42
+ },
43
+ {
44
+ "detail": "A streaming slot that resolved after the rest of the page had finished rendering (any `StreamSlot` or `SuspenseSlot` with an `async` resolver, in React, Svelte, Vue or Angular) dropped the page's closing `</body></html>`. On a route listed in `static.routes`, pre-rendering then rejected the captured shell as incomplete, so the route quietly went back to rendering on every request. Ordinary streamed responses were missing the closing tags too. The stream now keeps the closing tags until every slot has been patched in, so these routes are pre-rendered with their static slots inlined, and dynamic slots stay holes as before.",
45
+ "kind": "fixed",
46
+ "summary": "Routes whose static streaming slots resolve asynchronously are pre-rendered again"
47
+ },
48
+ {
49
+ "detail": "When a route listed in `static.routes` couldn't be pre-rendered, `absolute start` and `absolute compile` said nothing and the route fell back to rendering on every request. Each such route now gets one warning when pre-rendering runs, naming the route and the reason, for example `Could not pre-render /account: the route responded with HTTP 500. It renders on each request instead.` Other reasons are a failed request, a non-HTML response, an incomplete HTML document and a render that threw.",
50
+ "kind": "fixed",
51
+ "summary": "`absolute start` and `absolute compile` warn about routes they couldn't pre-render"
52
+ },
53
+ {
54
+ "detail": "The security headers guide showed a React page importing `getCspNonce` from `@absolutejs/absolute`, which is server code: the React client build failed with \"Browser build cannot import Node.js builtin\". `@absolutejs/absolute/react` now exports a `getCspNonce()` that is safe in page components. During server rendering it returns the request's nonce; in the browser it returns the same value, read from the page's own scripts. The guide now shows `<script nonce={getCspNonce()} suppressHydrationWarning … />`. Browsers hide the nonce attribute after load, so React's development hydration check warns about any element with a nonce unless it has `suppressHydrationWarning`.",
55
+ "kind": "added",
56
+ "summary": "`getCspNonce()` from `@absolutejs/absolute/react` gives a page component its CSP nonce on the server and in the browser",
57
+ "symbols": [
58
+ "getCspNonce"
59
+ ]
60
+ },
61
+ {
62
+ "detail": "A self-closing `<abs-include src=\"…\" />` inside another include's content (for example in a page's slot content for a layout) was counted as an unclosed tag, so the outer include never expanded and the page shipped raw `<abs-include>` tags with no error. Self-closing `<abs-include />`, `<abs-slot />` and `<template slot=\"…\" />` now work anywhere: at the top level, nested, inside slot content, mixed with the paired form and several to a line, and quoted attribute values containing `/` or `>` (such as `src=\"a/b.html\"` or `data-x=\"a>b\"`) no longer confuse the parser. An `<abs-include>` or `<abs-slot>` that is never closed, or a stray closing tag, now fails the build (and the dev rebuild) with the file and line instead of shipping raw tags.",
63
+ "kind": "fixed",
64
+ "summary": "Self-closing <abs-include /> tags expand inside other includes instead of shipping raw tags"
65
+ },
66
+ {
67
+ "detail": "A Svelte `{#await}` block streamed by the server (marked with `<!-- absolute:stream -->`) turned its branches into HTML with every `{expression}` inserted as-is: the pending branch on every render, and the `{:then}` and `{:catch}` branches when the page handler streamed them with `collectStreamingSlots: true`. A value containing markup, such as `<img src=x onerror=…>` coming from a database, an API or an error message, ran as script in the visitor's browser. A strict Content-Security-Policy such as the one `secureHeaders()` sets blocked the injected handler, but pages without one were exposed. Expressions in streamed branches are now escaped exactly as Svelte escapes them when it renders a page itself: text, attribute values, `class` and `style` all match its output, and `{@html value}` is now accepted and stays raw, as in Svelte. An event handler attribute (`onclick={…}`, `onerror=\"…{value}…\"`), a directive (`class:active={…}`) or a spread in a streamed branch is now a build error, because escaping cannot make a value safe inside code. Affects every release with Svelte `{#await}` streaming, from 0.19.0-beta.528 through 0.20.0-beta.181; up to 0.20.0-beta.169 every `{#await}` block with a `{:then}` branch was streamed this way, with no directive needed.",
68
+ "kind": "security",
69
+ "summary": "Escape expressions in streamed Svelte `{#await}` branches, which could run injected script"
70
+ },
71
+ {
72
+ "detail": "The branches of a Svelte `{#await}` block streamed by the server (marked with `<!-- absolute:stream -->`) are sent as HTML, and their elements never got the component's scoped-CSS class (`svelte-…`). Svelte also dropped every rule in the component's `<style>` that only matched elements in those branches, reporting it as an unused selector, so a rule such as `p.done { color: red }` styled nothing in the pending, `{:then}` or `{:catch}` branch, in dev and in production builds. Every element in a streamed branch now gets the same scoped class Svelte gives the rest of the component, and the component's rules for those elements are kept, so its `<style>` applies inside streamed branches as it does everywhere else in the component.",
73
+ "kind": "fixed",
74
+ "summary": "A Svelte component's `<style>` now applies inside its streamed `{#await}` branches"
75
+ }
76
+ ],
77
+ "date": "2026-11-15",
78
+ "version": "0.20.0-beta.182"
79
+ },
5
80
  {
6
81
  "changes": [
7
82
  {
@@ -9089,7 +9089,7 @@ var require_cjs = __commonJS(function(exports) {
9089
9089
  });
9090
9090
 
9091
9091
  // src/constants.ts
9092
- var ANGULAR_INIT_TIMEOUT_MS = 500, ANSI_ESCAPE_CODE = 27, ANSI_ESCAPE_LENGTH = 3, ASCII_SPACE = 32, BASE_36_RADIX = 36, BUN_BUILD_WARNING_SUPPRESSION = "wildcard sideEffects are not supported yet", TAILWIND_BUN_CSS_WARNING_PATTERN, BODY_SLICE_LENGTH = 2000, BYTES_PER_KILOBYTE = 1024, CLI_ARGS_OFFSET = 3, CSS_ERROR_RESOLVE_DELAY_MS = 50, CSS_MAX_CHECK_ATTEMPTS = 10, CSS_MAX_PARSE_TIMEOUT_MS = 500, CSS_RELOAD_BACKOFF_BASE_MS = 1000, CSS_RELOAD_BACKOFF_MAX_MS = 60000, CSS_SHEET_READY_TIMEOUT_MS = 100, DEFAULT_CHUNK_SIZE = 16384, DEFAULT_DEBOUNCE_MS = 15, DEFAULT_PORT = 3000, DEV_SERVER_RESTART_DEBOUNCE_MS = 100, DOM_UPDATE_DELAY_MS = 50, FILE_PROTOCOL_PREFIX_LENGTH = 7, FOCUS_ID_PREFIX_LENGTH = 3, FOCUS_IDX_PREFIX_LENGTH = 4, FOCUS_NAME_PREFIX_LENGTH = 5, ESLINT_STUDIO_DEFAULT_HOST = "eslint.absolute.localhost", ESLINT_STUDIO_DEFAULT_PORT = 4099, CONFIG_DEFAULT_HOST = "config.absolute.localhost", CONFIG_DEFAULT_PORT = 4099, HMR_UPDATE_TIMEOUT_MS = 2000, HOOK_SIGNATURE_LENGTH = 12, EXCLUDE_LAST_OFFSET = -1, HTTP_STATUS_OK = 200, HTTP_STATUS_BAD_REQUEST = 400, HTTP_STATUS_NOT_FOUND = 404, HTTP_STATUS_GONE = 410, HTTP_STATUS_INTERNAL_SERVER_ERROR = 500, HOURS_IN_DAY = 24, HOURS_IN_HALF_DAY = 12, IMAGE_DEFAULT_DEVICE_SIZES, IMAGE_DEFAULT_IMAGE_SIZES, IMAGE_DEFAULT_QUALITY = 75, IMAGE_GLOB_SUFFIX_LENGTH = 2, INSTANCE_PROBE_TIMEOUT_MS = 250, MAX_ERROR_LENGTH = 200, MAX_RECONNECT_ATTEMPTS = 60, MILLISECONDS_IN_A_SECOND = 1000, MINUTES_IN_AN_HOUR = 60, SECONDS_IN_A_MINUTE = 60, MILLISECONDS_IN_A_MINUTE, MILLISECONDS_IN_A_DAY, OVERLAY_FADE_DURATION_MS = 150, PING_INTERVAL_MS = 30000, LIST_LOG_TAIL_MAX_BYTES = 65536, LIST_TUI_COLUMN_GAP = 2, LIST_TUI_DEFAULT_HEIGHT = 28, LIST_TUI_DEFAULT_WIDTH = 100, LIST_TUI_ESCAPE_SEQUENCE_TIMEOUT_MS = 30, LIST_TUI_FOOTER_LINE_COUNT = 2, LIST_TUI_MARKER_WIDTH = 2, LIST_TUI_MIN_LOG_HEIGHT = 3, LIST_TUI_MIN_URL_WIDTH = 16, LIST_TUI_RENDER_DEBOUNCE_MS = 16, LIST_TUI_STATUS_MESSAGE_TIMEOUT_MS = 4000, LIST_WATCH_REFRESH_MS = 1000, RAF_BATCH_COUNT = 3, RANDOM_ID_END_INDEX = 11, REBUILD_BATCH_DELAY_MS = 10, REBUILD_RELOAD_DELAY_MS = 200, RECONNECT_INITIAL_DELAY_MS = 500, RECONNECT_POLL_INTERVAL_MS = 300, REACT_STREAM_SLOT_FAST_DELAY_MS = 5, REACT_STREAM_SLOT_SLOW_DELAY_MS = 20, SIGINT_EXIT_CODE = 130, SIGTERM_EXIT_CODE = 143, SVELTE_CSS_LOAD_TIMEOUT_MS = 500, TIME_PRECISION = 2, TWO_THIRDS, UNFOUND_INDEX = -1, WEBSOCKET_NORMAL_CLOSURE = 1000, DEFAULT_WEBSOCKET_IDLE_TIMEOUT_SECONDS = 240, DEFAULT_HTTP_IDLE_TIMEOUT_SECONDS = 240, MAX_HTTP_IDLE_TIMEOUT_SECONDS = 255, WORKSPACE_COMMAND_ARGS_OFFSET = 3, WORKSPACE_FAILURE_LOG_PRINT_LIMIT = 30, WORKSPACE_FAILURE_RECENT_LOG_LIMIT = 60, WORKSPACE_READY_ATTEMPT_TIMEOUT_MS = 5000, WORKSPACE_READY_PROBE_INTERVAL_MS = 250, WORKSPACE_READY_TIMEOUT_MS = 30000, WORKSPACE_SHUTDOWN_TIMEOUT_MS = 1e4, WORKSPACE_TUI_DEFAULT_HEIGHT = 28, WORKSPACE_TUI_DEFAULT_WIDTH = 100, WORKSPACE_TUI_ESCAPE_SEQUENCE_TIMEOUT_MS = 30, WORKSPACE_TUI_FOOTER_LINE_COUNT = 3, WORKSPACE_TUI_MIN_LOG_HEIGHT = 3, WORKSPACE_TUI_MIN_SERVICE_NAME_WIDTH = 7, WORKSPACE_TUI_MIN_TARGET_WIDTH = 8, WORKSPACE_TUI_MIN_WRAP_WIDTH = 12, WORKSPACE_TUI_PROMPT_CURSOR_OFFSET = 3, WORKSPACE_TUI_RECENT_LOG_LIMIT = 40, WORKSPACE_TUI_RENDER_DEBOUNCE_MS = 16, WORKSPACE_TUI_STATUS_WIDTH = 10, WORKSPACE_TUI_TARGET_PADDING_WIDTH = 6, WORKSPACE_TUI_VISIBILITY_WIDTH = 8;
9092
+ var ANGULAR_INIT_TIMEOUT_MS = 500, ANSI_ESCAPE_CODE = 27, ANSI_ESCAPE_LENGTH = 3, ASCII_SPACE = 32, BASE_36_RADIX = 36, BUN_BUILD_WARNING_SUPPRESSION = "wildcard sideEffects are not supported yet", TAILWIND_BUN_CSS_WARNING_PATTERN, BODY_SLICE_LENGTH = 2000, BYTES_PER_KILOBYTE = 1024, CLI_ARGS_OFFSET = 3, CSS_ERROR_RESOLVE_DELAY_MS = 50, CSS_MAX_CHECK_ATTEMPTS = 10, CSS_MAX_PARSE_TIMEOUT_MS = 500, CSS_RELOAD_BACKOFF_BASE_MS = 1000, CSS_RELOAD_BACKOFF_MAX_MS = 60000, CSS_SHEET_READY_TIMEOUT_MS = 100, DEFAULT_CHUNK_SIZE = 16384, DEFAULT_DEBOUNCE_MS = 15, DEFAULT_PORT = 3000, DEV_SERVER_RESTART_DEBOUNCE_MS = 100, DOM_UPDATE_DELAY_MS = 50, FILE_PROTOCOL_PREFIX_LENGTH = 7, FOCUS_ID_PREFIX_LENGTH = 3, FOCUS_IDX_PREFIX_LENGTH = 4, FOCUS_NAME_PREFIX_LENGTH = 5, ESLINT_STUDIO_DEFAULT_HOST = "eslint.absolute.localhost", ESLINT_STUDIO_DEFAULT_PORT = 4099, CONFIG_DEFAULT_HOST = "config.absolute.localhost", CONFIG_DEFAULT_PORT = 4099, HMR_UPDATE_TIMEOUT_MS = 2000, HOOK_SIGNATURE_LENGTH = 12, EXCLUDE_LAST_OFFSET = -1, HTML_CONTENT_TYPE = "text/html; charset=utf-8", HTTP_STATUS_OK = 200, HTTP_STATUS_BAD_REQUEST = 400, HTTP_STATUS_NOT_FOUND = 404, HTTP_STATUS_GONE = 410, HTTP_STATUS_INTERNAL_SERVER_ERROR = 500, HOURS_IN_DAY = 24, HOURS_IN_HALF_DAY = 12, IMAGE_DEFAULT_DEVICE_SIZES, IMAGE_DEFAULT_IMAGE_SIZES, IMAGE_DEFAULT_QUALITY = 75, IMAGE_GLOB_SUFFIX_LENGTH = 2, INSTANCE_PROBE_TIMEOUT_MS = 250, MAX_ERROR_LENGTH = 200, MAX_RECONNECT_ATTEMPTS = 60, MILLISECONDS_IN_A_SECOND = 1000, MINUTES_IN_AN_HOUR = 60, SECONDS_IN_A_MINUTE = 60, MILLISECONDS_IN_A_MINUTE, MILLISECONDS_IN_A_DAY, OVERLAY_FADE_DURATION_MS = 150, PING_INTERVAL_MS = 30000, LIST_LOG_TAIL_MAX_BYTES = 65536, LIST_TUI_COLUMN_GAP = 2, LIST_TUI_DEFAULT_HEIGHT = 28, LIST_TUI_DEFAULT_WIDTH = 100, LIST_TUI_ESCAPE_SEQUENCE_TIMEOUT_MS = 30, LIST_TUI_FOOTER_LINE_COUNT = 2, LIST_TUI_MARKER_WIDTH = 2, LIST_TUI_MIN_LOG_HEIGHT = 3, LIST_TUI_MIN_URL_WIDTH = 16, LIST_TUI_RENDER_DEBOUNCE_MS = 16, LIST_TUI_STATUS_MESSAGE_TIMEOUT_MS = 4000, LIST_WATCH_REFRESH_MS = 1000, RAF_BATCH_COUNT = 3, RANDOM_ID_END_INDEX = 11, REBUILD_BATCH_DELAY_MS = 10, REBUILD_RELOAD_DELAY_MS = 200, RECONNECT_INITIAL_DELAY_MS = 500, RECONNECT_POLL_INTERVAL_MS = 300, REACT_STREAM_SLOT_FAST_DELAY_MS = 5, REACT_STREAM_SLOT_SLOW_DELAY_MS = 20, SIGINT_EXIT_CODE = 130, SIGTERM_EXIT_CODE = 143, SVELTE_CSS_LOAD_TIMEOUT_MS = 500, TIME_PRECISION = 2, TWO_THIRDS, UNFOUND_INDEX = -1, WEBSOCKET_NORMAL_CLOSURE = 1000, DEFAULT_WEBSOCKET_IDLE_TIMEOUT_SECONDS = 240, DEFAULT_HTTP_IDLE_TIMEOUT_SECONDS = 240, MAX_HTTP_IDLE_TIMEOUT_SECONDS = 255, WORKSPACE_COMMAND_ARGS_OFFSET = 3, WORKSPACE_FAILURE_LOG_PRINT_LIMIT = 30, WORKSPACE_FAILURE_RECENT_LOG_LIMIT = 60, WORKSPACE_READY_ATTEMPT_TIMEOUT_MS = 5000, WORKSPACE_READY_PROBE_INTERVAL_MS = 250, WORKSPACE_READY_TIMEOUT_MS = 30000, WORKSPACE_SHUTDOWN_TIMEOUT_MS = 1e4, WORKSPACE_TUI_DEFAULT_HEIGHT = 28, WORKSPACE_TUI_DEFAULT_WIDTH = 100, WORKSPACE_TUI_ESCAPE_SEQUENCE_TIMEOUT_MS = 30, WORKSPACE_TUI_FOOTER_LINE_COUNT = 3, WORKSPACE_TUI_MIN_LOG_HEIGHT = 3, WORKSPACE_TUI_MIN_SERVICE_NAME_WIDTH = 7, WORKSPACE_TUI_MIN_TARGET_WIDTH = 8, WORKSPACE_TUI_MIN_WRAP_WIDTH = 12, WORKSPACE_TUI_PROMPT_CURSOR_OFFSET = 3, WORKSPACE_TUI_RECENT_LOG_LIMIT = 40, WORKSPACE_TUI_RENDER_DEBOUNCE_MS = 16, WORKSPACE_TUI_STATUS_WIDTH = 10, WORKSPACE_TUI_TARGET_PADDING_WIDTH = 6, WORKSPACE_TUI_VISIBILITY_WIDTH = 8;
9093
9093
  var init_constants = __esm(() => {
9094
9094
  TAILWIND_BUN_CSS_WARNING_PATTERN = /invalid @ rule encountered: '@(theme|tailwind|source|utility|variant|custom-variant|apply|reference|plugin|config)'/;
9095
9095
  IMAGE_DEFAULT_DEVICE_SIZES = [
@@ -10383,5 +10383,5 @@ export {
10383
10383
  withPendingTask
10384
10384
  };
10385
10385
 
10386
- //# debugId=6ABD5809EADF708164756E2164756E21
10386
+ //# debugId=09D52776D7F1748864756E2164756E21
10387
10387
  //# sourceMappingURL=browser.js.map