@bleedingdev/modern-js-runtime 3.9.0-ultramodern.9 → 3.9.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/code.js +2 -2
- package/dist/cjs/cli/index.js +0 -7
- package/dist/cjs/cli/ssr/loadable-bundler-plugin.js +2 -0
- package/dist/cjs/cli/template.server.js +1 -2
- package/dist/cjs/core/browser/hydrate.js +3 -9
- package/dist/cjs/core/browser/index.js +4 -5
- package/dist/cjs/core/context/index.js +8 -2
- package/dist/cjs/core/context/public.js +4 -4
- package/dist/cjs/core/context/runtime.js +3 -9
- package/dist/cjs/core/index.js +3 -3
- package/dist/cjs/core/plugin/index.js +2 -2
- package/dist/cjs/core/react/index.js +3 -3
- package/dist/cjs/core/react/wrapper.js +7 -8
- package/dist/cjs/core/server/requestHandler.js +253 -25
- package/dist/cjs/core/server/stream/beforeTemplate.js +3 -3
- package/dist/cjs/core/server/stream/beforeTemplate.worker.js +2 -2
- package/dist/cjs/core/server/stream/createReadableStream.js +51 -19
- package/dist/cjs/core/server/stream/createReadableStream.worker.js +54 -27
- package/dist/cjs/core/server/stream/deferredScript.js +12 -6
- package/dist/cjs/core/server/stream/deferredScriptOutputCoordinator.js +370 -0
- package/dist/cjs/core/server/stream/shared.js +4 -0
- package/dist/cjs/core/server/string/index.js +6 -4
- package/dist/cjs/core/server/string/loadable.js +4 -4
- package/dist/cjs/document/cli/index.js +14 -5
- package/dist/cjs/exports/head.js +2 -2
- package/dist/cjs/internal.js +2 -2
- package/dist/cjs/router/cli/code/nestedRoutes.js +1 -2
- package/dist/cjs/router/cli/code/templates.js +2 -2
- package/dist/cjs/router/cli/code/utils.js +5 -4
- package/dist/cjs/router/runtime/DeferredDataScripts.node.js +13 -10
- package/dist/cjs/router/runtime/PrefetchLink.js +4 -4
- package/dist/cjs/router/runtime/hooks.js +6 -7
- package/dist/cjs/router/runtime/plugin.js +22 -27
- package/dist/cjs/router/runtime/plugin.node.js +8 -9
- package/dist/esm/cli/code.mjs +2 -2
- package/dist/esm/cli/index.mjs +0 -7
- package/dist/esm/cli/ssr/loadable-bundler-plugin.mjs +2 -0
- package/dist/esm/cli/template.server.mjs +1 -2
- package/dist/esm/core/browser/hydrate.mjs +3 -9
- package/dist/esm/core/browser/index.mjs +1 -2
- package/dist/esm/core/context/index.mjs +1 -1
- package/dist/esm/core/context/public.mjs +1 -1
- package/dist/esm/core/context/runtime.mjs +3 -9
- package/dist/esm/core/index.mjs +1 -1
- package/dist/esm/core/plugin/index.mjs +1 -1
- package/dist/esm/core/react/index.mjs +1 -1
- package/dist/esm/core/react/wrapper.mjs +1 -2
- package/dist/esm/core/server/requestHandler.mjs +223 -19
- package/dist/esm/core/server/stream/beforeTemplate.mjs +3 -3
- package/dist/esm/core/server/stream/beforeTemplate.worker.mjs +2 -2
- package/dist/esm/core/server/stream/createReadableStream.mjs +48 -16
- package/dist/esm/core/server/stream/createReadableStream.worker.mjs +53 -26
- package/dist/esm/core/server/stream/deferredScript.mjs +12 -6
- package/dist/esm/core/server/stream/deferredScriptOutputCoordinator.mjs +332 -0
- package/dist/esm/core/server/stream/shared.mjs +2 -1
- package/dist/esm/core/server/string/index.mjs +3 -1
- package/dist/esm/core/server/string/loadable.mjs +4 -4
- package/dist/esm/document/cli/index.mjs +12 -6
- package/dist/esm/exports/head.mjs +1 -1
- package/dist/esm/internal.mjs +1 -1
- package/dist/esm/router/cli/code/nestedRoutes.mjs +1 -2
- package/dist/esm/router/cli/code/templates.mjs +2 -2
- package/dist/esm/router/cli/code/utils.mjs +6 -5
- package/dist/esm/router/runtime/DeferredDataScripts.node.mjs +13 -10
- package/dist/esm/router/runtime/PrefetchLink.mjs +1 -1
- package/dist/esm/router/runtime/hooks.mjs +6 -7
- package/dist/esm/router/runtime/plugin.mjs +14 -19
- package/dist/esm/router/runtime/plugin.node.mjs +3 -4
- package/dist/esm-node/cli/code.mjs +2 -2
- package/dist/esm-node/cli/index.mjs +1 -9
- package/dist/esm-node/cli/ssr/loadable-bundler-plugin.mjs +2 -0
- package/dist/esm-node/cli/template.server.mjs +1 -2
- package/dist/esm-node/core/browser/hydrate.mjs +3 -9
- package/dist/esm-node/core/browser/index.mjs +1 -2
- package/dist/esm-node/core/context/index.mjs +1 -1
- package/dist/esm-node/core/context/public.mjs +1 -1
- package/dist/esm-node/core/context/runtime.mjs +3 -9
- package/dist/esm-node/core/index.mjs +1 -1
- package/dist/esm-node/core/plugin/index.mjs +1 -1
- package/dist/esm-node/core/react/index.mjs +1 -1
- package/dist/esm-node/core/react/wrapper.mjs +1 -2
- package/dist/esm-node/core/server/requestHandler.mjs +223 -19
- package/dist/esm-node/core/server/stream/beforeTemplate.mjs +3 -3
- package/dist/esm-node/core/server/stream/beforeTemplate.worker.mjs +2 -2
- package/dist/esm-node/core/server/stream/createReadableStream.mjs +48 -16
- package/dist/esm-node/core/server/stream/createReadableStream.worker.mjs +53 -26
- package/dist/esm-node/core/server/stream/deferredScript.mjs +12 -6
- package/dist/esm-node/core/server/stream/deferredScriptOutputCoordinator.mjs +333 -0
- package/dist/esm-node/core/server/stream/shared.mjs +2 -1
- package/dist/esm-node/core/server/string/index.mjs +3 -1
- package/dist/esm-node/core/server/string/loadable.mjs +4 -4
- package/dist/esm-node/document/cli/index.mjs +12 -6
- package/dist/esm-node/exports/head.mjs +1 -1
- package/dist/esm-node/internal.mjs +1 -1
- package/dist/esm-node/router/cli/code/nestedRoutes.mjs +1 -2
- package/dist/esm-node/router/cli/code/templates.mjs +2 -2
- package/dist/esm-node/router/cli/code/utils.mjs +6 -5
- package/dist/esm-node/router/runtime/DeferredDataScripts.node.mjs +13 -10
- package/dist/esm-node/router/runtime/PrefetchLink.mjs +1 -1
- package/dist/esm-node/router/runtime/hooks.mjs +6 -7
- package/dist/esm-node/router/runtime/plugin.mjs +14 -19
- package/dist/esm-node/router/runtime/plugin.node.mjs +3 -4
- package/dist/types/common.d.ts +2 -8
- package/dist/types/core/context/index.d.ts +1 -1
- package/dist/types/core/context/public.d.ts +1 -1
- package/dist/types/core/index.d.ts +1 -1
- package/dist/types/core/react/wrapper.d.ts +1 -1
- package/dist/types/core/server/requestHandler.d.ts +30 -1
- package/dist/types/core/server/stream/deferredScript.d.ts +1 -1
- package/dist/types/core/server/stream/deferredScriptOutputCoordinator.d.ts +72 -0
- package/dist/types/core/server/stream/shared.d.ts +14 -0
- package/dist/types/document/cli/index.d.ts +1 -0
- package/dist/types/internal.d.ts +1 -1
- package/dist/types/router/cli/code/utils.d.ts +1 -1
- package/dist/types/router/runtime/hooks.d.ts +12 -16
- package/package.json +32 -26
- package/rslib.config.mts +3 -0
- package/rstest.config.mts +0 -4
- package/dist/cjs/core/server/requestResponse.js +0 -107
- package/dist/cjs/core/server/routerCleanup.js +0 -129
- package/dist/cjs/rsc/server.worker.js +0 -62
- package/dist/esm/core/server/requestResponse.mjs +0 -63
- package/dist/esm/core/server/routerCleanup.mjs +0 -82
- package/dist/esm/rsc/server.worker.mjs +0 -1
- package/dist/esm-node/core/server/requestResponse.mjs +0 -64
- package/dist/esm-node/core/server/routerCleanup.mjs +0 -83
- package/dist/esm-node/rsc/server.worker.mjs +0 -2
- package/dist/types/core/server/requestResponse.d.ts +0 -15
- package/dist/types/core/server/routerCleanup.d.ts +0 -31
- package/dist/types/rsc/server.worker.d.ts +0 -1
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import { renderSSRStream } from "@modern-js/render/ssr";
|
|
2
|
+
import { getGlobalEnableRsc, getGlobalInternalRuntimeContext } from "@modern-js/runtime/context";
|
|
2
3
|
import { storage } from "@modern-js/runtime-utils/node";
|
|
3
4
|
import react from "react";
|
|
4
5
|
import { ESCAPED_SHELL_STREAM_END_MARK } from "../../../common.mjs";
|
|
5
6
|
import { RenderLevel } from "../../constants.mjs";
|
|
6
|
-
import {
|
|
7
|
+
import { getMonitors } from "../../context/monitors/index.mjs";
|
|
7
8
|
import { wrapRuntimeComponentResolver } from "../../react/wrapper.mjs";
|
|
8
9
|
import { createReplaceHelemt, getHelmetData } from "../helmet.mjs";
|
|
9
10
|
import { createSSRRenderLifecycle, createSSRStreamErrorReporter, observeSSRStream, orderSSRStreamTransforms } from "../shared.mjs";
|
|
10
11
|
import { enqueueFromEntries } from "./deferredScript.mjs";
|
|
11
|
-
import {
|
|
12
|
+
import { DeferredScriptOutputCoordinator } from "./deferredScriptOutputCoordinator.mjs";
|
|
13
|
+
import { SHELL_PROGRESSIVE_CHUNK_SIZE, ShellChunkStatus, getReadableStreamFromString, resolveStreamingMode } from "./shared.mjs";
|
|
12
14
|
import { getTemplates } from "./template.mjs";
|
|
13
15
|
const createReadableStreamFromElement = async (request, rootElement, options)=>{
|
|
14
16
|
const { htmlTemplate, runtimeContext, config, ssrConfig, entryName, resource, rscManifest, rscRoot } = options;
|
|
@@ -21,6 +23,7 @@ const createReadableStreamFromElement = async (request, rootElement, options)=>{
|
|
|
21
23
|
config,
|
|
22
24
|
platform: 'web',
|
|
23
25
|
mode: 'stream',
|
|
26
|
+
monitors: getMonitors(),
|
|
24
27
|
isRsc,
|
|
25
28
|
terminalMarker: ESCAPED_SHELL_STREAM_END_MARK
|
|
26
29
|
}) || [];
|
|
@@ -33,6 +36,7 @@ const createReadableStreamFromElement = async (request, rootElement, options)=>{
|
|
|
33
36
|
let pendingSource;
|
|
34
37
|
let bodyOpen = true;
|
|
35
38
|
let bodyPipe;
|
|
39
|
+
let coordinator;
|
|
36
40
|
const templateOptions = {
|
|
37
41
|
runtimeContext,
|
|
38
42
|
ssrConfig,
|
|
@@ -51,6 +55,7 @@ const createReadableStreamFromElement = async (request, rootElement, options)=>{
|
|
|
51
55
|
request,
|
|
52
56
|
signal: request.signal,
|
|
53
57
|
nonce: config.nonce,
|
|
58
|
+
progressiveChunkSize: SHELL_PROGRESSIVE_CHUNK_SIZE,
|
|
54
59
|
rscManifest,
|
|
55
60
|
rscRoot: rscRoot,
|
|
56
61
|
routes: runtimeContext.routes,
|
|
@@ -79,66 +84,87 @@ const createReadableStreamFromElement = async (request, rootElement, options)=>{
|
|
|
79
84
|
const decoder = new TextDecoder();
|
|
80
85
|
const encoder = new TextEncoder();
|
|
81
86
|
const pendingScripts = [];
|
|
82
|
-
|
|
87
|
+
const buffered = [];
|
|
88
|
+
let bufferedLength = 0;
|
|
89
|
+
let markerTail = '';
|
|
83
90
|
let shellChunkStatus = ShellChunkStatus.START;
|
|
84
91
|
let bodyController;
|
|
85
|
-
|
|
92
|
+
let deferredResolversComplete = Promise.resolve();
|
|
93
|
+
coordinator = new DeferredScriptOutputCoordinator((content)=>{
|
|
94
|
+
if (!bodyOpen) return;
|
|
95
|
+
try {
|
|
96
|
+
bodyController.enqueue(encoder.encode(content));
|
|
97
|
+
} catch {
|
|
98
|
+
bodyOpen = false;
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
const emit = (chunk)=>{
|
|
86
102
|
if (shellChunkStatus === ShellChunkStatus.FINISH) {
|
|
87
|
-
if (chunk.length > 0)
|
|
103
|
+
if (chunk.length > 0) coordinator?.writeReact(chunk);
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
const window = markerTail + chunk;
|
|
107
|
+
const windowIndex = window.indexOf(ESCAPED_SHELL_STREAM_END_MARK);
|
|
108
|
+
const markerIndex = bufferedLength - markerTail.length + windowIndex;
|
|
109
|
+
buffered.push(chunk);
|
|
110
|
+
bufferedLength += chunk.length;
|
|
111
|
+
if (-1 === windowIndex) {
|
|
112
|
+
markerTail = window.slice(Math.max(0, window.length - ESCAPED_SHELL_STREAM_END_MARK.length + 1));
|
|
88
113
|
return;
|
|
89
114
|
}
|
|
90
|
-
|
|
91
|
-
const
|
|
92
|
-
|
|
93
|
-
const beforeMark = lifecycle.completedBody(buffered.slice(0, markerIndex), 'shell');
|
|
94
|
-
const afterMark = buffered.slice(markerIndex + ESCAPED_SHELL_STREAM_END_MARK.length);
|
|
115
|
+
const shell = buffered.join('');
|
|
116
|
+
const beforeMark = lifecycle.completedBody(shell.slice(0, markerIndex), 'shell');
|
|
117
|
+
const afterMark = shell.slice(markerIndex + ESCAPED_SHELL_STREAM_END_MARK.length);
|
|
95
118
|
const completedShellBefore = createReplaceHelemt(getHelmetData(extenders))(shellBefore);
|
|
96
119
|
shellChunkStatus = ShellChunkStatus.FINISH;
|
|
97
|
-
buffered =
|
|
98
|
-
|
|
99
|
-
if (afterMark.length > 0)
|
|
100
|
-
|
|
120
|
+
buffered.length = 0;
|
|
121
|
+
coordinator?.writeReact(`${completedShellBefore}${beforeMark}${shellAfter}`);
|
|
122
|
+
if (afterMark.length > 0) coordinator?.writeReact(afterMark);
|
|
123
|
+
coordinator?.markShellFinished();
|
|
124
|
+
for (const script of pendingScripts)coordinator?.enqueueResolver(script);
|
|
101
125
|
pendingScripts.length = 0;
|
|
102
126
|
};
|
|
103
127
|
const body = new TransformStream({
|
|
104
128
|
start (controller) {
|
|
105
129
|
bodyController = controller;
|
|
106
130
|
},
|
|
107
|
-
transform (chunk
|
|
131
|
+
transform (chunk) {
|
|
108
132
|
emit(decoder.decode(chunk, {
|
|
109
133
|
stream: true
|
|
110
|
-
})
|
|
134
|
+
}));
|
|
111
135
|
},
|
|
112
|
-
flush (
|
|
113
|
-
|
|
114
|
-
emit(decoder.decode(), controller);
|
|
136
|
+
async flush () {
|
|
137
|
+
emit(decoder.decode());
|
|
115
138
|
if (shellChunkStatus !== ShellChunkStatus.FINISH) throw new Error('React SSR stream ended before the shell marker');
|
|
139
|
+
await deferredResolversComplete;
|
|
140
|
+
coordinator?.finish();
|
|
141
|
+
bodyOpen = false;
|
|
116
142
|
}
|
|
117
143
|
});
|
|
118
144
|
bodyPipe = pendingSource.pipeTo(body.writable);
|
|
119
145
|
bodyPipe.catch(()=>{});
|
|
120
146
|
pendingSource = body.readable;
|
|
121
|
-
const
|
|
147
|
+
const storageContext = storage.useContext?.();
|
|
148
|
+
const activeDeferreds = storageContext?.activeDeferreds;
|
|
149
|
+
const deferredScriptKeys = storageContext?.deferredScriptKeys;
|
|
122
150
|
const entries = activeDeferreds instanceof Map ? Array.from(activeDeferreds.entries()) : [];
|
|
123
|
-
enqueueFromEntries(entries, config.nonce, (script)=>{
|
|
151
|
+
if (entries.length > 0) deferredResolversComplete = enqueueFromEntries(entries, deferredScriptKeys, config.nonce, (script)=>{
|
|
124
152
|
if (!bodyOpen) return;
|
|
125
|
-
if (shellChunkStatus === ShellChunkStatus.FINISH)
|
|
126
|
-
bodyController.enqueue(encoder.encode(script));
|
|
127
|
-
} catch {
|
|
128
|
-
bodyOpen = false;
|
|
129
|
-
}
|
|
153
|
+
if (shellChunkStatus === ShellChunkStatus.FINISH) coordinator?.enqueueResolver(script);
|
|
130
154
|
else pendingScripts.push(script);
|
|
131
155
|
});
|
|
132
156
|
return observeSSRStream(pendingSource, {
|
|
133
157
|
lifecycle,
|
|
134
158
|
async onError (error) {
|
|
135
159
|
bodyOpen = false;
|
|
160
|
+
coordinator?.abort();
|
|
136
161
|
await bodyPipe?.catch(()=>{});
|
|
137
162
|
reportError(error);
|
|
138
163
|
},
|
|
139
164
|
signal: request.signal,
|
|
140
165
|
async onCancel (reason) {
|
|
141
166
|
bodyOpen = false;
|
|
167
|
+
coordinator?.abort();
|
|
142
168
|
await bodyPipe?.catch((error)=>{
|
|
143
169
|
if (error !== reason) throw error;
|
|
144
170
|
});
|
|
@@ -147,6 +173,7 @@ const createReadableStreamFromElement = async (request, rootElement, options)=>{
|
|
|
147
173
|
});
|
|
148
174
|
} catch (error) {
|
|
149
175
|
bodyOpen = false;
|
|
176
|
+
coordinator?.abort();
|
|
150
177
|
if (void 0 !== pendingSource) try {
|
|
151
178
|
await pendingSource.cancel(error);
|
|
152
179
|
await bodyPipe?.catch(()=>{});
|
|
@@ -44,23 +44,29 @@ function buildDeferredDataScript(nonce, args) {
|
|
|
44
44
|
const nonceAttr = void 0 !== nonce && '' !== nonce ? ` nonce="${nonce}"` : '';
|
|
45
45
|
return `<script async${nonceAttr} data-fn-name="r" data-script-src="modern-run-router-data-fn" data-fn-args='${escaped}' suppressHydrationWarning>${runRouterDataFnStr}</script>`;
|
|
46
46
|
}
|
|
47
|
-
function enqueueFromEntries(entries, nonce, emit) {
|
|
47
|
+
function enqueueFromEntries(entries, deferredScriptKeys, nonce, emit) {
|
|
48
|
+
const pendingResolvers = [];
|
|
48
49
|
entries.forEach(([routeId, value])=>{
|
|
49
50
|
if (!isDeferredDataLike(value)) return;
|
|
50
|
-
const
|
|
51
|
-
|
|
51
|
+
const serializedKeys = void 0 !== deferredScriptKeys ? deferredScriptKeys.get(routeId) ?? [] : value.pendingKeys ?? [];
|
|
52
|
+
serializedKeys.forEach((key)=>{
|
|
52
53
|
const tracked = value.data?.[key];
|
|
53
|
-
if (isPromiseLike(tracked)) tracked.then((val)=>
|
|
54
|
+
if (isPromiseLike(tracked)) pendingResolvers.push(Promise.resolve(tracked).then((val)=>{
|
|
55
|
+
emit(buildDeferredDataScript(nonce, [
|
|
54
56
|
routeId,
|
|
55
57
|
key,
|
|
56
58
|
val
|
|
57
|
-
]))
|
|
59
|
+
]));
|
|
60
|
+
}, (err)=>{
|
|
61
|
+
emit(buildDeferredDataScript(nonce, [
|
|
58
62
|
routeId,
|
|
59
63
|
key,
|
|
60
64
|
void 0,
|
|
61
65
|
toErrorInfo(err)
|
|
62
|
-
]))
|
|
66
|
+
]));
|
|
67
|
+
}));
|
|
63
68
|
});
|
|
64
69
|
});
|
|
70
|
+
return Promise.all(pendingResolvers).then(()=>void 0);
|
|
65
71
|
}
|
|
66
72
|
export { buildDeferredDataScript, enqueueFromEntries, escapeAttr, isDeferredDataLike, isPromiseLike, isRecord, toErrorInfo };
|
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
import { SSR_HYDRATION_ID_PREFIX } from "@modern-js/utils/universal/constants";
|
|
2
|
+
const VOID_ELEMENTS = new Set([
|
|
3
|
+
'area',
|
|
4
|
+
'base',
|
|
5
|
+
'br',
|
|
6
|
+
'col',
|
|
7
|
+
'embed',
|
|
8
|
+
'hr',
|
|
9
|
+
'img',
|
|
10
|
+
'input',
|
|
11
|
+
'link',
|
|
12
|
+
'meta',
|
|
13
|
+
'param',
|
|
14
|
+
'source',
|
|
15
|
+
'track',
|
|
16
|
+
'wbr'
|
|
17
|
+
]);
|
|
18
|
+
const RAW_TEXT_ELEMENTS = new Set([
|
|
19
|
+
'iframe',
|
|
20
|
+
'noembed',
|
|
21
|
+
'noframes',
|
|
22
|
+
"script",
|
|
23
|
+
'style',
|
|
24
|
+
'textarea',
|
|
25
|
+
'title',
|
|
26
|
+
'xmp'
|
|
27
|
+
]);
|
|
28
|
+
const REACT_SEGMENT_ID_PATTERN = new RegExp(`^${SSR_HYDRATION_ID_PREFIX}S:[0-9a-f]+$`);
|
|
29
|
+
const TABLE_SEGMENT_CHILDREN = new Set([
|
|
30
|
+
'tbody',
|
|
31
|
+
'tr',
|
|
32
|
+
'colgroup'
|
|
33
|
+
]);
|
|
34
|
+
function isAsciiAlpha(char) {
|
|
35
|
+
return /[A-Za-z]/.test(char);
|
|
36
|
+
}
|
|
37
|
+
function isWhitespace(char) {
|
|
38
|
+
return /[\t\n\f\r ]/.test(char);
|
|
39
|
+
}
|
|
40
|
+
function getSuffix(value, pattern) {
|
|
41
|
+
const start = Math.max(0, value.length - pattern.length);
|
|
42
|
+
for(let index = start; index < value.length; index++){
|
|
43
|
+
const suffix = value.slice(index);
|
|
44
|
+
if (pattern.startsWith(suffix)) return suffix;
|
|
45
|
+
}
|
|
46
|
+
return '';
|
|
47
|
+
}
|
|
48
|
+
class DeferredScriptOutputCoordinator {
|
|
49
|
+
enqueueResolver(script) {
|
|
50
|
+
if (this.closed) return;
|
|
51
|
+
this.pendingResolvers.push(script);
|
|
52
|
+
this.flushResolvers();
|
|
53
|
+
}
|
|
54
|
+
markShellFinished() {
|
|
55
|
+
if (this.closed) return;
|
|
56
|
+
this.shellFinished = true;
|
|
57
|
+
this.flushResolvers();
|
|
58
|
+
}
|
|
59
|
+
writeReact(chunk) {
|
|
60
|
+
if (this.closed || '' === chunk) return;
|
|
61
|
+
this.flushResolvers();
|
|
62
|
+
let emittedUntil = 0;
|
|
63
|
+
for(let index = 0; index < chunk.length; index++){
|
|
64
|
+
const wasSafe = this.isSafeBoundary();
|
|
65
|
+
this.consume(chunk[index]);
|
|
66
|
+
if (!wasSafe && this.isSafeBoundary() && this.pendingResolvers.length > 0) {
|
|
67
|
+
this.emit(chunk.slice(emittedUntil, index + 1));
|
|
68
|
+
emittedUntil = index + 1;
|
|
69
|
+
this.flushResolvers();
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if (emittedUntil < chunk.length) this.emit(chunk.slice(emittedUntil));
|
|
73
|
+
}
|
|
74
|
+
finish() {
|
|
75
|
+
if (this.closed) return;
|
|
76
|
+
this.flushResolvers();
|
|
77
|
+
this.closed = true;
|
|
78
|
+
if (this.pendingResolvers.length > 0) throw new Error("Cannot emit deferred resolver scripts because the React stream ended outside a safe HTML boundary.");
|
|
79
|
+
}
|
|
80
|
+
abort() {
|
|
81
|
+
this.closed = true;
|
|
82
|
+
this.pendingResolvers.length = 0;
|
|
83
|
+
}
|
|
84
|
+
isSafeBoundary() {
|
|
85
|
+
return this.shellFinished && 'data' === this.state && 0 === this.openElements.length && !this.awaitingContinuationProtocol;
|
|
86
|
+
}
|
|
87
|
+
flushResolvers() {
|
|
88
|
+
if (!this.isSafeBoundary() || 0 === this.pendingResolvers.length) return;
|
|
89
|
+
while(this.pendingResolvers.length > 0){
|
|
90
|
+
const resolver = this.pendingResolvers.shift();
|
|
91
|
+
if (void 0 !== resolver) this.emit(resolver);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
consume(char) {
|
|
95
|
+
switch(this.state){
|
|
96
|
+
case 'data':
|
|
97
|
+
if ('<' === char) this.state = 'tag-open';
|
|
98
|
+
return;
|
|
99
|
+
case 'tag-open':
|
|
100
|
+
if ('/' === char) {
|
|
101
|
+
this.currentTagName = '';
|
|
102
|
+
this.state = 'end-tag-name';
|
|
103
|
+
} else if ('!' === char) {
|
|
104
|
+
this.declarationPrefix = '';
|
|
105
|
+
this.state = 'markup-declaration';
|
|
106
|
+
} else if ('?' === char) this.state = 'bogus-comment';
|
|
107
|
+
else if (isAsciiAlpha(char)) {
|
|
108
|
+
this.startTag(char);
|
|
109
|
+
this.state = 'start-tag-name';
|
|
110
|
+
} else this.state = 'data';
|
|
111
|
+
return;
|
|
112
|
+
case 'start-tag-name':
|
|
113
|
+
if (isWhitespace(char)) this.state = 'before-attribute-name';
|
|
114
|
+
else if ('/' === char) this.state = 'self-closing-start-tag';
|
|
115
|
+
else if ('>' === char) this.completeStartTag(false);
|
|
116
|
+
else this.currentTagName += char.toLowerCase();
|
|
117
|
+
return;
|
|
118
|
+
case 'before-attribute-name':
|
|
119
|
+
if (isWhitespace(char)) return;
|
|
120
|
+
if ('/' === char) this.state = 'self-closing-start-tag';
|
|
121
|
+
else if ('>' === char) this.completeStartTag(false);
|
|
122
|
+
else {
|
|
123
|
+
this.startAttribute(char);
|
|
124
|
+
this.state = 'attribute-name';
|
|
125
|
+
}
|
|
126
|
+
return;
|
|
127
|
+
case 'attribute-name':
|
|
128
|
+
if (isWhitespace(char)) this.state = 'after-attribute-name';
|
|
129
|
+
else if ('=' === char) {
|
|
130
|
+
this.currentAttributeHasValue = true;
|
|
131
|
+
this.state = 'before-attribute-value';
|
|
132
|
+
} else if ('/' === char) {
|
|
133
|
+
this.completeAttribute();
|
|
134
|
+
this.state = 'self-closing-start-tag';
|
|
135
|
+
} else if ('>' === char) this.completeStartTag(false);
|
|
136
|
+
else this.currentAttributeName += char.toLowerCase();
|
|
137
|
+
return;
|
|
138
|
+
case 'after-attribute-name':
|
|
139
|
+
if (isWhitespace(char)) return;
|
|
140
|
+
if ('=' === char) {
|
|
141
|
+
this.currentAttributeHasValue = true;
|
|
142
|
+
this.state = 'before-attribute-value';
|
|
143
|
+
} else if ('/' === char) {
|
|
144
|
+
this.completeAttribute();
|
|
145
|
+
this.state = 'self-closing-start-tag';
|
|
146
|
+
} else if ('>' === char) this.completeStartTag(false);
|
|
147
|
+
else {
|
|
148
|
+
this.completeAttribute();
|
|
149
|
+
this.startAttribute(char);
|
|
150
|
+
this.state = 'attribute-name';
|
|
151
|
+
}
|
|
152
|
+
return;
|
|
153
|
+
case 'before-attribute-value':
|
|
154
|
+
if (isWhitespace(char)) return;
|
|
155
|
+
if ('"' === char) this.state = 'attribute-value-double-quoted';
|
|
156
|
+
else if ("'" === char) this.state = 'attribute-value-single-quoted';
|
|
157
|
+
else if ('>' === char) this.completeStartTag(false);
|
|
158
|
+
else {
|
|
159
|
+
this.currentAttributeValue += char;
|
|
160
|
+
this.state = 'attribute-value-unquoted';
|
|
161
|
+
}
|
|
162
|
+
return;
|
|
163
|
+
case 'attribute-value-double-quoted':
|
|
164
|
+
if ('"' === char) {
|
|
165
|
+
this.completeAttribute();
|
|
166
|
+
this.state = 'before-attribute-name';
|
|
167
|
+
} else this.currentAttributeValue += char;
|
|
168
|
+
return;
|
|
169
|
+
case 'attribute-value-single-quoted':
|
|
170
|
+
if ("'" === char) {
|
|
171
|
+
this.completeAttribute();
|
|
172
|
+
this.state = 'before-attribute-name';
|
|
173
|
+
} else this.currentAttributeValue += char;
|
|
174
|
+
return;
|
|
175
|
+
case 'attribute-value-unquoted':
|
|
176
|
+
if (isWhitespace(char)) {
|
|
177
|
+
this.completeAttribute();
|
|
178
|
+
this.state = 'before-attribute-name';
|
|
179
|
+
} else if ('>' === char) this.completeStartTag(false);
|
|
180
|
+
else this.currentAttributeValue += char;
|
|
181
|
+
return;
|
|
182
|
+
case 'self-closing-start-tag':
|
|
183
|
+
if ('>' === char) this.completeStartTag(true);
|
|
184
|
+
else if (!isWhitespace(char)) {
|
|
185
|
+
this.startAttribute(char);
|
|
186
|
+
this.state = 'attribute-name';
|
|
187
|
+
}
|
|
188
|
+
return;
|
|
189
|
+
case 'end-tag-name':
|
|
190
|
+
if (isWhitespace(char)) this.state = 'after-end-tag-name';
|
|
191
|
+
else if ('>' === char) this.completeEndTag();
|
|
192
|
+
else this.currentTagName += char.toLowerCase();
|
|
193
|
+
return;
|
|
194
|
+
case 'after-end-tag-name':
|
|
195
|
+
if ('>' === char) this.completeEndTag();
|
|
196
|
+
return;
|
|
197
|
+
case 'markup-declaration':
|
|
198
|
+
if (this.declarationPrefix.length < 2 && '-' === char) {
|
|
199
|
+
this.declarationPrefix += char;
|
|
200
|
+
if ('--' === this.declarationPrefix) {
|
|
201
|
+
this.commentTail = '';
|
|
202
|
+
this.state = 'comment';
|
|
203
|
+
}
|
|
204
|
+
} else this.state = '>' === char ? 'data' : 'declaration';
|
|
205
|
+
return;
|
|
206
|
+
case 'declaration':
|
|
207
|
+
if ('>' === char) this.state = 'data';
|
|
208
|
+
return;
|
|
209
|
+
case 'comment':
|
|
210
|
+
this.commentTail = `${this.commentTail}${char}`.slice(-3);
|
|
211
|
+
if ('-->' === this.commentTail) this.state = 'data';
|
|
212
|
+
return;
|
|
213
|
+
case 'bogus-comment':
|
|
214
|
+
if ('>' === char) this.state = 'data';
|
|
215
|
+
return;
|
|
216
|
+
case 'raw-text':
|
|
217
|
+
this.consumeRawText(char);
|
|
218
|
+
return;
|
|
219
|
+
case 'raw-end-tag':
|
|
220
|
+
if ('>' === char) this.completeRawTextEndTag();
|
|
221
|
+
else if (!isWhitespace(char)) {
|
|
222
|
+
this.state = 'raw-text';
|
|
223
|
+
this.rawTextSearch = getSuffix(`${this.rawTextSearch}${char.toLowerCase()}`, `</${this.rawTextElement}`);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
startTag(char) {
|
|
228
|
+
this.currentTagName = char.toLowerCase();
|
|
229
|
+
this.currentAttributes = new Map();
|
|
230
|
+
this.currentAttributeName = '';
|
|
231
|
+
this.currentAttributeValue = '';
|
|
232
|
+
this.currentAttributeHasValue = false;
|
|
233
|
+
}
|
|
234
|
+
startAttribute(char) {
|
|
235
|
+
this.currentAttributeName = char.toLowerCase();
|
|
236
|
+
this.currentAttributeValue = '';
|
|
237
|
+
this.currentAttributeHasValue = false;
|
|
238
|
+
}
|
|
239
|
+
completeAttribute() {
|
|
240
|
+
if ('' === this.currentAttributeName) return;
|
|
241
|
+
this.currentAttributes.set(this.currentAttributeName, this.currentAttributeHasValue ? this.currentAttributeValue : true);
|
|
242
|
+
this.currentAttributeName = '';
|
|
243
|
+
this.currentAttributeValue = '';
|
|
244
|
+
this.currentAttributeHasValue = false;
|
|
245
|
+
}
|
|
246
|
+
completeStartTag(selfClosing) {
|
|
247
|
+
this.completeAttribute();
|
|
248
|
+
const tagName = this.currentTagName;
|
|
249
|
+
const id = this.currentAttributes.get('id');
|
|
250
|
+
const hasReactSegmentId = 'string' == typeof id && REACT_SEGMENT_ID_PATTERN.test(id);
|
|
251
|
+
const hasHiddenAttribute = this.currentAttributes.has('hidden');
|
|
252
|
+
const isHiddenSegmentTable = 'table' === tagName && hasHiddenAttribute && !hasReactSegmentId;
|
|
253
|
+
const isTableSegmentChild = hasReactSegmentId && TABLE_SEGMENT_CHILDREN.has(tagName) && this.openElements[this.openElements.length - 1]?.isSegmentTableWrapper === true;
|
|
254
|
+
const isContinuationContainer = hasReactSegmentId && ('div' === tagName && hasHiddenAttribute || ('svg' === tagName || 'math' === tagName) && void 0 !== id && 'true' === this.currentAttributes.get('aria-hidden') && 'display:none' === this.currentAttributes.get('style') || 'table' === tagName && hasHiddenAttribute || isTableSegmentChild);
|
|
255
|
+
this.continuationProtocolScript = "script" === tagName && this.awaitingContinuationProtocol;
|
|
256
|
+
this.continuationProtocolTail = '';
|
|
257
|
+
this.hasContinuationProtocolCall = false;
|
|
258
|
+
if (!selfClosing && !VOID_ELEMENTS.has(tagName)) this.openElements.push({
|
|
259
|
+
tagName,
|
|
260
|
+
isContinuationContainer,
|
|
261
|
+
isSegmentTableWrapper: isHiddenSegmentTable
|
|
262
|
+
});
|
|
263
|
+
this.currentTagName = '';
|
|
264
|
+
this.currentAttributes = new Map();
|
|
265
|
+
this.currentAttributeName = '';
|
|
266
|
+
this.currentAttributeValue = '';
|
|
267
|
+
this.currentAttributeHasValue = false;
|
|
268
|
+
if (!selfClosing && RAW_TEXT_ELEMENTS.has(tagName)) {
|
|
269
|
+
this.rawTextElement = tagName;
|
|
270
|
+
this.rawTextSearch = '';
|
|
271
|
+
this.state = 'raw-text';
|
|
272
|
+
} else this.state = 'data';
|
|
273
|
+
}
|
|
274
|
+
completeEndTag() {
|
|
275
|
+
this.closeOpenElement(this.currentTagName);
|
|
276
|
+
this.currentTagName = '';
|
|
277
|
+
this.state = 'data';
|
|
278
|
+
}
|
|
279
|
+
consumeRawText(char) {
|
|
280
|
+
const rawTextElement = this.rawTextElement;
|
|
281
|
+
if (void 0 === rawTextElement) {
|
|
282
|
+
this.state = 'data';
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
const endTagPrefix = `</${rawTextElement}`;
|
|
286
|
+
if (this.continuationProtocolScript) {
|
|
287
|
+
this.continuationProtocolTail = `${this.continuationProtocolTail}${char}`.slice(-4);
|
|
288
|
+
if (/\$(?:RC|RS|RX|RB|RR)\b/.test(this.continuationProtocolTail)) this.hasContinuationProtocolCall = true;
|
|
289
|
+
}
|
|
290
|
+
this.rawTextSearch = getSuffix(`${this.rawTextSearch}${char.toLowerCase()}`, endTagPrefix);
|
|
291
|
+
if (this.rawTextSearch === endTagPrefix) this.state = 'raw-end-tag';
|
|
292
|
+
}
|
|
293
|
+
completeRawTextEndTag() {
|
|
294
|
+
const rawTextElement = this.rawTextElement;
|
|
295
|
+
if (void 0 !== rawTextElement) this.closeOpenElement(rawTextElement);
|
|
296
|
+
if ("script" === rawTextElement && this.continuationProtocolScript && this.hasContinuationProtocolCall) this.awaitingContinuationProtocol = false;
|
|
297
|
+
this.rawTextElement = void 0;
|
|
298
|
+
this.rawTextSearch = '';
|
|
299
|
+
this.continuationProtocolScript = false;
|
|
300
|
+
this.continuationProtocolTail = '';
|
|
301
|
+
this.hasContinuationProtocolCall = false;
|
|
302
|
+
this.state = 'data';
|
|
303
|
+
}
|
|
304
|
+
closeOpenElement(tagName) {
|
|
305
|
+
const matchingIndex = this.openElements.map((element)=>element.tagName).lastIndexOf(tagName);
|
|
306
|
+
if (-1 === matchingIndex) return;
|
|
307
|
+
const closedElements = this.openElements.splice(matchingIndex);
|
|
308
|
+
const closedContinuation = closedElements.some((element)=>element.isContinuationContainer);
|
|
309
|
+
if (closedContinuation) this.awaitingContinuationProtocol = true;
|
|
310
|
+
}
|
|
311
|
+
constructor(emit){
|
|
312
|
+
this.emit = emit;
|
|
313
|
+
this.pendingResolvers = [];
|
|
314
|
+
this.openElements = [];
|
|
315
|
+
this.shellFinished = false;
|
|
316
|
+
this.closed = false;
|
|
317
|
+
this.state = 'data';
|
|
318
|
+
this.currentTagName = '';
|
|
319
|
+
this.currentAttributes = new Map();
|
|
320
|
+
this.currentAttributeName = '';
|
|
321
|
+
this.currentAttributeValue = '';
|
|
322
|
+
this.currentAttributeHasValue = false;
|
|
323
|
+
this.declarationPrefix = '';
|
|
324
|
+
this.commentTail = '';
|
|
325
|
+
this.rawTextSearch = '';
|
|
326
|
+
this.continuationProtocolScript = false;
|
|
327
|
+
this.continuationProtocolTail = '';
|
|
328
|
+
this.hasContinuationProtocolCall = false;
|
|
329
|
+
this.awaitingContinuationProtocol = false;
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
export { DeferredScriptOutputCoordinator };
|
|
@@ -10,6 +10,7 @@ var shared_ShellChunkStatus = /*#__PURE__*/ function(ShellChunkStatus) {
|
|
|
10
10
|
ShellChunkStatus[ShellChunkStatus["FINISH"] = 1] = "FINISH";
|
|
11
11
|
return ShellChunkStatus;
|
|
12
12
|
}({});
|
|
13
|
+
const SHELL_PROGRESSIVE_CHUNK_SIZE = Number.MAX_SAFE_INTEGER;
|
|
13
14
|
const SHOULD_STREAM_ALL_HEADER = 'x-should-stream-all';
|
|
14
15
|
function parseShouldStreamAllFlag(value) {
|
|
15
16
|
if (!value) return;
|
|
@@ -107,4 +108,4 @@ function createRenderStreaming(createReadableStreamPromise) {
|
|
|
107
108
|
return stream;
|
|
108
109
|
};
|
|
109
110
|
}
|
|
110
|
-
export { createRenderStreaming, encodeForWebStream, getReadableStreamFromString, resolveStreamingMode, shared_ShellChunkStatus as ShellChunkStatus };
|
|
111
|
+
export { SHELL_PROGRESSIVE_CHUNK_SIZE, createRenderStreaming, encodeForWebStream, getReadableStreamFromString, resolveStreamingMode, shared_ShellChunkStatus as ShellChunkStatus };
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import { getGlobalEnableRsc, getGlobalInternalRuntimeContext } from "@modern-js/runtime/context";
|
|
1
2
|
import { time } from "@modern-js/runtime-utils/time";
|
|
2
3
|
import { SSR_HYDRATION_ID_PREFIX } from "@modern-js/utils/universal/constants";
|
|
3
4
|
import server from "react-dom/server";
|
|
4
5
|
import { RenderLevel } from "../../constants.mjs";
|
|
5
|
-
import {
|
|
6
|
+
import { getMonitors } from "../../context/monitors/index.mjs";
|
|
6
7
|
import { wrapRuntimeComponentResolver, wrapRuntimeContextProvider } from "../../react/wrapper.mjs";
|
|
7
8
|
import { CHUNK_CSS_PLACEHOLDER, CHUNK_JS_PLACEHOLDER, HTML_PLACEHOLDER, SSR_DATA_PLACEHOLDER } from "../constants.mjs";
|
|
8
9
|
import { createReplaceHelemt, getHelmetData } from "../helmet.mjs";
|
|
@@ -60,6 +61,7 @@ const renderString = async (request, serverRoot, options)=>{
|
|
|
60
61
|
config,
|
|
61
62
|
platform: 'node',
|
|
62
63
|
mode: 'string',
|
|
64
|
+
monitors: getMonitors(),
|
|
63
65
|
isRsc: true === getGlobalEnableRsc()
|
|
64
66
|
}
|
|
65
67
|
});
|
|
@@ -16,8 +16,8 @@ const assetToChunk = (asset)=>({
|
|
|
16
16
|
});
|
|
17
17
|
const checkIsInline = (chunk, enableInline)=>{
|
|
18
18
|
if ('production' !== process.env.NODE_ENV) return false;
|
|
19
|
-
if (enableInline instanceof RegExp) return enableInline.test(chunk.url);
|
|
20
|
-
return Boolean(enableInline);
|
|
19
|
+
else if (enableInline instanceof RegExp) return enableInline.test(chunk.url);
|
|
20
|
+
else return Boolean(enableInline);
|
|
21
21
|
};
|
|
22
22
|
const readAsset = async (chunk)=>{
|
|
23
23
|
const fs = await import("fs/promises");
|
|
@@ -110,7 +110,7 @@ class LoadableCollector {
|
|
|
110
110
|
const scripts = await Promise.all(chunks.filter((chunk)=>!existedScript.includes(chunk.url) && !this.existsAssets?.includes(chunk.path)).map(async (chunk)=>{
|
|
111
111
|
const script = `<script${attributes} src="${chunk.url}"></script>`;
|
|
112
112
|
if (checkIsNode() && checkIsInline(chunk, inlineStyles)) return readAsset(chunk).then((content)=>`<script>${content}</script>`).catch((_)=>script);
|
|
113
|
-
return script;
|
|
113
|
+
else return script;
|
|
114
114
|
}));
|
|
115
115
|
chunkSet.jsChunk += scripts.filter((script)=>Boolean(script)).join('');
|
|
116
116
|
}
|
|
@@ -127,7 +127,7 @@ class LoadableCollector {
|
|
|
127
127
|
const css = await Promise.all(emittedChunks.map(async (chunk)=>{
|
|
128
128
|
const link = `<link${atrributes} href="${chunk.url}" rel="stylesheet" />`;
|
|
129
129
|
if (checkIsNode() && checkIsInline(chunk, inlineStyles)) return readAsset(chunk).then((content)=>`<style>${content}</style>`).catch((_)=>link);
|
|
130
|
-
return link;
|
|
130
|
+
else return link;
|
|
131
131
|
}));
|
|
132
132
|
chunkSet.cssChunk += css.filter((css)=>Boolean(css)).join('');
|
|
133
133
|
this.stylesheetInfo.emittedAssets = emittedChunks.map((chunk)=>chunk.url);
|
|
@@ -124,6 +124,7 @@ g.__MODERN_DOC_RENDERERS__[${JSON.stringify(_entryName)}] = render;
|
|
|
124
124
|
|
|
125
125
|
export default { render: render };`;
|
|
126
126
|
};
|
|
127
|
+
const getDocumentTempEntry = (internalDirectory, compilerName, entryName)=>path.join(internalDirectory, CONSTANTS.DOCUMENT_OUTPUT_DIR, compilerName ?? '', `${CONSTANTS.TEMP_ENTRY_PREFIX}${entryName}.js`);
|
|
127
128
|
const processChildCompilation = async (entryName, docPath, compilation, compiler, appDirectory, internalDirectory)=>new Promise((resolve, reject)=>{
|
|
128
129
|
const outFile = path.posix.join(CONSTANTS.DOCUMENT_OUTPUT_DIR, `${CONSTANTS.HTML_OUTPUT_PREFIX}${entryName}${CONSTANTS.HTML_OUTPUT_SUFFIX}`);
|
|
129
130
|
const child = compilation.createChildCompiler(`${CONSTANTS.CHILD_COMPILER_PREFIX}${entryName}`, {
|
|
@@ -134,8 +135,7 @@ const processChildCompilation = async (entryName, docPath, compilation, compiler
|
|
|
134
135
|
}, []);
|
|
135
136
|
configureChildCompiler(child, compiler, appDirectory);
|
|
136
137
|
applyExternalsPlugin(child, compiler);
|
|
137
|
-
const
|
|
138
|
-
const tempEntry = path.join(entryDir, `${CONSTANTS.TEMP_ENTRY_PREFIX}${entryName}.js`);
|
|
138
|
+
const tempEntry = getDocumentTempEntry(internalDirectory, compiler.name, entryName);
|
|
139
139
|
const finalize = ()=>{
|
|
140
140
|
try {
|
|
141
141
|
const EntryPlugin = compiler.rspack?.EntryPlugin;
|
|
@@ -202,6 +202,7 @@ const documentPlugin = ()=>({
|
|
|
202
202
|
const tasks = [];
|
|
203
203
|
for (const ep of entrypoints || []){
|
|
204
204
|
const entryName = ep.entryName;
|
|
205
|
+
if (!this.htmlEntryNames.has(entryName)) continue;
|
|
205
206
|
const docPath = getDocumentByEntryName(entrypoints, entryName, appDirectory);
|
|
206
207
|
if (docPath) {
|
|
207
208
|
compilation.fileDependencies?.add?.(docPath);
|
|
@@ -218,14 +219,19 @@ const documentPlugin = ()=>({
|
|
|
218
219
|
}
|
|
219
220
|
});
|
|
220
221
|
}
|
|
221
|
-
constructor(){
|
|
222
|
+
constructor(htmlEntryNames){
|
|
223
|
+
this.htmlEntryNames = htmlEntryNames;
|
|
222
224
|
this.name = 'ModernJsDocumentChildCompilerPlugin';
|
|
223
225
|
}
|
|
224
226
|
}
|
|
225
227
|
api.config(()=>({
|
|
226
228
|
tools: {
|
|
227
|
-
bundlerChain: (chain)=>{
|
|
228
|
-
|
|
229
|
+
bundlerChain: (chain, { environment })=>{
|
|
230
|
+
const htmlEntryNames = new Set(Object.keys(environment.htmlPaths));
|
|
231
|
+
if (0 === htmlEntryNames.size) return;
|
|
232
|
+
chain.plugin('modernjs-document-child-compiler').use(ModernJsDocumentChildCompilerPlugin, [
|
|
233
|
+
htmlEntryNames
|
|
234
|
+
]);
|
|
229
235
|
}
|
|
230
236
|
}
|
|
231
237
|
}));
|
|
@@ -346,4 +352,4 @@ const documentPlugin = ()=>({
|
|
|
346
352
|
});
|
|
347
353
|
const cli = documentPlugin;
|
|
348
354
|
export default cli;
|
|
349
|
-
export { documentPlugin, getDocumentByEntryName, processScriptPlaceholders };
|
|
355
|
+
export { documentPlugin, getDocumentByEntryName, getDocumentTempEntry, processScriptPlaceholders };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
|
+
import { RuntimeComponentResolverContext } from "@modern-js/runtime/context";
|
|
2
3
|
import react from "react";
|
|
3
4
|
import { Helmet, HelmetData, HelmetProvider } from "react-helmet-async";
|
|
4
|
-
import { RuntimeComponentResolverContext } from "../core/context/runtime.mjs";
|
|
5
5
|
const head_Helmet = (props)=>{
|
|
6
6
|
const resolveComponent = react.useContext(RuntimeComponentResolverContext);
|
|
7
7
|
const Component = resolveComponent?.(Helmet, {
|
package/dist/esm/internal.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { InternalRuntimeContext } from "
|
|
1
|
+
export { InternalRuntimeContext } from "@modern-js/runtime/context";
|