@quilted/quilt 0.5.136 → 0.5.138

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/build/cjs/index.cjs +34 -0
  3. package/build/cjs/server/ServerContext.cjs +3 -3
  4. package/build/cjs/server/index.cjs +28 -14
  5. package/build/cjs/server/preload.cjs +37 -0
  6. package/build/cjs/server/request-router.cjs +73 -57
  7. package/build/cjs/static/StaticContext.cjs +3 -3
  8. package/build/cjs/static/index.cjs +30 -44
  9. package/build/cjs/static/render.cjs +9 -6
  10. package/build/esm/index.mjs +2 -0
  11. package/build/esm/server/ServerContext.mjs +3 -3
  12. package/build/esm/server/index.mjs +3 -2
  13. package/build/esm/server/preload.mjs +35 -0
  14. package/build/esm/server/request-router.mjs +55 -39
  15. package/build/esm/static/StaticContext.mjs +3 -3
  16. package/build/esm/static/index.mjs +25 -39
  17. package/build/esm/static/render.mjs +7 -4
  18. package/build/esnext/index.esnext +2 -0
  19. package/build/esnext/server/ServerContext.esnext +3 -3
  20. package/build/esnext/server/index.esnext +3 -2
  21. package/build/esnext/server/preload.esnext +35 -0
  22. package/build/esnext/server/request-router.esnext +55 -39
  23. package/build/esnext/static/StaticContext.esnext +3 -3
  24. package/build/esnext/static/index.esnext +25 -39
  25. package/build/esnext/static/render.esnext +7 -4
  26. package/build/tsconfig.tsbuildinfo +1 -1
  27. package/build/typescript/assets.d.ts +7 -0
  28. package/build/typescript/assets.d.ts.map +1 -0
  29. package/build/typescript/index.d.ts +3 -0
  30. package/build/typescript/index.d.ts.map +1 -1
  31. package/build/typescript/magic/assets.d.ts +3 -0
  32. package/build/typescript/magic/assets.d.ts.map +1 -0
  33. package/build/typescript/server/ServerContext.d.ts +5 -5
  34. package/build/typescript/server/ServerContext.d.ts.map +1 -1
  35. package/build/typescript/server/index.d.ts +4 -3
  36. package/build/typescript/server/index.d.ts.map +1 -1
  37. package/build/typescript/server/preload.d.ts +8 -0
  38. package/build/typescript/server/preload.d.ts.map +1 -0
  39. package/build/typescript/server/request-router.d.ts +23 -14
  40. package/build/typescript/server/request-router.d.ts.map +1 -1
  41. package/build/typescript/static/StaticContext.d.ts +5 -5
  42. package/build/typescript/static/StaticContext.d.ts.map +1 -1
  43. package/build/typescript/static/index.d.ts +3 -5
  44. package/build/typescript/static/index.d.ts.map +1 -1
  45. package/build/typescript/static/render.d.ts +6 -4
  46. package/build/typescript/static/render.d.ts.map +1 -1
  47. package/package.json +5 -3
  48. package/source/assets.ts +7 -0
  49. package/source/index.ts +19 -0
  50. package/source/magic/assets.ts +5 -0
  51. package/source/server/ServerContext.tsx +7 -10
  52. package/source/server/index.ts +19 -13
  53. package/source/server/preload.ts +69 -0
  54. package/source/server/request-router.tsx +129 -73
  55. package/source/static/StaticContext.tsx +7 -10
  56. package/source/static/index.tsx +30 -41
  57. package/source/static/render.tsx +9 -12
  58. package/tsconfig.json +2 -0
  59. package/source/magic/asset-manifest.ts +0 -5
@@ -2,8 +2,8 @@
2
2
 
3
3
  var server$3 = require('@quilted/react-server-render/server');
4
4
  var server = require('@quilted/react-html/server');
5
- var server$2 = require('@quilted/react-http/server');
6
- var server$1 = require('@quilted/react-async/server');
5
+ var server$1 = require('@quilted/react-http/server');
6
+ var server$2 = require('@quilted/react-assets/server');
7
7
  var StaticContext = require('./StaticContext.cjs');
8
8
  var jsxRuntime = require('react/jsx-runtime');
9
9
 
@@ -11,20 +11,23 @@ async function renderApp(app, {
11
11
  decorate,
12
12
  url,
13
13
  headers,
14
+ cacheKey,
14
15
  ...rest
15
16
  } = {}) {
16
17
  const html = new server.HtmlManager();
17
- const asyncAssets = new server$1.AsyncAssetManager();
18
- const http = new server$2.HttpManager({
18
+ const http = new server$1.HttpManager({
19
19
  headers
20
20
  });
21
+ const assets = new server$2.AssetsManager({
22
+ cacheKey
23
+ });
21
24
  const markup = await server$3.extract(app, {
22
25
  decorate(app) {
23
26
  return /*#__PURE__*/jsxRuntime.jsx(StaticContext.StaticContext, {
24
- asyncAssets: asyncAssets,
25
27
  html: html,
26
28
  http: http,
27
29
  url: url,
30
+ assets: assets,
28
31
  children: decorate?.(app) ?? app
29
32
  });
30
33
  },
@@ -34,7 +37,7 @@ async function renderApp(app, {
34
37
  markup,
35
38
  http,
36
39
  html,
37
- asyncAssets
40
+ assets
38
41
  };
39
42
  }
40
43
 
@@ -1,5 +1,7 @@
1
+ export { createBrowserAssetsEntryFromManifest, createBrowserAssetsFromManifests, scriptAssetAttributes, scriptAssetPreloadAttributes, styleAssetAttributes, styleAssetPreloadAttributes } from '@quilted/assets';
1
2
  export { createAsyncModule } from '@quilted/async';
2
3
  export { AbortError, NestedAbortController, TimedAbortController, anyAbortSignal, createEmitter, on, once, raceAgainstAbortSignal, sleep } from '@quilted/events';
4
+ export { useAssetsCacheKey, useModuleAssets } from '@quilted/react-assets';
3
5
  export { createAsyncComponent, useAsyncModule, useAsyncModulePreload, usePreload } from '@quilted/react-async';
4
6
  export { GraphQLContext, createGraphQLHttpFetch, useGraphQLFetch } from '@quilted/react-graphql';
5
7
  export { useIdleCallback } from '@quilted/react-idle';
@@ -1,6 +1,6 @@
1
+ import { AssetsContext } from '@quilted/react-assets/server';
1
2
  import { InitialUrlContext } from '@quilted/react-router';
2
3
  import { HtmlContext } from '@quilted/react-html/server';
3
- import { AsyncAssetContext } from '@quilted/react-async/server';
4
4
  import { HttpServerContext } from '@quilted/react-http/server';
5
5
  import { maybeWrapContext } from '../utilities/react.mjs';
6
6
 
@@ -8,11 +8,11 @@ function ServerContext({
8
8
  url,
9
9
  html,
10
10
  http,
11
- asyncAssets,
11
+ assets,
12
12
  children
13
13
  }) {
14
14
  const normalizedUrl = typeof url === 'string' ? new URL(url) : url;
15
- return maybeWrapContext(AsyncAssetContext, asyncAssets, maybeWrapContext(HttpServerContext, http, maybeWrapContext(HtmlContext, html, maybeWrapContext(InitialUrlContext, normalizedUrl, children))));
15
+ return maybeWrapContext(AssetsContext, assets, maybeWrapContext(HttpServerContext, http, maybeWrapContext(HtmlContext, html, maybeWrapContext(InitialUrlContext, normalizedUrl, children))));
16
16
  }
17
17
 
18
18
  export { ServerContext };
@@ -1,9 +1,10 @@
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, scriptAssetAttributes, scriptAssetPreloadAttributes, styleAssetAttributes, styleAssetPreloadAttributes } from '@quilted/async/server';
4
- export { SERVER_ACTION_ID as ASYNC_ASSETS_SERVER_ACTION_ID, AsyncAssetContext, AsyncAssetManager } from '@quilted/react-async/server';
3
+ export { createBrowserAssetsEntryFromManifest, createBrowserAssetsFromManifests, scriptAssetAttributes, scriptAssetPreloadAttributes, styleAssetAttributes, styleAssetPreloadAttributes } from '@quilted/assets';
4
+ export { SERVER_ACTION_ID as ASSETS_SERVER_ACTION_ID, AssetsContext, AssetsManager, useAssetsCacheKey, useModuleAssets } from '@quilted/react-assets/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
8
  export { ServerContext } from './ServerContext.mjs';
9
9
  export { createServerRender, renderAppToResponse, renderAppToStreamedResponse } from './request-router.mjs';
10
+ export { createAssetPreloader } from './preload.mjs';
@@ -0,0 +1,35 @@
1
+ import { json } from '@quilted/request-router';
2
+
3
+ function createAssetPreloader(options) {
4
+ return async function handler(request, requestContext) {
5
+ const manifest = await assetsForRequest(request, {
6
+ ...options,
7
+ context: requestContext
8
+ });
9
+ return json(manifest);
10
+ };
11
+ }
12
+ async function assetsForRequest(request, {
13
+ assets,
14
+ context,
15
+ cacheKey: getCacheKey
16
+ }) {
17
+ const url = new URL(request.url);
18
+ const modules = url.searchParams.get('modules')?.split(',') ?? [];
19
+ const includeStyles = url.searchParams.get('styles') !== 'false';
20
+ const includeScripts = url.searchParams.get('scripts') !== 'false';
21
+ const cacheKey = (await getCacheKey?.(request, context)) ?? (await assets.cacheKey?.(request));
22
+ const {
23
+ styles,
24
+ scripts
25
+ } = await assets.entry({
26
+ modules,
27
+ cacheKey
28
+ });
29
+ const result = {};
30
+ if (includeStyles) result.styles = styles;
31
+ if (includeScripts) result.scripts = scripts;
32
+ return result;
33
+ }
34
+
35
+ export { createAssetPreloader };
@@ -1,6 +1,6 @@
1
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';
2
+ import { styleAssetPreloadAttributes, scriptAssetPreloadAttributes, styleAssetAttributes, scriptAssetAttributes } from '@quilted/assets';
3
+ import { AssetsManager } from '@quilted/react-assets/server';
4
4
  import { HttpManager } from '@quilted/react-http/server';
5
5
  import { HtmlManager, renderHtmlToString, Html } from '@quilted/react-html/server';
6
6
  import { extract } from '@quilted/react-server-render/server';
@@ -9,7 +9,6 @@ import { ServerContext } from './ServerContext.mjs';
9
9
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
10
10
 
11
11
  function createServerRender(getApp, {
12
- context,
13
12
  stream,
14
13
  ...options
15
14
  } = {}) {
@@ -17,23 +16,29 @@ function createServerRender(getApp, {
17
16
  const accepts = request.headers.get('Accept');
18
17
  if (accepts != null && !accepts.includes('text/html')) return;
19
18
  const renderResponse = stream ? renderAppToStreamedResponse : renderAppToResponse;
20
- return renderResponse(typeof getApp === 'function' ? () => getApp(request, requestContext) : getApp, request, {
19
+ return renderResponse(typeof getApp === 'function' ? () => getApp(request, requestContext) : getApp, {
21
20
  ...options,
21
+ request,
22
+ context: requestContext,
22
23
  extract: {
23
24
  ...options.extract,
24
- context: options.extract ?? context?.(request, requestContext) ?? requestContext
25
+ context: typeof options.extract?.context === 'function' ? options.extract.context(request, requestContext) : options.extract?.context
25
26
  }
26
27
  });
27
28
  };
28
29
  }
29
- async function renderAppToResponse(getApp, request, {
30
+ async function renderAppToResponse(getApp, {
31
+ request,
32
+ context,
30
33
  assets,
31
34
  extract,
32
35
  renderHtml
33
- } = {}) {
36
+ }) {
34
37
  const app = typeof getApp === 'function' ? await getApp() : getApp;
38
+ const cacheKey = await assets?.cacheKey?.(request);
35
39
  const renderDetails = await serverRenderDetailsForApp(app, {
36
40
  extract,
41
+ cacheKey,
37
42
  url: request.url,
38
43
  headers: request.headers
39
44
  });
@@ -48,7 +53,9 @@ async function renderAppToResponse(getApp, request, {
48
53
  headers
49
54
  });
50
55
  }
51
- const content = await renderAppDetailsToHtmlString(renderDetails, request, {
56
+ const content = await renderAppDetailsToHtmlString(renderDetails, {
57
+ request,
58
+ context,
52
59
  assets,
53
60
  renderHtml
54
61
  });
@@ -57,18 +64,18 @@ async function renderAppToResponse(getApp, request, {
57
64
  status: statusCode
58
65
  });
59
66
  }
60
- async function renderAppToStreamedResponse(getApp, request, {
67
+ async function renderAppToStreamedResponse(getApp, {
68
+ request,
69
+ context,
61
70
  assets,
62
71
  extract,
63
72
  renderHtml
64
- } = {}) {
73
+ }) {
65
74
  const headers = new Headers();
66
75
  const stream = new TransformStream();
67
- const assetContext = {
68
- userAgent: request.headers.get('User-Agent')
69
- };
70
- const guaranteedAssets = await assets?.assets({
71
- context: assetContext
76
+ const cacheKey = await assets?.cacheKey?.(request);
77
+ const guaranteedAssets = await assets?.entry({
78
+ cacheKey
72
79
  });
73
80
  if (guaranteedAssets) {
74
81
  for (const style of guaranteedAssets.styles) {
@@ -87,10 +94,13 @@ async function renderAppToStreamedResponse(getApp, request, {
87
94
  const app = typeof getApp === 'function' ? await getApp() : getApp;
88
95
  const renderDetails = await serverRenderDetailsForApp(app, {
89
96
  extract,
97
+ cacheKey,
90
98
  url: request.url,
91
99
  headers: request.headers
92
100
  });
93
- const content = await renderAppDetailsToHtmlString(renderDetails, request, {
101
+ const content = await renderAppDetailsToHtmlString(renderDetails, {
102
+ request,
103
+ context,
94
104
  assets,
95
105
  renderHtml
96
106
  });
@@ -103,13 +113,16 @@ async function renderAppToStreamedResponse(getApp, request, {
103
113
  async function serverRenderDetailsForApp(app, {
104
114
  url,
105
115
  headers,
116
+ cacheKey,
106
117
  extract: extractOptions
107
118
  } = {}) {
108
119
  const html = new HtmlManager();
109
- const asyncAssets = new AsyncAssetManager();
110
120
  const http = new HttpManager({
111
121
  headers
112
122
  });
123
+ const assets = new AssetsManager({
124
+ cacheKey
125
+ });
113
126
  const {
114
127
  decorate,
115
128
  ...rest
@@ -117,10 +130,10 @@ async function serverRenderDetailsForApp(app, {
117
130
  const rendered = await extract(app, {
118
131
  decorate(app) {
119
132
  return /*#__PURE__*/jsx(ServerContext, {
120
- asyncAssets: asyncAssets,
121
133
  http: http,
122
134
  html: html,
123
135
  url: url,
136
+ assets: assets,
124
137
  children: decorate?.(app) ?? app
125
138
  });
126
139
  },
@@ -130,34 +143,36 @@ async function serverRenderDetailsForApp(app, {
130
143
  rendered,
131
144
  http,
132
145
  html,
133
- asyncAssets
146
+ assets
134
147
  };
135
148
  }
136
- async function renderAppDetailsToHtmlString(details, request, {
149
+ async function renderAppDetailsToHtmlString(details, {
150
+ request,
151
+ context,
137
152
  assets,
138
153
  renderHtml = defaultRenderHtml
139
- } = {}) {
154
+ }) {
140
155
  const {
141
- html: htmlManager,
142
156
  http,
143
157
  rendered,
144
- asyncAssets
158
+ html: htmlManager,
159
+ assets: assetsManager
145
160
  } = details;
146
- const usedAssets = asyncAssets.used({
161
+ const cacheKey = assetsManager.cacheKey;
162
+ const usedModules = assetsManager.usedModules({
147
163
  timing: 'load'
148
164
  });
149
- const assetContext = {
150
- userAgent: request.headers.get('User-Agent')
151
- };
152
- const [entryAssets, preloadAssets] = assets ? await Promise.all([assets.assets({
153
- async: usedAssets,
154
- context: assetContext
155
- }), assets.asyncAssets(asyncAssets.used({
165
+ const [entryAssets, preloadAssets] = assets ? await Promise.all([assets.entry({
166
+ modules: usedModules,
167
+ cacheKey
168
+ }), assets.modules(assetsManager.usedModules({
156
169
  timing: 'preload'
157
170
  }), {
158
- context: assetContext
171
+ cacheKey
159
172
  })]) : [];
160
- const htmlElement = await renderHtml(rendered, request, {
173
+ const htmlElement = await renderHtml(rendered, {
174
+ request,
175
+ context,
161
176
  html: htmlManager,
162
177
  http,
163
178
  assets: entryAssets,
@@ -165,7 +180,8 @@ async function renderAppDetailsToHtmlString(details, request, {
165
180
  });
166
181
  return renderHtmlToString(htmlElement);
167
182
  }
168
- const defaultRenderHtml = function defaultRenderHtml(content, request, {
183
+ const defaultRenderHtml = function defaultRenderHtml(content, {
184
+ request,
169
185
  html,
170
186
  assets,
171
187
  preloadAssets
@@ -174,15 +190,15 @@ const defaultRenderHtml = function defaultRenderHtml(content, request, {
174
190
  return /*#__PURE__*/jsx(Html, {
175
191
  manager: html,
176
192
  headEndContent: /*#__PURE__*/jsxs(Fragment, {
177
- children: [assets && [...assets.styles].map(style => {
193
+ children: [assets && assets.styles.map(style => {
178
194
  const attributes = styleAssetAttributes(style, {
179
195
  baseUrl
180
196
  });
181
197
  return /*#__PURE__*/jsx("link", {
182
198
  ...attributes
183
199
  }, style.source);
184
- }), assets && [...assets.scripts].map(script => {
185
- const isModule = script.attributes.type === 'module';
200
+ }), assets && assets.scripts.map(script => {
201
+ const isModule = script.attributes?.type === 'module';
186
202
  const attributes = scriptAssetAttributes(script, {
187
203
  baseUrl
188
204
  });
@@ -200,14 +216,14 @@ const defaultRenderHtml = function defaultRenderHtml(content, request, {
200
216
  ...attributes,
201
217
  defer: true
202
218
  }, script.source);
203
- }), preloadAssets && [...preloadAssets.styles].map(style => {
219
+ }), preloadAssets && preloadAssets.styles.map(style => {
204
220
  const attributes = styleAssetPreloadAttributes(style, {
205
221
  baseUrl
206
222
  });
207
223
  return /*#__PURE__*/jsx("link", {
208
224
  ...attributes
209
225
  }, style.source);
210
- }), preloadAssets && [...preloadAssets.scripts].map(script => {
226
+ }), preloadAssets && preloadAssets.scripts.map(script => {
211
227
  const attributes = scriptAssetPreloadAttributes(script, {
212
228
  baseUrl
213
229
  });
@@ -1,6 +1,6 @@
1
+ import { AssetsContext } from '@quilted/react-assets/server';
1
2
  import { InitialUrlContext } from '@quilted/react-router';
2
3
  import { HtmlContext } from '@quilted/react-html/server';
3
- import { AsyncAssetContext } from '@quilted/react-async/server';
4
4
  import { HttpServerContext } from '@quilted/react-http/server';
5
5
  import { maybeWrapContext } from '../utilities/react.mjs';
6
6
 
@@ -8,11 +8,11 @@ function StaticContext({
8
8
  url,
9
9
  html,
10
10
  http,
11
- asyncAssets,
11
+ assets,
12
12
  children
13
13
  }) {
14
14
  const normalizedUrl = typeof url === 'string' ? new URL(url) : url;
15
- return maybeWrapContext(AsyncAssetContext, asyncAssets, maybeWrapContext(HttpServerContext, http, maybeWrapContext(HtmlContext, html, maybeWrapContext(InitialUrlContext, normalizedUrl, children))));
15
+ return maybeWrapContext(AssetsContext, assets, maybeWrapContext(HttpServerContext, http, maybeWrapContext(HtmlContext, html, maybeWrapContext(InitialUrlContext, normalizedUrl, children))));
16
16
  }
17
17
 
18
18
  export { StaticContext };
@@ -1,4 +1,5 @@
1
- import { styleAssetAttributes, scriptAssetAttributes, styleAssetPreloadAttributes, scriptAssetPreloadAttributes } from '@quilted/async/server';
1
+ import { Fragment as Fragment$1 } from 'react';
2
+ import { styleAssetAttributes, scriptAssetAttributes, scriptAssetPreloadAttributes, styleAssetPreloadAttributes } from '@quilted/assets';
2
3
  import { renderHtmlToString, Html } from '@quilted/react-html/server';
3
4
  import { StaticRenderer, StaticRendererContext } from '@quilted/react-router/static';
4
5
  import { renderApp } from './render.mjs';
@@ -157,13 +158,15 @@ async function renderStatic(App, {
157
158
  const routeRecorder = new StaticRenderer({
158
159
  forceFallback: fallback ? url.pathname : undefined
159
160
  });
161
+ const initialCacheKey = await assets.cacheKey?.(new Request(url));
160
162
  const {
161
163
  http,
162
164
  html: htmlManager,
163
- markup,
164
- asyncAssets
165
+ assets: assetsManager,
166
+ markup
165
167
  } = await renderApp( /*#__PURE__*/jsx(App, {}), {
166
168
  url,
169
+ cacheKey: initialCacheKey,
167
170
  decorate(app) {
168
171
  return /*#__PURE__*/jsx(StaticRendererContext.Provider, {
169
172
  value: routeRecorder,
@@ -171,65 +174,48 @@ async function renderStatic(App, {
171
174
  });
172
175
  }
173
176
  });
174
- const usedAssets = asyncAssets.used({
175
- timing: 'load'
176
- });
177
- const [moduleAssets, modulePreload, nomoduleAssets] = await Promise.all([assets.assets({
178
- async: usedAssets,
179
- context: {
180
- modules: true
181
- }
182
- }), assets.asyncAssets(asyncAssets.used({
177
+ const cacheKey = assetsManager.cacheKey;
178
+ const [mainAssets, preloadAssets] = await Promise.all([assets.entry({
179
+ modules: assetsManager.usedModules({
180
+ timing: 'load'
181
+ }),
182
+ cacheKey
183
+ }), assets.modules(assetsManager.usedModules({
183
184
  timing: 'preload'
184
185
  }), {
185
- context: {
186
- modules: true
187
- }
188
- }), assets.assets({
189
- async: usedAssets,
190
- context: {
191
- modules: false
192
- }
186
+ cacheKey
193
187
  })]);
194
-
195
- // We don’t want to load styles from both bundles, so we only use module styles,
196
- // since modules are intended to be the default and CSS (usually) doesn’t
197
- // have features that meaningfully break older user agents.
198
- const styles = moduleAssets.styles.length > 0 ? moduleAssets.styles : nomoduleAssets.styles;
199
188
  const minifiedHtml = renderHtmlToString( /*#__PURE__*/jsx(Html, {
200
189
  manager: htmlManager,
201
190
  headEndContent: /*#__PURE__*/jsxs(Fragment, {
202
- children: [[...styles].map(style => {
191
+ children: [[...mainAssets.styles].map(style => {
203
192
  const attributes = styleAssetAttributes(style, {
204
193
  baseUrl: url
205
194
  });
206
195
  return /*#__PURE__*/jsx("link", {
207
196
  ...attributes
208
197
  }, style.source);
209
- }), [...moduleAssets.scripts].map(script => {
198
+ }), [...mainAssets.scripts].map(script => {
210
199
  const attributes = scriptAssetAttributes(script, {
211
200
  baseUrl: url
212
201
  });
213
- return /*#__PURE__*/jsx("script", {
202
+ return attributes.type === 'module' ? /*#__PURE__*/jsxs(Fragment$1, {
203
+ children: [/*#__PURE__*/jsx("link", {
204
+ ...scriptAssetPreloadAttributes(script)
205
+ }), /*#__PURE__*/jsx("script", {
206
+ ...attributes
207
+ })]
208
+ }, script.source) : /*#__PURE__*/jsx("script", {
214
209
  ...attributes
215
210
  }, 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 => {
211
+ }), [...preloadAssets.styles].map(style => {
226
212
  const attributes = styleAssetPreloadAttributes(style, {
227
213
  baseUrl: url
228
214
  });
229
215
  return /*#__PURE__*/jsx("link", {
230
216
  ...attributes
231
217
  }, style.source);
232
- }), [...modulePreload.scripts].map(script => {
218
+ }), [...preloadAssets.scripts].map(script => {
233
219
  const attributes = scriptAssetPreloadAttributes(script, {
234
220
  baseUrl: url
235
221
  });
@@ -1,7 +1,7 @@
1
1
  import { extract } from '@quilted/react-server-render/server';
2
2
  import { HtmlManager } from '@quilted/react-html/server';
3
3
  import { HttpManager } from '@quilted/react-http/server';
4
- import { AsyncAssetManager } from '@quilted/react-async/server';
4
+ import { AssetsManager } from '@quilted/react-assets/server';
5
5
  import { StaticContext } from './StaticContext.mjs';
6
6
  import { jsx } from 'react/jsx-runtime';
7
7
 
@@ -9,20 +9,23 @@ async function renderApp(app, {
9
9
  decorate,
10
10
  url,
11
11
  headers,
12
+ cacheKey,
12
13
  ...rest
13
14
  } = {}) {
14
15
  const html = new HtmlManager();
15
- const asyncAssets = new AsyncAssetManager();
16
16
  const http = new HttpManager({
17
17
  headers
18
18
  });
19
+ const assets = new AssetsManager({
20
+ cacheKey
21
+ });
19
22
  const markup = await extract(app, {
20
23
  decorate(app) {
21
24
  return /*#__PURE__*/jsx(StaticContext, {
22
- asyncAssets: asyncAssets,
23
25
  html: html,
24
26
  http: http,
25
27
  url: url,
28
+ assets: assets,
26
29
  children: decorate?.(app) ?? app
27
30
  });
28
31
  },
@@ -32,7 +35,7 @@ async function renderApp(app, {
32
35
  markup,
33
36
  http,
34
37
  html,
35
- asyncAssets
38
+ assets
36
39
  };
37
40
  }
38
41
 
@@ -1,5 +1,7 @@
1
+ export { createBrowserAssetsEntryFromManifest, createBrowserAssetsFromManifests, scriptAssetAttributes, scriptAssetPreloadAttributes, styleAssetAttributes, styleAssetPreloadAttributes } from '@quilted/assets';
1
2
  export { createAsyncModule } from '@quilted/async';
2
3
  export { AbortError, NestedAbortController, TimedAbortController, anyAbortSignal, createEmitter, on, once, raceAgainstAbortSignal, sleep } from '@quilted/events';
4
+ export { useAssetsCacheKey, useModuleAssets } from '@quilted/react-assets';
3
5
  export { createAsyncComponent, useAsyncModule, useAsyncModulePreload, usePreload } from '@quilted/react-async';
4
6
  export { GraphQLContext, createGraphQLHttpFetch, useGraphQLFetch } from '@quilted/react-graphql';
5
7
  export { useIdleCallback } from '@quilted/react-idle';
@@ -1,6 +1,6 @@
1
+ import { AssetsContext } from '@quilted/react-assets/server';
1
2
  import { InitialUrlContext } from '@quilted/react-router';
2
3
  import { HtmlContext } from '@quilted/react-html/server';
3
- import { AsyncAssetContext } from '@quilted/react-async/server';
4
4
  import { HttpServerContext } from '@quilted/react-http/server';
5
5
  import { maybeWrapContext } from '../utilities/react.esnext';
6
6
 
@@ -8,11 +8,11 @@ function ServerContext({
8
8
  url,
9
9
  html,
10
10
  http,
11
- asyncAssets,
11
+ assets,
12
12
  children
13
13
  }) {
14
14
  const normalizedUrl = typeof url === 'string' ? new URL(url) : url;
15
- return maybeWrapContext(AsyncAssetContext, asyncAssets, maybeWrapContext(HttpServerContext, http, maybeWrapContext(HtmlContext, html, maybeWrapContext(InitialUrlContext, normalizedUrl, children))));
15
+ return maybeWrapContext(AssetsContext, assets, maybeWrapContext(HttpServerContext, http, maybeWrapContext(HtmlContext, html, maybeWrapContext(InitialUrlContext, normalizedUrl, children))));
16
16
  }
17
17
 
18
18
  export { ServerContext };
@@ -1,9 +1,10 @@
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, scriptAssetAttributes, scriptAssetPreloadAttributes, styleAssetAttributes, styleAssetPreloadAttributes } from '@quilted/async/server';
4
- export { SERVER_ACTION_ID as ASYNC_ASSETS_SERVER_ACTION_ID, AsyncAssetContext, AsyncAssetManager } from '@quilted/react-async/server';
3
+ export { createBrowserAssetsEntryFromManifest, createBrowserAssetsFromManifests, scriptAssetAttributes, scriptAssetPreloadAttributes, styleAssetAttributes, styleAssetPreloadAttributes } from '@quilted/assets';
4
+ export { SERVER_ACTION_ID as ASSETS_SERVER_ACTION_ID, AssetsContext, AssetsManager, useAssetsCacheKey, useModuleAssets } from '@quilted/react-assets/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
8
  export { ServerContext } from './ServerContext.esnext';
9
9
  export { createServerRender, renderAppToResponse, renderAppToStreamedResponse } from './request-router.esnext';
10
+ export { createAssetPreloader } from './preload.esnext';
@@ -0,0 +1,35 @@
1
+ import { json } from '@quilted/request-router';
2
+
3
+ function createAssetPreloader(options) {
4
+ return async function handler(request, requestContext) {
5
+ const manifest = await assetsForRequest(request, {
6
+ ...options,
7
+ context: requestContext
8
+ });
9
+ return json(manifest);
10
+ };
11
+ }
12
+ async function assetsForRequest(request, {
13
+ assets,
14
+ context,
15
+ cacheKey: getCacheKey
16
+ }) {
17
+ const url = new URL(request.url);
18
+ const modules = url.searchParams.get('modules')?.split(',') ?? [];
19
+ const includeStyles = url.searchParams.get('styles') !== 'false';
20
+ const includeScripts = url.searchParams.get('scripts') !== 'false';
21
+ const cacheKey = (await getCacheKey?.(request, context)) ?? (await assets.cacheKey?.(request));
22
+ const {
23
+ styles,
24
+ scripts
25
+ } = await assets.entry({
26
+ modules,
27
+ cacheKey
28
+ });
29
+ const result = {};
30
+ if (includeStyles) result.styles = styles;
31
+ if (includeScripts) result.scripts = scripts;
32
+ return result;
33
+ }
34
+
35
+ export { createAssetPreloader };