@vobs/compiler 1.2.2 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -96,7 +96,8 @@ function compileWithSourceMap(code, options = {}) {
96
96
  sourceLocation: options.sourceLocation ?? true,
97
97
  stateAliases: collectStateAliases(sourceFile),
98
98
  localBindings: collectLocallyDeclaredNames(sourceFile),
99
- diagnostics: []
99
+ diagnostics: [],
100
+ hmrModuleId: options.hmrModuleId ?? null
100
101
  };
101
102
  const cleanFilename = filename.split(/[?#]/u, 1)[0] || filename;
102
103
  const diagnostics = import_typescript.default.transpileModule(code, {
@@ -122,14 +123,15 @@ function compileWithSourceMap(code, options = {}) {
122
123
  }
123
124
  for (const plugin of plugins) sourceFile = transformPluginNodes(sourceFile, plugin, context);
124
125
  const statements = sourceFile.statements.map(
125
- (statement) => import_typescript.default.isImportDeclaration(statement) ? rebuildImport(state, statement) : transformStatement(state, statement)
126
+ (statement) => import_typescript.default.isImportDeclaration(statement) ? rebuildImport(state, statement) : transformStatement(state, statement, true)
126
127
  );
127
128
  const templateDeclarations = createTemplateDeclarations(state);
128
- const resultFile = import_typescript.default.factory.updateSourceFile(sourceFile, [
129
+ let resultFile = import_typescript.default.factory.updateSourceFile(sourceFile, [
129
130
  ...createRuntimeImports(state),
130
131
  ...templateDeclarations,
131
132
  ...statements
132
133
  ]);
134
+ resultFile = transformResidualJsx(state, resultFile);
133
135
  const generated = import_typescript.default.createPrinter().printFile(resultFile);
134
136
  return {
135
137
  code: generated,
@@ -411,7 +413,7 @@ function rebuildImport(state, node) {
411
413
  ), node);
412
414
  }
413
415
  __name(rebuildImport, "rebuildImport");
414
- function transformStatement(state, node) {
416
+ function transformStatement(state, node, moduleScope = false) {
415
417
  if (import_typescript.default.isFunctionDeclaration(node) && node.body) {
416
418
  return tagStatement(state, import_typescript.default.factory.updateFunctionDeclaration(
417
419
  node,
@@ -424,7 +426,7 @@ function transformStatement(state, node) {
424
426
  transformBlock(state, node.body)
425
427
  ), node);
426
428
  }
427
- if (import_typescript.default.isVariableStatement(node)) return transformVariableStatement(state, node);
429
+ if (import_typescript.default.isVariableStatement(node)) return transformVariableStatement(state, node, moduleScope);
428
430
  if (import_typescript.default.isExportAssignment(node) && containsJsx(node.expression)) {
429
431
  return tagStatement(state, import_typescript.default.factory.updateExportAssignment(node, node.modifiers, transformEmbeddedExpression(state, node.expression)), node);
430
432
  }
@@ -437,7 +439,7 @@ function transformStatement(state, node) {
437
439
  return node;
438
440
  }
439
441
  __name(transformStatement, "transformStatement");
440
- function transformVariableStatement(state, node) {
442
+ function transformVariableStatement(state, node, moduleScope = false) {
441
443
  let changed = false;
442
444
  const declarations = node.declarationList.declarations.map((declaration) => {
443
445
  const initializer = declaration.initializer;
@@ -445,6 +447,8 @@ function transformVariableStatement(state, node) {
445
447
  let nextInitializer = inferStateDebugName(state, declaration, initializer) ?? initializer;
446
448
  if (containsJsx(nextInitializer)) {
447
449
  nextInitializer = transformEmbeddedExpression(state, nextInitializer);
450
+ } else if (moduleScope && state.hmrModuleId !== null) {
451
+ nextInitializer = wrapStateWithHmrRef(state, declaration, nextInitializer) ?? nextInitializer;
448
452
  }
449
453
  if (nextInitializer === initializer) return declaration;
450
454
  changed = true;
@@ -482,6 +486,29 @@ function inferStateDebugName(state, declaration, initializer) {
482
486
  ]);
483
487
  }
484
488
  __name(inferStateDebugName, "inferStateDebugName");
489
+ function wrapStateWithHmrRef(state, declaration, initializer) {
490
+ let call = initializer;
491
+ while (import_typescript.default.isParenthesizedExpression(call) || import_typescript.default.isAsExpression(call) || import_typescript.default.isTypeAssertionExpression(call) || import_typescript.default.isSatisfiesExpression(call)) {
492
+ call = call.expression;
493
+ }
494
+ if (!import_typescript.default.isCallExpression(call)) return void 0;
495
+ const callee = call.expression;
496
+ if (!import_typescript.default.isIdentifier(callee) || !state.stateAliases.has(callee.text)) return void 0;
497
+ if (state.localBindings.has(callee.text)) return void 0;
498
+ if (!import_typescript.default.isIdentifier(declaration.name)) return void 0;
499
+ return import_typescript.default.factory.createCallExpression(helperRef(state, "hmrStateRef"), void 0, [
500
+ import_typescript.default.factory.createStringLiteral(`${state.hmrModuleId}#${declaration.name.text}`),
501
+ import_typescript.default.factory.createArrowFunction(
502
+ void 0,
503
+ void 0,
504
+ [],
505
+ void 0,
506
+ import_typescript.default.factory.createToken(import_typescript.default.SyntaxKind.EqualsGreaterThanToken),
507
+ initializer
508
+ )
509
+ ]);
510
+ }
511
+ __name(wrapStateWithHmrRef, "wrapStateWithHmrRef");
485
512
  function containsJsx(expression) {
486
513
  let found = false;
487
514
  const visit = /* @__PURE__ */ __name((node) => {
@@ -742,6 +769,27 @@ function transformEmbeddedExpression(state, expression) {
742
769
  }
743
770
  }
744
771
  __name(transformEmbeddedExpression, "transformEmbeddedExpression");
772
+ function transformResidualJsx(state, sourceFile) {
773
+ if (!containsJsx(sourceFile)) return sourceFile;
774
+ const result = import_typescript.default.transform(sourceFile, [(context) => (root) => {
775
+ const visit = /* @__PURE__ */ __name((node) => {
776
+ if (import_typescript.default.isReturnStatement(node) && node.expression && containsJsx(node.expression)) {
777
+ return import_typescript.default.factory.updateReturnStatement(node, transformEmbeddedExpression(state, node.expression));
778
+ }
779
+ if (isJsxExpression(node)) {
780
+ return transformJsxExpression(state, node);
781
+ }
782
+ return import_typescript.default.visitEachChild(node, visit, context);
783
+ }, "visit");
784
+ return import_typescript.default.visitNode(root, visit);
785
+ }]);
786
+ try {
787
+ return result.transformed[0];
788
+ } finally {
789
+ result.dispose();
790
+ }
791
+ }
792
+ __name(transformResidualJsx, "transformResidualJsx");
745
793
  function isStaticElement(tagName, attributes, children) {
746
794
  if (!import_typescript.default.isIdentifier(tagName) || !/^[a-z]/.test(tagName.text)) return false;
747
795
  for (const attribute of attributes.properties) {
@@ -994,36 +1042,52 @@ function createSourceLocation(node) {
994
1042
  }
995
1043
  __name(createSourceLocation, "createSourceLocation");
996
1044
  function transformDynamicExpression(state, expression) {
1045
+ const converted = convertDynamicNodeExpression(state, expression);
1046
+ return converted ? createGetter(converted) : null;
1047
+ }
1048
+ __name(transformDynamicExpression, "transformDynamicExpression");
1049
+ function convertDynamicNodeExpression(state, expression) {
997
1050
  if (import_typescript.default.isBinaryExpression(expression) && expression.operatorToken.kind === import_typescript.default.SyntaxKind.AmpersandAmpersandToken) {
998
1051
  const right = unwrapExpression(expression.right);
999
- if (!isJsxExpression(right)) return null;
1000
- return createGetter(import_typescript.default.factory.createConditionalExpression(
1001
- expression.left,
1002
- import_typescript.default.factory.createToken(import_typescript.default.SyntaxKind.QuestionToken),
1003
- transformJsxExpression(state, right),
1004
- import_typescript.default.factory.createToken(import_typescript.default.SyntaxKind.ColonToken),
1005
- import_typescript.default.factory.createNull()
1006
- ));
1052
+ if (isJsxExpression(right)) {
1053
+ return createNodeConditional(expression.left, transformJsxExpression(state, right), null);
1054
+ }
1055
+ const convertedRight = convertDynamicNodeExpression(state, right);
1056
+ if (convertedRight) return createNodeConditional(expression.left, convertedRight, null);
1057
+ return null;
1007
1058
  }
1008
1059
  if (import_typescript.default.isConditionalExpression(expression)) {
1009
1060
  const whenTrue = transformDynamicBranch(state, expression.whenTrue);
1010
1061
  const whenFalse = transformDynamicBranch(state, expression.whenFalse);
1011
1062
  if (!whenTrue && !whenFalse) return null;
1012
- return createGetter(import_typescript.default.factory.createConditionalExpression(
1063
+ return import_typescript.default.factory.createConditionalExpression(
1013
1064
  expression.condition,
1014
1065
  import_typescript.default.factory.createToken(import_typescript.default.SyntaxKind.QuestionToken),
1015
1066
  whenTrue ?? import_typescript.default.factory.createNull(),
1016
1067
  import_typescript.default.factory.createToken(import_typescript.default.SyntaxKind.ColonToken),
1017
1068
  whenFalse ?? import_typescript.default.factory.createNull()
1018
- ));
1069
+ );
1019
1070
  }
1020
1071
  return null;
1021
1072
  }
1022
- __name(transformDynamicExpression, "transformDynamicExpression");
1073
+ __name(convertDynamicNodeExpression, "convertDynamicNodeExpression");
1074
+ function createNodeConditional(condition, whenTrue, whenFalse) {
1075
+ return import_typescript.default.factory.createConditionalExpression(
1076
+ condition,
1077
+ import_typescript.default.factory.createToken(import_typescript.default.SyntaxKind.QuestionToken),
1078
+ whenTrue,
1079
+ import_typescript.default.factory.createToken(import_typescript.default.SyntaxKind.ColonToken),
1080
+ whenFalse ?? import_typescript.default.factory.createNull()
1081
+ );
1082
+ }
1083
+ __name(createNodeConditional, "createNodeConditional");
1023
1084
  function transformDynamicBranch(state, expression) {
1024
1085
  const branch = unwrapExpression(expression);
1025
1086
  if (isJsxExpression(branch)) return transformJsxExpression(state, branch);
1026
1087
  if (branch.kind === import_typescript.default.SyntaxKind.NullKeyword || branch.kind === import_typescript.default.SyntaxKind.FalseKeyword) return branch;
1088
+ if (import_typescript.default.isConditionalExpression(branch) || import_typescript.default.isBinaryExpression(branch) && branch.operatorToken.kind === import_typescript.default.SyntaxKind.AmpersandAmpersandToken) {
1089
+ return convertDynamicNodeExpression(state, branch);
1090
+ }
1027
1091
  return null;
1028
1092
  }
1029
1093
  __name(transformDynamicBranch, "transformDynamicBranch");