@sigil-dev/compiler 0.7.4 → 0.7.6
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/package.json +5 -1
- package/src/babel/handlers/dom/derived.ts +31 -1
- package/src/babel/handlers/dom/globals.ts +102 -0
- package/src/babel/handlers/ssr/state.ts +10 -10
- package/src/babel/index.ts +430 -257
- package/src/babel/jsx/children.ts +124 -124
- package/src/babel/jsx/element.ts +803 -582
- package/src/babel/jsx/ssr.ts +319 -310
- package/src/babel/jsx/utils.ts +95 -89
- package/src/babel/util/bind.ts +126 -135
- package/src/babel/util/css.ts +151 -151
- package/src/babel/util/helpers.ts +16 -2
- package/src/babel/util/magic.ts +5 -0
- package/src/bun-plugin.ts +86 -45
- package/src/vite/index.ts +7 -2
- package/test/jsx.test.ts +195 -195
- package/test/reactivity.test.ts +147 -1
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@sigil-dev/compiler",
|
|
3
3
|
"module": "index.ts",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"version": "0.7.
|
|
5
|
+
"version": "0.7.6",
|
|
6
6
|
"private": false,
|
|
7
7
|
"description": "Compiler for the Sigil framework",
|
|
8
8
|
"peerDependencies": {
|
|
@@ -20,5 +20,9 @@
|
|
|
20
20
|
"@babel/plugin-syntax-typescript": "next",
|
|
21
21
|
"@babel/traverse": "next",
|
|
22
22
|
"@babel/types": "next"
|
|
23
|
+
},
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"@babel/plugin-transform-typescript": "^8.0.0-rc.6",
|
|
26
|
+
"@babel/preset-typescript": "^8.0.0-rc.6"
|
|
23
27
|
}
|
|
24
28
|
}
|
|
@@ -2,6 +2,12 @@ import type { NodePath } from "@babel/core";
|
|
|
2
2
|
import { types as t } from "@babel/core";
|
|
3
3
|
import { MAGIC } from "../../util/magic.ts";
|
|
4
4
|
|
|
5
|
+
const setCall = (name: string, value: t.Expression) =>
|
|
6
|
+
t.callExpression(
|
|
7
|
+
t.memberExpression(t.identifier(name), t.identifier("set")),
|
|
8
|
+
[value],
|
|
9
|
+
);
|
|
10
|
+
|
|
5
11
|
export function handleDerived(
|
|
6
12
|
declaration: NodePath<t.VariableDeclaration>,
|
|
7
13
|
declarator: NodePath<t.VariableDeclarator>,
|
|
@@ -17,13 +23,37 @@ export function handleDerived(
|
|
|
17
23
|
const binding = declaration.scope.getBinding(name);
|
|
18
24
|
if (!binding) return;
|
|
19
25
|
const refs = [...binding.referencePaths];
|
|
26
|
+
const violations = [...binding.constantViolations];
|
|
20
27
|
|
|
21
28
|
init.replaceWith(
|
|
22
29
|
t.callExpression(t.identifier(MAGIC.createMemo), [
|
|
23
30
|
t.arrowFunctionExpression([], init.node.arguments[0] as t.Expression),
|
|
24
31
|
]),
|
|
25
32
|
);
|
|
26
|
-
declaration.node.kind = "
|
|
33
|
+
declaration.node.kind = "let";
|
|
34
|
+
|
|
35
|
+
// A6: $derived reassign — convert assignments to .set() calls
|
|
36
|
+
for (const violation of violations) {
|
|
37
|
+
if (violation.isAssignmentExpression()) {
|
|
38
|
+
const { operator, right } = violation.node;
|
|
39
|
+
if (operator === "=") {
|
|
40
|
+
violation.replaceWith(setCall(name, right));
|
|
41
|
+
} else {
|
|
42
|
+
const baseOp = operator.slice(0, -1);
|
|
43
|
+
violation.replaceWith(
|
|
44
|
+
setCall(
|
|
45
|
+
name,
|
|
46
|
+
t.binaryExpression(
|
|
47
|
+
baseOp as t.BinaryExpression["operator"],
|
|
48
|
+
t.callExpression(t.identifier(name), []),
|
|
49
|
+
right,
|
|
50
|
+
),
|
|
51
|
+
),
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
27
57
|
for (const ref of refs) {
|
|
28
58
|
if (!ref.isIdentifier()) continue;
|
|
29
59
|
if (ref.parentPath?.isUpdateExpression()) continue;
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { types as t } from "@babel/core";
|
|
2
|
+
|
|
3
|
+
const GLOBAL_TARGETS: Record<string, t.Expression> = {
|
|
4
|
+
Window: t.identifier("window"),
|
|
5
|
+
Document: t.identifier("document"),
|
|
6
|
+
Body: t.memberExpression(t.identifier("document"), t.identifier("body")),
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export function isGlobalComponent(tag: string): boolean {
|
|
10
|
+
return tag in GLOBAL_TARGETS;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function handleGlobalComponent(
|
|
14
|
+
tag: string,
|
|
15
|
+
node: t.JSXElement,
|
|
16
|
+
statements: t.Statement[],
|
|
17
|
+
genId: () => string,
|
|
18
|
+
): string {
|
|
19
|
+
const varName = genId();
|
|
20
|
+
const targetExpr = GLOBAL_TARGETS[tag];
|
|
21
|
+
|
|
22
|
+
for (const attr of node.openingElement.attributes) {
|
|
23
|
+
if (!t.isJSXAttribute(attr)) continue;
|
|
24
|
+
|
|
25
|
+
let attrName: string;
|
|
26
|
+
if (t.isJSXNamespacedName(attr.name)) {
|
|
27
|
+
attrName = attr.name.name.name;
|
|
28
|
+
} else {
|
|
29
|
+
attrName = (attr.name as t.JSXIdentifier).name;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (/^on[A-Z]/.test(attrName)) {
|
|
33
|
+
const event = attrName.slice(2).toLowerCase();
|
|
34
|
+
const handler = (attr.value as t.JSXExpressionContainer)
|
|
35
|
+
.expression as t.Expression;
|
|
36
|
+
|
|
37
|
+
// createEffect(() => {
|
|
38
|
+
// if (typeof window === "undefined") return;
|
|
39
|
+
// target.addEventListener(ev, handler);
|
|
40
|
+
// return () => target.removeEventListener(ev, handler);
|
|
41
|
+
// })
|
|
42
|
+
statements.push(
|
|
43
|
+
t.expressionStatement(
|
|
44
|
+
t.callExpression(t.identifier("createEffect"), [
|
|
45
|
+
t.arrowFunctionExpression(
|
|
46
|
+
[],
|
|
47
|
+
t.blockStatement([
|
|
48
|
+
t.ifStatement(
|
|
49
|
+
t.binaryExpression(
|
|
50
|
+
"===",
|
|
51
|
+
t.unaryExpression("typeof", targetExpr),
|
|
52
|
+
t.stringLiteral("undefined"),
|
|
53
|
+
),
|
|
54
|
+
t.returnStatement(),
|
|
55
|
+
),
|
|
56
|
+
t.expressionStatement(
|
|
57
|
+
t.callExpression(
|
|
58
|
+
t.memberExpression(
|
|
59
|
+
targetExpr,
|
|
60
|
+
t.identifier("addEventListener"),
|
|
61
|
+
),
|
|
62
|
+
[t.stringLiteral(event), handler],
|
|
63
|
+
),
|
|
64
|
+
),
|
|
65
|
+
t.returnStatement(
|
|
66
|
+
t.arrowFunctionExpression(
|
|
67
|
+
[],
|
|
68
|
+
t.callExpression(
|
|
69
|
+
t.memberExpression(
|
|
70
|
+
targetExpr,
|
|
71
|
+
t.identifier("removeEventListener"),
|
|
72
|
+
),
|
|
73
|
+
[t.stringLiteral(event), handler],
|
|
74
|
+
),
|
|
75
|
+
),
|
|
76
|
+
),
|
|
77
|
+
]),
|
|
78
|
+
),
|
|
79
|
+
]),
|
|
80
|
+
),
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Placeholder comment node for the component's return value
|
|
86
|
+
statements.push(
|
|
87
|
+
t.variableDeclaration("const", [
|
|
88
|
+
t.variableDeclarator(
|
|
89
|
+
t.identifier(varName),
|
|
90
|
+
t.callExpression(
|
|
91
|
+
t.memberExpression(
|
|
92
|
+
t.identifier("document"),
|
|
93
|
+
t.identifier("createComment"),
|
|
94
|
+
),
|
|
95
|
+
[t.stringLiteral(tag.toLowerCase())],
|
|
96
|
+
),
|
|
97
|
+
),
|
|
98
|
+
]),
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
return varName;
|
|
102
|
+
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import type { NodePath, types as t } from "@babel/core";
|
|
2
|
-
|
|
3
|
-
export function handleStateSSR(
|
|
4
|
-
declaration: NodePath<t.VariableDeclaration>,
|
|
5
|
-
declarator: NodePath<t.VariableDeclarator>,
|
|
6
|
-
init: NodePath<t.CallExpression>,
|
|
7
|
-
): void {
|
|
8
|
-
init.replaceWith(init.node.arguments[0] as t.Expression);
|
|
9
|
-
declaration.node.kind = "let";
|
|
10
|
-
}
|
|
1
|
+
import type { NodePath, types as t } from "@babel/core";
|
|
2
|
+
|
|
3
|
+
export function handleStateSSR(
|
|
4
|
+
declaration: NodePath<t.VariableDeclaration>,
|
|
5
|
+
declarator: NodePath<t.VariableDeclarator>,
|
|
6
|
+
init: NodePath<t.CallExpression>,
|
|
7
|
+
): void {
|
|
8
|
+
init.replaceWith(init.node.arguments[0] as t.Expression);
|
|
9
|
+
declaration.node.kind = "let";
|
|
10
|
+
}
|