@estjs/template 0.0.15-beta.9 → 0.0.15
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/dist/template.cjs.js +2 -2
- package/dist/template.cjs.js.map +1 -1
- package/dist/template.d.cts +166 -92
- package/dist/template.d.ts +166 -92
- package/dist/template.dev.cjs.js +628 -369
- package/dist/template.dev.cjs.js.map +1 -1
- package/dist/template.dev.esm.js +625 -372
- package/dist/template.dev.esm.js.map +1 -1
- package/dist/template.esm.js +2 -2
- package/dist/template.esm.js.map +1 -1
- package/package.json +3 -3
package/dist/template.d.ts
CHANGED
|
@@ -24,30 +24,16 @@ declare function provide<T>(key: InjectionKey<T> | string | number, value: T): v
|
|
|
24
24
|
*/
|
|
25
25
|
declare function inject<T>(key: InjectionKey<T> | string | number, defaultValue?: T): T;
|
|
26
26
|
|
|
27
|
-
/**
|
|
28
|
-
* Scope represents an execution context in the component tree.
|
|
29
|
-
* It manages provides, cleanup functions, and lifecycle hooks.
|
|
30
|
-
*/
|
|
31
27
|
interface Scope {
|
|
32
|
-
/** Unique identifier for debugging */
|
|
33
28
|
readonly id: number;
|
|
34
|
-
/** Parent scope in the hierarchy */
|
|
35
29
|
parent: Scope | null;
|
|
36
|
-
|
|
37
|
-
children: Set<Scope> | null;
|
|
38
|
-
/** Provided values (lazy initialized) */
|
|
30
|
+
children: Scope[] | null;
|
|
39
31
|
provides: Map<InjectionKey<unknown> | string | number | symbol, unknown> | null;
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
/** Update lifecycle hooks (lazy initialized) */
|
|
45
|
-
onUpdate: Set<() => void | Promise<void>> | null;
|
|
46
|
-
/** Destroy lifecycle hooks (lazy initialized) */
|
|
47
|
-
onDestroy: Set<() => void | Promise<void>> | null;
|
|
48
|
-
/** Whether the scope has been mounted */
|
|
32
|
+
cleanup: (() => void)[] | null;
|
|
33
|
+
onMount: (() => void | Promise<void>)[] | null;
|
|
34
|
+
onUpdate: (() => void | Promise<void>)[] | null;
|
|
35
|
+
onDestroy: (() => void | Promise<void>)[] | null;
|
|
49
36
|
isMounted: boolean;
|
|
50
|
-
/** Whether the scope has been destroyed */
|
|
51
37
|
isDestroyed: boolean;
|
|
52
38
|
}
|
|
53
39
|
/**
|
|
@@ -60,13 +46,6 @@ declare function getActiveScope(): Scope | null;
|
|
|
60
46
|
* @param scope - The scope to set as active
|
|
61
47
|
*/
|
|
62
48
|
declare function setActiveScope(scope: Scope | null): void;
|
|
63
|
-
/**
|
|
64
|
-
* Create a new scope with optional parent.
|
|
65
|
-
* If no parent is provided, uses the current active scope as parent.
|
|
66
|
-
*
|
|
67
|
-
* @param parent - Optional parent scope (defaults to active scope)
|
|
68
|
-
* @returns A new scope instance
|
|
69
|
-
*/
|
|
70
49
|
declare function createScope(parent?: Scope | null): Scope;
|
|
71
50
|
/**
|
|
72
51
|
* Run a function within a scope, ensuring proper cleanup.
|
|
@@ -78,27 +57,46 @@ declare function createScope(parent?: Scope | null): Scope;
|
|
|
78
57
|
*/
|
|
79
58
|
declare function runWithScope<T>(scope: Scope, fn: () => T): T;
|
|
80
59
|
/**
|
|
81
|
-
* Dispose a scope and all
|
|
82
|
-
*
|
|
60
|
+
* Dispose a scope and recursively dispose all child scopes.
|
|
61
|
+
* Performs the following cleanup in order:
|
|
62
|
+
* 1. Recursively disposes all children (depth-first)
|
|
63
|
+
* 2. Executes destroy lifecycle hooks
|
|
64
|
+
* 3. Executes registered cleanup functions
|
|
65
|
+
* 4. Removes scope from parent's children list
|
|
66
|
+
* 5. Clears all internal collections and resets state
|
|
67
|
+
*
|
|
68
|
+
* Safe to call multiple times (idempotent).
|
|
83
69
|
*
|
|
84
70
|
* @param scope - The scope to dispose
|
|
71
|
+
*
|
|
72
|
+
* @example
|
|
73
|
+
* ```ts
|
|
74
|
+
* const scope = createScope(parent);
|
|
75
|
+
* // ... use scope ...
|
|
76
|
+
* disposeScope(scope); // Cleanup everything
|
|
77
|
+
* ```
|
|
85
78
|
*/
|
|
86
79
|
declare function disposeScope(scope: Scope): void;
|
|
87
80
|
/**
|
|
88
|
-
* Register a cleanup function
|
|
89
|
-
*
|
|
81
|
+
* Register a cleanup function to be executed when the scope is disposed.
|
|
82
|
+
* Useful for cleaning up timers, subscriptions, event listeners, etc.
|
|
83
|
+
*
|
|
84
|
+
* Cleanup functions are executed in LIFO order (last registered, first executed).
|
|
85
|
+
* Cleanup errors don't prevent other cleanups from running.
|
|
90
86
|
*
|
|
91
|
-
* @param fn - The cleanup function
|
|
87
|
+
* @param fn - The cleanup function to register
|
|
88
|
+
*
|
|
89
|
+
* @throws Error in dev mode if called outside a scope
|
|
90
|
+
*
|
|
91
|
+
* @example
|
|
92
|
+
* ```ts
|
|
93
|
+
* const timerId = setInterval(() => {}, 1000);
|
|
94
|
+
* onCleanup(() => clearInterval(timerId));
|
|
95
|
+
* ```
|
|
92
96
|
*/
|
|
93
97
|
declare function onCleanup(fn: () => void): void;
|
|
94
98
|
|
|
95
|
-
declare
|
|
96
|
-
NORMAL = "normal",
|
|
97
|
-
FRAGMENT = "fragment",
|
|
98
|
-
PORTAL = "portal",
|
|
99
|
-
SUSPENSE = "suspense",
|
|
100
|
-
FOR = "for"
|
|
101
|
-
}
|
|
99
|
+
declare const NORMAL_COMPONENT: unique symbol;
|
|
102
100
|
|
|
103
101
|
type AnyNode = Node | Component<any> | Element | string | number | boolean | null | undefined | AnyNode[] | (() => AnyNode) | Signal<AnyNode> | Computed<AnyNode>;
|
|
104
102
|
type ComponentProps = Record<string, unknown>;
|
|
@@ -112,16 +110,26 @@ declare class Component<P extends ComponentProps = ComponentProps> {
|
|
|
112
110
|
protected parentNode: Node | undefined;
|
|
113
111
|
beforeNode: Node | undefined;
|
|
114
112
|
private reactiveProps;
|
|
113
|
+
private _propSnapshots;
|
|
115
114
|
readonly key: string | undefined;
|
|
116
115
|
protected state: number;
|
|
117
116
|
protected parentScope: Scope | null;
|
|
118
|
-
|
|
117
|
+
readonly [NORMAL_COMPONENT] = true;
|
|
119
118
|
get isConnected(): boolean;
|
|
120
119
|
get firstChild(): Node | undefined;
|
|
121
120
|
constructor(component: ComponentFn<P>, props?: P);
|
|
122
121
|
mount(parentNode: Node, beforeNode?: Node): AnyNode[];
|
|
123
|
-
update(prevNode: Component<
|
|
124
|
-
|
|
122
|
+
update<T extends ComponentProps>(prevNode: Component<T>): Component<T>;
|
|
123
|
+
/**
|
|
124
|
+
* Update reactive props by comparing with current values
|
|
125
|
+
*/
|
|
126
|
+
private _updateReactiveProps;
|
|
127
|
+
private unwrapRenderResult;
|
|
128
|
+
forceUpdate(): void;
|
|
129
|
+
/**
|
|
130
|
+
* Get anchor node for insertion
|
|
131
|
+
*/
|
|
132
|
+
private _getAnchorNode;
|
|
125
133
|
/**
|
|
126
134
|
* Destroy component
|
|
127
135
|
*/
|
|
@@ -151,13 +159,7 @@ declare function createComponent<P extends ComponentProps>(componentFn: Componen
|
|
|
151
159
|
* @param html - The HTML string to create template from
|
|
152
160
|
* @returns Factory function that returns a cloned node of the template
|
|
153
161
|
* @throws {Error} When template content is empty or invalid
|
|
154
|
-
|
|
155
|
-
* @example
|
|
156
|
-
* ```typescript
|
|
157
|
-
* const buttonTemplate = template('<button>Click me</button>');
|
|
158
|
-
* const button1 = buttonTemplate(); // Creates first button instance
|
|
159
|
-
* const button2 = buttonTemplate(); // Creates second button instance
|
|
160
|
-
* ```
|
|
162
|
+
|
|
161
163
|
*/
|
|
162
164
|
declare function template(html: string): () => Node;
|
|
163
165
|
/**
|
|
@@ -169,41 +171,57 @@ declare function template(html: string): () => Node;
|
|
|
169
171
|
* @param component - The root component function to mount
|
|
170
172
|
* @param target - CSS selector string or DOM element to mount to
|
|
171
173
|
* @returns The mount root component instance, or undefined if target not found
|
|
172
|
-
*
|
|
173
|
-
* @example
|
|
174
|
-
* ```typescript
|
|
175
|
-
* const App = () => template('<div>Hello World</div>')
|
|
176
|
-
* const app = createApp(App, '#root');
|
|
177
|
-
*
|
|
178
|
-
* // Or with DOM element
|
|
179
|
-
* const container = document.getElementById('app');
|
|
180
|
-
* const app = createApp(App, container);
|
|
181
|
-
* ```
|
|
182
174
|
*/
|
|
183
|
-
declare function createApp<P extends ComponentProps = {}>(component: ComponentFn<P>, target: string | Element): Component<P> | undefined;
|
|
175
|
+
declare function createApp<P extends ComponentProps = {}>(component: ComponentFn<P> | Component<P>, target: string | Element): Component<P> | undefined;
|
|
184
176
|
|
|
177
|
+
/**
|
|
178
|
+
* Lifecycle hook type: returns void or a Promise that resolves when complete.
|
|
179
|
+
* Hooks can perform cleanup by returning a cleanup function.
|
|
180
|
+
*/
|
|
185
181
|
type LifecycleHook = () => void | Promise<void>;
|
|
186
182
|
/**
|
|
187
183
|
* Register a mount lifecycle hook.
|
|
188
|
-
*
|
|
184
|
+
* Runs after component is mounted and virtual tree is committed.
|
|
185
|
+
* If the scope is already mounted, the hook executes immediately.
|
|
189
186
|
*
|
|
190
|
-
* @
|
|
187
|
+
* @throws Error in dev mode if called outside a scope
|
|
188
|
+
* @example
|
|
189
|
+
* ```tsx
|
|
190
|
+
* onMount(() => {
|
|
191
|
+
* console.log('Component mounted');
|
|
192
|
+
* return () => console.log('Cleanup');
|
|
193
|
+
* });
|
|
194
|
+
* ```
|
|
191
195
|
*/
|
|
192
196
|
declare function onMount(hook: LifecycleHook): void;
|
|
193
197
|
/**
|
|
194
|
-
* Register
|
|
195
|
-
*
|
|
198
|
+
* Register an update lifecycle hook.
|
|
199
|
+
* Runs whenever the component re-renders due to prop or state changes.
|
|
196
200
|
*
|
|
197
|
-
* @
|
|
201
|
+
* @throws Error in dev mode if called outside a scope
|
|
202
|
+
* @example
|
|
203
|
+
* ```tsx
|
|
204
|
+
* onUpdate(() => {
|
|
205
|
+
* console.log('Component updated');
|
|
206
|
+
* });
|
|
207
|
+
* ```
|
|
198
208
|
*/
|
|
199
|
-
declare function
|
|
209
|
+
declare function onUpdate(hook: LifecycleHook): void;
|
|
200
210
|
/**
|
|
201
|
-
* Register
|
|
202
|
-
*
|
|
211
|
+
* Register a destroy lifecycle hook.
|
|
212
|
+
* Runs before scope is disposed and resources are cleaned up.
|
|
213
|
+
* Perfect for resetting external state, unsubscribing from events, etc.
|
|
203
214
|
*
|
|
204
|
-
* @
|
|
215
|
+
* @throws Error in dev mode if called outside a scope
|
|
216
|
+
* @example
|
|
217
|
+
* ```tsx
|
|
218
|
+
* onDestroy(() => {
|
|
219
|
+
* unsubscribe();
|
|
220
|
+
* clearTimeout(timerId);
|
|
221
|
+
* });
|
|
222
|
+
* ```
|
|
205
223
|
*/
|
|
206
|
-
declare function
|
|
224
|
+
declare function onDestroy(hook: LifecycleHook): void;
|
|
207
225
|
|
|
208
226
|
/**
|
|
209
227
|
* Add event listener with automatic cleanup on scope destruction
|
|
@@ -226,16 +244,15 @@ declare function bindElement(node: Element, key: string, defaultValue: unknown,
|
|
|
226
244
|
/**
|
|
227
245
|
* Reactive node insertion with binding support
|
|
228
246
|
*
|
|
229
|
-
* @param parent
|
|
230
|
-
* @param nodeFactory
|
|
231
|
-
* @param before
|
|
232
|
-
* @returns Array of rendered nodes
|
|
247
|
+
* @param parent Parent node
|
|
248
|
+
* @param nodeFactory Node factory function or static node
|
|
249
|
+
* @param before Reference node for insertion position
|
|
233
250
|
*
|
|
234
251
|
* @example
|
|
235
252
|
* ```typescript
|
|
236
253
|
* insert(container, () => message.value, null);
|
|
237
254
|
* insert(container, staticElement, referenceNode);
|
|
238
|
-
* insert(container, "Hello World", null);
|
|
255
|
+
* insert(container, "Hello World", null); // Direct string support
|
|
239
256
|
* ```
|
|
240
257
|
*/
|
|
241
258
|
declare function insert(parent: Node, nodeFactory: AnyNode, before?: Node): AnyNode[] | undefined;
|
|
@@ -322,13 +339,35 @@ declare function normalizeNode(node: unknown): Node;
|
|
|
322
339
|
*/
|
|
323
340
|
declare function isSameNode(a: AnyNode, b: AnyNode): boolean;
|
|
324
341
|
/**
|
|
325
|
-
* Shallow compare two objects
|
|
342
|
+
* Shallow compare two objects or arrays
|
|
343
|
+
* Performs strict equality check on top-level properties
|
|
326
344
|
*
|
|
327
|
-
* @param a - First
|
|
328
|
-
* @param b - Second
|
|
329
|
-
* @returns true if
|
|
345
|
+
* @param a - First value to compare
|
|
346
|
+
* @param b - Second value to compare
|
|
347
|
+
* @returns true if values are shallowly equal
|
|
330
348
|
*/
|
|
331
|
-
declare function shallowCompare(a:
|
|
349
|
+
declare function shallowCompare(a: unknown, b: unknown): boolean;
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* Get rendered element by hydration key or create from template
|
|
353
|
+
* @param {string} temp - the template string
|
|
354
|
+
* @returns {Function} a function that returns the element
|
|
355
|
+
*/
|
|
356
|
+
declare function getRenderedElement(temp: string): () => Node | null;
|
|
357
|
+
/**
|
|
358
|
+
* Maps server-side rendered nodes during hydration
|
|
359
|
+
* @param {HTMLElement} templateEl - The root template element
|
|
360
|
+
* @param {number[]} idx - Array of indices to map
|
|
361
|
+
* @returns {Node[]} Array of mapped nodes
|
|
362
|
+
*/
|
|
363
|
+
declare function mapSSRNodes(templateEl: HTMLElement, idx: number[]): Node[];
|
|
364
|
+
/**
|
|
365
|
+
* Hydrate a server-rendered component
|
|
366
|
+
* @param {ComponentFn} component - Component function to hydrate
|
|
367
|
+
* @param {HTMLElement | string} container - Container element or selector
|
|
368
|
+
* @returns {any} Component instance or undefined if hydration fails
|
|
369
|
+
*/
|
|
370
|
+
declare function hydrate(component: ComponentFn, container: HTMLElement | string): any;
|
|
332
371
|
|
|
333
372
|
/**
|
|
334
373
|
* Start hydration mode
|
|
@@ -345,6 +384,15 @@ declare function endHydration(): void;
|
|
|
345
384
|
* @returns true if hydration is in progress
|
|
346
385
|
*/
|
|
347
386
|
declare function isHydrating(): boolean;
|
|
387
|
+
/**
|
|
388
|
+
* Get the hydration key
|
|
389
|
+
* @returns the hydration key string
|
|
390
|
+
*/
|
|
391
|
+
declare function getHydrationKey(): string;
|
|
392
|
+
/**
|
|
393
|
+
* Reset the hydration key counter
|
|
394
|
+
*/
|
|
395
|
+
declare function resetHydrationKey(): void;
|
|
348
396
|
|
|
349
397
|
/**
|
|
350
398
|
* Patches the class attribute of an element
|
|
@@ -420,23 +468,39 @@ interface FragmentProps extends ComponentProps {
|
|
|
420
468
|
children?: AnyNode | AnyNode[];
|
|
421
469
|
}
|
|
422
470
|
/**
|
|
423
|
-
* Fragment component - renders multiple children without wrapper elements
|
|
471
|
+
* Fragment component - renders multiple children without wrapper elements (Client-side only)
|
|
472
|
+
*
|
|
473
|
+
* **Client-side behavior:**
|
|
474
|
+
* - Returns children directly for rendering
|
|
475
|
+
* - Hydration system matches children using hydration keys
|
|
476
|
+
* - The template system handles array children automatically
|
|
424
477
|
*
|
|
425
478
|
* @param props - Component props with children
|
|
426
|
-
* @returns
|
|
479
|
+
* @returns Children directly without wrapper
|
|
427
480
|
*
|
|
428
481
|
* @example
|
|
429
482
|
* ```tsx
|
|
483
|
+
* // Basic usage
|
|
430
484
|
* <Fragment>
|
|
431
485
|
* <div>First</div>
|
|
432
486
|
* <span>Second</span>
|
|
433
487
|
* </Fragment>
|
|
488
|
+
*
|
|
489
|
+
* // Nested fragments
|
|
490
|
+
* <Fragment>
|
|
491
|
+
* <Fragment>
|
|
492
|
+
* <div>Nested 1</div>
|
|
493
|
+
* <div>Nested 2</div>
|
|
494
|
+
* </Fragment>
|
|
495
|
+
* <div>Third</div>
|
|
496
|
+
* </Fragment>
|
|
497
|
+
*
|
|
498
|
+
* // Empty fragment (renders nothing)
|
|
499
|
+
* <Fragment />
|
|
434
500
|
* ```
|
|
435
501
|
*/
|
|
436
502
|
declare function Fragment(props?: FragmentProps): AnyNode;
|
|
437
|
-
declare namespace Fragment {
|
|
438
|
-
var fragment: boolean;
|
|
439
|
-
}
|
|
503
|
+
declare namespace Fragment { }
|
|
440
504
|
/**
|
|
441
505
|
* Check if a node is a Fragment component
|
|
442
506
|
* @param node - Node to check
|
|
@@ -460,12 +524,9 @@ interface PortalProps {
|
|
|
460
524
|
* <Portal target="#modal-root">
|
|
461
525
|
* <div>Modal content</div>
|
|
462
526
|
* </Portal>
|
|
463
|
-
* ```
|
|
464
527
|
*/
|
|
465
528
|
declare function Portal(props: PortalProps): Comment | string;
|
|
466
|
-
declare namespace Portal {
|
|
467
|
-
var portal: boolean;
|
|
468
|
-
}
|
|
529
|
+
declare namespace Portal { }
|
|
469
530
|
/**
|
|
470
531
|
* Check if a node is a Portal component
|
|
471
532
|
* @param node - Node to check
|
|
@@ -495,9 +556,7 @@ interface SuspenseProps {
|
|
|
495
556
|
* ```
|
|
496
557
|
*/
|
|
497
558
|
declare function Suspense(props: SuspenseProps): AnyNode;
|
|
498
|
-
declare namespace Suspense {
|
|
499
|
-
var suspense: boolean;
|
|
500
|
-
}
|
|
559
|
+
declare namespace Suspense { }
|
|
501
560
|
/**
|
|
502
561
|
* Check if a node is a Suspense component
|
|
503
562
|
* @param node - Node to check
|
|
@@ -548,4 +607,19 @@ interface ResourceOptions<T> {
|
|
|
548
607
|
*/
|
|
549
608
|
declare function createResource<T>(fetcher: () => Promise<T>, options?: ResourceOptions<T>): [Resource<T>, ResourceActions<T>];
|
|
550
609
|
|
|
551
|
-
|
|
610
|
+
interface ForProps<T> {
|
|
611
|
+
each: T[] | Signal<T[]> | (() => T[]);
|
|
612
|
+
children: (item: T, index: number) => AnyNode;
|
|
613
|
+
keyFn?: (item: T) => unknown;
|
|
614
|
+
fallback?: () => AnyNode;
|
|
615
|
+
}
|
|
616
|
+
/**
|
|
617
|
+
* Optimized For Component
|
|
618
|
+
* - Uses createDetachedScope to avoid parent.children Set overhead (SolidJS style)
|
|
619
|
+
* - Uses DocumentFragment batching for mass creation
|
|
620
|
+
* - Inlines scope switching for performance
|
|
621
|
+
*/
|
|
622
|
+
declare function For<T>(props: ForProps<T>): Node;
|
|
623
|
+
declare namespace For { }
|
|
624
|
+
|
|
625
|
+
export { Component, type ComponentFn, type ComponentProps, For, type ForProps, Fragment, type FragmentProps, type InjectionKey, Portal, type PortalProps, type Scope, Suspense, type SuspenseProps, addEvent, addEventListener, bindElement, createApp, createComponent, createResource, createScope, delegateEvents, disposeScope, endHydration, getActiveScope, getFirstDOMNode, getHydrationKey, getRenderedElement, hydrate, inject, insert, insertNode, isComponent, isFragment, isHydrating, isPortal, isSameNode, isSuspense, mapNodes, mapSSRNodes, normalizeClass, normalizeNode, omitProps, onCleanup, onDestroy, onMount, onUpdate, patchAttr, patchClass, patchStyle, provide, removeNode, replaceNode, resetHydrationKey, runWithScope, setActiveScope, setStyle, shallowCompare, startHydration, template };
|