@esportsplus/template 0.32.0 → 0.32.2
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/build/attributes.js +1 -2
- package/build/constants.d.ts +18 -3
- package/build/constants.js +31 -4
- package/build/html.d.ts +3 -3
- package/build/index.d.ts +3 -3
- package/build/index.js +3 -3
- package/build/slot/array.d.ts +2 -2
- package/build/slot/array.js +5 -4
- package/build/slot/render.js +3 -2
- package/build/transformer/codegen.d.ts +3 -9
- package/build/transformer/codegen.js +90 -147
- package/build/transformer/index.d.ts +1 -5
- package/build/transformer/index.js +30 -46
- package/build/transformer/parser.d.ts +3 -2
- package/build/transformer/parser.js +4 -4
- package/build/transformer/plugins/tsc.d.ts +2 -2
- package/build/transformer/plugins/tsc.js +3 -4
- package/build/transformer/plugins/vite.d.ts +11 -3
- package/build/transformer/plugins/vite.js +7 -37
- package/build/transformer/ts-parser.d.ts +1 -2
- package/build/transformer/ts-parser.js +28 -41
- package/build/transformer/type-analyzer.d.ts +4 -5
- package/build/transformer/type-analyzer.js +73 -118
- package/build/types.d.ts +1 -1
- package/package.json +7 -7
- package/src/attributes.ts +1 -4
- package/src/constants.ts +42 -6
- package/src/html.ts +3 -3
- package/src/index.ts +5 -3
- package/src/slot/array.ts +9 -6
- package/src/slot/render.ts +5 -2
- package/src/transformer/codegen.ts +119 -189
- package/src/transformer/index.ts +34 -54
- package/src/transformer/parser.ts +10 -7
- package/src/transformer/plugins/tsc.ts +3 -5
- package/src/transformer/plugins/vite.ts +7 -47
- package/src/transformer/ts-parser.ts +34 -54
- package/src/transformer/type-analyzer.ts +90 -158
- package/src/types.ts +1 -1
- package/test/vite.config.ts +1 -1
- package/build/event/constants.d.ts +0 -3
- package/build/event/constants.js +0 -13
- package/src/event/constants.ts +0 -16
- package/storage/rewrite-analysis-2026-01-04.md +0 -439
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
COMPILER_TYPES,
|
|
3
|
+
PACKAGE,
|
|
4
|
+
SLOT_HTML
|
|
5
|
+
} from '../constants';
|
|
3
6
|
|
|
4
7
|
|
|
5
8
|
type NodePath = ('firstChild' | 'firstElementChild' | 'nextElementSibling' | 'nextSibling')[];
|
|
@@ -92,8 +95,8 @@ const parse = (literals: string[]) => {
|
|
|
92
95
|
parsed = html.split(SLOT_MARKER),
|
|
93
96
|
slot = 0,
|
|
94
97
|
slots: (
|
|
95
|
-
{ path: NodePath; type:
|
|
96
|
-
{ attributes: typeof attributes[string]; path: NodePath; type:
|
|
98
|
+
{ path: NodePath; type: COMPILER_TYPES.NodeSlot } |
|
|
99
|
+
{ attributes: typeof attributes[string]; path: NodePath; type: COMPILER_TYPES.AttributeSlot }
|
|
97
100
|
)[] = [];
|
|
98
101
|
|
|
99
102
|
{
|
|
@@ -186,10 +189,10 @@ const parse = (literals: string[]) => {
|
|
|
186
189
|
let attrs = attributes[attr];
|
|
187
190
|
|
|
188
191
|
if (!attrs) {
|
|
189
|
-
throw new Error(
|
|
192
|
+
throw new Error(`${PACKAGE}: attribute metadata could not be found for '${attr}'`);
|
|
190
193
|
}
|
|
191
194
|
|
|
192
|
-
slots.push({ attributes: attrs, path, type:
|
|
195
|
+
slots.push({ attributes: attrs, path, type: COMPILER_TYPES.AttributeSlot });
|
|
193
196
|
|
|
194
197
|
for (let i = 0, n = attrs.names.length; i < n; i++) {
|
|
195
198
|
buffer += parsed[slot++];
|
|
@@ -204,7 +207,7 @@ const parse = (literals: string[]) => {
|
|
|
204
207
|
}
|
|
205
208
|
else if (type === NODE_SLOT) {
|
|
206
209
|
buffer += parsed[slot++] + SLOT_HTML;
|
|
207
|
-
slots.push({ path: methods(parent.children, parent.path, 'firstChild', 'nextSibling'), type:
|
|
210
|
+
slots.push({ path: methods(parent.children, parent.path, 'firstChild', 'nextSibling'), type: COMPILER_TYPES.NodeSlot });
|
|
208
211
|
}
|
|
209
212
|
|
|
210
213
|
if (n === slot) {
|
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { plugin } from '@esportsplus/typescript/transformer';
|
|
2
|
+
import { transform } from '..';
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
export default (
|
|
6
|
-
return createTransformer(program);
|
|
7
|
-
};
|
|
5
|
+
export default plugin.tsc(transform) as ReturnType<typeof plugin.tsc>;
|
|
@@ -1,49 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import { ts } from '@esportsplus/typescript';
|
|
1
|
+
import { plugin } from '@esportsplus/typescript/transformer';
|
|
2
|
+
import { PACKAGE } from '../../constants';
|
|
3
|
+
import { transform } from '..';
|
|
5
4
|
|
|
6
5
|
|
|
7
|
-
export default (
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
enforce: 'pre',
|
|
12
|
-
name: '@esportsplus/template/plugin-vite',
|
|
13
|
-
|
|
14
|
-
configResolved(config: ResolvedConfig) {
|
|
15
|
-
root = options?.root ?? config.root;
|
|
16
|
-
},
|
|
17
|
-
|
|
18
|
-
transform(code: string, id: string) {
|
|
19
|
-
if (!TRANSFORM_PATTERN.test(id) || id.includes('node_modules')) {
|
|
20
|
-
return null;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
if (!mightNeedTransform(code, { patterns: PATTERNS })) {
|
|
24
|
-
return null;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
try {
|
|
28
|
-
let sourceFile = ts.createSourceFile(id, code, ts.ScriptTarget.Latest, true),
|
|
29
|
-
result = transform(sourceFile, program.get(root));
|
|
30
|
-
|
|
31
|
-
if (!result.changed) {
|
|
32
|
-
return null;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
return { code: result.code, map: null };
|
|
36
|
-
}
|
|
37
|
-
catch (error) {
|
|
38
|
-
console.error(`@esportsplus/template: Error transforming ${id}:`, error);
|
|
39
|
-
return null;
|
|
40
|
-
}
|
|
41
|
-
},
|
|
42
|
-
|
|
43
|
-
watchChange(id: string) {
|
|
44
|
-
if (TRANSFORM_PATTERN.test(id)) {
|
|
45
|
-
program.delete(root);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
};
|
|
49
|
-
};
|
|
6
|
+
export default plugin.vite({
|
|
7
|
+
name: PACKAGE,
|
|
8
|
+
transform
|
|
9
|
+
});
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { COMPILER_ENTRYPOINT, COMPILER_ENTRYPOINT_REACTIVITY } from '../constants';
|
|
1
2
|
import { ts } from '@esportsplus/typescript';
|
|
2
3
|
|
|
3
4
|
|
|
@@ -19,51 +20,13 @@ type TemplateInfo = {
|
|
|
19
20
|
};
|
|
20
21
|
|
|
21
22
|
|
|
22
|
-
function extractTemplateInfo(node: ts.TaggedTemplateExpression, depth: number): TemplateInfo {
|
|
23
|
-
let expressions: ts.Expression[] = [],
|
|
24
|
-
literals: string[] = [],
|
|
25
|
-
template = node.template;
|
|
26
|
-
|
|
27
|
-
if (ts.isNoSubstitutionTemplateLiteral(template)) {
|
|
28
|
-
literals.push(template.text);
|
|
29
|
-
}
|
|
30
|
-
else if (ts.isTemplateExpression(template)) {
|
|
31
|
-
literals.push(template.head.text);
|
|
32
|
-
|
|
33
|
-
for (let i = 0, n = template.templateSpans.length; i < n; i++) {
|
|
34
|
-
let span = template.templateSpans[i];
|
|
35
|
-
|
|
36
|
-
expressions.push(span.expression);
|
|
37
|
-
literals.push(span.literal.text);
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
return {
|
|
42
|
-
depth,
|
|
43
|
-
end: node.end,
|
|
44
|
-
expressions,
|
|
45
|
-
literals,
|
|
46
|
-
node,
|
|
47
|
-
start: node.getStart()
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
function isFunctionNode(node: ts.Node): boolean {
|
|
52
|
-
return (
|
|
53
|
-
ts.isArrowFunction(node) ||
|
|
54
|
-
ts.isFunctionDeclaration(node) ||
|
|
55
|
-
ts.isFunctionExpression(node) ||
|
|
56
|
-
ts.isMethodDeclaration(node)
|
|
57
|
-
);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
23
|
function visitReactiveCalls(node: ts.Node, calls: ReactiveCallInfo[]): void {
|
|
61
24
|
if (
|
|
62
25
|
ts.isCallExpression(node) &&
|
|
63
26
|
ts.isPropertyAccessExpression(node.expression) &&
|
|
64
27
|
ts.isIdentifier(node.expression.expression) &&
|
|
65
|
-
node.expression.expression.text ===
|
|
66
|
-
node.expression.name.text ===
|
|
28
|
+
node.expression.expression.text === COMPILER_ENTRYPOINT &&
|
|
29
|
+
node.expression.name.text === COMPILER_ENTRYPOINT_REACTIVITY &&
|
|
67
30
|
node.arguments.length === 2
|
|
68
31
|
) {
|
|
69
32
|
calls.push({
|
|
@@ -79,10 +42,37 @@ function visitReactiveCalls(node: ts.Node, calls: ReactiveCallInfo[]): void {
|
|
|
79
42
|
}
|
|
80
43
|
|
|
81
44
|
function visitTemplates(node: ts.Node, depth: number, templates: TemplateInfo[]): void {
|
|
82
|
-
let nextDepth =
|
|
45
|
+
let nextDepth = (ts.isArrowFunction(node) || ts.isFunctionDeclaration(node) || ts.isFunctionExpression(node) || ts.isMethodDeclaration(node))
|
|
46
|
+
? depth + 1
|
|
47
|
+
: depth;
|
|
48
|
+
|
|
49
|
+
if (ts.isTaggedTemplateExpression(node) && ts.isIdentifier(node.tag) && node.tag.text === COMPILER_ENTRYPOINT) {
|
|
50
|
+
let expressions: ts.Expression[] = [],
|
|
51
|
+
literals: string[] = [],
|
|
52
|
+
template = node.template;
|
|
53
|
+
|
|
54
|
+
if (ts.isNoSubstitutionTemplateLiteral(template)) {
|
|
55
|
+
literals.push(template.text);
|
|
56
|
+
}
|
|
57
|
+
else if (ts.isTemplateExpression(template)) {
|
|
58
|
+
literals.push(template.head.text);
|
|
59
|
+
|
|
60
|
+
for (let i = 0, n = template.templateSpans.length; i < n; i++) {
|
|
61
|
+
let span = template.templateSpans[i];
|
|
62
|
+
|
|
63
|
+
expressions.push(span.expression);
|
|
64
|
+
literals.push(span.literal.text);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
83
67
|
|
|
84
|
-
|
|
85
|
-
|
|
68
|
+
templates.push({
|
|
69
|
+
depth,
|
|
70
|
+
end: node.end,
|
|
71
|
+
expressions,
|
|
72
|
+
literals,
|
|
73
|
+
node,
|
|
74
|
+
start: node.getStart()
|
|
75
|
+
});
|
|
86
76
|
}
|
|
87
77
|
|
|
88
78
|
ts.forEachChild(node, child => visitTemplates(child, nextDepth, templates));
|
|
@@ -108,16 +98,6 @@ const findReactiveCalls = (sourceFile: ts.SourceFile): ReactiveCallInfo[] => {
|
|
|
108
98
|
return calls;
|
|
109
99
|
};
|
|
110
100
|
|
|
111
|
-
const getTemplateExpressions = (info: TemplateInfo, sourceFile: ts.SourceFile): string[] => {
|
|
112
|
-
let exprs: string[] = [];
|
|
113
|
-
|
|
114
|
-
for (let i = 0, n = info.expressions.length; i < n; i++) {
|
|
115
|
-
exprs.push(info.expressions[i].getText(sourceFile));
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
return exprs;
|
|
119
|
-
};
|
|
120
|
-
|
|
121
101
|
|
|
122
|
-
export { findHtmlTemplates, findReactiveCalls
|
|
102
|
+
export { findHtmlTemplates, findReactiveCalls };
|
|
123
103
|
export type { ReactiveCallInfo, TemplateInfo };
|
|
@@ -1,21 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
COMPILER_ENTRYPOINT,
|
|
3
|
+
COMPILER_ENTRYPOINT_REACTIVITY,
|
|
4
|
+
COMPILER_TYPES,
|
|
5
|
+
DIRECT_ATTACH_EVENTS,
|
|
6
|
+
LIFECYCLE_EVENTS
|
|
7
|
+
} from '../constants';
|
|
3
8
|
import { ts } from '@esportsplus/typescript';
|
|
4
9
|
|
|
5
10
|
|
|
6
|
-
type AnalyzerContext = {
|
|
7
|
-
checker?: ts.TypeChecker;
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
type SlotType =
|
|
11
|
-
| 'array-slot'
|
|
12
|
-
| 'document-fragment'
|
|
13
|
-
| 'effect'
|
|
14
|
-
| 'node'
|
|
15
|
-
| 'primitive'
|
|
16
|
-
| 'static'
|
|
17
|
-
| 'unknown';
|
|
18
|
-
|
|
19
11
|
type SpreadAnalysis = {
|
|
20
12
|
canUnpack: boolean;
|
|
21
13
|
keys: string[];
|
|
@@ -51,188 +43,112 @@ function analyzeSpread(expr: ts.Expression, checker?: ts.TypeChecker): SpreadAna
|
|
|
51
43
|
|
|
52
44
|
if (checker && (ts.isIdentifier(expr) || ts.isPropertyAccessExpression(expr))) {
|
|
53
45
|
try {
|
|
54
|
-
let keys =
|
|
55
|
-
|
|
56
|
-
if (keys.length > 0) {
|
|
57
|
-
return { canUnpack: true, keys };
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
catch {
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
return { canUnpack: false, keys: [] };
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
function extractTypePropertyKeys(type: ts.Type): string[] {
|
|
68
|
-
let keys: string[] = [],
|
|
69
|
-
props = type.getProperties();
|
|
70
|
-
|
|
71
|
-
for (let i = 0, n = props.length; i < n; i++) {
|
|
72
|
-
let name = props[i].getName();
|
|
73
|
-
|
|
74
|
-
if (name.startsWith('__') || name.startsWith('[')) {
|
|
75
|
-
continue;
|
|
76
|
-
}
|
|
46
|
+
let keys: string[] = [],
|
|
47
|
+
props = checker.getTypeAtLocation(expr).getProperties();
|
|
77
48
|
|
|
78
|
-
|
|
79
|
-
|
|
49
|
+
for (let i = 0, n = props.length; i < n; i++) {
|
|
50
|
+
let name = props[i].getName();
|
|
80
51
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
function getObjectPropertyValue(expr: ts.ObjectLiteralExpression, key: string, sourceFile: ts.SourceFile): string | null {
|
|
85
|
-
for (let i = 0, n = expr.properties.length; i < n; i++) {
|
|
86
|
-
let prop = expr.properties[i];
|
|
52
|
+
if (name.startsWith('__') || name.startsWith('[')) {
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
87
55
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
? prop.name.text
|
|
91
|
-
: ts.isStringLiteral(prop.name) ? prop.name.text : null;
|
|
56
|
+
keys.push(name);
|
|
57
|
+
}
|
|
92
58
|
|
|
93
|
-
if (
|
|
94
|
-
return
|
|
59
|
+
if (keys.length > 0) {
|
|
60
|
+
return { canUnpack: true, keys };
|
|
95
61
|
}
|
|
96
62
|
}
|
|
97
|
-
|
|
98
|
-
return prop.name.text;
|
|
99
|
-
}
|
|
63
|
+
catch { }
|
|
100
64
|
}
|
|
101
65
|
|
|
102
|
-
return
|
|
66
|
+
return { canUnpack: false, keys: [] };
|
|
103
67
|
}
|
|
104
68
|
|
|
105
|
-
function
|
|
69
|
+
function inferCOMPILER_TYPES(expr: ts.Expression, checker?: ts.TypeChecker): COMPILER_TYPES {
|
|
106
70
|
while (ts.isParenthesizedExpression(expr)) {
|
|
107
71
|
expr = expr.expression;
|
|
108
72
|
}
|
|
109
73
|
|
|
110
74
|
if (ts.isArrowFunction(expr) || ts.isFunctionExpression(expr)) {
|
|
111
|
-
return
|
|
75
|
+
return COMPILER_TYPES.Effect;
|
|
112
76
|
}
|
|
113
77
|
|
|
114
78
|
if (
|
|
115
79
|
ts.isCallExpression(expr) &&
|
|
116
80
|
ts.isPropertyAccessExpression(expr.expression) &&
|
|
117
81
|
ts.isIdentifier(expr.expression.expression) &&
|
|
118
|
-
expr.expression.expression.text ===
|
|
119
|
-
expr.expression.name.text ===
|
|
82
|
+
expr.expression.expression.text === COMPILER_ENTRYPOINT &&
|
|
83
|
+
expr.expression.name.text === COMPILER_ENTRYPOINT_REACTIVITY
|
|
120
84
|
) {
|
|
121
|
-
return
|
|
85
|
+
return COMPILER_TYPES.ArraySlot;
|
|
122
86
|
}
|
|
123
87
|
|
|
124
|
-
if (ts.isTaggedTemplateExpression(expr) && ts.isIdentifier(expr.tag) && expr.tag.text ===
|
|
125
|
-
return
|
|
88
|
+
if (ts.isTaggedTemplateExpression(expr) && ts.isIdentifier(expr.tag) && expr.tag.text === COMPILER_ENTRYPOINT) {
|
|
89
|
+
return COMPILER_TYPES.DocumentFragment;
|
|
126
90
|
}
|
|
127
91
|
|
|
128
92
|
if (ts.isArrayLiteralExpression(expr)) {
|
|
129
|
-
return
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
if (ts.isStringLiteral(expr) || ts.isNoSubstitutionTemplateLiteral(expr)) {
|
|
133
|
-
return 'static';
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
if (ts.isNumericLiteral(expr)) {
|
|
137
|
-
return 'static';
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
if (expr.kind === ts.SyntaxKind.TrueKeyword || expr.kind === ts.SyntaxKind.FalseKeyword) {
|
|
141
|
-
return 'static';
|
|
93
|
+
return COMPILER_TYPES.ArraySlot;
|
|
142
94
|
}
|
|
143
95
|
|
|
144
|
-
if (
|
|
145
|
-
|
|
96
|
+
if (
|
|
97
|
+
ts.isNumericLiteral(expr) ||
|
|
98
|
+
ts.isStringLiteral(expr) ||
|
|
99
|
+
ts.isNoSubstitutionTemplateLiteral(expr) ||
|
|
100
|
+
expr.kind === ts.SyntaxKind.TrueKeyword ||
|
|
101
|
+
expr.kind === ts.SyntaxKind.FalseKeyword ||
|
|
102
|
+
expr.kind === ts.SyntaxKind.NullKeyword ||
|
|
103
|
+
expr.kind === ts.SyntaxKind.UndefinedKeyword
|
|
104
|
+
) {
|
|
105
|
+
return COMPILER_TYPES.Static;
|
|
146
106
|
}
|
|
147
107
|
|
|
148
108
|
if (ts.isTemplateExpression(expr)) {
|
|
149
|
-
return
|
|
109
|
+
return COMPILER_TYPES.Primitive;
|
|
150
110
|
}
|
|
151
111
|
|
|
152
112
|
if (ts.isConditionalExpression(expr)) {
|
|
153
|
-
let whenFalse =
|
|
154
|
-
whenTrue =
|
|
113
|
+
let whenFalse = inferCOMPILER_TYPES(expr.whenFalse, checker),
|
|
114
|
+
whenTrue = inferCOMPILER_TYPES(expr.whenTrue, checker);
|
|
155
115
|
|
|
156
116
|
if (whenTrue === whenFalse) {
|
|
157
117
|
return whenTrue;
|
|
158
118
|
}
|
|
159
119
|
|
|
160
|
-
if (whenTrue ===
|
|
161
|
-
return
|
|
120
|
+
if (whenTrue === COMPILER_TYPES.Effect || whenFalse === COMPILER_TYPES.Effect) {
|
|
121
|
+
return COMPILER_TYPES.Effect;
|
|
162
122
|
}
|
|
163
123
|
|
|
164
|
-
return
|
|
124
|
+
return COMPILER_TYPES.Unknown;
|
|
165
125
|
}
|
|
166
126
|
|
|
167
|
-
if (
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
if (ts.isIdentifier(expr)) {
|
|
171
|
-
try {
|
|
172
|
-
let type = checker.getTypeAtLocation(expr);
|
|
173
|
-
|
|
174
|
-
if (isTypeFunction(type, checker)) {
|
|
175
|
-
return 'effect';
|
|
176
|
-
}
|
|
127
|
+
if (checker && (ts.isIdentifier(expr) || ts.isPropertyAccessExpression(expr) || ts.isCallExpression(expr))) {
|
|
128
|
+
try {
|
|
129
|
+
let type = checker.getTypeAtLocation(expr);
|
|
177
130
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
catch {
|
|
131
|
+
if (isTypeFunction(type, checker)) {
|
|
132
|
+
return COMPILER_TYPES.Effect;
|
|
183
133
|
}
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
if (ts.isPropertyAccessExpression(expr)) {
|
|
187
|
-
try {
|
|
188
|
-
let type = checker.getTypeAtLocation(expr);
|
|
189
134
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
if (isTypeArray(type, checker)) {
|
|
195
|
-
return 'array-slot';
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
catch {
|
|
135
|
+
if (isTypeArray(type, checker)) {
|
|
136
|
+
return COMPILER_TYPES.ArraySlot;
|
|
199
137
|
}
|
|
200
138
|
}
|
|
201
|
-
|
|
202
|
-
if (ts.isCallExpression(expr)) {
|
|
203
|
-
try {
|
|
204
|
-
let type = checker.getTypeAtLocation(expr);
|
|
205
|
-
|
|
206
|
-
if (isTypeFunction(type, checker)) {
|
|
207
|
-
return 'effect';
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
if (isTypeArray(type, checker)) {
|
|
211
|
-
return 'array-slot';
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
catch {
|
|
215
|
-
}
|
|
139
|
+
catch {
|
|
216
140
|
}
|
|
217
141
|
}
|
|
218
142
|
|
|
219
|
-
return
|
|
143
|
+
return COMPILER_TYPES.Unknown;
|
|
220
144
|
}
|
|
221
145
|
|
|
222
146
|
function isTypeArray(type: ts.Type, checker: ts.TypeChecker): boolean {
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
if (typeStr.endsWith('[]') || typeStr.startsWith('Array<') || typeStr.startsWith('ReactiveArray<')) {
|
|
226
|
-
return true;
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
let symbol = type.getSymbol();
|
|
230
|
-
|
|
231
|
-
if (symbol && (symbol.getName() === 'Array' || symbol.getName() === 'ReactiveArray')) {
|
|
147
|
+
if (checker.isArrayType(type)) {
|
|
232
148
|
return true;
|
|
233
149
|
}
|
|
234
150
|
|
|
235
|
-
return
|
|
151
|
+
return type.getSymbol()?.getName() === 'ReactiveArray';
|
|
236
152
|
}
|
|
237
153
|
|
|
238
154
|
function isTypeFunction(type: ts.Type, checker: ts.TypeChecker): boolean {
|
|
@@ -252,49 +168,47 @@ function isTypeFunction(type: ts.Type, checker: ts.TypeChecker): boolean {
|
|
|
252
168
|
}
|
|
253
169
|
|
|
254
170
|
|
|
255
|
-
const analyzeExpression = (expr: ts.Expression, checker?: ts.TypeChecker):
|
|
256
|
-
return
|
|
171
|
+
const analyzeExpression = (expr: ts.Expression, checker?: ts.TypeChecker): COMPILER_TYPES => {
|
|
172
|
+
return inferCOMPILER_TYPES(expr, checker);
|
|
257
173
|
};
|
|
258
174
|
|
|
259
|
-
const generateAttributeBinding = (elementVar: string, name: string, expr: string, staticValue: string): string => {
|
|
260
|
-
let n = getNames();
|
|
261
|
-
|
|
175
|
+
const generateAttributeBinding = (elementVar: string, name: string, expr: string, staticValue: string, ns: string): string => {
|
|
262
176
|
if (name.startsWith('on') && name.length > 2) {
|
|
263
177
|
let event = name.slice(2).toLowerCase(),
|
|
264
178
|
key = name.toLowerCase();
|
|
265
179
|
|
|
266
180
|
if (LIFECYCLE_EVENTS.has(key)) {
|
|
267
|
-
return `${
|
|
181
|
+
return `${ns}.event.${key}(${elementVar}, ${expr});`;
|
|
268
182
|
}
|
|
269
183
|
|
|
270
184
|
if (DIRECT_ATTACH_EVENTS.has(key)) {
|
|
271
|
-
return `${
|
|
185
|
+
return `${ns}.event.direct(${elementVar}, '${event}', ${expr});`;
|
|
272
186
|
}
|
|
273
187
|
|
|
274
|
-
return `${
|
|
188
|
+
return `${ns}.event.delegate(${elementVar}, '${event}', ${expr});`;
|
|
275
189
|
}
|
|
276
190
|
|
|
277
191
|
if (name === 'class') {
|
|
278
|
-
return `${
|
|
192
|
+
return `${ns}.attributes.setClass(${elementVar}, '${staticValue}', ${expr});`;
|
|
279
193
|
}
|
|
280
194
|
|
|
281
195
|
if (name === 'spread') {
|
|
282
|
-
return `${
|
|
196
|
+
return `${ns}.attributes.spread(${elementVar}, ${expr});`;
|
|
283
197
|
}
|
|
284
198
|
|
|
285
199
|
if (name === 'style') {
|
|
286
|
-
return `${
|
|
200
|
+
return `${ns}.attributes.setStyle(${elementVar}, '${staticValue}', ${expr});`;
|
|
287
201
|
}
|
|
288
202
|
|
|
289
|
-
return `${
|
|
203
|
+
return `${ns}.attributes.setProperty(${elementVar}, '${name}', ${expr});`;
|
|
290
204
|
};
|
|
291
205
|
|
|
292
206
|
const generateSpreadBindings = (
|
|
293
207
|
expr: ts.Expression,
|
|
294
208
|
exprCode: string,
|
|
295
209
|
elementVar: string,
|
|
296
|
-
|
|
297
|
-
|
|
210
|
+
checker: ts.TypeChecker | undefined,
|
|
211
|
+
ns: string
|
|
298
212
|
): string[] => {
|
|
299
213
|
while (ts.isParenthesizedExpression(expr)) {
|
|
300
214
|
expr = expr.expression;
|
|
@@ -303,7 +217,7 @@ const generateSpreadBindings = (
|
|
|
303
217
|
let analysis = analyzeSpread(expr, checker);
|
|
304
218
|
|
|
305
219
|
if (!analysis.canUnpack) {
|
|
306
|
-
return [`${
|
|
220
|
+
return [`${ns}.attributes.spread(${elementVar}, ${exprCode});`];
|
|
307
221
|
}
|
|
308
222
|
|
|
309
223
|
let lines: string[] = [];
|
|
@@ -311,10 +225,29 @@ const generateSpreadBindings = (
|
|
|
311
225
|
if (ts.isObjectLiteralExpression(expr)) {
|
|
312
226
|
for (let i = 0, n = analysis.keys.length; i < n; i++) {
|
|
313
227
|
let key = analysis.keys[i],
|
|
314
|
-
value
|
|
228
|
+
value: string | null = null;
|
|
229
|
+
|
|
230
|
+
for (let j = 0, m = expr.properties.length; j < m; j++) {
|
|
231
|
+
let prop = expr.properties[j];
|
|
232
|
+
|
|
233
|
+
if (ts.isPropertyAssignment(prop)) {
|
|
234
|
+
let text = ts.isIdentifier(prop.name)
|
|
235
|
+
? prop.name.text
|
|
236
|
+
: ts.isStringLiteral(prop.name) ? prop.name.text : null;
|
|
237
|
+
|
|
238
|
+
if (text === key) {
|
|
239
|
+
value = prop.initializer.getText();
|
|
240
|
+
break;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
else if (ts.isShorthandPropertyAssignment(prop) && prop.name.text === key) {
|
|
244
|
+
value = prop.name.text;
|
|
245
|
+
break;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
315
248
|
|
|
316
249
|
if (value !== null) {
|
|
317
|
-
lines.push(generateAttributeBinding(elementVar, key, value, ''));
|
|
250
|
+
lines.push(generateAttributeBinding(elementVar, key, value, '', ns));
|
|
318
251
|
}
|
|
319
252
|
}
|
|
320
253
|
}
|
|
@@ -322,7 +255,7 @@ const generateSpreadBindings = (
|
|
|
322
255
|
for (let i = 0, n = analysis.keys.length; i < n; i++) {
|
|
323
256
|
let key = analysis.keys[i];
|
|
324
257
|
|
|
325
|
-
lines.push(generateAttributeBinding(elementVar, key, `${exprCode}.${key}`, ''));
|
|
258
|
+
lines.push(generateAttributeBinding(elementVar, key, `${exprCode}.${key}`, '', ns));
|
|
326
259
|
}
|
|
327
260
|
}
|
|
328
261
|
|
|
@@ -331,4 +264,3 @@ const generateSpreadBindings = (
|
|
|
331
264
|
|
|
332
265
|
|
|
333
266
|
export { analyzeExpression, generateAttributeBinding, generateSpreadBindings };
|
|
334
|
-
export type { SlotType };
|
package/src/types.ts
CHANGED
|
@@ -26,7 +26,7 @@ type Element = HTMLElement & Attributes<any>;
|
|
|
26
26
|
// - Importing from ^ causes 'cannot be named without a reference to...' error
|
|
27
27
|
type Primitive = bigint | boolean | null | number | string | undefined;
|
|
28
28
|
|
|
29
|
-
type Renderable<T> =
|
|
29
|
+
type Renderable<T> = ArraySlot<T> | DocumentFragment | Effect<T> | Node | NodeList | Primitive | Renderable<T>[];
|
|
30
30
|
|
|
31
31
|
type SlotGroup = {
|
|
32
32
|
head: Element;
|
package/test/vite.config.ts
CHANGED
package/build/event/constants.js
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
const DIRECT_ATTACH_EVENTS = new Set([
|
|
2
|
-
'onblur',
|
|
3
|
-
'onerror',
|
|
4
|
-
'onfocus', 'onfocusin', 'onfocusout',
|
|
5
|
-
'onload',
|
|
6
|
-
'onplay', 'onpause', 'onended', 'ontimeupdate',
|
|
7
|
-
'onreset',
|
|
8
|
-
'onscroll', 'onsubmit'
|
|
9
|
-
]);
|
|
10
|
-
const LIFECYCLE_EVENTS = new Set([
|
|
11
|
-
'onconnect', 'ondisconnect', 'onrender', 'onresize', 'ontick'
|
|
12
|
-
]);
|
|
13
|
-
export { DIRECT_ATTACH_EVENTS, LIFECYCLE_EVENTS };
|
package/src/event/constants.ts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
const DIRECT_ATTACH_EVENTS = new Set<string>([
|
|
2
|
-
'onblur',
|
|
3
|
-
'onerror',
|
|
4
|
-
'onfocus', 'onfocusin', 'onfocusout',
|
|
5
|
-
'onload',
|
|
6
|
-
'onplay', 'onpause', 'onended', 'ontimeupdate',
|
|
7
|
-
'onreset',
|
|
8
|
-
'onscroll', 'onsubmit'
|
|
9
|
-
]);
|
|
10
|
-
|
|
11
|
-
const LIFECYCLE_EVENTS = new Set<string>([
|
|
12
|
-
'onconnect', 'ondisconnect', 'onrender', 'onresize', 'ontick'
|
|
13
|
-
]);
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
export { DIRECT_ATTACH_EVENTS, LIFECYCLE_EVENTS };
|