@alwatr/signal 9.26.0 → 9.30.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.
- package/README.md +197 -603
- package/dist/core/channel-signal.d.ts +12 -53
- package/dist/core/channel-signal.d.ts.map +1 -1
- package/dist/core/computed-signal.d.ts +19 -33
- package/dist/core/computed-signal.d.ts.map +1 -1
- package/dist/core/derived-signal.d.ts +71 -0
- package/dist/core/derived-signal.d.ts.map +1 -0
- package/dist/core/effect-signal.d.ts +15 -1
- package/dist/core/effect-signal.d.ts.map +1 -1
- package/dist/core/event-signal.d.ts +11 -4
- package/dist/core/event-signal.d.ts.map +1 -1
- package/dist/core/persistent-state-signal.d.ts +21 -2
- package/dist/core/persistent-state-signal.d.ts.map +1 -1
- package/dist/core/session-state-signal.d.ts +19 -2
- package/dist/core/session-state-signal.d.ts.map +1 -1
- package/dist/core/signal-base.d.ts +58 -38
- package/dist/core/signal-base.d.ts.map +1 -1
- package/dist/core/state-signal.d.ts +33 -14
- package/dist/core/state-signal.d.ts.map +1 -1
- package/dist/creators/channel.d.ts +1 -1
- package/dist/creators/channel.d.ts.map +1 -1
- package/dist/creators/derived.d.ts +31 -0
- package/dist/creators/derived.d.ts.map +1 -0
- package/dist/main.d.ts +2 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +3 -3
- package/dist/main.js.map +16 -15
- package/dist/operators/debounce.d.ts +2 -3
- package/dist/operators/debounce.d.ts.map +1 -1
- package/dist/operators/filter.d.ts +14 -13
- package/dist/operators/filter.d.ts.map +1 -1
- package/dist/type.d.ts +68 -3
- package/dist/type.d.ts.map +1 -1
- package/package.json +6 -6
- package/src/core/channel-signal.ts +25 -68
- package/src/core/computed-signal.ts +50 -74
- package/src/core/derived-signal.ts +166 -0
- package/src/core/effect-signal.ts +23 -11
- package/src/core/event-signal.ts +14 -9
- package/src/core/persistent-state-signal.ts +21 -4
- package/src/core/session-state-signal.ts +19 -4
- package/src/core/signal-base.ts +98 -61
- package/src/core/state-signal.ts +48 -29
- package/src/creators/channel.ts +1 -2
- package/src/creators/derived.ts +34 -0
- package/src/main.ts +2 -1
- package/src/operators/debounce.ts +13 -23
- package/src/operators/filter.ts +20 -26
- package/src/type.ts +71 -3
- package/dist/operators/map.d.ts +0 -36
- package/dist/operators/map.d.ts.map +0 -1
- package/src/operators/map.ts +0 -48
|
@@ -1,100 +1,120 @@
|
|
|
1
1
|
import type { Observer_, SubscribeOptions, SubscribeResult, ListenerCallback, SignalConfig } from '../type.js';
|
|
2
2
|
import type { AlwatrLogger } from '@alwatr/logger';
|
|
3
3
|
/**
|
|
4
|
-
* An abstract base class for signal implementations.
|
|
5
|
-
* It provides the core functionality for managing subscriptions (observers).
|
|
4
|
+
* An abstract base class for all signal implementations in the `@alwatr/signal` package.
|
|
6
5
|
*
|
|
7
|
-
*
|
|
6
|
+
* It provides core subscription management capabilities, including priority observer queues,
|
|
7
|
+
* microtask/macrotask-friendly updates, type-safe unsubscribes, async promise resolution via `untilNext`,
|
|
8
|
+
* and safe destruction lifecycles to prevent memory leaks.
|
|
9
|
+
*
|
|
10
|
+
* @template T The type of data that the signal holds, dispatches, or streams.
|
|
8
11
|
*/
|
|
9
12
|
export declare abstract class SignalBase<T> {
|
|
10
13
|
protected config_: SignalConfig;
|
|
11
14
|
/**
|
|
12
15
|
* The unique identifier for this signal instance.
|
|
13
|
-
*
|
|
16
|
+
* Highly useful for debugging, filtering logs, and tracing data flows.
|
|
14
17
|
*/
|
|
15
18
|
readonly name: string;
|
|
16
19
|
/**
|
|
17
20
|
* The logger instance for this signal.
|
|
21
|
+
* Custom scoped logger based on the signal name and type.
|
|
22
|
+
*
|
|
18
23
|
* @protected
|
|
19
24
|
*/
|
|
20
25
|
protected abstract logger_: AlwatrLogger;
|
|
21
26
|
/**
|
|
22
|
-
*
|
|
27
|
+
* High-priority observers that are executed first during notifications.
|
|
28
|
+
* Allocated lazily upon the first priority subscription to guard heap memory.
|
|
29
|
+
*
|
|
30
|
+
* @protected
|
|
31
|
+
*/
|
|
32
|
+
protected priorityObservers_?: Set<Observer_<T>>;
|
|
33
|
+
/**
|
|
34
|
+
* Standard-priority observers executed after priority observers.
|
|
35
|
+
* Allocated lazily upon the first standard subscription to guard heap memory.
|
|
36
|
+
*
|
|
23
37
|
* @protected
|
|
24
38
|
*/
|
|
25
|
-
protected
|
|
26
|
-
protected readonly observers_: Set<Observer_<T>>;
|
|
39
|
+
protected observers_?: Set<Observer_<T>>;
|
|
27
40
|
/**
|
|
28
|
-
*
|
|
41
|
+
* Internal flag representing whether the signal has been destroyed.
|
|
42
|
+
*
|
|
29
43
|
* @private
|
|
30
44
|
*/
|
|
31
45
|
private isDestroyed__;
|
|
32
46
|
/**
|
|
33
47
|
* Indicates whether the signal has been destroyed.
|
|
34
|
-
* A destroyed signal cannot be
|
|
48
|
+
* A destroyed signal cannot be subscribed to or dispatched to.
|
|
35
49
|
*
|
|
36
50
|
* @returns `true` if the signal is destroyed, `false` otherwise.
|
|
37
51
|
*/
|
|
38
52
|
get isDestroyed(): boolean;
|
|
53
|
+
/**
|
|
54
|
+
* Creates a new instance of the signal base.
|
|
55
|
+
*
|
|
56
|
+
* @param config_ Configuration options including the unique signal name and cleanup hooks.
|
|
57
|
+
*/
|
|
39
58
|
constructor(config_: SignalConfig);
|
|
40
59
|
/**
|
|
41
|
-
* Removes a specific observer from the
|
|
60
|
+
* Removes a specific observer from both the standard and priority observer queues.
|
|
42
61
|
*
|
|
43
|
-
* @param observer The observer
|
|
62
|
+
* @param observer The observer wrapper object containing the callback and options to remove.
|
|
44
63
|
* @protected
|
|
45
64
|
*/
|
|
46
65
|
protected removeObserver_(observer: Observer_<T>): void;
|
|
47
66
|
/**
|
|
48
67
|
* Subscribes a listener function to this signal.
|
|
49
68
|
*
|
|
50
|
-
* The listener will be called whenever the signal
|
|
69
|
+
* The listener will be called whenever the signal notifies its observers.
|
|
51
70
|
*
|
|
52
|
-
* @param callback The function to
|
|
53
|
-
* @param options
|
|
54
|
-
* @returns
|
|
71
|
+
* @param callback The function to invoke when the signal dispatches a new value.
|
|
72
|
+
* @param options Custom options to control priority, immediate callback, or single execution.
|
|
73
|
+
* @returns An object with an `unsubscribe` method to remove the subscription.
|
|
55
74
|
*/
|
|
56
75
|
subscribe(callback: ListenerCallback<T>, options?: SubscribeOptions): SubscribeResult;
|
|
57
76
|
/**
|
|
58
|
-
* Notifies all registered observers
|
|
59
|
-
*
|
|
60
|
-
* This method iterates through a snapshot of the current observers to prevent issues
|
|
61
|
-
* with subscriptions changing during notification (e.g., an observer unsubscribing itself).
|
|
77
|
+
* Notifies all registered priority and standard observers with the given value.
|
|
78
|
+
* Iterates synchronously over current queues.
|
|
62
79
|
*
|
|
63
|
-
* @param value The
|
|
80
|
+
* @param value The value to pass to each observer's callback.
|
|
64
81
|
* @protected
|
|
65
82
|
*/
|
|
66
83
|
protected notify_(value: T): void;
|
|
67
84
|
/**
|
|
68
|
-
* Executes a
|
|
85
|
+
* Executes a single observer's callback, handles auto-unsubscribing for `once` listeners,
|
|
86
|
+
* and wraps execution in a try-catch block to prevent observer exceptions from crashing the signal.
|
|
87
|
+
*
|
|
88
|
+
* @param observer The observer descriptor to execute.
|
|
89
|
+
* @param value The value to supply to the observer's callback.
|
|
90
|
+
* @private
|
|
69
91
|
*/
|
|
70
92
|
private executeObserver__;
|
|
71
|
-
private pendingRejects__;
|
|
72
93
|
/**
|
|
73
|
-
*
|
|
74
|
-
*
|
|
94
|
+
* Holds the promise rejection functions of any pending `untilNext` invocations
|
|
95
|
+
* to reject them if the signal is destroyed.
|
|
75
96
|
*
|
|
76
|
-
* @
|
|
97
|
+
* @private
|
|
98
|
+
*/
|
|
99
|
+
private pendingRejects__?;
|
|
100
|
+
/**
|
|
101
|
+
* Returns a Promise that resolves with the next value/payload dispatched by the signal.
|
|
102
|
+
* Use this for async orchestration (e.g. `await signal.untilNext()`).
|
|
77
103
|
*
|
|
78
|
-
* @
|
|
79
|
-
* async function onButtonClick() {
|
|
80
|
-
* console.log('Waiting for the next signal...');
|
|
81
|
-
* const nextValue = await mySignal.untilNext();
|
|
82
|
-
* console.log('Signal received:', nextValue);
|
|
83
|
-
* }
|
|
104
|
+
* @returns A Promise that resolves with the next value dispatched by the signal.
|
|
84
105
|
*/
|
|
85
106
|
untilNext(): Promise<T>;
|
|
86
107
|
/**
|
|
87
|
-
*
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
* will throw an error. This is crucial for preventing memory leaks by allowing
|
|
91
|
-
* garbage collection of the signal and its observers.
|
|
108
|
+
* Permanently destroys the signal instance.
|
|
109
|
+
* Clears all observers, rejects pending `untilNext` promises with a 'signal_destroyed' error,
|
|
110
|
+
* invokes the optional `onDestroy` config hook, and breaks internal references to facilitate GC.
|
|
92
111
|
*/
|
|
93
112
|
destroy(): void;
|
|
94
113
|
/**
|
|
95
|
-
*
|
|
96
|
-
*
|
|
114
|
+
* Checks if the signal has been destroyed. If so, throws an error and logs an accident.
|
|
115
|
+
*
|
|
97
116
|
* @protected
|
|
117
|
+
* @throws {Error} If the signal has been destroyed.
|
|
98
118
|
*/
|
|
99
119
|
protected checkDestroyed_(): void;
|
|
100
120
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"signal-base.d.ts","sourceRoot":"","sources":["../../src/core/signal-base.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,SAAS,EAAE,gBAAgB,EAAE,eAAe,EAAE,gBAAgB,EAAE,YAAY,EAAC,MAAM,YAAY,CAAC;AAC7G,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,gBAAgB,CAAC;AAEjD
|
|
1
|
+
{"version":3,"file":"signal-base.d.ts","sourceRoot":"","sources":["../../src/core/signal-base.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,SAAS,EAAE,gBAAgB,EAAE,eAAe,EAAE,gBAAgB,EAAE,YAAY,EAAC,MAAM,YAAY,CAAC;AAC7G,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,gBAAgB,CAAC;AAEjD;;;;;;;;GAQG;AACH,8BAAsB,UAAU,CAAC,CAAC;IAqDpB,SAAS,CAAC,OAAO,EAAE,YAAY;IApD3C;;;OAGG;IACH,SAAgB,IAAI,EAAE,MAAM,CAAC;IAE7B;;;;;OAKG;IACH,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAC;IAEzC;;;;;OAKG;IACH,SAAS,CAAC,kBAAkB,CAAC,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;IAEjD;;;;;OAKG;IACH,SAAS,CAAC,UAAU,CAAC,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;IAEzC;;;;OAIG;IACH,OAAO,CAAC,aAAa,CAAS;IAE9B;;;;;OAKG;IACH,IAAW,WAAW,IAAI,OAAO,CAEhC;IAED;;;;OAIG;gBACmB,OAAO,EAAE,YAAY;IAI3C;;;;;OAKG;IACH,SAAS,CAAC,eAAe,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,IAAI;IAqBvD;;;;;;;;OAQG;IACI,SAAS,CAAC,QAAQ,EAAE,gBAAgB,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,eAAe;IAoB5F;;;;;;OAMG;IACH,SAAS,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI;IAuBjC;;;;;;;OAOG;IACH,OAAO,CAAC,iBAAiB;IAWzB;;;;;OAKG;IACH,OAAO,CAAC,gBAAgB,CAAC,CAA8B;IAEvD;;;;;OAKG;IACI,SAAS,IAAI,OAAO,CAAC,CAAC,CAAC;IAoB9B;;;;OAIG;IACI,OAAO,IAAI,IAAI;IAsBtB;;;;;OAKG;IACH,SAAS,CAAC,eAAe,IAAI,IAAI;CAMlC"}
|
|
@@ -37,39 +37,52 @@ import type { StateSignalConfig, ListenerCallback, SubscribeOptions, SubscribeRe
|
|
|
37
37
|
export declare class StateSignal<T> extends SignalBase<T> implements IReadonlySignal<T> {
|
|
38
38
|
/**
|
|
39
39
|
* The current value of the signal.
|
|
40
|
+
*
|
|
40
41
|
* @private
|
|
41
42
|
*/
|
|
42
43
|
private value__;
|
|
43
44
|
/**
|
|
44
45
|
* The logger instance for this signal.
|
|
46
|
+
*
|
|
45
47
|
* @protected
|
|
46
48
|
*/
|
|
47
49
|
protected logger_: AlwatrLogger;
|
|
48
50
|
/**
|
|
49
51
|
* Indicates if a notification is already scheduled.
|
|
52
|
+
* Helps batch multiple synchronous `set` operations into a single microtask notification.
|
|
53
|
+
*
|
|
50
54
|
* @private
|
|
51
55
|
*/
|
|
52
56
|
private notifyPending__;
|
|
53
57
|
/**
|
|
54
|
-
* The version of the last notification.
|
|
58
|
+
* The version of the last notification. Incrementing on every state update.
|
|
59
|
+
* Used to guard immediate subscriber execution when updates happen within the same tick.
|
|
60
|
+
*
|
|
55
61
|
* @private
|
|
56
62
|
*/
|
|
57
63
|
private notifyVersion__;
|
|
64
|
+
/**
|
|
65
|
+
* Creates a new StateSignal instance.
|
|
66
|
+
*
|
|
67
|
+
* @param config Configuration options including name, initialValue, and custom cleanup hooks.
|
|
68
|
+
*/
|
|
58
69
|
constructor(config: StateSignalConfig<T>);
|
|
59
70
|
/**
|
|
60
71
|
* Retrieves the current value of the signal.
|
|
61
72
|
*
|
|
62
73
|
* @returns The current value.
|
|
74
|
+
* @throws {Error} If the signal has been destroyed.
|
|
63
75
|
*
|
|
64
76
|
* @example
|
|
65
77
|
* console.log(mySignal.get());
|
|
66
78
|
*/
|
|
67
79
|
get(): T;
|
|
68
80
|
/**
|
|
69
|
-
* Updates the signal's value and
|
|
81
|
+
* Updates the signal's value and schedules notifications for all active listeners.
|
|
70
82
|
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
83
|
+
* Primitives are comparison-checked via `Object.is`. If unchanged, the update is ignored.
|
|
84
|
+
* The notification is scheduled as a microtask, allowing multiple synchronous updates
|
|
85
|
+
* to be batched and executed once.
|
|
73
86
|
*
|
|
74
87
|
* @param newValue The new value to set.
|
|
75
88
|
*
|
|
@@ -82,18 +95,18 @@ export declare class StateSignal<T> extends SignalBase<T> implements IReadonlySi
|
|
|
82
95
|
*/
|
|
83
96
|
set(newValue: T): void;
|
|
84
97
|
/**
|
|
85
|
-
*
|
|
98
|
+
* Forcefully schedules a notification of the current value to all subscribers.
|
|
86
99
|
*
|
|
87
|
-
*
|
|
100
|
+
* Useful when mutating properties within object states directly without assigning a new reference.
|
|
101
|
+
* Notification is queued as a microtask for batching.
|
|
88
102
|
*/
|
|
89
103
|
notifyChange(): void;
|
|
90
104
|
/**
|
|
91
105
|
* Updates the signal's value based on its previous value.
|
|
92
106
|
*
|
|
93
|
-
*
|
|
94
|
-
* especially for objects or arrays, as it promotes an immutable update pattern.
|
|
107
|
+
* A functional update pattern that retrieves the current value, computes the next, and sets it.
|
|
95
108
|
*
|
|
96
|
-
* @param updater A function that receives the current value and returns the new value.
|
|
109
|
+
* @param updater A callback function that receives the current value and returns the new value.
|
|
97
110
|
*
|
|
98
111
|
* @example
|
|
99
112
|
* // For a counter
|
|
@@ -104,21 +117,27 @@ export declare class StateSignal<T> extends SignalBase<T> implements IReadonlySi
|
|
|
104
117
|
*/
|
|
105
118
|
update(updater: (previousValue: T) => T): void;
|
|
106
119
|
/**
|
|
107
|
-
* Subscribes a listener to this signal.
|
|
120
|
+
* Subscribes a listener function to this state signal.
|
|
108
121
|
*
|
|
109
122
|
* By default, the listener is immediately called with the signal's current value (`receivePrevious: true`).
|
|
110
|
-
* This
|
|
123
|
+
* This immediate call is queued as a microtask to match the asynchronous flow of signals.
|
|
111
124
|
*
|
|
112
|
-
* @param callback The function to
|
|
113
|
-
* @param options
|
|
125
|
+
* @param callback The function to invoke when the state changes.
|
|
126
|
+
* @param options Custom options, such as `receivePrevious: false` to only listen to future updates.
|
|
114
127
|
* @returns An object with an `unsubscribe` method to remove the listener.
|
|
115
128
|
*/
|
|
116
129
|
subscribe(callback: ListenerCallback<T>, options?: SubscribeOptions): SubscribeResult;
|
|
117
130
|
/**
|
|
118
131
|
* Destroys the signal, clearing its value and all listeners.
|
|
119
|
-
*
|
|
132
|
+
* Breaks references for garbage collection.
|
|
120
133
|
*/
|
|
121
134
|
destroy(): void;
|
|
135
|
+
/**
|
|
136
|
+
* Returns this signal cast to the `IReadonlySignal<T>` interface.
|
|
137
|
+
* Limits access so external callers can only subscribe/read but not set/update state.
|
|
138
|
+
*
|
|
139
|
+
* @returns A readonly representation of this signal.
|
|
140
|
+
*/
|
|
122
141
|
asReadonly(): IReadonlySignal<T>;
|
|
123
142
|
}
|
|
124
143
|
//# sourceMappingURL=state-signal.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state-signal.d.ts","sourceRoot":"","sources":["../../src/core/state-signal.ts"],"names":[],"mappings":"AACA,OAAO,EAAe,KAAK,YAAY,EAAC,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"state-signal.d.ts","sourceRoot":"","sources":["../../src/core/state-signal.ts"],"names":[],"mappings":"AACA,OAAO,EAAe,KAAK,YAAY,EAAC,MAAM,gBAAgB,CAAC;AAC/D,OAAO,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AAC5C,OAAO,KAAK,EAAC,iBAAiB,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,eAAe,EAAE,eAAe,EAAC,MAAM,YAAY,CAAC;AAExH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,qBAAa,WAAW,CAAC,CAAC,CAAE,SAAQ,UAAU,CAAC,CAAC,CAAE,YAAW,eAAe,CAAC,CAAC,CAAC;IAC7E;;;;OAIG;IACH,OAAO,CAAC,OAAO,CAAI;IAEnB;;;;OAIG;IACH,SAAS,CAAC,OAAO,EAAE,YAAY,CAAC;IAEhC;;;;;OAKG;IACH,OAAO,CAAC,eAAe,CAAS;IAEhC;;;;;OAKG;IACH,OAAO,CAAC,eAAe,CAAK;IAE5B;;;;OAIG;gBACS,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAAC;IAUxC;;;;;;;;OAQG;IACI,GAAG,IAAI,CAAC;IAKf;;;;;;;;;;;;;;;OAeG;IACI,GAAG,CAAC,QAAQ,EAAE,CAAC,GAAG,IAAI;IAa7B;;;;;OAKG;IACI,YAAY,IAAI,IAAI;IAe3B;;;;;;;;;;;;;OAaG;IACI,MAAM,CAAC,OAAO,EAAE,CAAC,aAAa,EAAE,CAAC,KAAK,CAAC,GAAG,IAAI;IAOrD;;;;;;;;;OASG;IACa,SAAS,CAAC,QAAQ,EAAE,gBAAgB,CAAC,CAAC,CAAC,EAAE,OAAO,GAAE,gBAAqB,GAAG,eAAe;IA2BzG;;;OAGG;IACa,OAAO,IAAI,IAAI;IAK/B;;;;;OAKG;IACI,UAAU,IAAI,eAAe,CAAC,CAAC,CAAC;CAGxC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ChannelSignal } from '../core/channel-signal.js';
|
|
2
|
-
import type { ChannelSignalConfig } from '../
|
|
2
|
+
import type { ChannelSignalConfig } from '../type.js';
|
|
3
3
|
/**
|
|
4
4
|
* Creates a stateless multi-channel signal that acts as a typed message bus.
|
|
5
5
|
*
|
|
@@ -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;
|
|
1
|
+
{"version":3,"file":"channel.d.ts","sourceRoot":"","sources":["../../src/creators/channel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,aAAa,EAAC,MAAM,2BAA2B,CAAC;AACxD,OAAO,KAAK,EAAC,mBAAmB,EAAC,MAAM,YAAY,CAAC;AAEpD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,SAAS,MAAM,EAAE,MAAM,EAAE,mBAAmB,GAAG,aAAa,CAAC,IAAI,CAAC,CAEzG"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { DerivedSignal } from '../core/derived-signal.js';
|
|
2
|
+
import type { DerivedSignalConfig } from '../type.js';
|
|
3
|
+
/**
|
|
4
|
+
* Creates a read-only signal mapping exactly 1-to-1 over a single upstream source.
|
|
5
|
+
*
|
|
6
|
+
* `createDerivedSignal` is a utility function to instantiate `DerivedSignal` without using the `new` keyword.
|
|
7
|
+
* A derived signal wraps a source signal and maps its value to a new representation using a projector function.
|
|
8
|
+
* It uses the "Cold Awakening Lifecycle" pattern, which avoids subscribing to the source signal until the derived
|
|
9
|
+
* signal has at least one subscriber of its own, saving processing cycles.
|
|
10
|
+
*
|
|
11
|
+
* @template S The type of the source signal's state.
|
|
12
|
+
* @template T The type of the projected derived state.
|
|
13
|
+
*
|
|
14
|
+
* @param config Configuration options including name, source, and projector.
|
|
15
|
+
* @returns A new, readonly derived signal.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```typescript
|
|
19
|
+
* const countSignal = createStateSignal({ name: 'count', initialValue: 5 });
|
|
20
|
+
*
|
|
21
|
+
* const isEvenSignal = createDerivedSignal({
|
|
22
|
+
* name: 'is-even-signal',
|
|
23
|
+
* source: countSignal,
|
|
24
|
+
* projector: (count) => count % 2 === 0
|
|
25
|
+
* });
|
|
26
|
+
*
|
|
27
|
+
* console.log(isEvenSignal.get()); // false
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export declare function createDerivedSignal<S, T>(config: DerivedSignalConfig<S, T>): DerivedSignal<S, T>;
|
|
31
|
+
//# sourceMappingURL=derived.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"derived.d.ts","sourceRoot":"","sources":["../../src/creators/derived.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,aAAa,EAAC,MAAM,2BAA2B,CAAC;AAExD,OAAO,KAAK,EAAC,mBAAmB,EAAC,MAAM,YAAY,CAAC;AAEpD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,mBAAmB,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,CAEhG"}
|
package/dist/main.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ export * from './core/signal-base.js';
|
|
|
2
2
|
export * from './core/event-signal.js';
|
|
3
3
|
export * from './core/state-signal.js';
|
|
4
4
|
export * from './core/computed-signal.js';
|
|
5
|
+
export * from './core/derived-signal.js';
|
|
5
6
|
export * from './core/effect-signal.js';
|
|
6
7
|
export * from './core/persistent-state-signal.js';
|
|
7
8
|
export * from './core/session-state-signal.js';
|
|
@@ -9,12 +10,12 @@ export * from './core/channel-signal.js';
|
|
|
9
10
|
export * from './creators/event.js';
|
|
10
11
|
export * from './creators/state.js';
|
|
11
12
|
export * from './creators/computed.js';
|
|
13
|
+
export * from './creators/derived.js';
|
|
12
14
|
export * from './creators/effect.js';
|
|
13
15
|
export * from './creators/persistent-state.js';
|
|
14
16
|
export * from './creators/session-state.js';
|
|
15
17
|
export * from './creators/channel.js';
|
|
16
18
|
export * from './operators/debounce.js';
|
|
17
19
|
export * from './operators/filter.js';
|
|
18
|
-
export * from './operators/map.js';
|
|
19
20
|
export type * from './type.js';
|
|
20
21
|
//# sourceMappingURL=main.d.ts.map
|
package/dist/main.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,yBAAyB,CAAC;AACxC,cAAc,mCAAmC,CAAC;AAClD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,0BAA0B,CAAC;AAEzC,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,wBAAwB,CAAC;AACvC,cAAc,sBAAsB,CAAC;AACrC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,uBAAuB,CAAC;AAEtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,0BAA0B,CAAC;AACzC,cAAc,yBAAyB,CAAC;AACxC,cAAc,mCAAmC,CAAC;AAClD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,0BAA0B,CAAC;AAEzC,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,uBAAuB,CAAC;AAEtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC;AAEtC,mBAAmB,WAAW,CAAC"}
|
package/dist/main.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
/* 📦 @alwatr/signal v9.
|
|
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 E}from"@alwatr/delay";import{createLogger as x}from"@alwatr/logger";class R extends B{logger_;constructor(G){super(G);this.logger_=x(`event-signal:${this.name}`),this.logger_.logMethod?.("constructor")}dispatch(G){this.logger_.logMethodArgs?.("dispatch",{payload:G}),this.checkDestroyed_(),E.nextMicrotask().then(()=>this.notify_(G))}}import{delay as _}from"@alwatr/delay";import{createLogger as D}from"@alwatr/logger";class K extends B{value__;logger_;notifyPending__=!1;notifyVersion__=0;constructor(G){super({name:G.name,onDestroy:G.onDestroy});this.logger_=D(`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(){if(this.logger_.logMethod?.("notifyChange"),this.checkDestroyed_(),this.notifyVersion__++,this.notifyPending__)return;this.notifyPending__=!0,_.nextMicrotask().then(()=>{this.notifyPending__=!1,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={}){this.logger_.logMethodArgs?.("subscribe",H),this.checkDestroyed_();let Q=super.subscribe(G,H);if(H.receivePrevious===!1)return Q;if(this.notifyPending__)return Q;let X=this.notifyVersion__;return _.nextMicrotask().then(()=>{if(this.logger_.logStep?.("subscribe","immediate_callback"),this.notifyVersion__!==X)return;if(H.once)Q.unsubscribe();G(this.value__)}).catch((Y)=>this.logger_.error("subscribe","immediate_callback_failed",Y)),Q}destroy(){this.value__=null,super.destroy()}asReadonly(){return this}}import{delay as I}from"@alwatr/delay";import{createLogger as N}from"@alwatr/logger";class z{config_;name;logger_;internalSignal_;dependencySubscriptions__=[];isRecalculating__=!1;constructor(G){this.config_=G;this.name=G.name,this.logger_=N(`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 I.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 A}from"@alwatr/delay";import{createLogger as k}from"@alwatr/logger";class L{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_=k(`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 A.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 V}from"@alwatr/debounce";import{createLocalStorageProvider as j}from"@alwatr/local-storage";class O extends K{storageProvider__;storageDebouncer__;storageSyncSubscription__;windowPageHideListener_=()=>{this.storageDebouncer__.flush()};windowPageShowListener_=(G)=>{if(G.persisted){this.logger_.logMethod?.("windowPageShowListener_//restored_from_bfcache");let H=this.storageProvider__.read();if(H!==null)this.set(H)}};constructor(G){let{name:H,storageKey:Q=H,saveDebounceDelay:X=1000,initialValue:Y,onDestroy:Z,schemaVersion:q,parse:W,stringify:J}=G,P=j({name:Q,schemaVersion:q,parse:W,stringify:J});super({name:H,initialValue:P.read()??Y,onDestroy:Z});if(this.logger_.logMethodArgs?.("constructor",G),this.storageProvider__=P,this.storageDebouncer__=V({delay:X,leading:!1,trailing:!0,thisContext:this,func:this.syncStorage__}),this.storageSyncSubscription__=this.subscribe(this.storageDebouncer__.trigger,{receivePrevious:!1}),typeof globalThis.addEventListener==="function")globalThis.addEventListener("pagehide",this.windowPageHideListener_,{passive:!0}),globalThis.addEventListener("pageshow",this.windowPageShowListener_,{passive:!0})}syncStorage__(G){this.logger_.logMethodArgs?.("syncStorage__",G),this.storageProvider__.write(G)}remove(){this.checkDestroyed_(),this.logger_.logMethod?.("remove"),this.storageProvider__.remove()}destroy(){if(this.logger_.logMethod?.("destroy"),typeof globalThis.removeEventListener==="function")globalThis.removeEventListener("pagehide",this.windowPageHideListener_),globalThis.removeEventListener("pageshow",this.windowPageShowListener_);this.storageDebouncer__.flush(),this.storageSyncSubscription__.unsubscribe(),super.destroy()}}import{createDebouncer as C}from"@alwatr/debounce";import{createSessionStorageProvider as T}from"@alwatr/session-storage";class $ extends K{storageProvider__;storageDebouncer__;storageSyncSubscription__;windowPageHideListener__=()=>{this.storageDebouncer__.flush()};windowPageShowListener__=(G)=>{if(G.persisted){this.logger_.logMethod?.("windowPageShowListener__//restored_from_bfcache");let H=this.storageProvider__.read();if(H!==null)this.set(H)}};constructor(G){let{name:H,storageKey:Q=H,saveDebounceDelay:X=1000,initialValue:Y,onDestroy:Z,parse:q,stringify:W}=G,J=T({name:Q,parse:q,stringify:W});super({name:H,initialValue:J.read()??Y,onDestroy:Z});if(this.logger_.logMethodArgs?.("constructor",G),this.storageProvider__=J,this.storageDebouncer__=C({delay:X,leading:!1,trailing:!0,thisContext:this,func:this.syncStorage__}),this.storageSyncSubscription__=this.subscribe(this.storageDebouncer__.trigger,{receivePrevious:!1}),typeof globalThis.addEventListener==="function")globalThis.addEventListener("pagehide",this.windowPageHideListener__,{passive:!0}),globalThis.addEventListener("pageshow",this.windowPageShowListener__,{passive:!0})}syncStorage__(G){this.logger_.logMethodArgs?.("syncStorage__",G),this.storageProvider__.write(G)}remove(){this.checkDestroyed_(),this.logger_.logMethod?.("remove"),this.storageProvider__.remove()}destroy(){if(this.logger_.logMethod?.("destroy"),typeof globalThis.removeEventListener==="function")globalThis.removeEventListener("pagehide",this.windowPageHideListener__),globalThis.removeEventListener("pageshow",this.windowPageShowListener__);this.storageDebouncer__.flush(),this.storageSyncSubscription__.unsubscribe(),super.destroy()}}import{delay as w}from"@alwatr/delay";import{createLogger as b}from"@alwatr/logger";class M extends B{logger_;namedHandlers__=new Map;constructor(G){super(G);this.logger_=b(`channel-signal:${this.name}`),this.logger_.logMethod?.("constructor")}dispatch(...G){let[H,Q]=G;this.logger_.logMethodArgs?.("dispatch",{name:H,payload:Q}),this.checkDestroyed_(),w.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 qG(G){return new R(G)}function U(G){return new K(G)}function F(G){return new z(G)}function MG(G){return new L(G)}function UG(G){return new O(G)}function DG(G){return new $(G)}function AG(G){return new M(G)}import{createDebouncer as v}from"@alwatr/debounce";function TG(G,H){let Q=H.name??`${G.name}-debounced`,X=new K({name:`${Q}-internal`,initialValue:G.get()}),Y=v({...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 yG(G,H,Q=`${G.name}-filtered`){let X=G.get(),Y=H(X)?X:void 0,Z=U({name:`${Q}-internal`,initialValue:Y}),q=G.subscribe((W)=>{if(H(W))Z.set(W)});return F({name:Q,deps:[Z],get:()=>Z.get(),onDestroy:()=>{q.unsubscribe(),Z.destroy()}})}function mG(G,H,Q=`${G.name}-mapped`){return F({name:Q,deps:[G],get:()=>H(G.get())})}export{U as createStateSignal,DG as createSessionStateSignal,UG as createPersistentStateSignal,mG as createMappedSignal,yG as createFilteredSignal,qG as createEventSignal,MG as createEffect,TG as createDebouncedSignal,F as createComputedSignal,AG as createChannelSignal,K as StateSignal,B as SignalBase,$ as SessionStateSignal,O as PersistentStateSignal,R as EventSignal,L as EffectSignal,z as ComputedSignal,M as ChannelSignal};
|
|
1
|
+
/* 📦 @alwatr/signal v9.30.0 */
|
|
2
|
+
class K{config_;name;priorityObservers_;observers_;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}if(G.options?.priority){if(this.priorityObservers_?.delete(G),this.priorityObservers_?.size===0)this.priorityObservers_=void 0}else if(this.observers_?.delete(G),this.observers_?.size===0)this.observers_=void 0}subscribe(G,H){this.logger_.logMethodArgs?.("subscribe.base",H),this.checkDestroyed_();let Q={callback:G,options:H};if(H?.priority)this.priorityObservers_??=new Set,this.priorityObservers_.add(Q);else this.observers_??=new Set,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}if(this.priorityObservers_?.size)for(let H of this.priorityObservers_)this.executeObserver__(H,G);if(this.observers_?.size)for(let H of this.observers_)this.executeObserver__(H,G)}executeObserver__(G,H){if(G.options?.once)this.removeObserver_(G);try{G.callback(H)}catch(Q){this.logger_.error("notify_","sync_callback_failed",Q)}}pendingRejects__;untilNext(){return this.logger_.logMethod?.("untilNext"),this.checkDestroyed_(),new Promise((G,H)=>{this.pendingRejects__??=new Set,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{queueMicrotask as x}from"@alwatr/delay";import{createLogger as E}from"@alwatr/logger";class O extends K{logger_;constructor(G){super(G);this.logger_=E(`event_signal:${this.name}`),this.logger_.logMethod?.("constructor")}dispatch(G){this.logger_.logMethodArgs?.("dispatch",{payload:G}),this.checkDestroyed_(),x(()=>this.notify_(G))}}import{queueMicrotask as M}from"@alwatr/delay";import{createLogger as D}from"@alwatr/logger";class Z extends K{value__;logger_;notifyPending__=!1;notifyVersion__=0;constructor(G){super({name:G.name,onDestroy:G.onDestroy});this.logger_=D(`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(){if(this.logger_.logMethod?.("notifyChange"),this.checkDestroyed_(),this.notifyVersion__++,this.notifyPending__)return;this.notifyPending__=!0,M(()=>{this.notifyPending__=!1,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={}){this.logger_.logMethodArgs?.("subscribe",H),this.checkDestroyed_();let Q=super.subscribe(G,H);if(H.receivePrevious===!1)return Q;if(this.notifyPending__)return Q;let X=this.notifyVersion__;return M(()=>{if(this.logger_.logStep?.("subscribe","immediate_callback"),this.notifyVersion__!==X)return;if(H.once)Q.unsubscribe();try{G(this.value__)}catch(Y){this.logger_.error("subscribe","immediate_callback_failed",Y)}}),Q}destroy(){this.value__=null,super.destroy()}asReadonly(){return this}}import{queueMicrotask as N}from"@alwatr/delay";import{createLogger as I}from"@alwatr/logger";class R{config_;name;logger_;internalSignal_;dependencySubscriptions__=[];isRecalculating__=!1;constructor(G){this.config_=G;this.name=G.name,this.logger_=I(`computed_signal:${this.name}`),this.recalculate_=this.recalculate_.bind(this),this.logger_.logMethod?.("constructor"),this.internalSignal_=new Z({name:`compute_internal:${this.name}`,initialValue:this.config_.get()});for(let H=0;H<this.config_.deps.length;H++){let Q=this.config_.deps[H];this.logger_.logStep?.("constructor","subscribing_to_dependency",{signal:Q.name}),this.dependencySubscriptions__.push(Q.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=0;G<this.dependencySubscriptions__.length;G++)this.dependencySubscriptions__[G].unsubscribe();this.dependencySubscriptions__.length=0,this.internalSignal_.destroy(),this.config_.onDestroy?.(),this.config_=null}recalculate_(){if(this.logger_.logMethod?.("recalculate_"),this.isRecalculating__){this.logger_.logStep?.("recalculate_","skipping_recalculation_already_scheduled");return}this.isRecalculating__=!0,N(()=>{if(this.isDestroyed){this.logger_.incident?.("recalculate_","destroyed_during_delay"),this.isRecalculating__=!1;return}this.logger_.logStep?.("recalculate_","recalculating_value");try{this.internalSignal_.set(this.config_.get())}catch(G){this.logger_.error("recalculate_","projection_evaluation_failed",G)}this.isRecalculating__=!1})}}import{createLogger as A}from"@alwatr/logger";class z{config_;name;logger_;internalSignal_;sourceSubscription__;activeConsumerCount__=0;constructor(G){this.config_=G;this.name=this.config_.name,this.logger_=A(`derived_signal:${this.name}`)}untilNext(){return this.logger_.logMethod?.("untilNext"),this.checkDestroyed__(),new Promise((G)=>{this.subscribe((H)=>{G(H)},{receivePrevious:!1,once:!0})})}get(){if(this.logger_.logMethod?.("get"),this.checkDestroyed__(),this.activeConsumerCount__===0)return this.config_.projector(this.config_.source.get());return this.internalSignal_.get()}get isDestroyed(){return this.config_===null}subscribe(G,H){if(this.logger_.logMethod?.("subscribe"),this.checkDestroyed__(),this.activeConsumerCount__++,this.activeConsumerCount__===1)this.logger_.logMethod?.("wakeUp_"),this.internalSignal_=new Z({name:`derived-internal:${this.name}`,initialValue:this.config_.projector(this.config_.source.get())}),this.sourceSubscription__=this.config_.source.subscribe((X)=>{this.internalSignal_.set(this.config_.projector(X))},{receivePrevious:!1});let Q=this.internalSignal_.subscribe(G,H);return{unsubscribe:()=>{if(this.logger_.logMethod?.("unsubscribe"),Q.unsubscribe(),this.activeConsumerCount__--,this.activeConsumerCount__===0&&this.sourceSubscription__)this.logger_.logMethod?.("sleepCleanup_"),this.sourceSubscription__.unsubscribe(),this.sourceSubscription__=void 0,this.internalSignal_?.destroy(),this.internalSignal_=void 0}}}destroy(){if(this.logger_.logMethod?.("destroy"),this.isDestroyed)return;if(this.sourceSubscription__)this.sourceSubscription__.unsubscribe(),this.sourceSubscription__=void 0;this.internalSignal_?.destroy(),this.config_.onDestroy?.(),this.config_=null}checkDestroyed__(){if(this.logger_.logMethod?.("checkDestroyed__"),this.isDestroyed)throw Error(`Cannot interact with a destroyed signal (id: ${this.name})`)}}import{delay as j}from"@alwatr/delay";import{createLogger as C}from"@alwatr/logger";class ${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_=C(`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 j.nextMicrotask(),this.isDestroyed__){this.logger_.incident?.("scheduleExecution_","destroyed_during_delay"),this.isRunning__=!1;return}this.logger_.logStep?.("scheduleExecution_","executing_effect"),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 V}from"@alwatr/debounce";import{createLocalStorageProvider as T}from"@alwatr/local-storage";class q extends Z{storageProvider__;storageDebouncer__;storageSyncSubscription__;windowPageHideListener_=()=>{this.storageDebouncer__.flush()};windowPageShowListener_=(G)=>{if(G.persisted){this.logger_.logMethod?.("windowPageShowListener_//restored_from_bfcache");let H=this.storageProvider__.read();if(H!==null)this.set(H)}};constructor(G){let{name:H,storageKey:Q=H,saveDebounceDelay:X=1000,initialValue:Y,onDestroy:F,schemaVersion:B,parse:J,stringify:W}=G,P=T({name:Q,schemaVersion:B,parse:J,stringify:W});super({name:H,initialValue:P.read()??Y,onDestroy:F});if(this.logger_.logMethodArgs?.("constructor",G),this.storageProvider__=P,this.storageDebouncer__=V({delay:X,leading:!1,trailing:!0,thisContext:this,func:this.syncStorage__}),this.storageSyncSubscription__=this.subscribe(this.storageDebouncer__.trigger,{receivePrevious:!1}),typeof globalThis.addEventListener==="function")globalThis.addEventListener("pagehide",this.windowPageHideListener_,{passive:!0}),globalThis.addEventListener("pageshow",this.windowPageShowListener_,{passive:!0})}syncStorage__(G){this.logger_.logMethodArgs?.("syncStorage__",G),this.storageProvider__.write(G)}remove(){this.checkDestroyed_(),this.logger_.logMethod?.("remove"),this.storageProvider__.remove()}destroy(){if(this.logger_.logMethod?.("destroy"),typeof globalThis.removeEventListener==="function")globalThis.removeEventListener("pagehide",this.windowPageHideListener_),globalThis.removeEventListener("pageshow",this.windowPageShowListener_);this.storageDebouncer__.flush(),this.storageSyncSubscription__.unsubscribe(),super.destroy()}}import{createDebouncer as k}from"@alwatr/debounce";import{createSessionStorageProvider as w}from"@alwatr/session-storage";class _ extends Z{storageProvider__;storageDebouncer__;storageSyncSubscription__;windowPageHideListener__=()=>{this.storageDebouncer__.flush()};windowPageShowListener__=(G)=>{if(G.persisted){this.logger_.logMethod?.("windowPageShowListener__//restored_from_bfcache");let H=this.storageProvider__.read();if(H!==null)this.set(H)}};constructor(G){let{name:H,storageKey:Q=H,saveDebounceDelay:X=1000,initialValue:Y,onDestroy:F,parse:B,stringify:J}=G,W=w({name:Q,parse:B,stringify:J});super({name:H,initialValue:W.read()??Y,onDestroy:F});if(this.logger_.logMethodArgs?.("constructor",G),this.storageProvider__=W,this.storageDebouncer__=k({delay:X,leading:!1,trailing:!0,thisContext:this,func:this.syncStorage__}),this.storageSyncSubscription__=this.subscribe(this.storageDebouncer__.trigger,{receivePrevious:!1}),typeof globalThis.addEventListener==="function")globalThis.addEventListener("pagehide",this.windowPageHideListener__,{passive:!0}),globalThis.addEventListener("pageshow",this.windowPageShowListener__,{passive:!0})}syncStorage__(G){this.logger_.logMethodArgs?.("syncStorage__",G),this.storageProvider__.write(G)}remove(){this.checkDestroyed_(),this.logger_.logMethod?.("remove"),this.storageProvider__.remove()}destroy(){if(this.logger_.logMethod?.("destroy"),typeof globalThis.removeEventListener==="function")globalThis.removeEventListener("pagehide",this.windowPageHideListener__),globalThis.removeEventListener("pageshow",this.windowPageShowListener__);this.storageDebouncer__.flush(),this.storageSyncSubscription__.unsubscribe(),super.destroy()}}import{queueMicrotask as b}from"@alwatr/delay";import{createLogger as S}from"@alwatr/logger";class L extends K{logger_;namedHandlers__=new Map;constructor(G){super(G);this.logger_=S(`channel_signal:${this.name}`),this.logger_.logMethod?.("constructor")}dispatch(...G){let[H,Q]=G;this.logger_.logMethodArgs?.("dispatch",{name:H,payload:Q}),this.checkDestroyed_(),b(()=>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{X.handler(H)}catch(Y){this.logger_.error("route__","sync_named_handler_failed",Y)}}this.notify_({name:G,payload:H})}destroy(){this.namedHandlers__.clear(),super.destroy()}}function $G(G){return new O(G)}function U(G){return new Z(G)}function MG(G){return new R(G)}function EG(G){return new z(G)}function IG(G){return new $(G)}function CG(G){return new q(G)}function kG(G){return new _(G)}function SG(G){return new L(G)}import{createDebouncer as v}from"@alwatr/debounce";function hG(G,H){let Q=H.name??`${G.name}_debounced`,X=new Z({name:Q,initialValue:G.get(),onDestroy(){F.unsubscribe(),Y.cancel(),H.onDestroy?.(),H=null}}),Y=v({...H,thisContext:X,func:X.set}),F=G.subscribe(Y.trigger,{receivePrevious:!1});return X}function dG(G,H,Q=`${G.name}_filtered`){let X=G.get(),Y=H(X)?X:void 0,F=U({name:Q,initialValue:Y,onDestroy(){B.unsubscribe()}}),B=G.subscribe((J)=>{if(H(J))F.set(J)});return F}export{U as createStateSignal,kG as createSessionStateSignal,CG as createPersistentStateSignal,dG as createFilteredSignal,$G as createEventSignal,IG as createEffect,EG as createDerivedSignal,hG as createDebouncedSignal,MG as createComputedSignal,SG as createChannelSignal,Z as StateSignal,K as SignalBase,_ as SessionStateSignal,q as PersistentStateSignal,O as EventSignal,$ as EffectSignal,z as DerivedSignal,R as ComputedSignal,L as ChannelSignal};
|
|
3
3
|
|
|
4
|
-
//# debugId=
|
|
4
|
+
//# debugId=2DB7724539464C7064756E2164756E21
|
|
5
5
|
//# sourceMappingURL=main.js.map
|