eleva 1.0.1 → 1.1.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 (97) hide show
  1. package/README.md +21 -10
  2. package/dist/{eleva-plugins.cjs.js → eleva-plugins.cjs} +1002 -292
  3. package/dist/eleva-plugins.cjs.map +1 -0
  4. package/dist/eleva-plugins.d.cts +1352 -0
  5. package/dist/eleva-plugins.d.cts.map +1 -0
  6. package/dist/eleva-plugins.d.ts +1352 -0
  7. package/dist/eleva-plugins.d.ts.map +1 -0
  8. package/dist/{eleva-plugins.esm.js → eleva-plugins.js} +1002 -292
  9. package/dist/eleva-plugins.js.map +1 -0
  10. package/dist/eleva-plugins.umd.js +1001 -291
  11. package/dist/eleva-plugins.umd.js.map +1 -1
  12. package/dist/eleva-plugins.umd.min.js +1 -1
  13. package/dist/eleva-plugins.umd.min.js.map +1 -1
  14. package/dist/{eleva.cjs.js → eleva.cjs} +421 -191
  15. package/dist/eleva.cjs.map +1 -0
  16. package/dist/eleva.d.cts +1329 -0
  17. package/dist/eleva.d.cts.map +1 -0
  18. package/dist/eleva.d.ts +473 -226
  19. package/dist/eleva.d.ts.map +1 -0
  20. package/dist/{eleva.esm.js → eleva.js} +422 -192
  21. package/dist/eleva.js.map +1 -0
  22. package/dist/eleva.umd.js +420 -190
  23. package/dist/eleva.umd.js.map +1 -1
  24. package/dist/eleva.umd.min.js +1 -1
  25. package/dist/eleva.umd.min.js.map +1 -1
  26. package/dist/plugins/attr.cjs +279 -0
  27. package/dist/plugins/attr.cjs.map +1 -0
  28. package/dist/plugins/attr.d.cts +101 -0
  29. package/dist/plugins/attr.d.cts.map +1 -0
  30. package/dist/plugins/attr.d.ts +101 -0
  31. package/dist/plugins/attr.d.ts.map +1 -0
  32. package/dist/plugins/attr.js +276 -0
  33. package/dist/plugins/attr.js.map +1 -0
  34. package/dist/plugins/attr.umd.js +111 -22
  35. package/dist/plugins/attr.umd.js.map +1 -1
  36. package/dist/plugins/attr.umd.min.js +1 -1
  37. package/dist/plugins/attr.umd.min.js.map +1 -1
  38. package/dist/plugins/router.cjs +1873 -0
  39. package/dist/plugins/router.cjs.map +1 -0
  40. package/dist/plugins/router.d.cts +1296 -0
  41. package/dist/plugins/router.d.cts.map +1 -0
  42. package/dist/plugins/router.d.ts +1296 -0
  43. package/dist/plugins/router.d.ts.map +1 -0
  44. package/dist/plugins/router.js +1870 -0
  45. package/dist/plugins/router.js.map +1 -0
  46. package/dist/plugins/router.umd.js +482 -186
  47. package/dist/plugins/router.umd.js.map +1 -1
  48. package/dist/plugins/router.umd.min.js +1 -1
  49. package/dist/plugins/router.umd.min.js.map +1 -1
  50. package/dist/plugins/store.cjs +920 -0
  51. package/dist/plugins/store.cjs.map +1 -0
  52. package/dist/plugins/store.d.cts +266 -0
  53. package/dist/plugins/store.d.cts.map +1 -0
  54. package/dist/plugins/store.d.ts +266 -0
  55. package/dist/plugins/store.d.ts.map +1 -0
  56. package/dist/plugins/store.js +917 -0
  57. package/dist/plugins/store.js.map +1 -0
  58. package/dist/plugins/store.umd.js +410 -85
  59. package/dist/plugins/store.umd.js.map +1 -1
  60. package/dist/plugins/store.umd.min.js +1 -1
  61. package/dist/plugins/store.umd.min.js.map +1 -1
  62. package/package.json +112 -68
  63. package/src/core/Eleva.js +195 -115
  64. package/src/index.cjs +10 -0
  65. package/src/index.js +11 -0
  66. package/src/modules/Emitter.js +68 -20
  67. package/src/modules/Renderer.js +82 -20
  68. package/src/modules/Signal.js +43 -15
  69. package/src/modules/TemplateEngine.js +50 -9
  70. package/src/plugins/Attr.js +121 -19
  71. package/src/plugins/Router.js +526 -181
  72. package/src/plugins/Store.js +448 -69
  73. package/src/plugins/index.js +1 -0
  74. package/types/core/Eleva.d.ts +263 -169
  75. package/types/core/Eleva.d.ts.map +1 -1
  76. package/types/index.d.cts +3 -0
  77. package/types/index.d.cts.map +1 -0
  78. package/types/index.d.ts +5 -0
  79. package/types/index.d.ts.map +1 -1
  80. package/types/modules/Emitter.d.ts +73 -30
  81. package/types/modules/Emitter.d.ts.map +1 -1
  82. package/types/modules/Renderer.d.ts +48 -18
  83. package/types/modules/Renderer.d.ts.map +1 -1
  84. package/types/modules/Signal.d.ts +44 -16
  85. package/types/modules/Signal.d.ts.map +1 -1
  86. package/types/modules/TemplateEngine.d.ts +46 -11
  87. package/types/modules/TemplateEngine.d.ts.map +1 -1
  88. package/types/plugins/Attr.d.ts +83 -16
  89. package/types/plugins/Attr.d.ts.map +1 -1
  90. package/types/plugins/Router.d.ts +498 -207
  91. package/types/plugins/Router.d.ts.map +1 -1
  92. package/types/plugins/Store.d.ts +211 -37
  93. package/types/plugins/Store.d.ts.map +1 -1
  94. package/dist/eleva-plugins.cjs.js.map +0 -1
  95. package/dist/eleva-plugins.esm.js.map +0 -1
  96. package/dist/eleva.cjs.js.map +0 -1
  97. package/dist/eleva.esm.js.map +0 -1
package/dist/eleva.d.ts CHANGED
@@ -1,22 +1,45 @@
1
1
  /**
2
- * @template T
2
+ * @module eleva/emitter
3
+ * @fileoverview Event emitter for publish-subscribe communication between components.
4
+ */
5
+ /**
6
+ * Callback function invoked when an event is emitted.
3
7
  * @callback EventHandler
4
- * @param {...T} args - Event arguments
5
- * @returns {void|Promise<void>}
8
+ * @param {...any} args
9
+ * Event arguments passed to the handler.
10
+ * @returns {void | Promise<void>}
6
11
  */
7
12
  /**
13
+ * Function to unsubscribe an event handler.
8
14
  * @callback EventUnsubscribe
9
15
  * @returns {void}
10
16
  */
11
17
  /**
12
- * @typedef {`${string}:${string}`} EventName
13
- * Event names follow the format 'namespace:action' (e.g., 'user:login', 'cart:update')
18
+ * Event name string identifier.
19
+ * @typedef {string} EventName
20
+ * @description
21
+ * Recommended convention: 'namespace:action' (e.g., 'user:login').
22
+ * This pattern prevents naming collisions and improves code readability.
23
+ *
24
+ * Common namespaces:
25
+ * - `user:` - User-related events (login, logout, update)
26
+ * - `component:` - Component lifecycle events (mount, unmount)
27
+ * - `router:` - Navigation events (beforeEach, afterEach)
28
+ * - `store:` - State management events (change, error)
29
+ * @example
30
+ * 'user:login' // User logged in
31
+ * 'cart:update' // Shopping cart updated
32
+ * 'component:mount' // Component was mounted
14
33
  */
15
34
  /**
35
+ * Interface describing the public API of an Emitter.
16
36
  * @typedef {Object} EmitterLike
17
- * @property {function(string, EventHandler<unknown>): EventUnsubscribe} on - Subscribe to an event
18
- * @property {function(string, EventHandler<unknown>=): void} off - Unsubscribe from an event
19
- * @property {function(string, ...unknown): void} emit - Emit an event
37
+ * @property {(event: string, handler: EventHandler) => EventUnsubscribe} on
38
+ * Subscribe to an event.
39
+ * @property {(event: string, handler?: EventHandler) => void} off
40
+ * Unsubscribe from an event.
41
+ * @property {(event: string, ...args: unknown[]) => void} emit
42
+ * Emit an event with arguments.
20
43
  */
21
44
  /**
22
45
  * @class 📡 Emitter
@@ -55,6 +78,7 @@
55
78
  * // Lifecycle events
56
79
  * emitter.on('component:mount', (component) => {});
57
80
  * emitter.on('component:unmount', (component) => {});
81
+ * // Note: These lifecycle names are conventions; Eleva core does not emit them by default.
58
82
  * // State events
59
83
  * emitter.on('state:change', (newState, oldState) => {});
60
84
  * // Navigation events
@@ -66,7 +90,7 @@ declare class Emitter implements EmitterLike {
66
90
  /**
67
91
  * Map of event names to their registered handler functions
68
92
  * @private
69
- * @type {Map<string, Set<EventHandler<unknown>>>}
93
+ * @type {Map<string, Set<EventHandler>>}
70
94
  */
71
95
  private _events;
72
96
  /**
@@ -75,9 +99,10 @@ declare class Emitter implements EmitterLike {
75
99
  * Event names should follow the format 'namespace:action' for consistency.
76
100
  *
77
101
  * @public
78
- * @template T
79
102
  * @param {string} event - The name of the event to listen for (e.g., 'user:login').
80
- * @param {EventHandler<T>} handler - The callback function to invoke when the event occurs.
103
+ * @param {EventHandler} handler - The callback function to invoke when the event occurs.
104
+ * Note: Handlers returning Promises are NOT awaited. For async operations,
105
+ * handle promise resolution within your handler.
81
106
  * @returns {EventUnsubscribe} A function to unsubscribe the event handler.
82
107
  *
83
108
  * @example
@@ -85,8 +110,8 @@ declare class Emitter implements EmitterLike {
85
110
  * const unsubscribe = emitter.on('user:login', (user) => console.log(user));
86
111
  *
87
112
  * @example
88
- * // Typed handler
89
- * emitter.on('user:update', (/** @type {{id: number, name: string}} *\/ user) => {
113
+ * // Handler with typed parameter
114
+ * emitter.on('user:update', (user) => {
90
115
  * console.log(`User ${user.id}: ${user.name}`);
91
116
  * });
92
117
  *
@@ -94,16 +119,18 @@ declare class Emitter implements EmitterLike {
94
119
  * // Cleanup
95
120
  * unsubscribe(); // Stops listening for the event
96
121
  */
97
- public on<T>(event: string, handler: EventHandler<T>): EventUnsubscribe;
122
+ public on(event: string, handler: EventHandler): EventUnsubscribe;
98
123
  /**
99
124
  * Removes an event handler for the specified event name.
100
- * If no handler is provided, all handlers for the event are removed.
101
125
  * Automatically cleans up empty event sets to prevent memory leaks.
102
126
  *
127
+ * Behavior varies based on whether handler is provided:
128
+ * - With handler: Removes only that specific handler function (O(1) Set deletion)
129
+ * - Without handler: Removes ALL handlers for the event (O(1) Map deletion)
130
+ *
103
131
  * @public
104
- * @template T
105
132
  * @param {string} event - The name of the event to remove handlers from.
106
- * @param {EventHandler<T>} [handler] - The specific handler function to remove.
133
+ * @param {EventHandler} [handler] - The specific handler to remove. If omitted, all handlers are removed.
107
134
  * @returns {void}
108
135
  *
109
136
  * @example
@@ -116,17 +143,24 @@ declare class Emitter implements EmitterLike {
116
143
  * // Remove all handlers for an event
117
144
  * emitter.off('user:login');
118
145
  */
119
- public off<T>(event: string, handler?: EventHandler<T>): void;
146
+ public off(event: string, handler?: EventHandler): void;
120
147
  /**
121
148
  * Emits an event with the specified data to all registered handlers.
122
149
  * Handlers are called synchronously in the order they were registered.
123
150
  * If no handlers are registered for the event, the emission is silently ignored.
151
+ * Handlers that return promises are not awaited.
152
+ *
153
+ * Error propagation behavior:
154
+ * - If a handler throws synchronously, the error propagates immediately
155
+ * - Remaining handlers in the iteration are NOT called after an error
156
+ * - For error-resilient emission, wrap your emit call in try/catch
157
+ * - Async handler rejections are not caught (fire-and-forget)
124
158
  *
125
159
  * @public
126
- * @template T
127
160
  * @param {string} event - The name of the event to emit.
128
- * @param {...T} args - Optional arguments to pass to the event handlers.
161
+ * @param {...any} args - Optional arguments to pass to the event handlers.
129
162
  * @returns {void}
163
+ * @throws {Error} If a handler throws synchronously, the error propagates to the caller.
130
164
  *
131
165
  * @example
132
166
  * // Emit an event with data
@@ -140,40 +174,61 @@ declare class Emitter implements EmitterLike {
140
174
  * // Emit without data
141
175
  * emitter.emit('app:ready');
142
176
  */
143
- public emit<T>(event: string, ...args: T[]): void;
177
+ public emit(event: string, ...args: any[]): void;
144
178
  }
145
- type EventHandler<T> = (...args: T[]) => void | Promise<void>;
179
+ /**
180
+ * Callback function invoked when an event is emitted.
181
+ */
182
+ type EventHandler = (...args: any[]) => void | Promise<void>;
183
+ /**
184
+ * Function to unsubscribe an event handler.
185
+ */
146
186
  type EventUnsubscribe = () => void;
187
+ /**
188
+ * Interface describing the public API of an Emitter.
189
+ */
147
190
  type EmitterLike = {
148
191
  /**
149
- * - Subscribe to an event
192
+ * Subscribe to an event.
150
193
  */
151
- on: (arg0: string, arg1: EventHandler<unknown>) => EventUnsubscribe;
194
+ on: (event: string, handler: EventHandler) => EventUnsubscribe;
152
195
  /**
153
- * - Unsubscribe from an event
196
+ * Unsubscribe from an event.
154
197
  */
155
- off: (arg0: string, arg1: EventHandler<unknown> | undefined) => void;
198
+ off: (event: string, handler?: EventHandler) => void;
156
199
  /**
157
- * - Emit an event
200
+ * Emit an event with arguments.
158
201
  */
159
- emit: (arg0: string, ...args: unknown[]) => void;
202
+ emit: (event: string, ...args: unknown[]) => void;
160
203
  };
161
204
 
162
205
  /**
163
- * @template T
206
+ * @module eleva/signal
207
+ * @fileoverview Reactive Signal primitive for fine-grained state management and change notification.
208
+ */
209
+ /**
210
+ * Callback function invoked when a signal's value changes.
211
+ * @template T The type of value held by the signal.
164
212
  * @callback SignalWatcher
165
- * @param {T} value - The new value of the signal
213
+ * @param {T} value
214
+ * The new value of the signal.
166
215
  * @returns {void}
167
216
  */
168
217
  /**
218
+ * Function to unsubscribe a watcher from a signal.
169
219
  * @callback SignalUnsubscribe
170
- * @returns {boolean} True if the watcher was successfully removed
220
+ * @returns {boolean}
221
+ * True if the watcher was successfully removed, false if already removed.
222
+ * Safe to call multiple times (idempotent).
171
223
  */
172
224
  /**
173
- * @template T
225
+ * Interface describing the public API of a Signal.
226
+ * @template T The type of value held by the signal.
174
227
  * @typedef {Object} SignalLike
175
- * @property {T} value - The current value
176
- * @property {function(SignalWatcher<T>): SignalUnsubscribe} watch - Subscribe to changes
228
+ * @property {T} value
229
+ * The current value of the signal.
230
+ * @property {function(SignalWatcher<T>): SignalUnsubscribe} watch
231
+ * Subscribe to value changes.
177
232
  */
178
233
  /**
179
234
  * @class ⚡ Signal
@@ -184,7 +239,7 @@ type EmitterLike = {
184
239
  * Render batching is handled at the component level, not the signal level.
185
240
  * The class is generic, allowing type-safe handling of any value type T.
186
241
  *
187
- * @template T The type of value held by this signal
242
+ * @template T The type of value held by the signal.
188
243
  *
189
244
  * @example
190
245
  * // Basic usage
@@ -202,7 +257,6 @@ type EmitterLike = {
202
257
  *
203
258
  * @example
204
259
  * // With objects
205
- * /** @type {Signal<{x: number, y: number}>} *\/
206
260
  * const position = new Signal({ x: 0, y: 0 });
207
261
  * position.value = { x: 10, y: 20 }; // Triggers watchers
208
262
  *
@@ -213,6 +267,7 @@ declare class Signal<T> implements SignalLike<T> {
213
267
  * Creates a new Signal instance with the specified initial value.
214
268
  *
215
269
  * @public
270
+ * @constructor
216
271
  * @param {T} value - The initial value of the signal.
217
272
  *
218
273
  * @example
@@ -222,12 +277,9 @@ declare class Signal<T> implements SignalLike<T> {
222
277
  * const active = new Signal(true); // Signal<boolean>
223
278
  *
224
279
  * @example
225
- * // Complex types (use JSDoc for type inference)
226
- * /** @type {Signal<string[]>} *\/
227
- * const items = new Signal([]);
228
- *
229
- * /** @type {Signal<{id: number, name: string} | null>} *\/
230
- * const user = new Signal(null);
280
+ * // Complex types
281
+ * const items = new Signal([]); // Signal holding an array
282
+ * const user = new Signal(null); // Signal holding nullable object
231
283
  */
232
284
  constructor(value: T);
233
285
  /**
@@ -246,6 +298,10 @@ declare class Signal<T> implements SignalLike<T> {
246
298
  * Sets a new value for the signal and synchronously notifies all registered watchers if the value has changed.
247
299
  * Synchronous notification preserves stack traces and ensures immediate value consistency.
248
300
  *
301
+ * Uses strict equality (===) for comparison. For objects/arrays, watchers are only notified
302
+ * if the reference changes, not if properties are mutated. To trigger updates with objects,
303
+ * assign a new reference: `signal.value = { ...signal.value, updated: true }`.
304
+ *
249
305
  * @public
250
306
  * @param {T} newVal - The new value to set.
251
307
  * @returns {void}
@@ -265,6 +321,8 @@ declare class Signal<T> implements SignalLike<T> {
265
321
  * @public
266
322
  * @param {SignalWatcher<T>} fn - The callback function to invoke on value change.
267
323
  * @returns {SignalUnsubscribe} A function to unsubscribe the watcher.
324
+ * Returns true if watcher was removed, false if it wasn't registered.
325
+ * Safe to call multiple times (idempotent after first call).
268
326
  *
269
327
  * @example
270
328
  * // Basic watching
@@ -273,6 +331,7 @@ declare class Signal<T> implements SignalLike<T> {
273
331
  * @example
274
332
  * // Stop watching
275
333
  * unsubscribe(); // Returns true if watcher was removed
334
+ * unsubscribe(); // Returns false (already removed, safe to call again)
276
335
  *
277
336
  * @example
278
337
  * // Multiple watchers
@@ -286,35 +345,59 @@ declare class Signal<T> implements SignalLike<T> {
286
345
  * This preserves stack traces for debugging and ensures immediate
287
346
  * value consistency. Render batching is handled at the component level.
288
347
  *
348
+ * @note If a watcher throws, subsequent watchers are NOT called.
349
+ * The error propagates to the caller (the setter).
350
+ *
289
351
  * @private
290
352
  * @returns {void}
291
353
  */
292
354
  private _notify;
293
355
  }
356
+ /**
357
+ * Callback function invoked when a signal's value changes.
358
+ */
294
359
  type SignalWatcher<T> = (value: T) => void;
360
+ /**
361
+ * Function to unsubscribe a watcher from a signal.
362
+ */
295
363
  type SignalUnsubscribe = () => boolean;
364
+ /**
365
+ * Interface describing the public API of a Signal.
366
+ */
296
367
  type SignalLike<T> = {
297
368
  /**
298
- * - The current value
369
+ * The current value of the signal.
299
370
  */
300
371
  value: T;
301
372
  /**
302
- * - Subscribe to changes
373
+ * Subscribe to value changes.
303
374
  */
304
375
  watch: (arg0: SignalWatcher<T>) => SignalUnsubscribe;
305
376
  };
306
377
 
307
378
  /**
379
+ * @module eleva/template-engine
380
+ * @fileoverview Expression evaluator for directive attributes and property bindings.
381
+ */
382
+ /**
383
+ * Data context object for expression evaluation.
308
384
  * @typedef {Record<string, unknown>} ContextData
309
- * Data context for expression evaluation
385
+ * @description Contains variables and functions available during template evaluation.
310
386
  */
311
387
  /**
388
+ * JavaScript expression string to be evaluated.
312
389
  * @typedef {string} Expression
313
- * A JavaScript expression to be evaluated in the data context
390
+ * @description A JavaScript expression evaluated against a ContextData object.
314
391
  */
315
392
  /**
393
+ * Result of evaluating an expression.
316
394
  * @typedef {unknown} EvaluationResult
317
- * The result of evaluating an expression (string, number, boolean, object, function, etc.)
395
+ * @description Can be string, number, boolean, object, function, or any JavaScript value.
396
+ */
397
+ /**
398
+ * Compiled expression function cached for performance.
399
+ * @typedef {(data: ContextData) => EvaluationResult} CompiledExpressionFunction
400
+ * @description Pre-compiled function that evaluates an expression against context data.
318
401
  */
319
402
  /**
320
403
  * @class 🔒 TemplateEngine
@@ -348,25 +431,44 @@ declare class TemplateEngine {
348
431
  /**
349
432
  * Cache for compiled expression functions.
350
433
  * Stores compiled Function objects keyed by expression string for O(1) lookup.
434
+ * The cache persists for the application lifetime and is never cleared.
435
+ * This improves performance for repeated evaluations of the same expression.
436
+ *
437
+ * Memory consideration: For applications with highly dynamic expressions
438
+ * (e.g., user-generated), memory usage grows unbounded. This is typically
439
+ * not an issue for static templates where expressions are finite.
351
440
  *
352
441
  * @static
353
442
  * @private
354
- * @type {Map<string, Function>}
443
+ * @type {Map<string, CompiledExpressionFunction>}
355
444
  */
356
445
  private static _functionCache;
357
446
  /**
358
447
  * Evaluates an expression in the context of the provided data object.
359
448
  * Used for resolving `@event` handlers and `:prop` bindings.
449
+ * Non-string expressions are returned as-is.
450
+ *
451
+ * @security CRITICAL SECURITY WARNING
452
+ * This method is NOT sandboxed. It uses `new Function()` and `with` statement,
453
+ * allowing full access to the global scope. Potential attack vectors include:
454
+ * - Code injection via malicious expressions
455
+ * - XSS attacks if user input is used as expressions
456
+ * - Access to sensitive globals (window, document, fetch, etc.)
360
457
  *
361
- * Note: This does not provide a true sandbox and evaluated expressions may access global scope.
362
- * The use of the `with` statement is necessary for expression evaluation but has security implications.
363
- * Only use with trusted templates. User input should never be directly interpolated.
458
+ * ONLY use with developer-defined template strings.
459
+ * NEVER use with user-provided input or untrusted data.
460
+ *
461
+ * Mitigation strategies:
462
+ * - Always sanitize any user-generated content before rendering in templates
463
+ * - Use Content Security Policy (CSP) headers to restrict script execution
464
+ * - Keep expressions simple (property access, method calls) - avoid complex logic
364
465
  *
365
466
  * @public
366
467
  * @static
367
- * @param {Expression|unknown} expression - The expression to evaluate.
468
+ * @param {Expression | unknown} expression - The expression to evaluate.
368
469
  * @param {ContextData} data - The data context for evaluation.
369
470
  * @returns {EvaluationResult} The result of the evaluation, or empty string if evaluation fails.
471
+ * @note Evaluation failures return an empty string without throwing.
370
472
  *
371
473
  * @example
372
474
  * // Property access
@@ -401,15 +503,15 @@ declare class TemplateEngine {
401
503
  public static evaluate(expression: Expression | unknown, data: ContextData): EvaluationResult;
402
504
  }
403
505
  /**
404
- * Data context for expression evaluation
506
+ * Data context object for expression evaluation.
405
507
  */
406
508
  type ContextData = Record<string, unknown>;
407
509
  /**
408
- * A JavaScript expression to be evaluated in the data context
510
+ * JavaScript expression string to be evaluated.
409
511
  */
410
512
  type Expression = string;
411
513
  /**
412
- * The result of evaluating an expression (string, number, boolean, object, function, etc.)
514
+ * Result of evaluating an expression.
413
515
  */
414
516
  type EvaluationResult = unknown;
415
517
 
@@ -474,27 +576,41 @@ declare class Renderer implements RendererLike {
474
576
  * @example
475
577
  * // Empty the container
476
578
  * renderer.patchDOM(container, '');
579
+ *
580
+ * @see _diff - Low-level diffing algorithm.
581
+ * @see _patchNode - Individual node patching.
477
582
  */
478
583
  public patchDOM(container: HTMLElement, newHtml: string): void;
479
584
  /**
480
585
  * Performs a diff between two DOM nodes and patches the old node to match the new node.
481
586
  * Uses a two-pointer algorithm with key-based reconciliation for optimal performance.
587
+ * This method modifies oldParent in-place - it is not a pure function.
588
+ *
589
+ * Algorithm details:
590
+ * 1. Early exit if both nodes have no children (O(1) leaf node optimization)
591
+ * 2. Convert NodeLists to arrays for indexed access
592
+ * 3. Initialize two-pointer indices (oldStart/oldEnd, newStart/newEnd)
593
+ * 4. While pointers haven't crossed:
594
+ * a. Skip null entries (from previous moves)
595
+ * b. If nodes match (same key+tag or same type+name): patch and advance
596
+ * c. On mismatch: lazily build key→node map for O(1) lookup
597
+ * d. If keyed match found: move existing node (preserves DOM identity)
598
+ * e. Otherwise: clone and insert new node
599
+ * 5. After loop: append remaining new nodes or remove remaining old nodes
482
600
  *
483
- * Algorithm overview:
484
- * 1. Compare children from start using two pointers
485
- * 2. For mismatches, build a key map lazily for O(1) lookup
486
- * 3. Move or insert nodes as needed
487
- * 4. Clean up remaining nodes at the end
601
+ * Complexity: O(n) for most cases, O(n²) worst case with no keys.
602
+ * Non-keyed elements are matched by position and tag name.
488
603
  *
489
604
  * @private
490
- * @param {HTMLElement} oldParent - The original DOM element to update.
491
- * @param {HTMLElement} newParent - The new DOM element with desired state.
605
+ * @param {Element} oldParent - The original DOM element to update (modified in-place).
606
+ * @param {Element} newParent - The new DOM element with desired state.
492
607
  * @returns {void}
493
608
  */
494
609
  private _diff;
495
610
  /**
496
611
  * Patches a single node, updating its content and attributes to match the new node.
497
- * Handles text nodes by updating nodeValue, and element nodes by updating attributes
612
+ * Handles text nodes (nodeType 3 / Node.TEXT_NODE) by updating nodeValue,
613
+ * and element nodes (nodeType 1 / Node.ELEMENT_NODE) by updating attributes
498
614
  * and recursively diffing children.
499
615
  *
500
616
  * Skips nodes that are managed by Eleva component instances to prevent interference
@@ -509,12 +625,20 @@ declare class Renderer implements RendererLike {
509
625
  /**
510
626
  * Removes a node from its parent, with special handling for Eleva-managed elements.
511
627
  * Style elements with the `data-e-style` attribute are preserved to maintain
512
- * component-scoped styles across re-renders.
628
+ * component styles across re-renders. Without this protection, component styles
629
+ * would be removed during DOM diffing and lost until the next full re-render.
630
+ *
631
+ * @note Style tags persist for the component's entire lifecycle. If the template
632
+ * conditionally removes elements that the CSS rules target (e.g., `.foo` elements),
633
+ * the style rules remain but simply have no matching elements. This is expected
634
+ * behavior - styles are cleaned up when the component unmounts, not when individual
635
+ * elements are removed.
513
636
  *
514
637
  * @private
515
638
  * @param {HTMLElement} parent - The parent element containing the node.
516
639
  * @param {Node} node - The node to remove.
517
640
  * @returns {void}
641
+ * @see _injectStyles - Where data-e-style elements are created.
518
642
  */
519
643
  private _removeNode;
520
644
  /**
@@ -522,12 +646,16 @@ declare class Renderer implements RendererLike {
522
646
  * Adds new attributes, updates changed values, and removes attributes no longer present.
523
647
  * Also syncs DOM properties that can diverge from attributes after user interaction.
524
648
  *
525
- * Event attributes (prefixed with `@`) are skipped as they are handled separately
526
- * by Eleva's event binding system.
649
+ * Processing order:
650
+ * 1. Iterate new attributes, skip @ prefixed (event) attributes
651
+ * 2. Update attribute if value changed
652
+ * 3. Sync corresponding DOM property if writable (handles boolean conversion)
653
+ * 4. Iterate old attributes in reverse, remove if not in new element
654
+ * 5. Sync SYNC_PROPS (value, checked, selected) from new to old element
527
655
  *
528
656
  * @private
529
- * @param {HTMLElement} oldEl - The original element to update.
530
- * @param {HTMLElement} newEl - The new element with target attributes.
657
+ * @param {Element} oldEl - The original element to update.
658
+ * @param {Element} newEl - The new element with target attributes.
531
659
  * @returns {void}
532
660
  */
533
661
  private _updateAttributes;
@@ -550,10 +678,11 @@ declare class Renderer implements RendererLike {
550
678
  /**
551
679
  * Extracts the key attribute from a node if it exists.
552
680
  * Only element nodes (nodeType === 1) can have key attributes.
681
+ * Uses optional chaining for null-safe access.
553
682
  *
554
683
  * @private
555
- * @param {Node|null|undefined} node - The node to extract the key from.
556
- * @returns {string|null} The key attribute value, or null if not an element or no key.
684
+ * @param {Node | null | undefined} node - The node to extract the key from.
685
+ * @returns {string | null} The key attribute value, or null if not an element or no key.
557
686
  */
558
687
  private _getNodeKey;
559
688
  /**
@@ -561,184 +690,214 @@ declare class Renderer implements RendererLike {
561
690
  * The map is built lazily only when needed (when a mismatch occurs during diffing).
562
691
  *
563
692
  * @private
564
- * @param {Array<ChildNode>} children - The array of child nodes to map.
693
+ * @param {ChildNode[]} children - The array of child nodes to map.
565
694
  * @param {number} start - The start index (inclusive) for mapping.
566
695
  * @param {number} end - The end index (inclusive) for mapping.
567
696
  * @returns {KeyMap} A Map of key strings to their corresponding DOM nodes.
568
697
  */
569
698
  private _createKeyMap;
570
699
  }
700
+ /**
701
+ * Interface describing the public API of a Renderer.
702
+ */
571
703
  type RendererLike = {
572
704
  /**
573
- * - Patches the DOM with new HTML
705
+ * Patches the DOM with new HTML content.
574
706
  */
575
707
  patchDOM: (arg0: HTMLElement, arg1: string) => void;
576
708
  };
577
709
 
578
710
  /**
579
- * @typedef {Object} ElevaConfig
580
- * @property {boolean} [debug=false]
581
- * Enable debug mode for verbose logging
582
- * @property {string} [prefix='e']
583
- * Prefix for component style scoping
584
- * @property {boolean} [async=true]
585
- * Enable async component setup
711
+ * Configuration options for the Eleva instance (reserved for future use).
712
+ * @typedef {Record<string, unknown>} ElevaConfig
586
713
  */
587
714
  /**
715
+ * Component definition object.
588
716
  * @typedef {Object} ComponentDefinition
589
717
  * @property {SetupFunction} [setup]
590
- * Optional setup function that initializes the component's state and returns reactive data
591
- * @property {TemplateFunction|string} template
592
- * Required function or string that defines the component's HTML structure
593
- * @property {StyleFunction|string} [style]
594
- * Optional function or string that provides component-scoped CSS styles
718
+ * Optional setup function that initializes the component's state and returns reactive data.
719
+ * @property {TemplateFunction | string} template
720
+ * Required function or string that defines the component's HTML structure.
721
+ * @property {StyleFunction | string} [style]
722
+ * Optional function or string that provides CSS styles for the component.
723
+ * Styles are preserved across DOM diffs via data-e-style markers.
595
724
  * @property {ChildrenMap} [children]
596
- * Optional object defining nested child components
725
+ * Optional object defining nested child components.
597
726
  */
598
727
  /**
728
+ * Setup function that initializes component state.
599
729
  * @callback SetupFunction
600
- * @param {ComponentContext} ctx - The component context with props, emitter, and signal factory
601
- * @returns {SetupResult|Promise<SetupResult>} Reactive data and lifecycle hooks
730
+ * @param {ComponentContext} ctx
731
+ * The component context with props, emitter, and signal factory.
732
+ * @returns {SetupResult | Promise<SetupResult>}
733
+ * Reactive data and lifecycle hooks.
602
734
  */
603
735
  /**
736
+ * Data returned from setup function, may include lifecycle hooks.
604
737
  * @typedef {Record<string, unknown> & LifecycleHooks} SetupResult
605
- * Data returned from setup function, may include lifecycle hooks
606
738
  */
607
739
  /**
740
+ * Template function that returns HTML markup.
608
741
  * @callback TemplateFunction
609
- * @param {ComponentContext} ctx - The component context
610
- * @returns {string|Promise<string>} HTML template string
742
+ * @param {ComponentContext & SetupResult} ctx
743
+ * The merged component context and setup data.
744
+ * @returns {string | Promise<string>}
745
+ * HTML template string.
611
746
  */
612
747
  /**
748
+ * Style function that returns CSS styles.
613
749
  * @callback StyleFunction
614
- * @param {ComponentContext} ctx - The component context
615
- * @returns {string} CSS styles string
750
+ * @param {ComponentContext & SetupResult} ctx
751
+ * The merged component context and setup data.
752
+ * @returns {string}
753
+ * CSS styles string.
616
754
  */
617
755
  /**
618
- * @typedef {Record<string, ComponentDefinition|string>} ChildrenMap
619
- * Map of CSS selectors to component definitions or registered component names
756
+ * Map of CSS selectors to component definitions or registered component names.
757
+ * @typedef {Record<string, ComponentDefinition | string>} ChildrenMap
620
758
  */
621
759
  /**
760
+ * Context passed to component setup function.
622
761
  * @typedef {Object} ComponentContext
623
762
  * @property {ComponentProps} props
624
- * Component properties passed during mounting
763
+ * Component properties passed during mounting.
625
764
  * @property {Emitter} emitter
626
- * Event emitter instance for component event handling
765
+ * Event emitter instance for component event handling.
627
766
  * @property {SignalFactory} signal
628
- * Factory function to create reactive Signal instances
767
+ * Factory function to create reactive Signal instances.
768
+ * @description
769
+ * Plugins may extend this context with additional properties (e.g., `ctx.router`, `ctx.store`).
770
+ * @see RouterContext - Router plugin injected context.
771
+ * @see StoreApi - Store plugin injected context.
629
772
  */
630
773
  /**
774
+ * Properties passed to a component during mounting.
631
775
  * @typedef {Record<string, unknown>} ComponentProps
632
- * Properties passed to a component during mounting
633
776
  */
634
777
  /**
635
- * @callback SignalFactory
636
- * @template T
637
- * @param {T} initialValue - The initial value for the signal
638
- * @returns {Signal<T>} A new Signal instance
778
+ * Factory function to create reactive Signal instances.
779
+ * @typedef {<T>(initialValue: T) => Signal<T>} SignalFactory
639
780
  */
640
781
  /**
782
+ * Lifecycle hooks that can be returned from setup function.
641
783
  * @typedef {Object} LifecycleHooks
642
784
  * @property {LifecycleHook} [onBeforeMount]
643
- * Hook called before component mounting
785
+ * Called before component mounting.
644
786
  * @property {LifecycleHook} [onMount]
645
- * Hook called after component mounting
787
+ * Called after component mounting.
646
788
  * @property {LifecycleHook} [onBeforeUpdate]
647
- * Hook called before component update
789
+ * Called before component update.
648
790
  * @property {LifecycleHook} [onUpdate]
649
- * Hook called after component update
791
+ * Called after component update.
650
792
  * @property {UnmountHook} [onUnmount]
651
- * Hook called during component unmounting
793
+ * Called during component unmounting.
652
794
  */
653
795
  /**
796
+ * Lifecycle hook function.
654
797
  * @callback LifecycleHook
655
- * @param {LifecycleHookContext} ctx - Context with container and component data
656
- * @returns {void|Promise<void>}
798
+ * @param {LifecycleHookContext} ctx
799
+ * Context with container and component data.
800
+ * @returns {void | Promise<void>}
657
801
  */
658
802
  /**
803
+ * Unmount hook function with cleanup resources.
659
804
  * @callback UnmountHook
660
- * @param {UnmountHookContext} ctx - Context with cleanup resources
661
- * @returns {void|Promise<void>}
805
+ * @param {UnmountHookContext} ctx
806
+ * Context with cleanup resources.
807
+ * @returns {void | Promise<void>}
662
808
  */
663
809
  /**
810
+ * Context passed to lifecycle hooks.
664
811
  * @typedef {Object} LifecycleHookContext
665
812
  * @property {HTMLElement} container
666
- * The DOM element where the component is mounted
813
+ * The DOM element where the component is mounted.
667
814
  * @property {ComponentContext & SetupResult} context
668
- * The component's reactive state and context data
815
+ * The component's reactive state and context data.
669
816
  */
670
817
  /**
818
+ * Context passed to unmount hook with cleanup resources.
671
819
  * @typedef {Object} UnmountHookContext
672
820
  * @property {HTMLElement} container
673
- * The DOM element where the component is mounted
821
+ * The DOM element where the component is mounted.
674
822
  * @property {ComponentContext & SetupResult} context
675
- * The component's reactive state and context data
823
+ * The component's reactive state and context data.
676
824
  * @property {CleanupResources} cleanup
677
- * Object containing cleanup functions and instances
825
+ * Object containing cleanup functions and instances.
678
826
  */
679
827
  /**
828
+ * Resources available for cleanup during unmount.
680
829
  * @typedef {Object} CleanupResources
681
- * @property {Array<UnsubscribeFunction>} watchers
682
- * Signal watcher cleanup functions
683
- * @property {Array<UnsubscribeFunction>} listeners
684
- * Event listener cleanup functions
685
- * @property {Array<MountResult>} children
686
- * Child component instances
830
+ * @property {UnsubscribeFunction[]} watchers
831
+ * Signal watcher cleanup functions.
832
+ * @property {UnsubscribeFunction[]} listeners
833
+ * Event listener cleanup functions.
834
+ * @property {MountResult[]} children
835
+ * Child component instances.
687
836
  */
688
837
  /**
838
+ * Result of mounting a component.
689
839
  * @typedef {Object} MountResult
690
840
  * @property {HTMLElement} container
691
- * The DOM element where the component is mounted
841
+ * The DOM element where the component is mounted.
692
842
  * @property {ComponentContext & SetupResult} data
693
- * The component's reactive state and context data
843
+ * The component's reactive state and context data.
694
844
  * @property {UnmountFunction} unmount
695
- * Function to clean up and unmount the component
845
+ * Function to clean up and unmount the component.
696
846
  */
697
847
  /**
848
+ * Function to unmount a component and clean up resources.
698
849
  * @callback UnmountFunction
699
850
  * @returns {Promise<void>}
700
851
  */
701
852
  /**
853
+ * Function to unsubscribe from events or watchers.
702
854
  * @callback UnsubscribeFunction
703
- * @returns {void|boolean}
855
+ * @returns {void | boolean}
704
856
  */
705
857
  /**
858
+ * Plugin interface for extending Eleva.
706
859
  * @typedef {Object} ElevaPlugin
707
- * @property {PluginInstallFunction} install
708
- * Function that installs the plugin into the Eleva instance
709
860
  * @property {string} name
710
- * Unique identifier name for the plugin
861
+ * Unique identifier name for the plugin.
862
+ * @property {string} [version]
863
+ * Optional version string for the plugin.
864
+ * @property {PluginInstallFunction} install
865
+ * Function that installs the plugin.
711
866
  * @property {PluginUninstallFunction} [uninstall]
712
- * Optional function to uninstall the plugin
867
+ * Optional function to uninstall the plugin.
713
868
  */
714
869
  /**
870
+ * Plugin install function.
715
871
  * @callback PluginInstallFunction
716
- * @param {Eleva} eleva - The Eleva instance
717
- * @param {PluginOptions} options - Plugin configuration options
718
- * @returns {void|Eleva|unknown} Optionally returns the Eleva instance or plugin result
872
+ * @param {Eleva} eleva
873
+ * The Eleva instance.
874
+ * @param {PluginOptions} [options]
875
+ * Plugin configuration options.
876
+ * @returns {void | Eleva | unknown}
719
877
  */
720
878
  /**
879
+ * Plugin uninstall function.
721
880
  * @callback PluginUninstallFunction
722
- * @param {Eleva} eleva - The Eleva instance
723
- * @returns {void}
881
+ * @param {Eleva} eleva
882
+ * The Eleva instance.
883
+ * @returns {void | Promise<void>}
724
884
  */
725
885
  /**
886
+ * Configuration options passed to a plugin during installation.
726
887
  * @typedef {Record<string, unknown>} PluginOptions
727
- * Configuration options passed to a plugin during installation
728
888
  */
729
889
  /**
730
- * @callback EventHandler
731
- * @param {Event} event - The DOM event object
732
- * @returns {void}
890
+ * Handler function for DOM events (e.g., click, input, submit).
891
+ * @typedef {(event: Event) => void} DOMEventHandler
733
892
  */
734
893
  /**
894
+ * Common DOM event names (prefixed with @ in templates).
735
895
  * @typedef {'click'|'submit'|'input'|'change'|'focus'|'blur'|'keydown'|'keyup'|'keypress'|'mouseenter'|'mouseleave'|'mouseover'|'mouseout'|'mousedown'|'mouseup'|'touchstart'|'touchend'|'touchmove'|'scroll'|'resize'|'load'|'error'|string} DOMEventName
736
- * Common DOM event names (prefixed with @ in templates)
737
896
  */
738
897
  /**
739
898
  * @class 🧩 Eleva
740
899
  * @classdesc A modern, signal-based component runtime framework that provides lifecycle hooks,
741
- * scoped styles, and plugin support. Eleva manages component registration, plugin integration,
900
+ * component styles, and plugin support. Eleva manages component registration, plugin integration,
742
901
  * event handling, and DOM rendering with a focus on performance and developer experience.
743
902
  *
744
903
  * @example
@@ -768,11 +927,10 @@ declare class Eleva {
768
927
  * Creates a new Eleva instance with the specified name and configuration.
769
928
  *
770
929
  * @public
930
+ * @constructor
771
931
  * @param {string} name - The unique identifier name for this Eleva instance.
772
- * @param {Record<string, unknown>} [config={}] - Optional configuration object for the instance.
773
- * May include framework-wide settings and default behaviors.
932
+ * @param {ElevaConfig} [config={}] - Optional configuration object for the instance.
774
933
  * @throws {Error} If the name is not provided or is not a string.
775
- * @returns {Eleva} A new Eleva instance.
776
934
  *
777
935
  * @example
778
936
  * const app = new Eleva("myApp");
@@ -783,19 +941,19 @@ declare class Eleva {
783
941
  * app.mount(document.getElementById("app"), "myComponent", { name: "World" });
784
942
  *
785
943
  */
786
- constructor(name: string, config?: Record<string, unknown>);
787
- /** @public {string} The unique identifier name for this Eleva instance */
788
- public name: string;
789
- /** @public {Object<string, unknown>} Optional configuration object for the Eleva instance */
790
- public config: Record<string, unknown>;
791
- /** @public {Emitter} Instance of the event emitter for handling component events */
792
- public emitter: Emitter;
793
- /** @public {typeof Signal} Static reference to the Signal class for creating reactive state */
794
- public signal: typeof Signal;
795
- /** @public {typeof TemplateEngine} Static reference to the TemplateEngine class for template parsing */
796
- public templateEngine: typeof TemplateEngine;
797
- /** @public {Renderer} Instance of the renderer for handling DOM updates and patching */
798
- public renderer: Renderer;
944
+ constructor(name: string, config?: ElevaConfig);
945
+ /** @public @readonly {string} The unique identifier name for this Eleva instance */
946
+ public readonly name: string;
947
+ /** @public @readonly {Record<string, unknown>} Configuration object for the Eleva instance */
948
+ public readonly config: ElevaConfig;
949
+ /** @public @readonly {Emitter} Event emitter for handling component events */
950
+ public readonly emitter: Emitter;
951
+ /** @public @readonly {typeof Signal} Signal class for creating reactive state */
952
+ public readonly signal: typeof Signal;
953
+ /** @public @readonly {typeof TemplateEngine} TemplateEngine class for template parsing */
954
+ public readonly templateEngine: typeof TemplateEngine;
955
+ /** @public @readonly {Renderer} Renderer for handling DOM updates and patching */
956
+ public readonly renderer: Renderer;
799
957
  /** @private {Map<string, ComponentDefinition>} Registry of all component definitions by name */
800
958
  private _components;
801
959
  /** @private {Map<string, ElevaPlugin>} Collection of installed plugin instances by name */
@@ -807,14 +965,16 @@ declare class Eleva {
807
965
  * The plugin's install function will be called with the Eleva instance and provided options.
808
966
  * After installation, the plugin will be available for use by components.
809
967
  *
810
- * Note: Plugins that wrap core methods (e.g., mount) must be uninstalled in reverse order
968
+ * @note Plugins that wrap core methods (e.g., mount) must be uninstalled in reverse order
811
969
  * of installation (LIFO - Last In, First Out) to avoid conflicts.
812
970
  *
813
971
  * @public
814
972
  * @param {ElevaPlugin} plugin - The plugin object which must have an `install` function.
815
- * @param {Object<string, unknown>} [options={}] - Optional configuration options for the plugin.
816
- * @returns {Eleva} The Eleva instance (for method chaining).
973
+ * @param {PluginOptions} [options={}] - Optional configuration options for the plugin.
974
+ * @returns {Eleva | unknown} The Eleva instance (for method chaining) or the result returned by the plugin.
817
975
  * @throws {Error} If plugin does not have an install function.
976
+ * @see component - Register components after installing plugins.
977
+ * @see mount - Mount components to the DOM.
818
978
  * @example
819
979
  * app.use(myPlugin, { option1: "value1" });
820
980
  *
@@ -826,9 +986,7 @@ declare class Eleva {
826
986
  * PluginB.uninstall(app);
827
987
  * PluginA.uninstall(app);
828
988
  */
829
- public use(plugin: ElevaPlugin, options?: {
830
- [x: string]: unknown;
831
- }): Eleva;
989
+ public use(plugin: ElevaPlugin, options?: PluginOptions): Eleva | unknown;
832
990
  /**
833
991
  * Registers a new component with the Eleva instance.
834
992
  * The component will be available for mounting using its registered name.
@@ -838,6 +996,7 @@ declare class Eleva {
838
996
  * @param {ComponentDefinition} definition - The component definition including setup, template, style, and children.
839
997
  * @returns {Eleva} The Eleva instance (for method chaining).
840
998
  * @throws {Error} If name is not a non-empty string or definition has no template.
999
+ * @see mount - Mount this component to the DOM.
841
1000
  * @example
842
1001
  * app.component("myButton", {
843
1002
  * template: (ctx) => `<button>${ctx.props.text}</button>`,
@@ -848,45 +1007,57 @@ declare class Eleva {
848
1007
  /**
849
1008
  * Mounts a registered component to a DOM element.
850
1009
  * This will initialize the component, set up its reactive state, and render it to the DOM.
1010
+ * If the container already has a mounted Eleva instance, it is returned as-is.
1011
+ * Unmount clears the container contents and removes the internal instance marker.
851
1012
  *
852
1013
  * @public
1014
+ * @async
853
1015
  * @param {HTMLElement} container - The DOM element where the component will be mounted.
854
- * @param {string|ComponentDefinition} compName - The name of the registered component or a direct component definition.
855
- * @param {Object<string, unknown>} [props={}] - Optional properties to pass to the component.
1016
+ * @param {string | ComponentDefinition} compName - The name of the registered component or a direct component definition.
1017
+ * @param {ComponentProps} [props={}] - Optional properties to pass to the component.
856
1018
  * @returns {Promise<MountResult>}
857
1019
  * A Promise that resolves to an object containing:
858
1020
  * - container: The mounted component's container element
859
1021
  * - data: The component's reactive state and context
860
1022
  * - unmount: Function to clean up and unmount the component
861
1023
  * @throws {Error} If container is not a DOM element or component is not registered.
1024
+ * @throws {Error} If setup function, template function, or style function throws.
862
1025
  * @example
863
1026
  * const instance = await app.mount(document.getElementById("app"), "myComponent", { text: "Click me" });
864
1027
  * // Later...
865
- * instance.unmount();
1028
+ * await instance.unmount();
866
1029
  */
867
- public mount(container: HTMLElement, compName: string | ComponentDefinition, props?: {
868
- [x: string]: unknown;
869
- }): Promise<MountResult>;
1030
+ public mount(container: HTMLElement, compName: string | ComponentDefinition, props?: ComponentProps): Promise<MountResult>;
870
1031
  /**
871
1032
  * Processes DOM elements for event binding based on attributes starting with "@".
872
- * This method handles the event delegation system and ensures proper cleanup of event listeners.
1033
+ * This method attaches event listeners directly to elements and ensures proper cleanup.
1034
+ * Bound `@event` attributes are removed after listeners are attached.
1035
+ *
1036
+ * Handler resolution order:
1037
+ * 1. Direct context property lookup (e.g., context["handleClick"])
1038
+ * 2. Template expression evaluation via TemplateEngine (e.g., "increment()")
873
1039
  *
874
1040
  * @private
875
1041
  * @param {HTMLElement} container - The container element in which to search for event attributes.
876
- * @param {ComponentContext} context - The current component context containing event handler definitions.
877
- * @param {Array<() => void>} listeners - Array to collect cleanup functions for each event listener.
1042
+ * @param {ComponentContext & SetupResult} context - The merged component context and setup data.
1043
+ * @param {UnsubscribeFunction[]} listeners - Array to collect cleanup functions for each event listener.
878
1044
  * @returns {void}
1045
+ * @see TemplateEngine.evaluate - Expression evaluation. fallback.
879
1046
  */
880
1047
  private _processEvents;
881
1048
  /**
882
- * Injects scoped styles into the component's container.
883
- * The styles are automatically prefixed to prevent style leakage to other components.
1049
+ * Injects styles into the component's container.
1050
+ * Styles are placed in a `<style>` element with a `data-e-style` attribute for identification.
1051
+ *
1052
+ * @note Styles are not automatically scoped - use unique class names or CSS nesting for isolation.
1053
+ *
1054
+ * Optimization: Skips DOM update if style content hasn't changed.
884
1055
  *
885
1056
  * @private
886
1057
  * @param {HTMLElement} container - The container element where styles should be injected.
887
1058
  * @param {string} compId - The component ID used to identify the style element.
888
- * @param {(function(ComponentContext): string)|string} styleDef - The component's style definition (function or string).
889
- * @param {ComponentContext} context - The current component context for style interpolation.
1059
+ * @param {StyleFunction | string} styleDef - The component's style definition (function or string).
1060
+ * @param {ComponentContext & SetupResult} context - The merged component context and setup data.
890
1061
  * @returns {void}
891
1062
  */
892
1063
  private _injectStyles;
@@ -894,11 +1065,13 @@ declare class Eleva {
894
1065
  * Extracts and evaluates props from an element's attributes that start with `:`.
895
1066
  * Prop values are evaluated as expressions against the component context,
896
1067
  * allowing direct passing of objects, arrays, and other complex types.
1068
+ * Processed attributes are removed from the element after extraction.
897
1069
  *
898
1070
  * @private
899
- * @param {HTMLElement} element - The DOM element to extract props from
900
- * @param {ComponentContext} context - The component context for evaluating prop expressions
901
- * @returns {Record<string, string>} An object containing the evaluated props
1071
+ * @param {HTMLElement} element - The DOM element to extract props from.
1072
+ * @param {ComponentContext & SetupResult} context - The merged component context and setup data.
1073
+ * @returns {ComponentProps} An object containing the evaluated props.
1074
+ * @see TemplateEngine.evaluate - Expression evaluation.
902
1075
  * @example
903
1076
  * // For an element with attributes:
904
1077
  * // <div :name="user.name" :data="items">
@@ -911,172 +1084,246 @@ declare class Eleva {
911
1084
  * This method handles mounting of explicitly defined children components.
912
1085
  *
913
1086
  * The mounting process follows these steps:
914
- * 1. Cleans up any existing component instances
1087
+ * 1. Finds matching DOM nodes within the container
915
1088
  * 2. Mounts explicitly defined children components
916
1089
  *
917
1090
  * @private
918
- * @param {HTMLElement} container - The container element to mount components in
919
- * @param {Object<string, ComponentDefinition>} children - Map of selectors to component definitions for explicit children
920
- * @param {Array<MountResult>} childInstances - Array to store all mounted component instances
921
- * @param {ComponentContext} context - The parent component context for evaluating prop expressions
1091
+ * @async
1092
+ * @param {HTMLElement} container - The container element to mount components in.
1093
+ * @param {ChildrenMap} children - Map of selectors to component definitions for explicit children.
1094
+ * @param {MountResult[]} childInstances - Array to store all mounted component instances.
1095
+ * @param {ComponentContext & SetupResult} context - The merged component context and setup data.
922
1096
  * @returns {Promise<void>}
923
1097
  *
924
1098
  * @example
925
1099
  * // Explicit children mounting:
926
1100
  * const children = {
927
- * 'UserProfile': UserProfileComponent,
1101
+ * 'user-profile': UserProfileComponent,
928
1102
  * '#settings-panel': "settings-panel"
929
1103
  * };
930
1104
  */
931
1105
  private _mountComponents;
932
1106
  }
1107
+ /**
1108
+ * Configuration options for the Eleva instance (reserved for future use).
1109
+ */
1110
+ type ElevaConfig = Record<string, unknown>;
1111
+ /**
1112
+ * Component definition object.
1113
+ */
933
1114
  type ComponentDefinition = {
934
1115
  /**
935
- * Optional setup function that initializes the component's state and returns reactive data
1116
+ * Optional setup function that initializes the component's state and returns reactive data.
936
1117
  */
937
1118
  setup?: SetupFunction | undefined;
938
1119
  /**
939
- * Required function or string that defines the component's HTML structure
1120
+ * Required function or string that defines the component's HTML structure.
940
1121
  */
941
1122
  template: TemplateFunction | string;
942
1123
  /**
943
- * Optional function or string that provides component-scoped CSS styles
1124
+ * Optional function or string that provides CSS styles for the component.
1125
+ * Styles are preserved across DOM diffs via data-e-style markers.
944
1126
  */
945
1127
  style?: string | StyleFunction | undefined;
946
1128
  /**
947
- * Optional object defining nested child components
1129
+ * Optional object defining nested child components.
948
1130
  */
949
1131
  children?: ChildrenMap | undefined;
950
1132
  };
1133
+ /**
1134
+ * Setup function that initializes component state.
1135
+ */
951
1136
  type SetupFunction = (ctx: ComponentContext) => SetupResult | Promise<SetupResult>;
952
1137
  /**
953
- * Data returned from setup function, may include lifecycle hooks
1138
+ * Data returned from setup function, may include lifecycle hooks.
954
1139
  */
955
1140
  type SetupResult = Record<string, unknown> & LifecycleHooks;
956
- type TemplateFunction = (ctx: ComponentContext) => string | Promise<string>;
957
- type StyleFunction = (ctx: ComponentContext) => string;
958
1141
  /**
959
- * Map of CSS selectors to component definitions or registered component names
1142
+ * Template function that returns HTML markup.
1143
+ */
1144
+ type TemplateFunction = (ctx: ComponentContext & SetupResult) => string | Promise<string>;
1145
+ /**
1146
+ * Style function that returns CSS styles.
1147
+ */
1148
+ type StyleFunction = (ctx: ComponentContext & SetupResult) => string;
1149
+ /**
1150
+ * Map of CSS selectors to component definitions or registered component names.
960
1151
  */
961
1152
  type ChildrenMap = Record<string, ComponentDefinition | string>;
1153
+ /**
1154
+ * Context passed to component setup function.
1155
+ */
962
1156
  type ComponentContext = {
963
1157
  /**
964
- * Component properties passed during mounting
1158
+ * Component properties passed during mounting.
965
1159
  */
966
1160
  props: ComponentProps;
967
1161
  /**
968
- * Event emitter instance for component event handling
1162
+ * Event emitter instance for component event handling.
969
1163
  */
970
1164
  emitter: Emitter;
971
1165
  /**
972
- * Factory function to create reactive Signal instances
1166
+ * Factory function to create reactive Signal instances.
973
1167
  */
974
1168
  signal: SignalFactory;
975
1169
  };
976
1170
  /**
977
- * Properties passed to a component during mounting
1171
+ * Properties passed to a component during mounting.
978
1172
  */
979
1173
  type ComponentProps = Record<string, unknown>;
980
- type SignalFactory = () => any;
1174
+ /**
1175
+ * Factory function to create reactive Signal instances.
1176
+ */
1177
+ type SignalFactory = <T>(initialValue: T) => Signal<T>;
1178
+ /**
1179
+ * Lifecycle hooks that can be returned from setup function.
1180
+ */
981
1181
  type LifecycleHooks = {
982
1182
  /**
983
- * Hook called before component mounting
1183
+ * Called before component mounting.
984
1184
  */
985
1185
  onBeforeMount?: LifecycleHook | undefined;
986
1186
  /**
987
- * Hook called after component mounting
1187
+ * Called after component mounting.
988
1188
  */
989
1189
  onMount?: LifecycleHook | undefined;
990
1190
  /**
991
- * Hook called before component update
1191
+ * Called before component update.
992
1192
  */
993
1193
  onBeforeUpdate?: LifecycleHook | undefined;
994
1194
  /**
995
- * Hook called after component update
1195
+ * Called after component update.
996
1196
  */
997
1197
  onUpdate?: LifecycleHook | undefined;
998
1198
  /**
999
- * Hook called during component unmounting
1199
+ * Called during component unmounting.
1000
1200
  */
1001
1201
  onUnmount?: UnmountHook | undefined;
1002
1202
  };
1203
+ /**
1204
+ * Lifecycle hook function.
1205
+ */
1003
1206
  type LifecycleHook = (ctx: LifecycleHookContext) => void | Promise<void>;
1207
+ /**
1208
+ * Unmount hook function with cleanup resources.
1209
+ */
1004
1210
  type UnmountHook = (ctx: UnmountHookContext) => void | Promise<void>;
1211
+ /**
1212
+ * Context passed to lifecycle hooks.
1213
+ */
1005
1214
  type LifecycleHookContext = {
1006
1215
  /**
1007
- * The DOM element where the component is mounted
1216
+ * The DOM element where the component is mounted.
1008
1217
  */
1009
1218
  container: HTMLElement;
1010
1219
  /**
1011
- * The component's reactive state and context data
1220
+ * The component's reactive state and context data.
1012
1221
  */
1013
1222
  context: ComponentContext & SetupResult;
1014
1223
  };
1224
+ /**
1225
+ * Context passed to unmount hook with cleanup resources.
1226
+ */
1015
1227
  type UnmountHookContext = {
1016
1228
  /**
1017
- * The DOM element where the component is mounted
1229
+ * The DOM element where the component is mounted.
1018
1230
  */
1019
1231
  container: HTMLElement;
1020
1232
  /**
1021
- * The component's reactive state and context data
1233
+ * The component's reactive state and context data.
1022
1234
  */
1023
1235
  context: ComponentContext & SetupResult;
1024
1236
  /**
1025
- * Object containing cleanup functions and instances
1237
+ * Object containing cleanup functions and instances.
1026
1238
  */
1027
1239
  cleanup: CleanupResources;
1028
1240
  };
1241
+ /**
1242
+ * Resources available for cleanup during unmount.
1243
+ */
1029
1244
  type CleanupResources = {
1030
1245
  /**
1031
- * Signal watcher cleanup functions
1246
+ * Signal watcher cleanup functions.
1032
1247
  */
1033
- watchers: Array<UnsubscribeFunction>;
1248
+ watchers: UnsubscribeFunction[];
1034
1249
  /**
1035
- * Event listener cleanup functions
1250
+ * Event listener cleanup functions.
1036
1251
  */
1037
- listeners: Array<UnsubscribeFunction>;
1252
+ listeners: UnsubscribeFunction[];
1038
1253
  /**
1039
- * Child component instances
1254
+ * Child component instances.
1040
1255
  */
1041
- children: Array<MountResult>;
1256
+ children: MountResult[];
1042
1257
  };
1258
+ /**
1259
+ * Result of mounting a component.
1260
+ */
1043
1261
  type MountResult = {
1044
1262
  /**
1045
- * The DOM element where the component is mounted
1263
+ * The DOM element where the component is mounted.
1046
1264
  */
1047
1265
  container: HTMLElement;
1048
1266
  /**
1049
- * The component's reactive state and context data
1267
+ * The component's reactive state and context data.
1050
1268
  */
1051
1269
  data: ComponentContext & SetupResult;
1052
1270
  /**
1053
- * Function to clean up and unmount the component
1271
+ * Function to clean up and unmount the component.
1054
1272
  */
1055
1273
  unmount: UnmountFunction;
1056
1274
  };
1275
+ /**
1276
+ * Function to unmount a component and clean up resources.
1277
+ */
1057
1278
  type UnmountFunction = () => Promise<void>;
1279
+ /**
1280
+ * Function to unsubscribe from events or watchers.
1281
+ */
1058
1282
  type UnsubscribeFunction = () => void | boolean;
1283
+ /**
1284
+ * Plugin interface for extending Eleva.
1285
+ */
1059
1286
  type ElevaPlugin = {
1060
1287
  /**
1061
- * Function that installs the plugin into the Eleva instance
1288
+ * Unique identifier name for the plugin.
1062
1289
  */
1063
- install: PluginInstallFunction;
1290
+ name: string;
1064
1291
  /**
1065
- * Unique identifier name for the plugin
1292
+ * Optional version string for the plugin.
1066
1293
  */
1067
- name: string;
1294
+ version?: string | undefined;
1068
1295
  /**
1069
- * Optional function to uninstall the plugin
1296
+ * Function that installs the plugin.
1297
+ */
1298
+ install: PluginInstallFunction;
1299
+ /**
1300
+ * Optional function to uninstall the plugin.
1070
1301
  */
1071
1302
  uninstall?: PluginUninstallFunction | undefined;
1072
1303
  };
1073
- type PluginInstallFunction = (eleva: Eleva, options: PluginOptions) => void | Eleva | unknown;
1074
- type PluginUninstallFunction = (eleva: Eleva) => void;
1075
1304
  /**
1076
- * Configuration options passed to a plugin during installation
1305
+ * Plugin install function.
1306
+ */
1307
+ type PluginInstallFunction = (eleva: Eleva, options?: PluginOptions | undefined) => void | Eleva | unknown;
1308
+ /**
1309
+ * Plugin uninstall function.
1310
+ */
1311
+ type PluginUninstallFunction = (eleva: Eleva) => void | Promise<void>;
1312
+ /**
1313
+ * Configuration options passed to a plugin during installation.
1077
1314
  */
1078
1315
  type PluginOptions = Record<string, unknown>;
1316
+ /**
1317
+ * Handler function for DOM events (e.g., click, input, submit).
1318
+ */
1319
+ type DOMEventHandler = (event: Event) => void;
1320
+ /**
1321
+ * Common DOM event names (prefixed with @ in templates).
1322
+ */
1323
+ type DOMEventName = "click" | "submit" | "input" | "change" | "focus" | "blur" | "keydown" | "keyup" | "keypress" | "mouseenter" | "mouseleave" | "mouseover" | "mouseout" | "mousedown" | "mouseup" | "touchstart" | "touchend" | "touchmove" | "scroll" | "resize" | "load" | "error" | string;
1079
1324
 
1080
1325
  //# sourceMappingURL=index.d.ts.map
1081
1326
 
1082
- export { Eleva as default };
1327
+ export { Eleva, Emitter, Renderer, Signal, TemplateEngine, Eleva as default };
1328
+ export type { ChildrenMap, CleanupResources, ComponentContext, ComponentDefinition, ComponentProps, DOMEventHandler, DOMEventName, ElevaConfig, ElevaPlugin, LifecycleHook, LifecycleHookContext, LifecycleHooks, MountResult, PluginInstallFunction, PluginOptions, PluginUninstallFunction, SetupFunction, SetupResult, SignalFactory, StyleFunction, TemplateFunction, UnmountFunction, UnmountHook, UnmountHookContext, UnsubscribeFunction };
1329
+ //# sourceMappingURL=eleva.d.ts.map