@bleedingdev/modern-js-runtime 3.9.0-ultramodern.9 → 3.9.3-ultramodern.1
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
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
import "node:module";
|
|
2
|
+
import { SSR_HYDRATION_ID_PREFIX } from "@modern-js/utils/universal/constants";
|
|
3
|
+
const VOID_ELEMENTS = new Set([
|
|
4
|
+
'area',
|
|
5
|
+
'base',
|
|
6
|
+
'br',
|
|
7
|
+
'col',
|
|
8
|
+
'embed',
|
|
9
|
+
'hr',
|
|
10
|
+
'img',
|
|
11
|
+
'input',
|
|
12
|
+
'link',
|
|
13
|
+
'meta',
|
|
14
|
+
'param',
|
|
15
|
+
'source',
|
|
16
|
+
'track',
|
|
17
|
+
'wbr'
|
|
18
|
+
]);
|
|
19
|
+
const RAW_TEXT_ELEMENTS = new Set([
|
|
20
|
+
'iframe',
|
|
21
|
+
'noembed',
|
|
22
|
+
'noframes',
|
|
23
|
+
"script",
|
|
24
|
+
'style',
|
|
25
|
+
'textarea',
|
|
26
|
+
'title',
|
|
27
|
+
'xmp'
|
|
28
|
+
]);
|
|
29
|
+
const REACT_SEGMENT_ID_PATTERN = new RegExp(`^${SSR_HYDRATION_ID_PREFIX}S:[0-9a-f]+$`);
|
|
30
|
+
const TABLE_SEGMENT_CHILDREN = new Set([
|
|
31
|
+
'tbody',
|
|
32
|
+
'tr',
|
|
33
|
+
'colgroup'
|
|
34
|
+
]);
|
|
35
|
+
function isAsciiAlpha(char) {
|
|
36
|
+
return /[A-Za-z]/.test(char);
|
|
37
|
+
}
|
|
38
|
+
function isWhitespace(char) {
|
|
39
|
+
return /[\t\n\f\r ]/.test(char);
|
|
40
|
+
}
|
|
41
|
+
function getSuffix(value, pattern) {
|
|
42
|
+
const start = Math.max(0, value.length - pattern.length);
|
|
43
|
+
for(let index = start; index < value.length; index++){
|
|
44
|
+
const suffix = value.slice(index);
|
|
45
|
+
if (pattern.startsWith(suffix)) return suffix;
|
|
46
|
+
}
|
|
47
|
+
return '';
|
|
48
|
+
}
|
|
49
|
+
class DeferredScriptOutputCoordinator {
|
|
50
|
+
enqueueResolver(script) {
|
|
51
|
+
if (this.closed) return;
|
|
52
|
+
this.pendingResolvers.push(script);
|
|
53
|
+
this.flushResolvers();
|
|
54
|
+
}
|
|
55
|
+
markShellFinished() {
|
|
56
|
+
if (this.closed) return;
|
|
57
|
+
this.shellFinished = true;
|
|
58
|
+
this.flushResolvers();
|
|
59
|
+
}
|
|
60
|
+
writeReact(chunk) {
|
|
61
|
+
if (this.closed || '' === chunk) return;
|
|
62
|
+
this.flushResolvers();
|
|
63
|
+
let emittedUntil = 0;
|
|
64
|
+
for(let index = 0; index < chunk.length; index++){
|
|
65
|
+
const wasSafe = this.isSafeBoundary();
|
|
66
|
+
this.consume(chunk[index]);
|
|
67
|
+
if (!wasSafe && this.isSafeBoundary() && this.pendingResolvers.length > 0) {
|
|
68
|
+
this.emit(chunk.slice(emittedUntil, index + 1));
|
|
69
|
+
emittedUntil = index + 1;
|
|
70
|
+
this.flushResolvers();
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if (emittedUntil < chunk.length) this.emit(chunk.slice(emittedUntil));
|
|
74
|
+
}
|
|
75
|
+
finish() {
|
|
76
|
+
if (this.closed) return;
|
|
77
|
+
this.flushResolvers();
|
|
78
|
+
this.closed = true;
|
|
79
|
+
if (this.pendingResolvers.length > 0) throw new Error("Cannot emit deferred resolver scripts because the React stream ended outside a safe HTML boundary.");
|
|
80
|
+
}
|
|
81
|
+
abort() {
|
|
82
|
+
this.closed = true;
|
|
83
|
+
this.pendingResolvers.length = 0;
|
|
84
|
+
}
|
|
85
|
+
isSafeBoundary() {
|
|
86
|
+
return this.shellFinished && 'data' === this.state && 0 === this.openElements.length && !this.awaitingContinuationProtocol;
|
|
87
|
+
}
|
|
88
|
+
flushResolvers() {
|
|
89
|
+
if (!this.isSafeBoundary() || 0 === this.pendingResolvers.length) return;
|
|
90
|
+
while(this.pendingResolvers.length > 0){
|
|
91
|
+
const resolver = this.pendingResolvers.shift();
|
|
92
|
+
if (void 0 !== resolver) this.emit(resolver);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
consume(char) {
|
|
96
|
+
switch(this.state){
|
|
97
|
+
case 'data':
|
|
98
|
+
if ('<' === char) this.state = 'tag-open';
|
|
99
|
+
return;
|
|
100
|
+
case 'tag-open':
|
|
101
|
+
if ('/' === char) {
|
|
102
|
+
this.currentTagName = '';
|
|
103
|
+
this.state = 'end-tag-name';
|
|
104
|
+
} else if ('!' === char) {
|
|
105
|
+
this.declarationPrefix = '';
|
|
106
|
+
this.state = 'markup-declaration';
|
|
107
|
+
} else if ('?' === char) this.state = 'bogus-comment';
|
|
108
|
+
else if (isAsciiAlpha(char)) {
|
|
109
|
+
this.startTag(char);
|
|
110
|
+
this.state = 'start-tag-name';
|
|
111
|
+
} else this.state = 'data';
|
|
112
|
+
return;
|
|
113
|
+
case 'start-tag-name':
|
|
114
|
+
if (isWhitespace(char)) this.state = 'before-attribute-name';
|
|
115
|
+
else if ('/' === char) this.state = 'self-closing-start-tag';
|
|
116
|
+
else if ('>' === char) this.completeStartTag(false);
|
|
117
|
+
else this.currentTagName += char.toLowerCase();
|
|
118
|
+
return;
|
|
119
|
+
case 'before-attribute-name':
|
|
120
|
+
if (isWhitespace(char)) return;
|
|
121
|
+
if ('/' === char) this.state = 'self-closing-start-tag';
|
|
122
|
+
else if ('>' === char) this.completeStartTag(false);
|
|
123
|
+
else {
|
|
124
|
+
this.startAttribute(char);
|
|
125
|
+
this.state = 'attribute-name';
|
|
126
|
+
}
|
|
127
|
+
return;
|
|
128
|
+
case 'attribute-name':
|
|
129
|
+
if (isWhitespace(char)) this.state = 'after-attribute-name';
|
|
130
|
+
else if ('=' === char) {
|
|
131
|
+
this.currentAttributeHasValue = true;
|
|
132
|
+
this.state = 'before-attribute-value';
|
|
133
|
+
} else if ('/' === char) {
|
|
134
|
+
this.completeAttribute();
|
|
135
|
+
this.state = 'self-closing-start-tag';
|
|
136
|
+
} else if ('>' === char) this.completeStartTag(false);
|
|
137
|
+
else this.currentAttributeName += char.toLowerCase();
|
|
138
|
+
return;
|
|
139
|
+
case 'after-attribute-name':
|
|
140
|
+
if (isWhitespace(char)) return;
|
|
141
|
+
if ('=' === char) {
|
|
142
|
+
this.currentAttributeHasValue = true;
|
|
143
|
+
this.state = 'before-attribute-value';
|
|
144
|
+
} else if ('/' === char) {
|
|
145
|
+
this.completeAttribute();
|
|
146
|
+
this.state = 'self-closing-start-tag';
|
|
147
|
+
} else if ('>' === char) this.completeStartTag(false);
|
|
148
|
+
else {
|
|
149
|
+
this.completeAttribute();
|
|
150
|
+
this.startAttribute(char);
|
|
151
|
+
this.state = 'attribute-name';
|
|
152
|
+
}
|
|
153
|
+
return;
|
|
154
|
+
case 'before-attribute-value':
|
|
155
|
+
if (isWhitespace(char)) return;
|
|
156
|
+
if ('"' === char) this.state = 'attribute-value-double-quoted';
|
|
157
|
+
else if ("'" === char) this.state = 'attribute-value-single-quoted';
|
|
158
|
+
else if ('>' === char) this.completeStartTag(false);
|
|
159
|
+
else {
|
|
160
|
+
this.currentAttributeValue += char;
|
|
161
|
+
this.state = 'attribute-value-unquoted';
|
|
162
|
+
}
|
|
163
|
+
return;
|
|
164
|
+
case 'attribute-value-double-quoted':
|
|
165
|
+
if ('"' === char) {
|
|
166
|
+
this.completeAttribute();
|
|
167
|
+
this.state = 'before-attribute-name';
|
|
168
|
+
} else this.currentAttributeValue += char;
|
|
169
|
+
return;
|
|
170
|
+
case 'attribute-value-single-quoted':
|
|
171
|
+
if ("'" === char) {
|
|
172
|
+
this.completeAttribute();
|
|
173
|
+
this.state = 'before-attribute-name';
|
|
174
|
+
} else this.currentAttributeValue += char;
|
|
175
|
+
return;
|
|
176
|
+
case 'attribute-value-unquoted':
|
|
177
|
+
if (isWhitespace(char)) {
|
|
178
|
+
this.completeAttribute();
|
|
179
|
+
this.state = 'before-attribute-name';
|
|
180
|
+
} else if ('>' === char) this.completeStartTag(false);
|
|
181
|
+
else this.currentAttributeValue += char;
|
|
182
|
+
return;
|
|
183
|
+
case 'self-closing-start-tag':
|
|
184
|
+
if ('>' === char) this.completeStartTag(true);
|
|
185
|
+
else if (!isWhitespace(char)) {
|
|
186
|
+
this.startAttribute(char);
|
|
187
|
+
this.state = 'attribute-name';
|
|
188
|
+
}
|
|
189
|
+
return;
|
|
190
|
+
case 'end-tag-name':
|
|
191
|
+
if (isWhitespace(char)) this.state = 'after-end-tag-name';
|
|
192
|
+
else if ('>' === char) this.completeEndTag();
|
|
193
|
+
else this.currentTagName += char.toLowerCase();
|
|
194
|
+
return;
|
|
195
|
+
case 'after-end-tag-name':
|
|
196
|
+
if ('>' === char) this.completeEndTag();
|
|
197
|
+
return;
|
|
198
|
+
case 'markup-declaration':
|
|
199
|
+
if (this.declarationPrefix.length < 2 && '-' === char) {
|
|
200
|
+
this.declarationPrefix += char;
|
|
201
|
+
if ('--' === this.declarationPrefix) {
|
|
202
|
+
this.commentTail = '';
|
|
203
|
+
this.state = 'comment';
|
|
204
|
+
}
|
|
205
|
+
} else this.state = '>' === char ? 'data' : 'declaration';
|
|
206
|
+
return;
|
|
207
|
+
case 'declaration':
|
|
208
|
+
if ('>' === char) this.state = 'data';
|
|
209
|
+
return;
|
|
210
|
+
case 'comment':
|
|
211
|
+
this.commentTail = `${this.commentTail}${char}`.slice(-3);
|
|
212
|
+
if ('-->' === this.commentTail) this.state = 'data';
|
|
213
|
+
return;
|
|
214
|
+
case 'bogus-comment':
|
|
215
|
+
if ('>' === char) this.state = 'data';
|
|
216
|
+
return;
|
|
217
|
+
case 'raw-text':
|
|
218
|
+
this.consumeRawText(char);
|
|
219
|
+
return;
|
|
220
|
+
case 'raw-end-tag':
|
|
221
|
+
if ('>' === char) this.completeRawTextEndTag();
|
|
222
|
+
else if (!isWhitespace(char)) {
|
|
223
|
+
this.state = 'raw-text';
|
|
224
|
+
this.rawTextSearch = getSuffix(`${this.rawTextSearch}${char.toLowerCase()}`, `</${this.rawTextElement}`);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
startTag(char) {
|
|
229
|
+
this.currentTagName = char.toLowerCase();
|
|
230
|
+
this.currentAttributes = new Map();
|
|
231
|
+
this.currentAttributeName = '';
|
|
232
|
+
this.currentAttributeValue = '';
|
|
233
|
+
this.currentAttributeHasValue = false;
|
|
234
|
+
}
|
|
235
|
+
startAttribute(char) {
|
|
236
|
+
this.currentAttributeName = char.toLowerCase();
|
|
237
|
+
this.currentAttributeValue = '';
|
|
238
|
+
this.currentAttributeHasValue = false;
|
|
239
|
+
}
|
|
240
|
+
completeAttribute() {
|
|
241
|
+
if ('' === this.currentAttributeName) return;
|
|
242
|
+
this.currentAttributes.set(this.currentAttributeName, this.currentAttributeHasValue ? this.currentAttributeValue : true);
|
|
243
|
+
this.currentAttributeName = '';
|
|
244
|
+
this.currentAttributeValue = '';
|
|
245
|
+
this.currentAttributeHasValue = false;
|
|
246
|
+
}
|
|
247
|
+
completeStartTag(selfClosing) {
|
|
248
|
+
this.completeAttribute();
|
|
249
|
+
const tagName = this.currentTagName;
|
|
250
|
+
const id = this.currentAttributes.get('id');
|
|
251
|
+
const hasReactSegmentId = 'string' == typeof id && REACT_SEGMENT_ID_PATTERN.test(id);
|
|
252
|
+
const hasHiddenAttribute = this.currentAttributes.has('hidden');
|
|
253
|
+
const isHiddenSegmentTable = 'table' === tagName && hasHiddenAttribute && !hasReactSegmentId;
|
|
254
|
+
const isTableSegmentChild = hasReactSegmentId && TABLE_SEGMENT_CHILDREN.has(tagName) && this.openElements[this.openElements.length - 1]?.isSegmentTableWrapper === true;
|
|
255
|
+
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);
|
|
256
|
+
this.continuationProtocolScript = "script" === tagName && this.awaitingContinuationProtocol;
|
|
257
|
+
this.continuationProtocolTail = '';
|
|
258
|
+
this.hasContinuationProtocolCall = false;
|
|
259
|
+
if (!selfClosing && !VOID_ELEMENTS.has(tagName)) this.openElements.push({
|
|
260
|
+
tagName,
|
|
261
|
+
isContinuationContainer,
|
|
262
|
+
isSegmentTableWrapper: isHiddenSegmentTable
|
|
263
|
+
});
|
|
264
|
+
this.currentTagName = '';
|
|
265
|
+
this.currentAttributes = new Map();
|
|
266
|
+
this.currentAttributeName = '';
|
|
267
|
+
this.currentAttributeValue = '';
|
|
268
|
+
this.currentAttributeHasValue = false;
|
|
269
|
+
if (!selfClosing && RAW_TEXT_ELEMENTS.has(tagName)) {
|
|
270
|
+
this.rawTextElement = tagName;
|
|
271
|
+
this.rawTextSearch = '';
|
|
272
|
+
this.state = 'raw-text';
|
|
273
|
+
} else this.state = 'data';
|
|
274
|
+
}
|
|
275
|
+
completeEndTag() {
|
|
276
|
+
this.closeOpenElement(this.currentTagName);
|
|
277
|
+
this.currentTagName = '';
|
|
278
|
+
this.state = 'data';
|
|
279
|
+
}
|
|
280
|
+
consumeRawText(char) {
|
|
281
|
+
const rawTextElement = this.rawTextElement;
|
|
282
|
+
if (void 0 === rawTextElement) {
|
|
283
|
+
this.state = 'data';
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
const endTagPrefix = `</${rawTextElement}`;
|
|
287
|
+
if (this.continuationProtocolScript) {
|
|
288
|
+
this.continuationProtocolTail = `${this.continuationProtocolTail}${char}`.slice(-4);
|
|
289
|
+
if (/\$(?:RC|RS|RX|RB|RR)\b/.test(this.continuationProtocolTail)) this.hasContinuationProtocolCall = true;
|
|
290
|
+
}
|
|
291
|
+
this.rawTextSearch = getSuffix(`${this.rawTextSearch}${char.toLowerCase()}`, endTagPrefix);
|
|
292
|
+
if (this.rawTextSearch === endTagPrefix) this.state = 'raw-end-tag';
|
|
293
|
+
}
|
|
294
|
+
completeRawTextEndTag() {
|
|
295
|
+
const rawTextElement = this.rawTextElement;
|
|
296
|
+
if (void 0 !== rawTextElement) this.closeOpenElement(rawTextElement);
|
|
297
|
+
if ("script" === rawTextElement && this.continuationProtocolScript && this.hasContinuationProtocolCall) this.awaitingContinuationProtocol = false;
|
|
298
|
+
this.rawTextElement = void 0;
|
|
299
|
+
this.rawTextSearch = '';
|
|
300
|
+
this.continuationProtocolScript = false;
|
|
301
|
+
this.continuationProtocolTail = '';
|
|
302
|
+
this.hasContinuationProtocolCall = false;
|
|
303
|
+
this.state = 'data';
|
|
304
|
+
}
|
|
305
|
+
closeOpenElement(tagName) {
|
|
306
|
+
const matchingIndex = this.openElements.map((element)=>element.tagName).lastIndexOf(tagName);
|
|
307
|
+
if (-1 === matchingIndex) return;
|
|
308
|
+
const closedElements = this.openElements.splice(matchingIndex);
|
|
309
|
+
const closedContinuation = closedElements.some((element)=>element.isContinuationContainer);
|
|
310
|
+
if (closedContinuation) this.awaitingContinuationProtocol = true;
|
|
311
|
+
}
|
|
312
|
+
constructor(emit){
|
|
313
|
+
this.emit = emit;
|
|
314
|
+
this.pendingResolvers = [];
|
|
315
|
+
this.openElements = [];
|
|
316
|
+
this.shellFinished = false;
|
|
317
|
+
this.closed = false;
|
|
318
|
+
this.state = 'data';
|
|
319
|
+
this.currentTagName = '';
|
|
320
|
+
this.currentAttributes = new Map();
|
|
321
|
+
this.currentAttributeName = '';
|
|
322
|
+
this.currentAttributeValue = '';
|
|
323
|
+
this.currentAttributeHasValue = false;
|
|
324
|
+
this.declarationPrefix = '';
|
|
325
|
+
this.commentTail = '';
|
|
326
|
+
this.rawTextSearch = '';
|
|
327
|
+
this.continuationProtocolScript = false;
|
|
328
|
+
this.continuationProtocolTail = '';
|
|
329
|
+
this.hasContinuationProtocolCall = false;
|
|
330
|
+
this.awaitingContinuationProtocol = false;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
export { DeferredScriptOutputCoordinator };
|
|
@@ -11,6 +11,7 @@ var shared_ShellChunkStatus = /*#__PURE__*/ function(ShellChunkStatus) {
|
|
|
11
11
|
ShellChunkStatus[ShellChunkStatus["FINISH"] = 1] = "FINISH";
|
|
12
12
|
return ShellChunkStatus;
|
|
13
13
|
}({});
|
|
14
|
+
const SHELL_PROGRESSIVE_CHUNK_SIZE = Number.MAX_SAFE_INTEGER;
|
|
14
15
|
const SHOULD_STREAM_ALL_HEADER = 'x-should-stream-all';
|
|
15
16
|
function parseShouldStreamAllFlag(value) {
|
|
16
17
|
if (!value) return;
|
|
@@ -108,4 +109,4 @@ function createRenderStreaming(createReadableStreamPromise) {
|
|
|
108
109
|
return stream;
|
|
109
110
|
};
|
|
110
111
|
}
|
|
111
|
-
export { createRenderStreaming, encodeForWebStream, getReadableStreamFromString, resolveStreamingMode, shared_ShellChunkStatus as ShellChunkStatus };
|
|
112
|
+
export { SHELL_PROGRESSIVE_CHUNK_SIZE, createRenderStreaming, encodeForWebStream, getReadableStreamFromString, resolveStreamingMode, shared_ShellChunkStatus as ShellChunkStatus };
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import "node:module";
|
|
2
|
+
import { getGlobalEnableRsc, getGlobalInternalRuntimeContext } from "@modern-js/runtime/context";
|
|
2
3
|
import { time } from "@modern-js/runtime-utils/time";
|
|
3
4
|
import { SSR_HYDRATION_ID_PREFIX } from "@modern-js/utils/universal/constants";
|
|
4
5
|
import server from "react-dom/server";
|
|
5
6
|
import { RenderLevel } from "../../constants.mjs";
|
|
6
|
-
import {
|
|
7
|
+
import { getMonitors } from "../../context/monitors/index.mjs";
|
|
7
8
|
import { wrapRuntimeComponentResolver, wrapRuntimeContextProvider } from "../../react/wrapper.mjs";
|
|
8
9
|
import { CHUNK_CSS_PLACEHOLDER, CHUNK_JS_PLACEHOLDER, HTML_PLACEHOLDER, SSR_DATA_PLACEHOLDER } from "../constants.mjs";
|
|
9
10
|
import { createReplaceHelemt, getHelmetData } from "../helmet.mjs";
|
|
@@ -61,6 +62,7 @@ const renderString = async (request, serverRoot, options)=>{
|
|
|
61
62
|
config,
|
|
62
63
|
platform: 'node',
|
|
63
64
|
mode: 'string',
|
|
65
|
+
monitors: getMonitors(),
|
|
64
66
|
isRsc: true === getGlobalEnableRsc()
|
|
65
67
|
}
|
|
66
68
|
});
|
|
@@ -20,8 +20,8 @@ const assetToChunk = (asset)=>({
|
|
|
20
20
|
});
|
|
21
21
|
const checkIsInline = (chunk, enableInline)=>{
|
|
22
22
|
if ('production' !== process.env.NODE_ENV) return false;
|
|
23
|
-
if (enableInline instanceof RegExp) return enableInline.test(chunk.url);
|
|
24
|
-
return Boolean(enableInline);
|
|
23
|
+
else if (enableInline instanceof RegExp) return enableInline.test(chunk.url);
|
|
24
|
+
else return Boolean(enableInline);
|
|
25
25
|
};
|
|
26
26
|
const readAsset = async (chunk)=>{
|
|
27
27
|
const fs = await import("fs/promises");
|
|
@@ -114,7 +114,7 @@ class LoadableCollector {
|
|
|
114
114
|
const scripts = await Promise.all(chunks.filter((chunk)=>!existedScript.includes(chunk.url) && !this.existsAssets?.includes(chunk.path)).map(async (chunk)=>{
|
|
115
115
|
const script = `<script${attributes} src="${chunk.url}"></script>`;
|
|
116
116
|
if (checkIsNode() && checkIsInline(chunk, inlineStyles)) return readAsset(chunk).then((content)=>`<script>${content}</script>`).catch((_)=>script);
|
|
117
|
-
return script;
|
|
117
|
+
else return script;
|
|
118
118
|
}));
|
|
119
119
|
chunkSet.jsChunk += scripts.filter((script)=>Boolean(script)).join('');
|
|
120
120
|
}
|
|
@@ -131,7 +131,7 @@ class LoadableCollector {
|
|
|
131
131
|
const css = await Promise.all(emittedChunks.map(async (chunk)=>{
|
|
132
132
|
const link = `<link${atrributes} href="${chunk.url}" rel="stylesheet" />`;
|
|
133
133
|
if (checkIsNode() && checkIsInline(chunk, inlineStyles)) return readAsset(chunk).then((content)=>`<style>${content}</style>`).catch((_)=>link);
|
|
134
|
-
return link;
|
|
134
|
+
else return link;
|
|
135
135
|
}));
|
|
136
136
|
chunkSet.cssChunk += css.filter((css)=>Boolean(css)).join('');
|
|
137
137
|
this.stylesheetInfo.emittedAssets = emittedChunks.map((chunk)=>chunk.url);
|
|
@@ -126,6 +126,7 @@ g.__MODERN_DOC_RENDERERS__[${JSON.stringify(_entryName)}] = render;
|
|
|
126
126
|
|
|
127
127
|
export default { render: render };`;
|
|
128
128
|
};
|
|
129
|
+
const getDocumentTempEntry = (internalDirectory, compilerName, entryName)=>path.join(internalDirectory, CONSTANTS.DOCUMENT_OUTPUT_DIR, compilerName ?? '', `${CONSTANTS.TEMP_ENTRY_PREFIX}${entryName}.js`);
|
|
129
130
|
const processChildCompilation = async (entryName, docPath, compilation, compiler, appDirectory, internalDirectory)=>new Promise((resolve, reject)=>{
|
|
130
131
|
const outFile = path.posix.join(CONSTANTS.DOCUMENT_OUTPUT_DIR, `${CONSTANTS.HTML_OUTPUT_PREFIX}${entryName}${CONSTANTS.HTML_OUTPUT_SUFFIX}`);
|
|
131
132
|
const child = compilation.createChildCompiler(`${CONSTANTS.CHILD_COMPILER_PREFIX}${entryName}`, {
|
|
@@ -136,8 +137,7 @@ const processChildCompilation = async (entryName, docPath, compilation, compiler
|
|
|
136
137
|
}, []);
|
|
137
138
|
configureChildCompiler(child, compiler, appDirectory);
|
|
138
139
|
applyExternalsPlugin(child, compiler);
|
|
139
|
-
const
|
|
140
|
-
const tempEntry = path.join(entryDir, `${CONSTANTS.TEMP_ENTRY_PREFIX}${entryName}.js`);
|
|
140
|
+
const tempEntry = getDocumentTempEntry(internalDirectory, compiler.name, entryName);
|
|
141
141
|
const finalize = ()=>{
|
|
142
142
|
try {
|
|
143
143
|
const EntryPlugin = compiler.rspack?.EntryPlugin;
|
|
@@ -204,6 +204,7 @@ const documentPlugin = ()=>({
|
|
|
204
204
|
const tasks = [];
|
|
205
205
|
for (const ep of entrypoints || []){
|
|
206
206
|
const entryName = ep.entryName;
|
|
207
|
+
if (!this.htmlEntryNames.has(entryName)) continue;
|
|
207
208
|
const docPath = getDocumentByEntryName(entrypoints, entryName, appDirectory);
|
|
208
209
|
if (docPath) {
|
|
209
210
|
compilation.fileDependencies?.add?.(docPath);
|
|
@@ -220,14 +221,19 @@ const documentPlugin = ()=>({
|
|
|
220
221
|
}
|
|
221
222
|
});
|
|
222
223
|
}
|
|
223
|
-
constructor(){
|
|
224
|
+
constructor(htmlEntryNames){
|
|
225
|
+
this.htmlEntryNames = htmlEntryNames;
|
|
224
226
|
this.name = 'ModernJsDocumentChildCompilerPlugin';
|
|
225
227
|
}
|
|
226
228
|
}
|
|
227
229
|
api.config(()=>({
|
|
228
230
|
tools: {
|
|
229
|
-
bundlerChain: (chain)=>{
|
|
230
|
-
|
|
231
|
+
bundlerChain: (chain, { environment })=>{
|
|
232
|
+
const htmlEntryNames = new Set(Object.keys(environment.htmlPaths));
|
|
233
|
+
if (0 === htmlEntryNames.size) return;
|
|
234
|
+
chain.plugin('modernjs-document-child-compiler').use(ModernJsDocumentChildCompilerPlugin, [
|
|
235
|
+
htmlEntryNames
|
|
236
|
+
]);
|
|
231
237
|
}
|
|
232
238
|
}
|
|
233
239
|
}));
|
|
@@ -348,4 +354,4 @@ const documentPlugin = ()=>({
|
|
|
348
354
|
});
|
|
349
355
|
const cli = documentPlugin;
|
|
350
356
|
export default cli;
|
|
351
|
-
export { documentPlugin, getDocumentByEntryName, processScriptPlaceholders };
|
|
357
|
+
export { documentPlugin, getDocumentByEntryName, getDocumentTempEntry, processScriptPlaceholders };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import "node:module";
|
|
2
2
|
"use client";
|
|
3
|
+
import { RuntimeComponentResolverContext } from "@modern-js/runtime/context";
|
|
3
4
|
import react from "react";
|
|
4
5
|
import { Helmet, HelmetData, HelmetProvider } from "react-helmet-async";
|
|
5
|
-
import { RuntimeComponentResolverContext } from "../core/context/runtime.mjs";
|
|
6
6
|
const head_Helmet = (props)=>{
|
|
7
7
|
const resolveComponent = react.useContext(RuntimeComponentResolverContext);
|
|
8
8
|
const Component = resolveComponent?.(Helmet, {
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import "node:module";
|
|
2
|
-
export { InternalRuntimeContext } from "
|
|
2
|
+
export { InternalRuntimeContext } from "@modern-js/runtime/context";
|
|
@@ -43,8 +43,7 @@ const optimizeRoute = (routeTree)=>{
|
|
|
43
43
|
children: optimizedChildren
|
|
44
44
|
}
|
|
45
45
|
];
|
|
46
|
-
}
|
|
47
|
-
{
|
|
46
|
+
} else {
|
|
48
47
|
const newRoutes = children.map((child)=>{
|
|
49
48
|
const routePath = routeTree.path ? `${routeTree.path}${child.path ? `/${child.path}` : ''}` : child.path || '';
|
|
50
49
|
const newRoute = {
|
|
@@ -353,7 +353,7 @@ const runtimeGlobalContext = async ({ entryName, metaName, srcDirectory, nestedR
|
|
|
353
353
|
source: rootLayout.toString(),
|
|
354
354
|
filename: rootLayoutFile
|
|
355
355
|
});
|
|
356
|
-
const hasAppInit = moduleExports.some((e)=>e.
|
|
356
|
+
const hasAppInit = moduleExports.some((e)=>'reexport-all' !== e.type && e.name === APP_INIT_EXPORTED);
|
|
357
357
|
const layoutPath = formatImportPath(getPathWithoutExt(replaceWithAlias(srcDirectory, rootLayoutFile, internalSrcAlias)));
|
|
358
358
|
if (hasAppInit) imports.push(`import { init as appInit } from '${layoutPath}';`);
|
|
359
359
|
else imports.push("let appInit;");
|
|
@@ -379,7 +379,7 @@ const runtimeGlobalContext = async ({ entryName, metaName, srcDirectory, nestedR
|
|
|
379
379
|
enableRsc: true,
|
|
380
380
|
});
|
|
381
381
|
`;
|
|
382
|
-
return `${imports.join('\n')}
|
|
382
|
+
else return `${imports.join('\n')}
|
|
383
383
|
|
|
384
384
|
import { routes } from '${routesImportPath}';
|
|
385
385
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import "node:module";
|
|
2
2
|
import { JS_EXTENSIONS, fs, normalizeToPosixPath } from "@modern-js/utils";
|
|
3
|
-
import { parse } from "es-module-lexer";
|
|
3
|
+
import { init, parse } from "es-module-lexer";
|
|
4
4
|
import { transform } from "esbuild";
|
|
5
5
|
import fs_0 from "fs";
|
|
6
6
|
import path from "path";
|
|
@@ -11,7 +11,7 @@ const walkDirectory = (dir)=>fs_0.readdirSync(dir).reduce((previous, filename)=>
|
|
|
11
11
|
...previous,
|
|
12
12
|
...walkDirectory(filePath)
|
|
13
13
|
];
|
|
14
|
-
return [
|
|
14
|
+
else return [
|
|
15
15
|
...previous,
|
|
16
16
|
filePath
|
|
17
17
|
];
|
|
@@ -28,7 +28,7 @@ const isPageComponentFile = (filePath)=>{
|
|
|
28
28
|
};
|
|
29
29
|
const replaceWithAlias = (base, filePath, alias)=>{
|
|
30
30
|
if (filePath.includes(base)) return normalizeToPosixPath(path.join(alias, path.relative(base, filePath)));
|
|
31
|
-
return filePath;
|
|
31
|
+
else return filePath;
|
|
32
32
|
};
|
|
33
33
|
const parseModule = async ({ source, filename })=>{
|
|
34
34
|
let content = source;
|
|
@@ -48,6 +48,7 @@ const parseModule = async ({ source, filename })=>{
|
|
|
48
48
|
});
|
|
49
49
|
content = result.code;
|
|
50
50
|
}
|
|
51
|
+
await init();
|
|
51
52
|
return parse(content);
|
|
52
53
|
};
|
|
53
54
|
const hasLoader = async (filename, source)=>{
|
|
@@ -58,7 +59,7 @@ const hasLoader = async (filename, source)=>{
|
|
|
58
59
|
source: content.toString(),
|
|
59
60
|
filename
|
|
60
61
|
});
|
|
61
|
-
return moduleExports.some((e)=>e.
|
|
62
|
+
return moduleExports.some((e)=>'reexport-all' !== e.type && e.name === LOADER_EXPORT_NAME);
|
|
62
63
|
}
|
|
63
64
|
return false;
|
|
64
65
|
};
|
|
@@ -70,7 +71,7 @@ const hasAction = async (filename, source)=>{
|
|
|
70
71
|
source: content.toString(),
|
|
71
72
|
filename
|
|
72
73
|
});
|
|
73
|
-
return moduleExports.some((e)=>e.
|
|
74
|
+
return moduleExports.some((e)=>'reexport-all' !== e.type && e.name === ACTION_EXPORT_NAME);
|
|
74
75
|
}
|
|
75
76
|
return false;
|
|
76
77
|
};
|
|
@@ -29,7 +29,8 @@ const DeferredDataScripts = (props)=>{
|
|
|
29
29
|
}, []);
|
|
30
30
|
const deferredScripts = useMemo(()=>{
|
|
31
31
|
if (!staticContext) return null;
|
|
32
|
-
const
|
|
32
|
+
const requestStorage = storage.useContext();
|
|
33
|
+
const activeDeferreds = requestStorage.activeDeferreds;
|
|
33
34
|
const _ROUTER_DATA = {
|
|
34
35
|
loaderData: staticContext.loaderData,
|
|
35
36
|
errors: serializeErrors(staticContext.errors)
|
|
@@ -42,6 +43,7 @@ const DeferredDataScripts = (props)=>{
|
|
|
42
43
|
const deferredDataScripts = [];
|
|
43
44
|
const initialScripts = Array.from(activeDeferreds.entries()).map(([routeId, deferredData])=>{
|
|
44
45
|
const pendingKeys = new Set(deferredData.pendingKeys);
|
|
46
|
+
requestStorage.deferredScriptKeys?.set(routeId, Array.from(pendingKeys));
|
|
45
47
|
const { deferredKeys } = deferredData;
|
|
46
48
|
const deferredKeyPromiseManifests = deferredKeys.map((key)=>{
|
|
47
49
|
if (pendingKeys.has(key)) return {
|
|
@@ -52,7 +54,7 @@ const DeferredDataScripts = (props)=>{
|
|
|
52
54
|
serializeJson(key)
|
|
53
55
|
]
|
|
54
56
|
};
|
|
55
|
-
{
|
|
57
|
+
else {
|
|
56
58
|
const trackedPromise = deferredData.data[key];
|
|
57
59
|
if (void 0 !== trackedPromise._error) {
|
|
58
60
|
const error = toDeferredErrorInfo(trackedPromise._error);
|
|
@@ -64,15 +66,16 @@ const DeferredDataScripts = (props)=>{
|
|
|
64
66
|
serializeJson(error)
|
|
65
67
|
]
|
|
66
68
|
};
|
|
69
|
+
} else {
|
|
70
|
+
if (void 0 === trackedPromise._data) throw new Error(`The deferred data for ${key} was not resolved, did you forget to return data from a deferred promise`);
|
|
71
|
+
return {
|
|
72
|
+
key,
|
|
73
|
+
routerDataFnName: 'p',
|
|
74
|
+
routerDataFnArgs: [
|
|
75
|
+
serializeJson(trackedPromise._data)
|
|
76
|
+
]
|
|
77
|
+
};
|
|
67
78
|
}
|
|
68
|
-
if (void 0 === trackedPromise._data) throw new Error(`The deferred data for ${key} was not resolved, did you forget to return data from a deferred promise`);
|
|
69
|
-
return {
|
|
70
|
-
key,
|
|
71
|
-
routerDataFnName: 'p',
|
|
72
|
-
routerDataFnArgs: [
|
|
73
|
-
serializeJson(trackedPromise._data)
|
|
74
|
-
]
|
|
75
|
-
};
|
|
76
79
|
}
|
|
77
80
|
});
|
|
78
81
|
return {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import "node:module";
|
|
2
2
|
"use client";
|
|
3
3
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
4
|
+
import { InternalRuntimeContext } from "@modern-js/runtime/context";
|
|
4
5
|
import { Link as router_Link, NavLink, matchRoutes, useHref, useMatches, useResolvedPath } from "@modern-js/runtime-utils/router";
|
|
5
6
|
import react, { useContext, useMemo } from "react";
|
|
6
|
-
import { InternalRuntimeContext } from "../../core/context/index.mjs";
|
|
7
7
|
import { __webpack_require__ } from "../../rslib-runtime~0.mjs";
|
|
8
8
|
const getWebpackChunkLoader = ()=>__webpack_chunk_load__;
|
|
9
9
|
const getWebpackPublicPath = ()=>{
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import "node:module";
|
|
2
2
|
import { createSyncHook } from "@modern-js/plugin";
|
|
3
|
-
const
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
const onAfterHydrateRouter = createRouterSyncHook();
|
|
3
|
+
const modifyRoutes = createSyncHook();
|
|
4
|
+
const onBeforeCreateRoutes = createSyncHook();
|
|
5
|
+
const onBeforeCreateRouter = createSyncHook();
|
|
6
|
+
const onAfterCreateRouter = createSyncHook();
|
|
7
|
+
const onBeforeHydrateRouter = createSyncHook();
|
|
8
|
+
const onAfterHydrateRouter = createSyncHook();
|
|
10
9
|
const routerProviderRegistryHooks = {
|
|
11
10
|
modifyRoutes: modifyRoutes,
|
|
12
11
|
onBeforeCreateRoutes: onBeforeCreateRoutes,
|