@reckona/mreact-compiler 0.0.161 → 0.0.163

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/oxc.js CHANGED
@@ -13,7 +13,7 @@ import { collectOxcAsyncComponentNames, collectOxcExportedComponents, collectOxc
13
13
  import { collectOxcClientBoundaryImportComponents, collectOxcCompatReactNodeComponentReferences, collectOxcCompatRuntimeImportComponents, markOxcAsyncComponentReferences, markOxcClientReferences, markOxcCompatReactNodeReferences, markOxcCompatRuntimeReferences, } from "./oxc-component-references.js";
14
14
  import { normalizeOxcExpressionCode, stripOxcGeneratedImports } from "./oxc-code-utils.js";
15
15
  import { analyzeOxcExpressionChild, analyzeOxcJsxNode, } from "./oxc-child-analysis.js";
16
- import { analyzeCompatCreateElementRoot, collectCompatCreateElementNames, collectFunctionShadowedNames, hasLowerableCompatCreateElementReturn, } from "./oxc-compat-create-element.js";
16
+ import { analyzeCompatCreateElementFunctionRoot, analyzeCompatCreateElementRoot, collectCompatCreateElementNames, collectCompatRenderToStringNames, collectFunctionShadowedNames, hasLowerableCompatCreateElementReturn, } from "./oxc-compat-create-element.js";
17
17
  import { lowerOxcDomNodeExpression } from "./oxc-dom-lowering.js";
18
18
  import { lowerOxcCompatObjectExpression, lowerOxcCompatReactNodeExpression, lowerOxcNestedJsxExpression, lowerOxcServerStringExpression, } from "./oxc-nested-lowering.js";
19
19
  import { isOxcJsxBranch, readOxcReturnExpressionFromStatement } from "./oxc-expression-utils.js";
@@ -111,10 +111,13 @@ function analyzeOxcToIr(code, program, target, options) {
111
111
  ? collectOxcCompatReactNodeComponentReferences(program)
112
112
  : undefined;
113
113
  const localJsxReturnFunctionNames = target === "server" ? collectOxcLocalJsxReturnFunctionNames(program) : new Set();
114
- // Stream emit keeps interpreting compat trees for now; only the string
115
- // pipeline lowers createElement calls.
116
- const compatCreateElementNames = target === "server" && options?.serverOutput !== "stream"
117
- ? collectCompatCreateElementNames(program)
114
+ const compatCreateElementNames = target === "server" ? collectCompatCreateElementNames(program) : new Set();
115
+ const compatRenderToStringNames = target === "server" ? collectCompatRenderToStringNames(program) : new Set();
116
+ const compatCreateElementLocalFunctionLikes = target === "server"
117
+ ? collectCompatCreateElementLocalFunctionLikes(program)
118
+ : new Map();
119
+ const compatRenderToStringLowerableTargets = target === "server"
120
+ ? collectCompatRenderToStringLowerableTargets(code, body, compatCreateElementNames, compatRenderToStringNames, compatCreateElementLocalFunctionLikes)
118
121
  : new Set();
119
122
  const localJsxHelperHtmlParameters = target === "server"
120
123
  ? collectLocalJsxHelperHtmlParameters(program, localJsxReturnFunctionNames)
@@ -136,7 +139,7 @@ function analyzeOxcToIr(code, program, target, options) {
136
139
  continue;
137
140
  }
138
141
  if (isOxcJsxComponentStatement(statement, localJsxReturnFunctionNames) ||
139
- isCompatCreateElementComponentStatement(code, statement, compatCreateElementNames) ||
142
+ isCompatCreateElementComponentStatement(code, statement, compatCreateElementNames, compatRenderToStringNames, compatCreateElementLocalFunctionLikes, compatRenderToStringLowerableTargets, options?.serverOutput) ||
140
143
  (options?.compatReactNodeReturn === true && isOxcExportedFunctionLike(statement))) {
141
144
  const declaration = readObject(readObject(statement).declaration);
142
145
  if (declaration.type === "VariableDeclaration") {
@@ -174,7 +177,7 @@ function analyzeOxcToIr(code, program, target, options) {
174
177
  const componentNames = componentNamesFromProgram(program, moduleBindingNames);
175
178
  const componentCallNames = options?.serverOutput === "stream" ? componentCallNamesFromProgram(program) : undefined;
176
179
  const asyncComponentNames = collectOxcAsyncComponentNames(program);
177
- const components = body.flatMap((statement) => analyzeOxcComponent(code, statement, componentNames, target, diagnostics, options?.bodyStatementJsx ?? "dom-node", compatCreateElementNames, moduleRenderValueBindings, options?.compatReactNodeReturn === true, options?.serverOutput, componentCallNames, bodyLowerers, reactiveDerivedFunctionNames, localJsxReturnFunctionNames, localJsxHelperHtmlParameters));
180
+ const components = body.flatMap((statement) => analyzeOxcComponent(code, statement, componentNames, target, diagnostics, options?.bodyStatementJsx ?? "dom-node", compatCreateElementNames, compatRenderToStringNames, compatCreateElementLocalFunctionLikes, compatRenderToStringLowerableTargets, moduleRenderValueBindings, options?.compatReactNodeReturn === true, options?.serverOutput, componentCallNames, bodyLowerers, reactiveDerivedFunctionNames, localJsxReturnFunctionNames, localJsxHelperHtmlParameters));
178
181
  for (const component of components) {
179
182
  markOxcAsyncComponentReferences(component.root, asyncComponentNames);
180
183
  markOxcClientReferences(component.root, clientBoundaryImports);
@@ -305,47 +308,198 @@ function readCompatCreateElementPlainComponent(code, statement, names) {
305
308
  }
306
309
  return undefined;
307
310
  }
308
- function isCompatCreateElementComponentStatement(code, statement, names) {
309
- if (names.size === 0) {
311
+ function collectCompatCreateElementLocalFunctionLikes(program) {
312
+ const functionLikes = new Map();
313
+ for (const statement of readArray(readObject(program).body)) {
314
+ const object = readObject(statement);
315
+ const declaration = object.type === "ExportNamedDeclaration" ? readObject(object.declaration) : object;
316
+ if (declaration.type === "FunctionDeclaration") {
317
+ const id = readObject(declaration.id);
318
+ if (typeof id.name === "string") {
319
+ functionLikes.set(id.name, declaration);
320
+ }
321
+ continue;
322
+ }
323
+ if (declaration.type !== "VariableDeclaration") {
324
+ continue;
325
+ }
326
+ for (const declarator of readArray(declaration.declarations)) {
327
+ const declaratorObject = readObject(declarator);
328
+ const id = readObject(declaratorObject.id);
329
+ const initializer = unwrapOxcComponentFunctionLikeInitializer(readObject(declaratorObject.init));
330
+ if (typeof id.name === "string" && initializer !== undefined) {
331
+ functionLikes.set(id.name, initializer);
332
+ }
333
+ }
334
+ }
335
+ return functionLikes;
336
+ }
337
+ function collectCompatRenderToStringLowerableTargets(code, body, createElementNames, renderToStringNames, localFunctionLikes) {
338
+ const targets = new Set();
339
+ if (createElementNames.size === 0 || renderToStringNames.size === 0) {
340
+ return targets;
341
+ }
342
+ for (const statement of body) {
343
+ const functionLike = unwrapOxcStatementFunctionLike(statement);
344
+ if (functionLike === undefined) {
345
+ continue;
346
+ }
347
+ const targetName = readCompatRenderToStringWrapperTargetName(code, functionLike, renderToStringNames);
348
+ const targetFunctionLike = targetName === undefined ? undefined : localFunctionLikes.get(targetName);
349
+ if (targetName !== undefined &&
350
+ targetFunctionLike !== undefined &&
351
+ analyzeCompatCreateElementFunctionRoot(code, targetFunctionLike, createElementNames) !==
352
+ undefined) {
353
+ targets.add(targetName);
354
+ }
355
+ }
356
+ return targets;
357
+ }
358
+ function unwrapOxcStatementFunctionLike(statement) {
359
+ const object = readObject(statement);
360
+ const declaration = object.type === "ExportNamedDeclaration" || object.type === "ExportDefaultDeclaration"
361
+ ? readObject(object.declaration)
362
+ : object;
363
+ if (declaration.type === "FunctionDeclaration") {
364
+ return declaration;
365
+ }
366
+ if (declaration.type !== "VariableDeclaration") {
367
+ return unwrapOxcComponentFunctionLikeInitializer(declaration);
368
+ }
369
+ for (const declarator of readArray(declaration.declarations)) {
370
+ const initializer = unwrapOxcComponentFunctionLikeInitializer(readObject(readObject(declarator).init));
371
+ if (initializer !== undefined) {
372
+ return initializer;
373
+ }
374
+ }
375
+ return undefined;
376
+ }
377
+ function readCompatRenderToStringWrapperTargetName(code, functionLike, renderToStringNames) {
378
+ const expression = readCompatRenderToStringWrapperReturnExpression(functionLike);
379
+ if (expression === undefined) {
380
+ return undefined;
381
+ }
382
+ return readCompatRenderToStringTargetName(expression, renderToStringNames, collectFunctionShadowedNames(functionLike, renderToStringNames));
383
+ }
384
+ function readCompatRenderToStringWrapperReturnExpression(functionLike) {
385
+ const body = unwrapOxcParentheses(readObject(functionLike.body));
386
+ if (body.type !== "BlockStatement") {
387
+ return body;
388
+ }
389
+ for (const statement of readArray(body.body)) {
390
+ const statementObject = readObject(statement);
391
+ if (statementObject.type === "ReturnStatement") {
392
+ return unwrapOxcParentheses(readObject(statementObject.argument));
393
+ }
394
+ }
395
+ return undefined;
396
+ }
397
+ function readCompatRenderToStringTargetName(expression, renderToStringNames, shadowedNames) {
398
+ if (renderToStringNames.size === 0 ||
399
+ expression.type !== "CallExpression" ||
400
+ expression.optional === true) {
401
+ return undefined;
402
+ }
403
+ const callee = unwrapOxcParentheses(readObject(expression.callee));
404
+ if (callee.type !== "Identifier" ||
405
+ typeof callee.name !== "string" ||
406
+ !renderToStringNames.has(callee.name) ||
407
+ shadowedNames.has(callee.name)) {
408
+ return undefined;
409
+ }
410
+ const args = readArray(expression.arguments);
411
+ if (args.length !== 1) {
412
+ return undefined;
413
+ }
414
+ const target = unwrapOxcParentheses(readObject(args[0]));
415
+ return target.type === "Identifier" && typeof target.name === "string" ? target.name : undefined;
416
+ }
417
+ function hasCompatRenderToStringWrapperReturn(code, functionLike, renderToStringNames) {
418
+ return (readCompatRenderToStringWrapperTargetName(code, functionLike, renderToStringNames) !== undefined);
419
+ }
420
+ function analyzeCompatRenderToStringWrapperRoot(code, functionLike, returnExpression, createElementNames, renderToStringNames, localFunctionLikes) {
421
+ const targetName = readCompatRenderToStringTargetName(returnExpression, renderToStringNames, collectFunctionShadowedNames(functionLike, renderToStringNames));
422
+ if (targetName === undefined) {
423
+ return undefined;
424
+ }
425
+ const targetFunctionLike = localFunctionLikes.get(targetName);
426
+ const lowered = targetFunctionLike === undefined
427
+ ? undefined
428
+ : analyzeCompatCreateElementFunctionRoot(code, targetFunctionLike, createElementNames);
429
+ if (lowered !== undefined) {
430
+ return lowered;
431
+ }
432
+ return {
433
+ kind: "expr",
434
+ code: normalizeOxcExpressionCode(readSource(code, returnExpression)),
435
+ renderMode: "html",
436
+ };
437
+ }
438
+ function isCompatCreateElementComponentStatement(code, statement, names, renderToStringNames, localFunctionLikes, renderToStringLowerableTargets, serverOutput) {
439
+ if (names.size === 0 && renderToStringNames.size === 0) {
310
440
  return false;
311
441
  }
312
442
  const object = readObject(statement);
313
443
  if (object.type === "ExportDefaultDeclaration") {
314
- return readCompatCreateElementFunctionLike(code, readObject(object.declaration), names) !== undefined;
444
+ const functionLike = unwrapOxcComponentFunctionLikeInitializer(readObject(object.declaration));
445
+ return (readCompatCreateElementFunctionLike(code, readObject(object.declaration), names) !==
446
+ undefined ||
447
+ (functionLike !== undefined &&
448
+ hasCompatRenderToStringWrapperReturn(code, functionLike, renderToStringNames)));
315
449
  }
316
450
  if (object.type === "ExportNamedDeclaration") {
317
451
  const declaration = readObject(object.declaration);
318
452
  if (declaration.type === "FunctionDeclaration") {
319
- return hasLowerableCompatCreateElementReturn(code, declaration, names);
453
+ return (hasLowerableCompatCreateElementReturn(code, declaration, names) ||
454
+ hasCompatRenderToStringWrapperReturn(code, declaration, renderToStringNames));
320
455
  }
321
456
  return readCompatCreateElementPlainComponent(code, declaration, names) !== undefined;
322
457
  }
323
- return readCompatCreateElementPlainComponent(code, statement, names) !== undefined;
458
+ const plainComponent = readCompatCreateElementPlainComponent(code, statement, names);
459
+ if (serverOutput === "stream") {
460
+ return (plainComponent !== undefined &&
461
+ renderToStringLowerableTargets.has(plainComponent.name) &&
462
+ localFunctionLikes.get(plainComponent.name) === plainComponent.initializer);
463
+ }
464
+ if (plainComponent !== undefined) {
465
+ return true;
466
+ }
467
+ const functionLike = unwrapOxcStatementFunctionLike(statement);
468
+ if (functionLike === undefined) {
469
+ return false;
470
+ }
471
+ return hasCompatRenderToStringWrapperReturn(code, functionLike, renderToStringNames);
324
472
  }
325
- function analyzeOxcComponent(code, statement, componentNames, target, diagnostics, bodyStatementJsx, compatCreateElementNames, moduleRenderValueBindings, compatReactNodeReturn, serverOutput, componentCallNames, bodyLowerers, reactiveDerivedFunctionNames, localJsxReturnFunctionNames, localJsxHelperHtmlParameters) {
473
+ function analyzeOxcComponent(code, statement, componentNames, target, diagnostics, bodyStatementJsx, compatCreateElementNames, compatRenderToStringNames, compatCreateElementLocalFunctionLikes, compatRenderToStringLowerableTargets, moduleRenderValueBindings, compatReactNodeReturn, serverOutput, componentCallNames, bodyLowerers, reactiveDerivedFunctionNames, localJsxReturnFunctionNames, localJsxHelperHtmlParameters) {
326
474
  const object = readObject(statement);
327
475
  if (object.type === "ExportDefaultDeclaration") {
328
476
  const declaration = unwrapOxcComponentFunctionLikeInitializer(readObject(object.declaration));
329
477
  if (declaration === undefined ||
330
478
  (!hasOxcFunctionLikeComponentReturn(declaration) &&
331
- !hasLowerableCompatCreateElementReturn(code, declaration, compatCreateElementNames))) {
479
+ !hasLowerableCompatCreateElementReturn(code, declaration, compatCreateElementNames) &&
480
+ !hasCompatRenderToStringWrapperReturn(code, declaration, compatRenderToStringNames))) {
332
481
  return [];
333
482
  }
334
483
  const id = readObject(declaration.id);
335
484
  const name = typeof id.name === "string" ? id.name : "DefaultExport";
336
485
  return [
337
- analyzeOxcFunctionLikeComponent(code, name, declaration, "default", componentNames, target, diagnostics, bodyStatementJsx, compatCreateElementNames, moduleRenderValueBindings, compatReactNodeReturn, serverOutput, componentCallNames, bodyLowerers, reactiveDerivedFunctionNames, localJsxReturnFunctionNames, localJsxHelperHtmlParameters, true),
486
+ analyzeOxcFunctionLikeComponent(code, name, declaration, "default", componentNames, target, diagnostics, bodyStatementJsx, compatCreateElementNames, compatRenderToStringNames, compatCreateElementLocalFunctionLikes, moduleRenderValueBindings, compatReactNodeReturn, serverOutput, componentCallNames, bodyLowerers, reactiveDerivedFunctionNames, localJsxReturnFunctionNames, localJsxHelperHtmlParameters, true),
338
487
  ];
339
488
  }
340
489
  if (object.type !== "ExportNamedDeclaration") {
341
490
  const plainComponent = readOxcPlainComponent(statement) ??
342
- readCompatCreateElementPlainComponent(code, statement, compatCreateElementNames);
491
+ (serverOutput === "stream"
492
+ ? undefined
493
+ : readCompatCreateElementPlainComponent(code, statement, compatCreateElementNames));
343
494
  if (plainComponent === undefined) {
344
495
  return [];
345
496
  }
497
+ if (compatRenderToStringLowerableTargets.has(plainComponent.name)) {
498
+ return [];
499
+ }
346
500
  return [
347
501
  {
348
- ...analyzeOxcFunctionLikeComponent(code, plainComponent.name, plainComponent.initializer, plainComponent.name, componentNames, target, diagnostics, bodyStatementJsx, compatCreateElementNames, moduleRenderValueBindings, compatReactNodeReturn, serverOutput, componentCallNames, bodyLowerers, reactiveDerivedFunctionNames, localJsxReturnFunctionNames, localJsxHelperHtmlParameters),
502
+ ...analyzeOxcFunctionLikeComponent(code, plainComponent.name, plainComponent.initializer, plainComponent.name, componentNames, target, diagnostics, bodyStatementJsx, compatCreateElementNames, compatRenderToStringNames, compatCreateElementLocalFunctionLikes, moduleRenderValueBindings, compatReactNodeReturn, serverOutput, componentCallNames, bodyLowerers, reactiveDerivedFunctionNames, localJsxReturnFunctionNames, localJsxHelperHtmlParameters),
349
503
  exported: false,
350
504
  },
351
505
  ];
@@ -358,14 +512,15 @@ function analyzeOxcComponent(code, statement, componentNames, target, diagnostic
358
512
  return [];
359
513
  }
360
514
  return [
361
- analyzeOxcFunctionLikeComponent(code, variableComponent.name, variableComponent.initializer, variableComponent.name, componentNames, target, diagnostics, bodyStatementJsx, compatCreateElementNames, moduleRenderValueBindings, compatReactNodeReturn, serverOutput, componentCallNames, bodyLowerers, reactiveDerivedFunctionNames, localJsxReturnFunctionNames, localJsxHelperHtmlParameters),
515
+ analyzeOxcFunctionLikeComponent(code, variableComponent.name, variableComponent.initializer, variableComponent.name, componentNames, target, diagnostics, bodyStatementJsx, compatCreateElementNames, compatRenderToStringNames, compatCreateElementLocalFunctionLikes, moduleRenderValueBindings, compatReactNodeReturn, serverOutput, componentCallNames, bodyLowerers, reactiveDerivedFunctionNames, localJsxReturnFunctionNames, localJsxHelperHtmlParameters),
362
516
  ];
363
517
  }
364
518
  if (declaration.type !== "FunctionDeclaration" ||
365
519
  (!compatReactNodeReturn &&
366
520
  !hasComponentReturn(declaration.body) &&
367
521
  !hasLocalJsxHelperCallReturn(declaration.body, localJsxReturnFunctionNames) &&
368
- !hasLowerableCompatCreateElementReturn(code, declaration, compatCreateElementNames))) {
522
+ !hasLowerableCompatCreateElementReturn(code, declaration, compatCreateElementNames) &&
523
+ !hasCompatRenderToStringWrapperReturn(code, declaration, compatRenderToStringNames))) {
369
524
  return [];
370
525
  }
371
526
  const id = readObject(declaration.id);
@@ -373,7 +528,7 @@ function analyzeOxcComponent(code, statement, componentNames, target, diagnostic
373
528
  return [];
374
529
  }
375
530
  return [
376
- analyzeOxcFunctionLikeComponent(code, id.name, declaration, id.name, componentNames, target, diagnostics, bodyStatementJsx, compatCreateElementNames, moduleRenderValueBindings, compatReactNodeReturn, serverOutput, componentCallNames, bodyLowerers, reactiveDerivedFunctionNames, localJsxReturnFunctionNames, localJsxHelperHtmlParameters),
531
+ analyzeOxcFunctionLikeComponent(code, id.name, declaration, id.name, componentNames, target, diagnostics, bodyStatementJsx, compatCreateElementNames, compatRenderToStringNames, compatCreateElementLocalFunctionLikes, moduleRenderValueBindings, compatReactNodeReturn, serverOutput, componentCallNames, bodyLowerers, reactiveDerivedFunctionNames, localJsxReturnFunctionNames, localJsxHelperHtmlParameters),
377
532
  ];
378
533
  }
379
534
  function lowerOxcLocalJsxHelperCallExpressionCode(code, expression, componentNames, target, diagnostics, bodyLowerers) {
@@ -388,7 +543,7 @@ function lowerOxcLocalJsxHelperCallExpressionCode(code, expression, componentNam
388
543
  });
389
544
  return `${readSource(code, readObject(expression.callee))}(${args.join(", ")})`;
390
545
  }
391
- function analyzeOxcFunctionLikeComponent(code, name, functionLike, exportName, componentNames, target, diagnostics, bodyStatementJsx, compatCreateElementNames, moduleRenderValueBindings, compatReactNodeReturn, serverOutput, componentCallNames, bodyLowerers, reactiveDerivedFunctionNames, localJsxReturnFunctionNames, localJsxHelperHtmlParameters, exportDefault = false) {
546
+ function analyzeOxcFunctionLikeComponent(code, name, functionLike, exportName, componentNames, target, diagnostics, bodyStatementJsx, compatCreateElementNames, compatRenderToStringNames, compatCreateElementLocalFunctionLikes, moduleRenderValueBindings, compatReactNodeReturn, serverOutput, componentCallNames, bodyLowerers, reactiveDerivedFunctionNames, localJsxReturnFunctionNames, localJsxHelperHtmlParameters, exportDefault = false) {
392
547
  const functionBody = readObject(functionLike.body);
393
548
  const body = functionBody.type === "BlockStatement" ? readArray(functionBody.body) : [];
394
549
  const earlyIfRootReturn = bodyStatementJsx === "compat-object"
@@ -427,6 +582,7 @@ function analyzeOxcFunctionLikeComponent(code, name, functionLike, exportName, c
427
582
  names: compatCreateElementNames,
428
583
  shadowed: collectFunctionShadowedNames(functionLike, compatCreateElementNames),
429
584
  })) ??
585
+ analyzeCompatRenderToStringWrapperRoot(code, functionLike, returnExpression, compatCreateElementNames, compatRenderToStringNames, compatCreateElementLocalFunctionLikes) ??
430
586
  (isJsxRoot(returnExpression.type) || returnExpression.type === "JSXFragment"
431
587
  ? analyzeOxcJsxNode(code, returnExpression, childAnalysisContext)
432
588
  : isOxcComponentCallExpression(returnExpression)