@quilted/quilt 0.5.136 → 0.5.137

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 +10 -0
  2. package/build/cjs/index.cjs +30 -0
  3. package/build/cjs/server/ServerContext.cjs +6 -4
  4. package/build/cjs/server/index.cjs +30 -7
  5. package/build/cjs/server/preload.cjs +37 -0
  6. package/build/cjs/server/request-router.cjs +75 -54
  7. package/build/cjs/static/StaticContext.cjs +6 -4
  8. package/build/cjs/static/index.cjs +29 -42
  9. package/build/cjs/static/render.cjs +8 -2
  10. package/build/esm/index.mjs +2 -0
  11. package/build/esm/server/ServerContext.mjs +3 -1
  12. package/build/esm/server/index.mjs +3 -1
  13. package/build/esm/server/preload.mjs +35 -0
  14. package/build/esm/server/request-router.mjs +57 -36
  15. package/build/esm/static/StaticContext.mjs +3 -1
  16. package/build/esm/static/index.mjs +24 -37
  17. package/build/esm/static/render.mjs +6 -0
  18. package/build/esnext/index.esnext +2 -0
  19. package/build/esnext/server/ServerContext.esnext +3 -1
  20. package/build/esnext/server/index.esnext +3 -1
  21. package/build/esnext/server/preload.esnext +35 -0
  22. package/build/esnext/server/request-router.esnext +57 -36
  23. package/build/esnext/static/StaticContext.esnext +3 -1
  24. package/build/esnext/static/index.esnext +24 -37
  25. package/build/esnext/static/render.esnext +6 -0
  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 +3 -1
  34. package/build/typescript/server/ServerContext.d.ts.map +1 -1
  35. package/build/typescript/server/index.d.ts +4 -2
  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 -12
  40. package/build/typescript/server/request-router.d.ts.map +1 -1
  41. package/build/typescript/static/StaticContext.d.ts +3 -1
  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 -2
  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 +15 -7
  52. package/source/server/index.ts +19 -9
  53. package/source/server/preload.ts +69 -0
  54. package/source/server/request-router.tsx +135 -64
  55. package/source/static/StaticContext.tsx +15 -7
  56. package/source/static/index.tsx +26 -41
  57. package/source/static/render.tsx +8 -4
  58. package/tsconfig.json +2 -0
  59. package/source/magic/asset-manifest.ts +0 -5
@@ -1,5 +1,6 @@
1
1
  import { Fragment as Fragment$1 } from 'react';
2
- import { styleAssetPreloadAttributes, scriptAssetPreloadAttributes, styleAssetAttributes, scriptAssetAttributes } from '@quilted/async/server';
2
+ import { styleAssetPreloadAttributes, scriptAssetPreloadAttributes, styleAssetAttributes, scriptAssetAttributes } from '@quilted/assets';
3
+ import { AssetsManager } from '@quilted/react-assets/server';
3
4
  import { AsyncAssetManager } from '@quilted/react-async/server';
4
5
  import { HttpManager } from '@quilted/react-http/server';
5
6
  import { HtmlManager, renderHtmlToString, Html } from '@quilted/react-html/server';
@@ -9,7 +10,6 @@ import { ServerContext } from './ServerContext.esnext';
9
10
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
10
11
 
11
12
  function createServerRender(getApp, {
12
- context,
13
13
  stream,
14
14
  ...options
15
15
  } = {}) {
@@ -17,23 +17,29 @@ function createServerRender(getApp, {
17
17
  const accepts = request.headers.get('Accept');
18
18
  if (accepts != null && !accepts.includes('text/html')) return;
19
19
  const renderResponse = stream ? renderAppToStreamedResponse : renderAppToResponse;
20
- return renderResponse(typeof getApp === 'function' ? () => getApp(request, requestContext) : getApp, request, {
20
+ return renderResponse(typeof getApp === 'function' ? () => getApp(request, requestContext) : getApp, {
21
21
  ...options,
22
+ request,
23
+ context: requestContext,
22
24
  extract: {
23
25
  ...options.extract,
24
- context: options.extract ?? context?.(request, requestContext) ?? requestContext
26
+ context: typeof options.extract?.context === 'function' ? options.extract.context(request, requestContext) : options.extract?.context
25
27
  }
26
28
  });
27
29
  };
28
30
  }
29
- async function renderAppToResponse(getApp, request, {
31
+ async function renderAppToResponse(getApp, {
32
+ request,
33
+ context,
30
34
  assets,
31
35
  extract,
32
36
  renderHtml
33
- } = {}) {
37
+ }) {
34
38
  const app = typeof getApp === 'function' ? await getApp() : getApp;
39
+ const cacheKey = await assets?.cacheKey?.(request);
35
40
  const renderDetails = await serverRenderDetailsForApp(app, {
36
41
  extract,
42
+ cacheKey,
37
43
  url: request.url,
38
44
  headers: request.headers
39
45
  });
@@ -48,7 +54,9 @@ async function renderAppToResponse(getApp, request, {
48
54
  headers
49
55
  });
50
56
  }
51
- const content = await renderAppDetailsToHtmlString(renderDetails, request, {
57
+ const content = await renderAppDetailsToHtmlString(renderDetails, {
58
+ request,
59
+ context,
52
60
  assets,
53
61
  renderHtml
54
62
  });
@@ -57,18 +65,18 @@ async function renderAppToResponse(getApp, request, {
57
65
  status: statusCode
58
66
  });
59
67
  }
60
- async function renderAppToStreamedResponse(getApp, request, {
68
+ async function renderAppToStreamedResponse(getApp, {
69
+ request,
70
+ context,
61
71
  assets,
62
72
  extract,
63
73
  renderHtml
64
- } = {}) {
74
+ }) {
65
75
  const headers = new Headers();
66
76
  const stream = new TransformStream();
67
- const assetContext = {
68
- userAgent: request.headers.get('User-Agent')
69
- };
70
- const guaranteedAssets = await assets?.assets({
71
- context: assetContext
77
+ const cacheKey = await assets?.cacheKey?.(request);
78
+ const guaranteedAssets = await assets?.entry({
79
+ cacheKey
72
80
  });
73
81
  if (guaranteedAssets) {
74
82
  for (const style of guaranteedAssets.styles) {
@@ -87,10 +95,13 @@ async function renderAppToStreamedResponse(getApp, request, {
87
95
  const app = typeof getApp === 'function' ? await getApp() : getApp;
88
96
  const renderDetails = await serverRenderDetailsForApp(app, {
89
97
  extract,
98
+ cacheKey,
90
99
  url: request.url,
91
100
  headers: request.headers
92
101
  });
93
- const content = await renderAppDetailsToHtmlString(renderDetails, request, {
102
+ const content = await renderAppDetailsToHtmlString(renderDetails, {
103
+ request,
104
+ context,
94
105
  assets,
95
106
  renderHtml
96
107
  });
@@ -103,6 +114,7 @@ async function renderAppToStreamedResponse(getApp, request, {
103
114
  async function serverRenderDetailsForApp(app, {
104
115
  url,
105
116
  headers,
117
+ cacheKey,
106
118
  extract: extractOptions
107
119
  } = {}) {
108
120
  const html = new HtmlManager();
@@ -110,6 +122,9 @@ async function serverRenderDetailsForApp(app, {
110
122
  const http = new HttpManager({
111
123
  headers
112
124
  });
125
+ const assets = new AssetsManager({
126
+ cacheKey
127
+ });
113
128
  const {
114
129
  decorate,
115
130
  ...rest
@@ -121,6 +136,7 @@ async function serverRenderDetailsForApp(app, {
121
136
  http: http,
122
137
  html: html,
123
138
  url: url,
139
+ assets: assets,
124
140
  children: decorate?.(app) ?? app
125
141
  });
126
142
  },
@@ -130,34 +146,38 @@ async function serverRenderDetailsForApp(app, {
130
146
  rendered,
131
147
  http,
132
148
  html,
133
- asyncAssets
149
+ asyncAssets,
150
+ assets
134
151
  };
135
152
  }
136
- async function renderAppDetailsToHtmlString(details, request, {
153
+ async function renderAppDetailsToHtmlString(details, {
154
+ request,
155
+ context,
137
156
  assets,
138
157
  renderHtml = defaultRenderHtml
139
- } = {}) {
158
+ }) {
140
159
  const {
141
- html: htmlManager,
142
160
  http,
143
161
  rendered,
144
- asyncAssets
162
+ asyncAssets,
163
+ html: htmlManager,
164
+ assets: assetsManager
145
165
  } = details;
146
- const usedAssets = asyncAssets.used({
166
+ const usedModules = asyncAssets.used({
147
167
  timing: 'load'
148
168
  });
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({
169
+ const cacheKey = assetsManager.cacheKey;
170
+ const [entryAssets, preloadAssets] = assets ? await Promise.all([assets.entry({
171
+ modules: usedModules,
172
+ cacheKey
173
+ }), assets.modules(asyncAssets.used({
156
174
  timing: 'preload'
157
175
  }), {
158
- context: assetContext
176
+ cacheKey
159
177
  })]) : [];
160
- const htmlElement = await renderHtml(rendered, request, {
178
+ const htmlElement = await renderHtml(rendered, {
179
+ request,
180
+ context,
161
181
  html: htmlManager,
162
182
  http,
163
183
  assets: entryAssets,
@@ -165,7 +185,8 @@ async function renderAppDetailsToHtmlString(details, request, {
165
185
  });
166
186
  return renderHtmlToString(htmlElement);
167
187
  }
168
- const defaultRenderHtml = function defaultRenderHtml(content, request, {
188
+ const defaultRenderHtml = function defaultRenderHtml(content, {
189
+ request,
169
190
  html,
170
191
  assets,
171
192
  preloadAssets
@@ -174,15 +195,15 @@ const defaultRenderHtml = function defaultRenderHtml(content, request, {
174
195
  return /*#__PURE__*/jsx(Html, {
175
196
  manager: html,
176
197
  headEndContent: /*#__PURE__*/jsxs(Fragment, {
177
- children: [assets && [...assets.styles].map(style => {
198
+ children: [assets && assets.styles.map(style => {
178
199
  const attributes = styleAssetAttributes(style, {
179
200
  baseUrl
180
201
  });
181
202
  return /*#__PURE__*/jsx("link", {
182
203
  ...attributes
183
204
  }, style.source);
184
- }), assets && [...assets.scripts].map(script => {
185
- const isModule = script.attributes.type === 'module';
205
+ }), assets && assets.scripts.map(script => {
206
+ const isModule = script.attributes?.type === 'module';
186
207
  const attributes = scriptAssetAttributes(script, {
187
208
  baseUrl
188
209
  });
@@ -200,14 +221,14 @@ const defaultRenderHtml = function defaultRenderHtml(content, request, {
200
221
  ...attributes,
201
222
  defer: true
202
223
  }, script.source);
203
- }), preloadAssets && [...preloadAssets.styles].map(style => {
224
+ }), preloadAssets && preloadAssets.styles.map(style => {
204
225
  const attributes = styleAssetPreloadAttributes(style, {
205
226
  baseUrl
206
227
  });
207
228
  return /*#__PURE__*/jsx("link", {
208
229
  ...attributes
209
230
  }, style.source);
210
- }), preloadAssets && [...preloadAssets.scripts].map(script => {
231
+ }), preloadAssets && preloadAssets.scripts.map(script => {
211
232
  const attributes = scriptAssetPreloadAttributes(script, {
212
233
  baseUrl
213
234
  });
@@ -1,3 +1,4 @@
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
4
  import { AsyncAssetContext } from '@quilted/react-async/server';
@@ -8,11 +9,12 @@ function StaticContext({
8
9
  url,
9
10
  html,
10
11
  http,
12
+ assets,
11
13
  asyncAssets,
12
14
  children
13
15
  }) {
14
16
  const normalizedUrl = typeof url === 'string' ? new URL(url) : url;
15
- return maybeWrapContext(AsyncAssetContext, asyncAssets, maybeWrapContext(HttpServerContext, http, maybeWrapContext(HtmlContext, html, maybeWrapContext(InitialUrlContext, normalizedUrl, children))));
17
+ return maybeWrapContext(AssetsContext, assets, maybeWrapContext(AsyncAssetContext, asyncAssets, maybeWrapContext(HttpServerContext, http, maybeWrapContext(HtmlContext, html, maybeWrapContext(InitialUrlContext, normalizedUrl, children)))));
16
18
  }
17
19
 
18
20
  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.esnext';
@@ -157,13 +158,16 @@ 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,
165
+ assets: assetsManager,
163
166
  markup,
164
167
  asyncAssets
165
168
  } = await renderApp( /*#__PURE__*/jsx(App, {}), {
166
169
  url,
170
+ cacheKey: initialCacheKey,
167
171
  decorate(app) {
168
172
  return /*#__PURE__*/jsx(StaticRendererContext.Provider, {
169
173
  value: routeRecorder,
@@ -171,65 +175,48 @@ async function renderStatic(App, {
171
175
  });
172
176
  }
173
177
  });
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({
178
+ const cacheKey = assetsManager.cacheKey;
179
+ const [mainAssets, preloadAssets] = await Promise.all([assets.entry({
180
+ modules: asyncAssets.used({
181
+ timing: 'load'
182
+ }),
183
+ cacheKey
184
+ }), assets.modules(asyncAssets.used({
183
185
  timing: 'preload'
184
186
  }), {
185
- context: {
186
- modules: true
187
- }
188
- }), assets.assets({
189
- async: usedAssets,
190
- context: {
191
- modules: false
192
- }
187
+ cacheKey
193
188
  })]);
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
189
  const minifiedHtml = renderHtmlToString( /*#__PURE__*/jsx(Html, {
200
190
  manager: htmlManager,
201
191
  headEndContent: /*#__PURE__*/jsxs(Fragment, {
202
- children: [[...styles].map(style => {
192
+ children: [[...mainAssets.styles].map(style => {
203
193
  const attributes = styleAssetAttributes(style, {
204
194
  baseUrl: url
205
195
  });
206
196
  return /*#__PURE__*/jsx("link", {
207
197
  ...attributes
208
198
  }, style.source);
209
- }), [...moduleAssets.scripts].map(script => {
199
+ }), [...mainAssets.scripts].map(script => {
210
200
  const attributes = scriptAssetAttributes(script, {
211
201
  baseUrl: url
212
202
  });
213
- return /*#__PURE__*/jsx("script", {
203
+ return attributes.type === 'module' ? /*#__PURE__*/jsxs(Fragment$1, {
204
+ children: [/*#__PURE__*/jsx("link", {
205
+ ...scriptAssetPreloadAttributes(script)
206
+ }), /*#__PURE__*/jsx("script", {
207
+ ...attributes
208
+ })]
209
+ }, script.source) : /*#__PURE__*/jsx("script", {
214
210
  ...attributes
215
211
  }, 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 => {
212
+ }), [...preloadAssets.styles].map(style => {
226
213
  const attributes = styleAssetPreloadAttributes(style, {
227
214
  baseUrl: url
228
215
  });
229
216
  return /*#__PURE__*/jsx("link", {
230
217
  ...attributes
231
218
  }, style.source);
232
- }), [...modulePreload.scripts].map(script => {
219
+ }), [...preloadAssets.scripts].map(script => {
233
220
  const attributes = scriptAssetPreloadAttributes(script, {
234
221
  baseUrl: url
235
222
  });
@@ -2,6 +2,7 @@ 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
4
  import { AsyncAssetManager } from '@quilted/react-async/server';
5
+ import { AssetsManager } from '@quilted/react-assets/server';
5
6
  import { StaticContext } from './StaticContext.esnext';
6
7
  import { jsx } from 'react/jsx-runtime';
7
8
 
@@ -9,6 +10,7 @@ async function renderApp(app, {
9
10
  decorate,
10
11
  url,
11
12
  headers,
13
+ cacheKey,
12
14
  ...rest
13
15
  } = {}) {
14
16
  const html = new HtmlManager();
@@ -16,6 +18,9 @@ async function renderApp(app, {
16
18
  const http = new HttpManager({
17
19
  headers
18
20
  });
21
+ const assets = new AssetsManager({
22
+ cacheKey
23
+ });
19
24
  const markup = await extract(app, {
20
25
  decorate(app) {
21
26
  return /*#__PURE__*/jsx(StaticContext, {
@@ -32,6 +37,7 @@ async function renderApp(app, {
32
37
  markup,
33
38
  http,
34
39
  html,
40
+ assets,
35
41
  asyncAssets
36
42
  };
37
43
  }