@esportsplus/template 0.31.1 → 0.31.3
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/transformer/codegen.js +12 -53
- package/package.json +3 -3
- package/src/transformer/codegen.ts +12 -70
|
@@ -3,7 +3,7 @@ import { analyzeExpression, generateAttributeBinding, generateSpreadBindings } f
|
|
|
3
3
|
import { ts } from '@esportsplus/typescript';
|
|
4
4
|
import parser from './parser.js';
|
|
5
5
|
const ARROW_EMPTY_PARAMS = /\(\s*\)\s*=>\s*$/;
|
|
6
|
-
let currentChecker, hoistedFactories = new Map(), htmlToTemplateId = new Map(),
|
|
6
|
+
let currentChecker, hoistedFactories = new Map(), htmlToTemplateId = new Map(), ns = '';
|
|
7
7
|
function collectNestedTemplateReplacements(node, exprStart, sourceFile, replacements) {
|
|
8
8
|
if (isNestedHtmlTemplate(node)) {
|
|
9
9
|
replacements.push({
|
|
@@ -17,24 +17,7 @@ function collectNestedTemplateReplacements(node, exprStart, sourceFile, replacem
|
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
19
|
function generateImports() {
|
|
20
|
-
|
|
21
|
-
if (needsArraySlot) {
|
|
22
|
-
specifiers.push(`ArraySlot as ${nameArraySlot}`);
|
|
23
|
-
}
|
|
24
|
-
if (needsEffectSlot) {
|
|
25
|
-
specifiers.push(`EffectSlot as ${nameEffectSlot}`);
|
|
26
|
-
}
|
|
27
|
-
if (needsAttr) {
|
|
28
|
-
specifiers.push(`attributes as ${nameAttr}`);
|
|
29
|
-
}
|
|
30
|
-
if (needsEvent) {
|
|
31
|
-
specifiers.push(`event as ${nameEvent}`);
|
|
32
|
-
}
|
|
33
|
-
if (needsSlot) {
|
|
34
|
-
specifiers.push(`slot as ${nameSlot}`);
|
|
35
|
-
}
|
|
36
|
-
specifiers.push(`template as ${nameTemplate}`);
|
|
37
|
-
return `import { ${specifiers.join(', ')} } from '@esportsplus/template';`;
|
|
20
|
+
return `import * as ${ns} from '@esportsplus/template';`;
|
|
38
21
|
}
|
|
39
22
|
function generateNestedTemplateCode(node, sourceFile) {
|
|
40
23
|
let expressions = [], exprTexts = [], literals = [], template = node.template;
|
|
@@ -54,8 +37,7 @@ function generateNestedTemplateCode(node, sourceFile) {
|
|
|
54
37
|
}
|
|
55
38
|
function generateNodeBinding(anchor, exprText, exprNode, sourceFile) {
|
|
56
39
|
if (!exprNode) {
|
|
57
|
-
|
|
58
|
-
return `${nameSlot}(${anchor}, ${exprText});`;
|
|
40
|
+
return `${ns}.slot(${anchor}, ${exprText});`;
|
|
59
41
|
}
|
|
60
42
|
if (isNestedHtmlTemplate(exprNode)) {
|
|
61
43
|
return `${anchor}.parentNode.insertBefore(${generateNestedTemplateCode(exprNode, sourceFile)}, ${anchor});`;
|
|
@@ -63,18 +45,15 @@ function generateNodeBinding(anchor, exprText, exprNode, sourceFile) {
|
|
|
63
45
|
let slotType = analyzeExpression(exprNode, currentChecker);
|
|
64
46
|
switch (slotType) {
|
|
65
47
|
case 'effect':
|
|
66
|
-
|
|
67
|
-
return `new ${nameEffectSlot}(${anchor}, ${exprText});`;
|
|
48
|
+
return `new ${ns}.EffectSlot(${anchor}, ${exprText});`;
|
|
68
49
|
case 'array-slot':
|
|
69
|
-
|
|
70
|
-
return `new ${nameArraySlot}(${anchor}, ${exprText});`;
|
|
50
|
+
return `new ${ns}.ArraySlot(${anchor}, ${exprText});`;
|
|
71
51
|
case 'static':
|
|
72
52
|
return `${anchor}.textContent = ${exprText};`;
|
|
73
53
|
case 'document-fragment':
|
|
74
54
|
return `${anchor}.parentNode.insertBefore(${exprText}, ${anchor});`;
|
|
75
55
|
default:
|
|
76
|
-
|
|
77
|
-
return `${nameSlot}(${anchor}, ${exprText});`;
|
|
56
|
+
return `${ns}.slot(${anchor}, ${exprText});`;
|
|
78
57
|
}
|
|
79
58
|
}
|
|
80
59
|
function generateTemplateCode({ html, slots }, exprTexts, exprNodes, sourceFile, isArrowBody) {
|
|
@@ -117,14 +96,12 @@ function generateTemplateCode({ html, slots }, exprTexts, exprNodes, sourceFile,
|
|
|
117
96
|
if (name === 'spread') {
|
|
118
97
|
let bindings = generateSpreadBindings(exprNodes[index], exprTexts[index] || 'undefined', elementVar, sourceFile, currentChecker);
|
|
119
98
|
for (let k = 0, o = bindings.length; k < o; k++) {
|
|
120
|
-
trackBindingUsage(bindings[k]);
|
|
121
99
|
code.push(bindings[k]);
|
|
122
100
|
}
|
|
123
101
|
index++;
|
|
124
102
|
}
|
|
125
103
|
else {
|
|
126
104
|
let binding = generateAttributeBinding(elementVar, name, exprTexts[index++] || 'undefined', slot.attributes.statics[name] || '');
|
|
127
|
-
trackBindingUsage(binding);
|
|
128
105
|
code.push(binding);
|
|
129
106
|
}
|
|
130
107
|
}
|
|
@@ -220,14 +197,6 @@ function rewriteExpression(expr, sourceFile) {
|
|
|
220
197
|
collectNestedTemplateReplacements(expr, exprStart, sourceFile, replacements);
|
|
221
198
|
return applyReplacementsReverse(expr.getText(sourceFile), replacements);
|
|
222
199
|
}
|
|
223
|
-
function trackBindingUsage(binding) {
|
|
224
|
-
if (binding.startsWith(nameEvent + '.')) {
|
|
225
|
-
needsEvent = true;
|
|
226
|
-
}
|
|
227
|
-
else if (binding.startsWith(nameAttr + '.')) {
|
|
228
|
-
needsAttr = true;
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
200
|
const addArraySlotImport = (code) => {
|
|
232
201
|
return addImport(code, '@esportsplus/template', ['ArraySlot']);
|
|
233
202
|
};
|
|
@@ -237,17 +206,7 @@ const generateCode = (templates, originalCode, sourceFile) => {
|
|
|
237
206
|
}
|
|
238
207
|
hoistedFactories.clear();
|
|
239
208
|
htmlToTemplateId.clear();
|
|
240
|
-
|
|
241
|
-
nameAttr = uid('attr');
|
|
242
|
-
nameEffectSlot = uid('EffectSlot');
|
|
243
|
-
nameEvent = uid('event');
|
|
244
|
-
nameSlot = uid('slot');
|
|
245
|
-
nameTemplate = uid('template');
|
|
246
|
-
needsArraySlot = false;
|
|
247
|
-
needsAttr = false;
|
|
248
|
-
needsEffectSlot = false;
|
|
249
|
-
needsEvent = false;
|
|
250
|
-
needsSlot = false;
|
|
209
|
+
ns = uid('t');
|
|
251
210
|
let rootTemplates = templates.filter(t => !isNestedTemplate(t, templates));
|
|
252
211
|
if (rootTemplates.length === 0) {
|
|
253
212
|
return { changed: false, code: originalCode };
|
|
@@ -280,7 +239,7 @@ const generateCode = (templates, originalCode, sourceFile) => {
|
|
|
280
239
|
if (changed && hoistedFactories.size > 0) {
|
|
281
240
|
let factories = [];
|
|
282
241
|
for (let [id, html] of hoistedFactories) {
|
|
283
|
-
factories.push(`const ${id} = ${
|
|
242
|
+
factories.push(`const ${id} = ${ns}.template(\`${html}\`);`);
|
|
284
243
|
}
|
|
285
244
|
code = generateImports() + '\n\n' + factories.join('\n') + '\n\n' + code;
|
|
286
245
|
}
|
|
@@ -294,7 +253,7 @@ const generateReactiveInlining = (calls, code, sourceFile) => {
|
|
|
294
253
|
for (let i = calls.length - 1; i >= 0; i--) {
|
|
295
254
|
let call = calls[i];
|
|
296
255
|
result = result.slice(0, call.start);
|
|
297
|
-
result += `new ${
|
|
256
|
+
result += `new ${ns}.ArraySlot(
|
|
298
257
|
${printer.printNode(ts.EmitHint.Expression, call.arrayArg, sourceFile)},
|
|
299
258
|
${printer.printNode(ts.EmitHint.Expression, call.callbackArg, sourceFile)}
|
|
300
259
|
)`;
|
|
@@ -303,9 +262,9 @@ const generateReactiveInlining = (calls, code, sourceFile) => {
|
|
|
303
262
|
return result;
|
|
304
263
|
};
|
|
305
264
|
const getNames = () => ({
|
|
306
|
-
attr:
|
|
307
|
-
event:
|
|
308
|
-
slot:
|
|
265
|
+
attr: `${ns}.attributes`,
|
|
266
|
+
event: `${ns}.event`,
|
|
267
|
+
slot: `${ns}.slot`
|
|
309
268
|
});
|
|
310
269
|
const needsArraySlotImport = (sourceFile) => {
|
|
311
270
|
return hasArraySlotUsage(sourceFile) && !hasArraySlotImport(sourceFile);
|
package/package.json
CHANGED
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
"author": "ICJR",
|
|
3
3
|
"dependencies": {
|
|
4
4
|
"@esportsplus/queue": "^0.2.0",
|
|
5
|
-
"@esportsplus/reactivity": "^0.
|
|
5
|
+
"@esportsplus/reactivity": "^0.24.3",
|
|
6
6
|
"@esportsplus/utilities": "^0.27.2",
|
|
7
7
|
"serve": "^14.2.5"
|
|
8
8
|
},
|
|
9
9
|
"devDependencies": {
|
|
10
|
-
"@esportsplus/typescript": "^0.
|
|
10
|
+
"@esportsplus/typescript": "^0.17.0",
|
|
11
11
|
"@types/node": "^25.0.3",
|
|
12
12
|
"vite": "^7.3.0",
|
|
13
13
|
"vite-tsconfig-paths": "^6.0.3"
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
},
|
|
41
41
|
"type": "module",
|
|
42
42
|
"types": "./build/index.d.ts",
|
|
43
|
-
"version": "0.31.
|
|
43
|
+
"version": "0.31.3",
|
|
44
44
|
"scripts": {
|
|
45
45
|
"build": "tsc",
|
|
46
46
|
"build:test": "vite build --config test/vite.config.ts",
|
|
@@ -37,17 +37,7 @@ const ARROW_EMPTY_PARAMS = /\(\s*\)\s*=>\s*$/;
|
|
|
37
37
|
let currentChecker: ts.TypeChecker | undefined,
|
|
38
38
|
hoistedFactories = new Map<string, string>(),
|
|
39
39
|
htmlToTemplateId = new Map<string, string>(),
|
|
40
|
-
|
|
41
|
-
nameAttr = '',
|
|
42
|
-
nameEffectSlot = '',
|
|
43
|
-
nameEvent = '',
|
|
44
|
-
nameSlot = '',
|
|
45
|
-
nameTemplate = '',
|
|
46
|
-
needsArraySlot = false,
|
|
47
|
-
needsAttr = false,
|
|
48
|
-
needsEffectSlot = false,
|
|
49
|
-
needsEvent = false,
|
|
50
|
-
needsSlot = false;
|
|
40
|
+
ns = '';
|
|
51
41
|
|
|
52
42
|
|
|
53
43
|
function collectNestedTemplateReplacements(
|
|
@@ -69,31 +59,7 @@ function collectNestedTemplateReplacements(
|
|
|
69
59
|
}
|
|
70
60
|
|
|
71
61
|
function generateImports(): string {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
if (needsArraySlot) {
|
|
75
|
-
specifiers.push(`ArraySlot as ${nameArraySlot}`);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
if (needsEffectSlot) {
|
|
79
|
-
specifiers.push(`EffectSlot as ${nameEffectSlot}`);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
if (needsAttr) {
|
|
83
|
-
specifiers.push(`attributes as ${nameAttr}`);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
if (needsEvent) {
|
|
87
|
-
specifiers.push(`event as ${nameEvent}`);
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
if (needsSlot) {
|
|
91
|
-
specifiers.push(`slot as ${nameSlot}`);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
specifiers.push(`template as ${nameTemplate}`);
|
|
95
|
-
|
|
96
|
-
return `import { ${specifiers.join(', ')} } from '@esportsplus/template';`;
|
|
62
|
+
return `import * as ${ns} from '@esportsplus/template';`;
|
|
97
63
|
}
|
|
98
64
|
|
|
99
65
|
function generateNestedTemplateCode(node: ts.TaggedTemplateExpression, sourceFile: ts.SourceFile): string {
|
|
@@ -128,8 +94,7 @@ function generateNestedTemplateCode(node: ts.TaggedTemplateExpression, sourceFil
|
|
|
128
94
|
|
|
129
95
|
function generateNodeBinding(anchor: string, exprText: string, exprNode: ts.Expression | undefined, sourceFile: ts.SourceFile): string {
|
|
130
96
|
if (!exprNode) {
|
|
131
|
-
|
|
132
|
-
return `${nameSlot}(${anchor}, ${exprText});`;
|
|
97
|
+
return `${ns}.slot(${anchor}, ${exprText});`;
|
|
133
98
|
}
|
|
134
99
|
|
|
135
100
|
if (isNestedHtmlTemplate(exprNode)) {
|
|
@@ -140,12 +105,10 @@ function generateNodeBinding(anchor: string, exprText: string, exprNode: ts.Expr
|
|
|
140
105
|
|
|
141
106
|
switch (slotType) {
|
|
142
107
|
case 'effect':
|
|
143
|
-
|
|
144
|
-
return `new ${nameEffectSlot}(${anchor}, ${exprText});`;
|
|
108
|
+
return `new ${ns}.EffectSlot(${anchor}, ${exprText});`;
|
|
145
109
|
|
|
146
110
|
case 'array-slot':
|
|
147
|
-
|
|
148
|
-
return `new ${nameArraySlot}(${anchor}, ${exprText});`;
|
|
111
|
+
return `new ${ns}.ArraySlot(${anchor}, ${exprText});`;
|
|
149
112
|
|
|
150
113
|
case 'static':
|
|
151
114
|
return `${anchor}.textContent = ${exprText};`;
|
|
@@ -154,8 +117,7 @@ function generateNodeBinding(anchor: string, exprText: string, exprNode: ts.Expr
|
|
|
154
117
|
return `${anchor}.parentNode.insertBefore(${exprText}, ${anchor});`;
|
|
155
118
|
|
|
156
119
|
default:
|
|
157
|
-
|
|
158
|
-
return `${nameSlot}(${anchor}, ${exprText});`;
|
|
120
|
+
return `${ns}.slot(${anchor}, ${exprText});`;
|
|
159
121
|
}
|
|
160
122
|
}
|
|
161
123
|
|
|
@@ -237,7 +199,6 @@ function generateTemplateCode(
|
|
|
237
199
|
);
|
|
238
200
|
|
|
239
201
|
for (let k = 0, o = bindings.length; k < o; k++) {
|
|
240
|
-
trackBindingUsage(bindings[k]);
|
|
241
202
|
code.push(bindings[k]);
|
|
242
203
|
}
|
|
243
204
|
|
|
@@ -251,7 +212,6 @@ function generateTemplateCode(
|
|
|
251
212
|
slot.attributes.statics[name] || ''
|
|
252
213
|
);
|
|
253
214
|
|
|
254
|
-
trackBindingUsage(binding);
|
|
255
215
|
code.push(binding);
|
|
256
216
|
}
|
|
257
217
|
}
|
|
@@ -381,14 +341,6 @@ function rewriteExpression(expr: ts.Expression, sourceFile: ts.SourceFile): stri
|
|
|
381
341
|
return applyReplacementsReverse(expr.getText(sourceFile), replacements);
|
|
382
342
|
}
|
|
383
343
|
|
|
384
|
-
function trackBindingUsage(binding: string): void {
|
|
385
|
-
if (binding.startsWith(nameEvent + '.')) {
|
|
386
|
-
needsEvent = true;
|
|
387
|
-
}
|
|
388
|
-
else if (binding.startsWith(nameAttr + '.')) {
|
|
389
|
-
needsAttr = true;
|
|
390
|
-
}
|
|
391
|
-
}
|
|
392
344
|
|
|
393
345
|
|
|
394
346
|
const addArraySlotImport = (code: string): string => {
|
|
@@ -402,17 +354,7 @@ const generateCode = (templates: TemplateInfo[], originalCode: string, sourceFil
|
|
|
402
354
|
|
|
403
355
|
hoistedFactories.clear();
|
|
404
356
|
htmlToTemplateId.clear();
|
|
405
|
-
|
|
406
|
-
nameAttr = uid('attr');
|
|
407
|
-
nameEffectSlot = uid('EffectSlot');
|
|
408
|
-
nameEvent = uid('event');
|
|
409
|
-
nameSlot = uid('slot');
|
|
410
|
-
nameTemplate = uid('template');
|
|
411
|
-
needsArraySlot = false;
|
|
412
|
-
needsAttr = false;
|
|
413
|
-
needsEffectSlot = false;
|
|
414
|
-
needsEvent = false;
|
|
415
|
-
needsSlot = false;
|
|
357
|
+
ns = uid('t');
|
|
416
358
|
|
|
417
359
|
let rootTemplates = templates.filter(t => !isNestedTemplate(t, templates));
|
|
418
360
|
|
|
@@ -468,7 +410,7 @@ const generateCode = (templates: TemplateInfo[], originalCode: string, sourceFil
|
|
|
468
410
|
let factories: string[] = [];
|
|
469
411
|
|
|
470
412
|
for (let [id, html] of hoistedFactories) {
|
|
471
|
-
factories.push(`const ${id} = ${
|
|
413
|
+
factories.push(`const ${id} = ${ns}.template(\`${html}\`);`);
|
|
472
414
|
}
|
|
473
415
|
|
|
474
416
|
code = generateImports() + '\n\n' + factories.join('\n') + '\n\n' + code;
|
|
@@ -489,7 +431,7 @@ const generateReactiveInlining = (calls: ReactiveCallInfo[], code: string, sourc
|
|
|
489
431
|
let call = calls[i];
|
|
490
432
|
|
|
491
433
|
result = result.slice(0, call.start);
|
|
492
|
-
result += `new ${
|
|
434
|
+
result += `new ${ns}.ArraySlot(
|
|
493
435
|
${printer.printNode(ts.EmitHint.Expression, call.arrayArg, sourceFile)},
|
|
494
436
|
${printer.printNode(ts.EmitHint.Expression, call.callbackArg, sourceFile)}
|
|
495
437
|
)`;
|
|
@@ -500,9 +442,9 @@ const generateReactiveInlining = (calls: ReactiveCallInfo[], code: string, sourc
|
|
|
500
442
|
};
|
|
501
443
|
|
|
502
444
|
const getNames = () => ({
|
|
503
|
-
attr:
|
|
504
|
-
event:
|
|
505
|
-
slot:
|
|
445
|
+
attr: `${ns}.attributes`,
|
|
446
|
+
event: `${ns}.event`,
|
|
447
|
+
slot: `${ns}.slot`
|
|
506
448
|
});
|
|
507
449
|
|
|
508
450
|
const needsArraySlotImport = (sourceFile: ts.SourceFile): boolean => {
|