@esportsplus/template 0.16.0

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 (90) hide show
  1. package/.editorconfig +9 -0
  2. package/.gitattributes +2 -0
  3. package/.github/dependabot.yml +25 -0
  4. package/.github/workflows/bump.yml +9 -0
  5. package/.github/workflows/dependabot.yml +12 -0
  6. package/.github/workflows/publish.yml +16 -0
  7. package/README.md +385 -0
  8. package/build/attributes.d.ts +5 -0
  9. package/build/attributes.js +212 -0
  10. package/build/compiler/codegen.d.ts +21 -0
  11. package/build/compiler/codegen.js +303 -0
  12. package/build/compiler/constants.d.ts +16 -0
  13. package/build/compiler/constants.js +19 -0
  14. package/build/compiler/index.d.ts +14 -0
  15. package/build/compiler/index.js +61 -0
  16. package/build/compiler/parser.d.ts +19 -0
  17. package/build/compiler/parser.js +164 -0
  18. package/build/compiler/plugins/tsc.d.ts +3 -0
  19. package/build/compiler/plugins/tsc.js +4 -0
  20. package/build/compiler/plugins/vite.d.ts +13 -0
  21. package/build/compiler/plugins/vite.js +8 -0
  22. package/build/compiler/ts-analyzer.d.ts +4 -0
  23. package/build/compiler/ts-analyzer.js +63 -0
  24. package/build/compiler/ts-parser.d.ts +24 -0
  25. package/build/compiler/ts-parser.js +67 -0
  26. package/build/constants.d.ts +12 -0
  27. package/build/constants.js +25 -0
  28. package/build/event/index.d.ts +10 -0
  29. package/build/event/index.js +90 -0
  30. package/build/event/onconnect.d.ts +3 -0
  31. package/build/event/onconnect.js +15 -0
  32. package/build/event/onresize.d.ts +3 -0
  33. package/build/event/onresize.js +26 -0
  34. package/build/event/ontick.d.ts +6 -0
  35. package/build/event/ontick.js +41 -0
  36. package/build/html.d.ts +9 -0
  37. package/build/html.js +7 -0
  38. package/build/index.d.ts +8 -0
  39. package/build/index.js +12 -0
  40. package/build/render.d.ts +3 -0
  41. package/build/render.js +8 -0
  42. package/build/slot/array.d.ts +25 -0
  43. package/build/slot/array.js +189 -0
  44. package/build/slot/cleanup.d.ts +4 -0
  45. package/build/slot/cleanup.js +23 -0
  46. package/build/slot/effect.d.ts +12 -0
  47. package/build/slot/effect.js +85 -0
  48. package/build/slot/index.d.ts +7 -0
  49. package/build/slot/index.js +14 -0
  50. package/build/slot/render.d.ts +2 -0
  51. package/build/slot/render.js +44 -0
  52. package/build/svg.d.ts +5 -0
  53. package/build/svg.js +14 -0
  54. package/build/types.d.ts +23 -0
  55. package/build/types.js +1 -0
  56. package/build/utilities.d.ts +7 -0
  57. package/build/utilities.js +31 -0
  58. package/package.json +43 -0
  59. package/src/attributes.ts +313 -0
  60. package/src/compiler/codegen.ts +492 -0
  61. package/src/compiler/constants.ts +25 -0
  62. package/src/compiler/index.ts +87 -0
  63. package/src/compiler/parser.ts +242 -0
  64. package/src/compiler/plugins/tsc.ts +6 -0
  65. package/src/compiler/plugins/vite.ts +10 -0
  66. package/src/compiler/ts-analyzer.ts +89 -0
  67. package/src/compiler/ts-parser.ts +112 -0
  68. package/src/constants.ts +44 -0
  69. package/src/event/index.ts +130 -0
  70. package/src/event/onconnect.ts +22 -0
  71. package/src/event/onresize.ts +37 -0
  72. package/src/event/ontick.ts +59 -0
  73. package/src/html.ts +18 -0
  74. package/src/index.ts +19 -0
  75. package/src/llm.txt +403 -0
  76. package/src/render.ts +13 -0
  77. package/src/slot/array.ts +257 -0
  78. package/src/slot/cleanup.ts +37 -0
  79. package/src/slot/effect.ts +114 -0
  80. package/src/slot/index.ts +17 -0
  81. package/src/slot/render.ts +61 -0
  82. package/src/svg.ts +27 -0
  83. package/src/types.ts +40 -0
  84. package/src/utilities.ts +53 -0
  85. package/storage/compiler-architecture-2026-01-13.md +420 -0
  86. package/test/dist/test.js +1912 -0
  87. package/test/dist/test.js.map +1 -0
  88. package/test/index.ts +648 -0
  89. package/test/vite.config.ts +23 -0
  90. package/tsconfig.json +8 -0
@@ -0,0 +1,420 @@
1
+ # Compiler Architecture Documentation
2
+
3
+ ## Compilation Flow Diagram
4
+
5
+ ```
6
+ ┌─────────────────────────────────────────────────────┐
7
+ │ BUILD TOOLS │
8
+ │ (Vite / TypeScript) │
9
+ └─────────────────────┬───────────────────────────────┘
10
+
11
+
12
+ ┌───────────────────────────────────────────────────────────────────────────────────────────┐
13
+ │ @esportsplus/typescript/compiler │
14
+ │ │
15
+ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
16
+ │ │ program │───►│ coordinator │───►│ imports │───►│ ast │ │
17
+ │ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │
18
+ │ │ │ │ │
19
+ │ │ │ Sequential Plugin Execution │ │
20
+ │ ▼ ▼ ▼ │
21
+ │ ┌─────────────┐ ┌──────────────────────────────────────────────────┐ │
22
+ │ │ ts.Program │ │ PLUGIN CHAIN │ │
23
+ │ │ ts.Checker │ │ ┌────────────┐ ┌────────────┐ ┌────────────┐│ │
24
+ │ └─────────────┘ │ │ Plugin 1 │──►│ Plugin 2 │──►│ Plugin N ││ │
25
+ │ │ └────────────┘ └────────────┘ └────────────┘│ │
26
+ │ └──────────────────────────────────────────────────┘ │
27
+ └───────────────────────────────────────────────────────────────────────────────────────────┘
28
+
29
+ ┌──────────────────────────────┼──────────────────────────────┐
30
+ │ │ │
31
+ ▼ ▼ ▼
32
+ ┌────────────────────────────────┐ ┌────────────────────────────────┐ ┌────────────────────┐
33
+ │ @esportsplus/reactivity │ │ @esportsplus/frontend │ │ Custom Plugins │
34
+ │ /compiler │ │ /template/compiler │ │ │
35
+ │ │ │ │ │ │
36
+ │ ┌──────────────────────────┐ │ │ ┌──────────────────────────┐ │ │ ┌──────────────┐ │
37
+ │ │ index.ts │ │ │ │ index.ts │ │ │ │ Your │ │
38
+ │ │ (Plugin Definition) │ │ │ │ (Plugin Definition) │ │ │ │ Plugin │ │
39
+ │ └─────────────┬────────────┘ │ │ └─────────────┬────────────┘ │ │ └──────────────┘ │
40
+ │ │ │ │ │ │ │ │
41
+ │ ┌───────┴───────┐ │ │ ┌───────┴───────┐ │ │ │
42
+ │ ▼ ▼ ▼ │ │ ▼ ▼ ▼ │ │ │
43
+ │ ┌────────┬────────┬────────┐ │ │ ┌────────┬────────┬────────┐ │ │ │
44
+ │ │primit- │ array │ object │ │ │ │ parser │codegen │ts- │ │ │ │
45
+ │ │ives.ts │ .ts │ .ts │ │ │ │ .ts │ .ts │parser │ │ │ │
46
+ │ └────────┴────────┴────────┘ │ │ └────────┴────────┴────────┘ │ │ │
47
+ └────────────────────────────────┘ └────────────────────────────────┘ └────────────────────┘
48
+ │ │
49
+ ▼ ▼
50
+ ┌────────────────────────────────────────────────────────────────────────────────────────────┐
51
+ │ TRANSFORMED CODE │
52
+ │ │
53
+ │ Input: reactive(0) Input: html`<div>${name}</div>` │
54
+ │ Output: _r.signal(0) Output: (() => { let root = _t(); ... })() │
55
+ └────────────────────────────────────────────────────────────────────────────────────────────┘
56
+ ```
57
+
58
+ ---
59
+
60
+ ## Package Overview
61
+
62
+ ### 1. @esportsplus/typescript/compiler
63
+
64
+ **Purpose**: Core compiler infrastructure providing the plugin system, AST utilities, and build tool integrations.
65
+
66
+ **Location**: `G:/typescript/src/compiler/`
67
+
68
+ **Exports**:
69
+ - `ast` - AST traversal and inspection utilities
70
+ - `code` - Code generation template tag
71
+ - `coordinator` - Sequential plugin execution engine
72
+ - `imports` - Import analysis and manipulation
73
+ - `plugin` - Plugin factory for Vite/TSC
74
+ - `uid` - Unique identifier generator
75
+
76
+ #### Key Components
77
+
78
+ ##### coordinator.ts
79
+ The heart of the compilation system. Transforms source code through plugins sequentially:
80
+
81
+ 1. **Pattern Matching**: Fast-path skip if source doesn't contain plugin patterns
82
+ 2. **Plugin Execution**: Each plugin receives fresh AST with accurate positions
83
+ 3. **Intent Application**: Applies replacements, prepends, and import modifications
84
+ 4. **Program Rebuild**: Creates updated TypeScript program after each plugin for accurate type checking
85
+
86
+ ```typescript
87
+ // Core transformation flow
88
+ const transform = (plugins, code, file, program, shared) => {
89
+ for (let plugin of plugins) {
90
+ if (plugin.patterns && !hasPattern(code, plugin.patterns)) continue;
91
+
92
+ let { imports, prepend, replacements } = plugin.transform({
93
+ checker: program.getTypeChecker(),
94
+ code, program, shared, sourceFile
95
+ });
96
+
97
+ // Apply changes and rebuild program
98
+ }
99
+ }
100
+ ```
101
+
102
+ ##### imports.ts
103
+ Tracks and manipulates import statements:
104
+ - `all(file, pkg)` - Find all imports from a package
105
+ - `includes(checker, node, pkg, symbolName?)` - Check if a symbol originates from a package (handles re-exports)
106
+ - Uses WeakMap caching for performance
107
+
108
+ ##### ast.ts
109
+ AST utilities:
110
+ - `expression.name(node)` - Extract identifier or property path
111
+ - `inRange(ranges, start, end)` - Check if position falls within ranges
112
+ - `property.path(node)` - Build dot-separated property path
113
+ - `test(node, fn)` - Recursive predicate testing
114
+
115
+ ##### program.ts
116
+ TypeScript program management:
117
+ - Creates and caches `ts.Program` instances per project root
118
+ - Reads `tsconfig.json` for compiler options
119
+ - Provides type checker for semantic analysis
120
+
121
+ ##### uid.ts
122
+ Generates collision-free identifiers:
123
+ - Format: `{prefix}_{uuid}{counter}`
124
+ - Used for generated class names, variable names, template IDs
125
+
126
+ #### Plugin Interface
127
+
128
+ ```typescript
129
+ type Plugin = {
130
+ patterns?: string[]; // Quick-check strings (e.g., ['reactive(', 'html`'])
131
+ transform: (ctx: TransformContext) => TransformResult;
132
+ };
133
+
134
+ type TransformContext = {
135
+ checker: ts.TypeChecker; // Type information
136
+ code: string; // Current source
137
+ program: ts.Program; // Full program
138
+ shared: SharedContext; // Cross-plugin state
139
+ sourceFile: ts.SourceFile;
140
+ };
141
+
142
+ type TransformResult = {
143
+ imports?: ImportIntent[]; // Import modifications
144
+ prepend?: string[]; // Code after imports
145
+ replacements?: ReplacementIntent[]; // AST node replacements
146
+ };
147
+ ```
148
+
149
+ ---
150
+
151
+ ### 2. @esportsplus/reactivity/compiler
152
+
153
+ **Purpose**: Transforms `reactive()` calls into optimized signal/computed/reactive-array code.
154
+
155
+ **Location**: `G:/reactivity/src/compiler/`
156
+
157
+ **Entry Pattern**: `reactive(`, `reactive<`
158
+
159
+ #### Transformation Types
160
+
161
+ | Input | Output | Transform File |
162
+ |-------|--------|----------------|
163
+ | `reactive(value)` | `_r.signal(value)` | primitives.ts |
164
+ | `reactive(() => expr)` | `_r.computed(() => expr)` | primitives.ts |
165
+ | `reactive([...])` | `new _r.ReactiveArray(...)` | array.ts |
166
+ | `reactive({...})` | `new ReactiveObject_xyz(...)` | object.ts |
167
+
168
+ #### primitives.ts
169
+ Handles scalar reactivity transformations:
170
+
171
+ 1. **Signal Detection**: `reactive(staticValue)` → `_r.signal(staticValue)`
172
+ 2. **Computed Detection**: `reactive(() => expr)` → `_r.computed(() => expr)`
173
+ 3. **Read/Write Tracking**: Transforms variable access to `_r.read(x)` and assignments to `_r.write(x, value)`
174
+ 4. **Compound Operators**: `x += 1` → `_r.write(x, x.value + 1)`
175
+ 5. **Increment/Decrement**: `x++` → `_r.write(x, x.value + 1)`
176
+
177
+ ```typescript
178
+ // Input
179
+ let count = reactive(0);
180
+ count++;
181
+ console.log(count);
182
+
183
+ // Output
184
+ let count = _r.signal(0);
185
+ _r.write(count, count.value + 1);
186
+ console.log(_r.read(count));
187
+ ```
188
+
189
+ #### array.ts
190
+ Transforms reactive arrays:
191
+
192
+ 1. **Array Literal Detection**: `reactive([...])` → `new _r.ReactiveArray(...)`
193
+ 2. **Type Preservation**: Extracts element type from `as` assertions or variable declarations
194
+ 3. **Length Access**: `.length` → `.$length()` (reactive length)
195
+ 4. **Index Assignment**: `arr[i] = v` → `arr.$set(i, v)`
196
+ 5. **Binding Propagation**: Tracks array bindings through variable assignments
197
+
198
+ ```typescript
199
+ // Input
200
+ let items = reactive([1, 2, 3] as number[]);
201
+ items[0] = 10;
202
+ console.log(items.length);
203
+
204
+ // Output
205
+ let items = new _r.ReactiveArray<number>(...[1, 2, 3]);
206
+ items.$set(0, 10);
207
+ console.log(items.$length());
208
+ ```
209
+
210
+ #### object.ts
211
+ Transforms reactive objects into generated classes:
212
+
213
+ 1. **Class Generation**: Creates optimized class with private signals
214
+ 2. **Property Analysis**: Determines signal/computed/array type per property
215
+ 3. **Static Optimization**: Static values (literals) inline directly
216
+ 4. **Type Hints**: `reactive<Type>({...})` preserves type information
217
+
218
+ ```typescript
219
+ // Input
220
+ let state = reactive({ count: 0, double: () => state.count * 2 });
221
+
222
+ // Output
223
+ class ReactiveObject_abc<T0, T1 extends _r.Computed<ReturnType<T1>>['fn']> extends _r.ReactiveObject<any> {
224
+ #count;
225
+ #double;
226
+
227
+ constructor(_p0: T0, _p1: T1) {
228
+ super(null);
229
+ this.#count = this[_r.SIGNAL](_p0);
230
+ this.#double = this[_r.COMPUTED](_p1);
231
+ }
232
+
233
+ get count() { return _r.read(this.#count) as T0; }
234
+ set count(_v0) { _r.write(this.#count, _v0); }
235
+ get double() { return _r.read(this.#double); }
236
+ }
237
+
238
+ let state = new ReactiveObject_abc(0, () => state.count * 2);
239
+ ```
240
+
241
+ ---
242
+
243
+ ### 3. @esportsplus/frontend/template/compiler
244
+
245
+ **Purpose**: Compiles tagged HTML templates into optimized DOM creation code.
246
+
247
+ **Location**: `G:/frontend/src/template/compiler/`
248
+
249
+ **Entry Pattern**: `` html` ``, `html.reactive`
250
+
251
+ #### Transformation Pipeline
252
+
253
+ ```
254
+ html`<div>${expr}</div>`
255
+
256
+
257
+ ┌─────────────────┐
258
+ │ ts-parser.ts │ Extract template literals and expressions
259
+ └────────┬────────┘
260
+
261
+
262
+ ┌─────────────────┐
263
+ │ parser.ts │ Parse HTML, identify slots, build path tree
264
+ └────────┬────────┘
265
+
266
+
267
+ ┌─────────────────┐
268
+ │ ts-analyzer.ts │ Analyze expression types (Effect, Static, etc.)
269
+ └────────┬────────┘
270
+
271
+
272
+ ┌─────────────────┐
273
+ │ codegen.ts │ Generate optimized DOM code
274
+ └─────────────────┘
275
+ ```
276
+
277
+ #### ts-parser.ts
278
+ Extracts template information from AST:
279
+ - `findHtmlTemplates(sourceFile)` - Locate all `html\`...\`` expressions
280
+ - `findReactiveCalls(sourceFile)` - Locate `html.reactive(array, callback)` calls
281
+ - `extractTemplateParts(template)` - Split template into literals and expressions
282
+
283
+ #### parser.ts
284
+ Parses HTML template strings:
285
+
286
+ 1. **Slot Detection**: Identifies `{{$}}` markers for dynamic content
287
+ 2. **Path Generation**: Creates DOM traversal paths (e.g., `['firstChild', 'nextSibling']`)
288
+ 3. **Attribute Parsing**: Extracts dynamic attribute bindings
289
+ 4. **HTML Cleanup**: Removes whitespace, events, empty attributes
290
+
291
+ ```typescript
292
+ // Input: <div class="${cls}">${content}</div>
293
+ // Output:
294
+ {
295
+ html: '<div><!----></div>', // Cleaned HTML with comment slot
296
+ slots: [
297
+ { type: 'attribute', path: ['firstChild'], attributes: { names: ['class'], static: {} } },
298
+ { type: 'node', path: ['firstChild', 'firstChild'] }
299
+ ]
300
+ }
301
+ ```
302
+
303
+ #### ts-analyzer.ts
304
+ Determines expression types for optimization:
305
+
306
+ | Expression Type | Result | Optimization |
307
+ |-----------------|--------|--------------|
308
+ | Arrow/Function | `Effect` | Creates EffectSlot |
309
+ | `html\`...\`` | `DocumentFragment` | Direct insert |
310
+ | `html.reactive()` | `ArraySlot` | Creates ArraySlot |
311
+ | Literal (string/number/bool/null) | `Static` | Direct textContent |
312
+ | Template expression | `Primitive` | Runtime slot |
313
+ | Conditional | Analyzes branches | Unified handling |
314
+
315
+ #### codegen.ts
316
+ Generates optimized DOM creation code:
317
+
318
+ 1. **Template Factory**: Creates reusable template cloners
319
+ 2. **Path Variables**: Declares element references via path traversal
320
+ 3. **Attribute Bindings**: Generates appropriate setters (property, event, class/style list)
321
+ 4. **Node Bindings**: Creates slots, effects, or direct inserts based on type
322
+
323
+ ```typescript
324
+ // Input
325
+ html`<div class="${cls}" onclick=${handler}>${name}</div>`
326
+
327
+ // Output
328
+ const _t_abc = _template.template(`<div><!----></div>`);
329
+
330
+ (() => {
331
+ let root = _t_abc(),
332
+ el_1 = root.firstChild as _template.Element;
333
+
334
+ _template.setList(el_1, 'class', cls, _attr_1);
335
+ _template.delegate(el_1, 'click', handler);
336
+ _template.slot(el_1.firstChild as _template.Element, name);
337
+
338
+ return root;
339
+ })()
340
+ ```
341
+
342
+ #### Event Handling
343
+ Three event binding strategies:
344
+ - **Lifecycle Events** (`oncreate`, `ondestroy`): Direct element callbacks
345
+ - **Direct Attach** (`onfocus`, `onblur`, etc.): `addEventListener` directly
346
+ - **Delegated** (all others): Event delegation via `delegate()`
347
+
348
+ ---
349
+
350
+ ## Integration Flow
351
+
352
+ ### Vite Integration
353
+
354
+ ```typescript
355
+ // vite.config.ts
356
+ import reactivityCompiler from '@esportsplus/reactivity/compiler/plugins/vite';
357
+ import templateCompiler from '@esportsplus/frontend/template/compiler/plugins/vite';
358
+
359
+ export default {
360
+ plugins: [
361
+ plugin({
362
+ name: '@esportsplus/frontend',
363
+ plugins: [
364
+ reactivityCompiler, // First: transform reactive() calls
365
+ templateCompiler // Second: transform html`` templates
366
+ ]
367
+ })({ root: __dirname })
368
+ ]
369
+ }
370
+ ```
371
+
372
+ ### Execution Order
373
+
374
+ 1. **Vite Transform Hook**: File loaded/changed
375
+ 2. **Program Resolution**: Get/create TypeScript program
376
+ 3. **Coordinator**: Execute plugins sequentially
377
+ - **Reactivity Plugin**: Transform `reactive()` → signals/computed
378
+ - **Template Plugin**: Transform `html\`\`` → DOM code
379
+ 4. **Code Generation**: Apply replacements, prepends, imports
380
+ 5. **Return**: Transformed code to Vite
381
+
382
+ ### Cross-Plugin Communication
383
+
384
+ The `SharedContext` (`Map<string, unknown>`) enables plugins to share state:
385
+ - Cleared on file watch change
386
+ - Scoped per project root
387
+
388
+ ---
389
+
390
+ ## Key Design Decisions
391
+
392
+ ### 1. Sequential Plugin Execution
393
+ Each plugin receives a fresh AST with accurate positions after previous plugins' changes. This ensures:
394
+ - Correct source positions for replacements
395
+ - Valid type checker for semantic analysis
396
+ - No position drift from accumulated changes
397
+
398
+ ### 2. Intent-Based Transformations
399
+ Plugins return "intents" rather than modified strings:
400
+ - `ReplacementIntent`: AST node + generator function
401
+ - `ImportIntent`: Package + add/remove specifiers
402
+ - Intents resolved at apply-time with current positions
403
+
404
+ ### 3. Pattern-Based Quick Checks
405
+ Plugins declare patterns (e.g., `reactive(`) for fast-path skipping:
406
+ - Avoids AST parsing when unnecessary
407
+ - Simple string indexOf check
408
+ - Patterns checked before type analysis
409
+
410
+ ### 4. Type-Aware Transformations
411
+ Full TypeScript program enables:
412
+ - Symbol origin tracking (handles re-exports)
413
+ - Type-based optimization decisions
414
+ - Accurate identifier resolution
415
+
416
+ ### 5. Optimized Code Generation
417
+ - **Template Factories**: Clone once, reuse many times
418
+ - **Path-Based Traversal**: Direct DOM navigation, no queries
419
+ - **Event Delegation**: Single listener per event type
420
+ - **Static Inlining**: Literal values inlined directly