@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 +81 -17
- package/dist/compile.cjs.map +1 -1
- package/dist/compile.js +81 -17
- package/dist/compile.js.map +1 -1
- package/dist/index.cjs +81 -17
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +81 -17
- package/dist/index.js.map +1 -1
- package/dist/plugin.cjs.map +1 -1
- package/dist/plugin.d.cts +6 -0
- package/dist/plugin.d.ts +6 -0
- package/package.json +2 -2
- package/src/compile.test.ts +74 -0
- package/src/compile.ts +113 -17
- package/src/plugin.ts +6 -0
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
|
-
|
|
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 (
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
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
|
|
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(
|
|
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");
|