@esportsplus/template 0.30.1 → 0.31.1
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/README.md +1 -26
- package/build/transformer/codegen.d.ts +1 -1
- package/build/transformer/codegen.js +1 -1
- package/build/transformer/index.d.ts +1 -1
- package/build/transformer/index.js +8 -7
- package/build/transformer/plugins/tsc.d.ts +1 -1
- package/build/transformer/plugins/vite.js +8 -5
- package/build/transformer/ts-parser.d.ts +1 -1
- package/build/transformer/ts-parser.js +1 -1
- package/build/transformer/type-analyzer.d.ts +1 -1
- package/build/transformer/type-analyzer.js +1 -1
- package/package.json +4 -10
- package/src/transformer/codegen.ts +1 -1
- package/src/transformer/index.ts +16 -7
- package/src/transformer/plugins/tsc.ts +1 -1
- package/src/transformer/plugins/vite.ts +16 -7
- package/src/transformer/ts-parser.ts +1 -1
- package/src/transformer/type-analyzer.ts +1 -1
- package/build/transformer/plugins/esbuild.d.ts +0 -5
- package/build/transformer/plugins/esbuild.js +0 -35
- package/src/transformer/plugins/esbuild.ts +0 -46
package/README.md
CHANGED
|
@@ -43,31 +43,6 @@ templatePlugin({
|
|
|
43
43
|
})
|
|
44
44
|
```
|
|
45
45
|
|
|
46
|
-
### ESBuild
|
|
47
|
-
|
|
48
|
-
```typescript
|
|
49
|
-
// esbuild.config.ts
|
|
50
|
-
import * as esbuild from 'esbuild';
|
|
51
|
-
import templatePlugin from '@esportsplus/template/plugins/esbuild';
|
|
52
|
-
|
|
53
|
-
await esbuild.build({
|
|
54
|
-
entryPoints: ['src/index.ts'],
|
|
55
|
-
bundle: true,
|
|
56
|
-
outfile: 'dist/bundle.js',
|
|
57
|
-
plugins: [
|
|
58
|
-
templatePlugin()
|
|
59
|
-
]
|
|
60
|
-
});
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
**Options:**
|
|
64
|
-
|
|
65
|
-
```typescript
|
|
66
|
-
templatePlugin({
|
|
67
|
-
root: string // Optional: project root (defaults to process.cwd())
|
|
68
|
-
})
|
|
69
|
-
```
|
|
70
|
-
|
|
71
46
|
### TypeScript Compiler (tsc)
|
|
72
47
|
|
|
73
48
|
For direct `tsc` compilation, use the transformer factory:
|
|
@@ -86,7 +61,7 @@ For direct `tsc` compilation, use the transformer factory:
|
|
|
86
61
|
Or programmatically:
|
|
87
62
|
|
|
88
63
|
```typescript
|
|
89
|
-
import ts from 'typescript';
|
|
64
|
+
import { ts } from '@esportsplus/typescript';
|
|
90
65
|
import templateTransformer from '@esportsplus/template/plugins/tsc';
|
|
91
66
|
|
|
92
67
|
const program = ts.createProgram(['src/index.ts'], {});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { addImport, applyReplacementsReverse, uid } from '@esportsplus/typescript/transformer';
|
|
2
2
|
import { analyzeExpression, generateAttributeBinding, generateSpreadBindings } from './type-analyzer.js';
|
|
3
|
-
import ts from 'typescript';
|
|
3
|
+
import { ts } from '@esportsplus/typescript';
|
|
4
4
|
import parser from './parser.js';
|
|
5
5
|
const ARROW_EMPTY_PARAMS = /\(\s*\)\s*=>\s*$/;
|
|
6
6
|
let currentChecker, hoistedFactories = new Map(), htmlToTemplateId = new Map(), nameArraySlot = '', nameAttr = '', nameEffectSlot = '', nameEvent = '', nameSlot = '', nameTemplate = '', needsArraySlot = false, needsAttr = false, needsEffectSlot = false, needsEvent = false, needsSlot = false;
|
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
import { mightNeedTransform } from '@esportsplus/typescript/transformer';
|
|
2
2
|
import { addArraySlotImport, generateCode, generateReactiveInlining, needsArraySlotImport, setTypeChecker } from './codegen.js';
|
|
3
3
|
import { findHtmlTemplates, findReactiveCalls } from './ts-parser.js';
|
|
4
|
-
import ts from 'typescript';
|
|
4
|
+
import { ts } from '@esportsplus/typescript';
|
|
5
5
|
const PATTERNS = ['html`', 'html.reactive'];
|
|
6
6
|
function createTransformer(program) {
|
|
7
|
-
let typeChecker = program.getTypeChecker();
|
|
7
|
+
let printer = ts.createPrinter(), typeChecker = program.getTypeChecker();
|
|
8
8
|
return (_context) => {
|
|
9
9
|
return (sourceFile) => {
|
|
10
|
-
let code =
|
|
10
|
+
let code = printer.printFile(sourceFile);
|
|
11
11
|
if (!mightNeedTransform(code, { patterns: PATTERNS })) {
|
|
12
12
|
return sourceFile;
|
|
13
13
|
}
|
|
14
|
+
let reparsed = ts.createSourceFile(sourceFile.fileName, code, sourceFile.languageVersion, true);
|
|
14
15
|
setTypeChecker(typeChecker);
|
|
15
|
-
let result = transformCode(code,
|
|
16
|
+
let result = transformCode(code, reparsed);
|
|
16
17
|
if (!result.changed) {
|
|
17
18
|
return sourceFile;
|
|
18
19
|
}
|
|
@@ -45,18 +46,18 @@ function transformCode(code, sourceFile) {
|
|
|
45
46
|
return { changed, code: result, sourceFile };
|
|
46
47
|
}
|
|
47
48
|
const transform = (sourceFile, program) => {
|
|
48
|
-
let code =
|
|
49
|
+
let printer = ts.createPrinter(), code = printer.printFile(sourceFile);
|
|
49
50
|
if (!mightNeedTransform(code, { patterns: PATTERNS })) {
|
|
50
51
|
return { changed: false, code, sourceFile };
|
|
51
52
|
}
|
|
53
|
+
let reparsed = ts.createSourceFile(sourceFile.fileName, code, sourceFile.languageVersion, true);
|
|
52
54
|
let programSourceFile = program.getSourceFile(sourceFile.fileName);
|
|
53
55
|
if (programSourceFile) {
|
|
54
56
|
setTypeChecker(program.getTypeChecker());
|
|
55
|
-
sourceFile = programSourceFile;
|
|
56
57
|
}
|
|
57
58
|
else {
|
|
58
59
|
setTypeChecker(undefined);
|
|
59
60
|
}
|
|
60
|
-
return transformCode(code,
|
|
61
|
+
return transformCode(code, reparsed);
|
|
61
62
|
};
|
|
62
63
|
export { createTransformer, mightNeedTransform, PATTERNS, transform };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { mightNeedTransform, PATTERNS
|
|
1
|
+
import { createTransformer, mightNeedTransform, PATTERNS } from '../index.js';
|
|
2
2
|
import { program, TRANSFORM_PATTERN } from '@esportsplus/typescript/transformer';
|
|
3
|
-
import ts from 'typescript';
|
|
3
|
+
import { ts } from '@esportsplus/typescript';
|
|
4
4
|
export default (options) => {
|
|
5
5
|
let root;
|
|
6
6
|
return {
|
|
@@ -17,11 +17,14 @@ export default (options) => {
|
|
|
17
17
|
return null;
|
|
18
18
|
}
|
|
19
19
|
try {
|
|
20
|
-
let sourceFile = ts.createSourceFile(id, code, ts.ScriptTarget.Latest, true), result = transform(sourceFile,
|
|
21
|
-
if (
|
|
20
|
+
let p = program.get(root), printer = ts.createPrinter(), sourceFile = ts.createSourceFile(id, code, ts.ScriptTarget.Latest, true), transformer = createTransformer(p), result = ts.transform(sourceFile, [transformer]), transformed = result.transformed[0];
|
|
21
|
+
if (transformed === sourceFile) {
|
|
22
|
+
result.dispose();
|
|
22
23
|
return null;
|
|
23
24
|
}
|
|
24
|
-
|
|
25
|
+
let output = printer.printFile(transformed);
|
|
26
|
+
result.dispose();
|
|
27
|
+
return { code: output, map: null };
|
|
25
28
|
}
|
|
26
29
|
catch (error) {
|
|
27
30
|
console.error(`@esportsplus/template: Error transforming ${id}:`, error);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import ts from 'typescript';
|
|
1
|
+
import { ts } from '@esportsplus/typescript';
|
|
2
2
|
type SlotType = 'array-slot' | 'document-fragment' | 'effect' | 'node' | 'primitive' | 'static' | 'unknown';
|
|
3
3
|
declare const analyzeExpression: (expr: ts.Expression, checker?: ts.TypeChecker) => SlotType;
|
|
4
4
|
declare const generateAttributeBinding: (elementVar: string, name: string, expr: string, staticValue: string) => string;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { getNames } from './codegen.js';
|
|
2
2
|
import { DIRECT_ATTACH_EVENTS, LIFECYCLE_EVENTS } from '../event/constants.js';
|
|
3
|
-
import ts from 'typescript';
|
|
3
|
+
import { ts } from '@esportsplus/typescript';
|
|
4
4
|
function analyzeSpread(expr, checker) {
|
|
5
5
|
while (ts.isParenthesizedExpression(expr)) {
|
|
6
6
|
expr = expr.expression;
|
package/package.json
CHANGED
|
@@ -2,15 +2,13 @@
|
|
|
2
2
|
"author": "ICJR",
|
|
3
3
|
"dependencies": {
|
|
4
4
|
"@esportsplus/queue": "^0.2.0",
|
|
5
|
-
"@esportsplus/reactivity": "^0.23.
|
|
5
|
+
"@esportsplus/reactivity": "^0.23.5",
|
|
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.15.0",
|
|
11
11
|
"@types/node": "^25.0.3",
|
|
12
|
-
"esbuild": "^0.27.2",
|
|
13
|
-
"typescript": "^5.9.3",
|
|
14
12
|
"vite": "^7.3.0",
|
|
15
13
|
"vite-tsconfig-paths": "^6.0.3"
|
|
16
14
|
},
|
|
@@ -23,10 +21,6 @@
|
|
|
23
21
|
"import": "./build/constants.js",
|
|
24
22
|
"types": "./build/constants.d.ts"
|
|
25
23
|
},
|
|
26
|
-
"./plugins/esbuild": {
|
|
27
|
-
"import": "./build/transformer/plugins/esbuild.js",
|
|
28
|
-
"types": "./build/transformer/plugins/esbuild.d.ts"
|
|
29
|
-
},
|
|
30
24
|
"./plugins/tsc": {
|
|
31
25
|
"import": "./build/transformer/plugins/tsc.js",
|
|
32
26
|
"require": "./build/transformer/plugins/tsc.js",
|
|
@@ -46,9 +40,9 @@
|
|
|
46
40
|
},
|
|
47
41
|
"type": "module",
|
|
48
42
|
"types": "./build/index.d.ts",
|
|
49
|
-
"version": "0.
|
|
43
|
+
"version": "0.31.1",
|
|
50
44
|
"scripts": {
|
|
51
|
-
"build": "tsc
|
|
45
|
+
"build": "tsc",
|
|
52
46
|
"build:test": "vite build --config test/vite.config.ts",
|
|
53
47
|
"-": "-"
|
|
54
48
|
}
|
|
@@ -2,7 +2,7 @@ import { addImport, applyReplacementsReverse, uid } from '@esportsplus/typescrip
|
|
|
2
2
|
import type { Replacement } from '@esportsplus/typescript/transformer';
|
|
3
3
|
import type { ReactiveCallInfo, TemplateInfo } from './ts-parser';
|
|
4
4
|
import { analyzeExpression, generateAttributeBinding, generateSpreadBindings } from './type-analyzer';
|
|
5
|
-
import ts from 'typescript';
|
|
5
|
+
import { ts } from '@esportsplus/typescript';
|
|
6
6
|
import parser from './parser';
|
|
7
7
|
|
|
8
8
|
|
package/src/transformer/index.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { mightNeedTransform } from '@esportsplus/typescript/transformer';
|
|
2
2
|
import { addArraySlotImport, generateCode, generateReactiveInlining, needsArraySlotImport, setTypeChecker } from './codegen';
|
|
3
3
|
import { findHtmlTemplates, findReactiveCalls } from './ts-parser';
|
|
4
|
-
import ts from 'typescript';
|
|
4
|
+
import { ts } from '@esportsplus/typescript';
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
type TransformResult = {
|
|
@@ -15,19 +15,24 @@ const PATTERNS = ['html`', 'html.reactive'];
|
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
function createTransformer(program: ts.Program): ts.TransformerFactory<ts.SourceFile> {
|
|
18
|
-
let
|
|
18
|
+
let printer = ts.createPrinter(),
|
|
19
|
+
typeChecker = program.getTypeChecker();
|
|
19
20
|
|
|
20
21
|
return (_context: ts.TransformationContext) => {
|
|
21
22
|
return (sourceFile: ts.SourceFile): ts.SourceFile => {
|
|
22
|
-
|
|
23
|
+
// Use printer to get current text representation (handles chained transformers)
|
|
24
|
+
let code = printer.printFile(sourceFile);
|
|
23
25
|
|
|
24
26
|
if (!mightNeedTransform(code, { patterns: PATTERNS })) {
|
|
25
27
|
return sourceFile;
|
|
26
28
|
}
|
|
27
29
|
|
|
30
|
+
// Re-parse the printed code to get accurate positions
|
|
31
|
+
let reparsed = ts.createSourceFile(sourceFile.fileName, code, sourceFile.languageVersion, true);
|
|
32
|
+
|
|
28
33
|
setTypeChecker(typeChecker);
|
|
29
34
|
|
|
30
|
-
let result = transformCode(code,
|
|
35
|
+
let result = transformCode(code, reparsed);
|
|
31
36
|
|
|
32
37
|
if (!result.changed) {
|
|
33
38
|
return sourceFile;
|
|
@@ -74,23 +79,27 @@ function transformCode(code: string, sourceFile: ts.SourceFile): TransformResult
|
|
|
74
79
|
|
|
75
80
|
|
|
76
81
|
const transform = (sourceFile: ts.SourceFile, program: ts.Program): TransformResult => {
|
|
77
|
-
|
|
82
|
+
// Use printer to get current text representation (handles chained transformers)
|
|
83
|
+
let printer = ts.createPrinter(),
|
|
84
|
+
code = printer.printFile(sourceFile);
|
|
78
85
|
|
|
79
86
|
if (!mightNeedTransform(code, { patterns: PATTERNS })) {
|
|
80
87
|
return { changed: false, code, sourceFile };
|
|
81
88
|
}
|
|
82
89
|
|
|
90
|
+
// Re-parse the printed code to get accurate positions
|
|
91
|
+
let reparsed = ts.createSourceFile(sourceFile.fileName, code, sourceFile.languageVersion, true);
|
|
92
|
+
|
|
83
93
|
let programSourceFile = program.getSourceFile(sourceFile.fileName);
|
|
84
94
|
|
|
85
95
|
if (programSourceFile) {
|
|
86
96
|
setTypeChecker(program.getTypeChecker());
|
|
87
|
-
sourceFile = programSourceFile;
|
|
88
97
|
}
|
|
89
98
|
else {
|
|
90
99
|
setTypeChecker(undefined);
|
|
91
100
|
}
|
|
92
101
|
|
|
93
|
-
return transformCode(code,
|
|
102
|
+
return transformCode(code, reparsed);
|
|
94
103
|
};
|
|
95
104
|
|
|
96
105
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { mightNeedTransform, PATTERNS
|
|
1
|
+
import { createTransformer, mightNeedTransform, PATTERNS } from '../index';
|
|
2
2
|
import { program, TRANSFORM_PATTERN } from '@esportsplus/typescript/transformer';
|
|
3
3
|
import type { Plugin, ResolvedConfig } from 'vite';
|
|
4
|
-
import ts from 'typescript';
|
|
4
|
+
import { ts } from '@esportsplus/typescript';
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
export default (options?: { root?: string }): Plugin => {
|
|
@@ -25,14 +25,23 @@ export default (options?: { root?: string }): Plugin => {
|
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
try {
|
|
28
|
-
let
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
28
|
+
let p = program.get(root),
|
|
29
|
+
printer = ts.createPrinter(),
|
|
30
|
+
sourceFile = ts.createSourceFile(id, code, ts.ScriptTarget.Latest, true),
|
|
31
|
+
transformer = createTransformer(p),
|
|
32
|
+
result = ts.transform(sourceFile, [transformer]),
|
|
33
|
+
transformed = result.transformed[0];
|
|
34
|
+
|
|
35
|
+
if (transformed === sourceFile) {
|
|
36
|
+
result.dispose();
|
|
32
37
|
return null;
|
|
33
38
|
}
|
|
34
39
|
|
|
35
|
-
|
|
40
|
+
let output = printer.printFile(transformed);
|
|
41
|
+
|
|
42
|
+
result.dispose();
|
|
43
|
+
|
|
44
|
+
return { code: output, map: null };
|
|
36
45
|
}
|
|
37
46
|
catch (error) {
|
|
38
47
|
console.error(`@esportsplus/template: Error transforming ${id}:`, error);
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { mightNeedTransform, PATTERNS, transform } from '../index.js';
|
|
2
|
-
import { program, TRANSFORM_PATTERN } from '@esportsplus/typescript/transformer';
|
|
3
|
-
import fs from 'fs';
|
|
4
|
-
import ts from 'typescript';
|
|
5
|
-
export default (options) => {
|
|
6
|
-
let root = options?.root ?? process.cwd();
|
|
7
|
-
return {
|
|
8
|
-
name: '@esportsplus/template/plugin-esbuild',
|
|
9
|
-
setup(build) {
|
|
10
|
-
build.onLoad({ filter: TRANSFORM_PATTERN }, async (args) => {
|
|
11
|
-
let code = await fs.promises.readFile(args.path, 'utf8');
|
|
12
|
-
if (!mightNeedTransform(code, { patterns: PATTERNS })) {
|
|
13
|
-
return null;
|
|
14
|
-
}
|
|
15
|
-
try {
|
|
16
|
-
let sourceFile = ts.createSourceFile(args.path, code, ts.ScriptTarget.Latest, true), result = transform(sourceFile, program.get(root));
|
|
17
|
-
if (!result.changed) {
|
|
18
|
-
return null;
|
|
19
|
-
}
|
|
20
|
-
return {
|
|
21
|
-
contents: result.code,
|
|
22
|
-
loader: args.path.endsWith('x') ? 'tsx' : 'ts'
|
|
23
|
-
};
|
|
24
|
-
}
|
|
25
|
-
catch (error) {
|
|
26
|
-
console.error(`@esportsplus/template: Error transforming ${args.path}:`, error);
|
|
27
|
-
return null;
|
|
28
|
-
}
|
|
29
|
-
});
|
|
30
|
-
build.onEnd(() => {
|
|
31
|
-
program.delete(root);
|
|
32
|
-
});
|
|
33
|
-
}
|
|
34
|
-
};
|
|
35
|
-
};
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import { mightNeedTransform, PATTERNS, transform } from '../index';
|
|
2
|
-
import { program, TRANSFORM_PATTERN } from '@esportsplus/typescript/transformer';
|
|
3
|
-
import type { OnLoadArgs, Plugin, PluginBuild } from 'esbuild';
|
|
4
|
-
import fs from 'fs';
|
|
5
|
-
import ts from 'typescript';
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
export default (options?: { root?: string }): Plugin => {
|
|
9
|
-
let root = options?.root ?? process.cwd();
|
|
10
|
-
|
|
11
|
-
return {
|
|
12
|
-
name: '@esportsplus/template/plugin-esbuild',
|
|
13
|
-
|
|
14
|
-
setup(build: PluginBuild) {
|
|
15
|
-
build.onLoad({ filter: TRANSFORM_PATTERN }, async (args: OnLoadArgs) => {
|
|
16
|
-
let code = await fs.promises.readFile(args.path, 'utf8');
|
|
17
|
-
|
|
18
|
-
if (!mightNeedTransform(code, { patterns: PATTERNS })) {
|
|
19
|
-
return null;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
try {
|
|
23
|
-
let sourceFile = ts.createSourceFile(args.path, code, ts.ScriptTarget.Latest, true),
|
|
24
|
-
result = transform(sourceFile, program.get(root));
|
|
25
|
-
|
|
26
|
-
if (!result.changed) {
|
|
27
|
-
return null;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
return {
|
|
31
|
-
contents: result.code,
|
|
32
|
-
loader: args.path.endsWith('x') ? 'tsx' : 'ts'
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
|
-
catch (error) {
|
|
36
|
-
console.error(`@esportsplus/template: Error transforming ${args.path}:`, error);
|
|
37
|
-
return null;
|
|
38
|
-
}
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
build.onEnd(() => {
|
|
42
|
-
program.delete(root);
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
};
|
|
46
|
-
};
|