@xaendar/core 0.6.14 → 0.6.16

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.
@@ -12,16 +12,21 @@ import { SignalOptions } from '@xaendar/signals';
12
12
  import { VoidFunction as VoidFunction_2 } from '@xaendar/types';
13
13
 
14
14
  /**
15
- * Base class for all Web Components in the framework
15
+ * Base class for all web components in the framework.
16
16
  *
17
- * This class internally has an `observedAttributes` property
18
- * add programmaticaly by the @WebComponent decorator.
19
- * It won't appear by intellisense but it's there.
17
+ * Extends `HTMLElement` with Shadow DOM support and the lifecycle hooks
18
+ * required for signal-based rendering. Concrete component classes should
19
+ * extend this class and be decorated with `@WebComponent`.
20
+ *
21
+ * The `observedAttributes` static getter is added programmatically by the
22
+ * `@WebComponent` decorator and will not appear in IDE autocompletion, but
23
+ * it is present at runtime.
20
24
  */
21
25
  export declare class BaseWebComponent extends HTMLElement {
22
26
  [key: string]: unknown;
23
27
  /**
24
- * Array of functions to unwatch all the signals used in the component
28
+ * The active template execution context for this component instance,
29
+ * holding all identifier bindings and registered cleanup functions.
25
30
  */
26
31
  protected context: Context;
27
32
  /**
@@ -31,37 +36,40 @@ export declare class BaseWebComponent extends HTMLElement {
31
36
  constructor();
32
37
  /* Excluded from this release type: _render */
33
38
  /**
34
- * Method automatically called by the JavascriptEngine when an attribute
35
- * on the host element is changed
39
+ * Called by the browser engine when an observed attribute on the host
40
+ * element is added, changed, or removed.
36
41
  *
37
- * This method runs before the connectedCallback method if any observed attribute
38
- * is specified on the CustomElement tag in the HTML
42
+ * This callback may fire before `connectedCallback` if the attribute is
43
+ * already present on the element at parse time.
39
44
  *
40
- * @param name Name of the attribute changed
41
- * @param _oldValue Old value of the attribute
42
- * @param newValue New value of the attribute
45
+ * @param name - The name of the attribute that changed.
46
+ * @param _oldValue - The previous value of the attribute (unused).
47
+ * @param newValue - The new value of the attribute.
43
48
  */
44
49
  private attributeChangedCallback;
45
50
  /**
46
- * Method automatically called by the JavascriptEngine when a CustomElement
47
- * is added to the DOM
51
+ * Called by the browser engine each time the element is inserted into the DOM.
48
52
  *
49
- * This method is called EVERY time the element is added
53
+ * Triggers the initial render by calling `_render()`, which builds the
54
+ * Shadow DOM tree and sets up reactive signal subscriptions.
50
55
  */
51
56
  private connectedCallback;
52
57
  /**
53
- * Method automatically called by the JavascriptEngine when a CustomElement
54
- * is removed from the DOM
55
- *
56
- * This method is called EVERY time the element is removed
58
+ * Called by the browser engine each time the element is removed from the DOM.
57
59
  *
58
- * We use this method to reset the _initialized flag
59
- * so that if the element is re-added to the DOM
60
- * the properties initialization won't call the render method
60
+ * Invokes `context.unlisten()` to dispose all active signal subscriptions,
61
+ * detach event listeners, and remove tracked DOM nodes so the component
62
+ * can be cleanly re-rendered if it is re-inserted.
61
63
  */
62
64
  private disconnectedCallback;
63
65
  }
64
66
 
67
+ /**
68
+ * Constructor type for classes that extend {@link BaseWebComponent}.
69
+ *
70
+ * Includes the static `observedAttributes` array required by the Custom
71
+ * Elements API to register attribute change callbacks.
72
+ */
65
73
  export declare type BaseWebComponentConstructor = Constructor<BaseWebComponent, {
66
74
  observedAttributes: string[];
67
75
  }>;
@@ -97,14 +105,14 @@ export declare type Computed<Value = any> = Signal.Computed<Value> & {
97
105
  };
98
106
 
99
107
  /**
100
- * Creates a read-only computed signal.
108
+ * Creates a read-only computed signal whose value is derived from other signals.
101
109
  *
102
110
  * Returns a callable getter that reads the current value, augmented with the
103
111
  * underlying {@link Signal.State} API.
104
112
  *
105
113
  * @template Value - The type of the computed value. Defaults to `any`.
106
- * @param value - The initial value.
107
- * @param options - Configuration options for the signal.
114
+ * @param value - The initial (seed) value of the computed signal.
115
+ * @param options - Configuration options for the underlying signal.
108
116
  * @returns A {@link Computed} instance.
109
117
  */
110
118
  export declare function computed<Value = any>(value: Value, options?: SignalOptions<Value>): Computed<Value>;
@@ -117,49 +125,78 @@ export declare function computed<Value = any>(value: Value, options?: SignalOpti
117
125
  export declare class Context {
118
126
  private _root;
119
127
  private _parent;
120
- private _identifiers;
121
128
  /**
122
- * Array of functions to be called when the current context is destroyed (e.g. a `@if` becomes false)
123
- * These functions contains
124
- * - Remove Element
125
- * - Remove EventListener
126
- * - Effect unsubscription Function
129
+ * Child contexts representing nested scopes (e.g. `@for` loop iterations, `@if` branches).
127
130
  */
128
- private _unwatchFns;
129
131
  private _children;
132
+ /**
133
+ * DOM nodes owned by this context, tracked for cleanup on destruction.
134
+ */
130
135
  private _nodes;
136
+ /**
137
+ * Cleanup functions registered via {@link listen}.
138
+ * Called when this context is destroyed to remove DOM nodes,
139
+ * detach event listeners, and dispose signal effect subscriptions.
140
+ */
141
+ private _unwatchFns;
131
142
  /**
132
143
  * Creates a new scope context.
133
144
  *
134
- * @param _root - Web Component Reference to access properties and methods directly for bindings
135
- * @param _parent Optional parent context representing the enclosing scope.
136
- * @param _identifiers List of loop variable names declared in this scope.
145
+ * @param _root - Web component reference used to resolve property and method bindings.
146
+ * @param _parent - Optional parent context representing the enclosing scope.
147
+ * @param _identifiers - Named identifier bindings declared in this scope.
137
148
  */
138
- constructor(_root: BaseWebComponent, _parent: Context, _identifiers?: Map<string, ContextIdentifier>);
139
- addIdentifier(name: string, valueFn: NoArgsFunction<unknown>): void;
149
+ constructor(_root: BaseWebComponent, _parent: Context);
140
150
  /**
141
- * Returns the innermost identifier in the current scope chain, or
142
- * delegates to the parent context if none is found in this scope.
151
+ * Returns the event handler method bound to the root component instance.
143
152
  *
144
- * @returns The most recently declared identifier name, or `undefined` if none exists.
153
+ * @param handler - The name of the method on the root component to retrieve.
154
+ * @returns The handler function, bound to the root component so `this` is correct.
145
155
  */
146
- getIdentifier<ReturnType = unknown>(name: string): ContextIdentifier<ReturnType> | undefined;
147
156
  getEventHandler(handler: string): VoidFunction;
157
+ /**
158
+ * Registers a child context as a nested scope of this context.
159
+ *
160
+ * @param context - The child context to add.
161
+ */
148
162
  addChild(context: Context): void;
163
+ /**
164
+ * Removes a previously registered child context from this scope.
165
+ *
166
+ * @param context - The child context to remove.
167
+ */
149
168
  removeChild(context: Context): void;
169
+ /**
170
+ * Registers a DOM node as owned by this context.
171
+ *
172
+ * @param node - The DOM node to track.
173
+ */
150
174
  addNode(node: Node): void;
175
+ /**
176
+ * Removes a tracked DOM node from this context.
177
+ *
178
+ * @param nodeToRemove - The DOM node to untrack.
179
+ */
151
180
  removeNode(nodeToRemove: Node): void;
181
+ /**
182
+ * Registers one or more cleanup functions to be called when this context is destroyed.
183
+ *
184
+ * Cleanup functions typically remove DOM nodes, detach event listeners, or
185
+ * dispose of signal effect subscriptions.
186
+ *
187
+ * @param fns - The cleanup functions to register.
188
+ */
152
189
  listen(...fns: NoArgsVoidFunction[]): void;
190
+ /**
191
+ * Destroys this context by invoking all registered cleanup functions,
192
+ * recursively destroying child contexts, and clearing internal state.
193
+ *
194
+ * After calling `unlisten`, this context and its entire subtree are
195
+ * considered disposed and should no longer be used.
196
+ */
153
197
  unlisten(): void;
154
198
  }
155
199
 
156
- declare type ContextIdentifier<ReturnType = unknown> = {
157
- get: NoArgsFunction<ReturnType>;
158
- reactive: boolean;
159
- };
160
-
161
- export declare function declareConst(context: Context, name: string, expression: NoArgsFunction<unknown>): void;
162
-
163
200
  /**
164
201
  * Runs a side-effectful function and automatically re-runs it whenever any
165
202
  * Signal read during its execution changes.
@@ -197,11 +234,34 @@ export declare function declareConst(context: Context, name: string, expression:
197
234
  */
198
235
  export declare function effect(fn: NoArgsVoidFunction_2, options?: EffectOptions): NoArgsVoidFunction_2;
199
236
 
237
+ /**
238
+ * Decorator that declares a custom event output on a web component.
239
+ *
240
+ * Transforms the decorated accessor into an {@link Output} object whose
241
+ * `emit` method dispatches a `CustomEvent` on the host element. The event
242
+ * name is derived from the accessor name, and the provided `options`
243
+ * (bubbles, cancelable, composed) are used as defaults that can be
244
+ * overridden per-emission.
245
+ *
246
+ * @param options - Default `CustomEvent` options for every emission. At
247
+ * least one of `bubbles`, `cancelable`, or `composed` must be specified.
248
+ * @returns An accessor decorator that replaces the field with an `Output`.
249
+ *
250
+ * @example
251
+ * ```ts
252
+ * @Event({ bubbles: true })
253
+ * accessor clicked: Output<MouseEvent>;
254
+ * ```
255
+ */
200
256
  declare function Event_2<Class extends BaseWebComponent, Data = void>(options?: EventOptions): AccessorDecorator<Class, Output<Data>>;
201
257
  export { Event_2 as Event }
202
258
 
203
259
  /**
204
- * Rapresent the options to configure an @Event Decorator in a Web Component.
260
+ * Represents the options used to configure an `@Event` decorator in a web component.
261
+ *
262
+ * At least one of `bubbles`, `cancelable`, or `composed` must be provided.
263
+ * Mirrors the relevant subset of {@link CustomEventInit}, excluding `detail`
264
+ * which is provided separately when emitting.
205
265
  */
206
266
  export declare type EventOptions = Beautify<RequireOne<Omit<CustomEventInit, 'detail'>>>;
207
267
 
@@ -214,7 +274,7 @@ export declare type EventOptions = Beautify<RequireOne<Omit<CustomEventInit, 'de
214
274
  * @param condition - A reactive function that returns the array of items to iterate over.
215
275
  * @param forFn - A callback invoked for each item, receiving the parent node, the item, and its index. Must return an array of cleanup functions.
216
276
  */
217
- export declare function _for(parentNode: HTMLElement, parentContext: Context, condition: () => unknown[], forFn: Function_2<[parentNode: HTMLElement, context: Context, item: unknown, index: number], Context>): void;
277
+ export declare function _for(parentNode: HTMLElement, parentContext: Context, condition: () => unknown[], forFn: Function_2<[parentNode: HTMLElement, context: Context, items: unknown[], index: number], Context>): void;
218
278
 
219
279
  /**
220
280
  * Creates a reactive conditional structure from a list of branches.
@@ -240,9 +300,19 @@ export declare function _for(parentNode: HTMLElement, parentContext: Context, co
240
300
  export declare function _if(parentNode: HTMLElement, parentContext: Context, blocks: Block[]): void;
241
301
 
242
302
  /**
243
- * An `InputSignal` is a specialized `Signal.State` designed for use as a property signal in web components.
244
- * It extends the base `State` signal with additional functionality to handle incoming values, such as those from HTML attributes or external sources,
245
- * and allows for optional transformation of these values before they are stored in the signal.
303
+ * Creates an `InputSignal` a specialized reactive state designed for use
304
+ * as a property signal in web components.
305
+ *
306
+ * Unlike a plain `Signal.State`, the `set` method of an `InputSignal` is
307
+ * restricted to internal callers (identified by the private symbol) and
308
+ * accepts an optional `transform` function that converts incoming values
309
+ * (e.g. raw HTML attribute strings) into the internally stored type before
310
+ * updating the signal.
311
+ *
312
+ * @param value - The initial value of the signal.
313
+ * @param options - Optional configuration including an equality function,
314
+ * lifecycle hooks, and a `transform` function applied to incoming values.
315
+ * @returns A new `InputSignal` instance.
246
316
  */
247
317
  export declare function input<ActualValue = unknown, IncomingValue = ActualValue>(value?: ActualValue, options?: InputSignalOptions<ActualValue, IncomingValue>): InputSignal<ActualValue, IncomingValue>;
248
318
 
@@ -306,29 +376,38 @@ export declare type InputSignalOptions<ActualValue = unknown, IncomingValue = Ac
306
376
  export declare function _iterationVariables(items: unknown[], index: number, itemAlias: string, indexAlias: string): Record<string, unknown>;
307
377
 
308
378
  /**
309
- * Rapresent the output type returned by an @Event Decorator in a Web Component.
379
+ * Represents the output type returned by an `@Event` decorator in a web component.
310
380
  *
311
- * Function type `emit` can be used to emit the event with the specified value and options.
312
- * @param Value - The type of the value to be emitted with the event. Default is `void`.
313
- * @param EventParams - The type of the event parameters to configure the event emission.
314
- * This object's properties override the default event parameters defined in the decorator.
381
+ * The `emit` method dispatches a `CustomEvent` with the specified value and
382
+ * options. Any options passed to `emit` override the defaults configured in
383
+ * the decorator.
384
+ *
385
+ * @template Value - The type of the value to emit as the event detail. Defaults to `void`.
315
386
  */
316
387
  export declare type Output<Value = void> = {
317
388
  emit: VoidFunction_2<Value extends void ? ([EventOptions] | []) : ([Value, EventOptions] | [Value])>;
318
389
  };
319
390
 
320
391
  /**
321
- * Decoratore per proprietà opzionale.
392
+ * Decorator that declares an optional input property on a web component.
393
+ *
394
+ * Transforms the decorated accessor into a reactive {@link InputSignal}
395
+ * bound to the corresponding HTML attribute. An optional default `value`
396
+ * and further configuration can be supplied via `options`.
397
+ *
398
+ * @param value - Optional default value for the property.
399
+ * @param options - Additional configuration (equality function, lifecycle
400
+ * hooks, attribute alias, transform function).
401
+ * @returns An accessor decorator that replaces the field with an `InputSignal`.
322
402
  *
323
403
  * @example
404
+ * ```ts
324
405
  * @Property()
325
406
  * accessor label: InputSignal<string>;
326
407
  *
327
- * @Property({ value: 0 })
408
+ * @Property(0)
328
409
  * accessor count: InputSignal<number>;
329
- *
330
- * @Property({ value: { required: true, foo: 'bar' }, alias: 'cfg' })
331
- * accessor config: InputSignal<Config>;
410
+ * ```
332
411
  */
333
412
  export declare function Property<Class extends BaseWebComponent, Value extends InputSignal<ActualValue, IncomingValue>, ActualValue = Value extends InputSignal<infer U, any> ? U : unknown, IncomingValue = Value extends InputSignal<any, infer V> ? V : ActualValue>(value?: ActualValue, options?: PropertyDecoratorOptions<ActualValue, IncomingValue>): AccessorDecorator<Class, InputSignal<ActualValue, IncomingValue>>;
334
413
 
@@ -368,36 +447,86 @@ declare type PropertyDecoratorOptionsWithRequired<ActualValue = unknown, Incomin
368
447
  required: true;
369
448
  };
370
449
 
450
+ /**
451
+ * Creates a DOM element, applies attributes and event listeners, appends it
452
+ * to the parent, and registers cleanup functions in the current context.
453
+ *
454
+ * Static (literal) attribute values are set once via `setAttribute`. Dynamic
455
+ * attribute values are wrapped in a reactive `effect` so they update
456
+ * automatically whenever the underlying signal changes. Event listeners are
457
+ * attached with `addEventListener` and the corresponding `removeEventListener`
458
+ * is registered as a cleanup function.
459
+ *
460
+ * @param parentNode - The parent HTML element to append the new element to.
461
+ * @param context - The current template execution scope.
462
+ * @param tagName - The HTML tag name of the element to create.
463
+ * @param attributes - List of attribute descriptors to apply to the element.
464
+ * @param events - List of event listener descriptors to attach to the element.
465
+ * @returns The newly created HTML element.
466
+ */
371
467
  export declare function _renderElement(parentNode: HTMLElement, context: Context, tagName: string, attributes: RenderElementAttribute[], events: RenderElementEvent[]): HTMLElement;
372
468
 
469
+ /**
470
+ * Describes a single HTML attribute to be applied to a rendered DOM element.
471
+ *
472
+ * When `literal` is `true`, `value` is a raw string written directly as the
473
+ * attribute value. When `false`, `value` is a getter function resolved at
474
+ * render time against the current {@link Context}.
475
+ */
373
476
  declare type RenderElementAttribute = {
477
+ /**
478
+ * The attribute name (e.g. `class`, `id`, `href`).
479
+ */
374
480
  name: string;
375
- value: string;
481
+ /**
482
+ * A getter returning the attribute value, or a reactive identifier resolved against the current context.
483
+ */
484
+ value: NoArgsFunction<unknown>;
485
+ /**
486
+ * When `true`, the value is a static string literal; when `false`, it is a reactive expression.
487
+ */
376
488
  literal: boolean;
377
489
  };
378
490
 
491
+ /**
492
+ * Describes a single DOM event listener to be attached to a rendered element.
493
+ */
379
494
  declare type RenderElementEvent = {
495
+ /**
496
+ * The DOM event name (e.g. `click`, `input`).
497
+ */
380
498
  name: string;
499
+ /**
500
+ * The name of the handler method on the component class to invoke when the event fires.
501
+ */
381
502
  handler: string;
382
503
  };
383
504
 
384
505
  /**
506
+ * Creates a static (non-reactive) text node with a literal string value.
507
+ *
508
+ * Appends a `Text` node containing `text` directly to `parentNode` and
509
+ * registers a cleanup function that removes the node when the context is
510
+ * destroyed.
385
511
  *
386
- * @param parentNode
387
- * @param text
388
- * @param context
389
- * @returns
512
+ * @param parentNode - The parent HTML element to append the text node to.
513
+ * @param context - The current template execution scope.
514
+ * @param text - The literal string to render as text content.
390
515
  */
391
516
  export declare function _renderLiteralText(parentNode: HTMLElement, context: Context, text: string): void;
392
517
 
393
518
  /**
519
+ * Creates a reactive text node bound to a named identifier in the current scope.
394
520
  *
395
- * @param parentNode
396
- * @param text
397
- * @param context
398
- * @returns
521
+ * Appends a `Text` node to `parentNode` with the initial value of the identifier.
522
+ * If the identifier is reactive, wraps the text update in an effect so the node
523
+ * content is kept in sync whenever the underlying signal changes.
524
+ *
525
+ * @param parentNode - The parent HTML element to append the text node to.
526
+ * @param context - The current template execution scope used to resolve `text`.
527
+ * @param text - The identifier name to resolve as the text content.
399
528
  */
400
- export declare function _renderText(parentNode: HTMLElement, context: Context, text: string): void;
529
+ export declare function _renderText(parentNode: HTMLElement, context: Context, textFn: NoArgsFunction<string>): void;
401
530
 
402
531
  /**
403
532
  * Creates a writable reactive signal.
@@ -468,14 +597,40 @@ export declare function _switch(parentNode: HTMLElement, parentContext: Context,
468
597
  }>): void;
469
598
 
470
599
  /**
471
- * Decorator to define a web component
472
- * @param selector Name or names of the custom element
600
+ * Decorator that registers a class as a custom web component.
601
+ *
602
+ * Automatically defines the `observedAttributes` static getter on the class
603
+ * from metadata populated by `@Property` decorators, and registers the
604
+ * component with the browser's Custom Elements registry under the given
605
+ * selector(s).
606
+ *
607
+ * @param options - Configuration object containing at least a `selector`
608
+ * (the custom element tag name) and a `templateUrl`.
609
+ * @returns A class decorator applied to the web component class.
610
+ *
611
+ * @example
612
+ * ```ts
613
+ * @WebComponent({ selector: 'my-button', templateUrl: './my-button.html' })
614
+ * class MyButtonComponent extends BaseWebComponent {}
615
+ * ```
473
616
  */
474
617
  export declare function WebComponent<T extends BaseWebComponent>(options: WebComponentDecoratorParams): ClassDecorator_2<T>;
475
618
 
619
+ /**
620
+ * Configuration object accepted by the `@WebComponent` decorator.
621
+ */
476
622
  export declare type WebComponentDecoratorParams = {
623
+ /**
624
+ * The custom element selector (or an array of selectors) used to register the component in the browser.
625
+ */
477
626
  selector: string | string[];
627
+ /**
628
+ * Optional path to the component's stylesheet, relative to the component file.
629
+ */
478
630
  styleUrl?: string;
631
+ /**
632
+ * Path to the component's HTML template, relative to the component file.
633
+ */
479
634
  templateUrl: string;
480
635
  };
481
636
 
@@ -2,6 +2,25 @@
2
2
  function isEventOptions(value) {
3
3
  return !!value && typeof value === "object" && ("bubbles" in value || "cancelable" in value || "composed" in value);
4
4
  }
5
+ /**
6
+ * Decorator that declares a custom event output on a web component.
7
+ *
8
+ * Transforms the decorated accessor into an {@link Output} object whose
9
+ * `emit` method dispatches a `CustomEvent` on the host element. The event
10
+ * name is derived from the accessor name, and the provided `options`
11
+ * (bubbles, cancelable, composed) are used as defaults that can be
12
+ * overridden per-emission.
13
+ *
14
+ * @param options - Default `CustomEvent` options for every emission. At
15
+ * least one of `bubbles`, `cancelable`, or `composed` must be specified.
16
+ * @returns An accessor decorator that replaces the field with an `Output`.
17
+ *
18
+ * @example
19
+ * ```ts
20
+ * @Event({ bubbles: true })
21
+ * accessor clicked: Output<MouseEvent>;
22
+ * ```
23
+ */
5
24
  function Event(options) {
6
25
  return (_value, context) => {
7
26
  const name = context.name;
@@ -31,22 +50,37 @@ function Event(options) {
31
50
  }
32
51
  //#endregion
33
52
  //#region ../packages/core/src/costants.ts
53
+ /**
54
+ * Metadata key used internally to store the list of observed attribute names
55
+ * on a web component class.
56
+ *
57
+ * Populated by the `@Property` decorator and consumed by `@WebComponent` to
58
+ * define `observedAttributes` on the custom element class.
59
+ *
60
+ * @internal
61
+ */
34
62
  var INTERNAL_OBSERVED_ATTRIBUTES = `observedAttributes`;
35
63
  //#endregion
36
64
  //#region ../packages/core/src/signals/input/input-instance.symbol.ts
37
65
  /**
38
- * This file defines a unique symbol used to identify instances of input signals within the framework.
39
- * The symbol serves as a marker to ensure that only valid input signal instances are recognized and processed.
66
+ * Unique symbol used to mark an object as a valid `InputSignal` instance.
67
+ *
68
+ * Set to `true` on every `InputSignal` created by the `input()` factory.
69
+ * Used by {@link isInputSignal} to distinguish input signals from plain
70
+ * `Signal.State` instances at runtime without exposing the marker in the
71
+ * public API.
40
72
  *
41
73
  * @internal
42
74
  */
43
75
  var INPUT_SIGNAL_INSTANCE_SYMBOL = Symbol(`InputSignalInstance`);
44
76
  /**
45
- * Type guard function to check if a given instance is an InputSignal.
46
- * This function checks for the presence of the INPUT_SIGNAL_INSTANCE_SYMBOL on the instance,
47
- * which is set to true for valid InputSignal instances.
48
- * @param instance - The object to check for being an InputSignal instance.
49
- * @returns A boolean indicating whether the instance is an InputSignal.
77
+ * Type guard that checks whether a given value is an `InputSignal` instance.
78
+ *
79
+ * Inspects the presence of {@link INPUT_SIGNAL_INSTANCE_SYMBOL} on the object,
80
+ * which is set to `true` by the `input()` factory for every valid instance.
81
+ *
82
+ * @param instance - The value to inspect.
83
+ * @returns `true` if `instance` is an `InputSignal`, `false` otherwise.
50
84
  */
51
85
  function isInputSignal(instance) {
52
86
  return instance?.[INPUT_SIGNAL_INSTANCE_SYMBOL];
@@ -76,9 +110,19 @@ function assertPrivateContext(symbol) {
76
110
  //#endregion
77
111
  //#region ../packages/core/src/signals/input/input.ts
78
112
  /**
79
- * An `InputSignal` is a specialized `Signal.State` designed for use as a property signal in web components.
80
- * It extends the base `State` signal with additional functionality to handle incoming values, such as those from HTML attributes or external sources,
81
- * and allows for optional transformation of these values before they are stored in the signal.
113
+ * Creates an `InputSignal` a specialized reactive state designed for use
114
+ * as a property signal in web components.
115
+ *
116
+ * Unlike a plain `Signal.State`, the `set` method of an `InputSignal` is
117
+ * restricted to internal callers (identified by the private symbol) and
118
+ * accepts an optional `transform` function that converts incoming values
119
+ * (e.g. raw HTML attribute strings) into the internally stored type before
120
+ * updating the signal.
121
+ *
122
+ * @param value - The initial value of the signal.
123
+ * @param options - Optional configuration including an equality function,
124
+ * lifecycle hooks, and a `transform` function applied to incoming values.
125
+ * @returns A new `InputSignal` instance.
82
126
  */
83
127
  function input(value, options) {
84
128
  const transform = options?.transform;
@@ -132,31 +176,49 @@ function createPropertyDecorator(value, options) {
132
176
  };
133
177
  }
134
178
  /**
135
- * Decoratore per proprietà opzionale.
179
+ * Decorator that declares an optional input property on a web component.
180
+ *
181
+ * Transforms the decorated accessor into a reactive {@link InputSignal}
182
+ * bound to the corresponding HTML attribute. An optional default `value`
183
+ * and further configuration can be supplied via `options`.
184
+ *
185
+ * @param value - Optional default value for the property.
186
+ * @param options - Additional configuration (equality function, lifecycle
187
+ * hooks, attribute alias, transform function).
188
+ * @returns An accessor decorator that replaces the field with an `InputSignal`.
136
189
  *
137
190
  * @example
191
+ * ```ts
138
192
  * @Property()
139
193
  * accessor label: InputSignal<string>;
140
194
  *
141
- * @Property({ value: 0 })
195
+ * @Property(0)
142
196
  * accessor count: InputSignal<number>;
143
- *
144
- * @Property({ value: { required: true, foo: 'bar' }, alias: 'cfg' })
145
- * accessor config: InputSignal<Config>;
197
+ * ```
146
198
  */
147
199
  function Property(value, options) {
148
200
  return createPropertyDecorator(value, options);
149
201
  }
150
202
  /**
151
- * Decoratore per proprietà obbligatoria.
152
- * Il consumer deve fornire il valore; non accetta un valore di default.
203
+ * Decorator that declares a required input property on a web component.
204
+ *
205
+ * The consumer must explicitly supply the attribute value; no default is
206
+ * accepted. If the attribute is absent, the signal value will be `undefined`
207
+ * and any transform or default handling is the responsibility of the consumer.
208
+ *
209
+ * @param options - Optional configuration (equality function, lifecycle
210
+ * hooks, attribute alias, transform function). The `required` flag is
211
+ * added automatically.
212
+ * @returns An accessor decorator that replaces the field with an `InputSignal`.
153
213
  *
154
214
  * @example
215
+ * ```ts
155
216
  * @Property.required()
156
217
  * accessor userId: InputSignal<string>;
157
218
  *
158
219
  * @Property.required({ alias: 'user-id' })
159
220
  * accessor userId: InputSignal<string>;
221
+ * ```
160
222
  */
161
223
  Property.required = function required(options) {
162
224
  return createPropertyDecorator({
@@ -168,8 +230,22 @@ Property.required = function required(options) {
168
230
  //#endregion
169
231
  //#region ../packages/core/src/decorators/web-component/web-component.decorator.ts
170
232
  /**
171
- * Decorator to define a web component
172
- * @param selector Name or names of the custom element
233
+ * Decorator that registers a class as a custom web component.
234
+ *
235
+ * Automatically defines the `observedAttributes` static getter on the class
236
+ * from metadata populated by `@Property` decorators, and registers the
237
+ * component with the browser's Custom Elements registry under the given
238
+ * selector(s).
239
+ *
240
+ * @param options - Configuration object containing at least a `selector`
241
+ * (the custom element tag name) and a `templateUrl`.
242
+ * @returns A class decorator applied to the web component class.
243
+ *
244
+ * @example
245
+ * ```ts
246
+ * @WebComponent({ selector: 'my-button', templateUrl: './my-button.html' })
247
+ * class MyButtonComponent extends BaseWebComponent {}
248
+ * ```
173
249
  */
174
250
  function WebComponent(options) {
175
251
  return function(klass, context) {
@@ -178,14 +254,16 @@ function WebComponent(options) {
178
254
  };
179
255
  }
180
256
  /**
181
- * Function to define the observedAttributes static property on the class.
182
- * We define static get observedAttributes programmatically
183
- * to abstract the manual definition from the user.
184
- *
185
- * We could not define the property in the base class due to the fact
186
- * that is static and each derived class would override the value of the others
187
- * @param klass The class to set the observedAttributes on
188
- * @param attributes The attributes to observe
257
+ * Defines the `observedAttributes` static getter on a web component class
258
+ * using metadata collected by `@Property` decorators.
259
+ *
260
+ * Defined programmatically to avoid requiring each component class to
261
+ * manually re-declare the static property, and to prevent subclasses from
262
+ * accidentally clobbering each other's attribute lists.
263
+ *
264
+ * @param klass - The web component class to augment.
265
+ * @param context - The class decorator context providing access to the
266
+ * shared metadata object.
189
267
  */
190
268
  function defineObservedAttributes(klass, context) {
191
269
  Object.defineProperty(klass, "observedAttributes", {
@@ -195,9 +273,11 @@ function defineObservedAttributes(klass, context) {
195
273
  });
196
274
  }
197
275
  /**
198
- * Function to add the custom element definition to the browser using the passed selectors.
199
- * @param klass The class to define as a web component
200
- * @param selectors The selector or selectors to reference the web component in HTML
276
+ * Registers the component class in the browser's Custom Elements registry
277
+ * under the given selector(s).
278
+ *
279
+ * @param klass - The web component class to register.
280
+ * @param selectors - One or more custom element tag names to associate with the class.
201
281
  */
202
282
  function setSelectors(klass, selectors) {
203
283
  Array.isArray(selectors) ? selectors.forEach((selector) => customElements.define(selector, klass)) : customElements.define(selectors, klass);
@@ -205,15 +285,20 @@ function setSelectors(klass, selectors) {
205
285
  //#endregion
206
286
  //#region ../packages/core/src/directives/base-web-component.ts
207
287
  /**
208
- * Base class for all Web Components in the framework
209
- *
210
- * This class internally has an `observedAttributes` property
211
- * add programmaticaly by the @WebComponent decorator.
212
- * It won't appear by intellisense but it's there.
288
+ * Base class for all web components in the framework.
289
+ *
290
+ * Extends `HTMLElement` with Shadow DOM support and the lifecycle hooks
291
+ * required for signal-based rendering. Concrete component classes should
292
+ * extend this class and be decorated with `@WebComponent`.
293
+ *
294
+ * The `observedAttributes` static getter is added programmatically by the
295
+ * `@WebComponent` decorator and will not appear in IDE autocompletion, but
296
+ * it is present at runtime.
213
297
  */
214
298
  var BaseWebComponent = class extends HTMLElement {
215
299
  /**
216
- * Array of functions to unwatch all the signals used in the component
300
+ * The active template execution context for this component instance,
301
+ * holding all identifier bindings and registered cleanup functions.
217
302
  */
218
303
  context;
219
304
  /**
@@ -225,23 +310,27 @@ var BaseWebComponent = class extends HTMLElement {
225
310
  this._root = this.attachShadow({ mode: "open" });
226
311
  }
227
312
  /**
228
- * Method called by the @Property decorator to
229
- * update the rendering of the component
230
- * @internal
313
+ * Initialises the component's Shadow DOM render tree.
314
+ *
315
+ * Overridden by the compiler-generated code injected via the `@WebComponent`
316
+ * decorator pipeline. Returns an array of effect disposer functions that
317
+ * should be called when the component is disconnected.
318
+ *
319
+ * @internal
231
320
  */
232
321
  _render() {
233
322
  return [];
234
323
  }
235
324
  /**
236
- * Method automatically called by the JavascriptEngine when an attribute
237
- * on the host element is changed
238
- *
239
- * This method runs before the connectedCallback method if any observed attribute
240
- * is specified on the CustomElement tag in the HTML
241
- *
242
- * @param name Name of the attribute changed
243
- * @param _oldValue Old value of the attribute
244
- * @param newValue New value of the attribute
325
+ * Called by the browser engine when an observed attribute on the host
326
+ * element is added, changed, or removed.
327
+ *
328
+ * This callback may fire before `connectedCallback` if the attribute is
329
+ * already present on the element at parse time.
330
+ *
331
+ * @param name - The name of the attribute that changed.
332
+ * @param _oldValue - The previous value of the attribute (unused).
333
+ * @param newValue - The new value of the attribute.
245
334
  */
246
335
  attributeChangedCallback(name, _oldValue, newValue) {
247
336
  const context = this;
@@ -250,23 +339,20 @@ var BaseWebComponent = class extends HTMLElement {
250
339
  context[name].set(newValue, INPUT_SIGNAL_SET_SYMBOL);
251
340
  }
252
341
  /**
253
- * Method automatically called by the JavascriptEngine when a CustomElement
254
- * is added to the DOM
255
- *
256
- * This method is called EVERY time the element is added
342
+ * Called by the browser engine each time the element is inserted into the DOM.
343
+ *
344
+ * Triggers the initial render by calling `_render()`, which builds the
345
+ * Shadow DOM tree and sets up reactive signal subscriptions.
257
346
  */
258
347
  connectedCallback() {
259
348
  this.unwatchFns = this._render();
260
349
  }
261
350
  /**
262
- * Method automatically called by the JavascriptEngine when a CustomElement
263
- * is removed from the DOM
264
- *
265
- * This method is called EVERY time the element is removed
266
- *
267
- * We use this method to reset the _initialized flag
268
- * so that if the element is re-added to the DOM
269
- * the properties initialization won't call the render method
351
+ * Called by the browser engine each time the element is removed from the DOM.
352
+ *
353
+ * Invokes `context.unlisten()` to dispose all active signal subscriptions,
354
+ * detach event listeners, and remove tracked DOM nodes so the component
355
+ * can be cleanly re-rendered if it is re-inserted.
270
356
  */
271
357
  disconnectedCallback() {
272
358
  this.context.unlisten();
@@ -275,14 +361,14 @@ var BaseWebComponent = class extends HTMLElement {
275
361
  //#endregion
276
362
  //#region ../packages/core/src/signals/computed/computed.ts
277
363
  /**
278
- * Creates a read-only computed signal.
364
+ * Creates a read-only computed signal whose value is derived from other signals.
279
365
  *
280
366
  * Returns a callable getter that reads the current value, augmented with the
281
367
  * underlying {@link Signal.State} API.
282
368
  *
283
369
  * @template Value - The type of the computed value. Defaults to `any`.
284
- * @param value - The initial value.
285
- * @param options - Configuration options for the signal.
370
+ * @param value - The initial (seed) value of the computed signal.
371
+ * @param options - Configuration options for the underlying signal.
286
372
  * @returns A {@link Computed} instance.
287
373
  */
288
374
  function computed(value, options) {
@@ -409,68 +495,90 @@ function signal(value, options) {
409
495
  var Context = class {
410
496
  _root;
411
497
  _parent;
412
- _identifiers;
413
- /**
414
- * Array of functions to be called when the current context is destroyed (e.g. a `@if` becomes false)
415
- * These functions contains
416
- * - Remove Element
417
- * - Remove EventListener
418
- * - Effect unsubscription Function
498
+ /**
499
+ * Child contexts representing nested scopes (e.g. `@for` loop iterations, `@if` branches).
419
500
  */
420
- _unwatchFns = new Array();
421
501
  _children = new Array();
502
+ /**
503
+ * DOM nodes owned by this context, tracked for cleanup on destruction.
504
+ */
422
505
  _nodes = new Array();
423
506
  /**
507
+ * Cleanup functions registered via {@link listen}.
508
+ * Called when this context is destroyed to remove DOM nodes,
509
+ * detach event listeners, and dispose signal effect subscriptions.
510
+ */
511
+ _unwatchFns = new Array();
512
+ /**
424
513
  * Creates a new scope context.
425
514
  *
426
- * @param _root - Web Component Reference to access properties and methods directly for bindings
427
- * @param _parent Optional parent context representing the enclosing scope.
428
- * @param _identifiers List of loop variable names declared in this scope.
515
+ * @param _root - Web component reference used to resolve property and method bindings.
516
+ * @param _parent - Optional parent context representing the enclosing scope.
517
+ * @param _identifiers - Named identifier bindings declared in this scope.
429
518
  */
430
- constructor(_root, _parent, _identifiers = /* @__PURE__ */ new Map()) {
519
+ constructor(_root, _parent) {
431
520
  this._root = _root;
432
521
  this._parent = _parent;
433
- this._identifiers = _identifiers;
434
- }
435
- addIdentifier(name, valueFn) {
436
- if (this.getIdentifier(name)) throw new Error(`Identifier "${name}" is already declared in this scope.`);
437
- this._identifiers.set(name, {
438
- get: valueFn,
439
- reactive: true
440
- });
441
522
  }
442
523
  /**
443
- * Returns the innermost identifier in the current scope chain, or
444
- * delegates to the parent context if none is found in this scope.
524
+ * Returns the event handler method bound to the root component instance.
445
525
  *
446
- * @returns The most recently declared identifier name, or `undefined` if none exists.
526
+ * @param handler - The name of the method on the root component to retrieve.
527
+ * @returns The handler function, bound to the root component so `this` is correct.
447
528
  */
448
- getIdentifier(name) {
449
- if (this._identifiers.has(name)) return this._identifiers.get(name);
450
- if (this._parent) return this._parent.getIdentifier(name);
451
- return {
452
- get: () => this._root[name],
453
- reactive: true
454
- };
455
- }
456
529
  getEventHandler(handler) {
457
530
  return this._root[handler].bind(this._root);
458
531
  }
532
+ /**
533
+ * Registers a child context as a nested scope of this context.
534
+ *
535
+ * @param context - The child context to add.
536
+ */
459
537
  addChild(context) {
460
538
  this._children.push(context);
461
539
  }
540
+ /**
541
+ * Removes a previously registered child context from this scope.
542
+ *
543
+ * @param context - The child context to remove.
544
+ */
462
545
  removeChild(context) {
463
546
  this._children = this._children.filter((child) => child === context);
464
547
  }
548
+ /**
549
+ * Registers a DOM node as owned by this context.
550
+ *
551
+ * @param node - The DOM node to track.
552
+ */
465
553
  addNode(node) {
466
554
  this._nodes.push(node);
467
555
  }
556
+ /**
557
+ * Removes a tracked DOM node from this context.
558
+ *
559
+ * @param nodeToRemove - The DOM node to untrack.
560
+ */
468
561
  removeNode(nodeToRemove) {
469
562
  this._nodes = this._nodes.filter((node) => node === nodeToRemove);
470
563
  }
564
+ /**
565
+ * Registers one or more cleanup functions to be called when this context is destroyed.
566
+ *
567
+ * Cleanup functions typically remove DOM nodes, detach event listeners, or
568
+ * dispose of signal effect subscriptions.
569
+ *
570
+ * @param fns - The cleanup functions to register.
571
+ */
471
572
  listen(...fns) {
472
573
  this._unwatchFns.push(...fns);
473
574
  }
575
+ /**
576
+ * Destroys this context by invoking all registered cleanup functions,
577
+ * recursively destroying child contexts, and clearing internal state.
578
+ *
579
+ * After calling `unlisten`, this context and its entire subtree are
580
+ * considered disposed and should no longer be used.
581
+ */
474
582
  unlisten() {
475
583
  this._unwatchFns.forEach((fn) => fn());
476
584
  this._children.forEach((child) => child.unlisten());
@@ -479,11 +587,6 @@ var Context = class {
479
587
  }
480
588
  };
481
589
  //#endregion
482
- //#region ../packages/core/src/utils/declare-const.util.ts
483
- function declareConst(context, name, expression) {
484
- context.addIdentifier(name, expression);
485
- }
486
- //#endregion
487
590
  //#region ../packages/core/src/utils/for.util.ts
488
591
  /**
489
592
  * Reactively iterates over a list of items, re-running the loop whenever the tracked condition changes.
@@ -505,7 +608,7 @@ function _for(parentNode, parentContext, condition, forFn) {
505
608
  const items = condition();
506
609
  Signal.subtle.untrack(() => {
507
610
  for (let i = 0; i < items.length; i++) {
508
- const context = forFn(parentNode, parentContext, items[i], i);
611
+ const context = forFn(parentNode, parentContext, items, i);
509
612
  contexts.push(context);
510
613
  parentContext.addChild(context);
511
614
  }
@@ -655,8 +758,8 @@ function handleIfElseIf(parentNode, parentContext, blocks, state) {
655
758
  * @param newState - The new state to set (index of the branch to activate, or `null`).
656
759
  * @param conditionalBlockFn - Branch function to execute, which returns its own
657
760
  * cleanup functions.
658
- * @returns Il nuovo stato e le nuove funzioni di cleanup se il ramo è cambiato, altrimenti
659
- * `undefined`.
761
+ * @returns The updated state if the active branch changed, or `undefined` if the branch
762
+ * is unchanged.
660
763
  */
661
764
  function checkAndUpdateState(parentNode, parentContext, state, newState, conditionalBlockFn) {
662
765
  if (state?.activeBranch !== newState) {
@@ -670,28 +773,35 @@ function checkAndUpdateState(parentNode, parentContext, state, newState, conditi
670
773
  //#endregion
671
774
  //#region ../packages/core/src/utils/render-text.util.ts
672
775
  /**
673
- *
674
- * @param parentNode
675
- * @param text
676
- * @param context
677
- * @returns
776
+ * Creates a reactive text node bound to a named identifier in the current scope.
777
+ *
778
+ * Appends a `Text` node to `parentNode` with the initial value of the identifier.
779
+ * If the identifier is reactive, wraps the text update in an effect so the node
780
+ * content is kept in sync whenever the underlying signal changes.
781
+ *
782
+ * @param parentNode - The parent HTML element to append the text node to.
783
+ * @param context - The current template execution scope used to resolve `text`.
784
+ * @param text - The identifier name to resolve as the text content.
678
785
  */
679
- function _renderText(parentNode, context, text) {
680
- const identifier = context.getIdentifier(text);
681
- const node = document.createTextNode(identifier.get());
786
+ function _renderText(parentNode, context, textFn) {
787
+ const node = document.createTextNode(textFn());
682
788
  parentNode.appendChild(node);
683
789
  context.listen(() => {
684
790
  context.removeNode(node);
685
791
  parentNode.removeChild(node);
686
792
  });
687
- if (identifier.reactive) context.listen(effect(() => node.textContent = identifier.get()));
793
+ context.listen(effect(() => node.textContent = textFn()));
688
794
  }
689
795
  /**
690
- *
691
- * @param parentNode
692
- * @param text
693
- * @param context
694
- * @returns
796
+ * Creates a static (non-reactive) text node with a literal string value.
797
+ *
798
+ * Appends a `Text` node containing `text` directly to `parentNode` and
799
+ * registers a cleanup function that removes the node when the context is
800
+ * destroyed.
801
+ *
802
+ * @param parentNode - The parent HTML element to append the text node to.
803
+ * @param context - The current template execution scope.
804
+ * @param text - The literal string to render as text content.
695
805
  */
696
806
  function _renderLiteralText(parentNode, context, text) {
697
807
  const node = document.createTextNode(text);
@@ -700,6 +810,23 @@ function _renderLiteralText(parentNode, context, text) {
700
810
  }
701
811
  //#endregion
702
812
  //#region ../packages/core/src/utils/render-util.ts
813
+ /**
814
+ * Creates a DOM element, applies attributes and event listeners, appends it
815
+ * to the parent, and registers cleanup functions in the current context.
816
+ *
817
+ * Static (literal) attribute values are set once via `setAttribute`. Dynamic
818
+ * attribute values are wrapped in a reactive `effect` so they update
819
+ * automatically whenever the underlying signal changes. Event listeners are
820
+ * attached with `addEventListener` and the corresponding `removeEventListener`
821
+ * is registered as a cleanup function.
822
+ *
823
+ * @param parentNode - The parent HTML element to append the new element to.
824
+ * @param context - The current template execution scope.
825
+ * @param tagName - The HTML tag name of the element to create.
826
+ * @param attributes - List of attribute descriptors to apply to the element.
827
+ * @param events - List of event listener descriptors to attach to the element.
828
+ * @returns The newly created HTML element.
829
+ */
703
830
  function _renderElement(parentNode, context, tagName, attributes, events) {
704
831
  const element = document.createElement(tagName);
705
832
  parentNode.appendChild(element);
@@ -708,11 +835,7 @@ function _renderElement(parentNode, context, tagName, attributes, events) {
708
835
  parentNode.removeChild(element);
709
836
  });
710
837
  attributes.forEach(({ name, value, literal }) => {
711
- if (literal) element.setAttribute(name, value);
712
- else {
713
- const identifier = context.getIdentifier(value);
714
- identifier.reactive ? context.listen(effect(() => element.setAttribute(name, String(identifier.get())))) : element.setAttribute(name, String(identifier.get()));
715
- }
838
+ literal ? element.setAttribute(name, String(value())) : context.listen(effect(() => element.setAttribute(name, String(value()))));
716
839
  });
717
840
  events.forEach((event) => {
718
841
  const handler = ($event) => context.getEventHandler(event.handler)();
@@ -756,4 +879,4 @@ function _switch(parentNode, parentContext, expression, blocks) {
756
879
  })));
757
880
  }
758
881
  //#endregion
759
- export { BaseWebComponent, Context, Event, Property, WebComponent, _for, _if, _iterationVariables, _renderElement, _renderLiteralText, _renderText, _switch, computed, declareConst, effect, input, signal };
882
+ export { BaseWebComponent, Context, Event, Property, WebComponent, _for, _if, _iterationVariables, _renderElement, _renderLiteralText, _renderText, _switch, computed, effect, input, signal };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xaendar/core",
3
- "version": "0.6.14",
3
+ "version": "0.6.16",
4
4
  "description": "A library containing core utils such as webcomponent base classes and theming support",
5
5
  "sideEffects": false,
6
6
  "type": "module",
@@ -16,7 +16,7 @@
16
16
  }
17
17
  },
18
18
  "dependencies": {
19
- "@xaendar/signals": "0.6.14",
20
- "@xaendar/types": "0.6.14"
19
+ "@xaendar/signals": "0.6.16",
20
+ "@xaendar/types": "0.6.16"
21
21
  }
22
22
  }