@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/compile.cjs CHANGED
@@ -93,7 +93,8 @@ function compileWithSourceMap(code, options = {}) {
93
93
  sourceLocation: options.sourceLocation ?? true,
94
94
  stateAliases: collectStateAliases(sourceFile),
95
95
  localBindings: collectLocallyDeclaredNames(sourceFile),
96
- diagnostics: []
96
+ diagnostics: [],
97
+ hmrModuleId: options.hmrModuleId ?? null
97
98
  };
98
99
  const cleanFilename = filename.split(/[?#]/u, 1)[0] || filename;
99
100
  const diagnostics = import_typescript.default.transpileModule(code, {
@@ -119,14 +120,15 @@ function compileWithSourceMap(code, options = {}) {
119
120
  }
120
121
  for (const plugin of plugins) sourceFile = transformPluginNodes(sourceFile, plugin, context);
121
122
  const statements = sourceFile.statements.map(
122
- (statement) => import_typescript.default.isImportDeclaration(statement) ? rebuildImport(state, statement) : transformStatement(state, statement)
123
+ (statement) => import_typescript.default.isImportDeclaration(statement) ? rebuildImport(state, statement) : transformStatement(state, statement, true)
123
124
  );
124
125
  const templateDeclarations = createTemplateDeclarations(state);
125
- const resultFile = import_typescript.default.factory.updateSourceFile(sourceFile, [
126
+ let resultFile = import_typescript.default.factory.updateSourceFile(sourceFile, [
126
127
  ...createRuntimeImports(state),
127
128
  ...templateDeclarations,
128
129
  ...statements
129
130
  ]);
131
+ resultFile = transformResidualJsx(state, resultFile);
130
132
  const generated = import_typescript.default.createPrinter().printFile(resultFile);
131
133
  return {
132
134
  code: generated,
@@ -408,7 +410,7 @@ function rebuildImport(state, node) {
408
410
  ), node);
409
411
  }
410
412
  __name(rebuildImport, "rebuildImport");
411
- function transformStatement(state, node) {
413
+ function transformStatement(state, node, moduleScope = false) {
412
414
  if (import_typescript.default.isFunctionDeclaration(node) && node.body) {
413
415
  return tagStatement(state, import_typescript.default.factory.updateFunctionDeclaration(
414
416
  node,
@@ -421,7 +423,7 @@ function transformStatement(state, node) {
421
423
  transformBlock(state, node.body)
422
424
  ), node);
423
425
  }
424
- if (import_typescript.default.isVariableStatement(node)) return transformVariableStatement(state, node);
426
+ if (import_typescript.default.isVariableStatement(node)) return transformVariableStatement(state, node, moduleScope);
425
427
  if (import_typescript.default.isExportAssignment(node) && containsJsx(node.expression)) {
426
428
  return tagStatement(state, import_typescript.default.factory.updateExportAssignment(node, node.modifiers, transformEmbeddedExpression(state, node.expression)), node);
427
429
  }
@@ -434,7 +436,7 @@ function transformStatement(state, node) {
434
436
  return node;
435
437
  }
436
438
  __name(transformStatement, "transformStatement");
437
- function transformVariableStatement(state, node) {
439
+ function transformVariableStatement(state, node, moduleScope = false) {
438
440
  let changed = false;
439
441
  const declarations = node.declarationList.declarations.map((declaration) => {
440
442
  const initializer = declaration.initializer;
@@ -442,6 +444,8 @@ function transformVariableStatement(state, node) {
442
444
  let nextInitializer = inferStateDebugName(state, declaration, initializer) ?? initializer;
443
445
  if (containsJsx(nextInitializer)) {
444
446
  nextInitializer = transformEmbeddedExpression(state, nextInitializer);
447
+ } else if (moduleScope && state.hmrModuleId !== null) {
448
+ nextInitializer = wrapStateWithHmrRef(state, declaration, nextInitializer) ?? nextInitializer;
445
449
  }
446
450
  if (nextInitializer === initializer) return declaration;
447
451
  changed = true;
@@ -479,6 +483,29 @@ function inferStateDebugName(state, declaration, initializer) {
479
483
  ]);
480
484
  }
481
485
  __name(inferStateDebugName, "inferStateDebugName");
486
+ function wrapStateWithHmrRef(state, declaration, initializer) {
487
+ let call = initializer;
488
+ while (import_typescript.default.isParenthesizedExpression(call) || import_typescript.default.isAsExpression(call) || import_typescript.default.isTypeAssertionExpression(call) || import_typescript.default.isSatisfiesExpression(call)) {
489
+ call = call.expression;
490
+ }
491
+ if (!import_typescript.default.isCallExpression(call)) return void 0;
492
+ const callee = call.expression;
493
+ if (!import_typescript.default.isIdentifier(callee) || !state.stateAliases.has(callee.text)) return void 0;
494
+ if (state.localBindings.has(callee.text)) return void 0;
495
+ if (!import_typescript.default.isIdentifier(declaration.name)) return void 0;
496
+ return import_typescript.default.factory.createCallExpression(helperRef(state, "hmrStateRef"), void 0, [
497
+ import_typescript.default.factory.createStringLiteral(`${state.hmrModuleId}#${declaration.name.text}`),
498
+ import_typescript.default.factory.createArrowFunction(
499
+ void 0,
500
+ void 0,
501
+ [],
502
+ void 0,
503
+ import_typescript.default.factory.createToken(import_typescript.default.SyntaxKind.EqualsGreaterThanToken),
504
+ initializer
505
+ )
506
+ ]);
507
+ }
508
+ __name(wrapStateWithHmrRef, "wrapStateWithHmrRef");
482
509
  function containsJsx(expression) {
483
510
  let found = false;
484
511
  const visit = /* @__PURE__ */ __name((node) => {
@@ -739,6 +766,27 @@ function transformEmbeddedExpression(state, expression) {
739
766
  }
740
767
  }
741
768
  __name(transformEmbeddedExpression, "transformEmbeddedExpression");
769
+ function transformResidualJsx(state, sourceFile) {
770
+ if (!containsJsx(sourceFile)) return sourceFile;
771
+ const result = import_typescript.default.transform(sourceFile, [(context) => (root) => {
772
+ const visit = /* @__PURE__ */ __name((node) => {
773
+ if (import_typescript.default.isReturnStatement(node) && node.expression && containsJsx(node.expression)) {
774
+ return import_typescript.default.factory.updateReturnStatement(node, transformEmbeddedExpression(state, node.expression));
775
+ }
776
+ if (isJsxExpression(node)) {
777
+ return transformJsxExpression(state, node);
778
+ }
779
+ return import_typescript.default.visitEachChild(node, visit, context);
780
+ }, "visit");
781
+ return import_typescript.default.visitNode(root, visit);
782
+ }]);
783
+ try {
784
+ return result.transformed[0];
785
+ } finally {
786
+ result.dispose();
787
+ }
788
+ }
789
+ __name(transformResidualJsx, "transformResidualJsx");
742
790
  function isStaticElement(tagName, attributes, children) {
743
791
  if (!import_typescript.default.isIdentifier(tagName) || !/^[a-z]/.test(tagName.text)) return false;
744
792
  for (const attribute of attributes.properties) {
@@ -991,36 +1039,52 @@ function createSourceLocation(node) {
991
1039
  }
992
1040
  __name(createSourceLocation, "createSourceLocation");
993
1041
  function transformDynamicExpression(state, expression) {
1042
+ const converted = convertDynamicNodeExpression(state, expression);
1043
+ return converted ? createGetter(converted) : null;
1044
+ }
1045
+ __name(transformDynamicExpression, "transformDynamicExpression");
1046
+ function convertDynamicNodeExpression(state, expression) {
994
1047
  if (import_typescript.default.isBinaryExpression(expression) && expression.operatorToken.kind === import_typescript.default.SyntaxKind.AmpersandAmpersandToken) {
995
1048
  const right = unwrapExpression(expression.right);
996
- if (!isJsxExpression(right)) return null;
997
- return createGetter(import_typescript.default.factory.createConditionalExpression(
998
- expression.left,
999
- import_typescript.default.factory.createToken(import_typescript.default.SyntaxKind.QuestionToken),
1000
- transformJsxExpression(state, right),
1001
- import_typescript.default.factory.createToken(import_typescript.default.SyntaxKind.ColonToken),
1002
- import_typescript.default.factory.createNull()
1003
- ));
1049
+ if (isJsxExpression(right)) {
1050
+ return createNodeConditional(expression.left, transformJsxExpression(state, right), null);
1051
+ }
1052
+ const convertedRight = convertDynamicNodeExpression(state, right);
1053
+ if (convertedRight) return createNodeConditional(expression.left, convertedRight, null);
1054
+ return null;
1004
1055
  }
1005
1056
  if (import_typescript.default.isConditionalExpression(expression)) {
1006
1057
  const whenTrue = transformDynamicBranch(state, expression.whenTrue);
1007
1058
  const whenFalse = transformDynamicBranch(state, expression.whenFalse);
1008
1059
  if (!whenTrue && !whenFalse) return null;
1009
- return createGetter(import_typescript.default.factory.createConditionalExpression(
1060
+ return import_typescript.default.factory.createConditionalExpression(
1010
1061
  expression.condition,
1011
1062
  import_typescript.default.factory.createToken(import_typescript.default.SyntaxKind.QuestionToken),
1012
1063
  whenTrue ?? import_typescript.default.factory.createNull(),
1013
1064
  import_typescript.default.factory.createToken(import_typescript.default.SyntaxKind.ColonToken),
1014
1065
  whenFalse ?? import_typescript.default.factory.createNull()
1015
- ));
1066
+ );
1016
1067
  }
1017
1068
  return null;
1018
1069
  }
1019
- __name(transformDynamicExpression, "transformDynamicExpression");
1070
+ __name(convertDynamicNodeExpression, "convertDynamicNodeExpression");
1071
+ function createNodeConditional(condition, whenTrue, whenFalse) {
1072
+ return import_typescript.default.factory.createConditionalExpression(
1073
+ condition,
1074
+ import_typescript.default.factory.createToken(import_typescript.default.SyntaxKind.QuestionToken),
1075
+ whenTrue,
1076
+ import_typescript.default.factory.createToken(import_typescript.default.SyntaxKind.ColonToken),
1077
+ whenFalse ?? import_typescript.default.factory.createNull()
1078
+ );
1079
+ }
1080
+ __name(createNodeConditional, "createNodeConditional");
1020
1081
  function transformDynamicBranch(state, expression) {
1021
1082
  const branch = unwrapExpression(expression);
1022
1083
  if (isJsxExpression(branch)) return transformJsxExpression(state, branch);
1023
1084
  if (branch.kind === import_typescript.default.SyntaxKind.NullKeyword || branch.kind === import_typescript.default.SyntaxKind.FalseKeyword) return branch;
1085
+ if (import_typescript.default.isConditionalExpression(branch) || import_typescript.default.isBinaryExpression(branch) && branch.operatorToken.kind === import_typescript.default.SyntaxKind.AmpersandAmpersandToken) {
1086
+ return convertDynamicNodeExpression(state, branch);
1087
+ }
1024
1088
  return null;
1025
1089
  }
1026
1090
  __name(transformDynamicBranch, "transformDynamicBranch");