@absolutejs/absolute 0.20.0-beta.180 → 0.20.0-beta.182

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 (129) hide show
  1. package/CHANGELOG.md +41 -0
  2. package/changelog.json +70 -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 +349 -48
  9. package/dist/angular/index.js.map +11 -11
  10. package/dist/angular/server.js +349 -48
  11. package/dist/angular/server.js.map +11 -11
  12. package/dist/build.js +605 -114
  13. package/dist/build.js.map +20 -20
  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-fz7qbdn3.js → build-mskrk9zb.js} +3 -3
  20. package/dist/cli/{build-fntmf42w.js → build-p3qra1nj.js} +65 -7
  21. package/dist/cli/{buildDepVendor-qnwfct22.js → buildDepVendor-36d1aa7c.js} +2 -2
  22. package/dist/cli/{buildReactServerComponents-fq6mw10d.js → buildReactServerComponents-vc9hh2rd.js} +5 -5
  23. package/dist/cli/{compile-54rb8szn.js → compile-7mjd739p.js} +10 -6
  24. package/dist/cli/config/server.js +18 -17
  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-9djrap79.js → index-3pz5sjaz.js} +1 -1
  39. package/dist/cli/{index-50ag35xg.js → index-3ys9tz53.js} +2 -2
  40. package/dist/cli/{index-6f448d7m.js → index-4ynx0cq6.js} +26 -12
  41. package/dist/cli/{index-btp4fyf1.js → index-785hpa2r.js} +2 -2
  42. package/dist/cli/{index-w79snsxv.js → index-7zwzyymv.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-xf9sfr8a.js → index-fgqh48qr.js} +63 -1
  50. package/dist/cli/{index-c8rcfe5a.js → index-fy4th3n0.js} +1 -1
  51. package/dist/cli/{index-prza6tkp.js → index-gx6pjzzk.js} +3 -3
  52. package/dist/cli/{index-125cfzvn.js → index-hker5fs4.js} +2 -2
  53. package/dist/cli/{index-cgmp9d02.js → index-hqkcxa2p.js} +1 -1
  54. package/dist/cli/{index-x1vvn549.js → index-mmm6d3k5.js} +3 -3
  55. package/dist/cli/{index-enbw9484.js → index-wpgsermq.js} +1 -1
  56. package/dist/cli/{index-0z5fgb80.js → index-wqpg377f.js} +1 -1
  57. package/dist/cli/{index-3sfcmb49.js → index-x7h6w6td.js} +1 -1
  58. package/dist/cli/{index-a6xx0p9e.js → index-ydaxsftq.js} +1 -1
  59. package/dist/cli/{index-3ewt17wm.js → index-yhkg5by0.js} +1 -1
  60. package/dist/cli/{index-aqe25w4h.js → index-zeeep92g.js} +1 -1
  61. package/dist/cli/index.js +32 -32
  62. package/dist/cli/{info-k124sh7g.js → info-5rwsbhe2.js} +4 -4
  63. package/dist/cli/{inspect-n6pcfvfw.js → inspect-nmwb0q5k.js} +5 -5
  64. package/dist/cli/{iosNativeWatcher-wdq2fvj1.js → iosNativeWatcher-7r9gnk87.js} +7 -7
  65. package/dist/cli/{iosSimulatorController-n97dpa8p.js → iosSimulatorController-w963vv9r.js} +7 -7
  66. package/dist/cli/{islands-17tfx8jf.js → islands-w9xrehpk.js} +3 -3
  67. package/dist/cli/{logs-shg23fbt.js → logs-m793x8a7.js} +3 -3
  68. package/dist/cli/{ls-0wr74w0b.js → ls-k31npd5b.js} +3 -3
  69. package/dist/cli/{mem-16sy1707.js → mem-jm6kw6gr.js} +5 -5
  70. package/dist/cli/{migrate-k91k050s.js → migrate-95bjkqkr.js} +2 -2
  71. package/dist/cli/{mobile-hpqpy61f.js → mobile-cpp8vfn7.js} +13 -13
  72. package/dist/cli/prerender-26pzynh4.js +13 -0
  73. package/dist/cli/{prettier-dh5fh786.js → prettier-0ws9pbc1.js} +1 -1
  74. package/dist/cli/{ps-pk7ncjac.js → ps-fx8mz3e3.js} +6 -6
  75. package/dist/cli/{psTui-50wf0b72.js → psTui-0e9c7an6.js} +7 -7
  76. package/dist/cli/{remoteMacProtocol-g10s408w.js → remoteMacProtocol-y7h79gr8.js} +7 -7
  77. package/dist/cli/{remove-x987pvd3.js → remove-xhvph8bz.js} +8 -8
  78. package/dist/cli/{routes-mc3ymp8t.js → routes-hq9yje5z.js} +3 -3
  79. package/dist/cli/{start-mbn2zgs2.js → start-5mjh9hh2.js} +5 -5
  80. package/dist/cli/{staticAnalyzeSpaRoutes-2nev05m1.js → staticAnalyzeSpaRoutes-rcc1d3az.js} +3 -1
  81. package/dist/cli/{typecheck-488txsfc.js → typecheck-yjme4fv1.js} +71 -35
  82. package/dist/cli/{workspace-7sbyyc59.js → workspace-xeb6abxj.js} +5 -5
  83. package/dist/index.js +620 -126
  84. package/dist/index.js.map +22 -22
  85. package/dist/islands/index.js +312 -23
  86. package/dist/islands/index.js.map +5 -5
  87. package/dist/mobile/index.js +2 -2
  88. package/dist/mobile/index.js.map +3 -3
  89. package/dist/react/browser.js +18 -1
  90. package/dist/react/browser.js.map +6 -4
  91. package/dist/react/components/index.js +2 -2
  92. package/dist/react/components/index.js.map +3 -3
  93. package/dist/react/index.js +366 -61
  94. package/dist/react/index.js.map +14 -13
  95. package/dist/react/server.js +47 -35
  96. package/dist/react/server.js.map +10 -10
  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/angular/staticAnalyzeSpaRoutes.d.ts +9 -0
  100. package/dist/src/cli/scripts/manifestKeysEditorHint.d.ts +9 -0
  101. package/dist/src/cli/scripts/typecheck.d.ts +7 -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/spaRouteRefresh.d.ts +12 -5
  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 +2 -0
  110. package/dist/svelte/components/Image.svelte +1 -1
  111. package/dist/svelte/components/Island.svelte +1 -1
  112. package/dist/svelte/index.js +368 -68
  113. package/dist/svelte/index.js.map +11 -11
  114. package/dist/svelte/router/Router.svelte.d.ts +31 -1
  115. package/dist/svelte/server.js +359 -59
  116. package/dist/svelte/server.js.map +11 -11
  117. package/dist/types/manifest.d.ts +3 -2
  118. package/dist/types/svelte.d.ts +3 -0
  119. package/dist/vue/components/Image.js +2 -2
  120. package/dist/vue/components/Image.js.map +3 -3
  121. package/dist/vue/components/index.js +2 -2
  122. package/dist/vue/components/index.js.map +3 -3
  123. package/dist/vue/index.js +360 -60
  124. package/dist/vue/index.js.map +11 -11
  125. package/dist/vue/server.js +50 -39
  126. package/dist/vue/server.js.map +9 -9
  127. package/package.json +4 -1
  128. package/dist/cli/prerender-w65xp6h8.js +0 -11
  129. /package/dist/cli/{index-t8jmj8w1.js → index-fm9x6sjs.js} +0 -0
package/CHANGELOG.md CHANGED
@@ -6,6 +6,47 @@ 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.182 — 2026-11-15
10
+
11
+ ### Security
12
+
13
+ - **Escape expressions in streamed Svelte `{#await}` branches, which could run injected script**
14
+ 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.
15
+
16
+ ### Added
17
+
18
+ - **`getCspNonce()` from `@absolutejs/absolute/react` gives a page component its CSP nonce on the server and in the browser** (`getCspNonce`)
19
+ 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`.
20
+
21
+ ### Fixed
22
+
23
+ - **Pages without a `<meta charset>` no longer show non-ASCII text as mojibake: every page response sends `charset=utf-8`**
24
+ 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`.
25
+ - **The typecheck manifest-keys note gives a tsconfig.json change that works when `.absolutejs` is excluded, and stops once it is applied**
26
+ 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.
27
+ - **Routes whose static streaming slots resolve asynchronously are pre-rendered again**
28
+ 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.
29
+ - **`absolute start` and `absolute compile` warn about routes they couldn't pre-render**
30
+ 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.
31
+ - **Self-closing <abs-include /> tags expand inside other includes instead of shipping raw tags**
32
+ 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.
33
+ - **A Svelte component's `<style>` now applies inside its streamed `{#await}` branches**
34
+ 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.
35
+
36
+ ### Internal
37
+
38
+ - **Angular `@defer` slot payloads no longer carry unescaped interpolated HTML**
39
+ 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.
40
+
41
+ ## 0.20.0-beta.181 — 2026-11-15
42
+
43
+ ### Fixed
44
+
45
+ - **Dev renders a newly added Vue route on the server at once and reports Angular colocated route edits**
46
+ In `absolute dev`, adding a route to a Vue page's `routes` admitted the new path right away, but the server kept rendering the page with its old router for a couple of seconds: requests logged `[Vue Router warn]: No match found for location` and got the 404 page, and a page that reloaded straight after the edit hit the same thing. Dev now rebuilds the page's server bundle before it admits the new path, so the first request renders it. Svelte pages with a `<Router>` get the same ordering, and an Angular router edit is published once its server bundle has the change. React was not affected. Editing an Angular page's colocated `export const routes = [...]` now prints a `routes update` line with the added and removed paths, like the other frameworks.
47
+ - **Typecheck checks Svelte islands outside svelteDirectory, and reports each Svelte and Angular error once**
48
+ A project with Svelte pages in svelteDirectory and Svelte islands in another folder (src/islands) ran svelte-check once per folder, and every run wrote the same generated config at the same time. The last write won, so both runs checked one folder: a type error inside an island component passed, and an error in a page was printed twice under two svelte-check headings. svelte-check now runs once over every Svelte folder (configured directories whole, island folders by their .svelte files) and reports under one svelte-check label; ngc likewise runs once over every Angular directory. An error in an Angular component’s plain TypeScript, which both the plain checker and ngc read, is now reported once, under bun check (or tsc); ngc keeps the template errors only it sees, and the run still fails whenever any checker finds an error.
49
+
9
50
  ## 0.20.0-beta.180 — 2026-11-14
10
51
 
11
52
  ### Added
package/changelog.json CHANGED
@@ -2,6 +2,76 @@
2
2
  "contract": 1,
3
3
  "name": "@absolutejs/absolute",
4
4
  "releases": [
5
+ {
6
+ "changes": [
7
+ {
8
+ "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.",
9
+ "kind": "internal",
10
+ "summary": "Angular `@defer` slot payloads no longer carry unescaped interpolated HTML"
11
+ },
12
+ {
13
+ "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`.",
14
+ "kind": "fixed",
15
+ "summary": "Pages without a `<meta charset>` no longer show non-ASCII text as mojibake: every page response sends `charset=utf-8`"
16
+ },
17
+ {
18
+ "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.",
19
+ "kind": "fixed",
20
+ "summary": "The typecheck manifest-keys note gives a tsconfig.json change that works when `.absolutejs` is excluded, and stops once it is applied"
21
+ },
22
+ {
23
+ "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.",
24
+ "kind": "fixed",
25
+ "summary": "Routes whose static streaming slots resolve asynchronously are pre-rendered again"
26
+ },
27
+ {
28
+ "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.",
29
+ "kind": "fixed",
30
+ "summary": "`absolute start` and `absolute compile` warn about routes they couldn't pre-render"
31
+ },
32
+ {
33
+ "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`.",
34
+ "kind": "added",
35
+ "summary": "`getCspNonce()` from `@absolutejs/absolute/react` gives a page component its CSP nonce on the server and in the browser",
36
+ "symbols": [
37
+ "getCspNonce"
38
+ ]
39
+ },
40
+ {
41
+ "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.",
42
+ "kind": "fixed",
43
+ "summary": "Self-closing <abs-include /> tags expand inside other includes instead of shipping raw tags"
44
+ },
45
+ {
46
+ "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.",
47
+ "kind": "security",
48
+ "summary": "Escape expressions in streamed Svelte `{#await}` branches, which could run injected script"
49
+ },
50
+ {
51
+ "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.",
52
+ "kind": "fixed",
53
+ "summary": "A Svelte component's `<style>` now applies inside its streamed `{#await}` branches"
54
+ }
55
+ ],
56
+ "date": "2026-11-15",
57
+ "version": "0.20.0-beta.182"
58
+ },
59
+ {
60
+ "changes": [
61
+ {
62
+ "detail": "In `absolute dev`, adding a route to a Vue page's `routes` admitted the new path right away, but the server kept rendering the page with its old router for a couple of seconds: requests logged `[Vue Router warn]: No match found for location` and got the 404 page, and a page that reloaded straight after the edit hit the same thing. Dev now rebuilds the page's server bundle before it admits the new path, so the first request renders it. Svelte pages with a `<Router>` get the same ordering, and an Angular router edit is published once its server bundle has the change. React was not affected. Editing an Angular page's colocated `export const routes = [...]` now prints a `routes update` line with the added and removed paths, like the other frameworks.",
63
+ "kind": "fixed",
64
+ "summary": "Dev renders a newly added Vue route on the server at once and reports Angular colocated route edits"
65
+ },
66
+ {
67
+ "detail": "A project with Svelte pages in svelteDirectory and Svelte islands in another folder (src/islands) ran svelte-check once per folder, and every run wrote the same generated config at the same time. The last write won, so both runs checked one folder: a type error inside an island component passed, and an error in a page was printed twice under two svelte-check headings. svelte-check now runs once over every Svelte folder (configured directories whole, island folders by their .svelte files) and reports under one svelte-check label; ngc likewise runs once over every Angular directory. An error in an Angular component’s plain TypeScript, which both the plain checker and ngc read, is now reported once, under bun check (or tsc); ngc keeps the template errors only it sees, and the run still fails whenever any checker finds an error.",
68
+ "kind": "fixed",
69
+ "summary": "Typecheck checks Svelte islands outside svelteDirectory, and reports each Svelte and Angular error once"
70
+ }
71
+ ],
72
+ "date": "2026-11-15",
73
+ "version": "0.20.0-beta.181"
74
+ },
5
75
  {
6
76
  "changes": [
7
77
  {
@@ -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