@reckona/mreact-compiler 0.0.16 → 0.0.17

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.
@@ -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,CAOR;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,GACnB,UAAU,CAQZ"}
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"}
@@ -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
- return `${filename}${loc} [${diagnostic.code}] ${diagnostic.message}`;
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
  }
@@ -1 +1 @@
1
- {"version":3,"file":"diagnostics.js","sourceRoot":"","sources":["../src/diagnostics.ts"],"names":[],"mappings":"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"}
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;AAKD,wBAAgB,gBAAgB,CAC9B,EAAE,EAAE,QAAQ,EACZ,OAAO,GAAE,uBAA4B,GACpC,sBAAsB,CA4GxB"}
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 collected = collectHtmlParts(node, escapeHelperName, asyncBoundaryHelperName, outOfOrderBoundaryHelperName, reactSuspenseBoundaryHelperName, reactSuspenseOutOfOrderBoundaryHelperName, {
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
- return coalesceAdjacentStaticParts(collected).map((part) => {
205
- if (part.kind === "async-boundary") {
206
- return emitAsyncBoundary(part, sinkName, asyncBoundaryHelperName, compatRenderToStringHelperName);
207
- }
208
- if (part.kind === "out-of-order-boundary") {
209
- return emitOutOfOrderBoundary(part, sinkName, outOfOrderBoundaryHelperName, compatRenderToStringHelperName);
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
- return ` await ${part.name}(${sinkName}, ${emitPropsObject(part.props, part.children, part.escapeHelperName)});`;
222
- }
223
- if (part.kind === "react-node") {
224
- return ` ${sinkName}.append(${compatRenderToStringHelperName}(() => (${part.code})));`;
225
- }
226
- if (part.kind === "list") {
227
- return emitListPart(part, sinkName, compatRenderToStringHelperName, " ");
228
- }
229
- const expression = part.kind === "static"
230
- ? stringLiteral(part.value)
231
- : part.kind === "dynamic"
232
- ? `${escapeHelperName}(${part.code})`
233
- : part.code;
234
- return ` ${sinkName}.append(${expression});`;
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
- ? findFormValueAttributeCode(node.attributes)
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 findFormValueAttributeCode(attrs) {
769
- const valueAttr = attrs.find((attr) => attr.kind !== "spread-attr" && attr.name === "value");
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: ${emitHtmlExpressionFromChildren(children, escapeHelperName)}`);
1302
+ entries.push(`children: ${emitStreamRendererFromChildren(children, escapeHelperName) ??
1303
+ emitHtmlExpressionFromChildren(children, escapeHelperName)}`);
1160
1304
  }
1161
1305
  return `{ ${entries.join(", ")} }`;
1162
1306
  }