@quilted/quilt 0.5.130 → 0.5.131

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.
@@ -1,34 +1,39 @@
1
- import { renderHtmlToString, Html } from '@quilted/react-html/server';
1
+ import { Fragment as Fragment$1 } from 'react';
2
+ import { styleAssetPreloadAttributes, scriptAssetPreloadAttributes, styleAssetAttributes, scriptAssetAttributes } from '@quilted/async/server';
3
+ import { AsyncAssetManager } from '@quilted/react-async/server';
4
+ import { HttpManager } from '@quilted/react-http/server';
5
+ import { HtmlManager, renderHtmlToString, Html } from '@quilted/react-html/server';
6
+ import { extract } from '@quilted/react-server-render/server';
2
7
  import { redirect, html } from '@quilted/request-router';
3
- import { renderApp } from './render.mjs';
4
- import { jsx } from 'react/jsx-runtime';
8
+ import { ServerContext } from './ServerContext.mjs';
9
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
5
10
 
6
11
  function createServerRender(render, {
7
12
  context,
13
+ stream,
8
14
  ...options
9
15
  } = {}) {
10
16
  return async (request, requestContext) => {
11
17
  const accepts = request.headers.get('Accept');
12
18
  if (accepts != null && !accepts.includes('text/html')) return;
13
19
  const app = await render(request, requestContext);
14
- return renderAppToResponse(app, request, {
20
+ const renderResponse = stream ? renderAppToStreamedResponse : renderAppToResponse;
21
+ return renderResponse(app, request, {
15
22
  ...options,
16
- context: context?.(request, requestContext) ?? requestContext
23
+ extract: {
24
+ ...options.extract,
25
+ context: options.extract ?? context?.(request, requestContext) ?? requestContext
26
+ }
17
27
  });
18
28
  };
19
29
  }
20
30
  async function renderAppToResponse(app, request, {
21
31
  assets,
22
- renderHtml = defaultRenderHtml,
23
- ...options
32
+ extract,
33
+ renderHtml
24
34
  } = {}) {
25
- const {
26
- html: htmlManager,
27
- http,
28
- rendered,
29
- asyncAssets
30
- } = await renderApp(app, {
31
- ...options,
35
+ const renderDetails = await serverRenderDetailsForApp(app, {
36
+ extract,
32
37
  url: request.url,
33
38
  headers: request.headers
34
39
  });
@@ -36,56 +41,200 @@ async function renderAppToResponse(app, request, {
36
41
  headers,
37
42
  statusCode = 200,
38
43
  redirectUrl
39
- } = http.state;
44
+ } = renderDetails.http.state;
40
45
  if (redirectUrl) {
41
46
  return redirect(redirectUrl, {
42
47
  status: statusCode,
43
48
  headers
44
49
  });
45
50
  }
51
+ const content = await renderAppDetailsToHtmlString(renderDetails, request, {
52
+ assets,
53
+ renderHtml
54
+ });
55
+ return html(content, {
56
+ headers,
57
+ status: statusCode
58
+ });
59
+ }
60
+ async function renderAppToStreamedResponse(app, request, {
61
+ assets,
62
+ extract,
63
+ renderHtml
64
+ } = {}) {
65
+ const headers = new Headers();
66
+ const stream = new TransformStream();
67
+ const assetContext = {
68
+ userAgent: request.headers.get('User-Agent')
69
+ };
70
+ const guaranteedAssets = await assets?.assets({
71
+ context: assetContext
72
+ });
73
+ if (guaranteedAssets) {
74
+ for (const style of guaranteedAssets.styles) {
75
+ headers.append('Link', preloadHeader(styleAssetPreloadAttributes(style)));
76
+ }
77
+ for (const script of guaranteedAssets.scripts) {
78
+ headers.append('Link', preloadHeader(scriptAssetPreloadAttributes(script)));
79
+ }
80
+ }
81
+ renderResponseToStream();
82
+ return html(stream.readable, {
83
+ headers,
84
+ status: 200
85
+ });
86
+ async function renderResponseToStream() {
87
+ const renderDetails = await serverRenderDetailsForApp(app, {
88
+ extract,
89
+ url: request.url,
90
+ headers: request.headers
91
+ });
92
+ const content = await renderAppDetailsToHtmlString(renderDetails, request, {
93
+ assets,
94
+ renderHtml
95
+ });
96
+ const writer = stream.writable.getWriter();
97
+ await writer.write(content);
98
+ await writer.close();
99
+ }
100
+ }
101
+ async function serverRenderDetailsForApp(app, {
102
+ url,
103
+ headers,
104
+ extract: extractOptions
105
+ } = {}) {
106
+ const html = new HtmlManager();
107
+ const asyncAssets = new AsyncAssetManager();
108
+ const http = new HttpManager({
109
+ headers
110
+ });
111
+ const {
112
+ decorate,
113
+ ...rest
114
+ } = extractOptions ?? {};
115
+ const rendered = await extract(app, {
116
+ decorate(app) {
117
+ return /*#__PURE__*/jsx(ServerContext, {
118
+ asyncAssets: asyncAssets,
119
+ http: http,
120
+ html: html,
121
+ url: url,
122
+ children: decorate?.(app) ?? app
123
+ });
124
+ },
125
+ ...rest
126
+ });
127
+ return {
128
+ rendered,
129
+ http,
130
+ html,
131
+ asyncAssets
132
+ };
133
+ }
134
+ async function renderAppDetailsToHtmlString(details, request, {
135
+ assets,
136
+ renderHtml = defaultRenderHtml
137
+ } = {}) {
138
+ const {
139
+ html: htmlManager,
140
+ http,
141
+ rendered,
142
+ asyncAssets
143
+ } = details;
46
144
  const usedAssets = asyncAssets.used({
47
145
  timing: 'load'
48
146
  });
49
- const assetOptions = {
147
+ const assetContext = {
50
148
  userAgent: request.headers.get('User-Agent')
51
149
  };
52
- const [styles, scripts, preload] = assets ? await Promise.all([assets.styles({
150
+ const [entryAssets, preloadAssets] = assets ? await Promise.all([assets.assets({
53
151
  async: usedAssets,
54
- options: assetOptions
55
- }), assets.scripts({
56
- async: usedAssets,
57
- options: assetOptions
152
+ context: assetContext
58
153
  }), assets.asyncAssets(asyncAssets.used({
59
154
  timing: 'preload'
60
155
  }), {
61
- options: assetOptions
62
- })]) : [[], [], []];
156
+ context: assetContext
157
+ })]) : [];
63
158
  const htmlElement = await renderHtml(rendered, request, {
64
159
  html: htmlManager,
65
160
  http,
66
- styles,
67
- scripts,
68
- preload
69
- });
70
- return html(renderHtmlToString(htmlElement), {
71
- headers,
72
- status: statusCode
161
+ assets: entryAssets,
162
+ preloadAssets
73
163
  });
164
+ return renderHtmlToString(htmlElement);
74
165
  }
75
- function defaultRenderHtml(content, request, {
166
+ const defaultRenderHtml = function defaultRenderHtml(content, request, {
76
167
  html,
77
- styles,
78
- scripts,
79
- preload
168
+ assets,
169
+ preloadAssets
80
170
  }) {
171
+ const baseUrl = new URL(request.url);
81
172
  return /*#__PURE__*/jsx(Html, {
82
- url: new URL(request.url),
83
173
  manager: html,
84
- styles: styles,
85
- scripts: scripts,
86
- preloadAssets: preload,
174
+ headEndContent: /*#__PURE__*/jsxs(Fragment, {
175
+ children: [assets && [...assets.styles].map(style => {
176
+ const attributes = styleAssetAttributes(style, {
177
+ baseUrl
178
+ });
179
+ return /*#__PURE__*/jsx("link", {
180
+ ...attributes
181
+ }, style.source);
182
+ }), assets && [...assets.scripts].map(script => {
183
+ const isModule = script.attributes.type === 'module';
184
+ const attributes = scriptAssetAttributes(script, {
185
+ baseUrl
186
+ });
187
+ if (isModule) {
188
+ return /*#__PURE__*/jsxs(Fragment$1, {
189
+ children: [/*#__PURE__*/jsx("link", {
190
+ ...scriptAssetPreloadAttributes(script)
191
+ }), /*#__PURE__*/jsx("script", {
192
+ ...attributes,
193
+ async: true
194
+ })]
195
+ }, script.source);
196
+ }
197
+ return /*#__PURE__*/jsx("script", {
198
+ ...attributes,
199
+ defer: true
200
+ }, script.source);
201
+ }), preloadAssets && [...preloadAssets.styles].map(style => {
202
+ const attributes = styleAssetPreloadAttributes(style, {
203
+ baseUrl
204
+ });
205
+ return /*#__PURE__*/jsx("link", {
206
+ ...attributes
207
+ }, style.source);
208
+ }), preloadAssets && [...preloadAssets.scripts].map(script => {
209
+ const attributes = scriptAssetPreloadAttributes(script, {
210
+ baseUrl
211
+ });
212
+ return /*#__PURE__*/jsx("link", {
213
+ ...attributes
214
+ }, script.source);
215
+ })]
216
+ }),
87
217
  children: content
88
218
  });
219
+ };
220
+ function preloadHeader(attributes) {
221
+ const {
222
+ as,
223
+ rel = 'preload',
224
+ href,
225
+ crossOrigin,
226
+ crossorigin
227
+ } = attributes;
228
+
229
+ // Support both property and attribute versions of the casing
230
+ const finalCrossOrigin = crossOrigin ?? crossorigin;
231
+ let header = `<${href}>; rel="${rel}"; as="${as}"`;
232
+ if (finalCrossOrigin === '' || finalCrossOrigin === true) {
233
+ header += `; crossorigin`;
234
+ } else if (typeof finalCrossOrigin === 'string') {
235
+ header += `; crossorigin="${finalCrossOrigin}"`;
236
+ }
237
+ return header;
89
238
  }
90
239
 
91
- export { createServerRender, renderAppToResponse };
240
+ export { createServerRender, renderAppToResponse, renderAppToStreamedResponse };
@@ -1,7 +1,8 @@
1
+ import { styleAssetAttributes, scriptAssetAttributes, styleAssetPreloadAttributes, scriptAssetPreloadAttributes } from '@quilted/async/server';
1
2
  import { renderHtmlToString, Html } from '@quilted/react-html/server';
2
3
  import { StaticRenderer, StaticRendererContext } from '@quilted/react-router/static';
3
4
  import { renderApp } from './render.mjs';
4
- import { jsx } from 'react/jsx-runtime';
5
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
5
6
 
6
7
  const BASE_URL = 'http://localhost:3000';
7
8
  async function renderStatic(App, {
@@ -173,30 +174,20 @@ async function renderStatic(App, {
173
174
  const usedAssets = asyncAssets.used({
174
175
  timing: 'load'
175
176
  });
176
- const [moduleStyles, moduleScripts, modulePreload, nomoduleStyles, nomoduleScripts] = await Promise.all([assets.styles({
177
+ const [moduleAssets, modulePreload, nomoduleAssets] = await Promise.all([assets.assets({
177
178
  async: usedAssets,
178
- options: {
179
- modules: true
180
- }
181
- }), assets.scripts({
182
- async: usedAssets,
183
- options: {
179
+ context: {
184
180
  modules: true
185
181
  }
186
182
  }), assets.asyncAssets(asyncAssets.used({
187
183
  timing: 'preload'
188
184
  }), {
189
- options: {
185
+ context: {
190
186
  modules: true
191
187
  }
192
- }), assets.styles({
193
- async: usedAssets,
194
- options: {
195
- modules: false
196
- }
197
- }), assets.scripts({
188
+ }), assets.assets({
198
189
  async: usedAssets,
199
- options: {
190
+ context: {
200
191
  modules: false
201
192
  }
202
193
  })]);
@@ -204,22 +195,49 @@ async function renderStatic(App, {
204
195
  // We don’t want to load styles from both bundles, so we only use module styles,
205
196
  // since modules are intended to be the default and CSS (usually) doesn’t
206
197
  // have features that meaningfully break older user agents.
207
- const styles = moduleStyles.length > 0 ? moduleStyles : nomoduleStyles;
208
-
209
- // If there are nomodule scripts, we can’t really do preloading, because we can’t
210
- // prevent the nomodule scripts from being preloaded in module browsers. If there
211
- // are only module scripts, we can preload those.
212
- const preload = nomoduleScripts.length > 0 ? [] : modulePreload;
213
- const scripts = [...moduleScripts, ...nomoduleScripts.map(script => ({
214
- ...script,
215
- nomodule: true
216
- }))];
198
+ const styles = moduleAssets.styles.length > 0 ? moduleAssets.styles : nomoduleAssets.styles;
217
199
  const minifiedHtml = renderHtmlToString( /*#__PURE__*/jsx(Html, {
218
- url: url,
219
200
  manager: htmlManager,
220
- styles: styles,
221
- scripts: scripts,
222
- preloadAssets: preload,
201
+ headEndContent: /*#__PURE__*/jsxs(Fragment, {
202
+ children: [[...styles].map(style => {
203
+ const attributes = styleAssetAttributes(style, {
204
+ baseUrl: url
205
+ });
206
+ return /*#__PURE__*/jsx("link", {
207
+ ...attributes
208
+ }, style.source);
209
+ }), [...moduleAssets.scripts].map(script => {
210
+ const attributes = scriptAssetAttributes(script, {
211
+ baseUrl: url
212
+ });
213
+ return /*#__PURE__*/jsx("script", {
214
+ ...attributes
215
+ }, script.source);
216
+ }), [...nomoduleAssets.scripts].map(script => {
217
+ const attributes = scriptAssetAttributes(script, {
218
+ baseUrl: url
219
+ });
220
+ return /*#__PURE__*/jsx("script", {
221
+ ...attributes,
222
+ // @ts-expect-error Rendering to HTML, so using the lowercase name
223
+ nomodule: moduleAssets.scripts.length > 0 ? true : undefined
224
+ }, script.source);
225
+ }), [...modulePreload.styles].map(style => {
226
+ const attributes = styleAssetPreloadAttributes(style, {
227
+ baseUrl: url
228
+ });
229
+ return /*#__PURE__*/jsx("link", {
230
+ ...attributes
231
+ }, style.source);
232
+ }), [...modulePreload.scripts].map(script => {
233
+ const attributes = scriptAssetPreloadAttributes(script, {
234
+ baseUrl: url
235
+ });
236
+ return /*#__PURE__*/jsx("link", {
237
+ ...attributes
238
+ }, script.source);
239
+ })]
240
+ }),
223
241
  children: markup
224
242
  }));
225
243
  const html = prettify ? await prettifyHtml(minifiedHtml) : minifiedHtml;
@@ -1,10 +1,9 @@
1
1
  export { SERVER_ACTION_ID as HTML_SERVER_ACTION_ID, Html, HtmlContext, HtmlManager, Serialize, renderHtmlToString } from '@quilted/react-html/server';
2
2
  export { ServerAction, ServerRenderManager, ServerRenderManagerContext, extract, useServerAction } from '@quilted/react-server-render/server';
3
- export { createAssetManifest } from '@quilted/async/server';
3
+ export { createAssetManifest, scriptAssetAttributes, scriptAssetPreloadAttributes, styleAssetAttributes, styleAssetPreloadAttributes } from '@quilted/async/server';
4
4
  export { SERVER_ACTION_ID as ASYNC_ASSETS_SERVER_ACTION_ID, AsyncAssetContext, AsyncAssetManager } from '@quilted/react-async/server';
5
5
  export { createRequestRouterLocalization } from '@quilted/react-localize/request-router';
6
6
  export { EnhancedRequest, EnhancedResponse, Request, Response, createHeaders, createRequestRouter } from '@quilted/request-router';
7
7
  export { parseAcceptLanguageHeader } from '@quilted/react-localize';
8
- export { renderApp } from './render.esnext';
9
8
  export { ServerContext } from './ServerContext.esnext';
10
- export { createServerRender, renderAppToResponse } from './request-router.esnext';
9
+ export { createServerRender, renderAppToResponse, renderAppToStreamedResponse } from './request-router.esnext';
@@ -1,34 +1,39 @@
1
- import { renderHtmlToString, Html } from '@quilted/react-html/server';
1
+ import { Fragment as Fragment$1 } from 'react';
2
+ import { styleAssetPreloadAttributes, scriptAssetPreloadAttributes, styleAssetAttributes, scriptAssetAttributes } from '@quilted/async/server';
3
+ import { AsyncAssetManager } from '@quilted/react-async/server';
4
+ import { HttpManager } from '@quilted/react-http/server';
5
+ import { HtmlManager, renderHtmlToString, Html } from '@quilted/react-html/server';
6
+ import { extract } from '@quilted/react-server-render/server';
2
7
  import { redirect, html } from '@quilted/request-router';
3
- import { renderApp } from './render.esnext';
4
- import { jsx } from 'react/jsx-runtime';
8
+ import { ServerContext } from './ServerContext.esnext';
9
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
5
10
 
6
11
  function createServerRender(render, {
7
12
  context,
13
+ stream,
8
14
  ...options
9
15
  } = {}) {
10
16
  return async (request, requestContext) => {
11
17
  const accepts = request.headers.get('Accept');
12
18
  if (accepts != null && !accepts.includes('text/html')) return;
13
19
  const app = await render(request, requestContext);
14
- return renderAppToResponse(app, request, {
20
+ const renderResponse = stream ? renderAppToStreamedResponse : renderAppToResponse;
21
+ return renderResponse(app, request, {
15
22
  ...options,
16
- context: context?.(request, requestContext) ?? requestContext
23
+ extract: {
24
+ ...options.extract,
25
+ context: options.extract ?? context?.(request, requestContext) ?? requestContext
26
+ }
17
27
  });
18
28
  };
19
29
  }
20
30
  async function renderAppToResponse(app, request, {
21
31
  assets,
22
- renderHtml = defaultRenderHtml,
23
- ...options
32
+ extract,
33
+ renderHtml
24
34
  } = {}) {
25
- const {
26
- html: htmlManager,
27
- http,
28
- rendered,
29
- asyncAssets
30
- } = await renderApp(app, {
31
- ...options,
35
+ const renderDetails = await serverRenderDetailsForApp(app, {
36
+ extract,
32
37
  url: request.url,
33
38
  headers: request.headers
34
39
  });
@@ -36,56 +41,200 @@ async function renderAppToResponse(app, request, {
36
41
  headers,
37
42
  statusCode = 200,
38
43
  redirectUrl
39
- } = http.state;
44
+ } = renderDetails.http.state;
40
45
  if (redirectUrl) {
41
46
  return redirect(redirectUrl, {
42
47
  status: statusCode,
43
48
  headers
44
49
  });
45
50
  }
51
+ const content = await renderAppDetailsToHtmlString(renderDetails, request, {
52
+ assets,
53
+ renderHtml
54
+ });
55
+ return html(content, {
56
+ headers,
57
+ status: statusCode
58
+ });
59
+ }
60
+ async function renderAppToStreamedResponse(app, request, {
61
+ assets,
62
+ extract,
63
+ renderHtml
64
+ } = {}) {
65
+ const headers = new Headers();
66
+ const stream = new TransformStream();
67
+ const assetContext = {
68
+ userAgent: request.headers.get('User-Agent')
69
+ };
70
+ const guaranteedAssets = await assets?.assets({
71
+ context: assetContext
72
+ });
73
+ if (guaranteedAssets) {
74
+ for (const style of guaranteedAssets.styles) {
75
+ headers.append('Link', preloadHeader(styleAssetPreloadAttributes(style)));
76
+ }
77
+ for (const script of guaranteedAssets.scripts) {
78
+ headers.append('Link', preloadHeader(scriptAssetPreloadAttributes(script)));
79
+ }
80
+ }
81
+ renderResponseToStream();
82
+ return html(stream.readable, {
83
+ headers,
84
+ status: 200
85
+ });
86
+ async function renderResponseToStream() {
87
+ const renderDetails = await serverRenderDetailsForApp(app, {
88
+ extract,
89
+ url: request.url,
90
+ headers: request.headers
91
+ });
92
+ const content = await renderAppDetailsToHtmlString(renderDetails, request, {
93
+ assets,
94
+ renderHtml
95
+ });
96
+ const writer = stream.writable.getWriter();
97
+ await writer.write(content);
98
+ await writer.close();
99
+ }
100
+ }
101
+ async function serverRenderDetailsForApp(app, {
102
+ url,
103
+ headers,
104
+ extract: extractOptions
105
+ } = {}) {
106
+ const html = new HtmlManager();
107
+ const asyncAssets = new AsyncAssetManager();
108
+ const http = new HttpManager({
109
+ headers
110
+ });
111
+ const {
112
+ decorate,
113
+ ...rest
114
+ } = extractOptions ?? {};
115
+ const rendered = await extract(app, {
116
+ decorate(app) {
117
+ return /*#__PURE__*/jsx(ServerContext, {
118
+ asyncAssets: asyncAssets,
119
+ http: http,
120
+ html: html,
121
+ url: url,
122
+ children: decorate?.(app) ?? app
123
+ });
124
+ },
125
+ ...rest
126
+ });
127
+ return {
128
+ rendered,
129
+ http,
130
+ html,
131
+ asyncAssets
132
+ };
133
+ }
134
+ async function renderAppDetailsToHtmlString(details, request, {
135
+ assets,
136
+ renderHtml = defaultRenderHtml
137
+ } = {}) {
138
+ const {
139
+ html: htmlManager,
140
+ http,
141
+ rendered,
142
+ asyncAssets
143
+ } = details;
46
144
  const usedAssets = asyncAssets.used({
47
145
  timing: 'load'
48
146
  });
49
- const assetOptions = {
147
+ const assetContext = {
50
148
  userAgent: request.headers.get('User-Agent')
51
149
  };
52
- const [styles, scripts, preload] = assets ? await Promise.all([assets.styles({
150
+ const [entryAssets, preloadAssets] = assets ? await Promise.all([assets.assets({
53
151
  async: usedAssets,
54
- options: assetOptions
55
- }), assets.scripts({
56
- async: usedAssets,
57
- options: assetOptions
152
+ context: assetContext
58
153
  }), assets.asyncAssets(asyncAssets.used({
59
154
  timing: 'preload'
60
155
  }), {
61
- options: assetOptions
62
- })]) : [[], [], []];
156
+ context: assetContext
157
+ })]) : [];
63
158
  const htmlElement = await renderHtml(rendered, request, {
64
159
  html: htmlManager,
65
160
  http,
66
- styles,
67
- scripts,
68
- preload
69
- });
70
- return html(renderHtmlToString(htmlElement), {
71
- headers,
72
- status: statusCode
161
+ assets: entryAssets,
162
+ preloadAssets
73
163
  });
164
+ return renderHtmlToString(htmlElement);
74
165
  }
75
- function defaultRenderHtml(content, request, {
166
+ const defaultRenderHtml = function defaultRenderHtml(content, request, {
76
167
  html,
77
- styles,
78
- scripts,
79
- preload
168
+ assets,
169
+ preloadAssets
80
170
  }) {
171
+ const baseUrl = new URL(request.url);
81
172
  return /*#__PURE__*/jsx(Html, {
82
- url: new URL(request.url),
83
173
  manager: html,
84
- styles: styles,
85
- scripts: scripts,
86
- preloadAssets: preload,
174
+ headEndContent: /*#__PURE__*/jsxs(Fragment, {
175
+ children: [assets && [...assets.styles].map(style => {
176
+ const attributes = styleAssetAttributes(style, {
177
+ baseUrl
178
+ });
179
+ return /*#__PURE__*/jsx("link", {
180
+ ...attributes
181
+ }, style.source);
182
+ }), assets && [...assets.scripts].map(script => {
183
+ const isModule = script.attributes.type === 'module';
184
+ const attributes = scriptAssetAttributes(script, {
185
+ baseUrl
186
+ });
187
+ if (isModule) {
188
+ return /*#__PURE__*/jsxs(Fragment$1, {
189
+ children: [/*#__PURE__*/jsx("link", {
190
+ ...scriptAssetPreloadAttributes(script)
191
+ }), /*#__PURE__*/jsx("script", {
192
+ ...attributes,
193
+ async: true
194
+ })]
195
+ }, script.source);
196
+ }
197
+ return /*#__PURE__*/jsx("script", {
198
+ ...attributes,
199
+ defer: true
200
+ }, script.source);
201
+ }), preloadAssets && [...preloadAssets.styles].map(style => {
202
+ const attributes = styleAssetPreloadAttributes(style, {
203
+ baseUrl
204
+ });
205
+ return /*#__PURE__*/jsx("link", {
206
+ ...attributes
207
+ }, style.source);
208
+ }), preloadAssets && [...preloadAssets.scripts].map(script => {
209
+ const attributes = scriptAssetPreloadAttributes(script, {
210
+ baseUrl
211
+ });
212
+ return /*#__PURE__*/jsx("link", {
213
+ ...attributes
214
+ }, script.source);
215
+ })]
216
+ }),
87
217
  children: content
88
218
  });
219
+ };
220
+ function preloadHeader(attributes) {
221
+ const {
222
+ as,
223
+ rel = 'preload',
224
+ href,
225
+ crossOrigin,
226
+ crossorigin
227
+ } = attributes;
228
+
229
+ // Support both property and attribute versions of the casing
230
+ const finalCrossOrigin = crossOrigin ?? crossorigin;
231
+ let header = `<${href}>; rel="${rel}"; as="${as}"`;
232
+ if (finalCrossOrigin === '' || finalCrossOrigin === true) {
233
+ header += `; crossorigin`;
234
+ } else if (typeof finalCrossOrigin === 'string') {
235
+ header += `; crossorigin="${finalCrossOrigin}"`;
236
+ }
237
+ return header;
89
238
  }
90
239
 
91
- export { createServerRender, renderAppToResponse };
240
+ export { createServerRender, renderAppToResponse, renderAppToStreamedResponse };