@sigil-dev/compiler 0.7.5 → 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 -269
- 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 -72
- package/src/vite/index.ts +7 -2
- package/test/jsx.test.ts +195 -195
- package/test/reactivity.test.ts +147 -1
package/src/babel/jsx/utils.ts
CHANGED
|
@@ -1,51 +1,57 @@
|
|
|
1
1
|
import { types as t } from "@babel/core";
|
|
2
2
|
|
|
3
3
|
export const ATTR_MAP: Record<string, string> = {
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
class: "className",
|
|
5
|
+
for: "htmlFor",
|
|
6
6
|
};
|
|
7
7
|
|
|
8
8
|
export function containsSignal(
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
expr: t.Expression,
|
|
10
|
+
signals: Set<string>,
|
|
11
11
|
): boolean {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
12
|
+
if (t.isIdentifier(expr)) return signals.has(expr.name);
|
|
13
|
+
if (t.isCallExpression(expr)) {
|
|
14
|
+
return containsSignal(expr.callee as t.Expression, signals);
|
|
15
|
+
}
|
|
16
|
+
if (t.isBinaryExpression(expr)) {
|
|
17
|
+
return (
|
|
18
|
+
containsSignal(expr.left as t.Expression, signals) ||
|
|
19
|
+
containsSignal(expr.right, signals)
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
if (t.isMemberExpression(expr)) {
|
|
23
|
+
return containsSignal(expr.object as t.Expression, signals);
|
|
24
|
+
}
|
|
25
|
+
if (t.isLogicalExpression(expr)) {
|
|
26
|
+
return (
|
|
27
|
+
containsSignal(expr.left as t.Expression, signals) ||
|
|
28
|
+
containsSignal(expr.right as t.Expression, signals)
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
if (t.isConditionalExpression(expr)) {
|
|
32
|
+
return (
|
|
33
|
+
containsSignal(expr.test as t.Expression, signals) ||
|
|
34
|
+
containsSignal(expr.consequent as t.Expression, signals) ||
|
|
35
|
+
containsSignal(expr.alternate as t.Expression, signals)
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
if (t.isUnaryExpression(expr)) {
|
|
39
|
+
return containsSignal(expr.argument as t.Expression, signals);
|
|
40
|
+
}
|
|
41
|
+
if (t.isTemplateLiteral(expr)) {
|
|
42
|
+
return expr.expressions.some(e => containsSignal(e as t.Expression, signals));
|
|
43
|
+
}
|
|
44
|
+
return false;
|
|
39
45
|
}
|
|
40
46
|
|
|
41
47
|
export function isPrimitive(expr: t.Expression): boolean {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
48
|
+
if (t.isCallExpression(expr) && t.isIdentifier(expr.callee)) return true;
|
|
49
|
+
if (t.isBinaryExpression(expr)) return true;
|
|
50
|
+
if (t.isTemplateLiteral(expr)) return true;
|
|
51
|
+
if (t.isIdentifier(expr)) return true;
|
|
52
|
+
// user().name is a MemberExpression after state handler rewrites user → user()
|
|
53
|
+
if (t.isMemberExpression(expr)) return true;
|
|
54
|
+
return false;
|
|
49
55
|
}
|
|
50
56
|
|
|
51
57
|
/**
|
|
@@ -53,22 +59,22 @@ export function isPrimitive(expr: t.Expression): boolean {
|
|
|
53
59
|
* When parentVar is provided, passes it to claim() for SPA fallback (append on create).
|
|
54
60
|
*/
|
|
55
61
|
export function getCreateElement(
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
62
|
+
tag: string,
|
|
63
|
+
hydrate: boolean,
|
|
64
|
+
nodesVar = "__nodes",
|
|
65
|
+
parentVar?: string,
|
|
60
66
|
): t.Expression {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
67
|
+
if (hydrate) {
|
|
68
|
+
const args: t.Expression[] = [t.identifier(nodesVar), t.stringLiteral(tag)];
|
|
69
|
+
if (parentVar) {
|
|
70
|
+
args.push(t.identifier(parentVar));
|
|
71
|
+
}
|
|
72
|
+
return t.callExpression(t.identifier("claim"), args);
|
|
73
|
+
}
|
|
74
|
+
return t.callExpression(
|
|
75
|
+
t.memberExpression(t.identifier("document"), t.identifier("createElement")),
|
|
76
|
+
[t.stringLiteral(tag)],
|
|
77
|
+
);
|
|
72
78
|
}
|
|
73
79
|
|
|
74
80
|
/**
|
|
@@ -76,24 +82,24 @@ export function getCreateElement(
|
|
|
76
82
|
* When parentVar is provided, passes it to claimText() for SPA fallback.
|
|
77
83
|
*/
|
|
78
84
|
export function getCreateText(
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
85
|
+
hydrate: boolean,
|
|
86
|
+
nodesVar = "__nodes",
|
|
87
|
+
parentVar?: string,
|
|
82
88
|
): t.Expression {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
89
|
+
if (hydrate) {
|
|
90
|
+
const args: t.Expression[] = [t.identifier(nodesVar)];
|
|
91
|
+
if (parentVar) {
|
|
92
|
+
args.push(t.identifier(parentVar));
|
|
93
|
+
}
|
|
94
|
+
return t.callExpression(t.identifier("claimText"), args);
|
|
95
|
+
}
|
|
96
|
+
return t.callExpression(
|
|
97
|
+
t.memberExpression(
|
|
98
|
+
t.identifier("document"),
|
|
99
|
+
t.identifier("createTextNode"),
|
|
100
|
+
),
|
|
101
|
+
[t.stringLiteral("")],
|
|
102
|
+
);
|
|
97
103
|
}
|
|
98
104
|
|
|
99
105
|
/**
|
|
@@ -101,24 +107,24 @@ export function getCreateText(
|
|
|
101
107
|
* Returns the generated variable name for use by children.
|
|
102
108
|
*/
|
|
103
109
|
export function buildHydrationScope(
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
110
|
+
parentVar: string,
|
|
111
|
+
statements: t.Statement[],
|
|
112
|
+
nodesVar: string,
|
|
107
113
|
): void {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
114
|
+
statements.push(
|
|
115
|
+
t.variableDeclaration("const", [
|
|
116
|
+
t.variableDeclarator(
|
|
117
|
+
t.identifier(nodesVar),
|
|
118
|
+
t.callExpression(
|
|
119
|
+
t.memberExpression(t.identifier("Array"), t.identifier("from")),
|
|
120
|
+
[
|
|
121
|
+
t.memberExpression(
|
|
122
|
+
t.identifier(parentVar),
|
|
123
|
+
t.identifier("childNodes"),
|
|
124
|
+
),
|
|
125
|
+
],
|
|
126
|
+
),
|
|
127
|
+
),
|
|
128
|
+
]),
|
|
129
|
+
);
|
|
124
130
|
}
|
package/src/babel/util/bind.ts
CHANGED
|
@@ -1,135 +1,126 @@
|
|
|
1
|
-
import { types as t } from "@babel/core";
|
|
2
|
-
|
|
3
|
-
const BIND_EVENT: Record<string, string> = {
|
|
4
|
-
value: "input",
|
|
5
|
-
checked: "change",
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
),
|
|
128
|
-
),
|
|
129
|
-
]),
|
|
130
|
-
),
|
|
131
|
-
],
|
|
132
|
-
),
|
|
133
|
-
),
|
|
134
|
-
);
|
|
135
|
-
}
|
|
1
|
+
import { types as t } from "@babel/core";
|
|
2
|
+
|
|
3
|
+
const BIND_EVENT: Record<string, string> = {
|
|
4
|
+
value: "input",
|
|
5
|
+
checked: "change",
|
|
6
|
+
innerHTML: "input",
|
|
7
|
+
textContent: "input",
|
|
8
|
+
group: "change",
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export function buildBind(
|
|
12
|
+
varName: string,
|
|
13
|
+
bindProp: string,
|
|
14
|
+
attr: t.JSXAttribute,
|
|
15
|
+
statements: t.Statement[],
|
|
16
|
+
): void {
|
|
17
|
+
const signal = (attr.value as t.JSXExpressionContainer)
|
|
18
|
+
.expression as t.CallExpression; // already text()
|
|
19
|
+
|
|
20
|
+
const signalId = signal.callee as t.Identifier; // text — for .set()
|
|
21
|
+
|
|
22
|
+
const event = BIND_EVENT[bindProp] ?? "input";
|
|
23
|
+
|
|
24
|
+
// createEffect(() => _el.prop = text())
|
|
25
|
+
statements.push(
|
|
26
|
+
t.expressionStatement(
|
|
27
|
+
t.callExpression(t.identifier("createEffect"), [
|
|
28
|
+
t.arrowFunctionExpression(
|
|
29
|
+
[],
|
|
30
|
+
t.blockStatement([
|
|
31
|
+
t.expressionStatement(
|
|
32
|
+
t.assignmentExpression(
|
|
33
|
+
"=",
|
|
34
|
+
t.memberExpression(t.identifier(varName), t.identifier(bindProp)),
|
|
35
|
+
signal,
|
|
36
|
+
),
|
|
37
|
+
),
|
|
38
|
+
]),
|
|
39
|
+
),
|
|
40
|
+
]),
|
|
41
|
+
),
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
// addEventListener(event, e => text.set(e.target.prop))
|
|
45
|
+
statements.push(
|
|
46
|
+
t.expressionStatement(
|
|
47
|
+
t.callExpression(
|
|
48
|
+
t.memberExpression(t.identifier(varName), t.identifier("addEventListener")),
|
|
49
|
+
[
|
|
50
|
+
t.stringLiteral(event),
|
|
51
|
+
t.arrowFunctionExpression(
|
|
52
|
+
[t.identifier("e")],
|
|
53
|
+
t.callExpression(
|
|
54
|
+
t.memberExpression(signalId, t.identifier("set")),
|
|
55
|
+
[
|
|
56
|
+
t.memberExpression(
|
|
57
|
+
t.memberExpression(t.identifier("e"), t.identifier("target")),
|
|
58
|
+
t.identifier(bindProp),
|
|
59
|
+
),
|
|
60
|
+
],
|
|
61
|
+
),
|
|
62
|
+
),
|
|
63
|
+
],
|
|
64
|
+
),
|
|
65
|
+
),
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export function buildProxyBind(
|
|
70
|
+
varName: string,
|
|
71
|
+
bindProp: string,
|
|
72
|
+
attr: t.JSXAttribute,
|
|
73
|
+
statements: t.Statement[],
|
|
74
|
+
signal: t.MemberExpression, // already form().name
|
|
75
|
+
): void {
|
|
76
|
+
const event = BIND_EVENT[bindProp] ?? "input";
|
|
77
|
+
|
|
78
|
+
// createEffect(() => el.prop = form().name)
|
|
79
|
+
statements.push(
|
|
80
|
+
t.expressionStatement(
|
|
81
|
+
t.callExpression(t.identifier("createEffect"), [
|
|
82
|
+
t.arrowFunctionExpression(
|
|
83
|
+
[],
|
|
84
|
+
t.blockStatement([
|
|
85
|
+
t.expressionStatement(
|
|
86
|
+
t.assignmentExpression(
|
|
87
|
+
"=",
|
|
88
|
+
t.memberExpression(t.identifier(varName), t.identifier(bindProp)),
|
|
89
|
+
signal,
|
|
90
|
+
),
|
|
91
|
+
),
|
|
92
|
+
]),
|
|
93
|
+
),
|
|
94
|
+
]),
|
|
95
|
+
),
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
// addEventListener(event, e => { form().name = e.target.prop })
|
|
99
|
+
statements.push(
|
|
100
|
+
t.expressionStatement(
|
|
101
|
+
t.callExpression(
|
|
102
|
+
t.memberExpression(t.identifier(varName), t.identifier("addEventListener")),
|
|
103
|
+
[
|
|
104
|
+
t.stringLiteral(event),
|
|
105
|
+
t.arrowFunctionExpression(
|
|
106
|
+
[t.identifier("e")],
|
|
107
|
+
t.blockStatement([
|
|
108
|
+
t.expressionStatement(
|
|
109
|
+
t.assignmentExpression(
|
|
110
|
+
"=",
|
|
111
|
+
signal as unknown as t.LVal, // form().name — valid LVal
|
|
112
|
+
t.memberExpression(
|
|
113
|
+
t.memberExpression(t.identifier("e"), t.identifier("target")),
|
|
114
|
+
t.identifier(bindProp),
|
|
115
|
+
),
|
|
116
|
+
),
|
|
117
|
+
),
|
|
118
|
+
]),
|
|
119
|
+
),
|
|
120
|
+
],
|
|
121
|
+
),
|
|
122
|
+
),
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
|