@alwatr/signal 9.13.0 → 9.14.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.
@@ -1,28 +1,53 @@
1
+ import type { Awaitable } from '@alwatr/type-helper';
1
2
  import { type AlwatrLogger } from '@alwatr/logger';
2
3
  import { SignalBase } from './signal-base.js';
3
4
  import type { SignalConfig, SubscribeOptions, SubscribeResult, ListenerCallback } from '../type.js';
5
+ /**
6
+ * Determines whether the payload argument for a given channel message is
7
+ * required or optional, based solely on the declared type in `TMap`.
8
+ *
9
+ * - `void | undefined` → payload is optional (second arg may be omitted).
10
+ * - anything else → payload is **required** (omitting it is a compile error).
11
+ *
12
+ * This is used to build the rest-parameter tuple for `dispatch()` so that
13
+ * TypeScript enforces the correct call signature at every dispatch site.
14
+ *
15
+ * @template TMap A record mapping message names to their payload types.
16
+ * @template K The specific message name key.
17
+ *
18
+ * @example
19
+ * ```ts
20
+ * // ActionRecord: { 'logout': void; 'add-to-cart': {productId: number} }
21
+ * type A = DispatchArgs<ActionRecord, 'logout'>; // [name: 'logout', payload?: void]
22
+ * type B = DispatchArgs<ActionRecord, 'add-to-cart'>; // [name: 'add-to-cart', payload: {productId: number}]
23
+ * ```
24
+ */
25
+ export type DispatchArgs<TMap extends object, K extends keyof TMap> = TMap[K] extends void | undefined ? [name: K, payload?: TMap[K]] : [name: K, payload: TMap[K]];
4
26
  /**
5
27
  * A single message dispatched through a `ChannelSignal`.
6
28
  *
7
29
  * `name` identifies the message type (e.g. `'open-drawer'`, `'add-to-cart'`).
8
- * `payload` is the optional value attached to the message its type is narrowed
9
- * by the generic map `TMap` at the class level.
30
+ * `payload` carries the associated data, whose type is determined by the generic `TMap` based on the `name`.
10
31
  *
11
32
  * @template TMap A record mapping message names to their payload types.
12
33
  * @template K The specific message name key (inferred, not set manually).
13
34
  */
14
- export type ChannelMessage<TMap extends Record<string, unknown>, K extends keyof TMap = keyof TMap> = K extends keyof TMap ? {
35
+ export type ChannelMessage<TMap extends object, K extends keyof TMap = keyof TMap> = {
15
36
  name: K;
16
- payload?: TMap[K];
17
- } : never;
37
+ payload: TMap[K];
38
+ };
18
39
  /**
19
40
  * A typed handler for a specific named message on a `ChannelSignal`.
20
41
  * Receives only the `payload` — the name is already known at subscription time.
21
42
  *
43
+ * The payload type mirrors `DispatchArgs`: it is `TMap[K] | undefined` only
44
+ * when the declared type is `void | undefined`; otherwise it is exactly `TMap[K]`
45
+ * (non-optional) so handlers do not need unnecessary null-guards.
46
+ *
22
47
  * @template TMap A record mapping message names to their payload types.
23
48
  * @template K The specific message name key.
24
49
  */
25
- export type ChannelHandler<TMap extends Record<string, unknown>, K extends keyof TMap> = (payload: TMap[K] | undefined) => void | Promise<void>;
50
+ export type ChannelHandler<TMap extends object, K extends keyof TMap = keyof TMap> = (payload: TMap[K]) => Awaitable<void>;
26
51
  /**
27
52
  * Configuration for creating a `ChannelSignal`.
28
53
  */
@@ -72,7 +97,7 @@ export interface ChannelSignalConfig extends SignalConfig {
72
97
  * appChannel.dispatch('close-drawer'); // no payload needed
73
98
  * ```
74
99
  */
75
- export declare class ChannelSignal<TMap extends Record<string, unknown>> extends SignalBase<ChannelMessage<TMap>> {
100
+ export declare class ChannelSignal<TMap extends object> extends SignalBase<ChannelMessage<TMap>> {
76
101
  /**
77
102
  * The logger instance for this signal.
78
103
  * @protected
@@ -85,6 +110,10 @@ export declare class ChannelSignal<TMap extends Record<string, unknown>> extends
85
110
  * registered via `on()`. Kept separate from `SignalBase`'s observer list so
86
111
  * that `subscribe()` (raw stream) and `on()` (named routing) never interfere.
87
112
  *
113
+ * Stored as `InternalHandler` (erased to `unknown` payload) to avoid
114
+ * unevaluable conditional types at the storage boundary. Type safety is
115
+ * enforced at the public `on()` and `dispatch()` call sites.
116
+ *
88
117
  * @private
89
118
  */
90
119
  private readonly namedHandlers__;
@@ -97,20 +126,25 @@ export declare class ChannelSignal<TMap extends Record<string, unknown>> extends
97
126
  * The notification is scheduled as a microtask to ensure non-blocking,
98
127
  * consistent delivery — matching the behavior of `EventSignal`.
99
128
  *
100
- * TypeScript enforces that `payload` matches the type declared for `name`
101
- * in `TMap`. If the payload type is `void` or `undefined`, the argument can
102
- * be omitted entirely.
129
+ * ### Payload enforcement
103
130
  *
104
- * @param name The message name (must be a key of `TMap`).
105
- * @param payload The optional payload for the message.
131
+ * The payload argument is **required** unless the declared type in `TMap` is
132
+ * `void` or `undefined`. Omitting a required payload or passing `undefined`
133
+ * for a non-optional type — is a **compile error**. This prevents accidental
134
+ * `undefined` from propagating into handlers that expect a real value.
106
135
  *
107
- * @example
108
136
  * ```ts
109
- * channel.dispatch('open-drawer', {panel: 'settings'});
110
- * channel.dispatch('close-drawer'); // no payload needed
137
+ * // TMap: { 'add-to-cart': {productId: number}; 'logout': void }
138
+ * channel.dispatch('add-to-cart', {productId: 42}); // required payload
139
+ * channel.dispatch('add-to-cart'); // ❌ compile error
140
+ * channel.dispatch('logout'); // ✅ void — no payload
141
+ * channel.dispatch('logout', undefined); // ✅ also fine
111
142
  * ```
143
+ *
144
+ * @param args Tuple of `[name, payload]` — payload optionality is enforced
145
+ * by `DispatchArgs<TMap, K>` based on the declared type.
112
146
  */
113
- dispatch<K extends keyof TMap>(name: K, payload?: TMap[K]): void;
147
+ dispatch<K extends keyof TMap>(...args: DispatchArgs<TMap, K>): void;
114
148
  /**
115
149
  * Subscribes to a specific named message on this channel.
116
150
  *
@@ -1 +1 @@
1
- {"version":3,"file":"channel-signal.d.ts","sourceRoot":"","sources":["../../src/core/channel-signal.ts"],"names":[],"mappings":"AACA,OAAO,EAAe,KAAK,YAAY,EAAC,MAAM,gBAAgB,CAAC;AAE/D,OAAO,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AAE5C,OAAO,KAAK,EAAC,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,gBAAgB,EAAC,MAAM,YAAY,CAAC;AAIlG;;;;;;;;;GASG;AACH,MAAM,MAAM,cAAc,CAAC,IAAI,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,SAAS,MAAM,IAAI,GAAG,MAAM,IAAI,IAChG,CAAC,SAAS,MAAM,IAAI,GAAG;IAAC,IAAI,EAAE,CAAC,CAAC;IAAC,OAAO,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAA;CAAC,GAAG,KAAK,CAAC;AAE9D;;;;;;GAMG;AACH,MAAM,MAAM,cAAc,CAAC,IAAI,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,SAAS,MAAM,IAAI,IAAI,CACvF,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,GAAG,SAAS,KACzB,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAE1B;;GAEG;AACH,MAAM,WAAW,mBAAoB,SAAQ,YAAY;CAAG;AAI5D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,qBAAa,aAAa,CAAC,IAAI,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAE,SAAQ,UAAU,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;IACvG;;;OAGG;IACH,SAAS,CAAC,OAAO,EAAE,YAAY,CAAC;IAEhC;;;;;;;;OAQG;IACH,OAAO,CAAC,QAAQ,CAAC,eAAe,CACpB;gBAEA,MAAM,EAAE,mBAAmB;IAMvC;;;;;;;;;;;;;;;;;;;;OAoBG;IACI,QAAQ,CAAC,CAAC,SAAS,MAAM,IAAI,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI;IAMvE;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BG;IACI,EAAE,CAAC,CAAC,SAAS,MAAM,IAAI,EAC5B,IAAI,EAAE,CAAC,EACP,OAAO,EAAE,cAAc,CAAC,IAAI,EAAE,CAAC,CAAC,EAChC,OAAO,CAAC,EAAE,IAAI,CAAC,gBAAgB,EAAE,MAAM,CAAC,GACvC,eAAe;IA2BlB;;;;;;;;;;;;;;;;;;OAkBG;IACa,SAAS,CACvB,QAAQ,EAAE,gBAAgB,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,EAChD,OAAO,CAAC,EAAE,gBAAgB,GACzB,eAAe;IAKlB;;;;;;;;OAQG;IACH,OAAO,CAAC,OAAO;IAyBf;;OAEG;IACa,OAAO,IAAI,IAAI;CAIhC"}
1
+ {"version":3,"file":"channel-signal.d.ts","sourceRoot":"","sources":["../../src/core/channel-signal.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,qBAAqB,CAAC;AAEnD,OAAO,EAAe,KAAK,YAAY,EAAC,MAAM,gBAAgB,CAAC;AAE/D,OAAO,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AAE5C,OAAO,KAAK,EAAC,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,gBAAgB,EAAC,MAAM,YAAY,CAAC;AAIlG;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,MAAM,YAAY,CAAC,IAAI,SAAS,MAAM,EAAE,CAAC,SAAS,MAAM,IAAI,IAChE,IAAI,CAAC,CAAC,CAAC,SAAS,IAAI,GAAG,SAAS,GAAG,CAAC,IAAI,EAAE,CAAC,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AAEhG;;;;;;;;GAQG;AACH,MAAM,MAAM,cAAc,CAAC,IAAI,SAAS,MAAM,EAAE,CAAC,SAAS,MAAM,IAAI,GAAG,MAAM,IAAI,IAAI;IAAC,IAAI,EAAE,CAAC,CAAC;IAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,CAAA;CAAC,CAAC;AAEjH;;;;;;;;;;GAUG;AACH,MAAM,MAAM,cAAc,CAAC,IAAI,SAAS,MAAM,EAAE,CAAC,SAAS,MAAM,IAAI,GAAG,MAAM,IAAI,IAAI,CACnF,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,KACb,SAAS,CAAC,IAAI,CAAC,CAAC;AAerB;;GAEG;AACH,MAAM,WAAW,mBAAoB,SAAQ,YAAY;CAAG;AAI5D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,qBAAa,aAAa,CAAC,IAAI,SAAS,MAAM,CAAE,SAAQ,UAAU,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;IACtF;;;OAGG;IACH,SAAS,CAAC,OAAO,EAAE,YAAY,CAAC;IAEhC;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAyE;gBAE7F,MAAM,EAAE,mBAAmB;IAMvC;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;IACI,QAAQ,CAAC,CAAC,SAAS,MAAM,IAAI,EAAE,GAAG,IAAI,EAAE,YAAY,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI;IAO3E;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BG;IACI,EAAE,CAAC,CAAC,SAAS,MAAM,IAAI,EAC5B,IAAI,EAAE,CAAC,EACP,OAAO,EAAE,cAAc,CAAC,IAAI,EAAE,CAAC,CAAC,EAChC,OAAO,CAAC,EAAE,IAAI,CAAC,gBAAgB,EAAE,MAAM,CAAC,GACvC,eAAe;IAyBlB;;;;;;;;;;;;;;;;;;OAkBG;IACa,SAAS,CACvB,QAAQ,EAAE,gBAAgB,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,EAChD,OAAO,CAAC,EAAE,gBAAgB,GACzB,eAAe;IAKlB;;;;;;;;OAQG;IACH,OAAO,CAAC,OAAO;IAyBf;;OAEG;IACa,OAAO,IAAI,IAAI;CAIhC"}
@@ -35,5 +35,5 @@ import type { ChannelSignalConfig } from '../core/channel-signal.js';
35
35
  * appChannel.dispatch('close-drawer');
36
36
  * ```
37
37
  */
38
- export declare function createChannelSignal<TMap extends Record<string, unknown>>(config: ChannelSignalConfig): ChannelSignal<TMap>;
38
+ export declare function createChannelSignal<TMap extends object>(config: ChannelSignalConfig): ChannelSignal<TMap>;
39
39
  //# sourceMappingURL=channel.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"channel.d.ts","sourceRoot":"","sources":["../../src/creators/channel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,aAAa,EAAC,MAAM,2BAA2B,CAAC;AAExD,OAAO,KAAK,EAAC,mBAAmB,EAAC,MAAM,2BAA2B,CAAC;AAEnE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACtE,MAAM,EAAE,mBAAmB,GAC1B,aAAa,CAAC,IAAI,CAAC,CAErB"}
1
+ {"version":3,"file":"channel.d.ts","sourceRoot":"","sources":["../../src/creators/channel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,aAAa,EAAC,MAAM,2BAA2B,CAAC;AAExD,OAAO,KAAK,EAAC,mBAAmB,EAAC,MAAM,2BAA2B,CAAC;AAEnE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,SAAS,MAAM,EAAE,MAAM,EAAE,mBAAmB,GAAG,aAAa,CAAC,IAAI,CAAC,CAEzG"}
package/dist/main.js CHANGED
@@ -1,5 +1,5 @@
1
- /* 📦 @alwatr/signal v9.13.0 */
2
- class B{config_;name;priorityObservers_=new Set;observers_=new Set;isDestroyed__=!1;get isDestroyed(){return this.isDestroyed__}constructor(G){this.config_=G;this.name=G.name}removeObserver_(G){if(this.logger_.logMethod?.("removeObserver_"),this.isDestroyed__){this.logger_.incident?.("removeObserver_","remove_observer_on_destroyed_signal");return}this.priorityObservers_.delete(G),this.observers_.delete(G)}subscribe(G,H){this.logger_.logMethodArgs?.("subscribe.base",H),this.checkDestroyed_();let Q={callback:G,options:H};if(H?.priority)this.priorityObservers_.add(Q);else this.observers_.add(Q);return{unsubscribe:()=>this.removeObserver_(Q)}}notify_(G){if(this.logger_.logMethodArgs?.("notify_",G),this.isDestroyed__){this.logger_.incident?.("notify_","notify_on_destroyed_signal");return}for(let H of this.priorityObservers_)this.executeObserver__(H,G);for(let H of this.observers_)this.executeObserver__(H,G)}executeObserver__(G,H){if(G.options?.once)this.removeObserver_(G);try{let Q=G.callback(H);if(Q instanceof Promise)Q.catch((X)=>this.logger_.error("notify_","async_callback_failed",X,{observer:G}))}catch(Q){this.logger_.error("notify_","sync_callback_failed",Q)}}pendingRejects__=new Set;untilNext(){return this.logger_.logMethod?.("untilNext"),this.checkDestroyed_(),new Promise((G,H)=>{this.pendingRejects__.add(H),this.subscribe((Q)=>{this.pendingRejects__.delete(H),G(Q)},{once:!0,priority:!0,receivePrevious:!1})})}destroy(){if(this.logger_.logMethod?.("destroy"),this.isDestroyed__){this.logger_.incident?.("destroy_","double_destroy_attempt");return}if(this.isDestroyed__=!0,this.pendingRejects__.size){let G=Error("signal_destroyed");for(let H of this.pendingRejects__)H(G);this.pendingRejects__.clear()}this.priorityObservers_.clear(),this.observers_.clear(),this.config_.onDestroy?.(),this.config_=null}checkDestroyed_(){if(this.isDestroyed__)throw this.logger_.accident("checkDestroyed_","attempt_to_use_destroyed_signal"),Error(`Cannot interact with a destroyed signal (id: ${this.name})`)}}import{delay as _}from"@alwatr/delay";import{createLogger as U}from"@alwatr/logger";class J extends B{logger_;constructor(G){super(G);this.logger_=U(`event-signal:${this.name}`),this.logger_.logMethod?.("constructor")}dispatch(G){this.logger_.logMethodArgs?.("dispatch",{payload:G}),this.checkDestroyed_(),_.nextMicrotask().then(()=>this.notify_(G))}}import{delay as M}from"@alwatr/delay";import{createLogger as E}from"@alwatr/logger";class K extends B{value__;logger_;constructor(G){super({name:G.name,onDestroy:G.onDestroy});this.logger_=E(`state-signal:${this.name}`),this.value__=G.initialValue,this.logger_.logMethodArgs?.("constructor",{initialValue:this.value__})}get(){return this.checkDestroyed_(),this.value__}set(G){if(this.logger_.logMethodArgs?.("set",{newValue:G}),Object.is(this.value__,G)&&(typeof G!=="object"||G===null))return;this.value__=G,this.notifyChange()}notifyChange(){this.logger_.logMethod?.("notifyChange"),this.checkDestroyed_(),M.nextMicrotask().then(()=>this.notify_(this.value__))}update(G){this.checkDestroyed_();let H=G(this.value__);this.logger_.logMethodFull?.("update",this.value__,H),this.set(H)}subscribe(G,H={}){if(this.logger_.logMethodArgs?.("subscribe",H),this.checkDestroyed_(),H.receivePrevious!==!1){if(M.nextMicrotask().then(()=>{this.logger_.logStep?.("subscribe","immediate_callback"),G(this.value__)}).catch((Q)=>this.logger_.error("subscribe","immediate_callback_failed",Q)),H.once)return{unsubscribe:()=>{}}}return super.subscribe(G,H)}destroy(){this.value__=null,super.destroy()}asReadonly(){return this}}import{delay as x}from"@alwatr/delay";import{createLogger as D}from"@alwatr/logger";class R{config_;name;logger_;internalSignal_;dependencySubscriptions__=[];isRecalculating__=!1;constructor(G){this.config_=G;this.name=G.name,this.logger_=D(`computed-signal:${this.name}`),this.recalculate_=this.recalculate_.bind(this),this.logger_.logMethod?.("constructor"),this.internalSignal_=new K({name:`compute-${this.name}_`,initialValue:this.config_.get()});for(let H of G.deps)this.logger_.logStep?.("constructor","subscribing_to_dependency",{signal:H.name}),this.dependencySubscriptions__.push(H.subscribe(this.recalculate_,{receivePrevious:!1}))}get(){return this.internalSignal_.get()}get isDestroyed(){return this.internalSignal_.isDestroyed}subscribe(G,H){return this.internalSignal_.subscribe(G,H)}untilNext(){return this.internalSignal_.untilNext()}destroy(){if(this.logger_.logMethod?.("destroy"),this.isDestroyed){this.logger_.incident?.("destroy","already_destroyed");return}for(let G of this.dependencySubscriptions__)G.unsubscribe();this.dependencySubscriptions__.length=0,this.internalSignal_.destroy(),this.config_.onDestroy?.(),this.config_=null}async recalculate_(){if(this.logger_.logMethod?.("recalculate_"),this.internalSignal_.isDestroyed){this.logger_.incident?.("recalculate_","recalculate_on_destroyed_signal");return}if(this.isRecalculating__){this.logger_.logStep?.("recalculate_","skipping_recalculation_already_scheduled");return}this.isRecalculating__=!0;try{if(await x.nextMacrotask(),this.isDestroyed){this.logger_.incident?.("recalculate_","destroyed_during_delay"),this.isRecalculating__=!1;return}this.logger_.logStep?.("recalculate_","recalculating_value"),this.internalSignal_.set(this.config_.get())}catch(G){this.logger_.error("recalculate_","recalculation_failed",G)}this.isRecalculating__=!1}}import{delay as I}from"@alwatr/delay";import{createLogger as N}from"@alwatr/logger";class z{config_;name;logger_;dependencySubscriptions__=[];isRunning__=!1;isDestroyed__=!1;get isDestroyed(){return this.isDestroyed__}constructor(G){this.config_=G;this.name=G.name??`[${G.deps.map((H)=>H.name).join(", ")}]`,this.logger_=N(`effect-signal:${this.name}`),this.scheduleExecution_=this.scheduleExecution_.bind(this),this.logger_.logMethod?.("constructor");for(let H of G.deps)this.logger_.logStep?.("constructor","subscribing_to_dependency",{signal:H.name}),this.dependencySubscriptions__.push(H.subscribe(this.scheduleExecution_,{receivePrevious:!1}));if(G.runImmediately===!0)this.logger_.logStep?.("constructor","scheduling_initial_execution"),this.scheduleExecution_()}async scheduleExecution_(){if(this.logger_.logMethod?.("scheduleExecution_"),this.isDestroyed__){this.logger_.incident?.("scheduleExecution_","schedule_execution_on_destroyed_signal");return}if(this.isRunning__){this.logger_.logStep?.("scheduleExecution_","skipped_because_already_running");return}this.isRunning__=!0;try{if(await I.nextMacrotask(),this.isDestroyed__){this.logger_.incident?.("scheduleExecution_","destroyed_during_delay"),this.isRunning__=!1;return}this.logger_.logStep?.("scheduleExecution_","executing_effect"),await this.config_.run()}catch(G){this.logger_.error("scheduleExecution_","effect_failed",G)}this.isRunning__=!1}destroy(){if(this.logger_.logMethod?.("destroy"),this.isDestroyed__){this.logger_.incident?.("destroy","already_destroyed");return}this.isDestroyed__=!0;for(let G of this.dependencySubscriptions__)G.unsubscribe();this.dependencySubscriptions__.length=0,this.config_.onDestroy?.(),this.config_=null}}import{createDebouncer as A}from"@alwatr/debounce";import{createLocalStorageProvider as k}from"@alwatr/local-storage";class L extends K{storageProvider__;storageDebouncer__;storageSyncSubscription__;constructor(G){let{name:H,storageKey:Q=H,saveDebounceDelay:X=500,initialValue:Y,onDestroy:Z,schemaVersion:W}=G,q=k({name:Q,schemaVersion:W});super({name:H,initialValue:q.read()??Y,onDestroy:Z});this.logger_.logMethodArgs?.("constructor",G),this.storageProvider__=q,this.storageDebouncer__=A({delay:X,leading:!1,trailing:!0,thisContext:this,func:this.syncStorage__}),this.storageSyncSubscription__=this.subscribe(this.storageDebouncer__.trigger,{receivePrevious:!1})}syncStorage__(G){this.logger_.logMethodArgs?.("syncStorage__",G),this.storageProvider__.write(G)}remove(){this.checkDestroyed_(),this.logger_.logMethod?.("remove"),this.storageProvider__.remove()}destroy(){this.logger_.logMethod?.("destroy"),this.storageDebouncer__.flush(),this.storageSyncSubscription__.unsubscribe(),super.destroy()}}import{createDebouncer as V}from"@alwatr/debounce";import{createSessionStorageProvider as j}from"@alwatr/session-storage";class O extends K{storageProvider__;storageDebouncer__;storageSyncSubscription__;constructor(G){let{name:H,storageKey:Q=H,saveDebounceDelay:X=500,initialValue:Y,onDestroy:Z}=G,W=j({name:Q});super({name:H,initialValue:W.read()??Y,onDestroy:Z});this.logger_.logMethodArgs?.("constructor",G),this.storageProvider__=W,this.storageDebouncer__=V({delay:X,leading:!1,trailing:!0,thisContext:this,func:this.syncStorage__}),this.storageSyncSubscription__=this.subscribe(this.storageDebouncer__.trigger,{receivePrevious:!1})}syncStorage__(G){this.logger_.logMethodArgs?.("syncStorage__",G),this.storageProvider__.write(G)}remove(){this.checkDestroyed_(),this.logger_.logMethod?.("remove"),this.storageProvider__.remove()}destroy(){this.logger_.logMethod?.("destroy"),this.storageDebouncer__.flush(),this.storageSyncSubscription__.unsubscribe(),super.destroy()}}import{delay as C}from"@alwatr/delay";import{createLogger as T}from"@alwatr/logger";class $ extends B{logger_;namedHandlers__=new Map;constructor(G){super(G);this.logger_=T(`channel-signal:${this.name}`),this.logger_.logMethod?.("constructor")}dispatch(G,H){this.logger_.logMethodArgs?.("dispatch",{name:G,payload:H}),this.checkDestroyed_(),C.nextMicrotask().then(()=>this.route__(G,H))}on(G,H,Q){this.logger_.logMethodArgs?.("on",{name:G}),this.checkDestroyed_();let X=this.namedHandlers__.get(G);if(!X)X=new Set,this.namedHandlers__.set(G,X);let Y={handler:H,once:Q?.once??!1};return X.add(Y),{unsubscribe:()=>{if(X.delete(Y),X.size===0)this.namedHandlers__.delete(G)}}}subscribe(G,H){return this.logger_.logMethodArgs?.("subscribe",H),super.subscribe(G,H)}route__(G,H){if(this.isDestroyed)return;let Q=this.namedHandlers__.get(G);if(Q?.size)for(let X of Q){if(X.once){if(Q.delete(X),Q.size===0)this.namedHandlers__.delete(G)}try{let Y=X.handler(H);if(Y instanceof Promise)Y.catch((Z)=>this.logger_.error("route__","async_named_handler_failed",Z))}catch(Y){this.logger_.error("route__","sync_named_handler_failed",Y)}}this.notify_({name:G,payload:H})}destroy(){this.namedHandlers__.clear(),super.destroy()}}function WG(G){return new J(G)}function P(G){return new K(G)}function F(G){return new R(G)}function OG(G){return new z(G)}function PG(G){return new L(G)}function EG(G){return new O(G)}function IG(G){return new $(G)}import{createDebouncer as w}from"@alwatr/debounce";function jG(G,H){let Q=H.name??`${G.name}-debounced`,X=new K({name:`${Q}-internal`,initialValue:G.get()}),Y=w({...H,thisContext:X,func:X.set}),Z=G.subscribe(Y.trigger,{receivePrevious:!1});return F({name:Q,deps:[X],get:()=>X.get(),onDestroy:()=>{if(X.isDestroyed)return;Z.unsubscribe(),Y.cancel(),X.destroy(),H.onDestroy?.(),H=null}})}function vG(G,H,Q=`${G.name}-filtered`){let X=G.get(),Y=H(X)?X:void 0,Z=P({name:`${Q}-internal`,initialValue:Y}),W=G.subscribe((q)=>{if(H(q))Z.set(q)});return F({name:Q,deps:[Z],get:()=>Z.get(),onDestroy:()=>{W.unsubscribe(),Z.destroy()}})}function SG(G,H,Q=`${G.name}-mapped`){return F({name:Q,deps:[G],get:()=>H(G.get())})}export{P as createStateSignal,EG as createSessionStateSignal,PG as createPersistentStateSignal,SG as createMappedSignal,vG as createFilteredSignal,WG as createEventSignal,OG as createEffect,jG as createDebouncedSignal,F as createComputedSignal,IG as createChannelSignal,K as StateSignal,B as SignalBase,O as SessionStateSignal,L as PersistentStateSignal,J as EventSignal,z as EffectSignal,R as ComputedSignal,$ as ChannelSignal};
1
+ /* 📦 @alwatr/signal v9.14.0 */
2
+ class B{config_;name;priorityObservers_=new Set;observers_=new Set;isDestroyed__=!1;get isDestroyed(){return this.isDestroyed__}constructor(G){this.config_=G;this.name=G.name}removeObserver_(G){if(this.logger_.logMethod?.("removeObserver_"),this.isDestroyed__){this.logger_.incident?.("removeObserver_","remove_observer_on_destroyed_signal");return}this.priorityObservers_.delete(G),this.observers_.delete(G)}subscribe(G,H){this.logger_.logMethodArgs?.("subscribe.base",H),this.checkDestroyed_();let Q={callback:G,options:H};if(H?.priority)this.priorityObservers_.add(Q);else this.observers_.add(Q);return{unsubscribe:()=>this.removeObserver_(Q)}}notify_(G){if(this.logger_.logMethodArgs?.("notify_",G),this.isDestroyed__){this.logger_.incident?.("notify_","notify_on_destroyed_signal");return}for(let H of this.priorityObservers_)this.executeObserver__(H,G);for(let H of this.observers_)this.executeObserver__(H,G)}executeObserver__(G,H){if(G.options?.once)this.removeObserver_(G);try{let Q=G.callback(H);if(Q instanceof Promise)Q.catch((X)=>this.logger_.error("notify_","async_callback_failed",X,{observer:G}))}catch(Q){this.logger_.error("notify_","sync_callback_failed",Q)}}pendingRejects__=new Set;untilNext(){return this.logger_.logMethod?.("untilNext"),this.checkDestroyed_(),new Promise((G,H)=>{this.pendingRejects__.add(H),this.subscribe((Q)=>{this.pendingRejects__.delete(H),G(Q)},{once:!0,priority:!0,receivePrevious:!1})})}destroy(){if(this.logger_.logMethod?.("destroy"),this.isDestroyed__){this.logger_.incident?.("destroy_","double_destroy_attempt");return}if(this.isDestroyed__=!0,this.pendingRejects__.size){let G=Error("signal_destroyed");for(let H of this.pendingRejects__)H(G);this.pendingRejects__.clear()}this.priorityObservers_.clear(),this.observers_.clear(),this.config_.onDestroy?.(),this.config_=null}checkDestroyed_(){if(this.isDestroyed__)throw this.logger_.accident("checkDestroyed_","attempt_to_use_destroyed_signal"),Error(`Cannot interact with a destroyed signal (id: ${this.name})`)}}import{delay as _}from"@alwatr/delay";import{createLogger as U}from"@alwatr/logger";class J extends B{logger_;constructor(G){super(G);this.logger_=U(`event-signal:${this.name}`),this.logger_.logMethod?.("constructor")}dispatch(G){this.logger_.logMethodArgs?.("dispatch",{payload:G}),this.checkDestroyed_(),_.nextMicrotask().then(()=>this.notify_(G))}}import{delay as M}from"@alwatr/delay";import{createLogger as E}from"@alwatr/logger";class K extends B{value__;logger_;constructor(G){super({name:G.name,onDestroy:G.onDestroy});this.logger_=E(`state-signal:${this.name}`),this.value__=G.initialValue,this.logger_.logMethodArgs?.("constructor",{initialValue:this.value__})}get(){return this.checkDestroyed_(),this.value__}set(G){if(this.logger_.logMethodArgs?.("set",{newValue:G}),Object.is(this.value__,G)&&(typeof G!=="object"||G===null))return;this.value__=G,this.notifyChange()}notifyChange(){this.logger_.logMethod?.("notifyChange"),this.checkDestroyed_(),M.nextMicrotask().then(()=>this.notify_(this.value__))}update(G){this.checkDestroyed_();let H=G(this.value__);this.logger_.logMethodFull?.("update",this.value__,H),this.set(H)}subscribe(G,H={}){if(this.logger_.logMethodArgs?.("subscribe",H),this.checkDestroyed_(),H.receivePrevious!==!1){if(M.nextMicrotask().then(()=>{this.logger_.logStep?.("subscribe","immediate_callback"),G(this.value__)}).catch((Q)=>this.logger_.error("subscribe","immediate_callback_failed",Q)),H.once)return{unsubscribe:()=>{}}}return super.subscribe(G,H)}destroy(){this.value__=null,super.destroy()}asReadonly(){return this}}import{delay as x}from"@alwatr/delay";import{createLogger as D}from"@alwatr/logger";class R{config_;name;logger_;internalSignal_;dependencySubscriptions__=[];isRecalculating__=!1;constructor(G){this.config_=G;this.name=G.name,this.logger_=D(`computed-signal:${this.name}`),this.recalculate_=this.recalculate_.bind(this),this.logger_.logMethod?.("constructor"),this.internalSignal_=new K({name:`compute-${this.name}_`,initialValue:this.config_.get()});for(let H of G.deps)this.logger_.logStep?.("constructor","subscribing_to_dependency",{signal:H.name}),this.dependencySubscriptions__.push(H.subscribe(this.recalculate_,{receivePrevious:!1}))}get(){return this.internalSignal_.get()}get isDestroyed(){return this.internalSignal_.isDestroyed}subscribe(G,H){return this.internalSignal_.subscribe(G,H)}untilNext(){return this.internalSignal_.untilNext()}destroy(){if(this.logger_.logMethod?.("destroy"),this.isDestroyed){this.logger_.incident?.("destroy","already_destroyed");return}for(let G of this.dependencySubscriptions__)G.unsubscribe();this.dependencySubscriptions__.length=0,this.internalSignal_.destroy(),this.config_.onDestroy?.(),this.config_=null}async recalculate_(){if(this.logger_.logMethod?.("recalculate_"),this.internalSignal_.isDestroyed){this.logger_.incident?.("recalculate_","recalculate_on_destroyed_signal");return}if(this.isRecalculating__){this.logger_.logStep?.("recalculate_","skipping_recalculation_already_scheduled");return}this.isRecalculating__=!0;try{if(await x.nextMacrotask(),this.isDestroyed){this.logger_.incident?.("recalculate_","destroyed_during_delay"),this.isRecalculating__=!1;return}this.logger_.logStep?.("recalculate_","recalculating_value"),this.internalSignal_.set(this.config_.get())}catch(G){this.logger_.error("recalculate_","recalculation_failed",G)}this.isRecalculating__=!1}}import{delay as I}from"@alwatr/delay";import{createLogger as N}from"@alwatr/logger";class z{config_;name;logger_;dependencySubscriptions__=[];isRunning__=!1;isDestroyed__=!1;get isDestroyed(){return this.isDestroyed__}constructor(G){this.config_=G;this.name=G.name??`[${G.deps.map((H)=>H.name).join(", ")}]`,this.logger_=N(`effect-signal:${this.name}`),this.scheduleExecution_=this.scheduleExecution_.bind(this),this.logger_.logMethod?.("constructor");for(let H of G.deps)this.logger_.logStep?.("constructor","subscribing_to_dependency",{signal:H.name}),this.dependencySubscriptions__.push(H.subscribe(this.scheduleExecution_,{receivePrevious:!1}));if(G.runImmediately===!0)this.logger_.logStep?.("constructor","scheduling_initial_execution"),this.scheduleExecution_()}async scheduleExecution_(){if(this.logger_.logMethod?.("scheduleExecution_"),this.isDestroyed__){this.logger_.incident?.("scheduleExecution_","schedule_execution_on_destroyed_signal");return}if(this.isRunning__){this.logger_.logStep?.("scheduleExecution_","skipped_because_already_running");return}this.isRunning__=!0;try{if(await I.nextMacrotask(),this.isDestroyed__){this.logger_.incident?.("scheduleExecution_","destroyed_during_delay"),this.isRunning__=!1;return}this.logger_.logStep?.("scheduleExecution_","executing_effect"),await this.config_.run()}catch(G){this.logger_.error("scheduleExecution_","effect_failed",G)}this.isRunning__=!1}destroy(){if(this.logger_.logMethod?.("destroy"),this.isDestroyed__){this.logger_.incident?.("destroy","already_destroyed");return}this.isDestroyed__=!0;for(let G of this.dependencySubscriptions__)G.unsubscribe();this.dependencySubscriptions__.length=0,this.config_.onDestroy?.(),this.config_=null}}import{createDebouncer as A}from"@alwatr/debounce";import{createLocalStorageProvider as k}from"@alwatr/local-storage";class L extends K{storageProvider__;storageDebouncer__;storageSyncSubscription__;constructor(G){let{name:H,storageKey:Q=H,saveDebounceDelay:X=500,initialValue:Y,onDestroy:Z,schemaVersion:W}=G,q=k({name:Q,schemaVersion:W});super({name:H,initialValue:q.read()??Y,onDestroy:Z});this.logger_.logMethodArgs?.("constructor",G),this.storageProvider__=q,this.storageDebouncer__=A({delay:X,leading:!1,trailing:!0,thisContext:this,func:this.syncStorage__}),this.storageSyncSubscription__=this.subscribe(this.storageDebouncer__.trigger,{receivePrevious:!1})}syncStorage__(G){this.logger_.logMethodArgs?.("syncStorage__",G),this.storageProvider__.write(G)}remove(){this.checkDestroyed_(),this.logger_.logMethod?.("remove"),this.storageProvider__.remove()}destroy(){this.logger_.logMethod?.("destroy"),this.storageDebouncer__.flush(),this.storageSyncSubscription__.unsubscribe(),super.destroy()}}import{createDebouncer as V}from"@alwatr/debounce";import{createSessionStorageProvider as j}from"@alwatr/session-storage";class O extends K{storageProvider__;storageDebouncer__;storageSyncSubscription__;constructor(G){let{name:H,storageKey:Q=H,saveDebounceDelay:X=500,initialValue:Y,onDestroy:Z}=G,W=j({name:Q});super({name:H,initialValue:W.read()??Y,onDestroy:Z});this.logger_.logMethodArgs?.("constructor",G),this.storageProvider__=W,this.storageDebouncer__=V({delay:X,leading:!1,trailing:!0,thisContext:this,func:this.syncStorage__}),this.storageSyncSubscription__=this.subscribe(this.storageDebouncer__.trigger,{receivePrevious:!1})}syncStorage__(G){this.logger_.logMethodArgs?.("syncStorage__",G),this.storageProvider__.write(G)}remove(){this.checkDestroyed_(),this.logger_.logMethod?.("remove"),this.storageProvider__.remove()}destroy(){this.logger_.logMethod?.("destroy"),this.storageDebouncer__.flush(),this.storageSyncSubscription__.unsubscribe(),super.destroy()}}import{delay as C}from"@alwatr/delay";import{createLogger as T}from"@alwatr/logger";class $ extends B{logger_;namedHandlers__=new Map;constructor(G){super(G);this.logger_=T(`channel-signal:${this.name}`),this.logger_.logMethod?.("constructor")}dispatch(...G){let[H,Q]=G;this.logger_.logMethodArgs?.("dispatch",{name:H,payload:Q}),this.checkDestroyed_(),C.nextMicrotask().then(()=>this.route__(H,Q))}on(G,H,Q){this.logger_.logMethodArgs?.("on",{name:G}),this.checkDestroyed_();let X=this.namedHandlers__.get(G);if(!X)X=new Set,this.namedHandlers__.set(G,X);let Y={handler:H,once:Q?.once??!1};return X.add(Y),{unsubscribe:()=>{if(X.delete(Y),X.size===0)this.namedHandlers__.delete(G)}}}subscribe(G,H){return this.logger_.logMethodArgs?.("subscribe",H),super.subscribe(G,H)}route__(G,H){if(this.isDestroyed)return;let Q=this.namedHandlers__.get(G);if(Q?.size)for(let X of Q){if(X.once){if(Q.delete(X),Q.size===0)this.namedHandlers__.delete(G)}try{let Y=X.handler(H);if(Y instanceof Promise)Y.catch((Z)=>this.logger_.error("route__","async_named_handler_failed",Z))}catch(Y){this.logger_.error("route__","sync_named_handler_failed",Y)}}this.notify_({name:G,payload:H})}destroy(){this.namedHandlers__.clear(),super.destroy()}}function WG(G){return new J(G)}function P(G){return new K(G)}function F(G){return new R(G)}function OG(G){return new z(G)}function PG(G){return new L(G)}function EG(G){return new O(G)}function IG(G){return new $(G)}import{createDebouncer as w}from"@alwatr/debounce";function jG(G,H){let Q=H.name??`${G.name}-debounced`,X=new K({name:`${Q}-internal`,initialValue:G.get()}),Y=w({...H,thisContext:X,func:X.set}),Z=G.subscribe(Y.trigger,{receivePrevious:!1});return F({name:Q,deps:[X],get:()=>X.get(),onDestroy:()=>{if(X.isDestroyed)return;Z.unsubscribe(),Y.cancel(),X.destroy(),H.onDestroy?.(),H=null}})}function vG(G,H,Q=`${G.name}-filtered`){let X=G.get(),Y=H(X)?X:void 0,Z=P({name:`${Q}-internal`,initialValue:Y}),W=G.subscribe((q)=>{if(H(q))Z.set(q)});return F({name:Q,deps:[Z],get:()=>Z.get(),onDestroy:()=>{W.unsubscribe(),Z.destroy()}})}function SG(G,H,Q=`${G.name}-mapped`){return F({name:Q,deps:[G],get:()=>H(G.get())})}export{P as createStateSignal,EG as createSessionStateSignal,PG as createPersistentStateSignal,SG as createMappedSignal,vG as createFilteredSignal,WG as createEventSignal,OG as createEffect,jG as createDebouncedSignal,F as createComputedSignal,IG as createChannelSignal,K as StateSignal,B as SignalBase,O as SessionStateSignal,L as PersistentStateSignal,J as EventSignal,z as EffectSignal,R as ComputedSignal,$ as ChannelSignal};
3
3
 
4
- //# debugId=39558698A04B4C5764756E2164756E21
4
+ //# debugId=37136463C45B4D5764756E2164756E21
5
5
  //# sourceMappingURL=main.js.map
package/dist/main.js.map CHANGED
@@ -9,19 +9,19 @@
9
9
  "import { delay } from '@alwatr/delay';\nimport { createLogger, type AlwatrLogger } from '@alwatr/logger';\n\nimport type { EffectSignalConfig, IEffectSignal, SubscribeResult } from '../type.js';\n\n/**\n * Manages a side-effect that runs in response to changes in dependency signals.\n *\n * `EffectSignal` is designed for running logic that interacts with the \"outside world\"—such as\n * logging, network requests, or DOM manipulation—whenever its dependencies are updated.\n * It encapsulates the subscription and cleanup logic, providing a robust and memory-safe\n * way to handle reactive side-effects.\n *\n * A key feature is its lifecycle management: an `EffectSignal` **must** be destroyed when no longer\n * needed to prevent memory leaks and stop the effect from running unnecessarily.\n *\n * @implements {IEffectSignal}\n *\n * @example\n * // --- Create dependency signals ---\n * const counter = new StateSignal({ initialValue: 0, name: 'counter' });\n * const user = new StateSignal({ initialValue: 'guest', name: 'user' });\n *\n * // --- Create an effect ---\n * const analyticsEffect = new EffectSignal({\n * name: 'analytics-effect',\n * deps: [counter, user],\n * run: () => {\n * console.log(`Analytics: User '${user.get()}' clicked ${counter.get()} times.`);\n * },\n * runImmediately: true, // Optional: run once on creation\n * });\n * // Immediately logs: \"Analytics: User 'guest' clicked 0 times.\"\n *\n * // --- Trigger the effect by updating a dependency ---\n * counter.set(1);\n * // After a macrotask, logs: \"Analytics: User 'guest' clicked 1 times.\"\n *\n * // --- IMPORTANT: Clean up when the effect is no longer needed ---\n * analyticsEffect.destroy();\n *\n * // Further updates will not trigger the effect.\n * counter.set(2); // Nothing is logged.\n */\nexport class EffectSignal implements IEffectSignal {\n /**\n * The unique identifier for this signal instance.\n */\n public readonly name: string;\n\n /**\n * The logger instance for this signal.\n * @protected\n */\n protected readonly logger_: AlwatrLogger;\n\n /**\n * A list of subscriptions to dependency signals.\n * @private\n */\n private readonly dependencySubscriptions__: SubscribeResult[] = [];\n\n /**\n * A flag to prevent concurrent executions of the effect.\n * @private\n */\n private isRunning__ = false;\n\n /**\n * A flag indicating whether the effect has been destroyed.\n * @private\n */\n private isDestroyed__ = false;\n\n /**\n * Indicates whether the effect signal has been destroyed.\n * A destroyed signal will no longer execute its effect and cannot be reused.\n *\n * @returns `true` if the signal is destroyed, `false` otherwise.\n */\n public get isDestroyed(): boolean {\n return this.isDestroyed__;\n }\n\n constructor(protected config_: EffectSignalConfig) {\n this.name = config_.name ?? `[${config_.deps.map((dep) => dep.name).join(', ')}]`;\n this.logger_ = createLogger(`effect-signal:${this.name}`);\n this.scheduleExecution_ = this.scheduleExecution_.bind(this);\n\n this.logger_.logMethod?.('constructor');\n\n // Subscribe to all dependencies. We don't need the previous value,\n // as the `runImmediately` option controls the initial execution.\n for (const signal of config_.deps) {\n this.logger_.logStep?.('constructor', 'subscribing_to_dependency', { signal: signal.name });\n this.dependencySubscriptions__.push(signal.subscribe(this.scheduleExecution_, { receivePrevious: false }));\n }\n\n // Run the effect immediately if requested.\n if (config_.runImmediately === true) {\n this.logger_.logStep?.('constructor', 'scheduling_initial_execution');\n // We don't need to await this, let it run in the background.\n void this.scheduleExecution_();\n }\n }\n\n /**\n * Schedules the execution of the effect's `run` function.\n *\n * This method batches updates using a macrotask (`delay.nextMacrotask`) to ensure the\n * `run` function executes only once per event loop tick, even if multiple\n * dependencies change simultaneously.\n * @protected\n */\n protected async scheduleExecution_(): Promise<void> {\n this.logger_.logMethod?.('scheduleExecution_');\n\n if (this.isDestroyed__) {\n this.logger_.incident?.('scheduleExecution_', 'schedule_execution_on_destroyed_signal');\n return;\n }\n if (this.isRunning__) {\n // If an execution is already scheduled, do nothing.\n this.logger_.logStep?.('scheduleExecution_', 'skipped_because_already_running');\n return;\n }\n\n this.isRunning__ = true;\n\n try {\n // Wait for the next macrotask to batch simultaneous updates.\n await delay.nextMacrotask();\n if (this.isDestroyed__) {\n this.logger_.incident?.('scheduleExecution_', 'destroyed_during_delay');\n this.isRunning__ = false;\n return;\n }\n\n this.logger_.logStep?.('scheduleExecution_', 'executing_effect');\n await this.config_.run();\n }\n catch (err) {\n this.logger_.error('scheduleExecution_', 'effect_failed', err);\n }\n\n // Reset the flag after the current execution is complete.\n this.isRunning__ = false;\n }\n\n /**\n * Permanently disposes of the effect signal.\n *\n * This is a critical cleanup step. It unsubscribes from all dependency signals,\n * stopping any future executions of the effect and allowing it to be garbage collected.\n * Failure to call `destroy()` will result in memory leaks and potentially unwanted side effects.\n */\n public destroy(): void {\n this.logger_.logMethod?.('destroy');\n\n if (this.isDestroyed__) {\n this.logger_.incident?.('destroy', 'already_destroyed');\n return;\n }\n\n this.isDestroyed__ = true;\n\n // Unsubscribe from all upstream dependencies.\n for (const subscription of this.dependencySubscriptions__) {\n subscription.unsubscribe();\n }\n this.dependencySubscriptions__.length = 0; // Clear the array of subscriptions.\n\n this.config_.onDestroy?.(); // Call the optional onDestroy callback.\n this.config_ = null as unknown as EffectSignalConfig; // Release config closure.\n }\n}\n",
10
10
  "import {createDebouncer} from '@alwatr/debounce';\nimport {createLocalStorageProvider} from '@alwatr/local-storage';\n\nimport {StateSignal} from './state-signal.js';\n\nimport type {PersistentStateSignalConfig} from '../type.js';\nimport type {LocalStorageProvider} from '@alwatr/local-storage';\n\n/**\n * A stateful signal that persists its value in the browser's localStorage.\n *\n * It extends the functionality of a standard `StateSignal` by automatically reading\n * its initial value from localStorage and writing back any subsequent changes.\n *\n * @template T The type of the state it holds.\n */\nexport class PersistentStateSignal<T> extends StateSignal<T> {\n /**\n * The underlying storage provider instance.\n * @private\n */\n private readonly storageProvider__: LocalStorageProvider<T>;\n\n /**\n * Debouncer to limit how often we write to localStorage.\n * @private\n */\n private readonly storageDebouncer__;\n\n /**\n * The subscription to the signal's own changes to sync with storage.\n * We subscribe to our own signal. When the value is set from anywhere,\n * this listener will trigger and write it to localStorage.\n * @private\n */\n private readonly storageSyncSubscription__;\n\n constructor(config: PersistentStateSignalConfig<T>) {\n const {name, storageKey = name, saveDebounceDelay = 500, initialValue, onDestroy, schemaVersion} = config;\n\n const storageProvider = createLocalStorageProvider<T>({\n name: storageKey,\n schemaVersion,\n });\n\n super({\n name,\n initialValue: storageProvider.read() ?? initialValue,\n onDestroy,\n });\n\n this.logger_.logMethodArgs?.('constructor', config);\n\n this.storageProvider__ = storageProvider;\n\n this.storageDebouncer__ = createDebouncer({\n delay: saveDebounceDelay,\n leading: false,\n trailing: true,\n thisContext: this,\n func: this.syncStorage__,\n });\n\n this.storageSyncSubscription__ = this.subscribe(this.storageDebouncer__.trigger, {receivePrevious: false});\n }\n\n /**\n * Syncs the new value to storage.\n * @param newValue The new value to sync to storage.\n */\n private syncStorage__(newValue: T): void {\n this.logger_.logMethodArgs?.('syncStorage__', newValue);\n this.storageProvider__.write(newValue);\n }\n\n /**\n * Removes the value from localStorage.\n * This provides a clean way to clear persisted data.\n */\n public remove(): void {\n this.checkDestroyed_();\n this.logger_.logMethod?.('remove');\n // Remove from storage.\n this.storageProvider__.remove();\n }\n\n /**\n * Overrides the destroy method to also clean up the storage sync subscription.\n */\n public override destroy(): void {\n this.logger_.logMethod?.('destroy');\n // Flush any pending storage writes before destroying.\n this.storageDebouncer__.flush();\n // Unsubscribe from the sync listener to prevent memory leaks.\n this.storageSyncSubscription__.unsubscribe();\n super.destroy();\n }\n}\n",
11
11
  "import {createDebouncer} from '@alwatr/debounce';\nimport {createSessionStorageProvider} from '@alwatr/session-storage';\n\nimport {StateSignal} from './state-signal.js';\n\nimport type {SessionStateSignalConfig} from '../type.js';\nimport type {SessionStorageProvider} from '@alwatr/session-storage';\n\n/**\n * A stateful signal that persists its value in the browser's `sessionStorage`.\n *\n * It extends `StateSignal` by automatically reading its initial value from `sessionStorage`\n * and writing back any subsequent changes. Unlike `PersistentStateSignal`, the data is cleared\n * automatically when the browser tab or window is closed — it does not survive full page reloads\n * in a new session.\n *\n * This is ideal for transient UI state that should survive soft navigations and refreshes\n * within the same browser tab (e.g., wizard steps, unsaved form drafts, scroll position).\n *\n * @template T The type of the state it holds. Must be JSON-serializable.\n *\n * @example\n * ```typescript\n * import {SessionStateSignal} from '@alwatr/signal';\n *\n * interface WizardState {\n * step: number;\n * answers: Record<string, string>;\n * }\n *\n * const wizardSignal = new SessionStateSignal<WizardState>({\n * name: 'checkout-wizard',\n * initialValue: { step: 1, answers: {} },\n * });\n *\n * // On first load: reads from sessionStorage (or uses initialValue if not found).\n * console.log(wizardSignal.get()); // { step: 1, answers: {} }\n *\n * // Update state — written to sessionStorage automatically (debounced).\n * wizardSignal.set({ step: 2, answers: { q1: 'yes' } });\n *\n * // After a soft page reload, the state is restored from sessionStorage.\n *\n * // Clear the persisted session data without destroying the signal.\n * wizardSignal.remove();\n *\n * // Clean up when the component/page is unmounted.\n * wizardSignal.destroy();\n * ```\n */\nexport class SessionStateSignal<T> extends StateSignal<T> {\n /**\n * The underlying session storage provider instance.\n * @private\n */\n private readonly storageProvider__: SessionStorageProvider<T>;\n\n /**\n * Debouncer to limit how often we write to sessionStorage.\n * @private\n */\n private readonly storageDebouncer__;\n\n /**\n * Subscription to the signal's own changes for sessionStorage sync.\n * @private\n */\n private readonly storageSyncSubscription__;\n\n constructor(config: SessionStateSignalConfig<T>) {\n const {name, storageKey = name, saveDebounceDelay = 500, initialValue, onDestroy} = config;\n\n const storageProvider = createSessionStorageProvider<T>({name: storageKey});\n\n super({\n name,\n initialValue: storageProvider.read() ?? initialValue,\n onDestroy,\n });\n\n this.logger_.logMethodArgs?.('constructor', config);\n\n this.storageProvider__ = storageProvider;\n\n this.storageDebouncer__ = createDebouncer({\n delay: saveDebounceDelay,\n leading: false,\n trailing: true,\n thisContext: this,\n func: this.syncStorage__,\n });\n\n this.storageSyncSubscription__ = this.subscribe(this.storageDebouncer__.trigger, {receivePrevious: false});\n }\n\n /**\n * Syncs the new value to sessionStorage.\n * Called automatically by the debouncer after each state change.\n *\n * @param newValue The new value to sync.\n */\n private syncStorage__(newValue: T): void {\n this.logger_.logMethodArgs?.('syncStorage__', newValue);\n this.storageProvider__.write(newValue);\n }\n\n /**\n * Removes the stored value from sessionStorage without destroying the signal.\n *\n * After calling this, the signal continues to hold its current in-memory value;\n * only the sessionStorage entry is cleared.\n *\n * @example\n * ```typescript\n * // User logs out — clear transient session data.\n * wizardSignal.remove();\n * ```\n */\n public remove(): void {\n this.checkDestroyed_();\n this.logger_.logMethod?.('remove');\n this.storageProvider__.remove();\n }\n\n /**\n * Destroys the signal, flushing pending writes and cleaning up all resources.\n *\n * Always call this when the signal is no longer needed (e.g., on component unmount)\n * to prevent memory leaks.\n *\n * @example\n * ```typescript\n * // In a component teardown:\n * wizardSignal.destroy();\n * ```\n */\n public override destroy(): void {\n this.logger_.logMethod?.('destroy');\n // Flush any pending debounced writes before destroying.\n this.storageDebouncer__.flush();\n // Unsubscribe the storage sync listener to prevent memory leaks.\n this.storageSyncSubscription__.unsubscribe();\n super.destroy();\n }\n}\n",
12
- "import {delay} from '@alwatr/delay';\nimport {createLogger, type AlwatrLogger} from '@alwatr/logger';\n\nimport {SignalBase} from './signal-base.js';\n\nimport type {SignalConfig, SubscribeOptions, SubscribeResult, ListenerCallback} from '../type.js';\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\n/**\n * A single message dispatched through a `ChannelSignal`.\n *\n * `name` identifies the message type (e.g. `'open-drawer'`, `'add-to-cart'`).\n * `payload` is the optional value attached to the message — its type is narrowed\n * by the generic map `TMap` at the class level.\n *\n * @template TMap A record mapping message names to their payload types.\n * @template K The specific message name key (inferred, not set manually).\n */\nexport type ChannelMessage<TMap extends Record<string, unknown>, K extends keyof TMap = keyof TMap> =\n K extends keyof TMap ? {name: K; payload?: TMap[K]} : never;\n\n/**\n * A typed handler for a specific named message on a `ChannelSignal`.\n * Receives only the `payload` — the name is already known at subscription time.\n *\n * @template TMap A record mapping message names to their payload types.\n * @template K The specific message name key.\n */\nexport type ChannelHandler<TMap extends Record<string, unknown>, K extends keyof TMap> = (\n payload: TMap[K] | undefined,\n) => void | Promise<void>;\n\n/**\n * Configuration for creating a `ChannelSignal`.\n */\nexport interface ChannelSignalConfig extends SignalConfig {}\n\n// ─── Class ────────────────────────────────────────────────────────────────────\n\n/**\n * A stateless multi-channel signal that acts as a typed O(1) message bus.\n *\n * `ChannelSignal` is ideal when you need a single signal to carry multiple\n * distinct message types — each identified by a `name` — rather than creating\n * a separate `EventSignal` for every event.\n *\n * ### Routing architecture\n *\n * Internally, `on()` subscriptions are stored in a per-name `Map` of handler\n * sets. When a message is dispatched, only the handlers registered for that\n * specific name are invoked — O(1) lookup regardless of how many distinct\n * names are subscribed. The inherited `SignalBase` observer list is used\n * exclusively by `subscribe()`, which receives the raw message stream for\n * logging or middleware purposes.\n *\n * ### Type safety\n *\n * The generic parameter `TMap` is a record that maps every valid message name\n * to its payload type. TypeScript enforces the correct payload type at both\n * `dispatch` and `on` call sites.\n *\n * @template TMap A record mapping message names to their payload types.\n *\n * @example\n * ```ts\n * interface AppMessages {\n * 'open-drawer': {panel: string};\n * 'close-drawer': void;\n * 'show-toast': {message: string; type: 'info' | 'error'};\n * }\n *\n * const appChannel = new ChannelSignal<AppMessages>({name: 'app-channel'});\n *\n * // Subscribe to a specific message — handler receives payload directly\n * appChannel.on('open-drawer', (payload) => {\n * openDrawer(payload!.panel);\n * });\n *\n * // Dispatch a typed message\n * appChannel.dispatch('open-drawer', {panel: 'settings'});\n * appChannel.dispatch('close-drawer'); // no payload needed\n * ```\n */\nexport class ChannelSignal<TMap extends Record<string, unknown>> extends SignalBase<ChannelMessage<TMap>> {\n /**\n * The logger instance for this signal.\n * @protected\n */\n protected logger_: AlwatrLogger;\n\n /**\n * Per-name handler registry for O(1) routing.\n *\n * Each key is a message name; the value is a Set of `{handler, once}` entries\n * registered via `on()`. Kept separate from `SignalBase`'s observer list so\n * that `subscribe()` (raw stream) and `on()` (named routing) never interfere.\n *\n * @private\n */\n private readonly namedHandlers__: Map<keyof TMap, Set<{handler: ChannelHandler<TMap, keyof TMap>; once: boolean}>> =\n new Map();\n\n constructor(config: ChannelSignalConfig) {\n super(config);\n this.logger_ = createLogger(`channel-signal:${this.name}`);\n this.logger_.logMethod?.('constructor');\n }\n\n /**\n * Dispatches a named message to:\n * 1. All handlers registered via `on(name, …)` for this specific name — O(1).\n * 2. All raw-stream subscribers registered via `subscribe()` — O(N subscribers).\n *\n * The notification is scheduled as a microtask to ensure non-blocking,\n * consistent delivery — matching the behavior of `EventSignal`.\n *\n * TypeScript enforces that `payload` matches the type declared for `name`\n * in `TMap`. If the payload type is `void` or `undefined`, the argument can\n * be omitted entirely.\n *\n * @param name The message name (must be a key of `TMap`).\n * @param payload The optional payload for the message.\n *\n * @example\n * ```ts\n * channel.dispatch('open-drawer', {panel: 'settings'});\n * channel.dispatch('close-drawer'); // no payload needed\n * ```\n */\n public dispatch<K extends keyof TMap>(name: K, payload?: TMap[K]): void {\n this.logger_.logMethodArgs?.('dispatch', {name, payload});\n this.checkDestroyed_();\n delay.nextMicrotask().then(() => this.route__(name, payload));\n }\n\n /**\n * Subscribes to a specific named message on this channel.\n *\n * Uses an internal per-name handler map for O(1) routing — dispatching a\n * message with name `'A'` will never invoke handlers registered for `'B'`.\n *\n * The handler receives the `payload` directly (not the full `{name, payload}`\n * envelope) — since the name is already known at subscription time, passing\n * it again would be redundant.\n *\n * @param name The message name to listen for.\n * @param handler Callback invoked with the payload each time the named message\n * is dispatched.\n * @param options Standard subscribe options. Only `once` is supported here;\n * `priority` applies to `subscribe()` (raw stream) only.\n * @returns A `SubscribeResult` with an `unsubscribe()` method for cleanup.\n *\n * @example\n * ```ts\n * const sub = channel.on('open-drawer', (payload) => {\n * openDrawer(payload!.panel);\n * });\n *\n * // Stop listening when the component is destroyed\n * sub.unsubscribe();\n * ```\n */\n public on<K extends keyof TMap>(\n name: K,\n handler: ChannelHandler<TMap, K>,\n options?: Pick<SubscribeOptions, 'once'>,\n ): SubscribeResult {\n this.logger_.logMethodArgs?.('on', {name});\n this.checkDestroyed_();\n\n // Retrieve or create the handler set for this message name.\n let handlerSet = this.namedHandlers__.get(name);\n if (!handlerSet) {\n handlerSet = new Set();\n this.namedHandlers__.set(name, handlerSet);\n }\n\n // Cast is safe: K extends keyof TMap, so ChannelHandler<TMap, K> is\n // assignable to ChannelHandler<TMap, keyof TMap> at runtime.\n const entry = {handler: handler as ChannelHandler<TMap, keyof TMap>, once: options?.once ?? false};\n handlerSet.add(entry);\n\n return {\n unsubscribe: (): void => {\n handlerSet!.delete(entry);\n // Clean up the empty set to avoid memory leaks on long-lived channels.\n if (handlerSet!.size === 0) {\n this.namedHandlers__.delete(name);\n }\n },\n };\n }\n\n /**\n * Subscribes to **all** messages dispatched on this channel, regardless of name.\n *\n * Use this when you need to observe the raw message stream — for example,\n * for logging, debugging, or middleware-style processing.\n *\n * Prefer `on(name, handler)` for normal use cases to keep subscriptions\n * focused and type-safe.\n *\n * @param callback The function called with every `ChannelMessage`.\n * @param options Standard subscribe options.\n * @returns A `SubscribeResult` with an `unsubscribe()` method.\n *\n * @example\n * ```ts\n * // Log every message for debugging\n * channel.subscribe((msg) => console.log('[channel]', msg.name, msg.payload));\n * ```\n */\n public override subscribe(\n callback: ListenerCallback<ChannelMessage<TMap>>,\n options?: SubscribeOptions,\n ): SubscribeResult {\n this.logger_.logMethodArgs?.('subscribe', options);\n return super.subscribe(callback, options);\n }\n\n /**\n * Core routing method — called inside the microtask scheduled by `dispatch`.\n *\n * 1. Looks up the per-name handler set in O(1).\n * 2. Invokes each handler, removing `once` entries after their first call.\n * 3. Notifies raw-stream subscribers via `SignalBase.notify_()`.\n *\n * @private\n */\n private route__<K extends keyof TMap>(name: K, payload: TMap[K] | undefined): void {\n if (this.isDestroyed) return;\n // ── Named handlers (O(1) lookup) ──────────────────────────────────────────\n const handlerSet = this.namedHandlers__.get(name);\n if (handlerSet?.size) {\n for (const entry of handlerSet) {\n if (entry.once) {\n handlerSet.delete(entry);\n if (handlerSet.size === 0) this.namedHandlers__.delete(name);\n }\n try {\n const result = entry.handler(payload);\n if (result instanceof Promise) {\n result.catch((err) => this.logger_.error('route__', 'async_named_handler_failed', err));\n }\n } catch (err) {\n this.logger_.error('route__', 'sync_named_handler_failed', err);\n }\n }\n }\n\n // ── Raw-stream subscribers (SignalBase observers) ─────────────────────────\n this.notify_({name, payload} as unknown as ChannelMessage<TMap>);\n }\n\n /**\n * Destroys the signal, clearing all named handlers and raw-stream subscribers.\n */\n public override destroy(): void {\n this.namedHandlers__.clear();\n super.destroy();\n }\n}\n",
12
+ "import type {Awaitable} from '@alwatr/type-helper';\nimport {delay} from '@alwatr/delay';\nimport {createLogger, type AlwatrLogger} from '@alwatr/logger';\n\nimport {SignalBase} from './signal-base.js';\n\nimport type {SignalConfig, SubscribeOptions, SubscribeResult, ListenerCallback} from '../type.js';\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\n/**\n * Determines whether the payload argument for a given channel message is\n * required or optional, based solely on the declared type in `TMap`.\n *\n * - `void | undefined` → payload is optional (second arg may be omitted).\n * - anything else → payload is **required** (omitting it is a compile error).\n *\n * This is used to build the rest-parameter tuple for `dispatch()` so that\n * TypeScript enforces the correct call signature at every dispatch site.\n *\n * @template TMap A record mapping message names to their payload types.\n * @template K The specific message name key.\n *\n * @example\n * ```ts\n * // ActionRecord: { 'logout': void; 'add-to-cart': {productId: number} }\n * type A = DispatchArgs<ActionRecord, 'logout'>; // [name: 'logout', payload?: void]\n * type B = DispatchArgs<ActionRecord, 'add-to-cart'>; // [name: 'add-to-cart', payload: {productId: number}]\n * ```\n */\nexport type DispatchArgs<TMap extends object, K extends keyof TMap> =\n TMap[K] extends void | undefined ? [name: K, payload?: TMap[K]] : [name: K, payload: TMap[K]];\n\n/**\n * A single message dispatched through a `ChannelSignal`.\n *\n * `name` identifies the message type (e.g. `'open-drawer'`, `'add-to-cart'`).\n * `payload` carries the associated data, whose type is determined by the generic `TMap` based on the `name`.\n *\n * @template TMap A record mapping message names to their payload types.\n * @template K The specific message name key (inferred, not set manually).\n */\nexport type ChannelMessage<TMap extends object, K extends keyof TMap = keyof TMap> = {name: K; payload: TMap[K]};\n\n/**\n * A typed handler for a specific named message on a `ChannelSignal`.\n * Receives only the `payload` — the name is already known at subscription time.\n *\n * The payload type mirrors `DispatchArgs`: it is `TMap[K] | undefined` only\n * when the declared type is `void | undefined`; otherwise it is exactly `TMap[K]`\n * (non-optional) so handlers do not need unnecessary null-guards.\n *\n * @template TMap A record mapping message names to their payload types.\n * @template K The specific message name key.\n */\nexport type ChannelHandler<TMap extends object, K extends keyof TMap = keyof TMap> = (\n payload: TMap[K],\n) => Awaitable<void>;\n\n/**\n * Internal handler type used inside `namedHandlers__`.\n *\n * At the storage boundary we erase the conditional payload type to `unknown`\n * so TypeScript does not need to evaluate the conditional against every\n * possible `K`. Type safety is already enforced at the public `on()` and\n * `dispatch()` call sites — the internal executor only needs to call the\n * function with the value it received.\n *\n * @internal\n */\ntype InternalHandler = (payload: unknown) => Awaitable<void>;\n\n/**\n * Configuration for creating a `ChannelSignal`.\n */\nexport interface ChannelSignalConfig extends SignalConfig {}\n\n// ─── Class ────────────────────────────────────────────────────────────────────\n\n/**\n * A stateless multi-channel signal that acts as a typed O(1) message bus.\n *\n * `ChannelSignal` is ideal when you need a single signal to carry multiple\n * distinct message types — each identified by a `name` — rather than creating\n * a separate `EventSignal` for every event.\n *\n * ### Routing architecture\n *\n * Internally, `on()` subscriptions are stored in a per-name `Map` of handler\n * sets. When a message is dispatched, only the handlers registered for that\n * specific name are invoked — O(1) lookup regardless of how many distinct\n * names are subscribed. The inherited `SignalBase` observer list is used\n * exclusively by `subscribe()`, which receives the raw message stream for\n * logging or middleware purposes.\n *\n * ### Type safety\n *\n * The generic parameter `TMap` is a record that maps every valid message name\n * to its payload type. TypeScript enforces the correct payload type at both\n * `dispatch` and `on` call sites.\n *\n * @template TMap A record mapping message names to their payload types.\n *\n * @example\n * ```ts\n * interface AppMessages {\n * 'open-drawer': {panel: string};\n * 'close-drawer': void;\n * 'show-toast': {message: string; type: 'info' | 'error'};\n * }\n *\n * const appChannel = new ChannelSignal<AppMessages>({name: 'app-channel'});\n *\n * // Subscribe to a specific message — handler receives payload directly\n * appChannel.on('open-drawer', (payload) => {\n * openDrawer(payload!.panel);\n * });\n *\n * // Dispatch a typed message\n * appChannel.dispatch('open-drawer', {panel: 'settings'});\n * appChannel.dispatch('close-drawer'); // no payload needed\n * ```\n */\nexport class ChannelSignal<TMap extends object> extends SignalBase<ChannelMessage<TMap>> {\n /**\n * The logger instance for this signal.\n * @protected\n */\n protected logger_: AlwatrLogger;\n\n /**\n * Per-name handler registry for O(1) routing.\n *\n * Each key is a message name; the value is a Set of `{handler, once}` entries\n * registered via `on()`. Kept separate from `SignalBase`'s observer list so\n * that `subscribe()` (raw stream) and `on()` (named routing) never interfere.\n *\n * Stored as `InternalHandler` (erased to `unknown` payload) to avoid\n * unevaluable conditional types at the storage boundary. Type safety is\n * enforced at the public `on()` and `dispatch()` call sites.\n *\n * @private\n */\n private readonly namedHandlers__ = new Map<keyof TMap, Set<{handler: InternalHandler; once: boolean}>>();\n\n constructor(config: ChannelSignalConfig) {\n super(config);\n this.logger_ = createLogger(`channel-signal:${this.name}`);\n this.logger_.logMethod?.('constructor');\n }\n\n /**\n * Dispatches a named message to:\n * 1. All handlers registered via `on(name, …)` for this specific name — O(1).\n * 2. All raw-stream subscribers registered via `subscribe()` — O(N subscribers).\n *\n * The notification is scheduled as a microtask to ensure non-blocking,\n * consistent delivery — matching the behavior of `EventSignal`.\n *\n * ### Payload enforcement\n *\n * The payload argument is **required** unless the declared type in `TMap` is\n * `void` or `undefined`. Omitting a required payload — or passing `undefined`\n * for a non-optional type — is a **compile error**. This prevents accidental\n * `undefined` from propagating into handlers that expect a real value.\n *\n * ```ts\n * // TMap: { 'add-to-cart': {productId: number}; 'logout': void }\n * channel.dispatch('add-to-cart', {productId: 42}); // ✅ required payload\n * channel.dispatch('add-to-cart'); // ❌ compile error\n * channel.dispatch('logout'); // ✅ void — no payload\n * channel.dispatch('logout', undefined); // ✅ also fine\n * ```\n *\n * @param args Tuple of `[name, payload]` — payload optionality is enforced\n * by `DispatchArgs<TMap, K>` based on the declared type.\n */\n public dispatch<K extends keyof TMap>(...args: DispatchArgs<TMap, K>): void {\n const [name, payload] = args;\n this.logger_.logMethodArgs?.('dispatch', {name, payload});\n this.checkDestroyed_();\n delay.nextMicrotask().then(() => this.route__(name, payload));\n }\n\n /**\n * Subscribes to a specific named message on this channel.\n *\n * Uses an internal per-name handler map for O(1) routing — dispatching a\n * message with name `'A'` will never invoke handlers registered for `'B'`.\n *\n * The handler receives the `payload` directly (not the full `{name, payload}`\n * envelope) — since the name is already known at subscription time, passing\n * it again would be redundant.\n *\n * @param name The message name to listen for.\n * @param handler Callback invoked with the payload each time the named message\n * is dispatched.\n * @param options Standard subscribe options. Only `once` is supported here;\n * `priority` applies to `subscribe()` (raw stream) only.\n * @returns A `SubscribeResult` with an `unsubscribe()` method for cleanup.\n *\n * @example\n * ```ts\n * const sub = channel.on('open-drawer', (payload) => {\n * openDrawer(payload!.panel);\n * });\n *\n * // Stop listening when the component is destroyed\n * sub.unsubscribe();\n * ```\n */\n public on<K extends keyof TMap>(\n name: K,\n handler: ChannelHandler<TMap, K>,\n options?: Pick<SubscribeOptions, 'once'>,\n ): SubscribeResult {\n this.logger_.logMethodArgs?.('on', {name});\n this.checkDestroyed_();\n\n // Retrieve or create the handler set for this message name.\n let handlerSet = this.namedHandlers__.get(name);\n if (!handlerSet) {\n handlerSet = new Set();\n this.namedHandlers__.set(name, handlerSet);\n }\n\n const entry = {handler: handler as InternalHandler, once: options?.once ?? false};\n handlerSet.add(entry);\n\n return {\n unsubscribe: (): void => {\n handlerSet!.delete(entry);\n // Clean up the empty set to avoid memory leaks on long-lived channels.\n if (handlerSet!.size === 0) {\n this.namedHandlers__.delete(name);\n }\n },\n };\n }\n\n /**\n * Subscribes to **all** messages dispatched on this channel, regardless of name.\n *\n * Use this when you need to observe the raw message stream — for example,\n * for logging, debugging, or middleware-style processing.\n *\n * Prefer `on(name, handler)` for normal use cases to keep subscriptions\n * focused and type-safe.\n *\n * @param callback The function called with every `ChannelMessage`.\n * @param options Standard subscribe options.\n * @returns A `SubscribeResult` with an `unsubscribe()` method.\n *\n * @example\n * ```ts\n * // Log every message for debugging\n * channel.subscribe((msg) => console.log('[channel]', msg.name, msg.payload));\n * ```\n */\n public override subscribe(\n callback: ListenerCallback<ChannelMessage<TMap>>,\n options?: SubscribeOptions,\n ): SubscribeResult {\n this.logger_.logMethodArgs?.('subscribe', options);\n return super.subscribe(callback, options);\n }\n\n /**\n * Core routing method — called inside the microtask scheduled by `dispatch`.\n *\n * 1. Looks up the per-name handler set in O(1).\n * 2. Invokes each handler, removing `once` entries after their first call.\n * 3. Notifies raw-stream subscribers via `SignalBase.notify_()`.\n *\n * @private\n */\n private route__<K extends keyof TMap>(name: K, payload: TMap[K] | undefined): void {\n if (this.isDestroyed) return;\n // ── Named handlers (O(1) lookup) ──────────────────────────────────────────\n const handlerSet = this.namedHandlers__.get(name);\n if (handlerSet?.size) {\n for (const entry of handlerSet) {\n if (entry.once) {\n handlerSet.delete(entry);\n if (handlerSet.size === 0) this.namedHandlers__.delete(name);\n }\n try {\n const result = entry.handler(payload);\n if (result instanceof Promise) {\n result.catch((err) => this.logger_.error('route__', 'async_named_handler_failed', err));\n }\n } catch (err) {\n this.logger_.error('route__', 'sync_named_handler_failed', err);\n }\n }\n }\n\n // ── Raw-stream subscribers (SignalBase observers) ─────────────────────────\n this.notify_({name, payload} as ChannelMessage<TMap>);\n }\n\n /**\n * Destroys the signal, clearing all named handlers and raw-stream subscribers.\n */\n public override destroy(): void {\n this.namedHandlers__.clear();\n super.destroy();\n }\n}\n",
13
13
  "import {EventSignal} from '../core/event-signal.js';\n\nimport type {SignalConfig} from '../type.js';\n\n/**\n * Creates a stateless signal for dispatching transient events.\n *\n * `EventSignal` is ideal for broadcasting events that do not have a persistent state.\n * Unlike `StateSignal`, it does not hold a value. Listeners are only notified of new\n * events as they are dispatched. This makes it suitable for modeling user interactions,\n * system notifications, or any one-off message.\n *\n * @template T The type of the payload for the events.\n *\n * @param config The configuration for the event signal.\n * @returns A new instance of EventSignal.\n *\n * @example\n * const onUserClick = createEventSignal<{ x: number, y: number }>({\n * name: 'on-user-click'\n * });\n *\n * onUserClick.subscribe(pos => {\n * console.log(`User clicked at: ${pos.x}, ${pos.y}`);\n * });\n *\n * onUserClick.dispatch({ x: 100, y: 250 });\n */\nexport function createEventSignal<T = void>(config: SignalConfig): EventSignal<T> {\n return new EventSignal<T>(config);\n}\n",
14
14
  "import {StateSignal} from '../core/state-signal.js';\n\nimport type {StateSignalConfig} from '../type.js';\n\n/**\n * Creates a stateful signal that holds a value and notifies listeners when the value changes.\n *\n * `StateSignal` is the core of the signal library, representing a piece of mutable state.\n * It always has a value, and new subscribers immediately receive the current value by default.\n *\n * @template T The type of the state it holds.\n *\n * @param config The configuration for the state signal.\n * @returns A new instance of StateSignal.\n *\n * @example\n * const counter = createStateSignal({\n * name: 'counter-signal',\n * initialValue: 0,\n * });\n *\n * console.log(counter.get()); // Outputs: 0\n * counter.set(1);\n * console.log(counter.get()); // Outputs: 1\n */\nexport function createStateSignal<T>(config: StateSignalConfig<T>): StateSignal<T> {\n return new StateSignal(config);\n}\n",
15
15
  "import {ComputedSignal} from '../core/computed-signal.js';\n\nimport type {ComputedSignalConfig} from '../type.js';\n\n/**\n * Creates a read-only signal that derives its value from a set of dependency signals.\n *\n * `ComputedSignal` is a powerful tool for creating values that reactively update when their underlying\n * data sources change. Its value is memoized, meaning the `get` function is only re-evaluated when\n * one of its dependencies has actually changed.\n *\n * A key feature is its lifecycle management: a `ComputedSignal` **must** be destroyed when no longer\n * needed to prevent memory leaks from its subscriptions to dependency signals.\n *\n * @template T The type of the computed value.\n *\n * @param config The configuration for the computed signal.\n * @returns A new, read-only computed signal.\n *\n * @example\n * const firstName = createStateSignal({ name: 'firstName', initialValue: 'John' });\n * const lastName = createStateSignal({ name: 'lastName', initialValue: 'Doe' });\n *\n * const fullName = createComputedSignal({\n * name: 'fullName',\n * deps: [firstName, lastName],\n * get: () => `${firstName.get()} ${lastName.get()}`,\n * });\n *\n * console.log(fullName.get()); // \"John Doe\"\n *\n * // IMPORTANT: Always destroy a computed signal when no longer needed.\n * // fullName.destroy();\n */\nexport function createComputedSignal<T>(config: ComputedSignalConfig<T>): ComputedSignal<T> {\n return new ComputedSignal(config);\n}\n",
16
16
  "import {EffectSignal} from '../core/effect-signal.js';\n\nimport type {EffectSignalConfig} from '../type.js';\n\n/**\n * Creates a side-effect that runs in response to changes in dependency signals.\n *\n * `EffectSignal` is designed for running logic that interacts with the \"outside world\"—such as\n * logging, network requests, or DOM manipulation—whenever its dependencies are updated.\n * It encapsulates the subscription and cleanup logic, providing a robust and memory-safe\n * way to handle reactive side-effects.\n *\n * A key feature is its lifecycle management: an `EffectSignal` **must** be destroyed when no longer\n * needed to prevent memory leaks and stop the effect from running unnecessarily.\n *\n * @param config The configuration for the effect.\n * @returns An object with a `destroy` method to stop the effect.\n *\n * @example\n * // --- Create dependency signals ---\n * const counter = createStateSignal({ initialValue: 0, name: 'counter' });\n * const user = createStateSignal({ initialValue: 'guest', name: 'user' });\n *\n * // --- Create an effect ---\n * const analyticsEffect = createEffect({\n * deps: [counter, user],\n * run: () => {\n * console.log(`Analytics: User '${user.get()}' clicked ${counter.get()} times.`);\n * },\n * runImmediately: true, // Optional: run once on creation\n * });\n * // Immediately logs: \"Analytics: User 'guest' clicked 0 times.\"\n *\n * // --- Trigger the effect by updating a dependency ---\n * counter.set(1);\n * // After a macrotask, logs: \"Analytics: User 'guest' clicked 1 times.\"\n *\n * // --- IMPORTANT: Clean up when the effect is no longer needed ---\n * analyticsEffect.destroy();\n *\n * // Further updates will not trigger the effect.\n * counter.set(2); // Nothing is logged.\n */\nexport function createEffect(config: EffectSignalConfig): EffectSignal {\n return new EffectSignal(config);\n}\n",
17
17
  "import {PersistentStateSignal} from '../core/persistent-state-signal.js';\n\nimport type {PersistentStateSignalConfig} from '../type.js';\n\n/**\n * Creates a stateful signal that persists its value in localStorage.\n *\n * This function provides a clean, declarative API for creating state that\n * survives page reloads. It automatically handles reading the initial state\n * from localStorage and saving subsequent updates.\n *\n * @template T The type of the state it holds.\n *\n * @param {PersistentStateSignalConfig<T>} config The configuration for the persistent state signal.\n * @returns {PersistentStateSignal<T>} A new instance of PersistentStateSignal.\n *\n * @example\n * // Create a signal to store user's preferred theme.\n * const userThemeSignal = createPersistentStateSignal<string>({\n * name: 'user-theme',\n * schemaVersion: 1,\n * initialValue: 'light',\n * });\n *\n * // The initial value is read from localStorage, or 'light' if not present.\n * console.log(userThemeSignal.get());\n *\n * // Setting a new value updates the in-memory state and writes to localStorage.\n * userThemeSignal.set('dark');\n */\nexport function createPersistentStateSignal<T>(config: PersistentStateSignalConfig<T>): PersistentStateSignal<T> {\n return new PersistentStateSignal(config);\n}\n",
18
18
  "import {SessionStateSignal} from '../core/session-state-signal.js';\n\nimport type {SessionStateSignalConfig} from '../type.js';\n\n/**\n * Creates a stateful signal that persists its value in `sessionStorage`.\n *\n * The stored data survives soft navigations and page refreshes within the same browser tab,\n * but is automatically cleared when the tab or window is closed.\n *\n * Use this for transient UI state such as:\n * - Multi-step wizard progress\n * - Unsaved form drafts\n * - Scroll position or active tab indices\n *\n * @template T The type of the state it holds. Must be JSON-serializable.\n *\n * @param {SessionStateSignalConfig<T>} config The configuration for the session state signal.\n * @returns {SessionStateSignal<T>} A new `SessionStateSignal` instance.\n *\n * @example\n * ```typescript\n * import {createSessionStateSignal} from '@alwatr/signal';\n *\n * const checkoutWizard = createSessionStateSignal<{step: number}>({\n * name: 'checkout-wizard',\n * initialValue: {step: 1},\n * });\n *\n * // State is restored from sessionStorage if it exists.\n * console.log(checkoutWizard.get()); // {step: 1} or last saved value\n *\n * // Update state — automatically saved to sessionStorage.\n * checkoutWizard.set({step: 2});\n *\n * // Cleanup when no longer needed.\n * checkoutWizard.destroy();\n * ```\n */\nexport function createSessionStateSignal<T>(config: SessionStateSignalConfig<T>): SessionStateSignal<T> {\n return new SessionStateSignal(config);\n}\n",
19
- "import {ChannelSignal} from '../core/channel-signal.js';\n\nimport type {ChannelSignalConfig} from '../core/channel-signal.js';\n\n/**\n * Creates a stateless multi-channel signal that acts as a typed message bus.\n *\n * `ChannelSignal` is ideal when you need a single signal to carry multiple\n * distinct message types — each identified by a `name` — rather than creating\n * a separate `EventSignal` for every event.\n *\n * The generic parameter `TMap` is a record that maps every valid message name\n * to its payload type, giving you full type safety at both dispatch and subscribe sites.\n *\n * @template TMap A record mapping message names to their payload types.\n *\n * @param config The configuration for the channel signal.\n * @returns A new instance of `ChannelSignal`.\n *\n * @example\n * ```ts\n * interface AppMessages {\n * 'open-drawer': {panel: string};\n * 'close-drawer': void;\n * 'show-toast': {message: string; type: 'info' | 'error'};\n * }\n *\n * const appChannel = createChannelSignal<AppMessages>({name: 'app-channel'});\n *\n * // Subscribe to a specific message\n * appChannel.on('show-toast', (payload) => {\n * toast.show(payload!.message, payload!.type);\n * });\n *\n * // Dispatch a message\n * appChannel.dispatch('show-toast', {message: 'Saved!', type: 'info'});\n * appChannel.dispatch('close-drawer');\n * ```\n */\nexport function createChannelSignal<TMap extends Record<string, unknown>>(\n config: ChannelSignalConfig,\n): ChannelSignal<TMap> {\n return new ChannelSignal<TMap>(config);\n}\n",
19
+ "import {ChannelSignal} from '../core/channel-signal.js';\n\nimport type {ChannelSignalConfig} from '../core/channel-signal.js';\n\n/**\n * Creates a stateless multi-channel signal that acts as a typed message bus.\n *\n * `ChannelSignal` is ideal when you need a single signal to carry multiple\n * distinct message types — each identified by a `name` — rather than creating\n * a separate `EventSignal` for every event.\n *\n * The generic parameter `TMap` is a record that maps every valid message name\n * to its payload type, giving you full type safety at both dispatch and subscribe sites.\n *\n * @template TMap A record mapping message names to their payload types.\n *\n * @param config The configuration for the channel signal.\n * @returns A new instance of `ChannelSignal`.\n *\n * @example\n * ```ts\n * interface AppMessages {\n * 'open-drawer': {panel: string};\n * 'close-drawer': void;\n * 'show-toast': {message: string; type: 'info' | 'error'};\n * }\n *\n * const appChannel = createChannelSignal<AppMessages>({name: 'app-channel'});\n *\n * // Subscribe to a specific message\n * appChannel.on('show-toast', (payload) => {\n * toast.show(payload!.message, payload!.type);\n * });\n *\n * // Dispatch a message\n * appChannel.dispatch('show-toast', {message: 'Saved!', type: 'info'});\n * appChannel.dispatch('close-drawer');\n * ```\n */\nexport function createChannelSignal<TMap extends object>(config: ChannelSignalConfig): ChannelSignal<TMap> {\n return new ChannelSignal<TMap>(config);\n}\n",
20
20
  "import {createDebouncer} from '@alwatr/debounce';\n\nimport {StateSignal} from '../core/state-signal.js';\nimport {createComputedSignal} from '../creators/computed.js';\n\nimport type {ComputedSignal} from '../core/computed-signal.js';\nimport type {IReadonlySignal, DebounceSignalConfig} from '../type.js';\n\n/**\n * Creates a new computed signal that debounces updates from a source signal.\n *\n * The returned signal is a `ComputedSignal`, meaning it is read-only and its value is\n * derived from the source. It only updates its value after a specified period of\n * inactivity from the source signal.\n *\n * This operator is essential for handling high-frequency events, such as user input\n * in a search box, resizing a window, or any other event that fires rapidly.\n * By debouncing, you can ensure that expensive operations (like API calls or heavy\n * computations) are only executed once the events have settled.\n *\n * @template T The type of the signal's value.\n *\n * @param {IReadonlySignal<T>} sourceSignal The original signal to debounce.\n * It can be a `StateSignal`, `ComputedSignal`, or any signal implementing `IReadonlySignal`.\n * @param {DebounceSignalConfig} config Configuration object for the debouncer,\n * including `delay`, `leading`, and `trailing` options from `@alwatr/debounce`.\n *\n * @returns {IComputedSignal<T>} A new, read-only computed signal that emits debounced values.\n * Crucially, you **must** call `.destroy()` on this signal when it's no longer\n * needed to prevent memory leaks by cleaning up internal subscriptions and timers.\n *\n * @example\n * ```typescript\n * // Create a source signal for user input.\n * const searchInput = createStateSignal({\n * name: 'search-input',\n * initialValue: '',\n * });\n *\n * // Create a debounced signal that waits 300ms after the user stops typing.\n * const debouncedSearch = createDebouncedSignal(searchInput, { delay: 300 });\n *\n * // Use an effect to react to the debounced value.\n * createEffect({\n * deps: [debouncedSearch],\n * run: () => {\n * if (debouncedSearch.get()) {\n * console.log(`🚀 Sending API request for: \"${debouncedSearch.get()}\"`);\n * }\n * },\n * });\n *\n * searchInput.set('Alwatr');\n * searchInput.set('Alwatr Signal');\n * // (after 300ms of inactivity)\n * // Logs: \"🚀 Sending API request for: \"Alwatr Signal\"\"\n *\n * // IMPORTANT: Clean up when the component unmounts.\n * // debouncedSearch.destroy();\n * ```\n */\nexport function createDebouncedSignal<T>(sourceSignal: IReadonlySignal<T>, config: DebounceSignalConfig): ComputedSignal<T> {\n const name = config.name ?? `${sourceSignal.name}-debounced`;\n\n const internalSignal = new StateSignal<T>({\n name: `${name}-internal`,\n initialValue: sourceSignal.get(),\n });\n\n const debouncer = createDebouncer({\n ...config,\n thisContext: internalSignal,\n func: internalSignal.set,\n });\n\n const subscription = sourceSignal.subscribe(debouncer.trigger, {receivePrevious: false});\n\n return createComputedSignal({\n name: name,\n deps: [internalSignal],\n get: () => internalSignal.get(),\n onDestroy: () => {\n if (internalSignal.isDestroyed) return;\n subscription.unsubscribe();\n debouncer.cancel();\n internalSignal.destroy();\n config.onDestroy?.();\n config = null as unknown as DebounceSignalConfig;\n },\n });\n}\n",
21
21
  "import {createComputedSignal} from '../creators/computed.js';\nimport {createStateSignal} from '../creators/state.js';\n\nimport type {ComputedSignal} from '../core/computed-signal.js';\nimport type {IReadonlySignal} from '../type.js';\n\n/**\n * Creates a new computed signal that only emits values from a source signal\n * that satisfy a predicate function.\n *\n * This operator is analogous to `Array.prototype.filter`. It is particularly\n * useful for creating effects or other computed signals that should only react\n * to a specific subset of state changes.\n *\n * Note: The resulting signal's value will be `undefined` until the source\n * emits a value that passes the filter.\n *\n * @template T The type of the signal's value.\n *\n * @param sourceSignal The original signal to filter.\n * @param predicate A function that returns `true` if the value should be passed.\n * @param name An optional, unique identifier for the new signal for debugging. default: `${sourceSignal.name}-filtered`\n *\n * @returns A new computed signal that emits filtered values.\n *\n * @example\n * const numberSignal = createStateSignal({ name: 'number', initialValue: 0 });\n *\n * const evenNumberSignal = createFilteredSignal(\n * numberSignal,\n * (num) => num % 2 === 0,\n * );\n *\n * createEffect({\n * deps: [evenNumberSignal],\n * run: () => {\n * // This effect only runs for even numbers.\n * // The value can be `undefined` on the first run if initialValue is not even.\n * if (evenNumberSignal.get() !== undefined) {\n * console.log(`Even number detected: ${evenNumberSignal.get()}`);\n * }\n * },\n * runImmediately: true,\n * });\n * // Logs: \"Even number detected: 0\"\n *\n * numberSignal.set(1); // Effect does not run\n * numberSignal.set(2); // Logs: \"Even number detected: 2\"\n */\nexport function createFilteredSignal<T>(\n sourceSignal: IReadonlySignal<T>,\n predicate: (value: T) => boolean,\n name = `${sourceSignal.name}-filtered`,\n): ComputedSignal<T | undefined> {\n const sourceValue = sourceSignal.get();\n const initialValue = predicate(sourceValue) ? sourceValue : undefined;\n\n const internalSignal = createStateSignal({\n name: `${name}-internal`,\n initialValue,\n });\n\n const subscription = sourceSignal.subscribe((newValue) => {\n if (predicate(newValue)) {\n internalSignal.set(newValue);\n }\n });\n\n return createComputedSignal({\n name: name,\n deps: [internalSignal],\n get: () => internalSignal.get(),\n onDestroy: () => {\n subscription.unsubscribe();\n internalSignal.destroy();\n },\n });\n}\n",
22
22
  "import {createComputedSignal} from '../creators/computed.js';\n\nimport type {ComputedSignal} from '../core/computed-signal.js';\nimport type {IReadonlySignal} from '../type.js';\n\n/**\n * Creates a new read-only computed signal that transforms the value of a source\n * signal using a projection function.\n *\n * This operator is analogous to `Array.prototype.map`. It applies a function to\n * each value emitted by the source signal and emits the result.\n *\n * @template T The type of the source signal's value.\n * @template R The type of the projected value.\n *\n * @param sourceSignal The original signal to transform.\n * @param projectFunction A function to apply to each value from the source signal.\n * @param [name] An optional, unique identifier for the new signal for debugging. default: `${sourceSignal.name}-mapped`\n *\n * @returns A new, read-only computed signal with the transformed values.\n *\n * @example\n * const userSignal = createStateSignal({\n * name: 'user',\n * initialValue: { name: 'John', age: 30 },\n * });\n *\n * const userNameSignal = createMappedSignal(\n * userSignal,\n * (user) => user.name,\n * );\n *\n * console.log(userNameSignal.get()); // Outputs: \"John\"\n * // in next macro-task ...\n * userSignal.set({ name: 'Jane', age: 32 });\n * console.log(userNameSignal.get()); // Outputs: \"Jane\"\n */\nexport function createMappedSignal<T, R>(\n sourceSignal: IReadonlySignal<T>,\n projectFunction: (value: T) => R,\n name = `${sourceSignal.name}-mapped`,\n): ComputedSignal<R> {\n return createComputedSignal({\n name: name,\n deps: [sourceSignal],\n get: () => projectFunction(sourceSignal.get()),\n });\n}\n"
23
23
  ],
24
- "mappings": "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",
25
- "debugId": "39558698A04B4C5764756E2164756E21",
24
+ "mappings": ";AASO,MAAe,CAAc,CAoCZ,QA/BN,KAYG,mBAAqB,IAAI,IACzB,WAAa,IAAI,IAM5B,cAAgB,MAQb,YAAW,EAAY,CAChC,OAAO,KAAK,cAGd,WAAW,CAAW,EAAuB,CAAvB,eACpB,KAAK,KAAO,EAAQ,KASZ,eAAe,CAAC,EAA8B,CAGtD,GAFA,KAAK,QAAQ,YAAY,iBAAiB,EAEtC,KAAK,cAAe,CACtB,KAAK,QAAQ,WAAW,kBAAmB,qCAAqC,EAChF,OAGF,KAAK,mBAAmB,OAAO,CAAQ,EACvC,KAAK,WAAW,OAAO,CAAQ,EAY1B,SAAS,CAAC,EAA+B,EAA6C,CAC3F,KAAK,QAAQ,gBAAgB,iBAAkB,CAAO,EACtD,KAAK,gBAAgB,EAErB,IAAM,EAAyB,CAAC,WAAU,SAAO,EAEjD,GAAI,GAAS,SACX,KAAK,mBAAmB,IAAI,CAAQ,EAEpC,UAAK,WAAW,IAAI,CAAQ,EAI9B,MAAO,CACL,YAAa,IAAY,KAAK,gBAAgB,CAAQ,CACxD,EAYQ,OAAO,CAAC,EAAgB,CAGhC,GAFA,KAAK,QAAQ,gBAAgB,UAAW,CAAK,EAEzC,KAAK,cAAe,CACtB,KAAK,QAAQ,WAAW,UAAW,4BAA4B,EAC/D,OAGF,QAAW,KAAY,KAAK,mBAC1B,KAAK,kBAAkB,EAAU,CAAK,EAGxC,QAAW,KAAY,KAAK,WAC1B,KAAK,kBAAkB,EAAU,CAAK,EAOlC,iBAAiB,CAAC,EAAwB,EAAgB,CAChE,GAAI,EAAS,SAAS,KACpB,KAAK,gBAAgB,CAAQ,EAE/B,GAAI,CACF,IAAM,EAAS,EAAS,SAAS,CAAK,EACtC,GAAI,aAAkB,QACpB,EAAO,MAAM,CAAC,IAAQ,KAAK,QAAQ,MAAM,UAAW,wBAAyB,EAAK,CAAC,UAAQ,CAAC,CAAC,EAE/F,MAAO,EAAK,CACZ,KAAK,QAAQ,MAAM,UAAW,uBAAwB,CAAG,GAIrD,iBAAmB,IAAI,IAexB,SAAS,EAAe,CAG7B,OAFA,KAAK,QAAQ,YAAY,WAAW,EACpC,KAAK,gBAAgB,EACd,IAAI,QAAQ,CAAC,EAAS,IAAW,CACtC,KAAK,iBAAiB,IAAI,CAAM,EAChC,KAAK,UACH,CAAC,IAAU,CACT,KAAK,iBAAiB,OAAO,CAAM,EACnC,EAAQ,CAAK,GAEf,CACE,KAAM,GACN,SAAU,GACV,gBAAiB,EACnB,CACF,EACD,EAUI,OAAO,EAAS,CAErB,GADA,KAAK,QAAQ,YAAY,SAAS,EAC9B,KAAK,cAAe,CACtB,KAAK,QAAQ,WAAW,WAAY,wBAAwB,EAC5D,OAIF,GAFA,KAAK,cAAgB,GAEjB,KAAK,iBAAiB,KAAM,CAC9B,IAAM,EAAY,MAAM,kBAAkB,EAC1C,QAAW,KAAU,KAAK,iBACxB,EAAO,CAAK,EAEd,KAAK,iBAAiB,MAAM,EAE9B,KAAK,mBAAmB,MAAM,EAC9B,KAAK,WAAW,MAAM,EACtB,KAAK,QAAQ,YAAY,EACzB,KAAK,QAAU,KAQP,eAAe,EAAS,CAChC,GAAI,KAAK,cAEP,MADA,KAAK,QAAQ,SAAS,kBAAmB,iCAAiC,EAChE,MAAM,gDAAgD,KAAK,OAAO,EAGlF,CClNA,gBAAS,sBACT,uBAAS,uBAiCF,MAAM,UAA8B,CAAc,CAK7C,QAEV,WAAW,CAAC,EAAsB,CAChC,MAAM,CAAM,EACZ,KAAK,QAAU,EAAa,gBAAgB,KAAK,MAAM,EACvD,KAAK,QAAQ,YAAY,aAAa,EAUjC,QAAQ,CAAC,EAAkB,CAChC,KAAK,QAAQ,gBAAgB,WAAY,CAAE,SAAQ,CAAC,EACpD,KAAK,gBAAgB,EAErB,EAAM,cAAc,EAAE,KAAK,IAAM,KAAK,QAAQ,CAAO,CAAC,EAE1D,CC5DA,gBAAQ,sBACR,uBAAQ,uBAuCD,MAAM,UAAuB,CAA4C,CAKtE,QAME,QAEV,WAAW,CAAC,EAA8B,CACxC,MAAM,CACJ,KAAM,EAAO,KACb,UAAW,EAAO,SACpB,CAAC,EACD,KAAK,QAAU,EAAa,gBAAgB,KAAK,MAAM,EACvD,KAAK,QAAU,EAAO,aACtB,KAAK,QAAQ,gBAAgB,cAAe,CAAC,aAAc,KAAK,OAAO,CAAC,EAWnE,GAAG,EAAM,CAEd,OADA,KAAK,gBAAgB,EACd,KAAK,QAkBP,GAAG,CAAC,EAAmB,CAI5B,GAHA,KAAK,QAAQ,gBAAgB,MAAO,CAAC,UAAQ,CAAC,EAG1C,OAAO,GAAG,KAAK,QAAS,CAAQ,IAAM,OAAO,IAAa,UAAY,IAAa,MACrF,OAGF,KAAK,QAAU,EAEf,KAAK,aAAa,EAQb,YAAY,EAAS,CAC1B,KAAK,QAAQ,YAAY,cAAc,EACvC,KAAK,gBAAgB,EAErB,EAAM,cAAc,EAAE,KAAK,IAAM,KAAK,QAAQ,KAAK,OAAO,CAAC,EAkBtD,MAAM,CAAC,EAAwC,CACpD,KAAK,gBAAgB,EACrB,IAAM,EAAW,EAAQ,KAAK,OAAO,EACrC,KAAK,QAAQ,gBAAgB,SAAU,KAAK,QAAS,CAAQ,EAC7D,KAAK,IAAI,CAAQ,EAaH,SAAS,CAAC,EAA+B,EAA4B,CAAC,EAAoB,CAKxG,GAJA,KAAK,QAAQ,gBAAgB,YAAa,CAAO,EACjD,KAAK,gBAAgB,EAGjB,EAAQ,kBAAoB,IAa9B,GAVA,EACG,cAAc,EACd,KAAK,IAAM,CACV,KAAK,QAAQ,UAAU,YAAa,oBAAoB,EACxD,EAAS,KAAK,OAAO,EACtB,EACA,MAAM,CAAC,IAAQ,KAAK,QAAQ,MAAM,YAAa,4BAA6B,CAAG,CAAC,EAI/E,EAAQ,KAEV,MAAO,CAAC,YAAa,IAAM,EAAE,EAIjC,OAAO,MAAM,UAAU,EAAU,CAAO,EAO1B,OAAO,EAAS,CAC9B,KAAK,QAAU,KACf,MAAM,QAAQ,EAGT,UAAU,EAAuB,CACtC,OAAO,KAEX,CC3LA,gBAAS,sBACT,uBAAS,uBA4CF,MAAM,CAAgD,CAgCrC,QA5BN,KAMG,QAOA,gBAOF,0BAA+C,CAAC,EAMzD,kBAAoB,GAE5B,WAAW,CAAW,EAAkC,CAAlC,eACpB,KAAK,KAAO,EAAQ,KACpB,KAAK,QAAU,EAAa,mBAAmB,KAAK,MAAM,EAC1D,KAAK,aAAe,KAAK,aAAa,KAAK,IAAI,EAE/C,KAAK,QAAQ,YAAY,aAAa,EAEtC,KAAK,gBAAkB,IAAI,EAAe,CACxC,KAAM,WAAW,KAAK,QACtB,aAAc,KAAK,QAAQ,IAAI,CACjC,CAAC,EAGD,QAAW,KAAU,EAAQ,KAC3B,KAAK,QAAQ,UAAU,cAAe,4BAA6B,CAAE,OAAQ,EAAO,IAAK,CAAC,EAC1F,KAAK,0BAA0B,KAAK,EAAO,UAAU,KAAK,aAAc,CAAE,gBAAiB,EAAM,CAAC,CAAC,EAWhG,GAAG,EAAM,CACd,OAAO,KAAK,gBAAgB,IAAI,KAQvB,YAAW,EAAY,CAChC,OAAO,KAAK,gBAAgB,YAWvB,SAAS,CAAC,EAA8B,EAA6C,CAC1F,OAAO,KAAK,gBAAgB,UAAU,EAAU,CAAO,EAQlD,SAAS,EAAe,CAC7B,OAAO,KAAK,gBAAgB,UAAU,EAYjC,OAAO,EAAS,CAKrB,GAJA,KAAK,QAAQ,YAAY,SAAS,EAI9B,KAAK,YAAa,CACpB,KAAK,QAAQ,WAAW,UAAW,mBAAmB,EACtD,OAIF,QAAW,KAAgB,KAAK,0BAC9B,EAAa,YAAY,EAE3B,KAAK,0BAA0B,OAAS,EAExC,KAAK,gBAAgB,QAAQ,EAC7B,KAAK,QAAQ,YAAY,EACzB,KAAK,QAAU,UAWD,aAAY,EAAkB,CAG5C,GAFA,KAAK,QAAQ,YAAY,cAAc,EAEnC,KAAK,gBAAgB,YAAa,CAEpC,KAAK,QAAQ,WAAW,eAAgB,iCAAiC,EACzE,OAGF,GAAI,KAAK,kBAAmB,CAE1B,KAAK,QAAQ,UAAU,eAAgB,0CAA0C,EACjF,OAGF,KAAK,kBAAoB,GAEzB,GAAI,CAKF,GAFA,MAAM,EAAM,cAAc,EAEtB,KAAK,YAAa,CACpB,KAAK,QAAQ,WAAW,eAAgB,wBAAwB,EAChE,KAAK,kBAAoB,GACzB,OAGF,KAAK,QAAQ,UAAU,eAAgB,qBAAqB,EAG5D,KAAK,gBAAgB,IAAI,KAAK,QAAQ,IAAI,CAAC,EAE7C,MAAO,EAAK,CACV,KAAK,QAAQ,MAAM,eAAgB,uBAAwB,CAAG,EAIhE,KAAK,kBAAoB,GAE7B,CCvNA,gBAAS,sBACT,uBAAS,uBA2CF,MAAM,CAAsC,CAwC3B,QApCN,KAMG,QAMF,0BAA+C,CAAC,EAMzD,YAAc,GAMd,cAAgB,MAQb,YAAW,EAAY,CAChC,OAAO,KAAK,cAGd,WAAW,CAAW,EAA6B,CAA7B,eACpB,KAAK,KAAO,EAAQ,MAAQ,IAAI,EAAQ,KAAK,IAAI,CAAC,IAAQ,EAAI,IAAI,EAAE,KAAK,IAAI,KAC7E,KAAK,QAAU,EAAa,iBAAiB,KAAK,MAAM,EACxD,KAAK,mBAAqB,KAAK,mBAAmB,KAAK,IAAI,EAE3D,KAAK,QAAQ,YAAY,aAAa,EAItC,QAAW,KAAU,EAAQ,KAC3B,KAAK,QAAQ,UAAU,cAAe,4BAA6B,CAAE,OAAQ,EAAO,IAAK,CAAC,EAC1F,KAAK,0BAA0B,KAAK,EAAO,UAAU,KAAK,mBAAoB,CAAE,gBAAiB,EAAM,CAAC,CAAC,EAI3G,GAAI,EAAQ,iBAAmB,GAC7B,KAAK,QAAQ,UAAU,cAAe,8BAA8B,EAE/D,KAAK,mBAAmB,OAYjB,mBAAkB,EAAkB,CAGlD,GAFA,KAAK,QAAQ,YAAY,oBAAoB,EAEzC,KAAK,cAAe,CACtB,KAAK,QAAQ,WAAW,qBAAsB,wCAAwC,EACtF,OAEF,GAAI,KAAK,YAAa,CAEpB,KAAK,QAAQ,UAAU,qBAAsB,iCAAiC,EAC9E,OAGF,KAAK,YAAc,GAEnB,GAAI,CAGF,GADA,MAAM,EAAM,cAAc,EACtB,KAAK,cAAe,CACtB,KAAK,QAAQ,WAAW,qBAAsB,wBAAwB,EACtE,KAAK,YAAc,GACnB,OAGF,KAAK,QAAQ,UAAU,qBAAsB,kBAAkB,EAC/D,MAAM,KAAK,QAAQ,IAAI,EAEzB,MAAO,EAAK,CACV,KAAK,QAAQ,MAAM,qBAAsB,gBAAiB,CAAG,EAI/D,KAAK,YAAc,GAUd,OAAO,EAAS,CAGrB,GAFA,KAAK,QAAQ,YAAY,SAAS,EAE9B,KAAK,cAAe,CACtB,KAAK,QAAQ,WAAW,UAAW,mBAAmB,EACtD,OAGF,KAAK,cAAgB,GAGrB,QAAW,KAAgB,KAAK,0BAC9B,EAAa,YAAY,EAE3B,KAAK,0BAA0B,OAAS,EAExC,KAAK,QAAQ,YAAY,EACzB,KAAK,QAAU,KAEnB,CC/KA,0BAAQ,yBACR,qCAAQ,8BAeD,MAAM,UAAiC,CAAe,CAK1C,kBAMA,mBAQA,0BAEjB,WAAW,CAAC,EAAwC,CAClD,IAAO,OAAM,aAAa,EAAM,oBAAoB,IAAK,eAAc,YAAW,iBAAiB,EAE7F,EAAkB,EAA8B,CACpD,KAAM,EACN,eACF,CAAC,EAED,MAAM,CACJ,OACA,aAAc,EAAgB,KAAK,GAAK,EACxC,WACF,CAAC,EAED,KAAK,QAAQ,gBAAgB,cAAe,CAAM,EAElD,KAAK,kBAAoB,EAEzB,KAAK,mBAAqB,EAAgB,CACxC,MAAO,EACP,QAAS,GACT,SAAU,GACV,YAAa,KACb,KAAM,KAAK,aACb,CAAC,EAED,KAAK,0BAA4B,KAAK,UAAU,KAAK,mBAAmB,QAAS,CAAC,gBAAiB,EAAK,CAAC,EAOnG,aAAa,CAAC,EAAmB,CACvC,KAAK,QAAQ,gBAAgB,gBAAiB,CAAQ,EACtD,KAAK,kBAAkB,MAAM,CAAQ,EAOhC,MAAM,EAAS,CACpB,KAAK,gBAAgB,EACrB,KAAK,QAAQ,YAAY,QAAQ,EAEjC,KAAK,kBAAkB,OAAO,EAMhB,OAAO,EAAS,CAC9B,KAAK,QAAQ,YAAY,SAAS,EAElC,KAAK,mBAAmB,MAAM,EAE9B,KAAK,0BAA0B,YAAY,EAC3C,MAAM,QAAQ,EAElB,CCjGA,0BAAQ,yBACR,uCAAQ,gCAiDD,MAAM,UAA8B,CAAe,CAKvC,kBAMA,mBAMA,0BAEjB,WAAW,CAAC,EAAqC,CAC/C,IAAO,OAAM,aAAa,EAAM,oBAAoB,IAAK,eAAc,aAAa,EAE9E,EAAkB,EAAgC,CAAC,KAAM,CAAU,CAAC,EAE1E,MAAM,CACJ,OACA,aAAc,EAAgB,KAAK,GAAK,EACxC,WACF,CAAC,EAED,KAAK,QAAQ,gBAAgB,cAAe,CAAM,EAElD,KAAK,kBAAoB,EAEzB,KAAK,mBAAqB,EAAgB,CACxC,MAAO,EACP,QAAS,GACT,SAAU,GACV,YAAa,KACb,KAAM,KAAK,aACb,CAAC,EAED,KAAK,0BAA4B,KAAK,UAAU,KAAK,mBAAmB,QAAS,CAAC,gBAAiB,EAAK,CAAC,EASnG,aAAa,CAAC,EAAmB,CACvC,KAAK,QAAQ,gBAAgB,gBAAiB,CAAQ,EACtD,KAAK,kBAAkB,MAAM,CAAQ,EAehC,MAAM,EAAS,CACpB,KAAK,gBAAgB,EACrB,KAAK,QAAQ,YAAY,QAAQ,EACjC,KAAK,kBAAkB,OAAO,EAehB,OAAO,EAAS,CAC9B,KAAK,QAAQ,YAAY,SAAS,EAElC,KAAK,mBAAmB,MAAM,EAE9B,KAAK,0BAA0B,YAAY,EAC3C,MAAM,QAAQ,EAElB,CC/IA,gBAAQ,sBACR,uBAAQ,uBAyHD,MAAM,UAA2C,CAAiC,CAK7E,QAeO,gBAAkB,IAAI,IAEvC,WAAW,CAAC,EAA6B,CACvC,MAAM,CAAM,EACZ,KAAK,QAAU,EAAa,kBAAkB,KAAK,MAAM,EACzD,KAAK,QAAQ,YAAY,aAAa,EA6BjC,QAA8B,IAAI,EAAmC,CAC1E,IAAO,EAAM,GAAW,EACxB,KAAK,QAAQ,gBAAgB,WAAY,CAAC,OAAM,SAAO,CAAC,EACxD,KAAK,gBAAgB,EACrB,EAAM,cAAc,EAAE,KAAK,IAAM,KAAK,QAAQ,EAAM,CAAO,CAAC,EA8BvD,EAAwB,CAC7B,EACA,EACA,EACiB,CACjB,KAAK,QAAQ,gBAAgB,KAAM,CAAC,MAAI,CAAC,EACzC,KAAK,gBAAgB,EAGrB,IAAI,EAAa,KAAK,gBAAgB,IAAI,CAAI,EAC9C,GAAI,CAAC,EACH,EAAa,IAAI,IACjB,KAAK,gBAAgB,IAAI,EAAM,CAAU,EAG3C,IAAM,EAAQ,CAAC,QAAS,EAA4B,KAAM,GAAS,MAAQ,EAAK,EAGhF,OAFA,EAAW,IAAI,CAAK,EAEb,CACL,YAAa,IAAY,CAGvB,GAFA,EAAY,OAAO,CAAK,EAEpB,EAAY,OAAS,EACvB,KAAK,gBAAgB,OAAO,CAAI,EAGtC,EAsBc,SAAS,CACvB,EACA,EACiB,CAEjB,OADA,KAAK,QAAQ,gBAAgB,YAAa,CAAO,EAC1C,MAAM,UAAU,EAAU,CAAO,EAYlC,OAA6B,CAAC,EAAS,EAAoC,CACjF,GAAI,KAAK,YAAa,OAEtB,IAAM,EAAa,KAAK,gBAAgB,IAAI,CAAI,EAChD,GAAI,GAAY,KACd,QAAW,KAAS,EAAY,CAC9B,GAAI,EAAM,MAER,GADA,EAAW,OAAO,CAAK,EACnB,EAAW,OAAS,EAAG,KAAK,gBAAgB,OAAO,CAAI,EAE7D,GAAI,CACF,IAAM,EAAS,EAAM,QAAQ,CAAO,EACpC,GAAI,aAAkB,QACpB,EAAO,MAAM,CAAC,IAAQ,KAAK,QAAQ,MAAM,UAAW,6BAA8B,CAAG,CAAC,EAExF,MAAO,EAAK,CACZ,KAAK,QAAQ,MAAM,UAAW,4BAA6B,CAAG,GAMpE,KAAK,QAAQ,CAAC,OAAM,SAAO,CAAyB,EAMtC,OAAO,EAAS,CAC9B,KAAK,gBAAgB,MAAM,EAC3B,MAAM,QAAQ,EAElB,CCxRO,SAAS,EAA2B,CAAC,EAAsC,CAChF,OAAO,IAAI,EAAe,CAAM,ECJ3B,SAAS,CAAoB,CAAC,EAA8C,CACjF,OAAO,IAAI,EAAY,CAAM,ECQxB,SAAS,CAAuB,CAAC,EAAoD,CAC1F,OAAO,IAAI,EAAe,CAAM,ECQ3B,SAAS,EAAY,CAAC,EAA0C,CACrE,OAAO,IAAI,EAAa,CAAM,ECdzB,SAAS,EAA8B,CAAC,EAAkE,CAC/G,OAAO,IAAI,EAAsB,CAAM,ECQlC,SAAS,EAA2B,CAAC,EAA4D,CACtG,OAAO,IAAI,EAAmB,CAAM,ECD/B,SAAS,EAAwC,CAAC,EAAkD,CACzG,OAAO,IAAI,EAAoB,CAAM,ECxCvC,0BAAQ,yBA6DD,SAAS,EAAwB,CAAC,EAAkC,EAAiD,CAC1H,IAAM,EAAO,EAAO,MAAQ,GAAG,EAAa,iBAEtC,EAAiB,IAAI,EAAe,CACxC,KAAM,GAAG,aACT,aAAc,EAAa,IAAI,CACjC,CAAC,EAEK,EAAY,EAAgB,IAC7B,EACH,YAAa,EACb,KAAM,EAAe,GACvB,CAAC,EAEK,EAAe,EAAa,UAAU,EAAU,QAAS,CAAC,gBAAiB,EAAK,CAAC,EAEvF,OAAO,EAAqB,CAC1B,KAAM,EACN,KAAM,CAAC,CAAc,EACrB,IAAK,IAAM,EAAe,IAAI,EAC9B,UAAW,IAAM,CACf,GAAI,EAAe,YAAa,OAChC,EAAa,YAAY,EACzB,EAAU,OAAO,EACjB,EAAe,QAAQ,EACvB,EAAO,YAAY,EACnB,EAAS,KAEb,CAAC,ECxCI,SAAS,EAAuB,CACrC,EACA,EACA,EAAO,GAAG,EAAa,gBACQ,CAC/B,IAAM,EAAc,EAAa,IAAI,EAC/B,EAAe,EAAU,CAAW,EAAI,EAAc,OAEtD,EAAiB,EAAkB,CACvC,KAAM,GAAG,aACT,cACF,CAAC,EAEK,EAAe,EAAa,UAAU,CAAC,IAAa,CACxD,GAAI,EAAU,CAAQ,EACpB,EAAe,IAAI,CAAQ,EAE9B,EAED,OAAO,EAAqB,CAC1B,KAAM,EACN,KAAM,CAAC,CAAc,EACrB,IAAK,IAAM,EAAe,IAAI,EAC9B,UAAW,IAAM,CACf,EAAa,YAAY,EACzB,EAAe,QAAQ,EAE3B,CAAC,ECvCI,SAAS,EAAwB,CACtC,EACA,EACA,EAAO,GAAG,EAAa,cACJ,CACnB,OAAO,EAAqB,CAC1B,KAAM,EACN,KAAM,CAAC,CAAY,EACnB,IAAK,IAAM,EAAgB,EAAa,IAAI,CAAC,CAC/C,CAAC",
25
+ "debugId": "37136463C45B4D5764756E2164756E21",
26
26
  "names": []
27
27
  }
package/dist/type.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import type { Awaitable } from '@alwatr/type-helper';
1
2
  import type { DebouncerConfig } from '@alwatr/debounce';
2
3
  import type { LocalStorageProviderConfig } from '@alwatr/local-storage';
3
4
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"type.d.ts","sourceRoot":"","sources":["../src/type.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"type.d.ts","sourceRoot":"","sources":["../src/type.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alwatr/signal",
3
- "version": "9.13.0",
3
+ "version": "9.14.0",
4
4
  "description": "Alwatr Signal is a powerful, lightweight, and modern reactive programming library. It is inspired by the best concepts from major reactive libraries but engineered to be faster and more efficient than all of them. It provides a robust and elegant way to manage application state through a system of signals, offering fine-grained reactivity, predictability, and excellent performance.",
5
5
  "license": "MPL-2.0",
6
6
  "author": "S. Ali Mihandoost <ali.mihandoost@gmail.com> (https://ali.mihandoost.com)",
@@ -21,16 +21,16 @@
21
21
  },
22
22
  "sideEffects": false,
23
23
  "dependencies": {
24
- "@alwatr/debounce": "9.11.2",
25
- "@alwatr/delay": "9.11.2",
26
- "@alwatr/local-storage": "9.11.2",
27
- "@alwatr/logger": "9.11.2",
28
- "@alwatr/session-storage": "9.11.2"
24
+ "@alwatr/debounce": "9.14.0",
25
+ "@alwatr/delay": "9.14.0",
26
+ "@alwatr/local-storage": "9.14.0",
27
+ "@alwatr/logger": "9.14.0",
28
+ "@alwatr/session-storage": "9.14.0"
29
29
  },
30
30
  "devDependencies": {
31
- "@alwatr/nano-build": "9.10.1",
32
- "@alwatr/standard": "9.11.2",
33
- "@alwatr/type-helper": "9.11.2",
31
+ "@alwatr/nano-build": "9.14.0",
32
+ "@alwatr/standard": "9.14.0",
33
+ "@alwatr/type-helper": "9.14.0",
34
34
  "typescript": "^6.0.3"
35
35
  },
36
36
  "scripts": {
@@ -66,5 +66,5 @@
66
66
  "signal",
67
67
  "typescript"
68
68
  ],
69
- "gitHead": "da284d23e3173d589fa69376e51a098c5e89649d"
69
+ "gitHead": "4e499b23191d4460ea60f34cde8a99b472741f1a"
70
70
  }
@@ -1,3 +1,4 @@
1
+ import type {Awaitable} from '@alwatr/type-helper';
1
2
  import {delay} from '@alwatr/delay';
2
3
  import {createLogger, type AlwatrLogger} from '@alwatr/logger';
3
4
 
@@ -7,29 +8,67 @@ import type {SignalConfig, SubscribeOptions, SubscribeResult, ListenerCallback}
7
8
 
8
9
  // ─── Types ────────────────────────────────────────────────────────────────────
9
10
 
11
+ /**
12
+ * Determines whether the payload argument for a given channel message is
13
+ * required or optional, based solely on the declared type in `TMap`.
14
+ *
15
+ * - `void | undefined` → payload is optional (second arg may be omitted).
16
+ * - anything else → payload is **required** (omitting it is a compile error).
17
+ *
18
+ * This is used to build the rest-parameter tuple for `dispatch()` so that
19
+ * TypeScript enforces the correct call signature at every dispatch site.
20
+ *
21
+ * @template TMap A record mapping message names to their payload types.
22
+ * @template K The specific message name key.
23
+ *
24
+ * @example
25
+ * ```ts
26
+ * // ActionRecord: { 'logout': void; 'add-to-cart': {productId: number} }
27
+ * type A = DispatchArgs<ActionRecord, 'logout'>; // [name: 'logout', payload?: void]
28
+ * type B = DispatchArgs<ActionRecord, 'add-to-cart'>; // [name: 'add-to-cart', payload: {productId: number}]
29
+ * ```
30
+ */
31
+ export type DispatchArgs<TMap extends object, K extends keyof TMap> =
32
+ TMap[K] extends void | undefined ? [name: K, payload?: TMap[K]] : [name: K, payload: TMap[K]];
33
+
10
34
  /**
11
35
  * A single message dispatched through a `ChannelSignal`.
12
36
  *
13
37
  * `name` identifies the message type (e.g. `'open-drawer'`, `'add-to-cart'`).
14
- * `payload` is the optional value attached to the message its type is narrowed
15
- * by the generic map `TMap` at the class level.
38
+ * `payload` carries the associated data, whose type is determined by the generic `TMap` based on the `name`.
16
39
  *
17
40
  * @template TMap A record mapping message names to their payload types.
18
41
  * @template K The specific message name key (inferred, not set manually).
19
42
  */
20
- export type ChannelMessage<TMap extends Record<string, unknown>, K extends keyof TMap = keyof TMap> =
21
- K extends keyof TMap ? {name: K; payload?: TMap[K]} : never;
43
+ export type ChannelMessage<TMap extends object, K extends keyof TMap = keyof TMap> = {name: K; payload: TMap[K]};
22
44
 
23
45
  /**
24
46
  * A typed handler for a specific named message on a `ChannelSignal`.
25
47
  * Receives only the `payload` — the name is already known at subscription time.
26
48
  *
49
+ * The payload type mirrors `DispatchArgs`: it is `TMap[K] | undefined` only
50
+ * when the declared type is `void | undefined`; otherwise it is exactly `TMap[K]`
51
+ * (non-optional) so handlers do not need unnecessary null-guards.
52
+ *
27
53
  * @template TMap A record mapping message names to their payload types.
28
54
  * @template K The specific message name key.
29
55
  */
30
- export type ChannelHandler<TMap extends Record<string, unknown>, K extends keyof TMap> = (
31
- payload: TMap[K] | undefined,
32
- ) => void | Promise<void>;
56
+ export type ChannelHandler<TMap extends object, K extends keyof TMap = keyof TMap> = (
57
+ payload: TMap[K],
58
+ ) => Awaitable<void>;
59
+
60
+ /**
61
+ * Internal handler type used inside `namedHandlers__`.
62
+ *
63
+ * At the storage boundary we erase the conditional payload type to `unknown`
64
+ * so TypeScript does not need to evaluate the conditional against every
65
+ * possible `K`. Type safety is already enforced at the public `on()` and
66
+ * `dispatch()` call sites — the internal executor only needs to call the
67
+ * function with the value it received.
68
+ *
69
+ * @internal
70
+ */
71
+ type InternalHandler = (payload: unknown) => Awaitable<void>;
33
72
 
34
73
  /**
35
74
  * Configuration for creating a `ChannelSignal`.
@@ -82,7 +121,7 @@ export interface ChannelSignalConfig extends SignalConfig {}
82
121
  * appChannel.dispatch('close-drawer'); // no payload needed
83
122
  * ```
84
123
  */
85
- export class ChannelSignal<TMap extends Record<string, unknown>> extends SignalBase<ChannelMessage<TMap>> {
124
+ export class ChannelSignal<TMap extends object> extends SignalBase<ChannelMessage<TMap>> {
86
125
  /**
87
126
  * The logger instance for this signal.
88
127
  * @protected
@@ -96,10 +135,13 @@ export class ChannelSignal<TMap extends Record<string, unknown>> extends SignalB
96
135
  * registered via `on()`. Kept separate from `SignalBase`'s observer list so
97
136
  * that `subscribe()` (raw stream) and `on()` (named routing) never interfere.
98
137
  *
138
+ * Stored as `InternalHandler` (erased to `unknown` payload) to avoid
139
+ * unevaluable conditional types at the storage boundary. Type safety is
140
+ * enforced at the public `on()` and `dispatch()` call sites.
141
+ *
99
142
  * @private
100
143
  */
101
- private readonly namedHandlers__: Map<keyof TMap, Set<{handler: ChannelHandler<TMap, keyof TMap>; once: boolean}>> =
102
- new Map();
144
+ private readonly namedHandlers__ = new Map<keyof TMap, Set<{handler: InternalHandler; once: boolean}>>();
103
145
 
104
146
  constructor(config: ChannelSignalConfig) {
105
147
  super(config);
@@ -115,20 +157,26 @@ export class ChannelSignal<TMap extends Record<string, unknown>> extends SignalB
115
157
  * The notification is scheduled as a microtask to ensure non-blocking,
116
158
  * consistent delivery — matching the behavior of `EventSignal`.
117
159
  *
118
- * TypeScript enforces that `payload` matches the type declared for `name`
119
- * in `TMap`. If the payload type is `void` or `undefined`, the argument can
120
- * be omitted entirely.
160
+ * ### Payload enforcement
121
161
  *
122
- * @param name The message name (must be a key of `TMap`).
123
- * @param payload The optional payload for the message.
162
+ * The payload argument is **required** unless the declared type in `TMap` is
163
+ * `void` or `undefined`. Omitting a required payload or passing `undefined`
164
+ * for a non-optional type — is a **compile error**. This prevents accidental
165
+ * `undefined` from propagating into handlers that expect a real value.
124
166
  *
125
- * @example
126
167
  * ```ts
127
- * channel.dispatch('open-drawer', {panel: 'settings'});
128
- * channel.dispatch('close-drawer'); // no payload needed
168
+ * // TMap: { 'add-to-cart': {productId: number}; 'logout': void }
169
+ * channel.dispatch('add-to-cart', {productId: 42}); // required payload
170
+ * channel.dispatch('add-to-cart'); // ❌ compile error
171
+ * channel.dispatch('logout'); // ✅ void — no payload
172
+ * channel.dispatch('logout', undefined); // ✅ also fine
129
173
  * ```
174
+ *
175
+ * @param args Tuple of `[name, payload]` — payload optionality is enforced
176
+ * by `DispatchArgs<TMap, K>` based on the declared type.
130
177
  */
131
- public dispatch<K extends keyof TMap>(name: K, payload?: TMap[K]): void {
178
+ public dispatch<K extends keyof TMap>(...args: DispatchArgs<TMap, K>): void {
179
+ const [name, payload] = args;
132
180
  this.logger_.logMethodArgs?.('dispatch', {name, payload});
133
181
  this.checkDestroyed_();
134
182
  delay.nextMicrotask().then(() => this.route__(name, payload));
@@ -176,9 +224,7 @@ export class ChannelSignal<TMap extends Record<string, unknown>> extends SignalB
176
224
  this.namedHandlers__.set(name, handlerSet);
177
225
  }
178
226
 
179
- // Cast is safe: K extends keyof TMap, so ChannelHandler<TMap, K> is
180
- // assignable to ChannelHandler<TMap, keyof TMap> at runtime.
181
- const entry = {handler: handler as ChannelHandler<TMap, keyof TMap>, once: options?.once ?? false};
227
+ const entry = {handler: handler as InternalHandler, once: options?.once ?? false};
182
228
  handlerSet.add(entry);
183
229
 
184
230
  return {
@@ -250,7 +296,7 @@ export class ChannelSignal<TMap extends Record<string, unknown>> extends SignalB
250
296
  }
251
297
 
252
298
  // ── Raw-stream subscribers (SignalBase observers) ─────────────────────────
253
- this.notify_({name, payload} as unknown as ChannelMessage<TMap>);
299
+ this.notify_({name, payload} as ChannelMessage<TMap>);
254
300
  }
255
301
 
256
302
  /**
@@ -37,8 +37,6 @@ import type {ChannelSignalConfig} from '../core/channel-signal.js';
37
37
  * appChannel.dispatch('close-drawer');
38
38
  * ```
39
39
  */
40
- export function createChannelSignal<TMap extends Record<string, unknown>>(
41
- config: ChannelSignalConfig,
42
- ): ChannelSignal<TMap> {
40
+ export function createChannelSignal<TMap extends object>(config: ChannelSignalConfig): ChannelSignal<TMap> {
43
41
  return new ChannelSignal<TMap>(config);
44
42
  }
package/src/type.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import type {Awaitable} from '@alwatr/type-helper';
1
2
  import type {DebouncerConfig} from '@alwatr/debounce';
2
3
  import type {LocalStorageProviderConfig} from '@alwatr/local-storage';
3
4