@demiurgejs/core 0.1.0 → 0.1.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.
@@ -18,6 +18,11 @@ export type HydrateFileRouterOptions = Omit<FileRouterOptions, "initialMatch"> &
18
18
  root?: Element;
19
19
  };
20
20
  export declare function hydrateFileRouter(options: HydrateFileRouterOptions): Promise<void>;
21
+ type ReactDomClientApi = Pick<typeof import("react-dom/client"), "createRoot" | "hydrateRoot">;
22
+ type ReactDomClientModule = Partial<ReactDomClientApi> & {
23
+ default?: ReactDomClientApi;
24
+ };
25
+ export declare function resolveReactDomClient(module: ReactDomClientModule): ReactDomClientApi;
21
26
  export declare function Link<const TTo extends AppHref>(props: LinkTo<TTo> & {
22
27
  children: ReactNode;
23
28
  className?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"file-router.d.ts","sourceRoot":"","sources":["../../src/browser/file-router.tsx"],"names":[],"mappings":"AAAA,OAAO,EAEL,aAAa,EAEb,SAAS,EAQV,MAAM,OAAO,CAAC;AACf,OAAO,EAIL,KAAK,gBAAgB,EACtB,MAAM,aAAa,CAAC;AACrB,OAAO,EAIL,KAAK,aAAa,EAElB,KAAK,aAAa,EACnB,MAAM,UAAU,CAAC;AAClB,OAAO,EAUL,KAAK,iBAAiB,EACvB,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAQ,KAAK,OAAO,EAAmB,KAAK,MAAM,EAAE,MAAM,YAAY,CAAC;AAE9E,MAAM,MAAM,oBAAoB,GAAG,CACjC,OAAO,EAAE,OAAO,KACb,OAAO,CAAC,gBAAgB,CAAC,CAAC;AAE/B,MAAM,MAAM,iBAAiB,GAAG;IAC9B,YAAY,CAAC,EAAE,iBAAiB,CAAC;IACjC,kBAAkB,CAAC,EAAE,oBAAoB,CAAC;IAC1C,UAAU,CAAC,EAAE,UAAU,GAAG,QAAQ,CAAC;IACnC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACtC,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,QAAQ,CAAC,EAAE,aAAa,CAAC,aAAa,CAAC,CAAC;CACzC,CAAC;AAEF,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,iBAAiB,4FA8H1D;AA0BD,MAAM,MAAM,wBAAwB,GAAG,IAAI,CACzC,iBAAiB,EACjB,cAAc,CACf,GAAG;IACF,WAAW,CAAC,EAAE,gBAAgB,CAAC;IAC/B,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB,CAAC;AAEF,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,wBAAwB,iBAgDxE;AAED,wBAAgB,IAAI,CAAC,KAAK,CAAC,GAAG,SAAS,OAAO,EAC5C,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,GAAG;IACnB,QAAQ,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,+BAsBF;AA4LD,KAAK,SAAS,GAAG;IACf,UAAU,EAAE,UAAU,GAAG,QAAQ,CAAC;IAClC,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB,CAAC"}
1
+ {"version":3,"file":"file-router.d.ts","sourceRoot":"","sources":["../../src/browser/file-router.tsx"],"names":[],"mappings":"AAAA,OAAO,EAEL,aAAa,EAEb,SAAS,EAQV,MAAM,OAAO,CAAC;AACf,OAAO,EAIL,KAAK,gBAAgB,EACtB,MAAM,aAAa,CAAC;AACrB,OAAO,EAIL,KAAK,aAAa,EAElB,KAAK,aAAa,EACnB,MAAM,UAAU,CAAC;AAClB,OAAO,EAUL,KAAK,iBAAiB,EACvB,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAQ,KAAK,OAAO,EAAmB,KAAK,MAAM,EAAE,MAAM,YAAY,CAAC;AAE9E,MAAM,MAAM,oBAAoB,GAAG,CACjC,OAAO,EAAE,OAAO,KACb,OAAO,CAAC,gBAAgB,CAAC,CAAC;AAE/B,MAAM,MAAM,iBAAiB,GAAG;IAC9B,YAAY,CAAC,EAAE,iBAAiB,CAAC;IACjC,kBAAkB,CAAC,EAAE,oBAAoB,CAAC;IAC1C,UAAU,CAAC,EAAE,UAAU,GAAG,QAAQ,CAAC;IACnC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACtC,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,QAAQ,CAAC,EAAE,aAAa,CAAC,aAAa,CAAC,CAAC;CACzC,CAAC;AAEF,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,iBAAiB,4FA8H1D;AA0BD,MAAM,MAAM,wBAAwB,GAAG,IAAI,CACzC,iBAAiB,EACjB,cAAc,CACf,GAAG;IACF,WAAW,CAAC,EAAE,gBAAgB,CAAC;IAC/B,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB,CAAC;AAEF,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,wBAAwB,iBAkDxE;AAED,KAAK,iBAAiB,GAAG,IAAI,CAC3B,cAAc,kBAAkB,CAAC,EACjC,YAAY,GAAG,aAAa,CAC7B,CAAC;AAEF,KAAK,oBAAoB,GAAG,OAAO,CAAC,iBAAiB,CAAC,GAAG;IACvD,OAAO,CAAC,EAAE,iBAAiB,CAAC;CAC7B,CAAC;AAEF,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,oBAAoB,qBAiBjE;AAED,wBAAgB,IAAI,CAAC,KAAK,CAAC,GAAG,SAAS,OAAO,EAC5C,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,GAAG;IACnB,QAAQ,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,+BAsBF;AA4LD,KAAK,SAAS,GAAG;IACf,UAAU,EAAE,UAAU,GAAG,QAAQ,CAAC;IAClC,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB,CAAC"}
@@ -1,8 +1,8 @@
1
- import { renderToString as T } from "react-dom/server";
1
+ import { renderToString as b } from "react-dom/server";
2
2
  import { createElement as h } from "react";
3
- const g = "__demiurge_data", v = "data-demiurge-hydrate", E = "data-demiurge-fallback";
4
- function k(e, n = {}) {
5
- return w(
3
+ const g = "__demiurge_data", E = "data-demiurge-hydrate", v = "data-demiurge-fallback";
4
+ function w(e, n = {}) {
5
+ return S(
6
6
  JSON.stringify({ data: e, hasData: !0, ...n })
7
7
  );
8
8
  }
@@ -18,30 +18,31 @@ function F(e) {
18
18
  );
19
19
  }
20
20
  }
21
- function w(e) {
21
+ function S(e) {
22
22
  return e.replace(/&/g, "\\u0026").replace(/</g, "\\u003c").replace(/>/g, "\\u003e").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
23
23
  }
24
- function x(e) {
24
+ const k = "data-demiurge-structured-data";
25
+ function _(e) {
25
26
  if (e.body) {
26
- const { html: n, ...t } = e.body, { prefix: o, suffix: a } = S({ ...e, body: t });
27
+ const { html: n, ...t } = e.body, { prefix: o, suffix: a } = x({ ...e, body: t });
27
28
  return `${o}${n}${a}`;
28
29
  }
29
- return O(e);
30
+ return B(e);
30
31
  }
31
- function S({
32
+ function x({
32
33
  body: e,
33
34
  entrySrc: n,
34
35
  lang: t = "en",
35
36
  links: o = [],
36
37
  metadata: a,
37
38
  nonce: c,
38
- scripts: p = [],
39
- styles: s = [],
39
+ scripts: s = [],
40
+ styles: p = [],
40
41
  title: d = "Demiurge App"
41
42
  }) {
42
43
  const f = a?.title ?? d, $ = [
43
- ...p.map((R) => ` ${b(R, c)}`),
44
- I(e.data, e.navigation),
44
+ ...s.map((R) => ` ${D(R, c)}`),
45
+ C(e.data, e.navigation),
45
46
  ...n ? [A(n, c)] : []
46
47
  ].join(`
47
48
  `);
@@ -49,10 +50,10 @@ function S({
49
50
  prefix: `<!doctype html>
50
51
  <html lang="${i(t)}">
51
52
  <head>
52
- ${D({ links: o, metadata: a, nonce: c, styles: s, title: f })}
53
+ ${T({ links: o, metadata: a, nonce: c, styles: p, title: f })}
53
54
  </head>
54
55
  <body>
55
- ${B(e)}`,
56
+ ${O(e)}`,
56
57
  suffix: `</div>
57
58
  ${$}
58
59
  </body>
@@ -60,26 +61,26 @@ ${$}
60
61
  `
61
62
  };
62
63
  }
63
- function O({
64
+ function B({
64
65
  entrySrc: e,
65
66
  lang: n = "en",
66
67
  links: t = [],
67
68
  metadata: o,
68
69
  nonce: a,
69
70
  scripts: c = [],
70
- styles: p = [],
71
- title: s = "Demiurge App"
71
+ styles: s = [],
72
+ title: p = "Demiurge App"
72
73
  }) {
73
- const d = o?.title ?? s, f = [
74
- _(),
75
- ...c.map(($) => ` ${b($, a)}`),
74
+ const d = o?.title ?? p, f = [
75
+ I(),
76
+ ...c.map(($) => ` ${D($, a)}`),
76
77
  ...e ? [A(e, a)] : []
77
78
  ].join(`
78
79
  `);
79
80
  return `<!doctype html>
80
81
  <html lang="${i(n)}">
81
82
  <head>
82
- ${D({ links: t, metadata: o, nonce: a, styles: p, title: d })}
83
+ ${T({ links: t, metadata: o, nonce: a, styles: s, title: d })}
83
84
  </head>
84
85
  <body>
85
86
  ${f}
@@ -87,20 +88,20 @@ ${f}
87
88
  </html>
88
89
  `;
89
90
  }
90
- function _(e) {
91
+ function I(e) {
91
92
  return ' <div id="root"></div>';
92
93
  }
93
- function B(e) {
94
- const n = e.fallback ? ` ${E}="${i(e.fallback)}"` : "";
95
- return ` <div id="root" ${v}=""${n}>`;
94
+ function O(e) {
95
+ const n = e.fallback ? ` ${v}="${i(e.fallback)}"` : "";
96
+ return ` <div id="root" ${E}=""${n}>`;
96
97
  }
97
- function I(e, n) {
98
- return ` <template id="${g}">${k(e, { navigation: n })}</template>`;
98
+ function C(e, n) {
99
+ return ` <template id="${g}">${w(e, { navigation: n })}</template>`;
99
100
  }
100
101
  function A(e, n) {
101
102
  return ` <script type="module" src="${i(e)}"${r("nonce", n)}><\/script>`;
102
103
  }
103
- function D({
104
+ function T({
104
105
  links: e,
105
106
  metadata: n,
106
107
  nonce: t,
@@ -130,10 +131,10 @@ function D({
130
131
  })
131
132
  ] : [],
132
133
  ...M(n),
133
- ...C(n),
134
- ...(n?.custom ?? []).map(G),
134
+ ...G(n),
135
+ ...(n?.custom ?? []).map(N),
135
136
  ...(n?.structuredData ?? []).map(
136
- (c) => N(c, t)
137
+ (c) => H(c, t)
137
138
  ),
138
139
  ...o.map(
139
140
  (c) => ` <link rel="stylesheet" href="${i(c)}" />`
@@ -156,7 +157,7 @@ function M(e) {
156
157
  })
157
158
  ];
158
159
  }
159
- function C(e) {
160
+ function G(e) {
160
161
  return e?.openGraph ? [
161
162
  e.openGraph.title ? l({
162
163
  content: e.openGraph.title,
@@ -172,11 +173,11 @@ function C(e) {
172
173
  }) : null
173
174
  ].filter((n) => !!n) : [];
174
175
  }
175
- function G(e) {
176
+ function N(e) {
176
177
  return e.kind === "link" ? y(e) : l(e);
177
178
  }
178
- function N(e, n) {
179
- return ` <script type="application/ld+json"${r("nonce", n)}>${L(JSON.stringify(e.value))}<\/script>`;
179
+ function H(e, n) {
180
+ return ` <script type="application/ld+json"${n ? "" : ` ${k}`}${r("nonce", n)}>${U(JSON.stringify(e.value))}<\/script>`;
180
181
  }
181
182
  function l(e) {
182
183
  if (e.name === "charset")
@@ -187,10 +188,10 @@ function l(e) {
187
188
  function y(e) {
188
189
  return ` <link${r("rel", e.rel)}${r("href", e.href)}${r("as", e.as)}${r("type", e.type)}${r("crossorigin", e.crossOrigin)}${r("hreflang", e.hrefLang)} />`;
189
190
  }
190
- function b(e, n) {
191
- return `<script${r("id", e.id)}${r("src", e.src)}${r("type", e.type ?? H(e.strategy))}${r("nonce", e.nonce ?? n)}${r("integrity", e.integrity)}${r("referrerpolicy", e.referrerPolicy)}${r("data-api", e.dataApi)}${r("data-domain", e.dataDomain)}${m("async", e.async)}${m("defer", e.defer)}><\/script>`;
191
+ function D(e, n) {
192
+ return `<script${r("id", e.id)}${r("src", e.src)}${r("type", e.type ?? L(e.strategy))}${r("nonce", e.nonce ?? n)}${r("integrity", e.integrity)}${r("referrerpolicy", e.referrerPolicy)}${r("data-api", e.dataApi)}${r("data-domain", e.dataDomain)}${m("async", e.async)}${m("defer", e.defer)}><\/script>`;
192
193
  }
193
- function H(e) {
194
+ function L(e) {
194
195
  return e === "module" ? "module" : void 0;
195
196
  }
196
197
  function r(e, n) {
@@ -202,17 +203,17 @@ function m(e, n) {
202
203
  function i(e) {
203
204
  return e.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;");
204
205
  }
205
- function L(e) {
206
+ function U(e) {
206
207
  return e.replaceAll("<", "\\u003c").replaceAll(">", "\\u003e").replaceAll("\u2028", "\\u2028").replaceAll("\u2029", "\\u2029");
207
208
  }
208
209
  const u = /* @__PURE__ */ new WeakMap();
209
- function U(e) {
210
+ function Y(e) {
210
211
  return u.get(e);
211
212
  }
212
- function Y(e, n) {
213
+ function z(e, n) {
213
214
  u.set(e, n);
214
215
  }
215
- function z(e, n) {
216
+ function W(e, n) {
216
217
  const t = u.get(e);
217
218
  t && u.set(n, t);
218
219
  }
@@ -232,8 +233,8 @@ function j(e) {
232
233
  );
233
234
  }
234
235
  function J(e, n = {}) {
235
- const t = T(j(e));
236
- return x({
236
+ const t = b(j(e));
237
+ return _({
237
238
  body: {
238
239
  data: e.data,
239
240
  html: t,
@@ -249,7 +250,7 @@ function J(e, n = {}) {
249
250
  title: n.title
250
251
  });
251
252
  }
252
- function W(e, n = {}) {
253
+ function K(e, n = {}) {
253
254
  const t = J(e, n);
254
255
  return new Response(t, {
255
256
  headers: {
@@ -258,16 +259,17 @@ function W(e, n = {}) {
258
259
  });
259
260
  }
260
261
  export {
261
- v as H,
262
- S as a,
263
- x as b,
262
+ E as H,
263
+ k as S,
264
+ x as a,
265
+ _ as b,
264
266
  j as c,
265
267
  J as d,
266
268
  F as e,
267
- E as f,
268
- U as g,
269
- z as h,
270
- W as r,
271
- Y as s
269
+ v as f,
270
+ Y as g,
271
+ W as h,
272
+ K as r,
273
+ z as s
272
274
  };
273
- //# sourceMappingURL=ssr-O3d7Q73U.js.map
275
+ //# sourceMappingURL=ssr-BJejKlkZ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ssr-BJejKlkZ.js","sources":["../../src/document/hydration.ts","../../src/document/render.ts","../../src/server/request-metadata.ts","../../src/server/render-tree.ts","../../src/server/ssr.ts"],"sourcesContent":["export type InitialRouteData = {\n data?: unknown;\n hasData: boolean;\n navigation?: \"document\";\n};\n\nexport const HYDRATION_DATA_ELEMENT_ID = \"__demiurge_data\";\nexport const HYDRATION_ROOT_ATTRIBUTE = \"data-demiurge-hydrate\";\n// Marks a server document as a fallback, not a page. The client hydrates markup\n// that it can reproduce. It replaces other markup. This attribute distinguishes\n// a server 404 from a page that does not match the client manifest.\nexport const HYDRATION_FALLBACK_ATTRIBUTE = \"data-demiurge-fallback\";\n\nexport function serializeInitialRouteData(\n data: unknown,\n options: { navigation?: \"document\" } = {},\n) {\n return escapeJsonScript(\n JSON.stringify({ data, hasData: true, ...options }),\n );\n}\n\nexport function readInitialRouteData(source: Document) {\n const element = source.getElementById(HYDRATION_DATA_ELEMENT_ID);\n const serialized = element?.tagName === \"TEMPLATE\"\n ? (element as HTMLTemplateElement).content.textContent\n : element?.textContent;\n\n if (!serialized) {\n return undefined;\n }\n\n try {\n return JSON.parse(serialized) as InitialRouteData;\n } catch (error) {\n throw new Error(\n \"Demiurge could not parse the initial route data payload.\",\n { cause: error },\n );\n }\n}\n\nfunction escapeJsonScript(value: string) {\n return value\n .replace(/&/g, \"\\\\u0026\")\n .replace(/</g, \"\\\\u003c\")\n .replace(/>/g, \"\\\\u003e\")\n .replace(/\\u2028/g, \"\\\\u2028\")\n .replace(/\\u2029/g, \"\\\\u2029\");\n}\n","import {\n HYDRATION_DATA_ELEMENT_ID,\n HYDRATION_FALLBACK_ATTRIBUTE,\n HYDRATION_ROOT_ATTRIBUTE,\n serializeInitialRouteData,\n} from \"./hydration\";\nimport type {\n DocumentMetadataTag,\n LinkTag,\n ResolvedMetadata,\n StructuredDataTag,\n} from \"./metadata\";\nimport type { ScriptTag } from \"./scripts\";\n\nexport const STRUCTURED_DATA_ATTRIBUTE = \"data-demiurge-structured-data\";\n\nexport type DocumentBody = {\n data: unknown;\n fallback?: \"not-found\";\n html: string;\n navigation?: \"document\";\n};\n\nexport type RenderDocumentOptions = {\n body?: DocumentBody;\n entrySrc?: string;\n lang?: string;\n links?: LinkTag[];\n metadata?: ResolvedMetadata;\n nonce?: string;\n scripts?: ScriptTag[];\n styles?: string[];\n title?: string;\n};\n\nexport type RenderDocumentShellOptions = Omit<RenderDocumentOptions, \"body\"> & {\n body: Omit<DocumentBody, \"html\">;\n};\n\nexport function renderDocument(options: RenderDocumentOptions) {\n if (options.body) {\n const { html, ...body } = options.body;\n const { prefix, suffix } = renderDocumentShell({ ...options, body });\n\n return `${prefix}${html}${suffix}`;\n }\n\n return renderDocumentWithoutBody(options);\n}\n\nexport function renderDocumentShell({\n body,\n entrySrc,\n lang = \"en\",\n links = [],\n metadata,\n nonce,\n scripts = [],\n styles = [],\n title = \"Demiurge App\",\n}: RenderDocumentShellOptions) {\n const documentTitle = metadata?.title ?? title;\n const trailingBodyContent = [\n ...scripts.map((scriptTag) => ` ${renderScriptTag(scriptTag, nonce)}`),\n renderBootstrapData(body.data, body.navigation),\n ...(entrySrc ? [renderEntryScript(entrySrc, nonce)] : []),\n ].join(\"\\n\");\n\n return {\n prefix: `<!doctype html>\n<html lang=\"${escapeHtml(lang)}\">\n <head>\n${renderHeadTags({ links, metadata, nonce, styles, title: documentTitle })}\n </head>\n <body>\n${renderRootStart(body)}`,\n suffix: `</div>\n${trailingBodyContent}\n </body>\n</html>\n`,\n };\n}\n\nfunction renderDocumentWithoutBody({\n entrySrc,\n lang = \"en\",\n links = [],\n metadata,\n nonce,\n scripts = [],\n styles = [],\n title = \"Demiurge App\",\n}: RenderDocumentOptions) {\n const documentTitle = metadata?.title ?? title;\n const bodyContent = [\n renderRootElement(),\n ...scripts.map((scriptTag) => ` ${renderScriptTag(scriptTag, nonce)}`),\n ...(entrySrc ? [renderEntryScript(entrySrc, nonce)] : []),\n ].join(\"\\n\");\n\n return `<!doctype html>\n<html lang=\"${escapeHtml(lang)}\">\n <head>\n${renderHeadTags({ links, metadata, nonce, styles, title: documentTitle })}\n </head>\n <body>\n${bodyContent}\n </body>\n</html>\n`;\n}\n\nfunction renderRootElement(body?: DocumentBody) {\n if (!body) {\n return ` <div id=\"root\"></div>`;\n }\n\n return `${renderRootStart(body)}${body.html}</div>`;\n}\n\nfunction renderRootStart(body: Omit<DocumentBody, \"html\">) {\n const fallback = body.fallback\n ? ` ${HYDRATION_FALLBACK_ATTRIBUTE}=\"${escapeHtml(body.fallback)}\"`\n : \"\";\n\n return ` <div id=\"root\" ${HYDRATION_ROOT_ATTRIBUTE}=\"\"${fallback}>`;\n}\n\nfunction renderBootstrapData(data: unknown, navigation?: \"document\") {\n return ` <template id=\"${HYDRATION_DATA_ELEMENT_ID}\">${serializeInitialRouteData(data, { navigation })}</template>`;\n}\n\nfunction renderEntryScript(entrySrc: string, nonce: string | undefined) {\n return ` <script type=\"module\" src=\"${escapeHtml(entrySrc)}\"${renderAttribute(\"nonce\", nonce)}></script>`;\n}\n\nfunction renderHeadTags({\n links,\n metadata,\n nonce,\n styles,\n title,\n}: {\n links: LinkTag[];\n metadata: ResolvedMetadata | undefined;\n nonce: string | undefined;\n styles: string[];\n title: string;\n}) {\n return [\n renderMetaTag({\n content: metadata?.charset ?? \"UTF-8\",\n kind: \"meta\",\n name: \"charset\",\n }),\n renderMetaTag({\n content: metadata?.viewport ?? \"width=device-width, initial-scale=1.0\",\n kind: \"meta\",\n name: \"viewport\",\n }),\n ` <title>${escapeHtml(title)}</title>`,\n ...(metadata?.description\n ? [\n renderMetaTag({\n content: metadata.description,\n kind: \"meta\",\n name: \"description\",\n }),\n ]\n : []),\n ...(metadata?.canonical\n ? [\n renderLinkTag({\n href: metadata.canonical,\n kind: \"link\",\n rel: \"canonical\",\n }),\n ]\n : []),\n ...renderRobotsTags(metadata),\n ...renderOpenGraphTags(metadata),\n ...(metadata?.custom ?? []).map(renderDocumentMetadataTag),\n ...(metadata?.structuredData ?? []).map((tag) =>\n renderStructuredDataTag(tag, nonce),\n ),\n ...styles.map(\n (href) => ` <link rel=\"stylesheet\" href=\"${escapeHtml(href)}\" />`,\n ),\n ...links.map(renderLinkTag),\n ].join(\"\\n\");\n}\n\nfunction renderRobotsTags(metadata: ResolvedMetadata | undefined) {\n if (!metadata?.robots) {\n return [];\n }\n\n const directives = [\n metadata.robots.index === false ? \"noindex\" : \"index\",\n metadata.robots.follow === false ? \"nofollow\" : \"follow\",\n ];\n\n return [\n renderMetaTag({\n content: directives.join(\", \"),\n kind: \"meta\",\n name: \"robots\",\n }),\n ];\n}\n\nfunction renderOpenGraphTags(metadata: ResolvedMetadata | undefined) {\n if (!metadata?.openGraph) {\n return [];\n }\n\n return [\n metadata.openGraph.title\n ? renderMetaTag({\n content: metadata.openGraph.title,\n kind: \"meta\",\n property: \"og:title\",\n })\n : null,\n metadata.openGraph.description\n ? renderMetaTag({\n content: metadata.openGraph.description,\n kind: \"meta\",\n property: \"og:description\",\n })\n : null,\n metadata.openGraph.image\n ? renderMetaTag({\n content: metadata.openGraph.image,\n kind: \"meta\",\n property: \"og:image\",\n })\n : null,\n ].filter((tag): tag is string => Boolean(tag));\n}\n\nfunction renderDocumentMetadataTag(tag: DocumentMetadataTag) {\n if (tag.kind === \"link\") {\n return renderLinkTag(tag);\n }\n\n return renderMetaTag(tag);\n}\n\nfunction renderStructuredDataTag(\n tag: StructuredDataTag,\n nonce: string | undefined,\n) {\n const ownership = nonce ? \"\" : ` ${STRUCTURED_DATA_ATTRIBUTE}`;\n\n return ` <script type=\"application/ld+json\"${ownership}${renderAttribute(\"nonce\", nonce)}>${escapeJsonScript(JSON.stringify(tag.value))}</script>`;\n}\n\nfunction renderMetaTag(tag: DocumentMetadataTag & { kind: \"meta\" }) {\n if (tag.name === \"charset\") {\n return ` <meta charset=\"${escapeHtml(tag.content)}\" />`;\n }\n\n const name = tag.name ? ` name=\"${escapeHtml(tag.name)}\"` : \"\";\n const property = tag.property ? ` property=\"${escapeHtml(tag.property)}\"` : \"\";\n\n return ` <meta${name}${property} content=\"${escapeHtml(tag.content)}\" />`;\n}\n\nfunction renderLinkTag(tag: LinkTag) {\n return ` <link${renderAttribute(\"rel\", tag.rel)}${renderAttribute(\"href\", tag.href)}${renderAttribute(\"as\", tag.as)}${renderAttribute(\"type\", tag.type)}${renderAttribute(\"crossorigin\", tag.crossOrigin)}${renderAttribute(\"hreflang\", tag.hrefLang)} />`;\n}\n\nfunction renderScriptTag(scriptTag: ScriptTag, nonce: string | undefined) {\n return `<script${renderAttribute(\"id\", scriptTag.id)}${renderAttribute(\"src\", scriptTag.src)}${renderAttribute(\"type\", scriptTag.type ?? scriptTypeForStrategy(scriptTag.strategy))}${renderAttribute(\"nonce\", scriptTag.nonce ?? nonce)}${renderAttribute(\"integrity\", scriptTag.integrity)}${renderAttribute(\"referrerpolicy\", scriptTag.referrerPolicy)}${renderAttribute(\"data-api\", scriptTag.dataApi)}${renderAttribute(\"data-domain\", scriptTag.dataDomain)}${renderBooleanAttribute(\"async\", scriptTag.async)}${renderBooleanAttribute(\"defer\", scriptTag.defer)}></script>`;\n}\n\nfunction scriptTypeForStrategy(strategy: ScriptTag[\"strategy\"]) {\n return strategy === \"module\" ? \"module\" : undefined;\n}\n\nfunction renderAttribute(name: string, value: string | undefined) {\n return value ? ` ${name}=\"${escapeHtml(value)}\"` : \"\";\n}\n\nfunction renderBooleanAttribute(name: string, value: boolean | undefined) {\n return value ? ` ${name}` : \"\";\n}\n\nfunction escapeHtml(value: string) {\n return value\n .replaceAll(\"&\", \"&amp;\")\n .replaceAll(\"<\", \"&lt;\")\n .replaceAll(\">\", \"&gt;\")\n .replaceAll('\"', \"&quot;\");\n}\n\nfunction escapeJsonScript(value: string) {\n return value\n .replaceAll(\"<\", \"\\\\u003c\")\n .replaceAll(\">\", \"\\\\u003e\")\n .replaceAll(\"
\", \"\\\\u2028\")\n .replaceAll(\"
\", \"\\\\u2029\");\n}\n","export type RequestConnectionMetadata = {\n clientIp: string;\n};\n\nconst connectionMetadata = new WeakMap<Request, RequestConnectionMetadata>();\n\nexport function getRequestConnectionMetadata(request: Request) {\n return connectionMetadata.get(request);\n}\n\nexport function setRequestConnectionMetadata(\n request: Request,\n metadata: RequestConnectionMetadata,\n) {\n connectionMetadata.set(request, metadata);\n}\n\nexport function copyRequestConnectionMetadata(from: Request, to: Request) {\n const metadata = connectionMetadata.get(from);\n\n if (metadata) {\n connectionMetadata.set(to, metadata);\n }\n}\n","import { createElement, type ReactNode } from \"react\";\nimport type { LoadedRouteMatch } from \"../router\";\n\nexport function createPageRenderTree(match: LoadedRouteMatch) {\n const page = createElement(match.page, {\n data: match.data,\n path: match.path,\n pathname: match.pathname,\n });\n\n return match.layouts.reduceRight<ReactNode>(\n (children, Layout) =>\n createElement(Layout, {\n children,\n path: match.path,\n pathname: match.pathname,\n }),\n page,\n );\n}\n","import { renderToString } from \"react-dom/server\";\nimport { renderDocument } from \"../document\";\nimport type { LoadedRouteMatch } from \"../router\";\nimport { createPageRenderTree } from \"./render-tree\";\n\nexport type SsrOptions = {\n clientEntry?: string;\n lang?: string;\n navigation?: \"document\";\n styles?: string[];\n title?: string;\n};\n\nexport type SsrRenderOptions = SsrOptions & {\n nonce?: string;\n onStreamError?: (error: unknown) => void;\n signal?: AbortSignal;\n transformDocument?: (html: string) => string | Promise<string>;\n};\n\nexport function renderPageDocument(\n match: LoadedRouteMatch,\n options: SsrRenderOptions = {},\n) {\n const html = renderToString(createPageRenderTree(match));\n\n return renderDocument({\n body: {\n data: match.data,\n html,\n navigation: match.render.mode === \"static\"\n ? \"document\"\n : options.navigation,\n },\n entrySrc: options.clientEntry,\n lang: options.lang,\n links: match.links,\n metadata: match.metadata,\n nonce: options.nonce,\n scripts: match.scripts,\n styles: options.styles,\n title: options.title,\n });\n}\n\nexport function renderPageResponse(\n match: LoadedRouteMatch,\n options: SsrRenderOptions = {},\n) {\n const html = renderPageDocument(match, options);\n\n return new Response(html, {\n headers: {\n \"content-type\": \"text/html; charset=utf-8\",\n },\n });\n}\n"],"names":["HYDRATION_DATA_ELEMENT_ID","HYDRATION_ROOT_ATTRIBUTE","HYDRATION_FALLBACK_ATTRIBUTE","serializeInitialRouteData","data","options","escapeJsonScript","readInitialRouteData","source","element","serialized","error","value","STRUCTURED_DATA_ATTRIBUTE","renderDocument","html","body","prefix","suffix","renderDocumentShell","renderDocumentWithoutBody","entrySrc","lang","links","metadata","nonce","scripts","styles","title","documentTitle","trailingBodyContent","scriptTag","renderScriptTag","renderBootstrapData","renderEntryScript","escapeHtml","renderHeadTags","renderRootStart","bodyContent","renderRootElement","fallback","navigation","renderAttribute","renderMetaTag","renderLinkTag","renderRobotsTags","renderOpenGraphTags","renderDocumentMetadataTag","tag","renderStructuredDataTag","href","directives","name","property","scriptTypeForStrategy","renderBooleanAttribute","strategy","connectionMetadata","getRequestConnectionMetadata","request","setRequestConnectionMetadata","copyRequestConnectionMetadata","from","to","createPageRenderTree","match","page","createElement","children","Layout","renderPageDocument","renderToString","renderPageResponse"],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ const t = /-[A-Za-z0-9_-]{8,}\.[A-Za-z0-9]+$/, e = "public, max-age=31536000, immutable", E = "public, max-age=0, must-revalidate";
2
+ function s(a) {
3
+ return t.test(a);
4
+ }
5
+ export {
6
+ t as C,
7
+ e as I,
8
+ E as R,
9
+ s as i
10
+ };
11
+ //# sourceMappingURL=static-files-DUjHw-4H.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"static-files-DUjHw-4H.js","sources":["../../src/static-files.ts"],"sourcesContent":["export const CONTENT_HASHED_FILE_NAME_PATTERN =\n /-[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9]+$/;\n\nexport const IMMUTABLE_FILE_CACHE_CONTROL =\n \"public, max-age=31536000, immutable\";\n\nexport const REVALIDATED_FILE_CACHE_CONTROL =\n \"public, max-age=0, must-revalidate\";\n\nexport function isContentHashedFileName(fileName: string) {\n return CONTENT_HASHED_FILE_NAME_PATTERN.test(fileName);\n}\n"],"names":["CONTENT_HASHED_FILE_NAME_PATTERN","IMMUTABLE_FILE_CACHE_CONTROL","REVALIDATED_FILE_CACHE_CONTROL","isContentHashedFileName","fileName"],"mappings":"AAAO,MAAMA,IACX,qCAEWC,IACX,uCAEWC,IACX;AAEK,SAASC,EAAwBC,GAAkB;AACxD,SAAOJ,EAAiC,KAAKI,CAAQ;AACvD;"}
@@ -1,7 +1,7 @@
1
1
  import { Readable as D, Transform as H } from "node:stream";
2
2
  import { pipeline as R } from "node:stream/promises";
3
3
  import { isIP as A } from "node:net";
4
- import { s as M, r as P, c as I, a as v } from "./ssr-O3d7Q73U.js";
4
+ import { s as M, r as P, c as I, a as v } from "./ssr-BJejKlkZ.js";
5
5
  import { renderToPipeableStream as $ } from "react-dom/server";
6
6
  const p = {
7
7
  for: "x-forwarded-for",
@@ -340,4 +340,4 @@ export {
340
340
  O as v,
341
341
  re as w
342
342
  };
343
- //# sourceMappingURL=streaming-27pwhjGC.js.map
343
+ //# sourceMappingURL=streaming-DN1DnbRE.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"streaming-27pwhjGC.js","sources":["../../src/node/http.ts","../../src/node/streaming.ts"],"sourcesContent":["import { Readable } from \"node:stream\";\nimport { pipeline } from \"node:stream/promises\";\nimport { isIP } from \"node:net\";\nimport type {\n IncomingHttpHeaders,\n IncomingMessage,\n ServerResponse,\n} from \"node:http\";\nimport { setRequestConnectionMetadata } from \"../server/request-metadata\";\n\nexport type HttpScheme = \"http\" | \"https\";\n\nexport type NodeOriginPolicy = {\n allowedHosts: readonly string[];\n trustProxy?: TrustProxy;\n};\n\nexport type ToWebRequestOptions = NodeOriginPolicy & {\n signal?: AbortSignal;\n};\n\nexport type TrustProxy =\n | false\n | { hops: number }\n | { ranges: readonly string[] };\n\nconst forwardedHeaders = {\n for: \"x-forwarded-for\",\n host: \"x-forwarded-host\",\n protocol: \"x-forwarded-proto\",\n} as const satisfies Record<\"for\" | \"host\" | \"protocol\", string>;\nconst defaultTrustProxy = false satisfies TrustProxy;\n\n// The Fetch specification prohibits these methods in the `Request` constructor.\n// `new Request(...)` throws for them. Without this guard, an unauthenticated\n// client can make a generic 500 response and add stack traces to the server log.\nconst forbiddenMethods = new Set([\"CONNECT\", \"TRACE\", \"TRACK\"]);\n\nexport class UnsupportedMethodError extends Error {\n method: string;\n\n constructor(method: string) {\n super(`HTTP method \"${method}\" is not supported.`);\n this.method = method;\n this.name = \"UnsupportedMethodError\";\n }\n}\n\nexport class UntrustedHostError extends Error {\n host: string;\n\n constructor(host: string) {\n super(`HTTP host \"${host}\" is not allowed.`);\n this.host = host;\n this.name = \"UntrustedHostError\";\n }\n}\n\nexport function validateNodeOriginPolicy(policy: NodeOriginPolicy) {\n if (policy.allowedHosts.length === 0) {\n throw new Error(\"Demiurge Node allowedHosts must contain at least one host.\");\n }\n\n for (const host of policy.allowedHosts) {\n if (!parseAuthority(host)) {\n throw new Error(`Demiurge Node allowed host \"${host}\" is invalid.`);\n }\n }\n\n const trustProxy = policy.trustProxy ?? defaultTrustProxy;\n\n if (trustProxy === false) {\n return;\n }\n\n if (\"hops\" in trustProxy) {\n if (!Number.isSafeInteger(trustProxy.hops) || trustProxy.hops < 0) {\n throw new Error(\n \"Demiurge Node trustProxy hop count must be a non-negative integer.\",\n );\n }\n\n return;\n }\n\n for (const range of trustProxy.ranges) {\n const network = range.split(\"/\")[0];\n ipMatchesRange(network, range);\n }\n}\n\nexport function toWebRequest(\n request: IncomingMessage,\n options: ToWebRequestOptions,\n) {\n validateNodeOriginPolicy(options);\n const method = request.method ?? \"GET\";\n\n if (forbiddenMethods.has(method.toUpperCase())) {\n throw new UnsupportedMethodError(method);\n }\n\n const peerAddress = normalizeIpAddress(request.socket?.remoteAddress);\n const proxy = resolveProxyChain(\n peerAddress,\n request.headers[forwardedHeaders.for],\n options.trustProxy ?? defaultTrustProxy,\n );\n const forwardedProtocol = selectForwardedValue(\n request.headers[forwardedHeaders.protocol],\n proxy.forwardedDepth,\n );\n const protocol = resolveProtocol(request, forwardedProtocol);\n const host = selectForwardedValue(\n request.headers[forwardedHeaders.host],\n proxy.forwardedDepth,\n ) ?? request.headers.host;\n const authority = validateAllowedHost(host, options.allowedHosts);\n const origin = `${protocol}://${authority}`;\n const url = new URL(request.url ?? \"/\", origin);\n const init: RequestInit & { duplex?: \"half\" } = {\n headers: toHeaders(request.headers),\n method,\n signal: options.signal,\n };\n\n if (method !== \"GET\" && method !== \"HEAD\") {\n init.body = Readable.toWeb(request) as ReadableStream;\n init.duplex = \"half\";\n }\n\n const webRequest = new Request(url, init);\n setRequestConnectionMetadata(webRequest, { clientIp: proxy.clientIp });\n\n return webRequest;\n}\n\nfunction resolveProtocol(\n request: IncomingMessage,\n forwardedProtocol: string | undefined,\n) {\n if (forwardedProtocol) {\n const protocol = forwardedProtocol.toLowerCase();\n\n if (protocol !== \"http\" && protocol !== \"https\") {\n throw new Error(`Unsupported forwarded protocol \"${forwardedProtocol}\".`);\n }\n\n return protocol;\n }\n\n return (request.socket as { encrypted?: boolean } | undefined)?.encrypted\n ? \"https\"\n : \"http\";\n}\n\nfunction validateAllowedHost(\n host: string | undefined,\n allowedHosts: readonly string[],\n) {\n if (allowedHosts.length === 0) {\n throw new Error(\"Demiurge Node allowedHosts must contain at least one host.\");\n }\n\n if (!host) {\n throw new UntrustedHostError(\"\");\n }\n\n const authority = parseAuthority(host);\n\n if (!authority) {\n throw new UntrustedHostError(host);\n }\n\n const allowed = allowedHosts.some((candidate) => {\n const expected = parseAuthority(candidate);\n\n if (!expected) {\n throw new Error(`Demiurge Node allowed host \"${candidate}\" is invalid.`);\n }\n\n return expected.port\n ? expected.host === authority.host\n : expected.hostname === authority.hostname;\n });\n\n if (!allowed) {\n throw new UntrustedHostError(host);\n }\n\n return authority.host;\n}\n\nfunction parseAuthority(value: string) {\n if (value.trim() !== value || value.includes(\"@\")) {\n return null;\n }\n\n try {\n const parsed = new URL(`http://${value}`);\n\n if (\n !parsed.hostname ||\n parsed.pathname !== \"/\" ||\n parsed.search ||\n parsed.hash ||\n parsed.host.toLowerCase() !== value.toLowerCase()\n ) {\n return null;\n }\n\n return parsed;\n } catch {\n return null;\n }\n}\n\nfunction resolveProxyChain(\n peerAddress: string,\n forwardedFor: string | readonly string[] | undefined,\n trustProxy: TrustProxy,\n) {\n const forwarded = headerValues(forwardedFor);\n const chain = [...forwarded, peerAddress];\n\n if (trustProxy === false) {\n return { clientIp: peerAddress, forwardedDepth: 0 };\n }\n\n if (\"hops\" in trustProxy) {\n if (!Number.isSafeInteger(trustProxy.hops) || trustProxy.hops < 0) {\n throw new Error(\n \"Demiurge Node trustProxy hop count must be a non-negative integer.\",\n );\n }\n\n const clientHops = Math.min(trustProxy.hops, forwarded.length);\n\n return {\n clientIp: chain[chain.length - 1 - clientHops],\n forwardedDepth: trustProxy.hops,\n };\n }\n\n let index = chain.length - 1;\n let trustedHops = 0;\n\n while (\n index > 0 &&\n isAddressTrusted(chain[index], trustProxy.ranges)\n ) {\n index -= 1;\n trustedHops += 1;\n }\n\n return {\n clientIp: chain[index],\n forwardedDepth:\n trustedHops || (isAddressTrusted(peerAddress, trustProxy.ranges) ? 1 : 0),\n };\n}\n\nfunction selectForwardedValue(\n header: string | readonly string[] | undefined,\n trustedDepth: number,\n) {\n if (trustedDepth === 0) {\n return undefined;\n }\n\n const values = headerValues(header);\n\n if (values.length === 0) {\n return undefined;\n }\n\n return values[Math.max(0, values.length - trustedDepth)];\n}\n\nfunction headerValues(value: string | readonly string[] | undefined) {\n return (Array.isArray(value) ? value : [value])\n .flatMap((item) => item?.split(\",\") ?? [])\n .map((item) => item.trim())\n .filter(Boolean);\n}\n\nfunction isAddressTrusted(address: string, ranges: readonly string[]) {\n return ranges.some((range) => ipMatchesRange(address, range));\n}\n\nfunction ipMatchesRange(address: string, range: string) {\n const [networkValue, prefixValue] = range.split(\"/\");\n const addressBytes = ipBytes(normalizeIpAddress(address));\n const networkBytes = ipBytes(normalizeIpAddress(networkValue));\n\n if (!addressBytes || !networkBytes || addressBytes.length !== networkBytes.length) {\n if (!networkBytes) {\n throw new Error(`Demiurge Node trustProxy range \"${range}\" is invalid.`);\n }\n\n return false;\n }\n\n const maximumPrefix = addressBytes.length * 8;\n const prefix = prefixValue === undefined ? maximumPrefix : Number(prefixValue);\n\n if (!Number.isInteger(prefix) || prefix < 0 || prefix > maximumPrefix) {\n throw new Error(`Demiurge Node trustProxy range \"${range}\" is invalid.`);\n }\n\n for (let bit = 0; bit < prefix; bit += 1) {\n const mask = 1 << (7 - (bit % 8));\n\n if ((addressBytes[Math.floor(bit / 8)] & mask) !==\n (networkBytes[Math.floor(bit / 8)] & mask)) {\n return false;\n }\n }\n\n return true;\n}\n\nfunction normalizeIpAddress(address: string | undefined) {\n if (!address) {\n return \"unknown\";\n }\n\n return address.startsWith(\"::ffff:\") ? address.slice(7) : address;\n}\n\nfunction ipBytes(address: string) {\n const version = isIP(address);\n\n if (version === 4) {\n return address.split(\".\").map(Number);\n }\n\n if (version !== 6) {\n return null;\n }\n\n const [left = \"\", right = \"\"] = address.split(\"::\");\n const leftGroups = left ? left.split(\":\") : [];\n const rightGroups = right ? right.split(\":\") : [];\n const missing = 8 - leftGroups.length - rightGroups.length;\n const groups = [\n ...leftGroups,\n ...Array.from({ length: missing }, () => \"0\"),\n ...rightGroups,\n ];\n\n return groups.flatMap((group) => {\n const value = Number.parseInt(group, 16);\n return [value >> 8, value & 255];\n });\n}\n\n// Shared by the Node adapter and the Vite dev middleware so a request the\n// Fetch layer cannot represent gets the same answer in both.\nexport function writeNotImplemented(serverResponse: ServerResponse) {\n serverResponse.statusCode = 501;\n serverResponse.setHeader(\"content-type\", \"text/plain; charset=utf-8\");\n serverResponse.end(\"Not Implemented\");\n}\n\nexport async function writeWebResponse(\n serverResponse: ServerResponse,\n webResponse: Response,\n) {\n // `Headers.forEach` joins repeated headers with a comma, which is wrong for\n // `set-cookie`: two cookies would arrive as one malformed header. Node's\n // `setHeader` takes an array for exactly this case.\n const cookies = getSetCookies(webResponse.headers);\n\n webResponse.headers.forEach((value, name) => {\n if (name === \"set-cookie\") {\n return;\n }\n\n serverResponse.setHeader(name, value);\n });\n\n if (cookies.length > 0) {\n serverResponse.setHeader(\"set-cookie\", cookies);\n }\n\n serverResponse.statusCode = webResponse.status;\n\n // An empty status text would otherwise overwrite Node's default reason\n // phrase with nothing at all.\n if (webResponse.statusText) {\n serverResponse.statusMessage = webResponse.statusText;\n }\n\n if (!webResponse.body) {\n serverResponse.end();\n return;\n }\n\n // `Readable.pipe()` does not destroy its source when the destination closes\n // or has an error. An aborted client can leave the source stream open. It can\n // also leave an associated file descriptor open. `pipeline` destroys the\n // source when either side closes.\n try {\n await pipeline(\n Readable.fromWeb(\n webResponse.body as unknown as import(\"node:stream/web\").ReadableStream,\n ),\n serverResponse,\n );\n } catch (error) {\n if (!isClientDisconnect(error)) {\n throw error;\n }\n }\n}\n\n// A client disconnect during a response is ordinary traffic, not a server\n// fault. A new throw would run the caller error path for each canceled download.\n// This path records a stack trace and creates an unused 500 response. An\n// unauthenticated client can cause this condition.\nconst clientDisconnectCodes = new Set([\n \"ECONNRESET\",\n \"EPIPE\",\n \"ERR_STREAM_DESTROYED\",\n \"ERR_STREAM_PREMATURE_CLOSE\",\n]);\n\nfunction isClientDisconnect(error: unknown) {\n return (\n error instanceof Error &&\n \"code\" in error &&\n typeof error.code === \"string\" &&\n clientDisconnectCodes.has(error.code)\n );\n}\n\nexport function toHeaders(headers: IncomingHttpHeaders) {\n const nextHeaders = new Headers();\n\n for (const [name, value] of Object.entries(headers)) {\n if (Array.isArray(value)) {\n for (const item of value) {\n nextHeaders.append(name, item);\n }\n continue;\n }\n\n if (value) {\n nextHeaders.set(name, value);\n }\n }\n\n return nextHeaders;\n}\n\nfunction getSetCookies(headers: Headers) {\n const getSetCookie = (headers as Headers & {\n getSetCookie?: () => string[];\n }).getSetCookie;\n\n if (getSetCookie) {\n return getSetCookie.call(headers);\n }\n\n const combined = headers.get(\"set-cookie\");\n\n return combined ? splitSetCookies(combined) : [];\n}\n\nfunction splitSetCookies(value: string) {\n return value.split(/,\\s*(?=[^;,=\\s]+\\s*=)/);\n}\n","import { Transform } from \"node:stream\";\nimport { renderToPipeableStream } from \"react-dom/server\";\nimport { renderDocumentShell } from \"../document/render\";\nimport type { LoadedRouteMatch } from \"../router\";\nimport { createPageRenderTree } from \"../server/render-tree\";\nimport {\n renderPageResponse,\n type SsrRenderOptions,\n} from \"../server/ssr\";\n\nconst streamRootMarker = '<template data-demiurge-stream-root=\"\"></template>';\n\nexport function renderNodePageResponse(\n match: LoadedRouteMatch,\n options: SsrRenderOptions = {},\n) {\n return match.render.mode === \"streaming\"\n ? renderStreamingPageResponse(match, options)\n : renderPageResponse(match, options);\n}\n\nexport async function renderStreamingPageResponse(\n match: LoadedRouteMatch,\n options: SsrRenderOptions = {},\n) {\n if (options.signal?.aborted) {\n throw options.signal.reason;\n }\n\n const shell = await createDocumentShell(match, options);\n const content = createPageRenderTree(match);\n\n return await new Promise<Response>((resolveResponse, rejectResponse) => {\n let completed = false;\n let cancelled = false;\n let responseCommitted = false;\n let stream = undefined as ReturnType<typeof renderToPipeableStream> | undefined;\n const documentStream = new Transform({\n destroy(error, callback) {\n if (!completed) {\n cancelled = true;\n }\n\n callback(error);\n },\n flush(callback) {\n callback(null, shell.suffix);\n },\n transform(chunk, _encoding, callback) {\n callback(null, chunk);\n },\n });\n const abort = () => {\n cancelled = true;\n stream?.abort(options.signal?.reason);\n documentStream.destroy();\n };\n const cleanup = () => options.signal?.removeEventListener(\"abort\", abort);\n\n documentStream.once(\"finish\", () => {\n completed = true;\n });\n documentStream.once(\"close\", () => {\n cleanup();\n\n if (!completed) {\n cancelled = true;\n stream?.abort(new Error(\"Demiurge streaming response was cancelled.\"));\n }\n });\n options.signal?.addEventListener(\"abort\", abort, { once: true });\n\n stream = renderToPipeableStream(content, {\n nonce: options.nonce,\n onError(error) {\n if (responseCommitted && !cancelled) {\n options.onStreamError?.(error);\n }\n },\n onShellError(error) {\n cleanup();\n rejectResponse(error);\n },\n onShellReady() {\n responseCommitted = true;\n documentStream.push(shell.prefix);\n stream?.pipe(documentStream);\n resolveResponse(\n new Response(toWebReadableStream(documentStream), {\n headers: { \"content-type\": \"text/html; charset=utf-8\" },\n }),\n );\n },\n });\n });\n}\n\nfunction toWebReadableStream(stream: Transform) {\n let closed = false;\n let removeListeners = () => {};\n\n return new ReadableStream<Uint8Array>({\n cancel() {\n closed = true;\n removeListeners();\n stream.pause();\n stream.destroy();\n },\n pull() {\n stream.resume();\n },\n start(controller) {\n stream.on(\"data\", onData);\n stream.once(\"end\", onEnd);\n stream.once(\"error\", onError);\n stream.once(\"close\", onClose);\n\n function onData(chunk: Buffer) {\n if (closed) {\n return;\n }\n\n controller.enqueue(Uint8Array.from(chunk));\n\n if ((controller.desiredSize ?? 1) <= 0) {\n stream.pause();\n }\n }\n\n function onEnd() {\n if (!closed) {\n closed = true;\n cleanup();\n controller.close();\n }\n }\n\n function onError(error: Error) {\n if (!closed) {\n closed = true;\n cleanup();\n controller.error(error);\n }\n }\n\n function onClose() {\n if (!closed) {\n closed = true;\n cleanup();\n controller.close();\n }\n }\n\n function cleanup() {\n stream.off(\"data\", onData);\n stream.off(\"end\", onEnd);\n stream.off(\"error\", onError);\n stream.off(\"close\", onClose);\n }\n\n removeListeners = cleanup;\n },\n });\n}\n\nasync function createDocumentShell(\n match: LoadedRouteMatch,\n options: SsrRenderOptions,\n) {\n const shell = renderDocumentShell({\n body: { data: match.data, navigation: options.navigation },\n entrySrc: options.clientEntry,\n lang: options.lang,\n links: match.links,\n metadata: match.metadata,\n nonce: options.nonce,\n scripts: match.scripts,\n styles: options.styles,\n title: options.title,\n });\n\n if (!options.transformDocument) {\n return shell;\n }\n\n const transformed = await options.transformDocument(\n `${shell.prefix}${streamRootMarker}${shell.suffix}`,\n );\n const markerIndex = transformed.indexOf(streamRootMarker);\n\n if (\n markerIndex === -1 ||\n transformed.indexOf(streamRootMarker, markerIndex + streamRootMarker.length) !== -1\n ) {\n throw new Error(\n \"Demiurge streaming document transform must preserve the root marker exactly once.\",\n );\n }\n\n return {\n prefix: transformed.slice(0, markerIndex),\n suffix: transformed.slice(markerIndex + streamRootMarker.length),\n };\n}\n"],"names":["forwardedHeaders","defaultTrustProxy","forbiddenMethods","UnsupportedMethodError","method","UntrustedHostError","host","validateNodeOriginPolicy","policy","parseAuthority","trustProxy","range","network","ipMatchesRange","toWebRequest","request","options","peerAddress","normalizeIpAddress","proxy","resolveProxyChain","forwardedProtocol","selectForwardedValue","protocol","resolveProtocol","authority","validateAllowedHost","origin","url","init","toHeaders","Readable","webRequest","setRequestConnectionMetadata","allowedHosts","candidate","expected","value","parsed","forwardedFor","forwarded","headerValues","chain","clientHops","index","trustedHops","isAddressTrusted","header","trustedDepth","values","item","address","ranges","networkValue","prefixValue","addressBytes","ipBytes","networkBytes","maximumPrefix","prefix","bit","mask","version","isIP","left","right","leftGroups","rightGroups","missing","group","writeNotImplemented","serverResponse","writeWebResponse","webResponse","cookies","getSetCookies","name","pipeline","error","isClientDisconnect","clientDisconnectCodes","headers","nextHeaders","getSetCookie","combined","splitSetCookies","streamRootMarker","renderNodePageResponse","match","renderStreamingPageResponse","renderPageResponse","shell","createDocumentShell","content","createPageRenderTree","resolveResponse","rejectResponse","completed","cancelled","responseCommitted","stream","documentStream","Transform","callback","chunk","_encoding","abort","cleanup","renderToPipeableStream","toWebReadableStream","closed","removeListeners","controller","onData","onEnd","onError","onClose","renderDocumentShell","transformed","markerIndex"],"mappings":"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"}
1
+ {"version":3,"file":"streaming-DN1DnbRE.js","sources":["../../src/node/http.ts","../../src/node/streaming.ts"],"sourcesContent":["import { Readable } from \"node:stream\";\nimport { pipeline } from \"node:stream/promises\";\nimport { isIP } from \"node:net\";\nimport type {\n IncomingHttpHeaders,\n IncomingMessage,\n ServerResponse,\n} from \"node:http\";\nimport { setRequestConnectionMetadata } from \"../server/request-metadata\";\n\nexport type HttpScheme = \"http\" | \"https\";\n\nexport type NodeOriginPolicy = {\n allowedHosts: readonly string[];\n trustProxy?: TrustProxy;\n};\n\nexport type ToWebRequestOptions = NodeOriginPolicy & {\n signal?: AbortSignal;\n};\n\nexport type TrustProxy =\n | false\n | { hops: number }\n | { ranges: readonly string[] };\n\nconst forwardedHeaders = {\n for: \"x-forwarded-for\",\n host: \"x-forwarded-host\",\n protocol: \"x-forwarded-proto\",\n} as const satisfies Record<\"for\" | \"host\" | \"protocol\", string>;\nconst defaultTrustProxy = false satisfies TrustProxy;\n\n// The Fetch specification prohibits these methods in the `Request` constructor.\n// `new Request(...)` throws for them. Without this guard, an unauthenticated\n// client can make a generic 500 response and add stack traces to the server log.\nconst forbiddenMethods = new Set([\"CONNECT\", \"TRACE\", \"TRACK\"]);\n\nexport class UnsupportedMethodError extends Error {\n method: string;\n\n constructor(method: string) {\n super(`HTTP method \"${method}\" is not supported.`);\n this.method = method;\n this.name = \"UnsupportedMethodError\";\n }\n}\n\nexport class UntrustedHostError extends Error {\n host: string;\n\n constructor(host: string) {\n super(`HTTP host \"${host}\" is not allowed.`);\n this.host = host;\n this.name = \"UntrustedHostError\";\n }\n}\n\nexport function validateNodeOriginPolicy(policy: NodeOriginPolicy) {\n if (policy.allowedHosts.length === 0) {\n throw new Error(\"Demiurge Node allowedHosts must contain at least one host.\");\n }\n\n for (const host of policy.allowedHosts) {\n if (!parseAuthority(host)) {\n throw new Error(`Demiurge Node allowed host \"${host}\" is invalid.`);\n }\n }\n\n const trustProxy = policy.trustProxy ?? defaultTrustProxy;\n\n if (trustProxy === false) {\n return;\n }\n\n if (\"hops\" in trustProxy) {\n if (!Number.isSafeInteger(trustProxy.hops) || trustProxy.hops < 0) {\n throw new Error(\n \"Demiurge Node trustProxy hop count must be a non-negative integer.\",\n );\n }\n\n return;\n }\n\n for (const range of trustProxy.ranges) {\n const network = range.split(\"/\")[0];\n ipMatchesRange(network, range);\n }\n}\n\nexport function toWebRequest(\n request: IncomingMessage,\n options: ToWebRequestOptions,\n) {\n validateNodeOriginPolicy(options);\n const method = request.method ?? \"GET\";\n\n if (forbiddenMethods.has(method.toUpperCase())) {\n throw new UnsupportedMethodError(method);\n }\n\n const peerAddress = normalizeIpAddress(request.socket?.remoteAddress);\n const proxy = resolveProxyChain(\n peerAddress,\n request.headers[forwardedHeaders.for],\n options.trustProxy ?? defaultTrustProxy,\n );\n const forwardedProtocol = selectForwardedValue(\n request.headers[forwardedHeaders.protocol],\n proxy.forwardedDepth,\n );\n const protocol = resolveProtocol(request, forwardedProtocol);\n const host = selectForwardedValue(\n request.headers[forwardedHeaders.host],\n proxy.forwardedDepth,\n ) ?? request.headers.host;\n const authority = validateAllowedHost(host, options.allowedHosts);\n const origin = `${protocol}://${authority}`;\n const url = new URL(request.url ?? \"/\", origin);\n const init: RequestInit & { duplex?: \"half\" } = {\n headers: toHeaders(request.headers),\n method,\n signal: options.signal,\n };\n\n if (method !== \"GET\" && method !== \"HEAD\") {\n init.body = Readable.toWeb(request) as ReadableStream;\n init.duplex = \"half\";\n }\n\n const webRequest = new Request(url, init);\n setRequestConnectionMetadata(webRequest, { clientIp: proxy.clientIp });\n\n return webRequest;\n}\n\nfunction resolveProtocol(\n request: IncomingMessage,\n forwardedProtocol: string | undefined,\n) {\n if (forwardedProtocol) {\n const protocol = forwardedProtocol.toLowerCase();\n\n if (protocol !== \"http\" && protocol !== \"https\") {\n throw new Error(`Unsupported forwarded protocol \"${forwardedProtocol}\".`);\n }\n\n return protocol;\n }\n\n return (request.socket as { encrypted?: boolean } | undefined)?.encrypted\n ? \"https\"\n : \"http\";\n}\n\nfunction validateAllowedHost(\n host: string | undefined,\n allowedHosts: readonly string[],\n) {\n if (allowedHosts.length === 0) {\n throw new Error(\"Demiurge Node allowedHosts must contain at least one host.\");\n }\n\n if (!host) {\n throw new UntrustedHostError(\"\");\n }\n\n const authority = parseAuthority(host);\n\n if (!authority) {\n throw new UntrustedHostError(host);\n }\n\n const allowed = allowedHosts.some((candidate) => {\n const expected = parseAuthority(candidate);\n\n if (!expected) {\n throw new Error(`Demiurge Node allowed host \"${candidate}\" is invalid.`);\n }\n\n return expected.port\n ? expected.host === authority.host\n : expected.hostname === authority.hostname;\n });\n\n if (!allowed) {\n throw new UntrustedHostError(host);\n }\n\n return authority.host;\n}\n\nfunction parseAuthority(value: string) {\n if (value.trim() !== value || value.includes(\"@\")) {\n return null;\n }\n\n try {\n const parsed = new URL(`http://${value}`);\n\n if (\n !parsed.hostname ||\n parsed.pathname !== \"/\" ||\n parsed.search ||\n parsed.hash ||\n parsed.host.toLowerCase() !== value.toLowerCase()\n ) {\n return null;\n }\n\n return parsed;\n } catch {\n return null;\n }\n}\n\nfunction resolveProxyChain(\n peerAddress: string,\n forwardedFor: string | readonly string[] | undefined,\n trustProxy: TrustProxy,\n) {\n const forwarded = headerValues(forwardedFor);\n const chain = [...forwarded, peerAddress];\n\n if (trustProxy === false) {\n return { clientIp: peerAddress, forwardedDepth: 0 };\n }\n\n if (\"hops\" in trustProxy) {\n if (!Number.isSafeInteger(trustProxy.hops) || trustProxy.hops < 0) {\n throw new Error(\n \"Demiurge Node trustProxy hop count must be a non-negative integer.\",\n );\n }\n\n const clientHops = Math.min(trustProxy.hops, forwarded.length);\n\n return {\n clientIp: chain[chain.length - 1 - clientHops],\n forwardedDepth: trustProxy.hops,\n };\n }\n\n let index = chain.length - 1;\n let trustedHops = 0;\n\n while (\n index > 0 &&\n isAddressTrusted(chain[index], trustProxy.ranges)\n ) {\n index -= 1;\n trustedHops += 1;\n }\n\n return {\n clientIp: chain[index],\n forwardedDepth:\n trustedHops || (isAddressTrusted(peerAddress, trustProxy.ranges) ? 1 : 0),\n };\n}\n\nfunction selectForwardedValue(\n header: string | readonly string[] | undefined,\n trustedDepth: number,\n) {\n if (trustedDepth === 0) {\n return undefined;\n }\n\n const values = headerValues(header);\n\n if (values.length === 0) {\n return undefined;\n }\n\n return values[Math.max(0, values.length - trustedDepth)];\n}\n\nfunction headerValues(value: string | readonly string[] | undefined) {\n return (Array.isArray(value) ? value : [value])\n .flatMap((item) => item?.split(\",\") ?? [])\n .map((item) => item.trim())\n .filter(Boolean);\n}\n\nfunction isAddressTrusted(address: string, ranges: readonly string[]) {\n return ranges.some((range) => ipMatchesRange(address, range));\n}\n\nfunction ipMatchesRange(address: string, range: string) {\n const [networkValue, prefixValue] = range.split(\"/\");\n const addressBytes = ipBytes(normalizeIpAddress(address));\n const networkBytes = ipBytes(normalizeIpAddress(networkValue));\n\n if (!addressBytes || !networkBytes || addressBytes.length !== networkBytes.length) {\n if (!networkBytes) {\n throw new Error(`Demiurge Node trustProxy range \"${range}\" is invalid.`);\n }\n\n return false;\n }\n\n const maximumPrefix = addressBytes.length * 8;\n const prefix = prefixValue === undefined ? maximumPrefix : Number(prefixValue);\n\n if (!Number.isInteger(prefix) || prefix < 0 || prefix > maximumPrefix) {\n throw new Error(`Demiurge Node trustProxy range \"${range}\" is invalid.`);\n }\n\n for (let bit = 0; bit < prefix; bit += 1) {\n const mask = 1 << (7 - (bit % 8));\n\n if ((addressBytes[Math.floor(bit / 8)] & mask) !==\n (networkBytes[Math.floor(bit / 8)] & mask)) {\n return false;\n }\n }\n\n return true;\n}\n\nfunction normalizeIpAddress(address: string | undefined) {\n if (!address) {\n return \"unknown\";\n }\n\n return address.startsWith(\"::ffff:\") ? address.slice(7) : address;\n}\n\nfunction ipBytes(address: string) {\n const version = isIP(address);\n\n if (version === 4) {\n return address.split(\".\").map(Number);\n }\n\n if (version !== 6) {\n return null;\n }\n\n const [left = \"\", right = \"\"] = address.split(\"::\");\n const leftGroups = left ? left.split(\":\") : [];\n const rightGroups = right ? right.split(\":\") : [];\n const missing = 8 - leftGroups.length - rightGroups.length;\n const groups = [\n ...leftGroups,\n ...Array.from({ length: missing }, () => \"0\"),\n ...rightGroups,\n ];\n\n return groups.flatMap((group) => {\n const value = Number.parseInt(group, 16);\n return [value >> 8, value & 255];\n });\n}\n\n// Shared by the Node adapter and the Vite dev middleware so a request the\n// Fetch layer cannot represent gets the same answer in both.\nexport function writeNotImplemented(serverResponse: ServerResponse) {\n serverResponse.statusCode = 501;\n serverResponse.setHeader(\"content-type\", \"text/plain; charset=utf-8\");\n serverResponse.end(\"Not Implemented\");\n}\n\nexport async function writeWebResponse(\n serverResponse: ServerResponse,\n webResponse: Response,\n) {\n // `Headers.forEach` joins repeated headers with a comma, which is wrong for\n // `set-cookie`: two cookies would arrive as one malformed header. Node's\n // `setHeader` takes an array for exactly this case.\n const cookies = getSetCookies(webResponse.headers);\n\n webResponse.headers.forEach((value, name) => {\n if (name === \"set-cookie\") {\n return;\n }\n\n serverResponse.setHeader(name, value);\n });\n\n if (cookies.length > 0) {\n serverResponse.setHeader(\"set-cookie\", cookies);\n }\n\n serverResponse.statusCode = webResponse.status;\n\n // An empty status text would otherwise overwrite Node's default reason\n // phrase with nothing at all.\n if (webResponse.statusText) {\n serverResponse.statusMessage = webResponse.statusText;\n }\n\n if (!webResponse.body) {\n serverResponse.end();\n return;\n }\n\n // `Readable.pipe()` does not destroy its source when the destination closes\n // or has an error. An aborted client can leave the source stream open. It can\n // also leave an associated file descriptor open. `pipeline` destroys the\n // source when either side closes.\n try {\n await pipeline(\n Readable.fromWeb(\n webResponse.body as unknown as import(\"node:stream/web\").ReadableStream,\n ),\n serverResponse,\n );\n } catch (error) {\n if (!isClientDisconnect(error)) {\n throw error;\n }\n }\n}\n\n// A client disconnect during a response is ordinary traffic, not a server\n// fault. A new throw would run the caller error path for each canceled download.\n// This path records a stack trace and creates an unused 500 response. An\n// unauthenticated client can cause this condition.\nconst clientDisconnectCodes = new Set([\n \"ECONNRESET\",\n \"EPIPE\",\n \"ERR_STREAM_DESTROYED\",\n \"ERR_STREAM_PREMATURE_CLOSE\",\n]);\n\nfunction isClientDisconnect(error: unknown) {\n return (\n error instanceof Error &&\n \"code\" in error &&\n typeof error.code === \"string\" &&\n clientDisconnectCodes.has(error.code)\n );\n}\n\nexport function toHeaders(headers: IncomingHttpHeaders) {\n const nextHeaders = new Headers();\n\n for (const [name, value] of Object.entries(headers)) {\n if (Array.isArray(value)) {\n for (const item of value) {\n nextHeaders.append(name, item);\n }\n continue;\n }\n\n if (value) {\n nextHeaders.set(name, value);\n }\n }\n\n return nextHeaders;\n}\n\nfunction getSetCookies(headers: Headers) {\n const getSetCookie = (headers as Headers & {\n getSetCookie?: () => string[];\n }).getSetCookie;\n\n if (getSetCookie) {\n return getSetCookie.call(headers);\n }\n\n const combined = headers.get(\"set-cookie\");\n\n return combined ? splitSetCookies(combined) : [];\n}\n\nfunction splitSetCookies(value: string) {\n return value.split(/,\\s*(?=[^;,=\\s]+\\s*=)/);\n}\n","import { Transform } from \"node:stream\";\nimport { renderToPipeableStream } from \"react-dom/server\";\nimport { renderDocumentShell } from \"../document/render\";\nimport type { LoadedRouteMatch } from \"../router\";\nimport { createPageRenderTree } from \"../server/render-tree\";\nimport {\n renderPageResponse,\n type SsrRenderOptions,\n} from \"../server/ssr\";\n\nconst streamRootMarker = '<template data-demiurge-stream-root=\"\"></template>';\n\nexport function renderNodePageResponse(\n match: LoadedRouteMatch,\n options: SsrRenderOptions = {},\n) {\n return match.render.mode === \"streaming\"\n ? renderStreamingPageResponse(match, options)\n : renderPageResponse(match, options);\n}\n\nexport async function renderStreamingPageResponse(\n match: LoadedRouteMatch,\n options: SsrRenderOptions = {},\n) {\n if (options.signal?.aborted) {\n throw options.signal.reason;\n }\n\n const shell = await createDocumentShell(match, options);\n const content = createPageRenderTree(match);\n\n return await new Promise<Response>((resolveResponse, rejectResponse) => {\n let completed = false;\n let cancelled = false;\n let responseCommitted = false;\n let stream = undefined as ReturnType<typeof renderToPipeableStream> | undefined;\n const documentStream = new Transform({\n destroy(error, callback) {\n if (!completed) {\n cancelled = true;\n }\n\n callback(error);\n },\n flush(callback) {\n callback(null, shell.suffix);\n },\n transform(chunk, _encoding, callback) {\n callback(null, chunk);\n },\n });\n const abort = () => {\n cancelled = true;\n stream?.abort(options.signal?.reason);\n documentStream.destroy();\n };\n const cleanup = () => options.signal?.removeEventListener(\"abort\", abort);\n\n documentStream.once(\"finish\", () => {\n completed = true;\n });\n documentStream.once(\"close\", () => {\n cleanup();\n\n if (!completed) {\n cancelled = true;\n stream?.abort(new Error(\"Demiurge streaming response was cancelled.\"));\n }\n });\n options.signal?.addEventListener(\"abort\", abort, { once: true });\n\n stream = renderToPipeableStream(content, {\n nonce: options.nonce,\n onError(error) {\n if (responseCommitted && !cancelled) {\n options.onStreamError?.(error);\n }\n },\n onShellError(error) {\n cleanup();\n rejectResponse(error);\n },\n onShellReady() {\n responseCommitted = true;\n documentStream.push(shell.prefix);\n stream?.pipe(documentStream);\n resolveResponse(\n new Response(toWebReadableStream(documentStream), {\n headers: { \"content-type\": \"text/html; charset=utf-8\" },\n }),\n );\n },\n });\n });\n}\n\nfunction toWebReadableStream(stream: Transform) {\n let closed = false;\n let removeListeners = () => {};\n\n return new ReadableStream<Uint8Array>({\n cancel() {\n closed = true;\n removeListeners();\n stream.pause();\n stream.destroy();\n },\n pull() {\n stream.resume();\n },\n start(controller) {\n stream.on(\"data\", onData);\n stream.once(\"end\", onEnd);\n stream.once(\"error\", onError);\n stream.once(\"close\", onClose);\n\n function onData(chunk: Buffer) {\n if (closed) {\n return;\n }\n\n controller.enqueue(Uint8Array.from(chunk));\n\n if ((controller.desiredSize ?? 1) <= 0) {\n stream.pause();\n }\n }\n\n function onEnd() {\n if (!closed) {\n closed = true;\n cleanup();\n controller.close();\n }\n }\n\n function onError(error: Error) {\n if (!closed) {\n closed = true;\n cleanup();\n controller.error(error);\n }\n }\n\n function onClose() {\n if (!closed) {\n closed = true;\n cleanup();\n controller.close();\n }\n }\n\n function cleanup() {\n stream.off(\"data\", onData);\n stream.off(\"end\", onEnd);\n stream.off(\"error\", onError);\n stream.off(\"close\", onClose);\n }\n\n removeListeners = cleanup;\n },\n });\n}\n\nasync function createDocumentShell(\n match: LoadedRouteMatch,\n options: SsrRenderOptions,\n) {\n const shell = renderDocumentShell({\n body: { data: match.data, navigation: options.navigation },\n entrySrc: options.clientEntry,\n lang: options.lang,\n links: match.links,\n metadata: match.metadata,\n nonce: options.nonce,\n scripts: match.scripts,\n styles: options.styles,\n title: options.title,\n });\n\n if (!options.transformDocument) {\n return shell;\n }\n\n const transformed = await options.transformDocument(\n `${shell.prefix}${streamRootMarker}${shell.suffix}`,\n );\n const markerIndex = transformed.indexOf(streamRootMarker);\n\n if (\n markerIndex === -1 ||\n transformed.indexOf(streamRootMarker, markerIndex + streamRootMarker.length) !== -1\n ) {\n throw new Error(\n \"Demiurge streaming document transform must preserve the root marker exactly once.\",\n );\n }\n\n return {\n prefix: transformed.slice(0, markerIndex),\n suffix: transformed.slice(markerIndex + streamRootMarker.length),\n };\n}\n"],"names":["forwardedHeaders","defaultTrustProxy","forbiddenMethods","UnsupportedMethodError","method","UntrustedHostError","host","validateNodeOriginPolicy","policy","parseAuthority","trustProxy","range","network","ipMatchesRange","toWebRequest","request","options","peerAddress","normalizeIpAddress","proxy","resolveProxyChain","forwardedProtocol","selectForwardedValue","protocol","resolveProtocol","authority","validateAllowedHost","origin","url","init","toHeaders","Readable","webRequest","setRequestConnectionMetadata","allowedHosts","candidate","expected","value","parsed","forwardedFor","forwarded","headerValues","chain","clientHops","index","trustedHops","isAddressTrusted","header","trustedDepth","values","item","address","ranges","networkValue","prefixValue","addressBytes","ipBytes","networkBytes","maximumPrefix","prefix","bit","mask","version","isIP","left","right","leftGroups","rightGroups","missing","group","writeNotImplemented","serverResponse","writeWebResponse","webResponse","cookies","getSetCookies","name","pipeline","error","isClientDisconnect","clientDisconnectCodes","headers","nextHeaders","getSetCookie","combined","splitSetCookies","streamRootMarker","renderNodePageResponse","match","renderStreamingPageResponse","renderPageResponse","shell","createDocumentShell","content","createPageRenderTree","resolveResponse","rejectResponse","completed","cancelled","responseCommitted","stream","documentStream","Transform","callback","chunk","_encoding","abort","cleanup","renderToPipeableStream","toWebReadableStream","closed","removeListeners","controller","onData","onEnd","onError","onClose","renderDocumentShell","transformed","markerIndex"],"mappings":"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"}