@faber1999/vite-plugin-axon 0.1.0 → 0.2.0
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.d.ts +24 -0
- package/dist/index.js +80 -0
- package/package.json +1 -1
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Plugin } from 'vite';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* vite-plugin-axon
|
|
5
|
+
*
|
|
6
|
+
* Transforms JSX attribute expressions that contain reactive calls into arrow
|
|
7
|
+
* functions, so that axon's h() can pick them up as reactive props.
|
|
8
|
+
*
|
|
9
|
+
* Before: class={`foo ${active() ? 'bar' : 'baz'}`}
|
|
10
|
+
* After: class={() => `foo ${active() ? 'bar' : 'baz'}`}
|
|
11
|
+
*
|
|
12
|
+
* Before: disabled={isDisabled()}
|
|
13
|
+
* After: disabled={() => isDisabled()}
|
|
14
|
+
*
|
|
15
|
+
* Rules:
|
|
16
|
+
* - Only JSX attributes (not children — those are already functions in signal patterns)
|
|
17
|
+
* - Skip event handlers (on*)
|
|
18
|
+
* - Skip expressions that are already arrow functions or function expressions
|
|
19
|
+
* - Only wrap when the expression contains at least one CallExpression
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
declare function axonPlugin(): Plugin;
|
|
23
|
+
|
|
24
|
+
export { axonPlugin as default };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import { parse } from "@babel/parser";
|
|
3
|
+
import _traverse from "@babel/traverse";
|
|
4
|
+
import _generate from "@babel/generator";
|
|
5
|
+
import * as t from "@babel/types";
|
|
6
|
+
var traverse = _traverse.default ?? _traverse;
|
|
7
|
+
var generate = _generate.default ?? _generate;
|
|
8
|
+
function containsCall(node) {
|
|
9
|
+
if (t.isCallExpression(node)) return true;
|
|
10
|
+
if (t.isTemplateLiteral(node)) {
|
|
11
|
+
return node.expressions.some((expr) => containsCall(expr));
|
|
12
|
+
}
|
|
13
|
+
if (t.isConditionalExpression(node)) {
|
|
14
|
+
return containsCall(node.test) || containsCall(node.consequent) || containsCall(node.alternate);
|
|
15
|
+
}
|
|
16
|
+
if (t.isLogicalExpression(node) || t.isBinaryExpression(node)) {
|
|
17
|
+
return containsCall(node.left) || containsCall(node.right);
|
|
18
|
+
}
|
|
19
|
+
if (t.isUnaryExpression(node)) {
|
|
20
|
+
return containsCall(node.argument);
|
|
21
|
+
}
|
|
22
|
+
if (t.isMemberExpression(node)) {
|
|
23
|
+
return containsCall(node.object);
|
|
24
|
+
}
|
|
25
|
+
if (t.isArrayExpression(node)) {
|
|
26
|
+
return node.elements.some((el) => el != null && containsCall(el));
|
|
27
|
+
}
|
|
28
|
+
if (t.isObjectExpression(node)) {
|
|
29
|
+
return node.properties.some((prop) => {
|
|
30
|
+
if (t.isObjectProperty(prop)) return containsCall(prop.value);
|
|
31
|
+
return false;
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
function shouldSkip(attrName, valueNode) {
|
|
37
|
+
if (attrName.startsWith("on") && attrName.length > 2) return true;
|
|
38
|
+
if (attrName === "ref") return true;
|
|
39
|
+
if (t.isArrowFunctionExpression(valueNode)) return true;
|
|
40
|
+
if (t.isFunctionExpression(valueNode)) return true;
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
function axonPlugin() {
|
|
44
|
+
return {
|
|
45
|
+
name: "vite-plugin-axon",
|
|
46
|
+
enforce: "pre",
|
|
47
|
+
transform(code, id) {
|
|
48
|
+
if (!id.endsWith(".jsx") && !id.endsWith(".tsx")) return null;
|
|
49
|
+
let ast;
|
|
50
|
+
try {
|
|
51
|
+
ast = parse(code, {
|
|
52
|
+
sourceType: "module",
|
|
53
|
+
plugins: ["jsx", "typescript"]
|
|
54
|
+
});
|
|
55
|
+
} catch {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
let changed = false;
|
|
59
|
+
traverse(ast, {
|
|
60
|
+
JSXAttribute(path) {
|
|
61
|
+
const { name, value } = path.node;
|
|
62
|
+
const attrName = t.isJSXIdentifier(name) ? name.name : `${name.namespace.name}:${name.name.name}`;
|
|
63
|
+
if (!t.isJSXExpressionContainer(value)) return;
|
|
64
|
+
const expr = value.expression;
|
|
65
|
+
if (t.isJSXEmptyExpression(expr)) return;
|
|
66
|
+
if (shouldSkip(attrName, expr)) return;
|
|
67
|
+
if (!containsCall(expr)) return;
|
|
68
|
+
value.expression = t.arrowFunctionExpression([], expr);
|
|
69
|
+
changed = true;
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
if (!changed) return null;
|
|
73
|
+
const result = generate(ast, { retainLines: true }, code);
|
|
74
|
+
return { code: result.code, map: result.map };
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
export {
|
|
79
|
+
axonPlugin as default
|
|
80
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@faber1999/vite-plugin-axon",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Vite plugin for axon.js — auto-wraps reactive JSX expressions in arrow functions",
|
|
5
5
|
"author": "Faber Grajales Hincapié <faber1999> (https://github.com/faber1999)",
|
|
6
6
|
"repository": {
|