@reckona/mreact-compiler 0.0.16 → 0.0.18
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/diagnostics.d.ts +1 -1
- package/dist/diagnostics.d.ts.map +1 -1
- package/dist/diagnostics.js +38 -2
- package/dist/diagnostics.js.map +1 -1
- package/dist/emit-server-stream.d.ts.map +1 -1
- package/dist/emit-server-stream.js +201 -57
- package/dist/emit-server-stream.js.map +1 -1
- package/dist/emit-server.js +54 -26
- package/dist/emit-server.js.map +1 -1
- package/dist/ir.d.ts +4 -1
- package/dist/ir.d.ts.map +1 -1
- package/dist/oxc-await-validation.d.ts +2 -2
- package/dist/oxc-await-validation.d.ts.map +1 -1
- package/dist/oxc-await-validation.js +3 -3
- package/dist/oxc-await-validation.js.map +1 -1
- package/dist/oxc-child-analysis.d.ts.map +1 -1
- package/dist/oxc-child-analysis.js +9 -2
- package/dist/oxc-child-analysis.js.map +1 -1
- package/dist/oxc-node-utils.d.ts +1 -0
- package/dist/oxc-node-utils.d.ts.map +1 -1
- package/dist/oxc-node-utils.js +6 -0
- package/dist/oxc-node-utils.js.map +1 -1
- package/dist/oxc-raw-jsx.d.ts.map +1 -1
- package/dist/oxc-raw-jsx.js +149 -1
- package/dist/oxc-raw-jsx.js.map +1 -1
- package/dist/oxc.d.ts.map +1 -1
- package/dist/oxc.js +15 -6
- package/dist/oxc.js.map +1 -1
- package/dist/types.d.ts +6 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -2
package/dist/diagnostics.d.ts
CHANGED
|
@@ -11,5 +11,5 @@ export declare function unsupportedNestedAwaitDiagnostic(loc?: SourceLocation):
|
|
|
11
11
|
export declare function unserializableAwaitValueDiagnostic(reason: string, loc?: SourceLocation): Diagnostic;
|
|
12
12
|
export declare function unsupportedBodyStatementJsxDiagnostic(loc?: SourceLocation): Diagnostic;
|
|
13
13
|
export declare function unsupportedTopLevelJsxInitializerDiagnostic(loc?: SourceLocation): Diagnostic;
|
|
14
|
-
export declare function invalidJsxExpressionDiagnostic(loc?: SourceLocation): Diagnostic;
|
|
14
|
+
export declare function invalidJsxExpressionDiagnostic(loc?: SourceLocation, context?: "text" | "attribute" | "unknown"): Diagnostic;
|
|
15
15
|
//# sourceMappingURL=diagnostics.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diagnostics.d.ts","sourceRoot":"","sources":["../src/diagnostics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE7D,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,UAAU,GACrB,MAAM,
|
|
1
|
+
{"version":3,"file":"diagnostics.d.ts","sourceRoot":"","sources":["../src/diagnostics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE7D,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,UAAU,GACrB,MAAM,CAiBR;AAED,wBAAgB,uCAAuC,CACrD,IAAI,EAAE,MAAM,EACZ,GAAG,CAAC,EAAE,cAAc,GACnB,UAAU,CAOZ;AAED,wBAAgB,oCAAoC,CAClD,GAAG,CAAC,EAAE,cAAc,GACnB,UAAU,CAOZ;AAED,wBAAgB,uCAAuC,CACrD,IAAI,EAAE,MAAM,EACZ,GAAG,CAAC,EAAE,cAAc,GACnB,UAAU,CAOZ;AAED,wBAAgB,2CAA2C,CACzD,IAAI,EAAE,MAAM,EACZ,GAAG,CAAC,EAAE,cAAc,GACnB,UAAU,CAOZ;AAED,wBAAgB,iCAAiC,CAAC,GAAG,CAAC,EAAE,cAAc,GAAG,UAAU,CAQlF;AAED,wBAAgB,uCAAuC,IAAI,UAAU,CAOpE;AAED,wBAAgB,wCAAwC,CACtD,IAAI,EAAE,MAAM,EACZ,GAAG,CAAC,EAAE,cAAc,GACnB,UAAU,CAOZ;AAED,wBAAgB,gCAAgC,CAAC,GAAG,CAAC,EAAE,cAAc,GAAG,UAAU,CAQjF;AAED,wBAAgB,kCAAkC,CAChD,MAAM,EAAE,MAAM,EACd,GAAG,CAAC,EAAE,cAAc,GACnB,UAAU,CAWZ;AAED,wBAAgB,qCAAqC,CACnD,GAAG,CAAC,EAAE,cAAc,GACnB,UAAU,CAQZ;AAED,wBAAgB,2CAA2C,CACzD,GAAG,CAAC,EAAE,cAAc,GACnB,UAAU,CAQZ;AAED,wBAAgB,8BAA8B,CAC5C,GAAG,CAAC,EAAE,cAAc,EACpB,OAAO,GAAE,MAAM,GAAG,WAAW,GAAG,SAAqB,GACpD,UAAU,CAuCZ"}
|
package/dist/diagnostics.js
CHANGED
|
@@ -2,7 +2,16 @@ export function formatDiagnostic(filename, diagnostic) {
|
|
|
2
2
|
const loc = diagnostic.loc === undefined
|
|
3
3
|
? ""
|
|
4
4
|
: `:${diagnostic.loc.line}:${diagnostic.loc.column}`;
|
|
5
|
-
|
|
5
|
+
const suggestion = diagnostic.suggestion === undefined
|
|
6
|
+
? ""
|
|
7
|
+
: [
|
|
8
|
+
` Suggestion: ${diagnostic.suggestion.title}`,
|
|
9
|
+
diagnostic.suggestion.replacement === undefined
|
|
10
|
+
? ""
|
|
11
|
+
: ` Replacement: ${diagnostic.suggestion.replacement}`,
|
|
12
|
+
diagnostic.suggestion.link === undefined ? "" : ` See: ${diagnostic.suggestion.link}`,
|
|
13
|
+
].join("");
|
|
14
|
+
return `${filename}${loc} [${diagnostic.code}] ${diagnostic.message}${suggestion}`;
|
|
6
15
|
}
|
|
7
16
|
export function unsupportedComponentReferenceDiagnostic(name, loc) {
|
|
8
17
|
return {
|
|
@@ -94,11 +103,38 @@ export function unsupportedTopLevelJsxInitializerDiagnostic(loc) {
|
|
|
94
103
|
...(loc === undefined ? {} : { loc }),
|
|
95
104
|
};
|
|
96
105
|
}
|
|
97
|
-
export function invalidJsxExpressionDiagnostic(loc) {
|
|
106
|
+
export function invalidJsxExpressionDiagnostic(loc, context = "unknown") {
|
|
107
|
+
if (context === "text") {
|
|
108
|
+
return {
|
|
109
|
+
level: "error",
|
|
110
|
+
code: "MR_INVALID_JSX_EXPRESSION",
|
|
111
|
+
message: "JSX text contains an empty or unparseable expression. To include literal braces in text, use { / } or {'{'} / {'}'} escapes.",
|
|
112
|
+
suggestion: {
|
|
113
|
+
title: "Escape literal braces in text as HTML entities or JSX string expressions.",
|
|
114
|
+
replacement: "{ / }",
|
|
115
|
+
},
|
|
116
|
+
...(loc === undefined ? {} : { loc }),
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
if (context === "attribute") {
|
|
120
|
+
return {
|
|
121
|
+
level: "error",
|
|
122
|
+
code: "MR_INVALID_JSX_EXPRESSION",
|
|
123
|
+
message: "JSX attribute expression is empty or unparseable. Attribute braces must contain a valid JavaScript expression.",
|
|
124
|
+
suggestion: {
|
|
125
|
+
title: "Use a valid JavaScript expression in braces, or quote literal attribute text.",
|
|
126
|
+
replacement: 'title="literal text"',
|
|
127
|
+
},
|
|
128
|
+
...(loc === undefined ? {} : { loc }),
|
|
129
|
+
};
|
|
130
|
+
}
|
|
98
131
|
return {
|
|
99
132
|
level: "error",
|
|
100
133
|
code: "MR_INVALID_JSX_EXPRESSION",
|
|
101
134
|
message: "JSX expression is empty or unparseable. To include literal braces in text, use { / } or {'{'} / {'}'} escapes.",
|
|
135
|
+
suggestion: {
|
|
136
|
+
title: "Check the JSX expression syntax at this location.",
|
|
137
|
+
},
|
|
102
138
|
...(loc === undefined ? {} : { loc }),
|
|
103
139
|
};
|
|
104
140
|
}
|
package/dist/diagnostics.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diagnostics.js","sourceRoot":"","sources":["../src/diagnostics.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,gBAAgB,CAC9B,QAAgB,EAChB,UAAsB;IAEtB,MAAM,GAAG,GACP,UAAU,CAAC,GAAG,KAAK,SAAS;QAC1B,CAAC,CAAC,EAAE;QACJ,CAAC,CAAC,IAAI,UAAU,CAAC,GAAG,CAAC,IAAI,IAAI,UAAU,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"diagnostics.js","sourceRoot":"","sources":["../src/diagnostics.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"emit-server-stream.d.ts","sourceRoot":"","sources":["../src/emit-server-stream.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAMV,QAAQ,EACT,MAAM,SAAS,CAAC;AACjB,OAAO,KAAK,EAAE,aAAa,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAa1F,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,aAAa,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,uBAAuB;IACtC,iBAAiB,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACpC,eAAe,CAAC,EAAE,mBAAmB,CAAC;IACtC,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,MAAM,CAAC,EAAE,mBAAmB,GAAG,SAAS,CAAC;IACzC,4BAA4B,CAAC,EAAE,MAAM,CAAC;CACvC;
|
|
1
|
+
{"version":3,"file":"emit-server-stream.d.ts","sourceRoot":"","sources":["../src/emit-server-stream.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAMV,QAAQ,EACT,MAAM,SAAS,CAAC;AACjB,OAAO,KAAK,EAAE,aAAa,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAa1F,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,aAAa,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,uBAAuB;IACtC,iBAAiB,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACpC,eAAe,CAAC,EAAE,mBAAmB,CAAC;IACtC,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,MAAM,CAAC,EAAE,mBAAmB,GAAG,SAAS,CAAC;IACzC,4BAA4B,CAAC,EAAE,MAAM,CAAC;CACvC;AAaD,wBAAgB,gBAAgB,CAC9B,EAAE,EAAE,QAAQ,EACZ,OAAO,GAAE,uBAA4B,GACpC,sBAAsB,CAsHxB"}
|
|
@@ -3,6 +3,13 @@ import { escapeHtmlAttribute as escapeHtml } from "@reckona/mreact-shared/html-e
|
|
|
3
3
|
import { htmlAttributeName, isDangerousHtmlAttribute, isStaticUrlValueUnsafe, isUrlAttribute, parseStaticStyleObjectLiteral, parseStyleLiteralValue, simpleSideEffectFreeExpression, } from "./emit-server-shared.js";
|
|
4
4
|
let currentUrlSafeHelperName = "_urlAttrSafe";
|
|
5
5
|
let currentClientBoundaryHelperName;
|
|
6
|
+
let currentStreamNodeHelperName = "_renderStreamNode";
|
|
7
|
+
let currentAsyncBoundaryHelperName = "_renderAsyncBoundary";
|
|
8
|
+
let currentOutOfOrderBoundaryHelperName = "_renderOutOfOrderBoundary";
|
|
9
|
+
let currentReactSuspenseBoundaryHelperName = "_renderReactSuspenseBoundary";
|
|
10
|
+
let currentReactSuspenseOutOfOrderBoundaryHelperName = "_renderReactSuspenseOutOfOrderBoundary";
|
|
11
|
+
let currentCompatRenderToStringHelperName = "_renderCompatToString";
|
|
12
|
+
let currentPropChildrenCollectState;
|
|
6
13
|
export function emitServerStream(ir, options = {}) {
|
|
7
14
|
const serverBootstrap = options.serverBootstrap ?? "none";
|
|
8
15
|
const escapeHelperName = allocateHelperName(ir, "_escapeHtml");
|
|
@@ -15,12 +22,19 @@ export function emitServerStream(ir, options = {}) {
|
|
|
15
22
|
const reactSuspenseBoundaryHelperName = allocateHelperName(ir, "_renderReactSuspenseBoundary");
|
|
16
23
|
const reactSuspenseOutOfOrderBoundaryHelperName = allocateHelperName(ir, "_renderReactSuspenseOutOfOrderBoundary");
|
|
17
24
|
const compatRenderToStringHelperName = allocateHelperName(ir, "_renderCompatToString");
|
|
25
|
+
const streamNodeHelperName = allocateHelperName(ir, "_renderStreamNode");
|
|
18
26
|
const clientBoundaryHelperName = usesClientBoundary(ir)
|
|
19
27
|
? allocateHelperName(ir, "_renderClientBoundary")
|
|
20
28
|
: undefined;
|
|
21
29
|
const urlSafeHelperName = allocateHelperName(ir, "_urlAttrSafe");
|
|
22
30
|
currentUrlSafeHelperName = urlSafeHelperName;
|
|
23
31
|
currentClientBoundaryHelperName = clientBoundaryHelperName;
|
|
32
|
+
currentStreamNodeHelperName = streamNodeHelperName;
|
|
33
|
+
currentAsyncBoundaryHelperName = asyncBoundaryHelperName;
|
|
34
|
+
currentOutOfOrderBoundaryHelperName = outOfOrderBoundaryHelperName;
|
|
35
|
+
currentReactSuspenseBoundaryHelperName = reactSuspenseBoundaryHelperName;
|
|
36
|
+
currentReactSuspenseOutOfOrderBoundaryHelperName = reactSuspenseOutOfOrderBoundaryHelperName;
|
|
37
|
+
currentCompatRenderToStringHelperName = compatRenderToStringHelperName;
|
|
24
38
|
const helper = emitEscapeHtmlHelper(escapeHelperName);
|
|
25
39
|
const urlSafeHelper = [
|
|
26
40
|
`function ${urlSafeHelperName}(name, value) {`,
|
|
@@ -86,8 +100,11 @@ export function emitServerStream(ir, options = {}) {
|
|
|
86
100
|
const clientBoundaryBlock = clientBoundaryHelperName === undefined || !components.includes(clientBoundaryHelperName)
|
|
87
101
|
? ""
|
|
88
102
|
: `\n\n${emitClientBoundaryHelper(clientBoundaryHelperName)}`;
|
|
103
|
+
const streamNodeBlock = components.includes(streamNodeHelperName)
|
|
104
|
+
? `\n\n${emitStreamNodeHelper(streamNodeHelperName)}`
|
|
105
|
+
: "";
|
|
89
106
|
return {
|
|
90
|
-
code: `${importsBlock === "" ? "" : `${importsBlock}\n\n`}${helper}${urlSafeBlock}${clientBoundaryBlock}\n\n${components}\n`,
|
|
107
|
+
code: `${importsBlock === "" ? "" : `${importsBlock}\n\n`}${helper}${urlSafeBlock}${clientBoundaryBlock}${streamNodeBlock}\n\n${components}\n`,
|
|
91
108
|
imports,
|
|
92
109
|
};
|
|
93
110
|
}
|
|
@@ -153,6 +170,17 @@ function emitClientBoundaryHelper(name) {
|
|
|
153
170
|
`}`,
|
|
154
171
|
].join("\n");
|
|
155
172
|
}
|
|
173
|
+
function emitStreamNodeHelper(name) {
|
|
174
|
+
return [
|
|
175
|
+
`async function ${name}($sink, value, escapeHtml) {`,
|
|
176
|
+
` if (value == null || value === false) return;`,
|
|
177
|
+
` if (typeof value === "function") { await value($sink); return; }`,
|
|
178
|
+
` if (Array.isArray(value)) { for (const item of value) await ${name}($sink, item, escapeHtml); return; }`,
|
|
179
|
+
` if (typeof value === "string") { $sink.append(value); return; }`,
|
|
180
|
+
` $sink.append(escapeHtml(value === true ? "" : value));`,
|
|
181
|
+
`}`,
|
|
182
|
+
].join("\n");
|
|
183
|
+
}
|
|
156
184
|
function emitComponent(component, escapeHelperName, asyncBoundaryHelperName, outOfOrderBoundaryHelperName, reorderScriptHelperName, reactSuspenseBoundaryHelperName, reactSuspenseOutOfOrderBoundaryHelperName, compatRenderToStringHelperName, options) {
|
|
157
185
|
const { serverBootstrap, serverBootstrapNonce, serverBootstrapSrc } = options;
|
|
158
186
|
const sinkName = allocateComponentSinkName(component);
|
|
@@ -192,7 +220,7 @@ function emitBootstrapOptions(nonce, src) {
|
|
|
192
220
|
return entries.length === 0 ? "" : `, { ${entries.join(", ")} }`;
|
|
193
221
|
}
|
|
194
222
|
function emitAppendStatements(node, sinkName, escapeHelperName, asyncBoundaryHelperName, outOfOrderBoundaryHelperName, reactSuspenseBoundaryHelperName, reactSuspenseOutOfOrderBoundaryHelperName, compatRenderToStringHelperName, reactSuspenseRevealScriptNonce, reactSuspenseRevealScriptSrc, hydration, awaitHydration, dynamicAttributes, escapeBatchHelperName) {
|
|
195
|
-
const
|
|
223
|
+
const collectState = {
|
|
196
224
|
dynamicAttributes,
|
|
197
225
|
...(escapeBatchHelperName === undefined ? {} : { escapeBatchHelperName }),
|
|
198
226
|
hydration,
|
|
@@ -200,39 +228,50 @@ function emitAppendStatements(node, sinkName, escapeHelperName, asyncBoundaryHel
|
|
|
200
228
|
nextFragmentId: 0,
|
|
201
229
|
...(reactSuspenseRevealScriptNonce === undefined ? {} : { reactSuspenseRevealScriptNonce }),
|
|
202
230
|
...(reactSuspenseRevealScriptSrc === undefined ? {} : { reactSuspenseRevealScriptSrc }),
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
if (part.kind === "react-suspense-boundary") {
|
|
212
|
-
return emitReactSuspenseBoundary(part, sinkName, reactSuspenseBoundaryHelperName, compatRenderToStringHelperName);
|
|
213
|
-
}
|
|
214
|
-
if (part.kind === "react-suspense-out-of-order-boundary") {
|
|
215
|
-
return emitReactSuspenseOutOfOrderBoundary(part, sinkName, reactSuspenseOutOfOrderBoundaryHelperName, compatRenderToStringHelperName);
|
|
216
|
-
}
|
|
217
|
-
if (part.kind === "component") {
|
|
218
|
-
if (part.runtime === "compat") {
|
|
219
|
-
return emitCompatComponentAppendStatements(part, sinkName, compatRenderToStringHelperName, " ");
|
|
231
|
+
};
|
|
232
|
+
const collected = collectHtmlParts(node, escapeHelperName, asyncBoundaryHelperName, outOfOrderBoundaryHelperName, reactSuspenseBoundaryHelperName, reactSuspenseOutOfOrderBoundaryHelperName, collectState);
|
|
233
|
+
const previousPropChildrenCollectState = currentPropChildrenCollectState;
|
|
234
|
+
currentPropChildrenCollectState = collectState;
|
|
235
|
+
try {
|
|
236
|
+
return coalesceAdjacentStaticParts(collected).map((part) => {
|
|
237
|
+
if (part.kind === "async-boundary") {
|
|
238
|
+
return emitAsyncBoundary(part, sinkName, asyncBoundaryHelperName, compatRenderToStringHelperName);
|
|
220
239
|
}
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
240
|
+
if (part.kind === "out-of-order-boundary") {
|
|
241
|
+
return emitOutOfOrderBoundary(part, sinkName, outOfOrderBoundaryHelperName, compatRenderToStringHelperName);
|
|
242
|
+
}
|
|
243
|
+
if (part.kind === "react-suspense-boundary") {
|
|
244
|
+
return emitReactSuspenseBoundary(part, sinkName, reactSuspenseBoundaryHelperName, compatRenderToStringHelperName);
|
|
245
|
+
}
|
|
246
|
+
if (part.kind === "react-suspense-out-of-order-boundary") {
|
|
247
|
+
return emitReactSuspenseOutOfOrderBoundary(part, sinkName, reactSuspenseOutOfOrderBoundaryHelperName, compatRenderToStringHelperName);
|
|
248
|
+
}
|
|
249
|
+
if (part.kind === "component") {
|
|
250
|
+
if (part.runtime === "compat") {
|
|
251
|
+
return emitCompatComponentAppendStatements(part, sinkName, compatRenderToStringHelperName, " ");
|
|
252
|
+
}
|
|
253
|
+
return ` await ${part.name}(${sinkName}, ${emitPropsObject(part.props, part.children, part.escapeHelperName)});`;
|
|
254
|
+
}
|
|
255
|
+
if (part.kind === "react-node") {
|
|
256
|
+
return ` ${sinkName}.append(${compatRenderToStringHelperName}(() => (${part.code})));`;
|
|
257
|
+
}
|
|
258
|
+
if (part.kind === "stream-node") {
|
|
259
|
+
return ` await ${currentStreamNodeHelperName}(${sinkName}, (${part.code}), ${part.escapeHelperName});`;
|
|
260
|
+
}
|
|
261
|
+
if (part.kind === "list") {
|
|
262
|
+
return emitListPart(part, sinkName, compatRenderToStringHelperName, " ");
|
|
263
|
+
}
|
|
264
|
+
const expression = part.kind === "static"
|
|
265
|
+
? stringLiteral(part.value)
|
|
266
|
+
: part.kind === "dynamic"
|
|
267
|
+
? `${escapeHelperName}(${part.code})`
|
|
268
|
+
: part.code;
|
|
269
|
+
return ` ${sinkName}.append(${expression});`;
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
finally {
|
|
273
|
+
currentPropChildrenCollectState = previousPropChildrenCollectState;
|
|
274
|
+
}
|
|
236
275
|
}
|
|
237
276
|
function isHtmlSyncPart(part) {
|
|
238
277
|
return (part.kind !== "async-boundary" &&
|
|
@@ -282,6 +321,9 @@ function emitSyncPartAsAppendStatement(part, sinkName, compatRenderToStringHelpe
|
|
|
282
321
|
if (part.kind === "react-node") {
|
|
283
322
|
return `${indent}${sinkName}.append(${compatRenderToStringHelperName}(() => (${part.code})));`;
|
|
284
323
|
}
|
|
324
|
+
if (part.kind === "stream-node") {
|
|
325
|
+
return `${indent}await ${currentStreamNodeHelperName}(${sinkName}, (${part.code}), ${part.escapeHelperName});`;
|
|
326
|
+
}
|
|
285
327
|
if (part.kind === "list") {
|
|
286
328
|
return emitListPart(part, sinkName, compatRenderToStringHelperName, indent);
|
|
287
329
|
}
|
|
@@ -352,6 +394,9 @@ function tryEmitPartAsStringExpression(part, compatRenderToStringHelperName) {
|
|
|
352
394
|
if (part.kind === "react-node") {
|
|
353
395
|
return `${compatRenderToStringHelperName}(() => (${part.code}))`;
|
|
354
396
|
}
|
|
397
|
+
if (part.kind === "stream-node") {
|
|
398
|
+
return undefined;
|
|
399
|
+
}
|
|
355
400
|
if (part.kind === "list") {
|
|
356
401
|
return emitListPartAsStringExpression(part, compatRenderToStringHelperName);
|
|
357
402
|
}
|
|
@@ -438,6 +483,25 @@ function emitNestedAppendStatements(parts, sinkName, compatRenderToStringHelperN
|
|
|
438
483
|
.map((part) => emitSyncPartAsAppendStatement(part, sinkName, compatRenderToStringHelperName, " "))
|
|
439
484
|
.join("\n");
|
|
440
485
|
}
|
|
486
|
+
function emitNestedStreamAppendStatements(parts, sinkName, compatRenderToStringHelperName) {
|
|
487
|
+
return coalesceAdjacentStaticParts(parts)
|
|
488
|
+
.map((part) => {
|
|
489
|
+
if (part.kind === "async-boundary") {
|
|
490
|
+
return emitAsyncBoundary(part, sinkName, currentAsyncBoundaryHelperName, compatRenderToStringHelperName).replace(/^/gm, " ");
|
|
491
|
+
}
|
|
492
|
+
if (part.kind === "out-of-order-boundary") {
|
|
493
|
+
return emitOutOfOrderBoundary(part, sinkName, currentOutOfOrderBoundaryHelperName, compatRenderToStringHelperName).replace(/^/gm, " ");
|
|
494
|
+
}
|
|
495
|
+
if (part.kind === "react-suspense-boundary") {
|
|
496
|
+
return emitReactSuspenseBoundary(part, sinkName, currentReactSuspenseBoundaryHelperName, compatRenderToStringHelperName).replace(/^/gm, " ");
|
|
497
|
+
}
|
|
498
|
+
if (part.kind === "react-suspense-out-of-order-boundary") {
|
|
499
|
+
return emitReactSuspenseOutOfOrderBoundary(part, sinkName, currentReactSuspenseOutOfOrderBoundaryHelperName, compatRenderToStringHelperName).replace(/^/gm, " ");
|
|
500
|
+
}
|
|
501
|
+
return emitSyncPartAsAppendStatement(part, sinkName, compatRenderToStringHelperName, " ");
|
|
502
|
+
})
|
|
503
|
+
.join("\n");
|
|
504
|
+
}
|
|
441
505
|
function emitCompatComponentAppendStatements(part, sinkName, compatRenderToStringHelperName, indent) {
|
|
442
506
|
const rendered = `${compatRenderToStringHelperName}(${part.name}, ${emitPropsObject(part.props, part.children, part.escapeHelperName)})`;
|
|
443
507
|
const statements = part.hydrationId === undefined
|
|
@@ -458,12 +522,18 @@ function collectHtmlParts(node, escapeHelperName, asyncBoundaryHelperName, outOf
|
|
|
458
522
|
return [{ kind: "static", value: escapeHtml(node.value) }];
|
|
459
523
|
}
|
|
460
524
|
if (node.kind === "expr") {
|
|
525
|
+
if (node.renderMode === "html" && isChildrenExpressionCode(node.code)) {
|
|
526
|
+
return [{ kind: "stream-node", code: node.code, escapeHelperName }];
|
|
527
|
+
}
|
|
461
528
|
if (node.renderMode === "html") {
|
|
462
529
|
return [{ kind: "raw-dynamic", code: rawHtmlExpression(node.code) }];
|
|
463
530
|
}
|
|
464
531
|
if (node.renderMode === "react-node") {
|
|
465
532
|
return [{ kind: "react-node", code: node.code }];
|
|
466
533
|
}
|
|
534
|
+
if (node.renderMode === "stream-node") {
|
|
535
|
+
return [{ kind: "stream-node", code: node.code, escapeHelperName }];
|
|
536
|
+
}
|
|
467
537
|
return [{ kind: "dynamic", code: node.code, escapeHelperName }];
|
|
468
538
|
}
|
|
469
539
|
if (node.kind === "conditional") {
|
|
@@ -636,16 +706,18 @@ function collectHtmlParts(node, escapeHelperName, asyncBoundaryHelperName, outOf
|
|
|
636
706
|
}
|
|
637
707
|
const closeTag = `</${node.tagName}>`;
|
|
638
708
|
if (node.tagName === "textarea") {
|
|
709
|
+
const attributeScan = scanElementAttributes(node.tagName, node.attributes);
|
|
639
710
|
return [
|
|
640
711
|
{ kind: "static", value: "<textarea" },
|
|
641
|
-
...collectElementAttributeParts(node.tagName, node.attributes, escapeHelperName, state),
|
|
712
|
+
...collectElementAttributeParts(node.tagName, node.attributes, escapeHelperName, state, attributeScan),
|
|
642
713
|
{ kind: "static", value: ">" },
|
|
643
|
-
...collectTextareaValueParts(node, escapeHelperName, asyncBoundaryHelperName, outOfOrderBoundaryHelperName, reactSuspenseBoundaryHelperName, reactSuspenseOutOfOrderBoundaryHelperName, state),
|
|
714
|
+
...collectTextareaValueParts(node, escapeHelperName, asyncBoundaryHelperName, outOfOrderBoundaryHelperName, reactSuspenseBoundaryHelperName, reactSuspenseOutOfOrderBoundaryHelperName, state, attributeScan),
|
|
644
715
|
{ kind: "static", value: closeTag },
|
|
645
716
|
];
|
|
646
717
|
}
|
|
718
|
+
const attributeScan = scanElementAttributes(node.tagName, node.attributes);
|
|
647
719
|
const childSelectedValueCode = node.tagName === "select"
|
|
648
|
-
?
|
|
720
|
+
? attributeScan.formValueAttributeCode
|
|
649
721
|
: undefined;
|
|
650
722
|
const childState = childSelectedValueCode === undefined
|
|
651
723
|
? state
|
|
@@ -653,7 +725,7 @@ function collectHtmlParts(node, escapeHelperName, asyncBoundaryHelperName, outOf
|
|
|
653
725
|
const selectedAttributePart = collectOptionSelectedAttributePart(node, state.selectedValueCode);
|
|
654
726
|
return [
|
|
655
727
|
{ kind: "static", value: `<${node.tagName}` },
|
|
656
|
-
...collectElementAttributeParts(node.tagName, node.attributes, escapeHelperName, state),
|
|
728
|
+
...collectElementAttributeParts(node.tagName, node.attributes, escapeHelperName, state, attributeScan),
|
|
657
729
|
...(selectedAttributePart === undefined ? [] : [selectedAttributePart]),
|
|
658
730
|
{ kind: "static", value: ">" },
|
|
659
731
|
...((childState.selectedValueCode === undefined
|
|
@@ -663,6 +735,22 @@ function collectHtmlParts(node, escapeHelperName, asyncBoundaryHelperName, outOf
|
|
|
663
735
|
{ kind: "static", value: closeTag },
|
|
664
736
|
];
|
|
665
737
|
}
|
|
738
|
+
function isChildrenExpressionCode(code) {
|
|
739
|
+
const trimmed = code.trim();
|
|
740
|
+
return (trimmed === "children" ||
|
|
741
|
+
endsWithChildrenMemberAccess(trimmed) ||
|
|
742
|
+
endsWithChildrenStringIndex(trimmed));
|
|
743
|
+
}
|
|
744
|
+
function endsWithChildrenMemberAccess(code) {
|
|
745
|
+
const propertyName = "children";
|
|
746
|
+
if (!code.endsWith(propertyName)) {
|
|
747
|
+
return false;
|
|
748
|
+
}
|
|
749
|
+
return code[code.length - propertyName.length - 1] === ".";
|
|
750
|
+
}
|
|
751
|
+
function endsWithChildrenStringIndex(code) {
|
|
752
|
+
return code.endsWith('["children"]') || code.endsWith("['children']");
|
|
753
|
+
}
|
|
666
754
|
function collectHtmlAttributeParts(tagName, attr, escapeHelperName, escapeBatchHelperName, dynamicAttributes) {
|
|
667
755
|
if (attr.kind === "event" || attr.kind === "spread-attr" || attr.name === "key") {
|
|
668
756
|
return [];
|
|
@@ -705,21 +793,54 @@ function collectHtmlAttributeParts(tagName, attr, escapeHelperName, escapeBatchH
|
|
|
705
793
|
},
|
|
706
794
|
];
|
|
707
795
|
}
|
|
708
|
-
function collectElementAttributeParts(tagName, attrs, escapeHelperName, state) {
|
|
796
|
+
function collectElementAttributeParts(tagName, attrs, escapeHelperName, state, attributeScan = scanElementAttributes(tagName, attrs)) {
|
|
709
797
|
const escapeBatchHelperName = state.escapeBatchHelperName;
|
|
710
|
-
const hasExplicitInputValue = tagName === "input" &&
|
|
711
|
-
attrs.some((attr) => attr.kind !== "spread-attr" && attr.name === "value");
|
|
712
|
-
const hasExplicitInputChecked = tagName === "input" &&
|
|
713
|
-
attrs.some((attr) => attr.kind !== "spread-attr" && attr.name === "checked");
|
|
714
798
|
return attrs.flatMap((attr) => attr.kind !== "spread-attr" &&
|
|
715
799
|
((tagName === "input" &&
|
|
716
|
-
((attr.name === "defaultValue" && hasExplicitInputValue) ||
|
|
717
|
-
(attr.name === "defaultChecked" && hasExplicitInputChecked))) ||
|
|
800
|
+
((attr.name === "defaultValue" && attributeScan.hasExplicitInputValue) ||
|
|
801
|
+
(attr.name === "defaultChecked" && attributeScan.hasExplicitInputChecked))) ||
|
|
718
802
|
((tagName === "textarea" || tagName === "select") &&
|
|
719
803
|
(attr.name === "value" || attr.name === "defaultValue")))
|
|
720
804
|
? []
|
|
721
805
|
: collectHtmlAttributeParts(tagName, attr, escapeHelperName, escapeBatchHelperName, state.dynamicAttributes));
|
|
722
806
|
}
|
|
807
|
+
function scanElementAttributes(tagName, attrs) {
|
|
808
|
+
let hasExplicitInputValue = false;
|
|
809
|
+
let hasExplicitInputChecked = false;
|
|
810
|
+
let valueAttributeCode;
|
|
811
|
+
let defaultValueAttributeCode;
|
|
812
|
+
for (const attr of attrs) {
|
|
813
|
+
if (attr.kind === "spread-attr") {
|
|
814
|
+
continue;
|
|
815
|
+
}
|
|
816
|
+
if (tagName === "input") {
|
|
817
|
+
if (attr.name === "value") {
|
|
818
|
+
hasExplicitInputValue = true;
|
|
819
|
+
}
|
|
820
|
+
else if (attr.name === "checked") {
|
|
821
|
+
hasExplicitInputChecked = true;
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
if ((tagName === "textarea" || tagName === "select") && attr.name === "value") {
|
|
825
|
+
valueAttributeCode = readFormValueAttributeCode(attr);
|
|
826
|
+
}
|
|
827
|
+
else if ((tagName === "textarea" || tagName === "select") &&
|
|
828
|
+
attr.name === "defaultValue") {
|
|
829
|
+
defaultValueAttributeCode = readFormValueAttributeCode(attr);
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
return {
|
|
833
|
+
hasExplicitInputValue,
|
|
834
|
+
hasExplicitInputChecked,
|
|
835
|
+
formValueAttributeCode: valueAttributeCode ?? defaultValueAttributeCode,
|
|
836
|
+
};
|
|
837
|
+
}
|
|
838
|
+
function readFormValueAttributeCode(attr) {
|
|
839
|
+
if (attr.kind === "event") {
|
|
840
|
+
return undefined;
|
|
841
|
+
}
|
|
842
|
+
return attr.kind === "static-attr" ? stringLiteral(attr.value) : `(${attr.code})`;
|
|
843
|
+
}
|
|
723
844
|
function emitDynamicAttributeExpression(name, code, escapeHelperName) {
|
|
724
845
|
if (isUrlAttribute(name)) {
|
|
725
846
|
return `(() => { const _value = (${code}); if (_value == null || _value === false) return ""; const _checked = ${currentUrlSafeHelperName}(${stringLiteral(name)}, _value === true ? "" : _value); return _checked === undefined ? "" : ${stringLiteral(` ${name}="`)} + ${escapeHelperName}(_checked) + ${stringLiteral("\"")}; })()`;
|
|
@@ -765,17 +886,8 @@ function emitStaticStyleObjectAttributeExpression(code, escapeHelperName) {
|
|
|
765
886
|
const statements = entries.map((entry) => `{ const _v = (${entry.valueCode}); if (_v != null && _v !== false) _style += (_style === "" ? "" : ";") + ${stringLiteral(`${entry.cssName}:`)} + ${escapeHelperName}(_v === true ? "" : _v); }`);
|
|
766
887
|
return `(() => { let _style = ""; ${statements.join(" ")} return _style === "" ? "" : ${stringLiteral(" style=\"")} + _style + ${stringLiteral("\"")}; })()`;
|
|
767
888
|
}
|
|
768
|
-
function
|
|
769
|
-
const
|
|
770
|
-
const defaultValueAttr = attrs.find((attr) => attr.kind !== "spread-attr" && attr.name === "defaultValue");
|
|
771
|
-
const attr = valueAttr ?? defaultValueAttr;
|
|
772
|
-
if (attr === undefined || attr.kind === "event" || attr.kind === "spread-attr") {
|
|
773
|
-
return undefined;
|
|
774
|
-
}
|
|
775
|
-
return attr.kind === "static-attr" ? stringLiteral(attr.value) : `(${attr.code})`;
|
|
776
|
-
}
|
|
777
|
-
function collectTextareaValueParts(node, escapeHelperName, asyncBoundaryHelperName, outOfOrderBoundaryHelperName, reactSuspenseBoundaryHelperName, reactSuspenseOutOfOrderBoundaryHelperName, state) {
|
|
778
|
-
const valueCode = findFormValueAttributeCode(node.attributes);
|
|
889
|
+
function collectTextareaValueParts(node, escapeHelperName, asyncBoundaryHelperName, outOfOrderBoundaryHelperName, reactSuspenseBoundaryHelperName, reactSuspenseOutOfOrderBoundaryHelperName, state, attributeScan = scanElementAttributes(node.tagName, node.attributes)) {
|
|
890
|
+
const valueCode = attributeScan.formValueAttributeCode;
|
|
779
891
|
if (valueCode !== undefined) {
|
|
780
892
|
return [{ kind: "dynamic", code: valueCode, escapeHelperName }];
|
|
781
893
|
}
|
|
@@ -960,6 +1072,33 @@ function emitHtmlExpressionFromChildren(children, escapeHelperName) {
|
|
|
960
1072
|
});
|
|
961
1073
|
return expressions.length === 0 ? '""' : expressions.join(" + ");
|
|
962
1074
|
}
|
|
1075
|
+
function emitStreamRendererFromChildren(children, escapeHelperName) {
|
|
1076
|
+
if (children.length === 0) {
|
|
1077
|
+
return undefined;
|
|
1078
|
+
}
|
|
1079
|
+
const parentState = currentPropChildrenCollectState;
|
|
1080
|
+
const childState = {
|
|
1081
|
+
dynamicAttributes: "emit",
|
|
1082
|
+
hydration: false,
|
|
1083
|
+
awaitHydration: false,
|
|
1084
|
+
nextFragmentId: parentState?.nextFragmentId ?? 0,
|
|
1085
|
+
...(parentState?.reactSuspenseRevealScriptNonce === undefined
|
|
1086
|
+
? {}
|
|
1087
|
+
: { reactSuspenseRevealScriptNonce: parentState.reactSuspenseRevealScriptNonce }),
|
|
1088
|
+
...(parentState?.reactSuspenseRevealScriptSrc === undefined
|
|
1089
|
+
? {}
|
|
1090
|
+
: { reactSuspenseRevealScriptSrc: parentState.reactSuspenseRevealScriptSrc }),
|
|
1091
|
+
};
|
|
1092
|
+
const parts = children.flatMap((child) => collectHtmlParts(child, escapeHelperName, currentAsyncBoundaryHelperName, currentOutOfOrderBoundaryHelperName, currentReactSuspenseBoundaryHelperName, currentReactSuspenseOutOfOrderBoundaryHelperName, childState));
|
|
1093
|
+
if (parentState !== undefined) {
|
|
1094
|
+
parentState.nextFragmentId = childState.nextFragmentId;
|
|
1095
|
+
}
|
|
1096
|
+
if (parts.every((part) => isHtmlSyncPart(part) &&
|
|
1097
|
+
tryEmitPartAsStringExpression(part, currentCompatRenderToStringHelperName) !== undefined)) {
|
|
1098
|
+
return undefined;
|
|
1099
|
+
}
|
|
1100
|
+
return `async ($sink) => {\n${emitNestedStreamAppendStatements(parts, "$sink", currentCompatRenderToStringHelperName)}\n}`;
|
|
1101
|
+
}
|
|
963
1102
|
function emitListRenderer(node, parameters, escapeHelperName) {
|
|
964
1103
|
const valueExpression = emitHtmlExpressionFromChildren(node.children, escapeHelperName);
|
|
965
1104
|
if (node.bodyStatements === undefined || node.bodyStatements.length === 0) {
|
|
@@ -994,6 +1133,10 @@ function containsAnyAsyncBoundary(node) {
|
|
|
994
1133
|
if (node.kind === "async-boundary") {
|
|
995
1134
|
return true;
|
|
996
1135
|
}
|
|
1136
|
+
if (node.kind === "expr") {
|
|
1137
|
+
return (node.renderMode === "stream-node" ||
|
|
1138
|
+
(node.renderMode === "html" && isChildrenExpressionCode(node.code)));
|
|
1139
|
+
}
|
|
997
1140
|
if (node.kind === "conditional") {
|
|
998
1141
|
return [...node.whenTrue, ...node.whenFalse].some(containsAnyAsyncBoundary);
|
|
999
1142
|
}
|
|
@@ -1156,7 +1299,8 @@ function emitPropsObject(props, children = [], escapeHelperName = "_escapeHtml")
|
|
|
1156
1299
|
return `${emitPropName(prop.name)}: (${prop.code})`;
|
|
1157
1300
|
});
|
|
1158
1301
|
if (children.length > 0) {
|
|
1159
|
-
entries.push(`children: ${
|
|
1302
|
+
entries.push(`children: ${emitStreamRendererFromChildren(children, escapeHelperName) ??
|
|
1303
|
+
emitHtmlExpressionFromChildren(children, escapeHelperName)}`);
|
|
1160
1304
|
}
|
|
1161
1305
|
return `{ ${entries.join(", ")} }`;
|
|
1162
1306
|
}
|