astro 4.3.7 → 4.4.1

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 (172) hide show
  1. package/components/Image.astro +4 -0
  2. package/components/Picture.astro +4 -0
  3. package/dist/@types/astro.d.ts +42 -42
  4. package/dist/assets/build/generate.d.ts +1 -1
  5. package/dist/assets/build/generate.js +1 -2
  6. package/dist/assets/internal.js +14 -0
  7. package/dist/assets/types.d.ts +23 -2
  8. package/dist/assets/utils/metadata.js +3 -3
  9. package/dist/assets/utils/remoteProbe.d.ts +2 -0
  10. package/dist/assets/utils/remoteProbe.js +35 -0
  11. package/dist/assets/utils/vendor/image-size/detector.d.ts +2 -0
  12. package/dist/assets/utils/vendor/image-size/detector.js +24 -0
  13. package/dist/assets/utils/vendor/image-size/lookup.d.ts +10 -0
  14. package/dist/assets/utils/vendor/image-size/lookup.js +26 -0
  15. package/dist/assets/utils/vendor/image-size/types/bmp.d.ts +2 -0
  16. package/dist/assets/utils/vendor/image-size/types/bmp.js +11 -0
  17. package/dist/assets/utils/vendor/image-size/types/cur.d.ts +2 -0
  18. package/dist/assets/utils/vendor/image-size/types/cur.js +17 -0
  19. package/dist/assets/utils/vendor/image-size/types/dds.d.ts +2 -0
  20. package/dist/assets/utils/vendor/image-size/types/dds.js +11 -0
  21. package/dist/assets/utils/vendor/image-size/types/gif.d.ts +2 -0
  22. package/dist/assets/utils/vendor/image-size/types/gif.js +12 -0
  23. package/dist/assets/utils/vendor/image-size/types/heif.d.ts +2 -0
  24. package/dist/assets/utils/vendor/image-size/types/heif.js +53 -0
  25. package/dist/assets/utils/vendor/image-size/types/icns.d.ts +2 -0
  26. package/dist/assets/utils/vendor/image-size/types/icns.js +85 -0
  27. package/dist/assets/utils/vendor/image-size/types/ico.d.ts +2 -0
  28. package/dist/assets/utils/vendor/image-size/types/ico.js +43 -0
  29. package/dist/assets/utils/vendor/image-size/types/index.d.ts +3 -0
  30. package/dist/assets/utils/vendor/image-size/types/index.js +43 -0
  31. package/dist/assets/utils/vendor/image-size/types/interface.d.ts +13 -0
  32. package/dist/assets/utils/vendor/image-size/types/interface.js +0 -0
  33. package/dist/assets/utils/vendor/image-size/types/j2c.d.ts +2 -0
  34. package/dist/assets/utils/vendor/image-size/types/j2c.js +12 -0
  35. package/dist/assets/utils/vendor/image-size/types/jp2.d.ts +2 -0
  36. package/dist/assets/utils/vendor/image-size/types/jp2.js +25 -0
  37. package/dist/assets/utils/vendor/image-size/types/jpg.d.ts +2 -0
  38. package/dist/assets/utils/vendor/image-size/types/jpg.js +97 -0
  39. package/dist/assets/utils/vendor/image-size/types/ktx.d.ts +2 -0
  40. package/dist/assets/utils/vendor/image-size/types/ktx.js +19 -0
  41. package/dist/assets/utils/vendor/image-size/types/png.d.ts +2 -0
  42. package/dist/assets/utils/vendor/image-size/types/png.js +34 -0
  43. package/dist/assets/utils/vendor/image-size/types/pnm.d.ts +2 -0
  44. package/dist/assets/utils/vendor/image-size/types/pnm.js +69 -0
  45. package/dist/assets/utils/vendor/image-size/types/psd.d.ts +2 -0
  46. package/dist/assets/utils/vendor/image-size/types/psd.js +11 -0
  47. package/dist/assets/utils/vendor/image-size/types/svg.d.ts +2 -0
  48. package/dist/assets/utils/vendor/image-size/types/svg.js +94 -0
  49. package/dist/assets/utils/vendor/image-size/types/tga.d.ts +2 -0
  50. package/dist/assets/utils/vendor/image-size/types/tga.js +15 -0
  51. package/dist/assets/utils/vendor/image-size/types/tiff.d.ts +2 -0
  52. package/dist/assets/utils/vendor/image-size/types/tiff.js +66 -0
  53. package/dist/assets/utils/vendor/image-size/types/utils.d.ts +15 -0
  54. package/dist/assets/utils/vendor/image-size/types/utils.js +60 -0
  55. package/dist/assets/utils/vendor/image-size/types/webp.d.ts +2 -0
  56. package/dist/assets/utils/vendor/image-size/types/webp.js +52 -0
  57. package/dist/cli/add/babel.d.ts +1 -1
  58. package/dist/cli/add/index.js +10 -3
  59. package/dist/cli/db/index.js +2 -0
  60. package/dist/cli/info/index.js +2 -0
  61. package/dist/cli/preferences/index.js +2 -0
  62. package/dist/content/runtime.js +3 -1
  63. package/dist/content/types-generator.js +7 -27
  64. package/dist/core/app/index.js +39 -122
  65. package/dist/core/app/pipeline.d.ts +7 -0
  66. package/dist/core/app/pipeline.js +39 -0
  67. package/dist/core/base-pipeline.d.ts +59 -0
  68. package/dist/core/base-pipeline.js +27 -0
  69. package/dist/core/build/generate.d.ts +1 -1
  70. package/dist/core/build/generate.js +39 -109
  71. package/dist/core/build/index.js +0 -4
  72. package/dist/core/build/{buildPipeline.d.ts → pipeline.d.ts} +13 -13
  73. package/dist/core/build/pipeline.js +180 -0
  74. package/dist/core/build/plugins/plugin-css.js +6 -5
  75. package/dist/core/build/plugins/plugin-hoisted-scripts.js +6 -5
  76. package/dist/core/build/plugins/util.d.ts +2 -1
  77. package/dist/core/build/plugins/util.js +12 -1
  78. package/dist/core/build/types.d.ts +0 -2
  79. package/dist/core/constants.d.ts +10 -1
  80. package/dist/core/constants.js +14 -4
  81. package/dist/core/dev/dev.js +1 -1
  82. package/dist/core/dev/restart.js +1 -1
  83. package/dist/core/endpoint/index.d.ts +5 -4
  84. package/dist/core/endpoint/index.js +7 -34
  85. package/dist/core/errors/errors-data.d.ts +16 -3
  86. package/dist/core/errors/errors-data.js +9 -2
  87. package/dist/core/messages.js +2 -2
  88. package/dist/core/middleware/callMiddleware.d.ts +1 -1
  89. package/dist/core/middleware/callMiddleware.js +2 -9
  90. package/dist/core/middleware/index.d.ts +2 -2
  91. package/dist/core/middleware/index.js +74 -9
  92. package/dist/core/module-loader/vite.js +4 -4
  93. package/dist/core/preview/index.js +2 -0
  94. package/dist/core/preview/static-preview-server.js +1 -7
  95. package/dist/core/redirects/helpers.d.ts +1 -3
  96. package/dist/core/redirects/helpers.js +0 -29
  97. package/dist/core/redirects/index.d.ts +2 -1
  98. package/dist/core/redirects/index.js +3 -3
  99. package/dist/core/redirects/render.d.ts +2 -0
  100. package/dist/core/redirects/render.js +33 -0
  101. package/dist/core/render/index.d.ts +7 -13
  102. package/dist/core/render/index.js +7 -7
  103. package/dist/core/render/params-and-props.d.ts +8 -3
  104. package/dist/core/render/params-and-props.js +24 -16
  105. package/dist/core/render/result.d.ts +6 -5
  106. package/dist/core/render/result.js +3 -4
  107. package/dist/core/render-context.d.ts +32 -0
  108. package/dist/core/render-context.js +219 -0
  109. package/dist/core/routing/index.d.ts +0 -1
  110. package/dist/core/routing/index.js +0 -2
  111. package/dist/core/routing/manifest/create.js +11 -27
  112. package/dist/core/routing/params.d.ts +1 -7
  113. package/dist/core/routing/params.js +0 -15
  114. package/dist/core/sync/index.js +3 -3
  115. package/dist/i18n/middleware.d.ts +0 -5
  116. package/dist/i18n/middleware.js +61 -69
  117. package/dist/i18n/utils.d.ts +25 -0
  118. package/dist/{core/render/context.js → i18n/utils.js} +3 -49
  119. package/dist/prerender/routing.d.ts +1 -1
  120. package/dist/prerender/routing.js +20 -21
  121. package/dist/runtime/client/dev-toolbar/apps/astro.js +14 -10
  122. package/dist/runtime/client/dev-toolbar/apps/audit/a11y.js +2 -2
  123. package/dist/runtime/client/dev-toolbar/apps/audit/index.d.ts +1 -1
  124. package/dist/runtime/client/dev-toolbar/apps/audit/index.js +115 -6
  125. package/dist/runtime/client/dev-toolbar/apps/audit/perf.d.ts +2 -0
  126. package/dist/runtime/client/dev-toolbar/apps/audit/perf.js +110 -0
  127. package/dist/runtime/client/dev-toolbar/apps/utils/highlight.d.ts +1 -1
  128. package/dist/runtime/client/dev-toolbar/apps/utils/highlight.js +6 -1
  129. package/dist/runtime/client/dev-toolbar/ui-library/card.js +1 -1
  130. package/dist/runtime/server/astro-island.js +10 -1
  131. package/dist/runtime/server/astro-island.prebuilt-dev.d.ts +7 -0
  132. package/dist/runtime/server/astro-island.prebuilt-dev.js +4 -0
  133. package/dist/runtime/server/astro-island.prebuilt.d.ts +1 -1
  134. package/dist/runtime/server/astro-island.prebuilt.js +1 -1
  135. package/dist/runtime/server/endpoint.js +2 -2
  136. package/dist/runtime/server/render/astro/render.d.ts +1 -0
  137. package/dist/runtime/server/render/astro/render.js +81 -2
  138. package/dist/runtime/server/render/component.js +6 -0
  139. package/dist/runtime/server/render/page.js +15 -2
  140. package/dist/runtime/server/render/util.d.ts +7 -0
  141. package/dist/runtime/server/render/util.js +15 -0
  142. package/dist/runtime/server/scripts.js +2 -4
  143. package/dist/runtime/server/transition.js +14 -1
  144. package/dist/vite-plugin-astro/hmr.d.ts +1 -0
  145. package/dist/vite-plugin-astro/hmr.js +7 -4
  146. package/dist/vite-plugin-astro-server/error.d.ts +2 -2
  147. package/dist/vite-plugin-astro-server/error.js +2 -5
  148. package/dist/vite-plugin-astro-server/index.d.ts +0 -6
  149. package/dist/vite-plugin-astro-server/index.js +0 -19
  150. package/dist/vite-plugin-astro-server/pipeline.d.ts +19 -0
  151. package/dist/vite-plugin-astro-server/pipeline.js +117 -0
  152. package/dist/vite-plugin-astro-server/plugin.js +3 -4
  153. package/dist/vite-plugin-astro-server/request.d.ts +3 -4
  154. package/dist/vite-plugin-astro-server/request.js +6 -9
  155. package/dist/vite-plugin-astro-server/route.d.ts +3 -4
  156. package/dist/vite-plugin-astro-server/route.js +34 -162
  157. package/dist/vite-plugin-dev-toolbar/vite-plugin-dev-toolbar.js +3 -3
  158. package/package.json +7 -12
  159. package/dist/core/app/ssrPipeline.d.ts +0 -3
  160. package/dist/core/app/ssrPipeline.js +0 -6
  161. package/dist/core/build/buildPipeline.js +0 -150
  162. package/dist/core/pipeline.d.ts +0 -39
  163. package/dist/core/pipeline.js +0 -107
  164. package/dist/core/render/context.d.ts +0 -52
  165. package/dist/core/render/core.d.ts +0 -10
  166. package/dist/core/render/core.js +0 -65
  167. package/dist/core/render/environment.d.ts +0 -34
  168. package/dist/core/render/environment.js +0 -6
  169. package/dist/runtime/server/consts.d.ts +0 -1
  170. package/dist/runtime/server/consts.js +0 -4
  171. package/dist/vite-plugin-astro-server/devPipeline.d.ts +0 -22
  172. package/dist/vite-plugin-astro-server/devPipeline.js +0 -65
@@ -0,0 +1,110 @@
1
+ const EXTERNAL_URL_REGEX = /^(?:[a-z+]+:)?\/\//i;
2
+ const perf = [
3
+ {
4
+ code: "perf-use-image-component",
5
+ title: "Use the Image component",
6
+ message: "This image could be replaced with the Image component to improve performance.",
7
+ selector: "img:not([data-image-component])",
8
+ async match(element) {
9
+ const src = element.getAttribute("src");
10
+ if (!src)
11
+ return false;
12
+ if (src.startsWith("data:"))
13
+ return false;
14
+ if (!EXTERNAL_URL_REGEX.test(src)) {
15
+ const imageData = await fetch(src).then((response) => response.blob());
16
+ if (imageData.size < 20480)
17
+ return false;
18
+ }
19
+ return true;
20
+ }
21
+ },
22
+ {
23
+ code: "perf-use-loading-lazy",
24
+ title: 'Use the loading="lazy" attribute',
25
+ message: (element) => `This ${element.nodeName} tag is below the fold and could be lazy-loaded to improve performance.`,
26
+ selector: 'img:not([loading]), img[loading="eager"], iframe:not([loading]), iframe[loading="eager"]',
27
+ match(element) {
28
+ const htmlElement = element;
29
+ if (htmlElement.offsetTop < window.innerHeight)
30
+ return false;
31
+ return true;
32
+ }
33
+ },
34
+ {
35
+ code: "perf-use-loading-eager",
36
+ title: 'Use the loading="eager" attribute',
37
+ message: (element) => `This ${element.nodeName} tag is above the fold and could be eagerly-loaded to improve performance.`,
38
+ selector: 'img[loading="lazy"], iframe[loading="lazy"]',
39
+ match(element) {
40
+ const htmlElement = element;
41
+ if (htmlElement.offsetTop > window.innerHeight)
42
+ return false;
43
+ return true;
44
+ }
45
+ },
46
+ {
47
+ code: "perf-use-videos",
48
+ title: "Use videos instead of GIFs for large animations",
49
+ message: "This GIF could be replaced with a video to reduce its file size and improve performance.",
50
+ selector: 'img[src$=".gif"]',
51
+ async match(element) {
52
+ const src = element.getAttribute("src");
53
+ if (!src)
54
+ return false;
55
+ if (EXTERNAL_URL_REGEX.test(src))
56
+ return false;
57
+ if (!EXTERNAL_URL_REGEX.test(src)) {
58
+ const imageData = await fetch(src).then((response) => response.blob());
59
+ if (imageData.size < 102400)
60
+ return false;
61
+ }
62
+ return true;
63
+ }
64
+ },
65
+ {
66
+ code: "perf-slow-component-server-render",
67
+ title: "Server-rendered component took a long time to render",
68
+ message: (element) => `This component took an unusually long time to render on the server (${getCleanRenderingTime(
69
+ element.getAttribute("server-render-time")
70
+ )}). This might be a sign that it's doing too much work on the server, or something is blocking rendering.`,
71
+ selector: "astro-island[server-render-time]",
72
+ match(element) {
73
+ const serverRenderTime = element.getAttribute("server-render-time");
74
+ if (!serverRenderTime)
75
+ return false;
76
+ const renderingTime = parseFloat(serverRenderTime);
77
+ if (Number.isNaN(renderingTime))
78
+ return false;
79
+ return renderingTime > 500;
80
+ }
81
+ },
82
+ {
83
+ code: "perf-slow-component-client-hydration",
84
+ title: "Client-rendered component took a long time to hydrate",
85
+ message: (element) => `This component took an unusually long time to render on the server (${getCleanRenderingTime(
86
+ element.getAttribute("client-render-time")
87
+ )}). This could be a sign that something is blocking the main thread and preventing the component from hydrating quickly.`,
88
+ selector: "astro-island[client-render-time]",
89
+ match(element) {
90
+ const clientRenderTime = element.getAttribute("client-render-time");
91
+ if (!clientRenderTime)
92
+ return false;
93
+ const renderingTime = parseFloat(clientRenderTime);
94
+ if (Number.isNaN(renderingTime))
95
+ return false;
96
+ return renderingTime > 500;
97
+ }
98
+ }
99
+ ];
100
+ function getCleanRenderingTime(time) {
101
+ if (!time)
102
+ return "unknown";
103
+ const renderingTime = parseFloat(time);
104
+ if (Number.isNaN(renderingTime))
105
+ return "unknown";
106
+ return renderingTime.toFixed(2) + "s";
107
+ }
108
+ export {
109
+ perf
110
+ };
@@ -1,6 +1,6 @@
1
1
  import type { DevToolbarHighlight } from '../../ui-library/highlight.js';
2
2
  import type { Icon } from '../../ui-library/icons.js';
3
- export declare function createHighlight(rect: DOMRect, icon?: Icon): DevToolbarHighlight;
3
+ export declare function createHighlight(rect: DOMRect, icon?: Icon, additionalAttributes?: Record<string, string>): DevToolbarHighlight;
4
4
  export declare function getElementsPositionInDocument(el: Element): {
5
5
  isFixed: boolean;
6
6
  };
@@ -1,7 +1,12 @@
1
- function createHighlight(rect, icon) {
1
+ function createHighlight(rect, icon, additionalAttributes) {
2
2
  const highlight = document.createElement("astro-dev-toolbar-highlight");
3
3
  if (icon)
4
4
  highlight.icon = icon;
5
+ if (additionalAttributes) {
6
+ for (const [key, value] of Object.entries(additionalAttributes)) {
7
+ highlight.setAttribute(key, value);
8
+ }
9
+ }
5
10
  highlight.tabIndex = 0;
6
11
  if (rect.width === 0 || rect.height === 0) {
7
12
  highlight.style.display = "none";
@@ -9,7 +9,7 @@ class DevToolbarCard extends HTMLElement {
9
9
  }
10
10
  connectedCallback() {
11
11
  const element = this.link ? "a" : this.clickAction ? "button" : "div";
12
- this.shadowRoot.innerHTML = `
12
+ this.shadowRoot.innerHTML += `
13
13
  <style>
14
14
  :host>a, :host>button, :host>div {
15
15
  box-sizing: border-box;
@@ -139,9 +139,18 @@
139
139
  );
140
140
  throw e;
141
141
  }
142
- await this.hydrator(this)(this.Component, props, slots, {
142
+ let hydrationTimeStart;
143
+ const hydrator = this.hydrator(this);
144
+ if (process.env.NODE_ENV === "development")
145
+ hydrationTimeStart = performance.now();
146
+ await hydrator(this.Component, props, slots, {
143
147
  client: this.getAttribute("client")
144
148
  });
149
+ if (process.env.NODE_ENV === "development" && hydrationTimeStart)
150
+ this.setAttribute(
151
+ "client-render-time",
152
+ (performance.now() - hydrationTimeStart).toString()
153
+ );
145
154
  this.removeAttribute("ssr");
146
155
  this.dispatchEvent(new CustomEvent("astro:hydrate"));
147
156
  };
@@ -0,0 +1,7 @@
1
+ /**
2
+ * This file is prebuilt from packages/astro/src/runtime/server/astro-island.ts
3
+ * Do not edit this directly, but instead edit that file and rerun the prebuild
4
+ * to generate this file.
5
+ */
6
+ declare const _default: "(()=>{var v=Object.defineProperty;var A=(c,s,a)=>s in c?v(c,s,{enumerable:!0,configurable:!0,writable:!0,value:a}):c[s]=a;var l=(c,s,a)=>(A(c,typeof s!=\"symbol\"?s+\"\":s,a),a);var m;{let c={0:t=>y(t),1:t=>a(t),2:t=>new RegExp(t),3:t=>new Date(t),4:t=>new Map(a(t)),5:t=>new Set(a(t)),6:t=>BigInt(t),7:t=>new URL(t),8:t=>new Uint8Array(t),9:t=>new Uint16Array(t),10:t=>new Uint32Array(t)},s=t=>{let[e,n]=t;return e in c?c[e](n):void 0},a=t=>t.map(s),y=t=>typeof t!=\"object\"||t===null?t:Object.fromEntries(Object.entries(t).map(([e,n])=>[e,s(n)]));customElements.get(\"astro-island\")||customElements.define(\"astro-island\",(m=class extends HTMLElement{constructor(){super(...arguments);l(this,\"Component\");l(this,\"hydrator\");l(this,\"hydrate\",async()=>{var f;if(!this.hydrator||!this.isConnected)return;let e=(f=this.parentElement)==null?void 0:f.closest(\"astro-island[ssr]\");if(e){e.addEventListener(\"astro:hydrate\",this.hydrate,{once:!0});return}let n=this.querySelectorAll(\"astro-slot\"),r={},h=this.querySelectorAll(\"template[data-astro-template]\");for(let o of h){let i=o.closest(this.tagName);i!=null&&i.isSameNode(this)&&(r[o.getAttribute(\"data-astro-template\")||\"default\"]=o.innerHTML,o.remove())}for(let o of n){let i=o.closest(this.tagName);i!=null&&i.isSameNode(this)&&(r[o.getAttribute(\"name\")||\"default\"]=o.innerHTML)}let p;try{p=this.hasAttribute(\"props\")?y(JSON.parse(this.getAttribute(\"props\"))):{}}catch(o){let i=this.getAttribute(\"component-url\")||\"<unknown>\",b=this.getAttribute(\"component-export\");throw b&&(i+=` (export ${b})`),console.error(`[hydrate] Error parsing props for component ${i}`,this.getAttribute(\"props\"),o),o}let d,u=this.hydrator(this);d=performance.now(),await u(this.Component,p,r,{client:this.getAttribute(\"client\")}),d&&this.setAttribute(\"client-render-time\",(performance.now()-d).toString()),this.removeAttribute(\"ssr\"),this.dispatchEvent(new CustomEvent(\"astro:hydrate\"))});l(this,\"unmount\",()=>{this.isConnected||this.dispatchEvent(new CustomEvent(\"astro:unmount\"))})}disconnectedCallback(){document.removeEventListener(\"astro:after-swap\",this.unmount),document.addEventListener(\"astro:after-swap\",this.unmount,{once:!0})}connectedCallback(){if(!this.hasAttribute(\"await-children\")||document.readyState===\"interactive\"||document.readyState===\"complete\")this.childrenConnectedCallback();else{let e=()=>{document.removeEventListener(\"DOMContentLoaded\",e),n.disconnect(),this.childrenConnectedCallback()},n=new MutationObserver(()=>{var r;((r=this.lastChild)==null?void 0:r.nodeType)===Node.COMMENT_NODE&&this.lastChild.nodeValue===\"astro:end\"&&(this.lastChild.remove(),e())});n.observe(this,{childList:!0}),document.addEventListener(\"DOMContentLoaded\",e)}}async childrenConnectedCallback(){let e=this.getAttribute(\"before-hydration-url\");e&&await import(e),this.start()}async start(){let e=JSON.parse(this.getAttribute(\"opts\")),n=this.getAttribute(\"client\");if(Astro[n]===void 0){window.addEventListener(`astro:${n}`,()=>this.start(),{once:!0});return}try{await Astro[n](async()=>{let r=this.getAttribute(\"renderer-url\"),[h,{default:p}]=await Promise.all([import(this.getAttribute(\"component-url\")),r?import(r):()=>()=>{}]),d=this.getAttribute(\"component-export\")||\"default\";if(!d.includes(\".\"))this.Component=h[d];else{this.Component=h;for(let u of d.split(\".\"))this.Component=this.Component[u]}return this.hydrator=p,this.hydrate},e,this)}catch(r){console.error(`[astro-island] Error hydrating ${this.getAttribute(\"component-url\")}`,r)}}attributeChangedCallback(){this.hydrate()}},l(m,\"observedAttributes\",[\"props\"]),m))}})();";
7
+ export default _default;
@@ -0,0 +1,4 @@
1
+ var astro_island_prebuilt_dev_default = `(()=>{var v=Object.defineProperty;var A=(c,s,a)=>s in c?v(c,s,{enumerable:!0,configurable:!0,writable:!0,value:a}):c[s]=a;var l=(c,s,a)=>(A(c,typeof s!="symbol"?s+"":s,a),a);var m;{let c={0:t=>y(t),1:t=>a(t),2:t=>new RegExp(t),3:t=>new Date(t),4:t=>new Map(a(t)),5:t=>new Set(a(t)),6:t=>BigInt(t),7:t=>new URL(t),8:t=>new Uint8Array(t),9:t=>new Uint16Array(t),10:t=>new Uint32Array(t)},s=t=>{let[e,n]=t;return e in c?c[e](n):void 0},a=t=>t.map(s),y=t=>typeof t!="object"||t===null?t:Object.fromEntries(Object.entries(t).map(([e,n])=>[e,s(n)]));customElements.get("astro-island")||customElements.define("astro-island",(m=class extends HTMLElement{constructor(){super(...arguments);l(this,"Component");l(this,"hydrator");l(this,"hydrate",async()=>{var f;if(!this.hydrator||!this.isConnected)return;let e=(f=this.parentElement)==null?void 0:f.closest("astro-island[ssr]");if(e){e.addEventListener("astro:hydrate",this.hydrate,{once:!0});return}let n=this.querySelectorAll("astro-slot"),r={},h=this.querySelectorAll("template[data-astro-template]");for(let o of h){let i=o.closest(this.tagName);i!=null&&i.isSameNode(this)&&(r[o.getAttribute("data-astro-template")||"default"]=o.innerHTML,o.remove())}for(let o of n){let i=o.closest(this.tagName);i!=null&&i.isSameNode(this)&&(r[o.getAttribute("name")||"default"]=o.innerHTML)}let p;try{p=this.hasAttribute("props")?y(JSON.parse(this.getAttribute("props"))):{}}catch(o){let i=this.getAttribute("component-url")||"<unknown>",b=this.getAttribute("component-export");throw b&&(i+=\` (export \${b})\`),console.error(\`[hydrate] Error parsing props for component \${i}\`,this.getAttribute("props"),o),o}let d,u=this.hydrator(this);d=performance.now(),await u(this.Component,p,r,{client:this.getAttribute("client")}),d&&this.setAttribute("client-render-time",(performance.now()-d).toString()),this.removeAttribute("ssr"),this.dispatchEvent(new CustomEvent("astro:hydrate"))});l(this,"unmount",()=>{this.isConnected||this.dispatchEvent(new CustomEvent("astro:unmount"))})}disconnectedCallback(){document.removeEventListener("astro:after-swap",this.unmount),document.addEventListener("astro:after-swap",this.unmount,{once:!0})}connectedCallback(){if(!this.hasAttribute("await-children")||document.readyState==="interactive"||document.readyState==="complete")this.childrenConnectedCallback();else{let e=()=>{document.removeEventListener("DOMContentLoaded",e),n.disconnect(),this.childrenConnectedCallback()},n=new MutationObserver(()=>{var r;((r=this.lastChild)==null?void 0:r.nodeType)===Node.COMMENT_NODE&&this.lastChild.nodeValue==="astro:end"&&(this.lastChild.remove(),e())});n.observe(this,{childList:!0}),document.addEventListener("DOMContentLoaded",e)}}async childrenConnectedCallback(){let e=this.getAttribute("before-hydration-url");e&&await import(e),this.start()}async start(){let e=JSON.parse(this.getAttribute("opts")),n=this.getAttribute("client");if(Astro[n]===void 0){window.addEventListener(\`astro:\${n}\`,()=>this.start(),{once:!0});return}try{await Astro[n](async()=>{let r=this.getAttribute("renderer-url"),[h,{default:p}]=await Promise.all([import(this.getAttribute("component-url")),r?import(r):()=>()=>{}]),d=this.getAttribute("component-export")||"default";if(!d.includes("."))this.Component=h[d];else{this.Component=h;for(let u of d.split("."))this.Component=this.Component[u]}return this.hydrator=p,this.hydrate},e,this)}catch(r){console.error(\`[astro-island] Error hydrating \${this.getAttribute("component-url")}\`,r)}}attributeChangedCallback(){this.hydrate()}},l(m,"observedAttributes",["props"]),m))}})();`;
2
+ export {
3
+ astro_island_prebuilt_dev_default as default
4
+ };
@@ -3,5 +3,5 @@
3
3
  * Do not edit this directly, but instead edit that file and rerun the prebuild
4
4
  * to generate this file.
5
5
  */
6
- declare const _default: "(()=>{var b=Object.defineProperty;var f=(c,s,a)=>s in c?b(c,s,{enumerable:!0,configurable:!0,writable:!0,value:a}):c[s]=a;var l=(c,s,a)=>(f(c,typeof s!=\"symbol\"?s+\"\":s,a),a);var p;{let c={0:t=>m(t),1:t=>a(t),2:t=>new RegExp(t),3:t=>new Date(t),4:t=>new Map(a(t)),5:t=>new Set(a(t)),6:t=>BigInt(t),7:t=>new URL(t),8:t=>new Uint8Array(t),9:t=>new Uint16Array(t),10:t=>new Uint32Array(t)},s=t=>{let[e,r]=t;return e in c?c[e](r):void 0},a=t=>t.map(s),m=t=>typeof t!=\"object\"||t===null?t:Object.fromEntries(Object.entries(t).map(([e,r])=>[e,s(r)]));customElements.get(\"astro-island\")||customElements.define(\"astro-island\",(p=class extends HTMLElement{constructor(){super(...arguments);l(this,\"Component\");l(this,\"hydrator\");l(this,\"hydrate\",async()=>{var d;if(!this.hydrator||!this.isConnected)return;let e=(d=this.parentElement)==null?void 0:d.closest(\"astro-island[ssr]\");if(e){e.addEventListener(\"astro:hydrate\",this.hydrate,{once:!0});return}let r=this.querySelectorAll(\"astro-slot\"),o={},h=this.querySelectorAll(\"template[data-astro-template]\");for(let n of h){let i=n.closest(this.tagName);i!=null&&i.isSameNode(this)&&(o[n.getAttribute(\"data-astro-template\")||\"default\"]=n.innerHTML,n.remove())}for(let n of r){let i=n.closest(this.tagName);i!=null&&i.isSameNode(this)&&(o[n.getAttribute(\"name\")||\"default\"]=n.innerHTML)}let u;try{u=this.hasAttribute(\"props\")?m(JSON.parse(this.getAttribute(\"props\"))):{}}catch(n){let i=this.getAttribute(\"component-url\")||\"<unknown>\",y=this.getAttribute(\"component-export\");throw y&&(i+=` (export ${y})`),console.error(`[hydrate] Error parsing props for component ${i}`,this.getAttribute(\"props\"),n),n}await this.hydrator(this)(this.Component,u,o,{client:this.getAttribute(\"client\")}),this.removeAttribute(\"ssr\"),this.dispatchEvent(new CustomEvent(\"astro:hydrate\"))});l(this,\"unmount\",()=>{this.isConnected||this.dispatchEvent(new CustomEvent(\"astro:unmount\"))})}disconnectedCallback(){document.removeEventListener(\"astro:after-swap\",this.unmount),document.addEventListener(\"astro:after-swap\",this.unmount,{once:!0})}connectedCallback(){if(!this.hasAttribute(\"await-children\")||document.readyState===\"interactive\"||document.readyState===\"complete\")this.childrenConnectedCallback();else{let e=()=>{document.removeEventListener(\"DOMContentLoaded\",e),r.disconnect(),this.childrenConnectedCallback()},r=new MutationObserver(()=>{var o;((o=this.lastChild)==null?void 0:o.nodeType)===Node.COMMENT_NODE&&this.lastChild.nodeValue===\"astro:end\"&&(this.lastChild.remove(),e())});r.observe(this,{childList:!0}),document.addEventListener(\"DOMContentLoaded\",e)}}async childrenConnectedCallback(){let e=this.getAttribute(\"before-hydration-url\");e&&await import(e),this.start()}async start(){let e=JSON.parse(this.getAttribute(\"opts\")),r=this.getAttribute(\"client\");if(Astro[r]===void 0){window.addEventListener(`astro:${r}`,()=>this.start(),{once:!0});return}try{await Astro[r](async()=>{let o=this.getAttribute(\"renderer-url\"),[h,{default:u}]=await Promise.all([import(this.getAttribute(\"component-url\")),o?import(o):()=>()=>{}]),d=this.getAttribute(\"component-export\")||\"default\";if(!d.includes(\".\"))this.Component=h[d];else{this.Component=h;for(let n of d.split(\".\"))this.Component=this.Component[n]}return this.hydrator=u,this.hydrate},e,this)}catch(o){console.error(`[astro-island] Error hydrating ${this.getAttribute(\"component-url\")}`,o)}}attributeChangedCallback(){this.hydrate()}},l(p,\"observedAttributes\",[\"props\"]),p))}})();";
6
+ declare const _default: "(()=>{var v=Object.defineProperty;var A=(c,s,a)=>s in c?v(c,s,{enumerable:!0,configurable:!0,writable:!0,value:a}):c[s]=a;var d=(c,s,a)=>(A(c,typeof s!=\"symbol\"?s+\"\":s,a),a);var u;{let c={0:t=>m(t),1:t=>a(t),2:t=>new RegExp(t),3:t=>new Date(t),4:t=>new Map(a(t)),5:t=>new Set(a(t)),6:t=>BigInt(t),7:t=>new URL(t),8:t=>new Uint8Array(t),9:t=>new Uint16Array(t),10:t=>new Uint32Array(t)},s=t=>{let[e,n]=t;return e in c?c[e](n):void 0},a=t=>t.map(s),m=t=>typeof t!=\"object\"||t===null?t:Object.fromEntries(Object.entries(t).map(([e,n])=>[e,s(n)]));customElements.get(\"astro-island\")||customElements.define(\"astro-island\",(u=class extends HTMLElement{constructor(){super(...arguments);d(this,\"Component\");d(this,\"hydrator\");d(this,\"hydrate\",async()=>{var f;if(!this.hydrator||!this.isConnected)return;let e=(f=this.parentElement)==null?void 0:f.closest(\"astro-island[ssr]\");if(e){e.addEventListener(\"astro:hydrate\",this.hydrate,{once:!0});return}let n=this.querySelectorAll(\"astro-slot\"),r={},l=this.querySelectorAll(\"template[data-astro-template]\");for(let o of l){let i=o.closest(this.tagName);i!=null&&i.isSameNode(this)&&(r[o.getAttribute(\"data-astro-template\")||\"default\"]=o.innerHTML,o.remove())}for(let o of n){let i=o.closest(this.tagName);i!=null&&i.isSameNode(this)&&(r[o.getAttribute(\"name\")||\"default\"]=o.innerHTML)}let h;try{h=this.hasAttribute(\"props\")?m(JSON.parse(this.getAttribute(\"props\"))):{}}catch(o){let i=this.getAttribute(\"component-url\")||\"<unknown>\",b=this.getAttribute(\"component-export\");throw b&&(i+=` (export ${b})`),console.error(`[hydrate] Error parsing props for component ${i}`,this.getAttribute(\"props\"),o),o}let p;await this.hydrator(this)(this.Component,h,r,{client:this.getAttribute(\"client\")}),this.removeAttribute(\"ssr\"),this.dispatchEvent(new CustomEvent(\"astro:hydrate\"))});d(this,\"unmount\",()=>{this.isConnected||this.dispatchEvent(new CustomEvent(\"astro:unmount\"))})}disconnectedCallback(){document.removeEventListener(\"astro:after-swap\",this.unmount),document.addEventListener(\"astro:after-swap\",this.unmount,{once:!0})}connectedCallback(){if(!this.hasAttribute(\"await-children\")||document.readyState===\"interactive\"||document.readyState===\"complete\")this.childrenConnectedCallback();else{let e=()=>{document.removeEventListener(\"DOMContentLoaded\",e),n.disconnect(),this.childrenConnectedCallback()},n=new MutationObserver(()=>{var r;((r=this.lastChild)==null?void 0:r.nodeType)===Node.COMMENT_NODE&&this.lastChild.nodeValue===\"astro:end\"&&(this.lastChild.remove(),e())});n.observe(this,{childList:!0}),document.addEventListener(\"DOMContentLoaded\",e)}}async childrenConnectedCallback(){let e=this.getAttribute(\"before-hydration-url\");e&&await import(e),this.start()}async start(){let e=JSON.parse(this.getAttribute(\"opts\")),n=this.getAttribute(\"client\");if(Astro[n]===void 0){window.addEventListener(`astro:${n}`,()=>this.start(),{once:!0});return}try{await Astro[n](async()=>{let r=this.getAttribute(\"renderer-url\"),[l,{default:h}]=await Promise.all([import(this.getAttribute(\"component-url\")),r?import(r):()=>()=>{}]),p=this.getAttribute(\"component-export\")||\"default\";if(!p.includes(\".\"))this.Component=l[p];else{this.Component=l;for(let y of p.split(\".\"))this.Component=this.Component[y]}return this.hydrator=h,this.hydrate},e,this)}catch(r){console.error(`[astro-island] Error hydrating ${this.getAttribute(\"component-url\")}`,r)}}attributeChangedCallback(){this.hydrate()}},d(u,\"observedAttributes\",[\"props\"]),u))}})();";
7
7
  export default _default;
@@ -1,4 +1,4 @@
1
- var astro_island_prebuilt_default = `(()=>{var b=Object.defineProperty;var f=(c,s,a)=>s in c?b(c,s,{enumerable:!0,configurable:!0,writable:!0,value:a}):c[s]=a;var l=(c,s,a)=>(f(c,typeof s!="symbol"?s+"":s,a),a);var p;{let c={0:t=>m(t),1:t=>a(t),2:t=>new RegExp(t),3:t=>new Date(t),4:t=>new Map(a(t)),5:t=>new Set(a(t)),6:t=>BigInt(t),7:t=>new URL(t),8:t=>new Uint8Array(t),9:t=>new Uint16Array(t),10:t=>new Uint32Array(t)},s=t=>{let[e,r]=t;return e in c?c[e](r):void 0},a=t=>t.map(s),m=t=>typeof t!="object"||t===null?t:Object.fromEntries(Object.entries(t).map(([e,r])=>[e,s(r)]));customElements.get("astro-island")||customElements.define("astro-island",(p=class extends HTMLElement{constructor(){super(...arguments);l(this,"Component");l(this,"hydrator");l(this,"hydrate",async()=>{var d;if(!this.hydrator||!this.isConnected)return;let e=(d=this.parentElement)==null?void 0:d.closest("astro-island[ssr]");if(e){e.addEventListener("astro:hydrate",this.hydrate,{once:!0});return}let r=this.querySelectorAll("astro-slot"),o={},h=this.querySelectorAll("template[data-astro-template]");for(let n of h){let i=n.closest(this.tagName);i!=null&&i.isSameNode(this)&&(o[n.getAttribute("data-astro-template")||"default"]=n.innerHTML,n.remove())}for(let n of r){let i=n.closest(this.tagName);i!=null&&i.isSameNode(this)&&(o[n.getAttribute("name")||"default"]=n.innerHTML)}let u;try{u=this.hasAttribute("props")?m(JSON.parse(this.getAttribute("props"))):{}}catch(n){let i=this.getAttribute("component-url")||"<unknown>",y=this.getAttribute("component-export");throw y&&(i+=\` (export \${y})\`),console.error(\`[hydrate] Error parsing props for component \${i}\`,this.getAttribute("props"),n),n}await this.hydrator(this)(this.Component,u,o,{client:this.getAttribute("client")}),this.removeAttribute("ssr"),this.dispatchEvent(new CustomEvent("astro:hydrate"))});l(this,"unmount",()=>{this.isConnected||this.dispatchEvent(new CustomEvent("astro:unmount"))})}disconnectedCallback(){document.removeEventListener("astro:after-swap",this.unmount),document.addEventListener("astro:after-swap",this.unmount,{once:!0})}connectedCallback(){if(!this.hasAttribute("await-children")||document.readyState==="interactive"||document.readyState==="complete")this.childrenConnectedCallback();else{let e=()=>{document.removeEventListener("DOMContentLoaded",e),r.disconnect(),this.childrenConnectedCallback()},r=new MutationObserver(()=>{var o;((o=this.lastChild)==null?void 0:o.nodeType)===Node.COMMENT_NODE&&this.lastChild.nodeValue==="astro:end"&&(this.lastChild.remove(),e())});r.observe(this,{childList:!0}),document.addEventListener("DOMContentLoaded",e)}}async childrenConnectedCallback(){let e=this.getAttribute("before-hydration-url");e&&await import(e),this.start()}async start(){let e=JSON.parse(this.getAttribute("opts")),r=this.getAttribute("client");if(Astro[r]===void 0){window.addEventListener(\`astro:\${r}\`,()=>this.start(),{once:!0});return}try{await Astro[r](async()=>{let o=this.getAttribute("renderer-url"),[h,{default:u}]=await Promise.all([import(this.getAttribute("component-url")),o?import(o):()=>()=>{}]),d=this.getAttribute("component-export")||"default";if(!d.includes("."))this.Component=h[d];else{this.Component=h;for(let n of d.split("."))this.Component=this.Component[n]}return this.hydrator=u,this.hydrate},e,this)}catch(o){console.error(\`[astro-island] Error hydrating \${this.getAttribute("component-url")}\`,o)}}attributeChangedCallback(){this.hydrate()}},l(p,"observedAttributes",["props"]),p))}})();`;
1
+ var astro_island_prebuilt_default = `(()=>{var v=Object.defineProperty;var A=(c,s,a)=>s in c?v(c,s,{enumerable:!0,configurable:!0,writable:!0,value:a}):c[s]=a;var d=(c,s,a)=>(A(c,typeof s!="symbol"?s+"":s,a),a);var u;{let c={0:t=>m(t),1:t=>a(t),2:t=>new RegExp(t),3:t=>new Date(t),4:t=>new Map(a(t)),5:t=>new Set(a(t)),6:t=>BigInt(t),7:t=>new URL(t),8:t=>new Uint8Array(t),9:t=>new Uint16Array(t),10:t=>new Uint32Array(t)},s=t=>{let[e,n]=t;return e in c?c[e](n):void 0},a=t=>t.map(s),m=t=>typeof t!="object"||t===null?t:Object.fromEntries(Object.entries(t).map(([e,n])=>[e,s(n)]));customElements.get("astro-island")||customElements.define("astro-island",(u=class extends HTMLElement{constructor(){super(...arguments);d(this,"Component");d(this,"hydrator");d(this,"hydrate",async()=>{var f;if(!this.hydrator||!this.isConnected)return;let e=(f=this.parentElement)==null?void 0:f.closest("astro-island[ssr]");if(e){e.addEventListener("astro:hydrate",this.hydrate,{once:!0});return}let n=this.querySelectorAll("astro-slot"),r={},l=this.querySelectorAll("template[data-astro-template]");for(let o of l){let i=o.closest(this.tagName);i!=null&&i.isSameNode(this)&&(r[o.getAttribute("data-astro-template")||"default"]=o.innerHTML,o.remove())}for(let o of n){let i=o.closest(this.tagName);i!=null&&i.isSameNode(this)&&(r[o.getAttribute("name")||"default"]=o.innerHTML)}let h;try{h=this.hasAttribute("props")?m(JSON.parse(this.getAttribute("props"))):{}}catch(o){let i=this.getAttribute("component-url")||"<unknown>",b=this.getAttribute("component-export");throw b&&(i+=\` (export \${b})\`),console.error(\`[hydrate] Error parsing props for component \${i}\`,this.getAttribute("props"),o),o}let p;await this.hydrator(this)(this.Component,h,r,{client:this.getAttribute("client")}),this.removeAttribute("ssr"),this.dispatchEvent(new CustomEvent("astro:hydrate"))});d(this,"unmount",()=>{this.isConnected||this.dispatchEvent(new CustomEvent("astro:unmount"))})}disconnectedCallback(){document.removeEventListener("astro:after-swap",this.unmount),document.addEventListener("astro:after-swap",this.unmount,{once:!0})}connectedCallback(){if(!this.hasAttribute("await-children")||document.readyState==="interactive"||document.readyState==="complete")this.childrenConnectedCallback();else{let e=()=>{document.removeEventListener("DOMContentLoaded",e),n.disconnect(),this.childrenConnectedCallback()},n=new MutationObserver(()=>{var r;((r=this.lastChild)==null?void 0:r.nodeType)===Node.COMMENT_NODE&&this.lastChild.nodeValue==="astro:end"&&(this.lastChild.remove(),e())});n.observe(this,{childList:!0}),document.addEventListener("DOMContentLoaded",e)}}async childrenConnectedCallback(){let e=this.getAttribute("before-hydration-url");e&&await import(e),this.start()}async start(){let e=JSON.parse(this.getAttribute("opts")),n=this.getAttribute("client");if(Astro[n]===void 0){window.addEventListener(\`astro:\${n}\`,()=>this.start(),{once:!0});return}try{await Astro[n](async()=>{let r=this.getAttribute("renderer-url"),[l,{default:h}]=await Promise.all([import(this.getAttribute("component-url")),r?import(r):()=>()=>{}]),p=this.getAttribute("component-export")||"default";if(!p.includes("."))this.Component=l[p];else{this.Component=l;for(let y of p.split("."))this.Component=this.Component[y]}return this.hydrator=h,this.hydrate},e,this)}catch(r){console.error(\`[astro-island] Error hydrating \${this.getAttribute("component-url")}\`,r)}}attributeChangedCallback(){this.hydrate()}},d(u,"observedAttributes",["props"]),u))}})();`;
2
2
  export {
3
3
  astro_island_prebuilt_default as default
4
4
  };
@@ -1,5 +1,5 @@
1
1
  import { bold } from "kleur/colors";
2
- import { REROUTE_DIRECTIVE_HEADER } from "./consts.js";
2
+ import { REROUTABLE_STATUS_CODES, REROUTE_DIRECTIVE_HEADER } from "../../core/constants.js";
3
3
  async function renderEndpoint(mod, context, ssr, logger) {
4
4
  const { request, url } = context;
5
5
  const method = request.method.toUpperCase();
@@ -30,7 +30,7 @@ Found handlers: ${Object.keys(mod).map((exp) => JSON.stringify(exp)).join(", ")}
30
30
  return new Response(null, { status: 500 });
31
31
  }
32
32
  const response = await handler.call(mod, context);
33
- if (response.status === 404 || response.status === 500) {
33
+ if (REROUTABLE_STATUS_CODES.includes(response.status)) {
34
34
  response.headers.set(REROUTE_DIRECTIVE_HEADER, "no");
35
35
  }
36
36
  return response;
@@ -2,3 +2,4 @@ import type { RouteData, SSRResult } from '../../../../@types/astro.js';
2
2
  import type { AstroComponentFactory } from './factory.js';
3
3
  export declare function renderToString(result: SSRResult, componentFactory: AstroComponentFactory, props: any, children: any, isPage?: boolean, route?: RouteData): Promise<string | Response>;
4
4
  export declare function renderToReadableStream(result: SSRResult, componentFactory: AstroComponentFactory, props: any, children: any, isPage?: boolean, route?: RouteData): Promise<ReadableStream | Response>;
5
+ export declare function renderToAsyncIterable(result: SSRResult, componentFactory: AstroComponentFactory, props: any, children: any, isPage?: boolean, route?: RouteData): Promise<AsyncIterable<Uint8Array> | Response>;
@@ -2,6 +2,8 @@ import { AstroError, AstroErrorData } from "../../../../core/errors/index.js";
2
2
  import { chunkToByteArray, chunkToString, encoder } from "../common.js";
3
3
  import { isHeadAndContent } from "./head-and-content.js";
4
4
  import { isRenderTemplateResult } from "./render-template.js";
5
+ import { promiseWithResolvers } from "../util.js";
6
+ const DOCTYPE_EXP = /<!doctype html/i;
5
7
  async function renderToString(result, componentFactory, props, children, isPage = false, route) {
6
8
  const templateResult = await callComponentAsTemplateResultOrResponse(
7
9
  result,
@@ -18,7 +20,7 @@ async function renderToString(result, componentFactory, props, children, isPage
18
20
  write(chunk) {
19
21
  if (isPage && !renderedFirstPageChunk) {
20
22
  renderedFirstPageChunk = true;
21
- if (!result.partial && !/<!doctype html/i.test(String(chunk))) {
23
+ if (!result.partial && !DOCTYPE_EXP.test(String(chunk))) {
22
24
  const doctype = result.compressHTML ? "<!DOCTYPE html>" : "<!DOCTYPE html>\n";
23
25
  str += doctype;
24
26
  }
@@ -51,7 +53,7 @@ async function renderToReadableStream(result, componentFactory, props, children,
51
53
  write(chunk) {
52
54
  if (isPage && !renderedFirstPageChunk) {
53
55
  renderedFirstPageChunk = true;
54
- if (!result.partial && !/<!doctype html/i.test(String(chunk))) {
56
+ if (!result.partial && !DOCTYPE_EXP.test(String(chunk))) {
55
57
  const doctype = result.compressHTML ? "<!DOCTYPE html>" : "<!DOCTYPE html>\n";
56
58
  controller.enqueue(encoder.encode(doctype));
57
59
  }
@@ -109,7 +111,84 @@ async function bufferHeadContent(result) {
109
111
  }
110
112
  }
111
113
  }
114
+ async function renderToAsyncIterable(result, componentFactory, props, children, isPage = false, route) {
115
+ const templateResult = await callComponentAsTemplateResultOrResponse(
116
+ result,
117
+ componentFactory,
118
+ props,
119
+ children,
120
+ route
121
+ );
122
+ if (templateResult instanceof Response)
123
+ return templateResult;
124
+ let renderedFirstPageChunk = false;
125
+ if (isPage) {
126
+ await bufferHeadContent(result);
127
+ }
128
+ let error = null;
129
+ let next = promiseWithResolvers();
130
+ const buffer = [];
131
+ const iterator = {
132
+ async next() {
133
+ await next.promise;
134
+ if (error) {
135
+ throw error;
136
+ }
137
+ let length = 0;
138
+ for (let i = 0, len = buffer.length; i < len; i++) {
139
+ length += buffer[i].length;
140
+ }
141
+ let mergedArray = new Uint8Array(length);
142
+ let offset = 0;
143
+ for (let i = 0, len = buffer.length; i < len; i++) {
144
+ const item = buffer[i];
145
+ mergedArray.set(item, offset);
146
+ offset += item.length;
147
+ }
148
+ buffer.length = 0;
149
+ const returnValue = {
150
+ // The iterator is done if there are no chunks to return.
151
+ done: length === 0,
152
+ value: mergedArray
153
+ };
154
+ return returnValue;
155
+ }
156
+ };
157
+ const destination = {
158
+ write(chunk) {
159
+ if (isPage && !renderedFirstPageChunk) {
160
+ renderedFirstPageChunk = true;
161
+ if (!result.partial && !DOCTYPE_EXP.test(String(chunk))) {
162
+ const doctype = result.compressHTML ? "<!DOCTYPE html>" : "<!DOCTYPE html>\n";
163
+ buffer.push(encoder.encode(doctype));
164
+ }
165
+ }
166
+ if (chunk instanceof Response) {
167
+ throw new AstroError(AstroErrorData.ResponseSentError);
168
+ }
169
+ const bytes = chunkToByteArray(result, chunk);
170
+ if (bytes.length > 0) {
171
+ buffer.push(bytes);
172
+ next.resolve();
173
+ next = promiseWithResolvers();
174
+ }
175
+ }
176
+ };
177
+ const renderPromise = templateResult.render(destination);
178
+ renderPromise.then(() => {
179
+ next.resolve();
180
+ }).catch((err) => {
181
+ error = err;
182
+ next.resolve();
183
+ });
184
+ return {
185
+ [Symbol.asyncIterator]() {
186
+ return iterator;
187
+ }
188
+ };
189
+ }
112
190
  export {
191
+ renderToAsyncIterable,
113
192
  renderToReadableStream,
114
193
  renderToString
115
194
  };
@@ -138,6 +138,7 @@ Did you forget to import the component or is it possible there is a typo?`
138
138
  )[0];
139
139
  }
140
140
  }
141
+ let componentServerRenderEndTime;
141
142
  if (!renderer) {
142
143
  if (metadata.hydrate === "only") {
143
144
  throw new AstroError({
@@ -192,6 +193,7 @@ If you're still stuck, please open an issue on GitHub or join us at https://astr
192
193
  if (metadata.hydrate === "only") {
193
194
  html = await renderSlotToString(result, slots?.fallback);
194
195
  } else {
196
+ const componentRenderStartTime = performance.now();
195
197
  ({ html, attrs } = await renderer.ssr.renderToStaticMarkup.call(
196
198
  { result },
197
199
  Component,
@@ -199,6 +201,8 @@ If you're still stuck, please open an issue on GitHub or join us at https://astr
199
201
  children,
200
202
  metadata
201
203
  ));
204
+ if (process.env.NODE_ENV === "development")
205
+ componentServerRenderEndTime = performance.now() - componentRenderStartTime;
202
206
  }
203
207
  }
204
208
  if (renderer && !renderer.clientEntrypoint && renderer.name !== "@astrojs/lit" && metadata.hydrate) {
@@ -261,6 +265,8 @@ ${serializeProps(
261
265
  { renderer, result, astroId, props, attrs },
262
266
  metadata
263
267
  );
268
+ if (componentServerRenderEndTime && process.env.NODE_ENV === "development")
269
+ island.props["server-render-time"] = componentServerRenderEndTime;
264
270
  let unrenderedSlots = [];
265
271
  if (html) {
266
272
  if (Object.keys(children).length > 0) {
@@ -1,7 +1,8 @@
1
1
  import { renderComponentToString } from "./component.js";
2
2
  import { isAstroComponentFactory } from "./astro/index.js";
3
- import { renderToReadableStream, renderToString } from "./astro/render.js";
3
+ import { renderToReadableStream, renderToString, renderToAsyncIterable } from "./astro/render.js";
4
4
  import { encoder } from "./common.js";
5
+ import { isNode } from "./util.js";
5
6
  async function renderPage(result, componentFactory, props, children, streaming, route) {
6
7
  if (!isAstroComponentFactory(componentFactory)) {
7
8
  result._metadata.headInTree = result.componentMetadata.get(componentFactory.moduleId)?.containsHead ?? false;
@@ -26,7 +27,19 @@ async function renderPage(result, componentFactory, props, children, streaming,
26
27
  result._metadata.headInTree = result.componentMetadata.get(componentFactory.moduleId)?.containsHead ?? false;
27
28
  let body;
28
29
  if (streaming) {
29
- body = await renderToReadableStream(result, componentFactory, props, children, true, route);
30
+ if (isNode) {
31
+ const nodeBody = await renderToAsyncIterable(
32
+ result,
33
+ componentFactory,
34
+ props,
35
+ children,
36
+ true,
37
+ route
38
+ );
39
+ body = nodeBody;
40
+ } else {
41
+ body = await renderToReadableStream(result, componentFactory, props, children, true, route);
42
+ }
30
43
  } else {
31
44
  body = await renderToString(result, componentFactory, props, children, true, route);
32
45
  }
@@ -29,3 +29,10 @@ export declare function renderElement(name: string, { props: _props, children }:
29
29
  export declare function renderToBufferDestination(bufferRenderFunction: RenderFunction): {
30
30
  renderToFinalDestination: RenderFunction;
31
31
  };
32
+ export declare const isNode: boolean;
33
+ export type PromiseWithResolvers<T> = {
34
+ promise: Promise<T>;
35
+ resolve: (value: T) => void;
36
+ reject: (reason?: any) => void;
37
+ };
38
+ export declare function promiseWithResolvers<T = any>(): PromiseWithResolvers<T>;
@@ -116,11 +116,26 @@ function renderToBufferDestination(bufferRenderFunction) {
116
116
  }
117
117
  };
118
118
  }
119
+ const isNode = typeof process !== "undefined" && Object.prototype.toString.call(process) === "[object process]";
120
+ function promiseWithResolvers() {
121
+ let resolve, reject;
122
+ const promise = new Promise((_resolve, _reject) => {
123
+ resolve = _resolve;
124
+ reject = _reject;
125
+ });
126
+ return {
127
+ promise,
128
+ resolve,
129
+ reject
130
+ };
131
+ }
119
132
  export {
120
133
  addAttribute,
121
134
  defineScriptVars,
122
135
  formatList,
123
136
  internalSpreadAttributes,
137
+ isNode,
138
+ promiseWithResolvers,
124
139
  renderElement,
125
140
  renderToBufferDestination,
126
141
  toAttributeString,
@@ -1,4 +1,5 @@
1
1
  import islandScript from "./astro-island.prebuilt.js";
2
+ import islandScriptDev from "./astro-island.prebuilt-dev.js";
2
3
  const ISLAND_STYLES = `<style>astro-island,astro-slot,astro-static-slot{display:contents}</style>`;
3
4
  function determineIfNeedsHydrationScript(result) {
4
5
  if (result._metadata.hasHydrationScript) {
@@ -24,10 +25,7 @@ function getDirectiveScriptText(result, directive) {
24
25
  function getPrescripts(result, type, directive) {
25
26
  switch (type) {
26
27
  case "both":
27
- return `${ISLAND_STYLES}<script>${getDirectiveScriptText(
28
- result,
29
- directive
30
- )};${islandScript}</script>`;
28
+ return `${ISLAND_STYLES}<script>${getDirectiveScriptText(result, directive)};${process.env.NODE_ENV === "development" ? islandScriptDev : islandScript}</script>`;
31
29
  case "directive":
32
30
  return `<script>${getDirectiveScriptText(result, directive)}</script>`;
33
31
  case null:
@@ -29,11 +29,24 @@ const addPairs = (animations, stylesheet) => {
29
29
  }
30
30
  }
31
31
  };
32
+ const reEncodeValidChars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_".split("").reduce((v, c) => (v[c.charCodeAt(0)] = c, v), []);
33
+ const reEncodeInValidStart = "-0123456789_".split("").reduce((v, c) => (v[c.charCodeAt(0)] = c, v), []);
34
+ function reEncode(s) {
35
+ let result = "";
36
+ let codepoint;
37
+ for (let i = 0; i < s.length; i += (codepoint ?? 0) > 65535 ? 2 : 1) {
38
+ codepoint = s.codePointAt(i);
39
+ if (codepoint !== void 0) {
40
+ result += codepoint < 128 ? codepoint === 95 ? "__" : reEncodeValidChars[codepoint] ?? "_" + codepoint.toString(16).padStart(2, "0") : String.fromCodePoint(codepoint);
41
+ }
42
+ }
43
+ return reEncodeInValidStart[result.codePointAt(0) ?? 0] ? "_" + result : result;
44
+ }
32
45
  function renderTransition(result, hash, animationName, transitionName) {
33
46
  if (!animationName)
34
47
  animationName = "fade";
35
48
  const scope = createTransitionScope(result, hash);
36
- const name = transitionName ? cssesc(transitionName, { isIdentifier: true }) : scope;
49
+ const name = transitionName ? cssesc(reEncode(transitionName), { isIdentifier: true }) : scope;
37
50
  const sheet = new ViewTransitionStyleSheet(scope, name);
38
51
  const animations = getAnimations(animationName);
39
52
  if (animations) {
@@ -9,3 +9,4 @@ export interface HandleHotUpdateOptions {
9
9
  astroFileToCompileMetadata: Map<string, CompileMetadata>;
10
10
  }
11
11
  export declare function handleHotUpdate(ctx: HmrContext, { logger, compile, astroFileToCssAstroDeps, astroFileToCompileMetadata }: HandleHotUpdateOptions): Promise<import("vite").ModuleNode[] | undefined>;
12
+ export declare function isStyleOnlyChanged(oldCode: string, newCode: string): boolean;
@@ -18,7 +18,7 @@ async function handleHotUpdate(ctx, { logger, compile, astroFileToCssAstroDeps,
18
18
  ctx.server.moduleGraph.invalidateModule(mod);
19
19
  }
20
20
  }
21
- ctx.server.ws.send({ type: "full-reload", path: "*" });
21
+ ctx.server.hot.send({ type: "full-reload", path: "*" });
22
22
  }
23
23
  }
24
24
  }
@@ -41,8 +41,10 @@ function isStyleOnlyChanged(oldCode, newCode) {
41
41
  return false;
42
42
  const oldStyles = [];
43
43
  const newStyles = [];
44
- oldCode.match(styleRE)?.forEach((m) => oldStyles.push(m));
45
- newCode.match(styleRE)?.forEach((m) => newStyles.push(m));
44
+ oldCode = oldCode.replace(styleRE, (m) => (oldStyles.push(m), ""));
45
+ newCode = newCode.replace(styleRE, (m) => (newStyles.push(m), ""));
46
+ if (oldCode !== newCode)
47
+ return false;
46
48
  return oldStyles.length === newStyles.length && !isArrayEqual(oldStyles, newStyles);
47
49
  }
48
50
  function isArrayEqual(a, b) {
@@ -60,5 +62,6 @@ function getShortName(file, root) {
60
62
  return file.startsWith(appendForwardSlash(root)) ? path.posix.relative(root, file) : file;
61
63
  }
62
64
  export {
63
- handleHotUpdate
65
+ handleHotUpdate,
66
+ isStyleOnlyChanged
64
67
  };
@@ -1,7 +1,7 @@
1
1
  import type { ModuleLoader } from '../core/module-loader/index.js';
2
2
  import type { AstroConfig } from '../@types/astro.js';
3
- import type DevPipeline from './devPipeline.js';
4
- export declare function recordServerError(loader: ModuleLoader, config: AstroConfig, pipeline: DevPipeline, _err: unknown): {
3
+ import type { DevPipeline } from './pipeline.js';
4
+ export declare function recordServerError(loader: ModuleLoader, config: AstroConfig, { logger }: DevPipeline, _err: unknown): {
5
5
  error: Error;
6
6
  errorWithMetadata: import("../core/errors/errors.js").ErrorWithMetadata;
7
7
  };
@@ -2,7 +2,7 @@ import { collectErrorMetadata } from "../core/errors/dev/index.js";
2
2
  import { createSafeError, AstroErrorData } from "../core/errors/index.js";
3
3
  import { formatErrorMessage } from "../core/messages.js";
4
4
  import { eventError, telemetry } from "../events/index.js";
5
- function recordServerError(loader, config, pipeline, _err) {
5
+ function recordServerError(loader, config, { logger }, _err) {
6
6
  const err = createSafeError(_err);
7
7
  try {
8
8
  loader.fixStacktrace(err);
@@ -12,10 +12,7 @@ function recordServerError(loader, config, pipeline, _err) {
12
12
  if (errorWithMetadata.name !== AstroErrorData.UnhandledRejection.name) {
13
13
  telemetry.record(eventError({ cmd: "dev", err: errorWithMetadata, isFatal: false }));
14
14
  }
15
- pipeline.logger.error(
16
- null,
17
- formatErrorMessage(errorWithMetadata, pipeline.logger.level() === "debug")
18
- );
15
+ logger.error(null, formatErrorMessage(errorWithMetadata, logger.level() === "debug"));
19
16
  return {
20
17
  error: err,
21
18
  errorWithMetadata
@@ -1,9 +1,3 @@
1
- import type { ComponentInstance } from '../@types/astro.js';
2
- import type DevPipeline from './devPipeline.js';
3
- export declare function preload({ pipeline, filePath, }: {
4
- pipeline: DevPipeline;
5
- filePath: URL;
6
- }): Promise<ComponentInstance>;
7
1
  export { createController, runWithErrorHandling } from './controller.js';
8
2
  export { default as vitePluginAstroServer } from './plugin.js';
9
3
  export { handleRequest } from './request.js';
@@ -1,28 +1,9 @@
1
- import { enhanceViteSSRError } from "../core/errors/dev/index.js";
2
- import { AggregateError, CSSError, MarkdownError } from "../core/errors/index.js";
3
- import { viteID } from "../core/util.js";
4
- async function preload({
5
- pipeline,
6
- filePath
7
- }) {
8
- await pipeline.loadRenderers();
9
- try {
10
- const mod = await pipeline.getModuleLoader().import(viteID(filePath));
11
- return mod;
12
- } catch (error) {
13
- if (MarkdownError.is(error) || CSSError.is(error) || AggregateError.is(error)) {
14
- throw error;
15
- }
16
- throw enhanceViteSSRError({ error, filePath, loader: pipeline.getModuleLoader() });
17
- }
18
- }
19
1
  import { createController, runWithErrorHandling } from "./controller.js";
20
2
  import { default as default2 } from "./plugin.js";
21
3
  import { handleRequest } from "./request.js";
22
4
  export {
23
5
  createController,
24
6
  handleRequest,
25
- preload,
26
7
  runWithErrorHandling,
27
8
  default2 as vitePluginAstroServer
28
9
  };