astro 1.0.0-beta.52 → 1.0.0-beta.55

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.
package/dist/cli/index.js CHANGED
@@ -40,7 +40,7 @@ function printAstroHelp() {
40
40
  });
41
41
  }
42
42
  async function printVersion() {
43
- const version = "1.0.0-beta.52";
43
+ const version = "1.0.0-beta.55";
44
44
  console.log();
45
45
  console.log(` ${colors.bgGreen(colors.black(` astro `))} ${colors.green(`v${version}`)}`);
46
46
  }
@@ -83,7 +83,7 @@ async function cli(args) {
83
83
  } else if (flags.silent) {
84
84
  logging.level = "silent";
85
85
  }
86
- const telemetry = new AstroTelemetry({ version: "1.0.0-beta.52" });
86
+ const telemetry = new AstroTelemetry({ version: "1.0.0-beta.55" });
87
87
  if (cmd === "telemetry") {
88
88
  try {
89
89
  const subcommand = (_a = flags._[3]) == null ? void 0 : _a.toString();
@@ -97,7 +97,7 @@ async function cli(args) {
97
97
  try {
98
98
  const packages = flags._.slice(3);
99
99
  telemetry.record(event.eventCliSession({
100
- astroVersion: "1.0.0-beta.52",
100
+ astroVersion: "1.0.0-beta.55",
101
101
  cliCommand: "add"
102
102
  }));
103
103
  return await add(packages, { cwd: root, flags, logging, telemetry });
@@ -108,7 +108,7 @@ async function cli(args) {
108
108
  case "dev": {
109
109
  try {
110
110
  const { astroConfig, userConfig } = await openConfig({ cwd: root, flags, cmd });
111
- telemetry.record(event.eventCliSession({ astroVersion: "1.0.0-beta.52", cliCommand: "dev" }, userConfig, flags));
111
+ telemetry.record(event.eventCliSession({ astroVersion: "1.0.0-beta.55", cliCommand: "dev" }, userConfig, flags));
112
112
  await devServer(astroConfig, { logging, telemetry });
113
113
  return await new Promise(() => {
114
114
  });
@@ -119,7 +119,7 @@ async function cli(args) {
119
119
  case "build": {
120
120
  try {
121
121
  const { astroConfig, userConfig } = await openConfig({ cwd: root, flags, cmd });
122
- telemetry.record(event.eventCliSession({ astroVersion: "1.0.0-beta.52", cliCommand: "build" }, userConfig, flags));
122
+ telemetry.record(event.eventCliSession({ astroVersion: "1.0.0-beta.55", cliCommand: "build" }, userConfig, flags));
123
123
  return await build(astroConfig, { logging, telemetry });
124
124
  } catch (err) {
125
125
  return throwAndExit(err);
@@ -127,14 +127,14 @@ async function cli(args) {
127
127
  }
128
128
  case "check": {
129
129
  const { astroConfig, userConfig } = await openConfig({ cwd: root, flags, cmd });
130
- telemetry.record(event.eventCliSession({ astroVersion: "1.0.0-beta.52", cliCommand: "check" }, userConfig, flags));
130
+ telemetry.record(event.eventCliSession({ astroVersion: "1.0.0-beta.55", cliCommand: "check" }, userConfig, flags));
131
131
  const ret = await check(astroConfig);
132
132
  return process.exit(ret);
133
133
  }
134
134
  case "preview": {
135
135
  try {
136
136
  const { astroConfig, userConfig } = await openConfig({ cwd: root, flags, cmd });
137
- telemetry.record(event.eventCliSession({ astroVersion: "1.0.0-beta.52", cliCommand: "preview" }, userConfig, flags));
137
+ telemetry.record(event.eventCliSession({ astroVersion: "1.0.0-beta.55", cliCommand: "preview" }, userConfig, flags));
138
138
  const server = await preview(astroConfig, { logging, telemetry });
139
139
  return await server.closed();
140
140
  } catch (err) {
@@ -144,7 +144,7 @@ async function cli(args) {
144
144
  case "docs": {
145
145
  try {
146
146
  await telemetry.record(event.eventCliSession({
147
- astroVersion: "1.0.0-beta.52",
147
+ astroVersion: "1.0.0-beta.55",
148
148
  cliCommand: "docs"
149
149
  }));
150
150
  return await openInBrowser("https://docs.astro.build/");
@@ -289,7 +289,7 @@ async function getInstallIntegrationsCommand({
289
289
  debug("add", `package manager: ${JSON.stringify(pm)}`);
290
290
  if (!pm)
291
291
  return null;
292
- let dependencies = integrations.map((i) => [[i.packageName, null], ...i.dependencies]).flat(1).filter((dep, i, arr) => arr.findIndex((d) => d[0] === dep[0]) === i).map(([name, version]) => version === null ? name : `${name}@${version}`).sort();
292
+ let dependencies = integrations.map((i) => [[i.packageName, null], ...i.dependencies]).flat(1).filter((dep, i, arr) => arr.findIndex((d) => d[0] === dep[0]) === i).map(([name, version]) => version === null ? name : `${name}@${version.split(/\s*\|\|\s*/).pop()}`).sort();
293
293
  switch (pm.name) {
294
294
  case "npm":
295
295
  return { pm: "npm", command: "install", flags: ["--save-dev"], dependencies };
@@ -105,7 +105,7 @@ renderPage_fn = async function(request, routeData, mod) {
105
105
  scripts.add(createModuleScriptElement(script, manifest.site));
106
106
  }
107
107
  }
108
- const result = await render({
108
+ const response = await render({
109
109
  links,
110
110
  logging: __privateGet(this, _logging),
111
111
  markdown: manifest.markdown,
@@ -127,16 +127,7 @@ renderPage_fn = async function(request, routeData, mod) {
127
127
  ssr: true,
128
128
  request
129
129
  });
130
- if (result.type === "response") {
131
- return result.response;
132
- }
133
- let html = result.html;
134
- let init = result.response;
135
- let headers = init.headers;
136
- let bytes = __privateGet(this, _encoder).encode(html);
137
- headers.set("Content-Type", "text/html");
138
- headers.set("Content-Length", bytes.byteLength.toString());
139
- return new Response(bytes, init);
130
+ return response;
140
131
  };
141
132
  _callEndpoint = new WeakSet();
142
133
  callEndpoint_fn = async function(request, routeData, mod) {
@@ -155,11 +155,11 @@ async function generatePath(pathname, opts, gopts) {
155
155
  }
156
156
  body = result.body;
157
157
  } else {
158
- const result = await render(options);
159
- if (result.type !== "html") {
158
+ const response = await render(options);
159
+ if (response.status !== 200 || !response.body) {
160
160
  return;
161
161
  }
162
- body = result.html;
162
+ body = await response.text();
163
163
  }
164
164
  const outFolder = getOutFolder(astroConfig, pathname, pageData.route.type);
165
165
  const outFile = getOutFile(astroConfig, outFolder, pathname, pageData.route.type);
@@ -98,12 +98,13 @@ async function ssrBuild(opts, internals, input) {
98
98
  outDir: fileURLToPath(out),
99
99
  rollupOptions: {
100
100
  input: [],
101
- output: __spreadValues({
101
+ output: __spreadProps(__spreadValues({
102
102
  format: "esm",
103
- entryFileNames: opts.buildConfig.serverEntry,
104
103
  chunkFileNames: "chunks/[name].[hash].mjs",
105
104
  assetFileNames: "assets/[name].[hash][extname]"
106
- }, (_d = (_c = viteConfig.build) == null ? void 0 : _c.rollupOptions) == null ? void 0 : _d.output)
105
+ }, (_d = (_c = viteConfig.build) == null ? void 0 : _c.rollupOptions) == null ? void 0 : _d.output), {
106
+ entryFileNames: opts.buildConfig.serverEntry
107
+ })
107
108
  },
108
109
  ssr: true,
109
110
  target: "esnext",
@@ -11,7 +11,7 @@ function vitePluginAnalyzer(astroConfig, internals) {
11
11
  var _a;
12
12
  const hoistedScripts = /* @__PURE__ */ new Set();
13
13
  for (let i = 0; i < scripts.length; i++) {
14
- const hid = `${from.replace("/@fs", "")}?astro&type=script&index=${i}`;
14
+ const hid = `${from.replace("/@fs", "")}?astro&type=script&index=${i}&lang.ts`;
15
15
  hoistedScripts.add(hid);
16
16
  }
17
17
  if (hoistedScripts.size) {
@@ -47,7 +47,7 @@ async function dev(config, options) {
47
47
  site,
48
48
  https: !!((_a = viteConfig.server) == null ? void 0 : _a.https)
49
49
  }));
50
- const currentVersion = "1.0.0-beta.52";
50
+ const currentVersion = "1.0.0-beta.55";
51
51
  if (currentVersion.includes("-")) {
52
52
  warn(options.logging, null, msg.prerelease({ currentVersion }));
53
53
  }
@@ -74,7 +74,7 @@ function timerMessage(message, startTime = Date.now()) {
74
74
  function warnIfUsingExperimentalSSR(opts, config) {
75
75
  var _a;
76
76
  if ((_a = config._ctx.adapter) == null ? void 0 : _a.serverEntrypoint) {
77
- warn(opts, "warning", bold(`Warning:`), `SSR support is still experimental and subject to API changes. If using in production pin your dependencies to prevent accidental breakage.`);
77
+ warn(opts, "warning", bold(`Warning:`), `SSR support is still experimental and subject to API changes. If using in production, pin your dependencies to prevent accidental breakage.`);
78
78
  }
79
79
  }
80
80
  export {
@@ -47,7 +47,7 @@ function devStart({
47
47
  https,
48
48
  site
49
49
  }) {
50
- const version = "1.0.0-beta.52";
50
+ const version = "1.0.0-beta.55";
51
51
  const rootPath = site ? site.pathname : "/";
52
52
  const localPrefix = `${dim("\u2503")} Local `;
53
53
  const networkPrefix = `${dim("\u2503")} Network `;
@@ -207,7 +207,7 @@ function printHelp({
207
207
  };
208
208
  let message = [];
209
209
  if (headline) {
210
- message.push(linebreak(), ` ${bgGreen(black(` ${commandName} `))} ${green(`v${"1.0.0-beta.52"}`)} ${headline}`);
210
+ message.push(linebreak(), ` ${bgGreen(black(` ${commandName} `))} ${green(`v${"1.0.0-beta.55"}`)} ${headline}`);
211
211
  }
212
212
  if (usage) {
213
213
  message.push(linebreak(), ` ${green(commandName)} ${bold(usage)}`);
@@ -17,7 +17,7 @@ var __spreadValues = (a, b) => {
17
17
  return a;
18
18
  };
19
19
  var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
20
- import { renderComponent, renderHead, renderPage } from "../../runtime/server/index.js";
20
+ import { renderComponent, renderPage } from "../../runtime/server/index.js";
21
21
  import { getParams } from "../routing/params.js";
22
22
  import { createResult } from "./result.js";
23
23
  import { callGetStaticPaths, findPathItemByKey } from "./route-cache.js";
@@ -100,33 +100,13 @@ async function render(opts) {
100
100
  scripts,
101
101
  ssr
102
102
  });
103
- let page;
104
103
  if (!Component.isAstroComponentFactory) {
105
104
  const props = __spreadProps(__spreadValues({}, pageProps ?? {}), { "server:root": true });
106
- const html2 = await renderComponent(result, Component.name, Component, props, null);
107
- page = {
108
- type: "html",
109
- html: html2.toString()
110
- };
105
+ const html = await renderComponent(result, Component.name, Component, props, null);
106
+ return new Response(html.toString(), result.response);
111
107
  } else {
112
- page = await renderPage(result, Component, pageProps, null);
108
+ return await renderPage(result, Component, pageProps, null);
113
109
  }
114
- if (page.type === "response") {
115
- return page;
116
- }
117
- let html = page.html;
118
- if (html.indexOf("<!--astro:head:injected-->") == -1) {
119
- html = await renderHead(result) + html;
120
- }
121
- html = html.replace("<!--astro:head:injected-->", "");
122
- if (!/<!doctype html/i.test(html)) {
123
- html = "<!DOCTYPE html>\n" + html;
124
- }
125
- return {
126
- type: "html",
127
- html,
128
- response: result.response
129
- };
130
110
  }
131
111
  export {
132
112
  GetParamsAndPropsError,
@@ -24,7 +24,6 @@ import { render as coreRender } from "../core.js";
24
24
  import { createModuleScriptElementWithSrcSet } from "../ssr-element.js";
25
25
  import { collectMdMetadata } from "../util.js";
26
26
  import { getStylesForURL } from "./css.js";
27
- import { injectTags } from "./html.js";
28
27
  import { resolveClientDevPath } from "./resolve.js";
29
28
  const svelteStylesRE = /svelte\?svelte&type=style/;
30
29
  async function loadRenderer(viteServer, renderer) {
@@ -100,15 +99,15 @@ async function render(renderers, mod, ssrOpts) {
100
99
  });
101
100
  });
102
101
  let styles = /* @__PURE__ */ new Set();
103
- [...stylesMap].forEach(([url, content2]) => {
102
+ [...stylesMap].forEach(([url, content]) => {
104
103
  styles.add({
105
104
  props: {
106
105
  "data-astro-injected": svelteStylesRE.test(url) ? url : true
107
106
  },
108
- children: content2
107
+ children: content
109
108
  });
110
109
  });
111
- let content = await coreRender({
110
+ let response = await coreRender({
112
111
  links,
113
112
  styles,
114
113
  logging,
@@ -130,19 +129,7 @@ async function render(renderers, mod, ssrOpts) {
130
129
  site: astroConfig.site ? new URL(astroConfig.base, astroConfig.site).toString() : void 0,
131
130
  ssr: isBuildingToSSR(astroConfig)
132
131
  });
133
- if ((route == null ? void 0 : route.type) === "endpoint" || content.type === "response") {
134
- return content;
135
- }
136
- const tags = [];
137
- let html = injectTags(content.html, tags);
138
- if (!/<!doctype html/i.test(html)) {
139
- html = "<!DOCTYPE html>\n" + content;
140
- }
141
- return {
142
- type: "html",
143
- html,
144
- response: content.response
145
- };
132
+ return response;
146
133
  }
147
134
  async function ssr(preloadedComponent, ssrOpts) {
148
135
  const [renderers, mod] = preloadedComponent;
@@ -114,10 +114,12 @@ function createResult(args) {
114
114
  const paginated = isPaginatedRoute(pageProps);
115
115
  const url = new URL(request.url);
116
116
  const canonicalURL = createCanonicalURL("." + pathname, site ?? url.origin, paginated);
117
+ const headers = new Headers();
118
+ headers.set("Transfer-Encoding", "chunked");
117
119
  const response = {
118
120
  status: 200,
119
121
  statusText: "OK",
120
- headers: new Headers()
122
+ headers
121
123
  };
122
124
  Object.defineProperty(response, "headers", {
123
125
  value: response.headers,
@@ -138,7 +140,7 @@ function createResult(args) {
138
140
  request,
139
141
  redirect: args.ssr ? (path) => {
140
142
  return new Response(null, {
141
- status: 301,
143
+ status: 302,
142
144
  headers: {
143
145
  Location: path
144
146
  }
@@ -190,7 +192,6 @@ ${extra}`);
190
192
  },
191
193
  resolve,
192
194
  _metadata: {
193
- needsHydrationStyles: false,
194
195
  renderers,
195
196
  pathname
196
197
  },
@@ -21,23 +21,26 @@ var _a;
21
21
  constructor() {
22
22
  super(...arguments);
23
23
  this.hydrate = () => {
24
- var _a2;
24
+ var _a2, _b, _c;
25
25
  if (!this.hydrator || ((_a2 = this.parentElement) == null ? void 0 : _a2.closest("astro-island[ssr]"))) {
26
26
  return;
27
27
  }
28
- let innerHTML = null;
29
- let fragment = this.querySelector("astro-fragment");
30
- if (fragment == null && this.hasAttribute("tmpl")) {
31
- let template = this.querySelector("template[data-astro-template]");
32
- if (template) {
33
- innerHTML = template.innerHTML;
34
- template.remove();
35
- }
36
- } else if (fragment) {
37
- innerHTML = fragment.innerHTML;
28
+ const slotted = this.querySelectorAll("astro-slot");
29
+ const slots = {};
30
+ const templates = this.querySelectorAll("template[data-astro-template]");
31
+ for (const template of templates) {
32
+ if (!((_b = template.closest(this.tagName)) == null ? void 0 : _b.isSameNode(this)))
33
+ continue;
34
+ slots[template.getAttribute("data-astro-template") || "default"] = template.innerHTML;
35
+ template.remove();
36
+ }
37
+ for (const slot of slotted) {
38
+ if (!((_c = slot.closest(this.tagName)) == null ? void 0 : _c.isSameNode(this)))
39
+ continue;
40
+ slots[slot.getAttribute("name") || "default"] = slot.innerHTML;
38
41
  }
39
42
  const props = this.hasAttribute("props") ? JSON.parse(this.getAttribute("props"), reviver) : {};
40
- this.hydrator(this)(this.Component, props, innerHTML, {
43
+ this.hydrator(this)(this.Component, props, slots, {
41
44
  client: this.getAttribute("client")
42
45
  });
43
46
  this.removeAttribute("ssr");
@@ -1,4 +1,4 @@
1
- var astro_island_prebuilt_default = `var o;{const a={0:t=>t,1:t=>JSON.parse(t,n),2:t=>new RegExp(t),3:t=>new Date(t),4:t=>new Map(JSON.parse(t,n)),5:t=>new Set(JSON.parse(t,n)),6:t=>BigInt(t),7:t=>new URL(t)},n=(t,e)=>{if(t===""||!Array.isArray(e))return e;const[r,s]=e;return r in a?a[r](s):void 0};customElements.get("astro-island")||customElements.define("astro-island",(o=class extends HTMLElement{constructor(){super(...arguments);this.hydrate=()=>{if(!this.hydrator||this.parentElement?.closest("astro-island[ssr]"))return;let e=null,r=this.querySelector("astro-fragment");if(r==null&&this.hasAttribute("tmpl")){let i=this.querySelector("template[data-astro-template]");i&&(e=i.innerHTML,i.remove())}else r&&(e=r.innerHTML);const s=this.hasAttribute("props")?JSON.parse(this.getAttribute("props"),n):{};this.hydrator(this)(this.Component,s,e,{client:this.getAttribute("client")}),this.removeAttribute("ssr"),window.removeEventListener("astro:hydrate",this.hydrate),window.dispatchEvent(new CustomEvent("astro:hydrate"))}}async connectedCallback(){window.addEventListener("astro:hydrate",this.hydrate),await import(this.getAttribute("before-hydration-url"));const e=JSON.parse(this.getAttribute("opts"));Astro[this.getAttribute("client")](async()=>{const r=this.getAttribute("renderer-url"),[s,{default:i}]=await Promise.all([import(this.getAttribute("component-url")),r?import(r):()=>()=>{}]);return this.Component=s[this.getAttribute("component-export")||"default"],this.hydrator=i,this.hydrate},e,this)}attributeChangedCallback(){this.hydrator&&this.hydrate()}},o.observedAttributes=["props"],o))}`;
1
+ var astro_island_prebuilt_default = `var a;{const l={0:t=>t,1:t=>JSON.parse(t,o),2:t=>new RegExp(t),3:t=>new Date(t),4:t=>new Map(JSON.parse(t,o)),5:t=>new Set(JSON.parse(t,o)),6:t=>BigInt(t),7:t=>new URL(t)},o=(t,s)=>{if(t===""||!Array.isArray(s))return s;const[e,i]=s;return e in l?l[e](i):void 0};customElements.get("astro-island")||customElements.define("astro-island",(a=class extends HTMLElement{constructor(){super(...arguments);this.hydrate=()=>{if(!this.hydrator||this.parentElement?.closest("astro-island[ssr]"))return;const s=this.querySelectorAll("astro-slot"),e={},i=this.querySelectorAll("template[data-astro-template]");for(const r of i)!r.closest(this.tagName)?.isSameNode(this)||(e[r.getAttribute("data-astro-template")||"default"]=r.innerHTML,r.remove());for(const r of s)!r.closest(this.tagName)?.isSameNode(this)||(e[r.getAttribute("name")||"default"]=r.innerHTML);const n=this.hasAttribute("props")?JSON.parse(this.getAttribute("props"),o):{};this.hydrator(this)(this.Component,n,e,{client:this.getAttribute("client")}),this.removeAttribute("ssr"),window.removeEventListener("astro:hydrate",this.hydrate),window.dispatchEvent(new CustomEvent("astro:hydrate"))}}async connectedCallback(){window.addEventListener("astro:hydrate",this.hydrate),await import(this.getAttribute("before-hydration-url"));const s=JSON.parse(this.getAttribute("opts"));Astro[this.getAttribute("client")](async()=>{const e=this.getAttribute("renderer-url"),[i,{default:n}]=await Promise.all([import(this.getAttribute("component-url")),e?import(e):()=>()=>{}]);return this.Component=i[this.getAttribute("component-export")||"default"],this.hydrator=n,this.hydrate},s,this)}attributeChangedCallback(){this.hydrator&&this.hydrate()}},a.observedAttributes=["props"],a))}`;
2
2
  export {
3
3
  astro_island_prebuilt_default as default
4
4
  };
@@ -15,6 +15,7 @@ var __objRest = (source, exclude) => {
15
15
  };
16
16
  import { escapeHTML, HTMLString, markHTMLString } from "./escape.js";
17
17
  import { extractDirectives, generateHydrateScript } from "./hydration.js";
18
+ import { createResponse } from "./response.js";
18
19
  import {
19
20
  determineIfNeedsHydrationScript,
20
21
  determinesIfNeedsDirectiveScript,
@@ -29,21 +30,25 @@ const voidElementNames = /^(area|base|br|col|command|embed|hr|img|input|keygen|l
29
30
  const htmlBooleanAttributes = /^(allowfullscreen|async|autofocus|autoplay|controls|default|defer|disabled|disablepictureinpicture|disableremoteplayback|formnovalidate|hidden|loop|nomodule|novalidate|open|playsinline|readonly|required|reversed|scoped|seamless|itemscope)$/i;
30
31
  const htmlEnumAttributes = /^(contenteditable|draggable|spellcheck|value)$/i;
31
32
  const svgEnumAttributes = /^(autoReverse|externalResourcesRequired|focusable|preserveAlpha)$/i;
32
- async function _render(child) {
33
+ async function* _render(child) {
33
34
  child = await child;
34
35
  if (child instanceof HTMLString) {
35
- return child;
36
+ yield child;
36
37
  } else if (Array.isArray(child)) {
37
- return markHTMLString((await Promise.all(child.map((value) => _render(value)))).join(""));
38
+ for (const value of child) {
39
+ yield markHTMLString(await _render(value));
40
+ }
38
41
  } else if (typeof child === "function") {
39
- return _render(child());
42
+ yield* _render(child());
40
43
  } else if (typeof child === "string") {
41
- return markHTMLString(escapeHTML(child));
44
+ yield markHTMLString(escapeHTML(child));
42
45
  } else if (!child && child !== 0) {
43
46
  } else if (child instanceof AstroComponent || Object.prototype.toString.call(child) === "[object AstroComponent]") {
44
- return markHTMLString(await renderAstroComponent(child));
47
+ yield* renderAstroComponent(child);
48
+ } else if (typeof child === "object" && Symbol.asyncIterator in child) {
49
+ yield* child;
45
50
  } else {
46
- return child;
51
+ yield child;
47
52
  }
48
53
  }
49
54
  class AstroComponent {
@@ -54,13 +59,13 @@ class AstroComponent {
54
59
  get [Symbol.toStringTag]() {
55
60
  return "AstroComponent";
56
61
  }
57
- *[Symbol.iterator]() {
62
+ async *[Symbol.asyncIterator]() {
58
63
  const { htmlParts, expressions } = this;
59
64
  for (let i = 0; i < htmlParts.length; i++) {
60
65
  const html = htmlParts[i];
61
66
  const expression = expressions[i];
62
67
  yield markHTMLString(html);
63
- yield _render(expression);
68
+ yield* _render(expression);
64
69
  }
65
70
  }
66
71
  }
@@ -76,7 +81,12 @@ function createComponent(cb) {
76
81
  }
77
82
  async function renderSlot(_result, slotted, fallback) {
78
83
  if (slotted) {
79
- return await _render(slotted);
84
+ let iterator = _render(slotted);
85
+ let content = "";
86
+ for await (const chunk of iterator) {
87
+ content += chunk;
88
+ }
89
+ return markHTMLString(content);
80
90
  }
81
91
  return fallback;
82
92
  }
@@ -112,8 +122,7 @@ async function renderComponent(result, displayName, Component, _props, slots = {
112
122
  return markHTMLString(children2);
113
123
  }
114
124
  if (Component && Component.isAstroComponentFactory) {
115
- const output = await renderToString(result, Component, _props, slots);
116
- return markHTMLString(output);
125
+ return renderToIterable(result, Component, _props, slots);
117
126
  }
118
127
  if (!Component && !_props["client:only"]) {
119
128
  throw new Error(`Unable to render ${displayName} because it is ${Component}!
@@ -139,7 +148,12 @@ There are no \`integrations\` set in your \`astro.config.mjs\` file.
139
148
  Did you mean to add ${formatList(probableRendererNames.map((r) => "`" + r + "`"))}?`;
140
149
  throw new Error(message);
141
150
  }
142
- const children = await renderSlot(result, slots == null ? void 0 : slots.default);
151
+ const children = {};
152
+ if (slots) {
153
+ await Promise.all(Object.entries(slots).map(([key, value]) => renderSlot(result, value).then((output) => {
154
+ children[key] = output;
155
+ })));
156
+ }
143
157
  let renderer;
144
158
  if (metadata.hydrate !== "only") {
145
159
  let error;
@@ -215,24 +229,36 @@ If you're still stuck, please open an issue on GitHub or join us at https://astr
215
229
  }
216
230
  }
217
231
  if (!html && typeof Component === "string") {
218
- html = await renderAstroComponent(await render`<${Component}${internalSpreadAttributes(props)}${markHTMLString((children == null || children == "") && voidElementNames.test(Component) ? `/>` : `>${children == null ? "" : children}</${Component}>`)}`);
232
+ const childSlots = Object.values(children).join("");
233
+ const iterable = renderAstroComponent(await render`<${Component}${internalSpreadAttributes(props)}${markHTMLString(childSlots === "" && voidElementNames.test(Component) ? `/>` : `>${childSlots}</${Component}>`)}`);
234
+ html = "";
235
+ for await (const chunk of iterable) {
236
+ html += chunk;
237
+ }
219
238
  }
220
239
  if (!hydration) {
221
240
  if (isPage) {
222
241
  return html;
223
242
  }
224
- return markHTMLString(html.replace(/\<\/?astro-fragment\>/g, ""));
243
+ return markHTMLString(html.replace(/\<\/?astro-slot\>/g, ""));
225
244
  }
226
245
  const astroId = shorthash(`<!--${metadata.componentExport.value}:${metadata.componentUrl}-->
227
246
  ${html}
228
247
  ${serializeProps(props)}`);
229
248
  const island = await generateHydrateScript({ renderer, result, astroId, props }, metadata);
230
- result._metadata.needsHydrationStyles = true;
231
- const needsAstroTemplate = children && !/<\/?astro-fragment\>/.test(html);
232
- const template = needsAstroTemplate ? `<template data-astro-template>${children}</template>` : "";
233
- if (needsAstroTemplate) {
234
- island.props.tmpl = "";
249
+ let unrenderedSlots = [];
250
+ if (html) {
251
+ if (Object.keys(children).length > 0) {
252
+ for (const key of Object.keys(children)) {
253
+ if (!html.includes(key === "default" ? `<astro-slot>` : `<astro-slot name="${key}">`)) {
254
+ unrenderedSlots.push(key);
255
+ }
256
+ }
257
+ }
258
+ } else {
259
+ unrenderedSlots = Object.keys(children);
235
260
  }
261
+ const template = unrenderedSlots.length > 0 ? unrenderedSlots.map((key) => `<template data-astro-template${key !== "default" ? `="${key}"` : ""}>${children[key]}</template>`).join("") : "";
236
262
  island.children = `${html ?? ""}${template}`;
237
263
  let prescriptType = needsHydrationScript ? "both" : needsDirectiveScript ? "directive" : null;
238
264
  let prescripts = getPrescripts(prescriptType, hydration.directive);
@@ -390,47 +416,56 @@ Update your code to remove this warning.`);
390
416
  });
391
417
  return handler.call(mod, proxy, request);
392
418
  }
393
- async function replaceHeadInjection(result, html) {
394
- let template = html;
395
- if (template.indexOf("<!--astro:head-->") > -1) {
396
- template = template.replace("<!--astro:head-->", await renderHead(result));
419
+ async function renderToString(result, componentFactory, props, children) {
420
+ const Component = await componentFactory(result, props, children);
421
+ if (!isAstroComponent(Component)) {
422
+ const response = Component;
423
+ throw response;
424
+ }
425
+ let html = "";
426
+ for await (const chunk of renderAstroComponent(Component)) {
427
+ html += chunk;
397
428
  }
398
- return template;
429
+ return html;
399
430
  }
400
- async function renderToString(result, componentFactory, props, children) {
431
+ async function renderToIterable(result, componentFactory, props, children) {
401
432
  const Component = await componentFactory(result, props, children);
402
433
  if (!isAstroComponent(Component)) {
434
+ console.warn(`Returning a Response is only supported inside of page components. Consider refactoring this logic into something like a function that can be used in the page.`);
403
435
  const response = Component;
404
436
  throw response;
405
437
  }
406
- let template = await renderAstroComponent(Component);
407
- return template;
438
+ return renderAstroComponent(Component);
408
439
  }
440
+ const encoder = new TextEncoder();
409
441
  async function renderPage(result, componentFactory, props, children) {
410
- try {
411
- const response = await componentFactory(result, props, children);
412
- if (isAstroComponent(response)) {
413
- let template = await renderAstroComponent(response);
414
- const html = await replaceHeadInjection(result, template);
415
- return {
416
- type: "html",
417
- html
418
- };
419
- } else {
420
- return {
421
- type: "response",
422
- response
423
- };
424
- }
425
- } catch (err) {
426
- if (err instanceof Response) {
427
- return {
428
- type: "response",
429
- response: err
430
- };
431
- } else {
432
- throw err;
433
- }
442
+ const factoryReturnValue = await componentFactory(result, props, children);
443
+ if (isAstroComponent(factoryReturnValue)) {
444
+ let iterable = renderAstroComponent(factoryReturnValue);
445
+ let stream = new ReadableStream({
446
+ start(controller) {
447
+ async function read() {
448
+ let i = 0;
449
+ for await (const chunk of iterable) {
450
+ let html = chunk.toString();
451
+ if (i === 0) {
452
+ if (!/<!doctype html/i.test(html)) {
453
+ controller.enqueue(encoder.encode("<!DOCTYPE html>\n"));
454
+ }
455
+ }
456
+ controller.enqueue(encoder.encode(html));
457
+ i++;
458
+ }
459
+ controller.close();
460
+ }
461
+ read();
462
+ }
463
+ });
464
+ let init = result.response;
465
+ let response = createResponse(stream, init);
466
+ return response;
467
+ } else {
468
+ return factoryReturnValue;
434
469
  }
435
470
  }
436
471
  const uniqueElements = (item, index, all) => {
@@ -438,32 +473,30 @@ const uniqueElements = (item, index, all) => {
438
473
  const children = item.children;
439
474
  return index === all.findIndex((i) => JSON.stringify(i.props) === props && i.children == children);
440
475
  };
476
+ const alreadyHeadRenderedResults = /* @__PURE__ */ new WeakSet();
441
477
  async function renderHead(result) {
478
+ alreadyHeadRenderedResults.add(result);
442
479
  const styles = Array.from(result.styles).filter(uniqueElements).map((style) => renderElement("style", style));
443
- let needsHydrationStyles = result._metadata.needsHydrationStyles;
444
480
  const scripts = Array.from(result.scripts).filter(uniqueElements).map((script, i) => {
445
- if ("data-astro-component-hydration" in script.props) {
446
- needsHydrationStyles = true;
447
- }
448
481
  return renderElement("script", script);
449
482
  });
450
- if (needsHydrationStyles) {
451
- styles.push(renderElement("style", {
452
- props: {},
453
- children: "astro-island, astro-fragment { display: contents; }"
454
- }));
455
- }
456
483
  const links = Array.from(result.links).filter(uniqueElements).map((link) => renderElement("link", link, false));
457
- return markHTMLString(links.join("\n") + styles.join("\n") + scripts.join("\n") + "\n<!--astro:head:injected-->");
484
+ return markHTMLString(links.join("\n") + styles.join("\n") + scripts.join("\n"));
458
485
  }
459
- async function renderAstroComponent(component) {
460
- let template = [];
486
+ function maybeRenderHead(result) {
487
+ if (alreadyHeadRenderedResults.has(result)) {
488
+ return "";
489
+ }
490
+ return renderHead(result);
491
+ }
492
+ async function* renderAstroComponent(component) {
461
493
  for await (const value of component) {
462
494
  if (value || value === 0) {
463
- template.push(value);
495
+ for await (const chunk of _render(value)) {
496
+ yield markHTMLString(chunk);
497
+ }
464
498
  }
465
499
  }
466
- return markHTMLString(await _render(template));
467
500
  }
468
501
  function componentIsHTMLElement(Component) {
469
502
  return typeof HTMLElement !== "undefined" && HTMLElement.isPrototypeOf(Component);
@@ -515,6 +548,7 @@ export {
515
548
  defineScriptVars,
516
549
  defineStyleVars,
517
550
  markHTMLString2 as markHTMLString,
551
+ maybeRenderHead,
518
552
  render,
519
553
  renderAstroComponent,
520
554
  renderComponent,
@@ -523,6 +557,7 @@ export {
523
557
  renderHead,
524
558
  renderPage,
525
559
  renderSlot,
560
+ renderToIterable,
526
561
  renderToString,
527
562
  spreadAttributes,
528
563
  markHTMLString3 as unescapeHTML
@@ -30,7 +30,7 @@ class Metadata {
30
30
  for (const metadata of this.deepMetadata()) {
31
31
  let i = 0, pathname = metadata.mockURL.pathname;
32
32
  while (i < metadata.hoisted.length) {
33
- yield `${pathname.replace("/@fs", "")}?astro&type=script&index=${i}`;
33
+ yield `${pathname.replace("/@fs", "")}?astro&type=script&index=${i}&lang.ts`;
34
34
  i++;
35
35
  }
36
36
  }
@@ -0,0 +1,83 @@
1
+ var __accessCheck = (obj, member, msg) => {
2
+ if (!member.has(obj))
3
+ throw TypeError("Cannot " + msg);
4
+ };
5
+ var __privateGet = (obj, member, getter) => {
6
+ __accessCheck(obj, member, "read from private field");
7
+ return getter ? getter.call(obj) : member.get(obj);
8
+ };
9
+ var __privateAdd = (obj, member, value) => {
10
+ if (member.has(obj))
11
+ throw TypeError("Cannot add the same private member more than once");
12
+ member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
13
+ };
14
+ var __privateSet = (obj, member, value, setter) => {
15
+ __accessCheck(obj, member, "write to private field");
16
+ setter ? setter.call(obj, value) : member.set(obj, value);
17
+ return value;
18
+ };
19
+ const isNodeJS = typeof process === "object" && Object.prototype.toString.call(process) === "[object process]";
20
+ let StreamingCompatibleResponse;
21
+ function createResponseClass() {
22
+ var _isStream, _body, _a;
23
+ StreamingCompatibleResponse = (_a = class extends Response {
24
+ constructor(body, init) {
25
+ let isStream = body instanceof ReadableStream;
26
+ super(isStream ? null : body, init);
27
+ __privateAdd(this, _isStream, void 0);
28
+ __privateAdd(this, _body, void 0);
29
+ __privateSet(this, _isStream, isStream);
30
+ __privateSet(this, _body, body);
31
+ }
32
+ get body() {
33
+ return __privateGet(this, _body);
34
+ }
35
+ async text() {
36
+ if (__privateGet(this, _isStream) && isNodeJS) {
37
+ let decoder = new TextDecoder();
38
+ let body = __privateGet(this, _body);
39
+ let reader = body.getReader();
40
+ let buffer = [];
41
+ while (true) {
42
+ let r = await reader.read();
43
+ if (r.value) {
44
+ buffer.push(...r.value);
45
+ }
46
+ if (r.done) {
47
+ break;
48
+ }
49
+ }
50
+ return decoder.decode(Uint8Array.from(buffer));
51
+ }
52
+ return super.text();
53
+ }
54
+ async arrayBuffer() {
55
+ if (__privateGet(this, _isStream) && isNodeJS) {
56
+ let body = __privateGet(this, _body);
57
+ let reader = body.getReader();
58
+ let chunks = [];
59
+ while (true) {
60
+ let r = await reader.read();
61
+ if (r.value) {
62
+ chunks.push(...r.value);
63
+ }
64
+ if (r.done) {
65
+ break;
66
+ }
67
+ }
68
+ return Uint8Array.from(chunks);
69
+ }
70
+ return super.arrayBuffer();
71
+ }
72
+ }, _isStream = new WeakMap(), _body = new WeakMap(), _a);
73
+ return StreamingCompatibleResponse;
74
+ }
75
+ const createResponse = isNodeJS ? (body, init) => {
76
+ if (typeof StreamingCompatibleResponse === "undefined") {
77
+ return new (createResponseClass())(body, init);
78
+ }
79
+ return new StreamingCompatibleResponse(body, init);
80
+ } : (body, init) => new Response(body, init);
81
+ export {
82
+ createResponse
83
+ };
@@ -41,7 +41,7 @@ function getDirectiveScriptText(directive) {
41
41
  function getPrescripts(type, directive) {
42
42
  switch (type) {
43
43
  case "both":
44
- return `<script>${getDirectiveScriptText(directive) + islandScript}<\/script>`;
44
+ return `<style>astro-island,astro-slot{display:contents}</style><script>${getDirectiveScriptText(directive) + islandScript}<\/script>`;
45
45
  case "directive":
46
46
  return `<script>${getDirectiveScriptText(directive)}<\/script>`;
47
47
  }
@@ -673,7 +673,7 @@ export interface AstroConfig extends z.output<typeof AstroConfigSchema> {
673
673
  }[];
674
674
  };
675
675
  }
676
- export declare type AsyncRendererComponentFn<U> = (Component: any, props: any, children: string | undefined, metadata?: AstroComponentMetadata) => Promise<U>;
676
+ export declare type AsyncRendererComponentFn<U> = (Component: any, props: any, slots: Record<string, string>, metadata?: AstroComponentMetadata) => Promise<U>;
677
677
  /** Generic interface for a component (Astro, Svelte, React, etc.) */
678
678
  export interface ComponentInstance {
679
679
  $$metadata: Metadata;
@@ -907,7 +907,6 @@ export interface SSRElement {
907
907
  export interface SSRMetadata {
908
908
  renderers: SSRLoadedRenderer[];
909
909
  pathname: string;
910
- needsHydrationStyles: boolean;
911
910
  }
912
911
  export interface SSRResult {
913
912
  styles: Set<SSRElement>;
@@ -31,12 +31,5 @@ export interface RenderOptions {
31
31
  ssr: boolean;
32
32
  request: Request;
33
33
  }
34
- export declare function render(opts: RenderOptions): Promise<{
35
- type: 'html';
36
- html: string;
37
- response: ResponseInit;
38
- } | {
39
- type: 'response';
40
- response: Response;
41
- }>;
34
+ export declare function render(opts: RenderOptions): Promise<Response>;
42
35
  export {};
@@ -25,16 +25,8 @@ export interface SSROptions {
25
25
  request: Request;
26
26
  }
27
27
  export declare type ComponentPreload = [SSRLoadedRenderer[], ComponentInstance];
28
- export declare type RenderResponse = {
29
- type: 'html';
30
- html: string;
31
- response: ResponseInit;
32
- } | {
33
- type: 'response';
34
- response: Response;
35
- };
36
28
  export declare function loadRenderers(viteServer: ViteDevServer, astroConfig: AstroConfig): Promise<SSRLoadedRenderer[]>;
37
29
  export declare function preload({ astroConfig, filePath, viteServer, }: Pick<SSROptions, 'astroConfig' | 'filePath' | 'viteServer'>): Promise<ComponentPreload>;
38
30
  /** use Vite to SSR */
39
- export declare function render(renderers: SSRLoadedRenderer[], mod: ComponentInstance, ssrOpts: SSROptions): Promise<RenderResponse>;
40
- export declare function ssr(preloadedComponent: ComponentPreload, ssrOpts: SSROptions): Promise<RenderResponse>;
31
+ export declare function render(renderers: SSRLoadedRenderer[], mod: ComponentInstance, ssrOpts: SSROptions): Promise<Response>;
32
+ export declare function ssr(preloadedComponent: ComponentPreload, ssrOpts: SSROptions): Promise<Response>;
@@ -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 o;{const a={0:t=>t,1:t=>JSON.parse(t,n),2:t=>new RegExp(t),3:t=>new Date(t),4:t=>new Map(JSON.parse(t,n)),5:t=>new Set(JSON.parse(t,n)),6:t=>BigInt(t),7:t=>new URL(t)},n=(t,e)=>{if(t===\"\"||!Array.isArray(e))return e;const[r,s]=e;return r in a?a[r](s):void 0};customElements.get(\"astro-island\")||customElements.define(\"astro-island\",(o=class extends HTMLElement{constructor(){super(...arguments);this.hydrate=()=>{if(!this.hydrator||this.parentElement?.closest(\"astro-island[ssr]\"))return;let e=null,r=this.querySelector(\"astro-fragment\");if(r==null&&this.hasAttribute(\"tmpl\")){let i=this.querySelector(\"template[data-astro-template]\");i&&(e=i.innerHTML,i.remove())}else r&&(e=r.innerHTML);const s=this.hasAttribute(\"props\")?JSON.parse(this.getAttribute(\"props\"),n):{};this.hydrator(this)(this.Component,s,e,{client:this.getAttribute(\"client\")}),this.removeAttribute(\"ssr\"),window.removeEventListener(\"astro:hydrate\",this.hydrate),window.dispatchEvent(new CustomEvent(\"astro:hydrate\"))}}async connectedCallback(){window.addEventListener(\"astro:hydrate\",this.hydrate),await import(this.getAttribute(\"before-hydration-url\"));const e=JSON.parse(this.getAttribute(\"opts\"));Astro[this.getAttribute(\"client\")](async()=>{const r=this.getAttribute(\"renderer-url\"),[s,{default:i}]=await Promise.all([import(this.getAttribute(\"component-url\")),r?import(r):()=>()=>{}]);return this.Component=s[this.getAttribute(\"component-export\")||\"default\"],this.hydrator=i,this.hydrate},e,this)}attributeChangedCallback(){this.hydrator&&this.hydrate()}},o.observedAttributes=[\"props\"],o))}";
6
+ declare const _default: "var a;{const l={0:t=>t,1:t=>JSON.parse(t,o),2:t=>new RegExp(t),3:t=>new Date(t),4:t=>new Map(JSON.parse(t,o)),5:t=>new Set(JSON.parse(t,o)),6:t=>BigInt(t),7:t=>new URL(t)},o=(t,s)=>{if(t===\"\"||!Array.isArray(s))return s;const[e,i]=s;return e in l?l[e](i):void 0};customElements.get(\"astro-island\")||customElements.define(\"astro-island\",(a=class extends HTMLElement{constructor(){super(...arguments);this.hydrate=()=>{if(!this.hydrator||this.parentElement?.closest(\"astro-island[ssr]\"))return;const s=this.querySelectorAll(\"astro-slot\"),e={},i=this.querySelectorAll(\"template[data-astro-template]\");for(const r of i)!r.closest(this.tagName)?.isSameNode(this)||(e[r.getAttribute(\"data-astro-template\")||\"default\"]=r.innerHTML,r.remove());for(const r of s)!r.closest(this.tagName)?.isSameNode(this)||(e[r.getAttribute(\"name\")||\"default\"]=r.innerHTML);const n=this.hasAttribute(\"props\")?JSON.parse(this.getAttribute(\"props\"),o):{};this.hydrator(this)(this.Component,n,e,{client:this.getAttribute(\"client\")}),this.removeAttribute(\"ssr\"),window.removeEventListener(\"astro:hydrate\",this.hydrate),window.dispatchEvent(new CustomEvent(\"astro:hydrate\"))}}async connectedCallback(){window.addEventListener(\"astro:hydrate\",this.hydrate),await import(this.getAttribute(\"before-hydration-url\"));const s=JSON.parse(this.getAttribute(\"opts\"));Astro[this.getAttribute(\"client\")](async()=>{const e=this.getAttribute(\"renderer-url\"),[i,{default:n}]=await Promise.all([import(this.getAttribute(\"component-url\")),e?import(e):()=>()=>{}]);return this.Component=i[this.getAttribute(\"component-export\")||\"default\"],this.hydrator=n,this.hydrate},s,this)}attributeChangedCallback(){this.hydrator&&this.hydrate()}},a.observedAttributes=[\"props\"],a))}";
7
7
  export default _default;
@@ -7,7 +7,7 @@ export declare class AstroComponent {
7
7
  private expressions;
8
8
  constructor(htmlParts: TemplateStringsArray, expressions: any[]);
9
9
  get [Symbol.toStringTag](): string;
10
- [Symbol.iterator](): Generator<any, void, unknown>;
10
+ [Symbol.asyncIterator](): AsyncGenerator<any, void, undefined>;
11
11
  }
12
12
  export declare function render(htmlParts: TemplateStringsArray, ...expressions: any[]): Promise<AstroComponent>;
13
13
  export interface AstroComponentFactory {
@@ -15,9 +15,9 @@ export interface AstroComponentFactory {
15
15
  isAstroComponentFactory?: boolean;
16
16
  }
17
17
  export declare function createComponent(cb: AstroComponentFactory): AstroComponentFactory;
18
- export declare function renderSlot(_result: any, slotted: string, fallback?: any): Promise<any>;
18
+ export declare function renderSlot(_result: any, slotted: string, fallback?: any): Promise<string>;
19
19
  export declare const Fragment: unique symbol;
20
- export declare function renderComponent(result: SSRResult, displayName: string, Component: unknown, _props: Record<string | number, any>, slots?: any): Promise<any>;
20
+ export declare function renderComponent(result: SSRResult, displayName: string, Component: unknown, _props: Record<string | number, any>, slots?: any): Promise<string | AsyncIterable<string>>;
21
21
  export declare function createAstro(filePathname: string, _site: string, projectRootStr: string): AstroGlobalPartial;
22
22
  export declare function addAttribute(value: any, key: string, shouldEscape?: boolean): any;
23
23
  export declare function spreadAttributes(values: Record<any, any>, name: string, { class: scopedClassName }?: {
@@ -28,13 +28,9 @@ export declare function defineScriptVars(vars: Record<any, any>): any;
28
28
  /** Renders an endpoint request to completion, returning the body. */
29
29
  export declare function renderEndpoint(mod: EndpointHandler, request: Request, params: Params): Promise<Response | import("../../@types/astro").EndpointOutput>;
30
30
  export declare function renderToString(result: SSRResult, componentFactory: AstroComponentFactory, props: any, children: any): Promise<string>;
31
- export declare function renderPage(result: SSRResult, componentFactory: AstroComponentFactory, props: any, children: any): Promise<{
32
- type: 'html';
33
- html: string;
34
- } | {
35
- type: 'response';
36
- response: Response;
37
- }>;
31
+ export declare function renderToIterable(result: SSRResult, componentFactory: AstroComponentFactory, props: any, children: any): Promise<AsyncIterable<string>>;
32
+ export declare function renderPage(result: SSRResult, componentFactory: AstroComponentFactory, props: any, children: any): Promise<Response>;
38
33
  export declare function renderHead(result: SSRResult): Promise<string>;
39
- export declare function renderAstroComponent(component: InstanceType<typeof AstroComponent>): Promise<any>;
34
+ export declare function maybeRenderHead(result: SSRResult): string | Promise<string>;
35
+ export declare function renderAstroComponent(component: InstanceType<typeof AstroComponent>): AsyncIterable<string>;
40
36
  export declare function renderHTMLElement(result: SSRResult, constructor: typeof HTMLElement, props: any, slots: any): Promise<any>;
@@ -0,0 +1,3 @@
1
+ declare type CreateResponseFn = (body?: BodyInit | null, init?: ResponseInit) => Response;
2
+ export declare const createResponse: CreateResponseFn;
3
+ export {};
@@ -6,7 +6,8 @@ export interface AstroQuery {
6
6
  lang?: string;
7
7
  raw?: boolean;
8
8
  }
9
- export declare function parseAstroRequest(id: string): {
9
+ export interface ParsedRequestResult {
10
10
  filename: string;
11
11
  query: AstroQuery;
12
- };
12
+ }
13
+ export declare function parseAstroRequest(id: string): ParsedRequestResult;
@@ -31,6 +31,15 @@ function astro({ config, logging }) {
31
31
  let viteDevServer = null;
32
32
  const srcRootWeb = config.srcDir.pathname.slice(config.root.pathname.length - 1);
33
33
  const isBrowserPath = (path) => path.startsWith(srcRootWeb);
34
+ function resolveRelativeFromAstroParent(id, parsedFrom) {
35
+ const filename = normalizeFilename(parsedFrom.filename);
36
+ const resolvedURL = new URL(id, `file://${filename}`);
37
+ const resolved = resolvedURL.pathname;
38
+ if (isBrowserPath(resolved)) {
39
+ return relativeToRoot(resolved + resolvedURL.search);
40
+ }
41
+ return slash(fileURLToPath(resolvedURL)) + resolvedURL.search;
42
+ }
34
43
  return {
35
44
  name: "astro:build",
36
45
  enforce: "pre",
@@ -41,17 +50,15 @@ function astro({ config, logging }) {
41
50
  configureServer(server) {
42
51
  viteDevServer = server;
43
52
  },
44
- async resolveId(id, from) {
53
+ async resolveId(id, from, opts) {
45
54
  if (from) {
46
55
  const parsedFrom = parseAstroRequest(from);
47
- if (parsedFrom.query.astro && isRelativePath(id) && parsedFrom.query.type === "script") {
48
- const filename = normalizeFilename(parsedFrom.filename);
49
- const resolvedURL = new URL(id, `file://${filename}`);
50
- const resolved = resolvedURL.pathname;
51
- if (isBrowserPath(resolved)) {
52
- return relativeToRoot(resolved + resolvedURL.search);
53
- }
54
- return slash(fileURLToPath(resolvedURL)) + resolvedURL.search;
56
+ const isAstroScript = parsedFrom.query.astro && parsedFrom.query.type === "script";
57
+ if (isAstroScript && isRelativePath(id)) {
58
+ return this.resolve(resolveRelativeFromAstroParent(id, parsedFrom), from, {
59
+ custom: opts.custom,
60
+ skipSelf: true
61
+ });
55
62
  }
56
63
  }
57
64
  const { query } = parseAstroRequest(id);
@@ -133,7 +140,12 @@ File: ${filename}`);
133
140
  }
134
141
  }
135
142
  return {
136
- code: hoistedScript.type === "inline" ? hoistedScript.code : `import "${hoistedScript.src}";`
143
+ code: hoistedScript.type === "inline" ? hoistedScript.code : `import "${hoistedScript.src}";`,
144
+ meta: {
145
+ vite: {
146
+ lang: "ts"
147
+ }
148
+ }
137
149
  };
138
150
  }
139
151
  }
@@ -161,8 +173,8 @@ const $$url = ${JSON.stringify(url)};export { $$file as file, $$url as url };
161
173
  }
162
174
  let i = 0;
163
175
  while (i < transformResult.scripts.length) {
164
- deps.add(`${id}?astro&type=script&index=${i}`);
165
- SUFFIX += `import "${id}?astro&type=script&index=${i}";`;
176
+ deps.add(`${id}?astro&type=script&index=${i}&lang.ts`);
177
+ SUFFIX += `import "${id}?astro&type=script&index=${i}&lang.ts";`;
166
178
  i++;
167
179
  }
168
180
  SUFFIX += `
@@ -52,7 +52,12 @@ async function writeWebResponse(res, webResponse) {
52
52
  }
53
53
  res.writeHead(status, _headers);
54
54
  if (body) {
55
- if (body instanceof Readable) {
55
+ if (Symbol.for("astro.responseBody") in webResponse) {
56
+ let stream = webResponse[Symbol.for("astro.responseBody")];
57
+ for await (const chunk of stream) {
58
+ res.write(chunk.toString());
59
+ }
60
+ } else if (body instanceof Readable) {
56
61
  body.pipe(res);
57
62
  return;
58
63
  } else {
@@ -69,17 +74,8 @@ async function writeWebResponse(res, webResponse) {
69
74
  }
70
75
  res.end();
71
76
  }
72
- async function writeSSRResult(result, res, statusCode) {
73
- if (result.type === "response") {
74
- const { response } = result;
75
- await writeWebResponse(res, response);
76
- return;
77
- }
78
- const { html, response: init } = result;
79
- const headers = init.headers;
80
- headers.set("Content-Type", "text/html; charset=utf-8");
81
- headers.set("Content-Length", Buffer.byteLength(html, "utf-8").toString());
82
- return writeWebResponse(res, new Response(html, init));
77
+ async function writeSSRResult(webResponse, res) {
78
+ return writeWebResponse(res, webResponse);
83
79
  }
84
80
  async function handle404Response(origin, config, req, res) {
85
81
  const site = config.site ? new URL(config.base, config.site) : void 0;
@@ -214,7 +210,7 @@ async function handleRequest(routeCache, viteServer, logging, manifest, config,
214
210
  routeCache,
215
211
  viteServer
216
212
  });
217
- return await writeSSRResult(result, res, statusCode);
213
+ return await writeSSRResult(result, res);
218
214
  } else {
219
215
  return handle404Response(origin, config, req, res);
220
216
  }
@@ -241,7 +237,7 @@ async function handleRequest(routeCache, viteServer, logging, manifest, config,
241
237
  }
242
238
  } else {
243
239
  const result = await ssr(preloadedComponent, options);
244
- return await writeSSRResult(result, res, statusCode);
240
+ return await writeSSRResult(result, res);
245
241
  }
246
242
  } catch (_err) {
247
243
  const err = fixViteErrorMessage(createSafeError(_err), viteServer);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "astro",
3
- "version": "1.0.0-beta.52",
3
+ "version": "1.0.0-beta.55",
4
4
  "description": "Astro is a modern site builder with web best practices, performance, and DX front-of-mind.",
5
5
  "type": "module",
6
6
  "author": "withastro",
@@ -66,7 +66,7 @@
66
66
  "vendor"
67
67
  ],
68
68
  "dependencies": {
69
- "@astrojs/compiler": "^0.16.1",
69
+ "@astrojs/compiler": "^0.17.0",
70
70
  "@astrojs/language-server": "^0.13.4",
71
71
  "@astrojs/markdown-remark": "^0.11.3",
72
72
  "@astrojs/prism": "0.4.1",
@@ -93,7 +93,6 @@
93
93
  "gray-matter": "^4.0.3",
94
94
  "html-entities": "^2.3.3",
95
95
  "html-escaper": "^3.0.3",
96
- "htmlparser2": "^7.2.0",
97
96
  "kleur": "^4.1.4",
98
97
  "magic-string": "^0.25.9",
99
98
  "micromorph": "^0.1.2",
@@ -1,90 +0,0 @@
1
- import htmlparser2 from "htmlparser2";
2
- function injectTags(html, tags) {
3
- let output = html;
4
- if (!tags.length)
5
- return output;
6
- const pos = { "head-prepend": -1, head: -1, "body-prepend": -1, body: -1 };
7
- const parser = new htmlparser2.Parser({
8
- onopentag(tagname) {
9
- if (tagname === "head")
10
- pos["head-prepend"] = parser.endIndex + 1;
11
- if (tagname === "body")
12
- pos["body-prepend"] = parser.endIndex + 1;
13
- },
14
- onclosetag(tagname) {
15
- if (tagname === "head")
16
- pos["head"] = parser.startIndex;
17
- if (tagname === "body")
18
- pos["body"] = parser.startIndex;
19
- }
20
- });
21
- parser.write(html);
22
- parser.end();
23
- const lastToFirst = Object.entries(pos).sort((a, b) => b[1] - a[1]);
24
- lastToFirst.forEach(([name, i]) => {
25
- if (i === -1) {
26
- if (name === "head-prepend" || name === "head")
27
- i = 0;
28
- if (name === "body-prepend" || name === "body")
29
- i = html.length;
30
- }
31
- let selected = tags.filter(({ injectTo }) => {
32
- if (name === "head-prepend" && !injectTo) {
33
- return true;
34
- } else {
35
- return injectTo === name;
36
- }
37
- });
38
- if (!selected.length)
39
- return;
40
- output = output.substring(0, i) + serializeTags(selected) + html.substring(i);
41
- });
42
- return output;
43
- }
44
- function collectResources(html) {
45
- let resources = [];
46
- const parser = new htmlparser2.Parser({
47
- onopentag(tagname, attrs) {
48
- if (tagname === "link")
49
- resources.push(attrs);
50
- }
51
- });
52
- parser.write(html);
53
- parser.end();
54
- return resources;
55
- }
56
- const unaryTags = /* @__PURE__ */ new Set(["link", "meta", "base"]);
57
- function serializeTag({ tag, attrs, children }, indent = "") {
58
- if (unaryTags.has(tag)) {
59
- return `<${tag}${serializeAttrs(attrs)}>`;
60
- } else {
61
- return `<${tag}${serializeAttrs(attrs)}>${serializeTags(children, incrementIndent(indent))}</${tag}>`;
62
- }
63
- }
64
- function serializeTags(tags, indent = "") {
65
- if (typeof tags === "string") {
66
- return tags;
67
- } else if (tags && tags.length) {
68
- return tags.map((tag) => `${indent}${serializeTag(tag, indent)}
69
- `).join("");
70
- }
71
- return "";
72
- }
73
- function serializeAttrs(attrs) {
74
- let res = "";
75
- for (const key in attrs) {
76
- if (typeof attrs[key] === "boolean") {
77
- res += attrs[key] ? ` ${key}` : ``;
78
- } else {
79
- res += ` ${key}=${JSON.stringify(attrs[key])}`;
80
- }
81
- }
82
- return res;
83
- }
84
- function incrementIndent(indent = "") {
85
- return `${indent}${indent[0] === " " ? " " : " "}`;
86
- }
87
- export {
88
- collectResources,
89
- injectTags
90
- };
@@ -1,7 +0,0 @@
1
- import type * as vite from 'vite';
2
- /** Inject tags into HTML (note: for best performance, group as many tags as possible into as few calls as you can) */
3
- export declare function injectTags(html: string, tags: vite.HtmlTagDescriptor[]): string;
4
- declare type Resource = Record<string, string>;
5
- /** Collect resources (scans final, rendered HTML so expressions have been applied) */
6
- export declare function collectResources(html: string): Resource[];
7
- export {};