@quilted/quilt 0.5.130 → 0.5.132

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
- function createServerRender(render, {
11
+ function createServerRender(getApp, {
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
- const app = await render(request, requestContext);
14
- return renderAppToResponse(app, request, {
19
+ const renderResponse = stream ? renderAppToStreamedResponse : renderAppToResponse;
20
+ return renderResponse(typeof getApp === 'function' ? () => getApp(request, requestContext) : getApp, request, {
15
21
  ...options,
16
- context: context?.(request, requestContext) ?? requestContext
22
+ extract: {
23
+ ...options.extract,
24
+ context: options.extract ?? context?.(request, requestContext) ?? requestContext
25
+ }
17
26
  });
18
27
  };
19
28
  }
20
- async function renderAppToResponse(app, request, {
29
+ async function renderAppToResponse(getApp, request, {
21
30
  assets,
22
- renderHtml = defaultRenderHtml,
23
- ...options
31
+ extract,
32
+ renderHtml
24
33
  } = {}) {
25
- const {
26
- html: htmlManager,
27
- http,
28
- rendered,
29
- asyncAssets
30
- } = await renderApp(app, {
31
- ...options,
34
+ const app = typeof getApp === 'function' ? await getApp() : getApp;
35
+ const renderDetails = await serverRenderDetailsForApp(app, {
36
+ extract,
32
37
  url: request.url,
33
38
  headers: request.headers
34
39
  });
@@ -36,56 +41,201 @@ 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(getApp, 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 app = typeof getApp === 'function' ? await getApp() : getApp;
88
+ const renderDetails = await serverRenderDetailsForApp(app, {
89
+ extract,
90
+ url: request.url,
91
+ headers: request.headers
92
+ });
93
+ const content = await renderAppDetailsToHtmlString(renderDetails, request, {
94
+ assets,
95
+ renderHtml
96
+ });
97
+ const writer = stream.writable.getWriter();
98
+ await writer.write(content);
99
+ await writer.close();
100
+ }
101
+ }
102
+ async function serverRenderDetailsForApp(app, {
103
+ url,
104
+ headers,
105
+ extract: extractOptions
106
+ } = {}) {
107
+ const html = new HtmlManager();
108
+ const asyncAssets = new AsyncAssetManager();
109
+ const http = new HttpManager({
110
+ headers
111
+ });
112
+ const {
113
+ decorate,
114
+ ...rest
115
+ } = extractOptions ?? {};
116
+ const rendered = await extract(app, {
117
+ decorate(app) {
118
+ return /*#__PURE__*/jsx(ServerContext, {
119
+ asyncAssets: asyncAssets,
120
+ http: http,
121
+ html: html,
122
+ url: url,
123
+ children: decorate?.(app) ?? app
124
+ });
125
+ },
126
+ ...rest
127
+ });
128
+ return {
129
+ rendered,
130
+ http,
131
+ html,
132
+ asyncAssets
133
+ };
134
+ }
135
+ async function renderAppDetailsToHtmlString(details, request, {
136
+ assets,
137
+ renderHtml = defaultRenderHtml
138
+ } = {}) {
139
+ const {
140
+ html: htmlManager,
141
+ http,
142
+ rendered,
143
+ asyncAssets
144
+ } = details;
46
145
  const usedAssets = asyncAssets.used({
47
146
  timing: 'load'
48
147
  });
49
- const assetOptions = {
148
+ const assetContext = {
50
149
  userAgent: request.headers.get('User-Agent')
51
150
  };
52
- const [styles, scripts, preload] = assets ? await Promise.all([assets.styles({
151
+ const [entryAssets, preloadAssets] = assets ? await Promise.all([assets.assets({
53
152
  async: usedAssets,
54
- options: assetOptions
55
- }), assets.scripts({
56
- async: usedAssets,
57
- options: assetOptions
153
+ context: assetContext
58
154
  }), assets.asyncAssets(asyncAssets.used({
59
155
  timing: 'preload'
60
156
  }), {
61
- options: assetOptions
62
- })]) : [[], [], []];
157
+ context: assetContext
158
+ })]) : [];
63
159
  const htmlElement = await renderHtml(rendered, request, {
64
160
  html: htmlManager,
65
161
  http,
66
- styles,
67
- scripts,
68
- preload
69
- });
70
- return html(renderHtmlToString(htmlElement), {
71
- headers,
72
- status: statusCode
162
+ assets: entryAssets,
163
+ preloadAssets
73
164
  });
165
+ return renderHtmlToString(htmlElement);
74
166
  }
75
- function defaultRenderHtml(content, request, {
167
+ const defaultRenderHtml = function defaultRenderHtml(content, request, {
76
168
  html,
77
- styles,
78
- scripts,
79
- preload
169
+ assets,
170
+ preloadAssets
80
171
  }) {
172
+ const baseUrl = new URL(request.url);
81
173
  return /*#__PURE__*/jsx(Html, {
82
- url: new URL(request.url),
83
174
  manager: html,
84
- styles: styles,
85
- scripts: scripts,
86
- preloadAssets: preload,
175
+ headEndContent: /*#__PURE__*/jsxs(Fragment, {
176
+ children: [assets && [...assets.styles].map(style => {
177
+ const attributes = styleAssetAttributes(style, {
178
+ baseUrl
179
+ });
180
+ return /*#__PURE__*/jsx("link", {
181
+ ...attributes
182
+ }, style.source);
183
+ }), assets && [...assets.scripts].map(script => {
184
+ const isModule = script.attributes.type === 'module';
185
+ const attributes = scriptAssetAttributes(script, {
186
+ baseUrl
187
+ });
188
+ if (isModule) {
189
+ return /*#__PURE__*/jsxs(Fragment$1, {
190
+ children: [/*#__PURE__*/jsx("link", {
191
+ ...scriptAssetPreloadAttributes(script)
192
+ }), /*#__PURE__*/jsx("script", {
193
+ ...attributes,
194
+ async: true
195
+ })]
196
+ }, script.source);
197
+ }
198
+ return /*#__PURE__*/jsx("script", {
199
+ ...attributes,
200
+ defer: true
201
+ }, script.source);
202
+ }), preloadAssets && [...preloadAssets.styles].map(style => {
203
+ const attributes = styleAssetPreloadAttributes(style, {
204
+ baseUrl
205
+ });
206
+ return /*#__PURE__*/jsx("link", {
207
+ ...attributes
208
+ }, style.source);
209
+ }), preloadAssets && [...preloadAssets.scripts].map(script => {
210
+ const attributes = scriptAssetPreloadAttributes(script, {
211
+ baseUrl
212
+ });
213
+ return /*#__PURE__*/jsx("link", {
214
+ ...attributes
215
+ }, script.source);
216
+ })]
217
+ }),
87
218
  children: content
88
219
  });
220
+ };
221
+ function preloadHeader(attributes) {
222
+ const {
223
+ as,
224
+ rel = 'preload',
225
+ href,
226
+ crossOrigin,
227
+ crossorigin
228
+ } = attributes;
229
+
230
+ // Support both property and attribute versions of the casing
231
+ const finalCrossOrigin = crossOrigin ?? crossorigin;
232
+ let header = `<${href}>; rel="${rel}"; as="${as}"`;
233
+ if (finalCrossOrigin === '' || finalCrossOrigin === true) {
234
+ header += `; crossorigin`;
235
+ } else if (typeof finalCrossOrigin === 'string') {
236
+ header += `; crossorigin="${finalCrossOrigin}"`;
237
+ }
238
+ return header;
89
239
  }
90
240
 
91
- export { createServerRender, renderAppToResponse };
241
+ 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
- function createServerRender(render, {
11
+ function createServerRender(getApp, {
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
- const app = await render(request, requestContext);
14
- return renderAppToResponse(app, request, {
19
+ const renderResponse = stream ? renderAppToStreamedResponse : renderAppToResponse;
20
+ return renderResponse(typeof getApp === 'function' ? () => getApp(request, requestContext) : getApp, request, {
15
21
  ...options,
16
- context: context?.(request, requestContext) ?? requestContext
22
+ extract: {
23
+ ...options.extract,
24
+ context: options.extract ?? context?.(request, requestContext) ?? requestContext
25
+ }
17
26
  });
18
27
  };
19
28
  }
20
- async function renderAppToResponse(app, request, {
29
+ async function renderAppToResponse(getApp, request, {
21
30
  assets,
22
- renderHtml = defaultRenderHtml,
23
- ...options
31
+ extract,
32
+ renderHtml
24
33
  } = {}) {
25
- const {
26
- html: htmlManager,
27
- http,
28
- rendered,
29
- asyncAssets
30
- } = await renderApp(app, {
31
- ...options,
34
+ const app = typeof getApp === 'function' ? await getApp() : getApp;
35
+ const renderDetails = await serverRenderDetailsForApp(app, {
36
+ extract,
32
37
  url: request.url,
33
38
  headers: request.headers
34
39
  });
@@ -36,56 +41,201 @@ 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(getApp, 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 app = typeof getApp === 'function' ? await getApp() : getApp;
88
+ const renderDetails = await serverRenderDetailsForApp(app, {
89
+ extract,
90
+ url: request.url,
91
+ headers: request.headers
92
+ });
93
+ const content = await renderAppDetailsToHtmlString(renderDetails, request, {
94
+ assets,
95
+ renderHtml
96
+ });
97
+ const writer = stream.writable.getWriter();
98
+ await writer.write(content);
99
+ await writer.close();
100
+ }
101
+ }
102
+ async function serverRenderDetailsForApp(app, {
103
+ url,
104
+ headers,
105
+ extract: extractOptions
106
+ } = {}) {
107
+ const html = new HtmlManager();
108
+ const asyncAssets = new AsyncAssetManager();
109
+ const http = new HttpManager({
110
+ headers
111
+ });
112
+ const {
113
+ decorate,
114
+ ...rest
115
+ } = extractOptions ?? {};
116
+ const rendered = await extract(app, {
117
+ decorate(app) {
118
+ return /*#__PURE__*/jsx(ServerContext, {
119
+ asyncAssets: asyncAssets,
120
+ http: http,
121
+ html: html,
122
+ url: url,
123
+ children: decorate?.(app) ?? app
124
+ });
125
+ },
126
+ ...rest
127
+ });
128
+ return {
129
+ rendered,
130
+ http,
131
+ html,
132
+ asyncAssets
133
+ };
134
+ }
135
+ async function renderAppDetailsToHtmlString(details, request, {
136
+ assets,
137
+ renderHtml = defaultRenderHtml
138
+ } = {}) {
139
+ const {
140
+ html: htmlManager,
141
+ http,
142
+ rendered,
143
+ asyncAssets
144
+ } = details;
46
145
  const usedAssets = asyncAssets.used({
47
146
  timing: 'load'
48
147
  });
49
- const assetOptions = {
148
+ const assetContext = {
50
149
  userAgent: request.headers.get('User-Agent')
51
150
  };
52
- const [styles, scripts, preload] = assets ? await Promise.all([assets.styles({
151
+ const [entryAssets, preloadAssets] = assets ? await Promise.all([assets.assets({
53
152
  async: usedAssets,
54
- options: assetOptions
55
- }), assets.scripts({
56
- async: usedAssets,
57
- options: assetOptions
153
+ context: assetContext
58
154
  }), assets.asyncAssets(asyncAssets.used({
59
155
  timing: 'preload'
60
156
  }), {
61
- options: assetOptions
62
- })]) : [[], [], []];
157
+ context: assetContext
158
+ })]) : [];
63
159
  const htmlElement = await renderHtml(rendered, request, {
64
160
  html: htmlManager,
65
161
  http,
66
- styles,
67
- scripts,
68
- preload
69
- });
70
- return html(renderHtmlToString(htmlElement), {
71
- headers,
72
- status: statusCode
162
+ assets: entryAssets,
163
+ preloadAssets
73
164
  });
165
+ return renderHtmlToString(htmlElement);
74
166
  }
75
- function defaultRenderHtml(content, request, {
167
+ const defaultRenderHtml = function defaultRenderHtml(content, request, {
76
168
  html,
77
- styles,
78
- scripts,
79
- preload
169
+ assets,
170
+ preloadAssets
80
171
  }) {
172
+ const baseUrl = new URL(request.url);
81
173
  return /*#__PURE__*/jsx(Html, {
82
- url: new URL(request.url),
83
174
  manager: html,
84
- styles: styles,
85
- scripts: scripts,
86
- preloadAssets: preload,
175
+ headEndContent: /*#__PURE__*/jsxs(Fragment, {
176
+ children: [assets && [...assets.styles].map(style => {
177
+ const attributes = styleAssetAttributes(style, {
178
+ baseUrl
179
+ });
180
+ return /*#__PURE__*/jsx("link", {
181
+ ...attributes
182
+ }, style.source);
183
+ }), assets && [...assets.scripts].map(script => {
184
+ const isModule = script.attributes.type === 'module';
185
+ const attributes = scriptAssetAttributes(script, {
186
+ baseUrl
187
+ });
188
+ if (isModule) {
189
+ return /*#__PURE__*/jsxs(Fragment$1, {
190
+ children: [/*#__PURE__*/jsx("link", {
191
+ ...scriptAssetPreloadAttributes(script)
192
+ }), /*#__PURE__*/jsx("script", {
193
+ ...attributes,
194
+ async: true
195
+ })]
196
+ }, script.source);
197
+ }
198
+ return /*#__PURE__*/jsx("script", {
199
+ ...attributes,
200
+ defer: true
201
+ }, script.source);
202
+ }), preloadAssets && [...preloadAssets.styles].map(style => {
203
+ const attributes = styleAssetPreloadAttributes(style, {
204
+ baseUrl
205
+ });
206
+ return /*#__PURE__*/jsx("link", {
207
+ ...attributes
208
+ }, style.source);
209
+ }), preloadAssets && [...preloadAssets.scripts].map(script => {
210
+ const attributes = scriptAssetPreloadAttributes(script, {
211
+ baseUrl
212
+ });
213
+ return /*#__PURE__*/jsx("link", {
214
+ ...attributes
215
+ }, script.source);
216
+ })]
217
+ }),
87
218
  children: content
88
219
  });
220
+ };
221
+ function preloadHeader(attributes) {
222
+ const {
223
+ as,
224
+ rel = 'preload',
225
+ href,
226
+ crossOrigin,
227
+ crossorigin
228
+ } = attributes;
229
+
230
+ // Support both property and attribute versions of the casing
231
+ const finalCrossOrigin = crossOrigin ?? crossorigin;
232
+ let header = `<${href}>; rel="${rel}"; as="${as}"`;
233
+ if (finalCrossOrigin === '' || finalCrossOrigin === true) {
234
+ header += `; crossorigin`;
235
+ } else if (typeof finalCrossOrigin === 'string') {
236
+ header += `; crossorigin="${finalCrossOrigin}"`;
237
+ }
238
+ return header;
89
239
  }
90
240
 
91
- export { createServerRender, renderAppToResponse };
241
+ export { createServerRender, renderAppToResponse, renderAppToStreamedResponse };