@esportsplus/template 0.28.3 → 0.29.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.
Files changed (110) hide show
  1. package/README.md +431 -0
  2. package/build/attributes.d.ts +7 -1
  3. package/build/attributes.js +86 -33
  4. package/build/constants.d.ts +3 -11
  5. package/build/constants.js +4 -32
  6. package/build/event/constants.d.ts +3 -0
  7. package/build/event/constants.js +13 -0
  8. package/build/event/index.d.ts +9 -1
  9. package/build/event/index.js +29 -35
  10. package/build/event/ontick.js +6 -9
  11. package/build/html.d.ts +9 -0
  12. package/build/html.js +7 -0
  13. package/build/index.d.ts +8 -2
  14. package/build/index.js +8 -1
  15. package/build/render.d.ts +2 -2
  16. package/build/render.js +2 -3
  17. package/build/runtime.d.ts +1 -0
  18. package/build/runtime.js +5 -0
  19. package/build/slot/array.d.ts +3 -3
  20. package/build/slot/array.js +11 -14
  21. package/build/slot/cleanup.d.ts +1 -1
  22. package/build/slot/cleanup.js +1 -2
  23. package/build/slot/effect.js +5 -7
  24. package/build/slot/index.js +1 -7
  25. package/build/slot/render.js +6 -8
  26. package/build/svg.d.ts +1 -1
  27. package/build/svg.js +1 -1
  28. package/build/transformer/codegen.d.ts +18 -0
  29. package/build/transformer/codegen.js +316 -0
  30. package/build/transformer/index.d.ts +12 -0
  31. package/build/transformer/index.js +62 -0
  32. package/build/transformer/parser.d.ts +18 -0
  33. package/build/transformer/parser.js +166 -0
  34. package/build/transformer/plugins/esbuild.d.ts +5 -0
  35. package/build/transformer/plugins/esbuild.js +35 -0
  36. package/build/transformer/plugins/tsc.d.ts +3 -0
  37. package/build/transformer/plugins/tsc.js +4 -0
  38. package/build/transformer/plugins/vite.d.ts +5 -0
  39. package/build/transformer/plugins/vite.js +37 -0
  40. package/build/transformer/ts-parser.d.ts +21 -0
  41. package/build/transformer/ts-parser.js +72 -0
  42. package/build/transformer/type-analyzer.d.ts +7 -0
  43. package/build/transformer/type-analyzer.js +230 -0
  44. package/build/types.d.ts +2 -3
  45. package/build/utilities.d.ts +7 -0
  46. package/build/utilities.js +31 -0
  47. package/package.json +33 -4
  48. package/src/attributes.ts +115 -51
  49. package/src/constants.ts +6 -53
  50. package/src/event/constants.ts +16 -0
  51. package/src/event/index.ts +36 -42
  52. package/src/event/onconnect.ts +1 -1
  53. package/src/event/onresize.ts +1 -1
  54. package/src/event/ontick.ts +7 -11
  55. package/src/html.ts +18 -0
  56. package/src/index.ts +8 -2
  57. package/src/render.ts +6 -7
  58. package/src/runtime.ts +8 -0
  59. package/src/slot/array.ts +18 -24
  60. package/src/slot/cleanup.ts +3 -4
  61. package/src/slot/effect.ts +6 -8
  62. package/src/slot/index.ts +2 -8
  63. package/src/slot/render.ts +7 -9
  64. package/src/svg.ts +1 -1
  65. package/src/transformer/codegen.ts +518 -0
  66. package/src/transformer/index.ts +98 -0
  67. package/src/transformer/parser.ts +239 -0
  68. package/src/transformer/plugins/esbuild.ts +46 -0
  69. package/src/transformer/plugins/tsc.ts +7 -0
  70. package/src/transformer/plugins/vite.ts +49 -0
  71. package/src/transformer/ts-parser.ts +123 -0
  72. package/src/transformer/type-analyzer.ts +334 -0
  73. package/src/types.ts +3 -4
  74. package/src/utilities.ts +52 -0
  75. package/storage/rewrite-analysis-2026-01-04.md +439 -0
  76. package/test/constants.ts +69 -0
  77. package/test/effects.ts +237 -0
  78. package/test/events.ts +318 -0
  79. package/test/imported-values.ts +253 -0
  80. package/test/nested.ts +298 -0
  81. package/test/slots.ts +259 -0
  82. package/test/spread.ts +290 -0
  83. package/test/static.ts +118 -0
  84. package/test/templates.ts +473 -0
  85. package/test/tsconfig.json +17 -0
  86. package/test/vite.config.ts +50 -0
  87. package/build/html/index.d.ts +0 -9
  88. package/build/html/index.js +0 -29
  89. package/build/html/parser.d.ts +0 -5
  90. package/build/html/parser.js +0 -165
  91. package/build/utilities/element.d.ts +0 -11
  92. package/build/utilities/element.js +0 -9
  93. package/build/utilities/fragment.d.ts +0 -3
  94. package/build/utilities/fragment.js +0 -10
  95. package/build/utilities/marker.d.ts +0 -2
  96. package/build/utilities/marker.js +0 -4
  97. package/build/utilities/node.d.ts +0 -9
  98. package/build/utilities/node.js +0 -10
  99. package/build/utilities/raf.d.ts +0 -2
  100. package/build/utilities/raf.js +0 -1
  101. package/build/utilities/text.d.ts +0 -2
  102. package/build/utilities/text.js +0 -9
  103. package/src/html/index.ts +0 -48
  104. package/src/html/parser.ts +0 -235
  105. package/src/utilities/element.ts +0 -28
  106. package/src/utilities/fragment.ts +0 -19
  107. package/src/utilities/marker.ts +0 -6
  108. package/src/utilities/node.ts +0 -29
  109. package/src/utilities/raf.ts +0 -1
  110. package/src/utilities/text.ts +0 -15
@@ -0,0 +1,21 @@
1
+ import ts from 'typescript';
2
+ type ReactiveCallInfo = {
3
+ arrayArg: ts.Expression;
4
+ callbackArg: ts.Expression;
5
+ end: number;
6
+ node: ts.CallExpression;
7
+ start: number;
8
+ };
9
+ type TemplateInfo = {
10
+ depth: number;
11
+ end: number;
12
+ expressions: ts.Expression[];
13
+ literals: string[];
14
+ node: ts.TaggedTemplateExpression;
15
+ start: number;
16
+ };
17
+ declare const findHtmlTemplates: (sourceFile: ts.SourceFile) => TemplateInfo[];
18
+ declare const findReactiveCalls: (sourceFile: ts.SourceFile) => ReactiveCallInfo[];
19
+ declare const getTemplateExpressions: (info: TemplateInfo, sourceFile: ts.SourceFile) => string[];
20
+ export { findHtmlTemplates, findReactiveCalls, getTemplateExpressions };
21
+ export type { ReactiveCallInfo, TemplateInfo };
@@ -0,0 +1,72 @@
1
+ import ts from 'typescript';
2
+ function extractTemplateInfo(node, depth) {
3
+ let expressions = [], literals = [], template = node.template;
4
+ if (ts.isNoSubstitutionTemplateLiteral(template)) {
5
+ literals.push(template.text);
6
+ }
7
+ else if (ts.isTemplateExpression(template)) {
8
+ literals.push(template.head.text);
9
+ for (let i = 0, n = template.templateSpans.length; i < n; i++) {
10
+ let span = template.templateSpans[i];
11
+ expressions.push(span.expression);
12
+ literals.push(span.literal.text);
13
+ }
14
+ }
15
+ return {
16
+ depth,
17
+ end: node.end,
18
+ expressions,
19
+ literals,
20
+ node,
21
+ start: node.getStart()
22
+ };
23
+ }
24
+ function isFunctionNode(node) {
25
+ return (ts.isArrowFunction(node) ||
26
+ ts.isFunctionDeclaration(node) ||
27
+ ts.isFunctionExpression(node) ||
28
+ ts.isMethodDeclaration(node));
29
+ }
30
+ function visitReactiveCalls(node, calls) {
31
+ if (ts.isCallExpression(node) &&
32
+ ts.isPropertyAccessExpression(node.expression) &&
33
+ ts.isIdentifier(node.expression.expression) &&
34
+ node.expression.expression.text === 'html' &&
35
+ node.expression.name.text === 'reactive' &&
36
+ node.arguments.length === 2) {
37
+ calls.push({
38
+ arrayArg: node.arguments[0],
39
+ callbackArg: node.arguments[1],
40
+ end: node.end,
41
+ node,
42
+ start: node.getStart()
43
+ });
44
+ }
45
+ ts.forEachChild(node, child => visitReactiveCalls(child, calls));
46
+ }
47
+ function visitTemplates(node, depth, templates) {
48
+ let nextDepth = isFunctionNode(node) ? depth + 1 : depth;
49
+ if (ts.isTaggedTemplateExpression(node) && ts.isIdentifier(node.tag) && node.tag.text === 'html') {
50
+ templates.push(extractTemplateInfo(node, depth));
51
+ }
52
+ ts.forEachChild(node, child => visitTemplates(child, nextDepth, templates));
53
+ }
54
+ const findHtmlTemplates = (sourceFile) => {
55
+ let templates = [];
56
+ visitTemplates(sourceFile, 0, templates);
57
+ templates.sort((a, b) => a.depth !== b.depth ? b.depth - a.depth : a.start - b.start);
58
+ return templates;
59
+ };
60
+ const findReactiveCalls = (sourceFile) => {
61
+ let calls = [];
62
+ visitReactiveCalls(sourceFile, calls);
63
+ return calls;
64
+ };
65
+ const getTemplateExpressions = (info, sourceFile) => {
66
+ let exprs = [];
67
+ for (let i = 0, n = info.expressions.length; i < n; i++) {
68
+ exprs.push(info.expressions[i].getText(sourceFile));
69
+ }
70
+ return exprs;
71
+ };
72
+ export { findHtmlTemplates, findReactiveCalls, getTemplateExpressions };
@@ -0,0 +1,7 @@
1
+ import ts from 'typescript';
2
+ type SlotType = 'array-slot' | 'document-fragment' | 'effect' | 'node' | 'primitive' | 'static' | 'unknown';
3
+ declare const analyzeExpression: (expr: ts.Expression, checker?: ts.TypeChecker) => SlotType;
4
+ declare const generateAttributeBinding: (elementVar: string, name: string, expr: string, staticValue: string) => string;
5
+ declare const generateSpreadBindings: (expr: ts.Expression, exprCode: string, elementVar: string, sourceFile: ts.SourceFile, checker?: ts.TypeChecker) => string[];
6
+ export { analyzeExpression, generateAttributeBinding, generateSpreadBindings };
7
+ export type { SlotType };
@@ -0,0 +1,230 @@
1
+ import { getNames } from './codegen.js';
2
+ import { DIRECT_ATTACH_EVENTS, LIFECYCLE_EVENTS } from '../event/constants.js';
3
+ import ts from 'typescript';
4
+ function analyzeSpread(expr, checker) {
5
+ while (ts.isParenthesizedExpression(expr)) {
6
+ expr = expr.expression;
7
+ }
8
+ if (ts.isObjectLiteralExpression(expr)) {
9
+ let keys = [];
10
+ for (let i = 0, n = expr.properties.length; i < n; i++) {
11
+ let prop = expr.properties[i];
12
+ if (ts.isPropertyAssignment(prop)) {
13
+ if (ts.isIdentifier(prop.name) || ts.isStringLiteral(prop.name)) {
14
+ keys.push(prop.name.text);
15
+ }
16
+ }
17
+ else if (ts.isShorthandPropertyAssignment(prop)) {
18
+ keys.push(prop.name.text);
19
+ }
20
+ else if (ts.isSpreadAssignment(prop)) {
21
+ return { canUnpack: false, keys: [] };
22
+ }
23
+ }
24
+ return { canUnpack: true, keys };
25
+ }
26
+ if (checker && (ts.isIdentifier(expr) || ts.isPropertyAccessExpression(expr))) {
27
+ try {
28
+ let keys = extractTypePropertyKeys(checker.getTypeAtLocation(expr));
29
+ if (keys.length > 0) {
30
+ return { canUnpack: true, keys };
31
+ }
32
+ }
33
+ catch {
34
+ }
35
+ }
36
+ return { canUnpack: false, keys: [] };
37
+ }
38
+ function extractTypePropertyKeys(type) {
39
+ let keys = [], props = type.getProperties();
40
+ for (let i = 0, n = props.length; i < n; i++) {
41
+ let name = props[i].getName();
42
+ if (name.startsWith('__') || name.startsWith('[')) {
43
+ continue;
44
+ }
45
+ keys.push(name);
46
+ }
47
+ return keys;
48
+ }
49
+ function getObjectPropertyValue(expr, key, sourceFile) {
50
+ for (let i = 0, n = expr.properties.length; i < n; i++) {
51
+ let prop = expr.properties[i];
52
+ if (ts.isPropertyAssignment(prop)) {
53
+ let name = ts.isIdentifier(prop.name)
54
+ ? prop.name.text
55
+ : ts.isStringLiteral(prop.name) ? prop.name.text : null;
56
+ if (name === key) {
57
+ return prop.initializer.getText(sourceFile);
58
+ }
59
+ }
60
+ else if (ts.isShorthandPropertyAssignment(prop) && prop.name.text === key) {
61
+ return prop.name.text;
62
+ }
63
+ }
64
+ return null;
65
+ }
66
+ function inferSlotType(expr, ctx) {
67
+ while (ts.isParenthesizedExpression(expr)) {
68
+ expr = expr.expression;
69
+ }
70
+ if (ts.isArrowFunction(expr) || ts.isFunctionExpression(expr)) {
71
+ return 'effect';
72
+ }
73
+ if (ts.isCallExpression(expr) &&
74
+ ts.isPropertyAccessExpression(expr.expression) &&
75
+ ts.isIdentifier(expr.expression.expression) &&
76
+ expr.expression.expression.text === 'html' &&
77
+ expr.expression.name.text === 'reactive') {
78
+ return 'array-slot';
79
+ }
80
+ if (ts.isTaggedTemplateExpression(expr) && ts.isIdentifier(expr.tag) && expr.tag.text === 'html') {
81
+ return 'document-fragment';
82
+ }
83
+ if (ts.isArrayLiteralExpression(expr)) {
84
+ return 'array-slot';
85
+ }
86
+ if (ts.isStringLiteral(expr) || ts.isNoSubstitutionTemplateLiteral(expr)) {
87
+ return 'static';
88
+ }
89
+ if (ts.isNumericLiteral(expr)) {
90
+ return 'static';
91
+ }
92
+ if (expr.kind === ts.SyntaxKind.TrueKeyword || expr.kind === ts.SyntaxKind.FalseKeyword) {
93
+ return 'static';
94
+ }
95
+ if (expr.kind === ts.SyntaxKind.NullKeyword || expr.kind === ts.SyntaxKind.UndefinedKeyword) {
96
+ return 'static';
97
+ }
98
+ if (ts.isTemplateExpression(expr)) {
99
+ return 'primitive';
100
+ }
101
+ if (ts.isConditionalExpression(expr)) {
102
+ let whenFalse = inferSlotType(expr.whenFalse, ctx), whenTrue = inferSlotType(expr.whenTrue, ctx);
103
+ if (whenTrue === whenFalse) {
104
+ return whenTrue;
105
+ }
106
+ if (whenTrue === 'effect' || whenFalse === 'effect') {
107
+ return 'effect';
108
+ }
109
+ return 'unknown';
110
+ }
111
+ if (ctx?.checker) {
112
+ let checker = ctx.checker;
113
+ if (ts.isIdentifier(expr)) {
114
+ try {
115
+ let type = checker.getTypeAtLocation(expr);
116
+ if (isTypeFunction(type, checker)) {
117
+ return 'effect';
118
+ }
119
+ if (isTypeArray(type, checker)) {
120
+ return 'array-slot';
121
+ }
122
+ }
123
+ catch {
124
+ }
125
+ }
126
+ if (ts.isPropertyAccessExpression(expr)) {
127
+ try {
128
+ let type = checker.getTypeAtLocation(expr);
129
+ if (isTypeFunction(type, checker)) {
130
+ return 'effect';
131
+ }
132
+ if (isTypeArray(type, checker)) {
133
+ return 'array-slot';
134
+ }
135
+ }
136
+ catch {
137
+ }
138
+ }
139
+ if (ts.isCallExpression(expr)) {
140
+ try {
141
+ let type = checker.getTypeAtLocation(expr);
142
+ if (isTypeFunction(type, checker)) {
143
+ return 'effect';
144
+ }
145
+ if (isTypeArray(type, checker)) {
146
+ return 'array-slot';
147
+ }
148
+ }
149
+ catch {
150
+ }
151
+ }
152
+ }
153
+ return 'unknown';
154
+ }
155
+ function isTypeArray(type, checker) {
156
+ let typeStr = checker.typeToString(type);
157
+ if (typeStr.endsWith('[]') || typeStr.startsWith('Array<') || typeStr.startsWith('ReactiveArray<')) {
158
+ return true;
159
+ }
160
+ let symbol = type.getSymbol();
161
+ if (symbol && (symbol.getName() === 'Array' || symbol.getName() === 'ReactiveArray')) {
162
+ return true;
163
+ }
164
+ return false;
165
+ }
166
+ function isTypeFunction(type, checker) {
167
+ if (type.getCallSignatures().length > 0) {
168
+ return true;
169
+ }
170
+ if (type.isUnion()) {
171
+ for (let i = 0, n = type.types.length; i < n; i++) {
172
+ if (isTypeFunction(type.types[i], checker)) {
173
+ return true;
174
+ }
175
+ }
176
+ }
177
+ return false;
178
+ }
179
+ const analyzeExpression = (expr, checker) => {
180
+ return inferSlotType(expr, checker ? { checker } : undefined);
181
+ };
182
+ const generateAttributeBinding = (elementVar, name, expr, staticValue) => {
183
+ let n = getNames();
184
+ if (name.startsWith('on') && name.length > 2) {
185
+ let event = name.slice(2).toLowerCase(), key = name.toLowerCase();
186
+ if (LIFECYCLE_EVENTS.has(key)) {
187
+ return `${n.event}.${key}(${elementVar}, ${expr});`;
188
+ }
189
+ if (DIRECT_ATTACH_EVENTS.has(key)) {
190
+ return `${n.event}.direct(${elementVar}, '${event}', ${expr});`;
191
+ }
192
+ return `${n.event}.delegate(${elementVar}, '${event}', ${expr});`;
193
+ }
194
+ if (name === 'class') {
195
+ return `${n.attr}.setClass(${elementVar}, '${staticValue}', ${expr});`;
196
+ }
197
+ if (name === 'spread') {
198
+ return `${n.attr}.spread(${elementVar}, ${expr});`;
199
+ }
200
+ if (name === 'style') {
201
+ return `${n.attr}.setStyle(${elementVar}, '${staticValue}', ${expr});`;
202
+ }
203
+ return `${n.attr}.setProperty(${elementVar}, '${name}', ${expr});`;
204
+ };
205
+ const generateSpreadBindings = (expr, exprCode, elementVar, sourceFile, checker) => {
206
+ while (ts.isParenthesizedExpression(expr)) {
207
+ expr = expr.expression;
208
+ }
209
+ let analysis = analyzeSpread(expr, checker);
210
+ if (!analysis.canUnpack) {
211
+ return [`${getNames().attr}.spread(${elementVar}, ${exprCode});`];
212
+ }
213
+ let lines = [];
214
+ if (ts.isObjectLiteralExpression(expr)) {
215
+ for (let i = 0, n = analysis.keys.length; i < n; i++) {
216
+ let key = analysis.keys[i], value = getObjectPropertyValue(expr, key, sourceFile);
217
+ if (value !== null) {
218
+ lines.push(generateAttributeBinding(elementVar, key, value, ''));
219
+ }
220
+ }
221
+ }
222
+ else {
223
+ for (let i = 0, n = analysis.keys.length; i < n; i++) {
224
+ let key = analysis.keys[i];
225
+ lines.push(generateAttributeBinding(elementVar, key, `${exprCode}.${key}`, ''));
226
+ }
227
+ }
228
+ return lines;
229
+ };
230
+ export { analyzeExpression, generateAttributeBinding, generateSpreadBindings };
package/build/types.d.ts CHANGED
@@ -1,4 +1,3 @@
1
- import { firstChild } from './utilities/node.js';
2
1
  import { ArraySlot } from './slot/array.js';
3
2
  import attributes from './attributes.js';
4
3
  import slot from './slot/index.js';
@@ -28,9 +27,9 @@ type Template = {
28
27
  html: string;
29
28
  literals: TemplateStringsArray;
30
29
  slots: {
31
- fn: typeof attributes.set | typeof attributes.spread | typeof slot;
30
+ fn: typeof attributes.spread | typeof slot;
32
31
  name: string | null;
33
- path: typeof firstChild[];
32
+ path: (() => ChildNode | null)[];
34
33
  }[] | null;
35
34
  };
36
35
  export type { Attribute, Attributes, Effect, Element, Renderable, SlotGroup, Template };
@@ -0,0 +1,7 @@
1
+ declare const clone: <T extends Node>(node: T, options?: boolean | ImportNodeOptions) => T;
2
+ declare const fragment: (html: string) => DocumentFragment;
3
+ declare const marker: ChildNode;
4
+ declare const raf: typeof requestAnimationFrame;
5
+ declare const template: (html: string) => () => DocumentFragment;
6
+ declare const text: (value: string) => Node;
7
+ export { clone, fragment, template, marker, raf, text };
@@ -0,0 +1,31 @@
1
+ import { SLOT_HTML } from './constants.js';
2
+ let clonableTemplate = document.createElement('template'), clonableText = document.createTextNode('');
3
+ const clone = typeof navigator !== 'undefined' && navigator.userAgent.includes('Firefox')
4
+ ? document.importNode.bind(document)
5
+ : (node, deep = true) => node.cloneNode(deep);
6
+ const fragment = (html) => {
7
+ let element = clonableTemplate.cloneNode();
8
+ element.innerHTML = html;
9
+ return element.content;
10
+ };
11
+ const marker = fragment(SLOT_HTML).firstChild;
12
+ const raf = globalThis?.requestAnimationFrame;
13
+ const template = (html) => {
14
+ let cached;
15
+ return () => {
16
+ if (!cached) {
17
+ let element = clonableTemplate.cloneNode();
18
+ element.innerHTML = html;
19
+ cached = element.content;
20
+ }
21
+ return clone(cached, true);
22
+ };
23
+ };
24
+ const text = (value) => {
25
+ let element = clonableText.cloneNode();
26
+ if (value !== '') {
27
+ element.nodeValue = value;
28
+ }
29
+ return element;
30
+ };
31
+ export { clone, fragment, template, marker, raf, text };
package/package.json CHANGED
@@ -2,11 +2,39 @@
2
2
  "author": "ICJR",
3
3
  "dependencies": {
4
4
  "@esportsplus/queue": "^0.2.0",
5
- "@esportsplus/reactivity": "^0.22.0",
6
- "@esportsplus/utilities": "^0.25.0"
5
+ "@esportsplus/reactivity": "^0.23.2",
6
+ "@esportsplus/utilities": "^0.27.2",
7
+ "serve": "^14.2.5"
7
8
  },
8
9
  "devDependencies": {
9
- "@esportsplus/typescript": "^0.9.2"
10
+ "@esportsplus/typescript": "^0.13.0",
11
+ "@types/node": "^25.0.3",
12
+ "esbuild": "^0.27.2",
13
+ "typescript": "^5.9.3",
14
+ "vite": "^7.3.0",
15
+ "vite-tsconfig-paths": "^6.0.3"
16
+ },
17
+ "exports": {
18
+ ".": {
19
+ "import": "./build/index.js",
20
+ "types": "./build/index.d.ts"
21
+ },
22
+ "./constants": {
23
+ "import": "./build/constants.js",
24
+ "types": "./build/constants.d.ts"
25
+ },
26
+ "./plugins/esbuild": {
27
+ "import": "./build/transformer/plugins/esbuild.js",
28
+ "types": "./build/transformer/plugins/esbuild.d.ts"
29
+ },
30
+ "./plugins/tsc": {
31
+ "import": "./build/transformer/plugins/tsc.js",
32
+ "types": "./build/transformer/plugins/tsc.d.ts"
33
+ },
34
+ "./plugins/vite": {
35
+ "import": "./build/transformer/plugins/vite.js",
36
+ "types": "./build/transformer/plugins/vite.d.ts"
37
+ }
10
38
  },
11
39
  "main": "./build/index.js",
12
40
  "name": "@esportsplus/template",
@@ -17,9 +45,10 @@
17
45
  },
18
46
  "type": "module",
19
47
  "types": "./build/index.d.ts",
20
- "version": "0.28.3",
48
+ "version": "0.29.2",
21
49
  "scripts": {
22
50
  "build": "tsc && tsc-alias",
51
+ "compile:test": "vite build --config test/vite.config.ts",
23
52
  "-": "-"
24
53
  }
25
54
  }