@esportsplus/template 0.16.15 → 0.17.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 +33 -1
- package/build/compiler/plugins/vite.d.ts +8 -4
- package/build/compiler/plugins/vite.js +37 -2
- package/build/hmr.d.ts +10 -0
- package/build/hmr.js +42 -0
- package/build/index.d.ts +1 -0
- package/build/index.js +1 -0
- package/build/slot/array.js +21 -2
- package/build/slot/effect.d.ts +3 -3
- package/build/slot/effect.js +36 -17
- package/llm.txt +63 -4
- package/package.json +1 -1
- package/src/compiler/plugins/vite.ts +74 -5
- package/src/hmr.ts +70 -0
- package/src/index.ts +1 -0
- package/src/slot/array.ts +30 -2
- package/src/slot/effect.ts +46 -20
- package/tests/compiler/vite-hmr.ts +126 -0
- package/tests/hmr.ts +146 -0
- package/tests/slot/array.ts +201 -0
- package/tests/slot/async.ts +389 -0
- package/storage/feature-research-2026-03-24.md +0 -475
- package/test-output.txt +0 -0
|
@@ -1,475 +0,0 @@
|
|
|
1
|
-
# Feature Research — @esportsplus/template
|
|
2
|
-
|
|
3
|
-
**Date:** 2026-03-24
|
|
4
|
-
**Method:** Parallel web research agents covering modern framework features, DOM APIs, compiler/DX improvements
|
|
5
|
-
**Scope:** Runtime features, compiler enhancements, developer experience, new browser APIs
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
## Current Library Capabilities
|
|
10
|
-
|
|
11
|
-
- Compile-time `html` tagged template literal → optimized DOM construction
|
|
12
|
-
- `svg` tagged template support with SVG sprite helper
|
|
13
|
-
- Reactive slots: `EffectSlot` (single values), `ArraySlot` (lists with fine-grained ops)
|
|
14
|
-
- Event delegation (document-level) + direct attachment for non-bubbling events
|
|
15
|
-
- Lifecycle events: `onconnect`, `ondisconnect`, `onrender`, `onresize`, `ontick`
|
|
16
|
-
- Attribute system with batched RAF updates, class/style list merging
|
|
17
|
-
- Cleanup system via symbol-keyed arrays on nodes
|
|
18
|
-
- Vite plugin + TypeScript transformer
|
|
19
|
-
|
|
20
|
-
---
|
|
21
|
-
|
|
22
|
-
## Removed Features
|
|
23
|
-
|
|
24
|
-
- **Directive System** — Already supported. Compile-time transforms handle `classMap`, `styleMap`, conditionals, and keyed iteration natively.
|
|
25
|
-
- **Portals** — Already supported. `render(anyElement, content)` renders into any DOM target.
|
|
26
|
-
|
|
27
|
-
---
|
|
28
|
-
|
|
29
|
-
## Feature Findings
|
|
30
|
-
|
|
31
|
-
### F2: Enter/Exit Animation Primitives
|
|
32
|
-
|
|
33
|
-
**What:** Built-in support for animating elements entering and leaving the DOM. Separate from View Transitions — this covers individual element lifecycle animations.
|
|
34
|
-
|
|
35
|
-
**How frameworks implement:**
|
|
36
|
-
- Svelte: `transition:fade`, `in:fly`, `out:slide` directives with built-in easing
|
|
37
|
-
- Vue: `<Transition>` component with CSS class hooks (`v-enter-from`, `v-enter-active`, `v-leave-to`)
|
|
38
|
-
- SolidJS: `<Transition>` + `onEnter`/`onExit` callbacks
|
|
39
|
-
- FLIP technique: First-Last-Invert-Play for layout animations
|
|
40
|
-
|
|
41
|
-
**Why useful:**
|
|
42
|
-
- Enter animations: fade in, slide in, scale up when element added
|
|
43
|
-
- Exit animations: fade out, slide out when element removed (requires delaying removal)
|
|
44
|
-
- List reorder animations: FLIP calculates position delta, animates transform
|
|
45
|
-
- Without framework support, exit animations require manual `setTimeout` + class toggling
|
|
46
|
-
|
|
47
|
-
**Key challenge:** Exit animations require the library to **delay node removal** until the animation completes. This needs integration with the cleanup system.
|
|
48
|
-
|
|
49
|
-
**Proposed API:**
|
|
50
|
-
```typescript
|
|
51
|
-
// Attribute-based (compile-time detected)
|
|
52
|
-
html`<div ontransition=${(el, phase) => { /* 'enter' | 'exit' | 'move' */ }}>...</div>`;
|
|
53
|
-
|
|
54
|
-
// Or: explicit animation hooks
|
|
55
|
-
onenter?: (element: Element, done: VoidFunction) => void;
|
|
56
|
-
onexit?: (element: Element, done: VoidFunction) => void;
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
**Applicability:** High — the library's `ondisconnect` hook is the right place to intercept removal. Compile-time can detect animation attributes and emit deferred removal code.
|
|
60
|
-
|
|
61
|
-
**Complexity:** Medium (exit animations need deferred removal; FLIP needs position tracking)
|
|
62
|
-
**Priority:** Medium-High
|
|
63
|
-
|
|
64
|
-
---
|
|
65
|
-
|
|
66
|
-
### F3: Suspense / Async Content Boundaries
|
|
67
|
-
|
|
68
|
-
**What:** Declarative async content handling — show fallback UI while async data loads, then swap in real content. Nested suspense boundaries enable progressive rendering.
|
|
69
|
-
|
|
70
|
-
**How frameworks implement:**
|
|
71
|
-
- React: `<Suspense fallback={<Loading/>}>`
|
|
72
|
-
- SolidJS 2.0: `<Loading>` boundary with `isPending()` — distinguishes initial load from revalidation
|
|
73
|
-
- Svelte: `{#await promise}...{:then data}...{:catch error}...{/await}`
|
|
74
|
-
- Qwik: Automatic suspense via resumability
|
|
75
|
-
|
|
76
|
-
**Why useful:**
|
|
77
|
-
- Async data fetching is universal; every app needs loading states
|
|
78
|
-
- Nested boundaries prevent full-page loading spinners
|
|
79
|
-
- Streaming SSR: flush boundary fallbacks, then stream resolved content
|
|
80
|
-
- SolidJS 2.0's `isPending()` avoids tearing — query if async work is in flight without demolishing UI
|
|
81
|
-
|
|
82
|
-
**Proposed API:**
|
|
83
|
-
```typescript
|
|
84
|
-
// Compile-time: detect async effects, wrap in boundary
|
|
85
|
-
html`<div>${async () => {
|
|
86
|
-
let data = await fetch('/api');
|
|
87
|
-
return html`<span>${data.name}</span>`;
|
|
88
|
-
}}</div>`;
|
|
89
|
-
|
|
90
|
-
// Runtime: AsyncSlot that renders fallback, then swaps to resolved content
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
**Applicability:** Medium — requires new `AsyncSlot` type. Compile-time could detect async arrow functions and emit boundary code. Runtime needs promise tracking + fallback rendering.
|
|
94
|
-
|
|
95
|
-
**Complexity:** Medium-High
|
|
96
|
-
**Priority:** Medium
|
|
97
|
-
|
|
98
|
-
---
|
|
99
|
-
|
|
100
|
-
### F4: Error Boundaries
|
|
101
|
-
|
|
102
|
-
**What:** Catch rendering errors in a subtree and display fallback UI instead of crashing the entire app.
|
|
103
|
-
|
|
104
|
-
**How frameworks implement:**
|
|
105
|
-
- React: `class ErrorBoundary extends Component` with `componentDidCatch`
|
|
106
|
-
- SolidJS: `<ErrorBoundary fallback={err => <p>{err.message}</p>}>`
|
|
107
|
-
- Vue: `onErrorCaptured` lifecycle hook
|
|
108
|
-
- Svelte: No built-in (try/catch in load functions)
|
|
109
|
-
|
|
110
|
-
**Why useful:**
|
|
111
|
-
- Production apps need graceful degradation
|
|
112
|
-
- Isolate errors to the component that failed
|
|
113
|
-
- Show meaningful error messages instead of blank screens
|
|
114
|
-
- Enable retry mechanisms
|
|
115
|
-
|
|
116
|
-
**Proposed API:**
|
|
117
|
-
```typescript
|
|
118
|
-
// Wrap slot rendering in try/catch
|
|
119
|
-
import { boundary } from '@esportsplus/template';
|
|
120
|
-
|
|
121
|
-
boundary(
|
|
122
|
-
() => html`<div>${riskyContent}</div>`,
|
|
123
|
-
(error) => html`<div class="error">${error.message}</div>`
|
|
124
|
-
);
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
**Applicability:** Medium — `EffectSlot` already wraps effect execution. Adding try/catch + fallback rendering is natural. Compile-time could detect `boundary()` calls and emit optimized error handling.
|
|
128
|
-
|
|
129
|
-
**Complexity:** Low-Medium
|
|
130
|
-
**Priority:** Medium
|
|
131
|
-
|
|
132
|
-
---
|
|
133
|
-
|
|
134
|
-
### F5: Popover API Integration
|
|
135
|
-
|
|
136
|
-
**What:** Native browser API for overlay/popup content. `popover` attribute + `popovertarget` for declarative show/hide. Automatic top-layer rendering, light-dismiss, focus management.
|
|
137
|
-
|
|
138
|
-
**Browser support:** Chrome 114+, Firefox 125+, Safari 17+
|
|
139
|
-
|
|
140
|
-
**Why useful:**
|
|
141
|
-
- Replaces custom tooltip/dropdown/menu libraries
|
|
142
|
-
- Native accessibility (inert background, keyboard handling)
|
|
143
|
-
- Top-layer eliminates z-index conflicts
|
|
144
|
-
- `beforetoggle`/`toggle` events for state tracking
|
|
145
|
-
- `interestfor` (experimental) for hover/focus activation
|
|
146
|
-
|
|
147
|
-
**Current library gap:** No special handling for `popover` attribute — it would be set via generic `setAttribute`. But `popovertarget` needs special handling since it references another element by ID.
|
|
148
|
-
|
|
149
|
-
**Proposed integration:**
|
|
150
|
-
- Compile-time: detect `popover` and `popovertarget` attributes
|
|
151
|
-
- Runtime: auto-generate unique IDs for `popovertarget` references
|
|
152
|
-
- Bind `toggle` event via event delegation
|
|
153
|
-
- Add `onpopovershow`/`onpopoverhide` lifecycle events
|
|
154
|
-
|
|
155
|
-
**Applicability:** Medium — mostly attribute detection + event binding. The compile-time system can validate `popovertarget` references.
|
|
156
|
-
|
|
157
|
-
**Complexity:** Low
|
|
158
|
-
**Priority:** Medium
|
|
159
|
-
|
|
160
|
-
---
|
|
161
|
-
|
|
162
|
-
### F6: `moveBefore()` DOM API
|
|
163
|
-
|
|
164
|
-
**What:** New DOM method (`parentNode.moveBefore(node, referenceNode)`) for moving nodes within the DOM without triggering disconnect/reconnect lifecycle callbacks. Preserves iframe state, CSS animations, focus, form data, `<video>` playback.
|
|
165
|
-
|
|
166
|
-
**Browser support:** Chrome 133+, Firefox 144+, Edge 133+. Safari: not yet.
|
|
167
|
-
|
|
168
|
-
**Why useful:**
|
|
169
|
-
- Array sort/reverse currently detaches all nodes into fragment, then reattaches
|
|
170
|
-
- This triggers `disconnectedCallback` + `connectedCallback` for every node
|
|
171
|
-
- Destroys iframe content, CSS animations, focus state, video playback
|
|
172
|
-
- `moveBefore` preserves all of these — just repositions in the tree
|
|
173
|
-
|
|
174
|
-
**Proposed integration:**
|
|
175
|
-
```typescript
|
|
176
|
-
// In ArraySlot.sort() / ArraySlot.sync():
|
|
177
|
-
if ('moveBefore' in this.marker.parentNode!) {
|
|
178
|
-
// Use moveBefore for each node
|
|
179
|
-
ref.parentNode!.moveBefore(node, ref.nextSibling);
|
|
180
|
-
}
|
|
181
|
-
else {
|
|
182
|
-
// Fallback: existing fragment-based approach
|
|
183
|
-
}
|
|
184
|
-
```
|
|
185
|
-
|
|
186
|
-
**Applicability:** High — direct drop-in for `ArraySlot.sort()` and `ArraySlot.sync()`. The LIS algorithm (already implemented) determines which nodes to move; `moveBefore` makes those moves non-destructive.
|
|
187
|
-
|
|
188
|
-
**Complexity:** Low
|
|
189
|
-
**Priority:** High (when Safari ships support)
|
|
190
|
-
|
|
191
|
-
---
|
|
192
|
-
|
|
193
|
-
### F7: Two-Way Binding / Form Handling
|
|
194
|
-
|
|
195
|
-
**What:** Syntactic sugar for binding form input values to reactive signals with automatic synchronization.
|
|
196
|
-
|
|
197
|
-
**How frameworks implement:**
|
|
198
|
-
- Vue: `v-model` directive (compiles to value binding + input event)
|
|
199
|
-
- Svelte: `bind:value`, `bind:checked`, `bind:group`
|
|
200
|
-
- SolidJS: No built-in two-way binding (explicit event handlers)
|
|
201
|
-
- Angular: `[(ngModel)]` with FormsModule
|
|
202
|
-
|
|
203
|
-
**Why useful:**
|
|
204
|
-
- Forms are the most common interactive pattern
|
|
205
|
-
- Manual `oninput` + signal write is boilerplate
|
|
206
|
-
- Checkbox groups, radio groups, select multiples need special handling
|
|
207
|
-
- Validation interception (transform before write)
|
|
208
|
-
|
|
209
|
-
**Proposed API:**
|
|
210
|
-
```typescript
|
|
211
|
-
// Compile-time: detect reactive value in value/checked position
|
|
212
|
-
html`<input value=${signal} />` // auto-bind: set value + listen for input event
|
|
213
|
-
|
|
214
|
-
// Or explicit:
|
|
215
|
-
html`<input bind:value=${signal} />`
|
|
216
|
-
```
|
|
217
|
-
|
|
218
|
-
**Compile-time detection:** If `value` attribute is an `Effect` (reactive function) on an `<input>`, emit both the attribute binding AND an `input` event listener that writes back to the signal.
|
|
219
|
-
|
|
220
|
-
**Applicability:** High — compile-time system can detect input elements + reactive attributes and emit two-way binding code.
|
|
221
|
-
|
|
222
|
-
**Complexity:** Medium (many edge cases: select, textarea, checkbox, radio, contenteditable)
|
|
223
|
-
**Priority:** Medium-High
|
|
224
|
-
|
|
225
|
-
---
|
|
226
|
-
|
|
227
|
-
### F8: Ref / Element Access Pattern
|
|
228
|
-
|
|
229
|
-
**What:** A way to get a reference to the actual DOM element after rendering, for use in imperative DOM manipulation, measurements, third-party library integration.
|
|
230
|
-
|
|
231
|
-
**How frameworks implement:**
|
|
232
|
-
- React: `useRef()` + `ref={myRef}`
|
|
233
|
-
- SolidJS: `let el; <div ref={el}>`
|
|
234
|
-
- Vue: `ref="myRef"` template attribute
|
|
235
|
-
- Lit: `@query('#selector')` decorator
|
|
236
|
-
|
|
237
|
-
**Why useful:**
|
|
238
|
-
- Canvas/WebGL integration needs element reference
|
|
239
|
-
- Third-party library init (charts, maps, editors)
|
|
240
|
-
- Measurements (getBoundingClientRect)
|
|
241
|
-
- Focus management
|
|
242
|
-
- Animation libraries (GSAP, Motion One)
|
|
243
|
-
|
|
244
|
-
**Current library state:** The `onconnect` lifecycle event already provides element reference:
|
|
245
|
-
```typescript
|
|
246
|
-
html`<div onconnect=${(el) => { /* have reference */ }}>...</div>`
|
|
247
|
-
```
|
|
248
|
-
|
|
249
|
-
This is already a ref mechanism. A dedicated `ref` API would be sugar for this pattern.
|
|
250
|
-
|
|
251
|
-
**Proposed API:**
|
|
252
|
-
```typescript
|
|
253
|
-
// Callback ref (already supported via onconnect)
|
|
254
|
-
html`<div onconnect=${(el) => { canvasRef = el; }}>...</div>`
|
|
255
|
-
|
|
256
|
-
// Signal ref (new — populate signal with element)
|
|
257
|
-
let el = signal<HTMLDivElement | null>(null);
|
|
258
|
-
html`<div ref=${el}>...</div>`
|
|
259
|
-
// Compile-time: emit `onconnect` that writes to signal + `ondisconnect` that nulls it
|
|
260
|
-
```
|
|
261
|
-
|
|
262
|
-
**Applicability:** Low-Medium — `onconnect` already covers the core use case. Signal ref is just syntactic sugar.
|
|
263
|
-
|
|
264
|
-
**Complexity:** Low
|
|
265
|
-
**Priority:** Low
|
|
266
|
-
|
|
267
|
-
---
|
|
268
|
-
|
|
269
|
-
### F9: Keyed List Rendering
|
|
270
|
-
|
|
271
|
-
**What:** Explicit key association for list items to ensure correct reconciliation when items are reordered, inserted, or removed. Without keys, positional identity is used (item at index 0 is always the "first" item).
|
|
272
|
-
|
|
273
|
-
**Why useful:**
|
|
274
|
-
- Reordering without keys: animations break, form state lost, components remount
|
|
275
|
-
- With keys: framework knows "item A moved from position 2 to 0" — can reuse existing DOM
|
|
276
|
-
- Critical for: sortable lists, drag-and-drop, filtered lists, paginated data
|
|
277
|
-
|
|
278
|
-
**Current library state:** `ArraySlot` uses `html.reactive(array, template)` — the template function receives the value. There's no explicit key mechanism; the array index IS the identity (positional).
|
|
279
|
-
|
|
280
|
-
**How frameworks handle it:**
|
|
281
|
-
- React: `key` prop on JSX elements
|
|
282
|
-
- SolidJS: `<For each={items}>{(item) => ...}</For>` — items tracked by reference
|
|
283
|
-
- Svelte: `{#each items as item (item.id)}` — parenthetical key expression
|
|
284
|
-
- Lit: `repeat(items, item => item.id, (item) => html\`...\`)` directive
|
|
285
|
-
|
|
286
|
-
**Proposed API:**
|
|
287
|
-
```typescript
|
|
288
|
-
// Key function as third argument to html.reactive:
|
|
289
|
-
html.reactive(array, (item) => html`<div>${item.name}</div>`, (item) => item.id);
|
|
290
|
-
|
|
291
|
-
// Compile-time: emit ArraySlot with key-based reconciliation
|
|
292
|
-
```
|
|
293
|
-
|
|
294
|
-
**Applicability:** High — the ArraySlot already has `splice`, `set`, `sort` operations. Adding key-based identity would improve reconciliation when the array is replaced entirely (vs mutated). Compile-time can detect the key function and emit optimal diff code.
|
|
295
|
-
|
|
296
|
-
**Complexity:** Medium-High (key-based diff algorithm, handling key collisions, mapping old→new)
|
|
297
|
-
**Priority:** High
|
|
298
|
-
|
|
299
|
-
---
|
|
300
|
-
|
|
301
|
-
### F10: Streaming SSR + Hydration
|
|
302
|
-
|
|
303
|
-
**What:** Server-side rendering that streams HTML chunks as they become ready, with client-side hydration that reuses the server-rendered DOM instead of re-creating it.
|
|
304
|
-
|
|
305
|
-
**How frameworks implement:**
|
|
306
|
-
- React 18: `renderToReadableStream()` + Suspense boundaries for streaming
|
|
307
|
-
- SolidJS: `renderToStream()` with island deduplication
|
|
308
|
-
- Lit: `@lit-labs/ssr` with Declarative Shadow DOM
|
|
309
|
-
- Qwik: Resumability — no hydration needed, just resume from serialized state
|
|
310
|
-
|
|
311
|
-
**Why useful:**
|
|
312
|
-
- TTFB improvement: stream first content immediately
|
|
313
|
-
- Progressive rendering: show above-the-fold content while below-fold loads
|
|
314
|
-
- SEO: search engines crawl the streamed HTML
|
|
315
|
-
- Performance: reuse server DOM instead of re-creating
|
|
316
|
-
|
|
317
|
-
**Key components needed:**
|
|
318
|
-
1. **Template serializer:** Convert compiled template to HTML string (server-side)
|
|
319
|
-
2. **Hydration runtime:** Walk existing DOM, attach event handlers, connect reactivity
|
|
320
|
-
3. **Marker reconciliation:** Match server-rendered markers to slot positions
|
|
321
|
-
4. **Streaming boundaries:** `Suspense`-like boundaries for progressive flush
|
|
322
|
-
|
|
323
|
-
**Applicability:** Medium — the compile-time system knows template structure. A server-side codegen target could emit `renderToString()` instead of DOM construction. Hydration would walk the existing DOM using the same paths the runtime uses.
|
|
324
|
-
|
|
325
|
-
**Complexity:** High
|
|
326
|
-
**Priority:** Medium (for full-stack applications)
|
|
327
|
-
|
|
328
|
-
---
|
|
329
|
-
|
|
330
|
-
### F11: HMR (Hot Module Replacement) for Templates
|
|
331
|
-
|
|
332
|
-
**What:** Fine-grained hot reloading during development — when a template changes, only that template's DOM updates without full page reload.
|
|
333
|
-
|
|
334
|
-
**How frameworks implement:**
|
|
335
|
-
- Vite: Module-level HMR via `import.meta.hot.accept()`
|
|
336
|
-
- Svelte: Component-level HMR preserving state
|
|
337
|
-
- Vue: Template-only HMR (script state preserved)
|
|
338
|
-
- SolidJS + Vite: Component-boundary HMR
|
|
339
|
-
|
|
340
|
-
**Why useful:**
|
|
341
|
-
- Faster development iteration
|
|
342
|
-
- Preserves app state during UI changes
|
|
343
|
-
- Instant visual feedback
|
|
344
|
-
|
|
345
|
-
**Current library state:** The Vite plugin (`compiler/plugins/vite.ts`) transforms templates at build time. No HMR handling exists.
|
|
346
|
-
|
|
347
|
-
**Proposed integration:**
|
|
348
|
-
- Vite plugin emits `import.meta.hot.accept()` for modules with `html` templates
|
|
349
|
-
- On update: re-run template factory, diff against existing DOM, patch
|
|
350
|
-
- Preserve reactive bindings across hot updates
|
|
351
|
-
|
|
352
|
-
**Applicability:** High — Vite plugin is already the entry point. Adding HMR is a natural extension.
|
|
353
|
-
|
|
354
|
-
**Complexity:** Medium
|
|
355
|
-
**Priority:** High (developer experience)
|
|
356
|
-
|
|
357
|
-
---
|
|
358
|
-
|
|
359
|
-
### F12: Declarative Shadow DOM
|
|
360
|
-
|
|
361
|
-
**What:** HTML attribute `shadowrootmode="open|closed"` on `<template>` elements creates shadow roots during HTML parsing — no JavaScript needed for initial render.
|
|
362
|
-
|
|
363
|
-
**Browser support:** Chrome 111+, Firefox 125+, Safari 16.4+
|
|
364
|
-
|
|
365
|
-
**Why useful:**
|
|
366
|
-
- SSR'd Web Components render with encapsulation immediately (no FOUC)
|
|
367
|
-
- No JavaScript needed for initial shadow DOM creation
|
|
368
|
-
- Works with streaming SSR
|
|
369
|
-
- `adoptedStyleSheets` share styles across shadow roots efficiently
|
|
370
|
-
|
|
371
|
-
**Proposed integration:**
|
|
372
|
-
```typescript
|
|
373
|
-
// Compile-time: detect shadow root directive
|
|
374
|
-
html`<my-component>
|
|
375
|
-
<template shadowrootmode="open">
|
|
376
|
-
<style>${styles}</style>
|
|
377
|
-
<slot></slot>
|
|
378
|
-
</template>
|
|
379
|
-
</my-component>`
|
|
380
|
-
```
|
|
381
|
-
|
|
382
|
-
**Applicability:** Medium — useful for Web Component authoring. Compile-time could emit Declarative Shadow DOM for SSR, then hydrate on client.
|
|
383
|
-
|
|
384
|
-
**Complexity:** Medium
|
|
385
|
-
**Priority:** Low-Medium (niche — Web Component authors)
|
|
386
|
-
|
|
387
|
-
---
|
|
388
|
-
|
|
389
|
-
### F13: Incremental Compilation
|
|
390
|
-
|
|
391
|
-
**What:** Only re-compile templates that changed since last build, using cached AST data.
|
|
392
|
-
|
|
393
|
-
**How frameworks implement:**
|
|
394
|
-
- TypeScript: `.tsbuildinfo` for incremental builds
|
|
395
|
-
- Vite: Module dependency graph + timestamp checking
|
|
396
|
-
- esbuild: Content hash comparison
|
|
397
|
-
|
|
398
|
-
**Why useful:**
|
|
399
|
-
- Large projects with 100+ templates: full recompilation is slow
|
|
400
|
-
- Dev builds benefit most — save seconds per change
|
|
401
|
-
- CI builds: cache compilation artifacts between runs
|
|
402
|
-
|
|
403
|
-
**Proposed implementation:**
|
|
404
|
-
- Store template hashes + compiled output in `.tsbuildinfo`-style cache
|
|
405
|
-
- On build: compare template string hash, skip unchanged
|
|
406
|
-
- Vite plugin: leverage Vite's module graph for dependency tracking
|
|
407
|
-
|
|
408
|
-
**Applicability:** Medium — more valuable as the library is adopted in larger projects.
|
|
409
|
-
|
|
410
|
-
**Complexity:** Medium
|
|
411
|
-
**Priority:** Medium (scales with project size)
|
|
412
|
-
|
|
413
|
-
---
|
|
414
|
-
|
|
415
|
-
## Priority Matrix
|
|
416
|
-
|
|
417
|
-
### Tier 1 — High Value, Practical to Implement
|
|
418
|
-
|
|
419
|
-
| # | Feature | Complexity | Notes |
|
|
420
|
-
|---|---------|------------|-------|
|
|
421
|
-
| F6 | `moveBefore()` API | Low | Drop-in for ArraySlot sort/sync |
|
|
422
|
-
| F9 | Keyed list rendering | Medium-High | Correctness requirement for real apps |
|
|
423
|
-
| F11 | HMR for templates | Medium | Critical DX improvement |
|
|
424
|
-
|
|
425
|
-
### Tier 2 — High Value, Higher Effort
|
|
426
|
-
|
|
427
|
-
| # | Feature | Complexity | Notes |
|
|
428
|
-
|---|---------|------------|-------|
|
|
429
|
-
| F2 | Enter/exit animations | Medium | Needs deferred removal |
|
|
430
|
-
| F3 | Suspense / Async boundaries | Medium-High | New slot type |
|
|
431
|
-
| F4 | Error boundaries | Low-Medium | Try/catch wrapper |
|
|
432
|
-
| F7 | Two-way binding | Medium | Many input type edge cases |
|
|
433
|
-
|
|
434
|
-
### Tier 3 — Nice to Have
|
|
435
|
-
|
|
436
|
-
| # | Feature | Complexity | Notes |
|
|
437
|
-
|---|---------|------------|-------|
|
|
438
|
-
| F1 | View Transitions API | Low-Medium | Wrapper around browser API |
|
|
439
|
-
| F5 | Popover API integration | Low | Attribute detection + events |
|
|
440
|
-
| F8 | Ref / element access | Low | `onconnect` already covers this |
|
|
441
|
-
| F12 | Declarative Shadow DOM | Medium | Niche use case |
|
|
442
|
-
| F13 | Incremental compilation | Medium | Scales with adoption |
|
|
443
|
-
|
|
444
|
-
### Tier 4 — Strategic / Long-term
|
|
445
|
-
|
|
446
|
-
| # | Feature | Complexity | Notes |
|
|
447
|
-
|---|---------|------------|-------|
|
|
448
|
-
| F10 | Streaming SSR + Hydration | High | Full-stack requirement |
|
|
449
|
-
|
|
450
|
-
---
|
|
451
|
-
|
|
452
|
-
## Recommended Implementation Order
|
|
453
|
-
|
|
454
|
-
1. **F6: `moveBefore()`** — Low complexity, improves ArraySlot sort/reverse
|
|
455
|
-
2. **F4: Error boundaries** — Low-medium complexity, production necessity
|
|
456
|
-
3. **F9: Keyed lists** — Medium-high complexity, correctness requirement
|
|
457
|
-
4. **F7: Two-way binding** — Medium complexity, form-heavy apps
|
|
458
|
-
5. **F2: Enter/exit animations** — Medium complexity, visual polish
|
|
459
|
-
6. **F11: HMR** — Medium complexity, developer experience
|
|
460
|
-
7. **F3: Suspense** — Medium-high complexity, async patterns
|
|
461
|
-
8. **F1: View Transitions** — Low complexity but niche, can add anytime
|
|
462
|
-
|
|
463
|
-
---
|
|
464
|
-
|
|
465
|
-
## Research Sources
|
|
466
|
-
|
|
467
|
-
- Lit 3.x documentation (directives, SSR, task management)
|
|
468
|
-
- Svelte 5 runes specification (fine-grained reactivity, snippets)
|
|
469
|
-
- SolidJS 2.0 RFC (async primitives, streaming dedup, `isPending`)
|
|
470
|
-
- Qwik documentation (resumability, symbol extraction)
|
|
471
|
-
- Million.js architecture (block virtual DOM)
|
|
472
|
-
- MDN: View Transitions API, Popover API, `moveBefore()`, Declarative Shadow DOM
|
|
473
|
-
- Chrome DevRel blog: View Transitions (Chrome 111/126), Popover API (Chrome 114)
|
|
474
|
-
- TC39 Signals proposal (Stage 1)
|
|
475
|
-
- Vite HMR documentation
|
package/test-output.txt
DELETED
|
Binary file
|