@reckona/mreact-compiler 0.0.120 → 0.0.121

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.
@@ -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;AAwB1F,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;AAcD,wBAAgB,gBAAgB,CAC9B,EAAE,EAAE,QAAQ,EACZ,OAAO,GAAE,uBAA4B,GACpC,sBAAsB,CAqIxB"}
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;AAwB1F,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;AAcD,wBAAgB,gBAAgB,CAC9B,EAAE,EAAE,QAAQ,EACZ,OAAO,GAAE,uBAA4B,GACpC,sBAAsB,CAsIxB"}
@@ -17,9 +17,7 @@ let currentPropChildrenCollectState;
17
17
  export function emitServerStream(ir, options = {}) {
18
18
  const serverBootstrap = options.serverBootstrap ?? "none";
19
19
  const escapeHelperName = allocateHelperName(ir, "_escapeHtml");
20
- const escapeBatchHelperName = options.escape === undefined
21
- ? undefined
22
- : allocateHelperName(ir, "_escapeHtmlBatch");
20
+ const escapeBatchHelperName = options.escape === undefined ? undefined : allocateHelperName(ir, "_escapeHtmlBatch");
23
21
  const asyncBoundaryHelperName = allocateHelperName(ir, "_renderAsyncBoundary");
24
22
  const outOfOrderBoundaryHelperName = allocateHelperName(ir, "_renderOutOfOrderBoundary");
25
23
  const reorderScriptHelperName = allocateHelperName(ir, "_renderOutOfOrderReorderScript");
@@ -101,7 +99,9 @@ export function emitServerStream(ir, options = {}) {
101
99
  .join("\n");
102
100
  const userImports = emitUserImports(ir);
103
101
  const moduleStatements = emitModuleStatements(ir);
104
- const importsBlock = [importLine, escapeImport, userImports, moduleStatements].filter(Boolean).join("\n");
102
+ const importsBlock = [importLine, escapeImport, userImports, moduleStatements]
103
+ .filter(Boolean)
104
+ .join("\n");
105
105
  const needsSpreadAttributesHelper = components.includes(spreadAttributesHelperName);
106
106
  const urlSafeBlock = components.includes(urlSafeHelperName) || needsSpreadAttributesHelper ? urlSafeHelper : "";
107
107
  const clientBoundaryBlock = clientBoundaryHelperName === undefined || !components.includes(clientBoundaryHelperName)
@@ -319,7 +319,11 @@ function emitComponent(component, escapeHelperName, asyncBoundaryHelperName, out
319
319
  const hydrationEndStatements = options.serverHydration === true
320
320
  ? [` ${sinkName}.append(${stringLiteral(`<!--mreact-h:end:${markerId}-->`)});`]
321
321
  : [];
322
- const exportPrefix = component.exportDefault === true ? "export default " : component.exported === false ? "" : "export ";
322
+ const exportPrefix = component.exportDefault === true
323
+ ? "export default "
324
+ : component.exported === false
325
+ ? ""
326
+ : "export ";
323
327
  const asyncPrefix = component.async === true || containsAnyAsyncBoundary(component.root) ? "async " : "";
324
328
  const functionKeyword = `${exportPrefix}${asyncPrefix}function`;
325
329
  return [
@@ -543,9 +547,7 @@ function emitListPart(part, sinkName, compatRenderToStringHelperName, indent) {
543
547
  ].join("\n");
544
548
  }
545
549
  const childLines = syncCoalescedParts === undefined
546
- ? [
547
- emitNestedStreamAppendStatements(coalescedParts, sinkName, compatRenderToStringHelperName),
548
- ]
550
+ ? [emitNestedStreamAppendStatements(coalescedParts, sinkName, compatRenderToStringHelperName)]
549
551
  : syncCoalescedParts.map((child) => emitSyncPartAsAppendStatement(child, sinkName, compatRenderToStringHelperName, innerIndent));
550
552
  return [
551
553
  `${indent}{`,
@@ -591,7 +593,7 @@ function tryEmitPartAsStringExpression(part, compatRenderToStringHelperName) {
591
593
  return `${stringLiteral(`<!--mreact-h:start:${encodeURIComponent(part.hydrationId)}-->`)} + ${rendered} + ${stringLiteral(`<!--mreact-h:end:${encodeURIComponent(part.hydrationId)}-->`)}`;
592
594
  }
593
595
  if (part.kind === "component" && part.hydrationId === undefined) {
594
- return `${part.name}(${emitPropsObject(part.props, part.children, part.escapeHelperName)})`;
596
+ return emitRenderableHtmlExpression(`${part.name}(${emitPropsObject(part.props, part.children, part.escapeHelperName)})`);
595
597
  }
596
598
  // Non-compat component parts require `await sink-write`; lists with
597
599
  // sink-needing children also can't collapse. Signal fallback.
@@ -732,9 +734,7 @@ function collectHtmlParts(node, escapeHelperName, asyncBoundaryHelperName, outOf
732
734
  ...(node.placeholderTagCode === undefined
733
735
  ? {}
734
736
  : { placeholderTagCode: node.placeholderTagCode }),
735
- ...(state.awaitHydration && node.awaitId !== undefined
736
- ? { awaitId: node.awaitId }
737
- : {}),
737
+ ...(state.awaitHydration && node.awaitId !== undefined ? { awaitId: node.awaitId } : {}),
738
738
  ...(node.catchName === undefined || node.catchChildren === undefined
739
739
  ? {}
740
740
  : {
@@ -750,9 +750,7 @@ function collectHtmlParts(node, escapeHelperName, asyncBoundaryHelperName, outOf
750
750
  valueCode: node.valueCode,
751
751
  valueName: node.valueName,
752
752
  parts: node.children.flatMap((child) => collectHtmlParts(child, escapeHelperName, asyncBoundaryHelperName, outOfOrderBoundaryHelperName, reactSuspenseBoundaryHelperName, reactSuspenseOutOfOrderBoundaryHelperName, state)),
753
- ...(state.awaitHydration && node.awaitId !== undefined
754
- ? { awaitId: node.awaitId }
755
- : {}),
753
+ ...(state.awaitHydration && node.awaitId !== undefined ? { awaitId: node.awaitId } : {}),
756
754
  ...(node.catchName === undefined || node.catchChildren === undefined
757
755
  ? {}
758
756
  : {
@@ -826,10 +824,14 @@ function collectHtmlParts(node, escapeHelperName, asyncBoundaryHelperName, outOf
826
824
  if (isClientBoundaryPlaceholder(node, state.hydration)) {
827
825
  const helperName = currentClientBoundaryHelperName;
828
826
  if (helperName !== undefined) {
827
+ const boundaryProps = emitPropsObject(node.props, [], escapeHelperName);
828
+ const fallbackHtml = shouldRenderClientBoundaryFallback(node)
829
+ ? `${node.name}(${boundaryProps})`
830
+ : emitHtmlExpressionFromChildren(node.children, escapeHelperName);
829
831
  return [
830
832
  {
831
833
  kind: "raw-dynamic",
832
- code: `${helperName}(${stringLiteral(node.name)}, ${emitPropsObject(node.props, [], escapeHelperName)}, ${emitHtmlExpressionFromChildren(node.children, escapeHelperName)})`,
834
+ code: `${helperName}(${stringLiteral(node.name)}, ${boundaryProps}, ${fallbackHtml})`,
833
835
  },
834
836
  ];
835
837
  }
@@ -862,9 +864,7 @@ function collectHtmlParts(node, escapeHelperName, asyncBoundaryHelperName, outOf
862
864
  ];
863
865
  }
864
866
  const attributeScan = scanElementAttributes(node.tagName, node.attributes);
865
- const childSelectedValueCode = node.tagName === "select"
866
- ? attributeScan.formValueAttributeCode
867
- : undefined;
867
+ const childSelectedValueCode = node.tagName === "select" ? attributeScan.formValueAttributeCode : undefined;
868
868
  const childState = childSelectedValueCode === undefined
869
869
  ? state
870
870
  : { ...state, selectedValueCode: childSelectedValueCode };
@@ -872,10 +872,10 @@ function collectHtmlParts(node, escapeHelperName, asyncBoundaryHelperName, outOf
872
872
  const dangerousInnerHtml = emitDangerouslySetInnerHtmlPart(node.attributes);
873
873
  const childrenParts = dangerousInnerHtml !== undefined
874
874
  ? [dangerousInnerHtml]
875
- : (childState.selectedValueCode === undefined
875
+ : ((childState.selectedValueCode === undefined
876
876
  ? collectBatchedSimpleChildrenParts(node.children, state.escapeBatchHelperName)
877
877
  : undefined) ??
878
- node.children.flatMap((child) => collectHtmlParts(child, escapeHelperName, asyncBoundaryHelperName, outOfOrderBoundaryHelperName, reactSuspenseBoundaryHelperName, reactSuspenseOutOfOrderBoundaryHelperName, childState));
878
+ node.children.flatMap((child) => collectHtmlParts(child, escapeHelperName, asyncBoundaryHelperName, outOfOrderBoundaryHelperName, reactSuspenseBoundaryHelperName, reactSuspenseOutOfOrderBoundaryHelperName, childState)));
879
879
  return [
880
880
  { kind: "static", value: `<${node.tagName}` },
881
881
  ...collectElementAttributeParts(node.tagName, node.attributes, escapeHelperName, state, attributeScan),
@@ -945,14 +945,19 @@ function collectHtmlAttributeParts(tagName, attr, escapeHelperName, escapeBatchH
945
945
  return [];
946
946
  }
947
947
  if (attr.name === "style") {
948
- return [{ kind: "raw-dynamic", code: emitDynamicStyleAttributeExpression(attr.code, escapeHelperName, escapeBatchHelperName) }];
948
+ return [
949
+ {
950
+ kind: "raw-dynamic",
951
+ code: emitDynamicStyleAttributeExpression(attr.code, escapeHelperName, escapeBatchHelperName),
952
+ },
953
+ ];
949
954
  }
950
955
  const dynamicHtmlName = htmlAttributeNameForElement(tagName, attr.name);
951
956
  if (isDangerousHtmlAttribute(dynamicHtmlName)) {
952
957
  return [
953
958
  {
954
959
  kind: "raw-dynamic",
955
- code: `(() => { const _value = (${attr.code}); if (_value == null || _value === false) return ""; if (typeof _value === "object" && _value !== null && typeof _value.__html === "string") return ${stringLiteral(` ${dynamicHtmlName}="`)} + ${escapeHelperName}(_value.__html) + ${stringLiteral("\"")}; return ""; })()`,
960
+ code: `(() => { const _value = (${attr.code}); if (_value == null || _value === false) return ""; if (typeof _value === "object" && _value !== null && typeof _value.__html === "string") return ${stringLiteral(` ${dynamicHtmlName}="`)} + ${escapeHelperName}(_value.__html) + ${stringLiteral('"')}; return ""; })()`,
956
961
  },
957
962
  ];
958
963
  }
@@ -1023,8 +1028,7 @@ function scanElementAttributes(tagName, attrs) {
1023
1028
  if ((tagName === "textarea" || tagName === "select") && attr.name === "value") {
1024
1029
  valueAttributeCode = readFormValueAttributeCode(attr);
1025
1030
  }
1026
- else if ((tagName === "textarea" || tagName === "select") &&
1027
- attr.name === "defaultValue") {
1031
+ else if ((tagName === "textarea" || tagName === "select") && attr.name === "defaultValue") {
1028
1032
  defaultValueAttributeCode = readFormValueAttributeCode(attr);
1029
1033
  }
1030
1034
  }
@@ -1042,14 +1046,14 @@ function readFormValueAttributeCode(attr) {
1042
1046
  }
1043
1047
  function emitDynamicAttributeExpression(name, code, escapeHelperName) {
1044
1048
  if (isUrlAttribute(name)) {
1045
- 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("\"")}; })()`;
1049
+ 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('"')}; })()`;
1046
1050
  }
1047
1051
  const inlineExpr = simpleSideEffectFreeExpression(code);
1048
1052
  if (inlineExpr !== undefined) {
1049
1053
  // Inline 3 evaluations to avoid per-attribute IIFE closure allocation.
1050
- return `(${inlineExpr} == null || ${inlineExpr} === false ? "" : ${stringLiteral(` ${name}="`)} + ${escapeHelperName}(${inlineExpr} === true ? "" : ${inlineExpr}) + ${stringLiteral("\"")})`;
1054
+ return `(${inlineExpr} == null || ${inlineExpr} === false ? "" : ${stringLiteral(` ${name}="`)} + ${escapeHelperName}(${inlineExpr} === true ? "" : ${inlineExpr}) + ${stringLiteral('"')})`;
1051
1055
  }
1052
- return `(() => { const _value = (${code}); return _value == null || _value === false ? "" : ${stringLiteral(` ${name}="`)} + ${escapeHelperName}(_value === true ? "" : _value) + ${stringLiteral("\"")}; })()`;
1056
+ return `(() => { const _value = (${code}); return _value == null || _value === false ? "" : ${stringLiteral(` ${name}="`)} + ${escapeHelperName}(_value === true ? "" : _value) + ${stringLiteral('"')}; })()`;
1053
1057
  }
1054
1058
  function emitDynamicStyleAttributeExpression(code, escapeHelperName, escapeBatchHelperName) {
1055
1059
  const staticStyleExpression = emitStaticStyleObjectAttributeExpression(code, escapeHelperName);
@@ -1059,7 +1063,7 @@ function emitDynamicStyleAttributeExpression(code, escapeHelperName, escapeBatch
1059
1063
  const escapedPair = escapeBatchHelperName === undefined
1060
1064
  ? `${escapeHelperName}(_cssName) + ":" + ${escapeHelperName}(_styleValue === true ? "" : _styleValue)`
1061
1065
  : `(() => { const _escaped = ${escapeBatchHelperName}([_cssName, _styleValue === true ? "" : _styleValue]); return _escaped[0] + ":" + _escaped[1]; })()`;
1062
- return `(() => { const _value = (${code}); if (_value == null || _value === false) return ""; if (typeof _value === "string") { const _style = ${escapeHelperName}(_value); return _style === "" ? "" : ${stringLiteral(" style=\"")} + _style + ${stringLiteral("\"")}; } const _style = Object.entries(_value).filter(([, _styleValue]) => _styleValue != null && _styleValue !== false).map(([_styleName, _styleValue]) => { const _cssName = String(_styleName).startsWith("--") ? String(_styleName) : String(_styleName).replace(/[A-Z]/g, (_char) => "-" + _char.toLowerCase()); return ${escapedPair}; }).join(";"); return _style === "" ? "" : ${stringLiteral(" style=\"")} + _style + ${stringLiteral("\"")}; })()`;
1066
+ return `(() => { const _value = (${code}); if (_value == null || _value === false) return ""; if (typeof _value === "string") { const _style = ${escapeHelperName}(_value); return _style === "" ? "" : ${stringLiteral(' style="')} + _style + ${stringLiteral('"')}; } const _style = Object.entries(_value).filter(([, _styleValue]) => _styleValue != null && _styleValue !== false).map(([_styleName, _styleValue]) => { const _cssName = String(_styleName).startsWith("--") ? String(_styleName) : String(_styleName).replace(/[A-Z]/g, (_char) => "-" + _char.toLowerCase()); return ${escapedPair}; }).join(";"); return _style === "" ? "" : ${stringLiteral(' style="')} + _style + ${stringLiteral('"')}; })()`;
1063
1067
  }
1064
1068
  function emitStaticStyleObjectAttributeExpression(code, escapeHelperName) {
1065
1069
  const entries = parseStaticStyleObjectLiteral(code);
@@ -1083,7 +1087,7 @@ function emitStaticStyleObjectAttributeExpression(code, escapeHelperName) {
1083
1087
  return stringLiteral(` style="${parts.join(";")}"`);
1084
1088
  }
1085
1089
  const statements = entries.map((entry) => `{ const _v = (${entry.valueCode}); if (_v != null && _v !== false) _style += (_style === "" ? "" : ";") + ${stringLiteral(`${entry.cssName}:`)} + ${escapeHelperName}(_v === true ? "" : _v); }`);
1086
- return `(() => { let _style = ""; ${statements.join(" ")} return _style === "" ? "" : ${stringLiteral(" style=\"")} + _style + ${stringLiteral("\"")}; })()`;
1090
+ return `(() => { let _style = ""; ${statements.join(" ")} return _style === "" ? "" : ${stringLiteral(' style="')} + _style + ${stringLiteral('"')}; })()`;
1087
1091
  }
1088
1092
  function collectTextareaValueParts(node, escapeHelperName, asyncBoundaryHelperName, outOfOrderBoundaryHelperName, reactSuspenseBoundaryHelperName, reactSuspenseOutOfOrderBoundaryHelperName, state, attributeScan = scanElementAttributes(node.tagName, node.attributes)) {
1089
1093
  const valueCode = attributeScan.formValueAttributeCode;
@@ -1108,7 +1112,9 @@ function collectOptionSelectedAttributePart(node, selectedValueCode) {
1108
1112
  function findOptionValueCode(node) {
1109
1113
  const valueAttr = node.attributes.find((attr) => attr.kind !== "spread-attr" && attr.name === "value");
1110
1114
  if (valueAttr !== undefined && valueAttr.kind !== "event" && valueAttr.kind !== "spread-attr") {
1111
- return valueAttr.kind === "static-attr" ? stringLiteral(valueAttr.value) : `(${valueAttr.code})`;
1115
+ return valueAttr.kind === "static-attr"
1116
+ ? stringLiteral(valueAttr.value)
1117
+ : `(${valueAttr.code})`;
1112
1118
  }
1113
1119
  return node.children.every((child) => child.kind === "text")
1114
1120
  ? stringLiteral(node.children.map((child) => child.value).join(""))
@@ -1247,7 +1253,9 @@ function collectBatchedSimpleChildrenParts(children, escapeBatchHelperName) {
1247
1253
  return undefined;
1248
1254
  }
1249
1255
  if (children.some((child) => child.kind !== "text" &&
1250
- !(child.kind === "expr" && child.renderMode !== "html" && child.renderMode !== "react-node"))) {
1256
+ !(child.kind === "expr" &&
1257
+ child.renderMode !== "html" &&
1258
+ child.renderMode !== "react-node"))) {
1251
1259
  return undefined;
1252
1260
  }
1253
1261
  const values = dynamicChildren.map((child) => child.code);
@@ -1278,7 +1286,7 @@ function emitHtmlExpressionFromChildren(children, escapeHelperName) {
1278
1286
  nextFragmentId: 0,
1279
1287
  }));
1280
1288
  const expressions = parts.map((part) => isHtmlSyncPart(part)
1281
- ? tryEmitPartAsStringExpression(part, currentCompatRenderToStringHelperName) ?? '""'
1289
+ ? (tryEmitPartAsStringExpression(part, currentCompatRenderToStringHelperName) ?? '""')
1282
1290
  : '""');
1283
1291
  return expressions.length === 0 ? '""' : expressions.join(" + ");
1284
1292
  }
@@ -1557,7 +1565,14 @@ function isClientBoundaryPlaceholder(node, serverHydration = true) {
1557
1565
  return node.clientReference !== undefined && (!serverHydration || !isCompatClientReference(node));
1558
1566
  }
1559
1567
  function isCompatClientReference(node) {
1560
- return node.clientReference !== undefined && /\.(?:compat)\.[cm]?[jt]sx?$/.test(node.clientReference.moduleId);
1568
+ return (node.clientReference !== undefined &&
1569
+ /\.(?:compat)\.[cm]?[jt]sx?$/.test(node.clientReference.moduleId));
1570
+ }
1571
+ function emitRenderableHtmlExpression(code) {
1572
+ return `((_value) => _value == null || typeof _value === "boolean" ? "" : _value)(${code})`;
1573
+ }
1574
+ function shouldRenderClientBoundaryFallback(node) {
1575
+ return node.clientReference?.ssrFallback === true;
1561
1576
  }
1562
1577
  function clientBoundaryPlaceholder(node) {
1563
1578
  return `<!--mreact-client-boundary:${escapeHtml(node.name)}-->`;