@bleedingdev/modern-js-runtime 3.8.3-ultramodern.1 → 3.8.3-ultramodern.2
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.
- package/dist/cjs/cli/ssr/loadable-bundler-plugin.js +1 -1
- package/dist/cjs/core/browser/hydrate.js +1 -11
- package/dist/cjs/core/context/extensions.js +7 -2
- package/dist/cjs/core/context/runtime.js +13 -2
- package/dist/cjs/core/react/wrapper.js +10 -8
- package/dist/cjs/core/server/federatedCss.js +7 -4
- package/dist/cjs/core/server/helmet.js +2 -0
- package/dist/cjs/core/server/requestResponse.js +35 -11
- package/dist/cjs/core/server/routerCleanup.js +10 -1
- package/dist/cjs/core/server/scriptOrder.js +5 -2
- package/dist/cjs/core/server/stream/beforeTemplate.worker.js +1 -1
- package/dist/cjs/core/server/stream/createReadableStream.js +18 -5
- package/dist/cjs/core/server/stream/createReadableStream.worker.js +10 -2
- package/dist/cjs/core/server/stream/deferredScript.js +2 -1
- package/dist/cjs/core/server/string/index.js +4 -0
- package/dist/cjs/core/server/string/loadable.js +11 -2
- package/dist/cjs/core/server/utils.js +12 -5
- package/dist/cjs/exports/head.js +7 -242
- package/dist/cjs/module-federation/last-known-good.js +35 -2
- package/dist/cjs/router/cli/nestedRoutesSpec.js +7 -38
- package/dist/cjs/router/runtime/PrefetchLink.js +55 -8
- package/dist/cjs/router/runtime/redirect.js +11 -1
- package/dist/cjs/router/runtime/utils.js +2 -0
- package/dist/esm/cli/ssr/loadable-bundler-plugin.mjs +1 -1
- package/dist/esm/core/browser/hydrate.mjs +1 -11
- package/dist/esm/core/context/extensions.mjs +7 -2
- package/dist/esm/core/context/runtime.mjs +13 -2
- package/dist/esm/core/react/wrapper.mjs +11 -9
- package/dist/esm/core/server/federatedCss.mjs +7 -4
- package/dist/esm/core/server/helmet.mjs +2 -0
- package/dist/esm/core/server/requestResponse.mjs +35 -11
- package/dist/esm/core/server/routerCleanup.mjs +10 -1
- package/dist/esm/core/server/scriptOrder.mjs +6 -3
- package/dist/esm/core/server/stream/beforeTemplate.worker.mjs +2 -2
- package/dist/esm/core/server/stream/createReadableStream.mjs +16 -3
- package/dist/esm/core/server/stream/createReadableStream.worker.mjs +10 -2
- package/dist/esm/core/server/stream/deferredScript.mjs +2 -1
- package/dist/esm/core/server/string/index.mjs +4 -0
- package/dist/esm/core/server/string/loadable.mjs +11 -2
- package/dist/esm/core/server/utils.mjs +8 -4
- package/dist/esm/exports/head.mjs +8 -237
- package/dist/esm/module-federation/last-known-good.mjs +35 -2
- package/dist/esm/router/cli/nestedRoutesSpec.mjs +7 -38
- package/dist/esm/router/runtime/PrefetchLink.mjs +28 -8
- package/dist/esm/router/runtime/redirect.mjs +11 -1
- package/dist/esm/router/runtime/utils.mjs +2 -0
- package/dist/esm/rslib-runtime.mjs +9 -0
- package/dist/esm-node/cli/ssr/loadable-bundler-plugin.mjs +1 -1
- package/dist/esm-node/core/browser/hydrate.mjs +1 -11
- package/dist/esm-node/core/context/extensions.mjs +7 -2
- package/dist/esm-node/core/context/runtime.mjs +13 -2
- package/dist/esm-node/core/react/wrapper.mjs +11 -9
- package/dist/esm-node/core/server/federatedCss.mjs +7 -4
- package/dist/esm-node/core/server/helmet.mjs +2 -0
- package/dist/esm-node/core/server/requestResponse.mjs +35 -11
- package/dist/esm-node/core/server/routerCleanup.mjs +10 -1
- package/dist/esm-node/core/server/scriptOrder.mjs +6 -3
- package/dist/esm-node/core/server/stream/beforeTemplate.worker.mjs +2 -2
- package/dist/esm-node/core/server/stream/createReadableStream.mjs +16 -3
- package/dist/esm-node/core/server/stream/createReadableStream.worker.mjs +10 -2
- package/dist/esm-node/core/server/stream/deferredScript.mjs +2 -1
- package/dist/esm-node/core/server/string/index.mjs +4 -0
- package/dist/esm-node/core/server/string/loadable.mjs +11 -2
- package/dist/esm-node/core/server/utils.mjs +8 -4
- package/dist/esm-node/exports/head.mjs +8 -237
- package/dist/esm-node/module-federation/last-known-good.mjs +35 -2
- package/dist/esm-node/router/cli/nestedRoutesSpec.mjs +7 -38
- package/dist/esm-node/router/runtime/PrefetchLink.mjs +28 -8
- package/dist/esm-node/router/runtime/redirect.mjs +11 -1
- package/dist/esm-node/router/runtime/utils.mjs +2 -0
- package/dist/esm-node/rslib-runtime.mjs +10 -0
- package/dist/types/core/context/extensions.d.ts +2 -4
- package/dist/types/core/context/public.d.ts +4 -8
- package/dist/types/core/server/requestResponse.d.ts +1 -1
- package/dist/types/core/server/routerCleanup.d.ts +2 -0
- package/dist/types/core/server/string/loadable.d.ts +1 -0
- package/dist/types/core/server/utils.d.ts +1 -0
- package/dist/types/exports/head.d.ts +1 -2
- package/dist/types/module-federation/last-known-good.d.ts +0 -20
- package/package.json +10 -9
- package/rstest.config.mts +11 -4
|
@@ -54,7 +54,7 @@ class LoadablePlugin {
|
|
|
54
54
|
const chunkLoadingGlobal = this.opts.chunkLoadingGlobal ?? compiler.options.output.chunkLoadingGlobal ?? DEFAULT_CHUNK_LOADING_GLOBAL;
|
|
55
55
|
compiler.options.output.chunkLoadingGlobal = chunkLoadingGlobal;
|
|
56
56
|
new compiler.webpack.DefinePlugin({
|
|
57
|
-
|
|
57
|
+
__MODERN_CHUNK_LOADING_GLOBAL__: JSON.stringify(chunkLoadingGlobal)
|
|
58
58
|
}).apply(compiler);
|
|
59
59
|
if (this.opts.outputAsset || this.opts.writeToDisk) compiler.hooks.make.tap(LoadablePlugin.name, (compilation)=>{
|
|
60
60
|
compilation.hooks.processAssets.tap({
|
|
@@ -38,18 +38,8 @@ const client_namespaceObject = require("react-dom/client");
|
|
|
38
38
|
const external_constants_js_namespaceObject = require("../constants.js");
|
|
39
39
|
const wrapper_js_namespaceObject = require("../react/wrapper.js");
|
|
40
40
|
const external_withCallback_js_namespaceObject = require("./withCallback.js");
|
|
41
|
-
const runtimeProcess = Reflect.get(globalThis, 'process');
|
|
42
|
-
const runtimeEnvironment = null !== runtimeProcess && 'object' == typeof runtimeProcess ? Reflect.get(runtimeProcess, 'env') : void 0;
|
|
43
|
-
const readRuntimeEnvironment = (name)=>{
|
|
44
|
-
if (null === runtimeEnvironment || 'object' != typeof runtimeEnvironment) return;
|
|
45
|
-
const value = Reflect.get(runtimeEnvironment, name);
|
|
46
|
-
return 'string' == typeof value ? value : void 0;
|
|
47
|
-
};
|
|
48
41
|
const loadableReadyOptions = {
|
|
49
|
-
chunkLoadingGlobal:
|
|
50
|
-
const configured = readRuntimeEnvironment('MODERN_CHUNK_LOADING_GLOBAL');
|
|
51
|
-
return void 0 === configured || '' === configured ? '__LOADABLE_LOADED_CHUNKS__' : configured;
|
|
52
|
-
})()
|
|
42
|
+
chunkLoadingGlobal: 'string' == typeof __MODERN_CHUNK_LOADING_GLOBAL__ && '' !== __MODERN_CHUNK_LOADING_GLOBAL__ ? __MODERN_CHUNK_LOADING_GLOBAL__ : '__LOADABLE_LOADED_CHUNKS__'
|
|
53
43
|
};
|
|
54
44
|
function hydrateWithReact(App, rootElement) {
|
|
55
45
|
return Promise.resolve((0, client_namespaceObject.hydrateRoot)(rootElement, App, {
|
|
@@ -33,8 +33,13 @@ function getStore(context) {
|
|
|
33
33
|
}
|
|
34
34
|
function ensureStore(context) {
|
|
35
35
|
const target = context;
|
|
36
|
-
target[EXTENSIONS_SLOT]
|
|
37
|
-
|
|
36
|
+
const store = target[EXTENSIONS_SLOT] ?? new Map();
|
|
37
|
+
Object.defineProperty(target, EXTENSIONS_SLOT, {
|
|
38
|
+
configurable: true,
|
|
39
|
+
enumerable: true,
|
|
40
|
+
value: store
|
|
41
|
+
});
|
|
42
|
+
return store;
|
|
38
43
|
}
|
|
39
44
|
function stripRuntimeContextExtensions(context) {
|
|
40
45
|
delete context[EXTENSIONS_SLOT];
|
|
@@ -40,8 +40,19 @@ const ROUTE_MANIFEST = '_MODERNJS_ROUTE_MANIFEST';
|
|
|
40
40
|
const InternalRuntimeContext = (0, external_react_namespaceObject.createContext)({});
|
|
41
41
|
const getInitialContext = (isBrowser = true, routeManifest)=>{
|
|
42
42
|
const requestContext = {
|
|
43
|
-
request: {
|
|
44
|
-
|
|
43
|
+
request: {
|
|
44
|
+
params: {},
|
|
45
|
+
pathname: '',
|
|
46
|
+
query: {},
|
|
47
|
+
headers: {},
|
|
48
|
+
host: '',
|
|
49
|
+
url: ''
|
|
50
|
+
},
|
|
51
|
+
response: {
|
|
52
|
+
setHeader () {},
|
|
53
|
+
status () {},
|
|
54
|
+
locals: {}
|
|
55
|
+
}
|
|
45
56
|
};
|
|
46
57
|
return {
|
|
47
58
|
isBrowser,
|
|
@@ -36,12 +36,14 @@ const index_js_namespaceObject = require("../context/index.js");
|
|
|
36
36
|
const extensions_js_namespaceObject = require("../context/extensions.js");
|
|
37
37
|
const helmetContext_js_namespaceObject = require("../context/helmetContext.js");
|
|
38
38
|
function createRscSafeRequestContext(ssrContext) {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
39
|
+
const requestContext = (0, index_js_namespaceObject.getInitialContext)().requestContext;
|
|
40
|
+
Object.defineProperty(requestContext.response, 'setHeader', {
|
|
41
|
+
enumerable: false
|
|
42
|
+
});
|
|
43
|
+
Object.defineProperty(requestContext.response, 'status', {
|
|
44
|
+
enumerable: false
|
|
45
|
+
});
|
|
46
|
+
if (void 0 === ssrContext) return requestContext;
|
|
45
47
|
const { request, response } = ssrContext;
|
|
46
48
|
return {
|
|
47
49
|
request: {
|
|
@@ -61,9 +63,9 @@ function createRscSafeRequestContext(ssrContext) {
|
|
|
61
63
|
host: request.host,
|
|
62
64
|
referer: request.referer
|
|
63
65
|
},
|
|
64
|
-
response: {
|
|
66
|
+
response: Object.assign(requestContext.response, {
|
|
65
67
|
locals: response.locals ?? {}
|
|
66
|
-
}
|
|
68
|
+
})
|
|
67
69
|
};
|
|
68
70
|
}
|
|
69
71
|
function wrapRuntimeContextProvider(App, contextValue) {
|
|
@@ -30,16 +30,19 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
30
30
|
__webpack_require__.d(__webpack_exports__, {
|
|
31
31
|
createFederatedCssLinks: ()=>createFederatedCssLinks
|
|
32
32
|
});
|
|
33
|
+
const runtime_extensions_namespaceObject = require("@modern-js/runtime-extensions");
|
|
33
34
|
const external_utils_js_namespaceObject = require("./utils.js");
|
|
34
|
-
const escapeHtmlAttribute = (value)=>value.replaceAll('&', '&').replaceAll('"', '"').replaceAll('<', '<').replaceAll('>', '>');
|
|
35
35
|
const createFederatedCssLinks = (assets, options)=>{
|
|
36
36
|
if (void 0 === assets || 0 === assets.length) return '';
|
|
37
37
|
const seen = new Set(options.existingAssets || []);
|
|
38
|
-
const attributes = (0, external_utils_js_namespaceObject.attributesToString)(options.attributes || {})
|
|
38
|
+
const attributes = (0, external_utils_js_namespaceObject.attributesToString)(Object.fromEntries(Object.entries(options.attributes || {}).filter(([name])=>![
|
|
39
|
+
'href',
|
|
40
|
+
'rel'
|
|
41
|
+
].includes(name.toLowerCase()))));
|
|
39
42
|
const links = [];
|
|
40
43
|
for (const asset of assets){
|
|
41
|
-
const href = escapeHtmlAttribute(asset);
|
|
42
|
-
if (!('' === asset || seen.has(asset) || options.template
|
|
44
|
+
const href = (0, runtime_extensions_namespaceObject.escapeHtmlAttribute)(asset);
|
|
45
|
+
if (!('' === asset || seen.has(asset) || (0, external_utils_js_namespaceObject.hasStylesheetLink)(options.template, asset) || (0, external_utils_js_namespaceObject.hasStylesheetLink)(options.template, href))) {
|
|
43
46
|
seen.add(asset);
|
|
44
47
|
links.push(`<link${attributes} href="${href}" rel="stylesheet" />`);
|
|
45
48
|
}
|
|
@@ -53,6 +53,7 @@ function helmetReplace(content, helmetData) {
|
|
|
53
53
|
const htmlAttributes = helmetData.htmlAttributes.toString();
|
|
54
54
|
if (htmlAttributes) result = (0, external_utils_js_namespaceObject.safeReplace)(result, RE_HTML_ATTR, `<html ${htmlAttributes}>`);
|
|
55
55
|
const base = helmetData.base.toString();
|
|
56
|
+
const priority = helmetData.priority.toString();
|
|
56
57
|
const link = helmetData.link.toString();
|
|
57
58
|
const meta = helmetData.meta.toString();
|
|
58
59
|
const noscript = helmetData.noscript.toString();
|
|
@@ -64,6 +65,7 @@ function helmetReplace(content, helmetData) {
|
|
|
64
65
|
if (shouldReplaceTitle) result = (0, external_utils_js_namespaceObject.safeReplace)(result, RE_TITLE, title);
|
|
65
66
|
const helmetStr = [
|
|
66
67
|
base,
|
|
68
|
+
priority,
|
|
67
69
|
link,
|
|
68
70
|
meta,
|
|
69
71
|
noscript,
|
|
@@ -35,9 +35,15 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
35
35
|
const lifecycle_js_namespaceObject = require("../../router/runtime/lifecycle.js");
|
|
36
36
|
const redirect_js_namespaceObject = require("../../router/runtime/redirect.js");
|
|
37
37
|
const external_tracer_js_namespaceObject = require("./tracer.js");
|
|
38
|
-
const isRedirectStatus = (status)=>status
|
|
38
|
+
const isRedirectStatus = (status)=>301 === status || 302 === status || 303 === status || 307 === status || 308 === status;
|
|
39
39
|
const isNullBodyStatus = (status)=>204 === status || 205 === status || 304 === status;
|
|
40
|
+
const getRedirectLocation = (headers)=>{
|
|
41
|
+
const location = headers.get('Location');
|
|
42
|
+
return location && URL.canParse(location, 'http://localhost') ? location : void 0;
|
|
43
|
+
};
|
|
40
44
|
const processRedirect = (headers, status, ctx)=>{
|
|
45
|
+
headers.delete('content-length');
|
|
46
|
+
headers.delete('transfer-encoding');
|
|
41
47
|
if (ctx.enableRsc && ctx.isRSCNavigation) return (0, redirect_js_namespaceObject.handleRSCRedirect)(headers, ctx.basename, status);
|
|
42
48
|
return new Response(null, {
|
|
43
49
|
status,
|
|
@@ -54,20 +60,38 @@ const applyRouterSnapshotResult = (context, onError)=>{
|
|
|
54
60
|
const createLoaderRedirectResponse = (beforeRenderResult, redirectCtx)=>{
|
|
55
61
|
if (void 0 === beforeRenderResult || !isRedirectStatus(beforeRenderResult.status)) return;
|
|
56
62
|
if (beforeRenderResult.headers.has('X-Modernjs-Redirect')) return beforeRenderResult;
|
|
57
|
-
const redirectUrl = beforeRenderResult.headers
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
}), beforeRenderResult.status, redirectCtx);
|
|
63
|
+
const redirectUrl = getRedirectLocation(beforeRenderResult.headers);
|
|
64
|
+
if (!redirectUrl) return;
|
|
65
|
+
return processRedirect(new Headers(beforeRenderResult.headers), beforeRenderResult.status, redirectCtx);
|
|
61
66
|
};
|
|
62
|
-
const finalizeRenderResponse = (response, responseProxy, redirectCtx, routerCleanup)=>{
|
|
63
|
-
|
|
67
|
+
const finalizeRenderResponse = async (response, responseProxy, redirectCtx, routerCleanup)=>{
|
|
68
|
+
const proxyHeaders = new Headers(responseProxy.headers);
|
|
69
|
+
if (-1 !== responseProxy.status && isRedirectStatus(responseProxy.status) && void 0 !== getRedirectLocation(proxyHeaders)) {
|
|
70
|
+
await routerCleanup.discardBody(response);
|
|
71
|
+
return processRedirect(proxyHeaders, responseProxy.status, redirectCtx);
|
|
72
|
+
}
|
|
73
|
+
const headers = new Headers(response.headers);
|
|
74
|
+
Object.entries(responseProxy.headers).forEach(([key, value])=>{
|
|
75
|
+
headers.set(key, value);
|
|
76
|
+
});
|
|
77
|
+
if (-1 !== responseProxy.status) {
|
|
78
|
+
if (isNullBodyStatus(responseProxy.status)) {
|
|
79
|
+
await routerCleanup.discardBody(response);
|
|
80
|
+
headers.delete('content-length');
|
|
81
|
+
headers.delete('transfer-encoding');
|
|
82
|
+
return new Response(null, {
|
|
83
|
+
status: responseProxy.status,
|
|
84
|
+
headers
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
return routerCleanup.deferUntilBodyDone(new Response(response.body, {
|
|
88
|
+
status: responseProxy.status,
|
|
89
|
+
headers
|
|
90
|
+
}));
|
|
91
|
+
}
|
|
64
92
|
Object.entries(responseProxy.headers).forEach(([key, value])=>{
|
|
65
93
|
response.headers.set(key, value);
|
|
66
94
|
});
|
|
67
|
-
if (-1 !== responseProxy.status) return routerCleanup.deferUntilBodyDone(new Response(isNullBodyStatus(responseProxy.status) ? null : response.body, {
|
|
68
|
-
status: responseProxy.status,
|
|
69
|
-
headers: response.headers
|
|
70
|
-
}));
|
|
71
95
|
return routerCleanup.deferUntilBodyDone(response);
|
|
72
96
|
};
|
|
73
97
|
exports.applyRouterSnapshotResult = __webpack_exports__.applyRouterSnapshotResult;
|
|
@@ -97,12 +97,21 @@ function createRouterCleanup(runtimeContext, onError) {
|
|
|
97
97
|
headers: response.headers
|
|
98
98
|
});
|
|
99
99
|
};
|
|
100
|
+
const discardBody = async (response)=>{
|
|
101
|
+
const { body } = response;
|
|
102
|
+
if (!body) return void await run();
|
|
103
|
+
deferred = true;
|
|
104
|
+
if (body.locked) throw new TypeError('Cannot discard a locked response body before router cleanup');
|
|
105
|
+
await body.cancel('Response body discarded during finalization');
|
|
106
|
+
await run();
|
|
107
|
+
};
|
|
100
108
|
return {
|
|
101
109
|
get deferred () {
|
|
102
110
|
return deferred;
|
|
103
111
|
},
|
|
104
112
|
run,
|
|
105
|
-
deferUntilBodyDone
|
|
113
|
+
deferUntilBodyDone,
|
|
114
|
+
discardBody
|
|
106
115
|
};
|
|
107
116
|
}
|
|
108
117
|
exports.ROUTER_CLEANUP_ERROR = __webpack_exports__.ROUTER_CLEANUP_ERROR;
|
|
@@ -102,6 +102,7 @@ function injectBeforeHydrationEntryScript(template, scripts, entryName = 'index'
|
|
|
102
102
|
return `${template.slice(0, target.index)}${scripts}${template.slice(target.index)}`;
|
|
103
103
|
}
|
|
104
104
|
function replaceChunkJsPlaceholder(template, scripts, entryName, placeholder = external_constants_js_namespaceObject.CHUNK_JS_PLACEHOLDER) {
|
|
105
|
+
if (!template.includes(placeholder)) return template;
|
|
105
106
|
if ('' === scripts) return (0, external_utils_js_namespaceObject.safeReplace)(template, placeholder, '');
|
|
106
107
|
const withoutPlaceholder = (0, external_utils_js_namespaceObject.safeReplace)(template, placeholder, '');
|
|
107
108
|
const withEarlyScripts = injectBeforeHydrationEntryScript(withoutPlaceholder, scripts, entryName);
|
|
@@ -117,8 +118,10 @@ function createRouteHydrationScriptTags(runtimeContext, entryName, options = {})
|
|
|
117
118
|
...getMatchedRouteAssets(runtimeContext),
|
|
118
119
|
...routeAssets[`async-${entryName}`]?.assets ?? []
|
|
119
120
|
].filter((asset)=>asset.endsWith('.js'))));
|
|
120
|
-
|
|
121
|
-
|
|
121
|
+
return jsAssets.filter((asset)=>!existingScriptSrcs.has(asset)).map((asset)=>`<script${(0, external_utils_js_namespaceObject.attributesToString)({
|
|
122
|
+
src: asset,
|
|
123
|
+
nonce: nonce || void 0
|
|
124
|
+
})}></script>`).join(' ');
|
|
122
125
|
}
|
|
123
126
|
exports.createRouteHydrationScriptTags = __webpack_exports__.createRouteHydrationScriptTags;
|
|
124
127
|
exports.getMatchedRouteChunks = __webpack_exports__.getMatchedRouteChunks;
|
|
@@ -68,7 +68,7 @@ async function buildShellBeforeTemplate(beforeAppTemplate, options) {
|
|
|
68
68
|
if (asyncEntry) matchedRouteManifests.push(asyncEntry);
|
|
69
69
|
const cssChunks = matchedRouteManifests.reduce((chunks, routeManifest)=>{
|
|
70
70
|
const { referenceCssAssets = [] } = routeManifest;
|
|
71
|
-
const _cssChunks = referenceCssAssets.filter((asset)=>asset?.endsWith('.css') && !
|
|
71
|
+
const _cssChunks = referenceCssAssets.filter((asset)=>asset?.endsWith('.css') && !(0, external_utils_js_namespaceObject.hasStylesheetLink)(template, asset));
|
|
72
72
|
return [
|
|
73
73
|
...chunks,
|
|
74
74
|
..._cssChunks
|
|
@@ -30,13 +30,15 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
30
30
|
__webpack_require__.d(__webpack_exports__, {
|
|
31
31
|
createReadableStreamFromElement: ()=>createReadableStreamFromElement
|
|
32
32
|
});
|
|
33
|
-
const node_namespaceObject = require("@modern-js/runtime-
|
|
33
|
+
const node_namespaceObject = require("@modern-js/runtime-extensions/node");
|
|
34
|
+
const runtime_utils_node_namespaceObject = require("@modern-js/runtime-utils/node");
|
|
34
35
|
const constants_namespaceObject = require("@modern-js/utils/universal/constants");
|
|
35
36
|
const external_stream_namespaceObject = require("stream");
|
|
36
37
|
const external_common_js_namespaceObject = require("../../../common.js");
|
|
37
38
|
const external_constants_js_namespaceObject = require("../../constants.js");
|
|
38
39
|
const index_js_namespaceObject = require("../../context/index.js");
|
|
39
40
|
const monitors_index_js_namespaceObject = require("../../context/monitors/index.js");
|
|
41
|
+
const external_helmet_js_namespaceObject = require("../helmet.js");
|
|
40
42
|
const external_deferredScript_js_namespaceObject = require("./deferredScript.js");
|
|
41
43
|
const external_shared_js_namespaceObject = require("./shared.js");
|
|
42
44
|
const external_template_js_namespaceObject = require("./template.js");
|
|
@@ -68,6 +70,8 @@ const createReadableStreamFromElement = async (request, rootElement, options)=>{
|
|
|
68
70
|
});
|
|
69
71
|
const chunkVec = [];
|
|
70
72
|
let hasStartedPipe = false;
|
|
73
|
+
node_namespaceObject.beginHeadRender(runtimeContext);
|
|
74
|
+
const reportError = node_namespaceObject.createOnceErrorReporter(options.onError);
|
|
71
75
|
return new Promise((resolve)=>{
|
|
72
76
|
const { pipe: reactStreamingPipe } = renderToPipeableStream(processedRootElement, {
|
|
73
77
|
nonce: config.nonce,
|
|
@@ -101,8 +105,10 @@ const createReadableStreamFromElement = async (request, rootElement, options)=>{
|
|
|
101
105
|
if (-1 !== markerIndex) {
|
|
102
106
|
const beforeMark = concatedChunk.slice(0, markerIndex);
|
|
103
107
|
const afterMark = concatedChunk.slice(markerIndex + external_common_js_namespaceObject.ESCAPED_SHELL_STREAM_END_MARK.length);
|
|
108
|
+
node_namespaceObject.publishHeadRender(runtimeContext);
|
|
109
|
+
const completedShellBefore = (0, external_helmet_js_namespaceObject.createReplaceHelemt)((0, external_helmet_js_namespaceObject.getHelmetData)(runtimeContext))(shellBefore);
|
|
104
110
|
shellChunkStatus = external_shared_js_namespaceObject.ShellChunkStatus.FINISH;
|
|
105
|
-
this.push(`${
|
|
111
|
+
this.push(`${completedShellBefore}${beforeMark}${shellAfter}`);
|
|
106
112
|
if (afterMark) this.push(afterMark);
|
|
107
113
|
if (pendingScripts.length > 0) for (const s of pendingScripts)this.push(s);
|
|
108
114
|
}
|
|
@@ -120,10 +126,16 @@ const createReadableStreamFromElement = async (request, rootElement, options)=>{
|
|
|
120
126
|
extenders.forEach((extender)=>{
|
|
121
127
|
if (extender.processStream) processedStream = extender.processStream(processedStream);
|
|
122
128
|
});
|
|
129
|
+
node_namespaceObject.pipeNodeHeadStream({
|
|
130
|
+
source: processedStream,
|
|
131
|
+
destination: body,
|
|
132
|
+
context: runtimeContext,
|
|
133
|
+
terminalMarker: external_common_js_namespaceObject.ESCAPED_SHELL_STREAM_END_MARK,
|
|
134
|
+
onError: reportError
|
|
135
|
+
});
|
|
123
136
|
reactStreamingPipe(passThrough);
|
|
124
|
-
processedStream.pipe(body);
|
|
125
137
|
try {
|
|
126
|
-
const storageContext =
|
|
138
|
+
const storageContext = runtime_utils_node_namespaceObject.storage.useContext?.();
|
|
127
139
|
const activeDeferreds = storageContext?.activeDeferreds;
|
|
128
140
|
const entries = activeDeferreds instanceof Map ? Array.from(activeDeferreds.entries()) : [];
|
|
129
141
|
if (entries.length > 0) {
|
|
@@ -140,6 +152,7 @@ const createReadableStreamFromElement = async (request, rootElement, options)=>{
|
|
|
140
152
|
});
|
|
141
153
|
},
|
|
142
154
|
onShellError (error) {
|
|
155
|
+
node_namespaceObject.abortHeadRender(runtimeContext);
|
|
143
156
|
renderLevel = external_constants_js_namespaceObject.RenderLevel.CLIENT_RENDER;
|
|
144
157
|
(0, external_template_js_namespaceObject.getTemplates)(htmlTemplate, {
|
|
145
158
|
request,
|
|
@@ -158,7 +171,7 @@ const createReadableStreamFromElement = async (request, rootElement, options)=>{
|
|
|
158
171
|
},
|
|
159
172
|
onError (error) {
|
|
160
173
|
renderLevel = external_constants_js_namespaceObject.RenderLevel.CLIENT_RENDER;
|
|
161
|
-
|
|
174
|
+
reportError(error);
|
|
162
175
|
}
|
|
163
176
|
});
|
|
164
177
|
});
|
|
@@ -31,9 +31,11 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
31
31
|
createReadableStreamFromElement: ()=>createReadableStreamFromElement
|
|
32
32
|
});
|
|
33
33
|
const ssr_namespaceObject = require("@modern-js/render/ssr");
|
|
34
|
+
const runtime_extensions_namespaceObject = require("@modern-js/runtime-extensions");
|
|
34
35
|
const node_namespaceObject = require("@modern-js/runtime-utils/node");
|
|
35
36
|
const external_common_js_namespaceObject = require("../../../common.js");
|
|
36
37
|
const external_constants_js_namespaceObject = require("../../constants.js");
|
|
38
|
+
const external_helmet_js_namespaceObject = require("../helmet.js");
|
|
37
39
|
const external_deferredScript_js_namespaceObject = require("./deferredScript.js");
|
|
38
40
|
const external_shared_js_namespaceObject = require("./shared.js");
|
|
39
41
|
const external_template_js_namespaceObject = require("./template.js");
|
|
@@ -41,6 +43,7 @@ const createReadableStreamFromElement = async (request, rootElement, options)=>{
|
|
|
41
43
|
let shellChunkStatus = external_shared_js_namespaceObject.ShellChunkStatus.START;
|
|
42
44
|
const chunkVec = [];
|
|
43
45
|
const { htmlTemplate, runtimeContext, config, ssrConfig, entryName, moduleFederationCssAssets, rscManifest, rscRoot } = options;
|
|
46
|
+
runtime_extensions_namespaceObject.beginHeadRender(runtimeContext);
|
|
44
47
|
const { shellBefore, shellAfter } = await (0, external_template_js_namespaceObject.getTemplates)(htmlTemplate, {
|
|
45
48
|
renderLevel: external_constants_js_namespaceObject.RenderLevel.SERVER_RENDER,
|
|
46
49
|
runtimeContext,
|
|
@@ -68,7 +71,7 @@ const createReadableStreamFromElement = async (request, rootElement, options)=>{
|
|
|
68
71
|
const forceStreamToString = Boolean("u" > typeof process && process.env?.MODERN_JS_STREAM_TO_STRING);
|
|
69
72
|
const { waitForAllReady } = (0, external_shared_js_namespaceObject.resolveStreamingMode)(request, forceStreamToString);
|
|
70
73
|
if (waitForAllReady) await readableOriginal.allReady;
|
|
71
|
-
const reader = readableOriginal.getReader();
|
|
74
|
+
const reader = runtime_extensions_namespaceObject.createConservingWebShellStream(readableOriginal, runtimeContext, external_common_js_namespaceObject.ESCAPED_SHELL_STREAM_END_MARK, options.onError).getReader();
|
|
72
75
|
const stream = new ReadableStream({
|
|
73
76
|
start (controller) {
|
|
74
77
|
const pendingScripts = [];
|
|
@@ -113,14 +116,17 @@ const createReadableStreamFromElement = async (request, rootElement, options)=>{
|
|
|
113
116
|
if (-1 !== markerIndex) {
|
|
114
117
|
const beforeMark = concatedChunk.slice(0, markerIndex);
|
|
115
118
|
const afterMark = concatedChunk.slice(markerIndex + external_common_js_namespaceObject.ESCAPED_SHELL_STREAM_END_MARK.length);
|
|
119
|
+
runtime_extensions_namespaceObject.publishHeadRender(runtimeContext);
|
|
120
|
+
const completedShellBefore = (0, external_helmet_js_namespaceObject.createReplaceHelemt)((0, external_helmet_js_namespaceObject.getHelmetData)(runtimeContext))(shellBefore);
|
|
116
121
|
shellChunkStatus = external_shared_js_namespaceObject.ShellChunkStatus.FINISH;
|
|
117
|
-
safeEnqueue((0, external_shared_js_namespaceObject.encodeForWebStream)(`${
|
|
122
|
+
safeEnqueue((0, external_shared_js_namespaceObject.encodeForWebStream)(`${completedShellBefore}${beforeMark}${shellAfter}`));
|
|
118
123
|
if (afterMark.length > 0) safeEnqueue((0, external_shared_js_namespaceObject.encodeForWebStream)(afterMark));
|
|
119
124
|
flushPendingScripts();
|
|
120
125
|
}
|
|
121
126
|
} else safeEnqueue(value);
|
|
122
127
|
if (!isClosed) push();
|
|
123
128
|
} catch (error) {
|
|
129
|
+
runtime_extensions_namespaceObject.abortHeadRender(runtimeContext);
|
|
124
130
|
if (!isClosed) {
|
|
125
131
|
isClosed = true;
|
|
126
132
|
try {
|
|
@@ -132,11 +138,13 @@ const createReadableStreamFromElement = async (request, rootElement, options)=>{
|
|
|
132
138
|
push();
|
|
133
139
|
},
|
|
134
140
|
cancel (reason) {
|
|
141
|
+
runtime_extensions_namespaceObject.abortHeadRender(runtimeContext);
|
|
135
142
|
reader.cancel(reason).catch(()=>{});
|
|
136
143
|
}
|
|
137
144
|
});
|
|
138
145
|
return stream;
|
|
139
146
|
} catch (e) {
|
|
147
|
+
runtime_extensions_namespaceObject.abortHeadRender(runtimeContext);
|
|
140
148
|
const fallbackHtml = `${shellBefore}${shellAfter}`;
|
|
141
149
|
const stream = (0, external_shared_js_namespaceObject.getReadableStreamFromString)(fallbackHtml);
|
|
142
150
|
return stream;
|
|
@@ -37,6 +37,7 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
37
37
|
toErrorInfo: ()=>toErrorInfo
|
|
38
38
|
});
|
|
39
39
|
const constants_js_namespaceObject = require("../../../router/runtime/constants.js");
|
|
40
|
+
const external_utils_js_namespaceObject = require("../utils.js");
|
|
40
41
|
const HTML_ESCAPE_MAP = {
|
|
41
42
|
'&': '&',
|
|
42
43
|
'<': '<',
|
|
@@ -60,7 +61,7 @@ function isPromiseLike(value) {
|
|
|
60
61
|
return !!value && 'function' == typeof value.then;
|
|
61
62
|
}
|
|
62
63
|
function toErrorInfo(error) {
|
|
63
|
-
if (
|
|
64
|
+
if ((0, external_utils_js_namespaceObject.shouldRedactServerError)()) return {
|
|
64
65
|
message: 'Unexpected Server Error'
|
|
65
66
|
};
|
|
66
67
|
if (error && 'object' == typeof error) {
|
|
@@ -39,6 +39,7 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
39
39
|
__webpack_require__.d(__webpack_exports__, {
|
|
40
40
|
renderString: ()=>renderString
|
|
41
41
|
});
|
|
42
|
+
const runtime_extensions_namespaceObject = require("@modern-js/runtime-extensions");
|
|
42
43
|
const time_namespaceObject = require("@modern-js/runtime-utils/time");
|
|
43
44
|
const constants_namespaceObject = require("@modern-js/utils/universal/constants");
|
|
44
45
|
const server_namespaceObject = require("react-dom/server");
|
|
@@ -108,16 +109,19 @@ async function generateHtml(App, htmlTemplate, chunkSet, collectors, htmlModifie
|
|
|
108
109
|
let html = '';
|
|
109
110
|
let helmetData;
|
|
110
111
|
const finalApp = collectors.reduce((pre, creator)=>creator.collect?.(pre) || pre, App);
|
|
112
|
+
runtime_extensions_namespaceObject.beginHeadRender(runtimeContext);
|
|
111
113
|
try {
|
|
112
114
|
const end = (0, time_namespaceObject.time)();
|
|
113
115
|
html = server_default().renderToString(finalApp, {
|
|
114
116
|
identifierPrefix: constants_namespaceObject.SSR_HYDRATION_ID_PREFIX
|
|
115
117
|
});
|
|
118
|
+
html = runtime_extensions_namespaceObject.completeHeadRender(runtimeContext, html);
|
|
116
119
|
chunkSet.renderLevel = external_constants_js_namespaceObject.RenderLevel.SERVER_RENDER;
|
|
117
120
|
helmetData = (0, external_helmet_js_namespaceObject.getHelmetData)(runtimeContext);
|
|
118
121
|
const cost = end();
|
|
119
122
|
onTiming(external_tracer_js_namespaceObject.SSRTimings.RENDER_HTML, cost);
|
|
120
123
|
} catch (e) {
|
|
124
|
+
runtime_extensions_namespaceObject.abortHeadRender(runtimeContext);
|
|
121
125
|
chunkSet.renderLevel = external_constants_js_namespaceObject.RenderLevel.CLIENT_RENDER;
|
|
122
126
|
onError(e, external_tracer_js_namespaceObject.SSRErrors.RENDER_HTML);
|
|
123
127
|
}
|
|
@@ -60,6 +60,10 @@ const readAsset = async (chunk)=>{
|
|
|
60
60
|
return fs.readFile(filepath, 'utf-8');
|
|
61
61
|
};
|
|
62
62
|
class LoadableCollector {
|
|
63
|
+
get existsAssets() {
|
|
64
|
+
const { routeManifest, entryName } = this.options;
|
|
65
|
+
return routeManifest?.routeAssets?.[entryName]?.assets;
|
|
66
|
+
}
|
|
63
67
|
collect(comopnent) {
|
|
64
68
|
const { stats, entryName } = this.options;
|
|
65
69
|
if (!stats) return comopnent;
|
|
@@ -121,7 +125,7 @@ class LoadableCollector {
|
|
|
121
125
|
const matchs = template.matchAll(jsScriptRegExp);
|
|
122
126
|
const existedScript = [];
|
|
123
127
|
for (const match of matchs)existedScript.push(match[1]);
|
|
124
|
-
const scripts = await Promise.all(chunks.filter((chunk)=>!existedScript.includes(chunk.url)).map(async (chunk)=>{
|
|
128
|
+
const scripts = await Promise.all(chunks.filter((chunk)=>!existedScript.includes(chunk.url) && !this.existsAssets?.includes(chunk.path)).map(async (chunk)=>{
|
|
125
129
|
const script = `<script${attributes} src="${chunk.url}"></script>`;
|
|
126
130
|
if ((0, external_utils_js_namespaceObject.checkIsNode)() && checkIsInline(chunk, inlineStyles)) return readAsset(chunk).then((content)=>`<script>${content}</script>`).catch((_)=>script);
|
|
127
131
|
return script;
|
|
@@ -132,7 +136,12 @@ class LoadableCollector {
|
|
|
132
136
|
const { template, chunkSet, config, moduleFederationCssAssets } = this.options;
|
|
133
137
|
const { inlineStyles } = config;
|
|
134
138
|
const atrributes = (0, external_utils_js_namespaceObject.attributesToString)(this.generateAttributes());
|
|
135
|
-
const
|
|
139
|
+
const emittedAssetUrls = new Set();
|
|
140
|
+
const emittedChunks = chunks.filter((chunk)=>{
|
|
141
|
+
const shouldEmit = !(0, external_utils_js_namespaceObject.hasStylesheetLink)(template, chunk.url) && !this.existsAssets?.includes(chunk.path) && !emittedAssetUrls.has(chunk.url);
|
|
142
|
+
if (shouldEmit) emittedAssetUrls.add(chunk.url);
|
|
143
|
+
return shouldEmit;
|
|
144
|
+
});
|
|
136
145
|
const css = await Promise.all(emittedChunks.map(async (chunk)=>{
|
|
137
146
|
const link = `<link${atrributes} href="${chunk.url}" rel="stylesheet" />`;
|
|
138
147
|
if ((0, external_utils_js_namespaceObject.checkIsNode)() && checkIsInline(chunk, inlineStyles)) return readAsset(chunk).then((content)=>`<style>${content}</style>`).catch((_)=>link);
|
|
@@ -34,11 +34,13 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
34
34
|
getSSRMode: ()=>getSSRMode,
|
|
35
35
|
hasStylesheetLink: ()=>hasStylesheetLink,
|
|
36
36
|
safeReplace: ()=>safeReplace,
|
|
37
|
-
serializeErrors: ()=>serializeErrors
|
|
37
|
+
serializeErrors: ()=>serializeErrors,
|
|
38
|
+
shouldRedactServerError: ()=>shouldRedactServerError
|
|
38
39
|
});
|
|
40
|
+
const runtime_extensions_namespaceObject = require("@modern-js/runtime-extensions");
|
|
39
41
|
const routerHelper_js_namespaceObject = require("../../router/runtime/routerHelper.js");
|
|
40
42
|
function attributesToString(attributes) {
|
|
41
|
-
return Object.entries(attributes).reduce((str, [key, value])=>void 0
|
|
43
|
+
return Object.entries(attributes).reduce((str, [key, value])=>void 0 !== value && (0, runtime_extensions_namespaceObject.isSafeHtmlAttributeName)(key) ? `${str} ${key}="${(0, runtime_extensions_namespaceObject.escapeHtmlAttribute)(value)}"` : str, '');
|
|
42
44
|
}
|
|
43
45
|
function safeReplace(source, searchValue, replaceValue) {
|
|
44
46
|
return source.replace(searchValue, ()=>replaceValue);
|
|
@@ -76,12 +78,14 @@ function serializeRouteErrorResponse(error) {
|
|
|
76
78
|
status: error.status,
|
|
77
79
|
statusText: 'Internal Server Error',
|
|
78
80
|
data: 'Unexpected Server Error',
|
|
81
|
+
internal: error.internal,
|
|
79
82
|
__type: 'RouteErrorResponse'
|
|
80
83
|
};
|
|
81
84
|
return {
|
|
82
85
|
status: error.status,
|
|
83
86
|
statusText: error.statusText,
|
|
84
87
|
data: error.data,
|
|
88
|
+
internal: error.internal,
|
|
85
89
|
__type: 'RouteErrorResponse'
|
|
86
90
|
};
|
|
87
91
|
}
|
|
@@ -103,8 +107,9 @@ const getLinkAttributes = (linkTag)=>{
|
|
|
103
107
|
let match;
|
|
104
108
|
while(match = attributeRegExp.exec(linkTag)){
|
|
105
109
|
const [, name, doubleQuotedValue, singleQuotedValue, unquotedValue] = match;
|
|
106
|
-
|
|
107
|
-
|
|
110
|
+
const normalizedName = name.toLowerCase();
|
|
111
|
+
if ('link' === normalizedName || attributes.has(normalizedName)) continue;
|
|
112
|
+
attributes.set(normalizedName, doubleQuotedValue ?? singleQuotedValue ?? unquotedValue ?? '');
|
|
108
113
|
}
|
|
109
114
|
return attributes;
|
|
110
115
|
};
|
|
@@ -124,6 +129,7 @@ exports.getSSRMode = __webpack_exports__.getSSRMode;
|
|
|
124
129
|
exports.hasStylesheetLink = __webpack_exports__.hasStylesheetLink;
|
|
125
130
|
exports.safeReplace = __webpack_exports__.safeReplace;
|
|
126
131
|
exports.serializeErrors = __webpack_exports__.serializeErrors;
|
|
132
|
+
exports.shouldRedactServerError = __webpack_exports__.shouldRedactServerError;
|
|
127
133
|
for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
128
134
|
"attributesToString",
|
|
129
135
|
"checkIsNode",
|
|
@@ -131,7 +137,8 @@ for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
|
131
137
|
"getSSRMode",
|
|
132
138
|
"hasStylesheetLink",
|
|
133
139
|
"safeReplace",
|
|
134
|
-
"serializeErrors"
|
|
140
|
+
"serializeErrors",
|
|
141
|
+
"shouldRedactServerError"
|
|
135
142
|
].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
136
143
|
Object.defineProperty(exports, '__esModule', {
|
|
137
144
|
value: true
|