@alwatr/signal 9.33.0 → 9.35.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/dist/dev/main.js +5 -0
- package/dist/dev/main.js.map +28 -0
- package/dist/main.js +3 -3
- package/dist/main.js.map +11 -11
- package/package.json +15 -12
- package/src/core/channel-signal.ts +4 -4
- package/src/core/computed-signal.ts +8 -8
- package/src/core/derived-signal.ts +8 -8
- package/src/core/effect-signal.ts +10 -10
- package/src/core/event-signal.ts +2 -2
- package/src/core/persistent-state-signal.ts +5 -5
- package/src/core/session-state-signal.ts +5 -5
- package/src/core/signal-base.ts +9 -9
- package/src/core/state-signal.ts +6 -6
|
@@ -47,7 +47,7 @@ export class DerivedSignal<S, T> implements IReadonlySignal<T> {
|
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
untilNext(): Promise<T> {
|
|
50
|
-
this.logger_.logMethod?.('untilNext');
|
|
50
|
+
DEV_MODE && this.logger_.logMethod?.('untilNext');
|
|
51
51
|
this.checkDestroyed__();
|
|
52
52
|
return new Promise<T>((resolve) => {
|
|
53
53
|
this.subscribe(
|
|
@@ -68,7 +68,7 @@ export class DerivedSignal<S, T> implements IReadonlySignal<T> {
|
|
|
68
68
|
* @returns The current projected value.
|
|
69
69
|
*/
|
|
70
70
|
public get(): T {
|
|
71
|
-
this.logger_.logMethod?.('get');
|
|
71
|
+
DEV_MODE && this.logger_.logMethod?.('get');
|
|
72
72
|
this.checkDestroyed__();
|
|
73
73
|
if (this.activeConsumerCount__ === 0) {
|
|
74
74
|
return this.config_.projector(this.config_.source.get());
|
|
@@ -94,13 +94,13 @@ export class DerivedSignal<S, T> implements IReadonlySignal<T> {
|
|
|
94
94
|
* @returns Unsubscribe handle object.
|
|
95
95
|
*/
|
|
96
96
|
public subscribe(callback: ListenerCallback<T>, options?: SubscribeOptions): SubscribeResult {
|
|
97
|
-
this.logger_.logMethod?.('subscribe');
|
|
97
|
+
DEV_MODE && this.logger_.logMethod?.('subscribe');
|
|
98
98
|
this.checkDestroyed__();
|
|
99
99
|
this.activeConsumerCount__++;
|
|
100
100
|
|
|
101
101
|
// Wake-up phase: if this is the first active consumer, dynamically clamp to the upstream core source
|
|
102
102
|
if (this.activeConsumerCount__ === 1) {
|
|
103
|
-
this.logger_.logMethod?.('wakeUp_');
|
|
103
|
+
DEV_MODE && this.logger_.logMethod?.('wakeUp_');
|
|
104
104
|
this.internalSignal_ = new StateSignal<T>({
|
|
105
105
|
name: `derived-internal:${this.name}`,
|
|
106
106
|
initialValue: this.config_.projector(this.config_.source.get()),
|
|
@@ -117,14 +117,14 @@ export class DerivedSignal<S, T> implements IReadonlySignal<T> {
|
|
|
117
117
|
|
|
118
118
|
return {
|
|
119
119
|
unsubscribe: () => {
|
|
120
|
-
this.logger_.logMethod?.('unsubscribe');
|
|
120
|
+
DEV_MODE && this.logger_.logMethod?.('unsubscribe');
|
|
121
121
|
|
|
122
122
|
sub.unsubscribe();
|
|
123
123
|
this.activeConsumerCount__--;
|
|
124
124
|
|
|
125
125
|
// Hibernation phase: unlink tracking dependencies when view elements clear out to preserve processing cycles
|
|
126
126
|
if (this.activeConsumerCount__ === 0 && this.sourceSubscription__) {
|
|
127
|
-
this.logger_.logMethod?.('sleepCleanup_');
|
|
127
|
+
DEV_MODE && this.logger_.logMethod?.('sleepCleanup_');
|
|
128
128
|
this.sourceSubscription__.unsubscribe();
|
|
129
129
|
this.sourceSubscription__ = undefined;
|
|
130
130
|
this.internalSignal_?.destroy();
|
|
@@ -138,7 +138,7 @@ export class DerivedSignal<S, T> implements IReadonlySignal<T> {
|
|
|
138
138
|
* Destroys the derived signal and unsubscribes from the source signal if currently awake.
|
|
139
139
|
*/
|
|
140
140
|
public destroy(): void {
|
|
141
|
-
this.logger_.logMethod?.('destroy');
|
|
141
|
+
DEV_MODE && this.logger_.logMethod?.('destroy');
|
|
142
142
|
if (this.isDestroyed) return;
|
|
143
143
|
|
|
144
144
|
if (this.sourceSubscription__) {
|
|
@@ -158,7 +158,7 @@ export class DerivedSignal<S, T> implements IReadonlySignal<T> {
|
|
|
158
158
|
* @throws {Error} If destroyed.
|
|
159
159
|
*/
|
|
160
160
|
private checkDestroyed__(): void {
|
|
161
|
-
this.logger_.logMethod?.('checkDestroyed__');
|
|
161
|
+
DEV_MODE && this.logger_.logMethod?.('checkDestroyed__');
|
|
162
162
|
if (this.isDestroyed) {
|
|
163
163
|
throw new Error(`Cannot interact with a destroyed signal (id: ${this.name})`);
|
|
164
164
|
}
|
|
@@ -98,18 +98,18 @@ export class EffectSignal implements IEffectSignal {
|
|
|
98
98
|
this.logger_ = createLogger(`effect-signal:${this.name}`);
|
|
99
99
|
this.scheduleExecution_ = this.scheduleExecution_.bind(this);
|
|
100
100
|
|
|
101
|
-
this.logger_.logMethod?.('constructor');
|
|
101
|
+
DEV_MODE && this.logger_.logMethod?.('constructor');
|
|
102
102
|
|
|
103
103
|
// Subscribe to all dependencies. We don't need the previous value,
|
|
104
104
|
// as the `runImmediately` option controls the initial execution.
|
|
105
105
|
for (const signal of config_.deps) {
|
|
106
|
-
this.logger_.logStep?.('constructor', 'subscribing_to_dependency', {signal: signal.name});
|
|
106
|
+
DEV_MODE && this.logger_.logStep?.('constructor', 'subscribing_to_dependency', {signal: signal.name});
|
|
107
107
|
this.dependencySubscriptions__.push(signal.subscribe(this.scheduleExecution_, {receivePrevious: false}));
|
|
108
108
|
}
|
|
109
109
|
|
|
110
110
|
// Run the effect immediately if requested.
|
|
111
111
|
if (config_.runImmediately === true) {
|
|
112
|
-
this.logger_.logStep?.('constructor', 'scheduling_initial_execution');
|
|
112
|
+
DEV_MODE && this.logger_.logStep?.('constructor', 'scheduling_initial_execution');
|
|
113
113
|
// We don't need to await this, let it run in the background.
|
|
114
114
|
void this.scheduleExecution_();
|
|
115
115
|
}
|
|
@@ -126,15 +126,15 @@ export class EffectSignal implements IEffectSignal {
|
|
|
126
126
|
* @returns A promise that resolves when the execution schedules or runs.
|
|
127
127
|
*/
|
|
128
128
|
protected async scheduleExecution_(): Promise<void> {
|
|
129
|
-
this.logger_.logMethod?.('scheduleExecution_');
|
|
129
|
+
DEV_MODE && this.logger_.logMethod?.('scheduleExecution_');
|
|
130
130
|
|
|
131
131
|
if (this.isDestroyed__) {
|
|
132
|
-
this.logger_.incident?.('scheduleExecution_', 'schedule_execution_on_destroyed_signal');
|
|
132
|
+
DEV_MODE && this.logger_.incident?.('scheduleExecution_', 'schedule_execution_on_destroyed_signal');
|
|
133
133
|
return;
|
|
134
134
|
}
|
|
135
135
|
if (this.isRunning__) {
|
|
136
136
|
// If an execution is already scheduled, do nothing.
|
|
137
|
-
this.logger_.logStep?.('scheduleExecution_', 'skipped_because_already_running');
|
|
137
|
+
DEV_MODE && this.logger_.logStep?.('scheduleExecution_', 'skipped_because_already_running');
|
|
138
138
|
return;
|
|
139
139
|
}
|
|
140
140
|
|
|
@@ -144,12 +144,12 @@ export class EffectSignal implements IEffectSignal {
|
|
|
144
144
|
// Wait for the next macrotask to batch simultaneous updates.
|
|
145
145
|
await delay.nextMicrotask();
|
|
146
146
|
if (this.isDestroyed__) {
|
|
147
|
-
this.logger_.incident?.('scheduleExecution_', 'destroyed_during_delay');
|
|
147
|
+
DEV_MODE && this.logger_.incident?.('scheduleExecution_', 'destroyed_during_delay');
|
|
148
148
|
this.isRunning__ = false;
|
|
149
149
|
return;
|
|
150
150
|
}
|
|
151
151
|
|
|
152
|
-
this.logger_.logStep?.('scheduleExecution_', 'executing_effect');
|
|
152
|
+
DEV_MODE && this.logger_.logStep?.('scheduleExecution_', 'executing_effect');
|
|
153
153
|
this.config_.run();
|
|
154
154
|
} catch (err) {
|
|
155
155
|
this.logger_.error('scheduleExecution_', 'effect_failed', err);
|
|
@@ -167,10 +167,10 @@ export class EffectSignal implements IEffectSignal {
|
|
|
167
167
|
* Failure to call `destroy()` will result in memory leaks and potentially unwanted side effects.
|
|
168
168
|
*/
|
|
169
169
|
public destroy(): void {
|
|
170
|
-
this.logger_.logMethod?.('destroy');
|
|
170
|
+
DEV_MODE && this.logger_.logMethod?.('destroy');
|
|
171
171
|
|
|
172
172
|
if (this.isDestroyed__) {
|
|
173
|
-
this.logger_.incident?.('destroy', 'already_destroyed');
|
|
173
|
+
DEV_MODE && this.logger_.incident?.('destroy', 'already_destroyed');
|
|
174
174
|
return;
|
|
175
175
|
}
|
|
176
176
|
|
package/src/core/event-signal.ts
CHANGED
|
@@ -46,7 +46,7 @@ export class EventSignal<T = void> extends SignalBase<T> implements IBaseSignal<
|
|
|
46
46
|
constructor(config: SignalConfig) {
|
|
47
47
|
super(config);
|
|
48
48
|
this.logger_ = createLogger(`event_signal:${this.name}`);
|
|
49
|
-
this.logger_.logMethod?.('constructor');
|
|
49
|
+
DEV_MODE && this.logger_.logMethod?.('constructor');
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
/**
|
|
@@ -58,7 +58,7 @@ export class EventSignal<T = void> extends SignalBase<T> implements IBaseSignal<
|
|
|
58
58
|
* @param payload The data payload to send with the event.
|
|
59
59
|
*/
|
|
60
60
|
public dispatch(payload: T): void {
|
|
61
|
-
this.logger_.logMethodArgs?.('dispatch', {payload});
|
|
61
|
+
DEV_MODE && this.logger_.logMethodArgs?.('dispatch', {payload});
|
|
62
62
|
this.checkDestroyed_();
|
|
63
63
|
// Dispatch as a microtask to ensure consistent, non-blocking behavior.
|
|
64
64
|
queueMicrotask(() => this.notify_(payload));
|
|
@@ -89,7 +89,7 @@ export class PersistentStateSignal<T> extends StateSignal<T> {
|
|
|
89
89
|
*/
|
|
90
90
|
private readonly windowPageShowListener_ = (event: PageTransitionEvent): void => {
|
|
91
91
|
if (event.persisted) {
|
|
92
|
-
this.logger_.logMethod?.('windowPageShowListener_//restored_from_bfcache');
|
|
92
|
+
DEV_MODE && this.logger_.logMethod?.('windowPageShowListener_//restored_from_bfcache');
|
|
93
93
|
const value = this.storageProvider__.read();
|
|
94
94
|
if (value !== null) {
|
|
95
95
|
this.set(value);
|
|
@@ -129,7 +129,7 @@ export class PersistentStateSignal<T> extends StateSignal<T> {
|
|
|
129
129
|
onDestroy,
|
|
130
130
|
});
|
|
131
131
|
|
|
132
|
-
this.logger_.logMethodArgs?.('constructor', config);
|
|
132
|
+
DEV_MODE && this.logger_.logMethodArgs?.('constructor', config);
|
|
133
133
|
|
|
134
134
|
this.storageProvider__ = storageProvider;
|
|
135
135
|
|
|
@@ -157,7 +157,7 @@ export class PersistentStateSignal<T> extends StateSignal<T> {
|
|
|
157
157
|
* @private
|
|
158
158
|
*/
|
|
159
159
|
private syncStorage__(newValue: T): void {
|
|
160
|
-
this.logger_.logMethodArgs?.('syncStorage__', newValue);
|
|
160
|
+
DEV_MODE && this.logger_.logMethodArgs?.('syncStorage__', newValue);
|
|
161
161
|
this.storageProvider__.write(newValue);
|
|
162
162
|
}
|
|
163
163
|
|
|
@@ -167,7 +167,7 @@ export class PersistentStateSignal<T> extends StateSignal<T> {
|
|
|
167
167
|
*/
|
|
168
168
|
public remove(): void {
|
|
169
169
|
this.checkDestroyed_();
|
|
170
|
-
this.logger_.logMethod?.('remove');
|
|
170
|
+
DEV_MODE && this.logger_.logMethod?.('remove');
|
|
171
171
|
// Remove from storage.
|
|
172
172
|
this.storageProvider__.remove();
|
|
173
173
|
}
|
|
@@ -176,7 +176,7 @@ export class PersistentStateSignal<T> extends StateSignal<T> {
|
|
|
176
176
|
* Overrides the destroy method to also clean up the storage sync subscription and event listeners.
|
|
177
177
|
*/
|
|
178
178
|
public override destroy(): void {
|
|
179
|
-
this.logger_.logMethod?.('destroy');
|
|
179
|
+
DEV_MODE && this.logger_.logMethod?.('destroy');
|
|
180
180
|
if (typeof globalThis.removeEventListener === 'function') {
|
|
181
181
|
globalThis.removeEventListener('pagehide', this.windowPageHideListener_);
|
|
182
182
|
globalThis.removeEventListener('pageshow', this.windowPageShowListener_);
|
|
@@ -99,7 +99,7 @@ export class SessionStateSignal<T> extends StateSignal<T> {
|
|
|
99
99
|
*/
|
|
100
100
|
private readonly windowPageShowListener__ = (event: PageTransitionEvent): void => {
|
|
101
101
|
if (event.persisted) {
|
|
102
|
-
this.logger_.logMethod?.('windowPageShowListener__//restored_from_bfcache');
|
|
102
|
+
DEV_MODE && this.logger_.logMethod?.('windowPageShowListener__//restored_from_bfcache');
|
|
103
103
|
const value = this.storageProvider__.read();
|
|
104
104
|
if (value !== null) {
|
|
105
105
|
this.set(value);
|
|
@@ -129,7 +129,7 @@ export class SessionStateSignal<T> extends StateSignal<T> {
|
|
|
129
129
|
onDestroy,
|
|
130
130
|
});
|
|
131
131
|
|
|
132
|
-
this.logger_.logMethodArgs?.('constructor', config);
|
|
132
|
+
DEV_MODE && this.logger_.logMethodArgs?.('constructor', config);
|
|
133
133
|
|
|
134
134
|
this.storageProvider__ = storageProvider;
|
|
135
135
|
|
|
@@ -157,7 +157,7 @@ export class SessionStateSignal<T> extends StateSignal<T> {
|
|
|
157
157
|
* @private
|
|
158
158
|
*/
|
|
159
159
|
private syncStorage__(newValue: T): void {
|
|
160
|
-
this.logger_.logMethodArgs?.('syncStorage__', newValue);
|
|
160
|
+
DEV_MODE && this.logger_.logMethodArgs?.('syncStorage__', newValue);
|
|
161
161
|
this.storageProvider__.write(newValue);
|
|
162
162
|
}
|
|
163
163
|
|
|
@@ -175,7 +175,7 @@ export class SessionStateSignal<T> extends StateSignal<T> {
|
|
|
175
175
|
*/
|
|
176
176
|
public remove(): void {
|
|
177
177
|
this.checkDestroyed_();
|
|
178
|
-
this.logger_.logMethod?.('remove');
|
|
178
|
+
DEV_MODE && this.logger_.logMethod?.('remove');
|
|
179
179
|
this.storageProvider__.remove();
|
|
180
180
|
}
|
|
181
181
|
|
|
@@ -192,7 +192,7 @@ export class SessionStateSignal<T> extends StateSignal<T> {
|
|
|
192
192
|
* ```
|
|
193
193
|
*/
|
|
194
194
|
public override destroy(): void {
|
|
195
|
-
this.logger_.logMethod?.('destroy');
|
|
195
|
+
DEV_MODE && this.logger_.logMethod?.('destroy');
|
|
196
196
|
if (typeof globalThis.removeEventListener === 'function') {
|
|
197
197
|
globalThis.removeEventListener('pagehide', this.windowPageHideListener__);
|
|
198
198
|
globalThis.removeEventListener('pageshow', this.windowPageShowListener__);
|
package/src/core/signal-base.ts
CHANGED
|
@@ -74,10 +74,10 @@ export abstract class SignalBase<T> {
|
|
|
74
74
|
* @protected
|
|
75
75
|
*/
|
|
76
76
|
protected removeObserver_(observer: Observer_<T>): void {
|
|
77
|
-
this.logger_.logMethod?.('removeObserver_');
|
|
77
|
+
DEV_MODE && this.logger_.logMethod?.('removeObserver_');
|
|
78
78
|
|
|
79
79
|
if (this.isDestroyed__) {
|
|
80
|
-
this.logger_.incident?.('removeObserver_', 'remove_observer_on_destroyed_signal');
|
|
80
|
+
DEV_MODE && this.logger_.incident?.('removeObserver_', 'remove_observer_on_destroyed_signal');
|
|
81
81
|
return;
|
|
82
82
|
}
|
|
83
83
|
|
|
@@ -104,7 +104,7 @@ export abstract class SignalBase<T> {
|
|
|
104
104
|
* @returns An object with an `unsubscribe` method to remove the subscription.
|
|
105
105
|
*/
|
|
106
106
|
public subscribe(callback: ListenerCallback<T>, options?: SubscribeOptions): SubscribeResult {
|
|
107
|
-
this.logger_.logMethodArgs?.('subscribe.base', options);
|
|
107
|
+
DEV_MODE && this.logger_.logMethodArgs?.('subscribe.base', options);
|
|
108
108
|
this.checkDestroyed_();
|
|
109
109
|
|
|
110
110
|
const observer: Observer_<T> = {callback, options};
|
|
@@ -131,10 +131,10 @@ export abstract class SignalBase<T> {
|
|
|
131
131
|
* @protected
|
|
132
132
|
*/
|
|
133
133
|
protected notify_(value: T): void {
|
|
134
|
-
this.logger_.logMethodArgs?.('notify_', value);
|
|
134
|
+
DEV_MODE && this.logger_.logMethodArgs?.('notify_', value);
|
|
135
135
|
|
|
136
136
|
if (this.isDestroyed__) {
|
|
137
|
-
this.logger_.incident?.('notify_', 'notify_on_destroyed_signal');
|
|
137
|
+
DEV_MODE && this.logger_.incident?.('notify_', 'notify_on_destroyed_signal');
|
|
138
138
|
return;
|
|
139
139
|
}
|
|
140
140
|
|
|
@@ -187,7 +187,7 @@ export abstract class SignalBase<T> {
|
|
|
187
187
|
* @returns A Promise that resolves with the next value dispatched by the signal.
|
|
188
188
|
*/
|
|
189
189
|
public untilNext(): Promise<T> {
|
|
190
|
-
this.logger_.logMethod?.('untilNext');
|
|
190
|
+
DEV_MODE && this.logger_.logMethod?.('untilNext');
|
|
191
191
|
this.checkDestroyed_();
|
|
192
192
|
return new Promise((resolve, reject) => {
|
|
193
193
|
this.pendingRejects__ ??= new Set();
|
|
@@ -212,9 +212,9 @@ export abstract class SignalBase<T> {
|
|
|
212
212
|
* invokes the optional `onDestroy` config hook, and breaks internal references to facilitate GC.
|
|
213
213
|
*/
|
|
214
214
|
public destroy(): void {
|
|
215
|
-
this.logger_.logMethod?.('destroy');
|
|
215
|
+
DEV_MODE && this.logger_.logMethod?.('destroy');
|
|
216
216
|
if (this.isDestroyed__) {
|
|
217
|
-
this.logger_.incident?.('destroy_', 'double_destroy_attempt');
|
|
217
|
+
DEV_MODE && this.logger_.incident?.('destroy_', 'double_destroy_attempt');
|
|
218
218
|
return;
|
|
219
219
|
}
|
|
220
220
|
this.isDestroyed__ = true;
|
|
@@ -241,7 +241,7 @@ export abstract class SignalBase<T> {
|
|
|
241
241
|
*/
|
|
242
242
|
protected checkDestroyed_(): void {
|
|
243
243
|
if (this.isDestroyed__) {
|
|
244
|
-
this.logger_.accident('checkDestroyed_', 'attempt_to_use_destroyed_signal');
|
|
244
|
+
DEV_MODE && this.logger_.accident('checkDestroyed_', 'attempt_to_use_destroyed_signal');
|
|
245
245
|
throw new Error(`Cannot interact with a destroyed signal (id: ${this.name})`);
|
|
246
246
|
}
|
|
247
247
|
}
|
package/src/core/state-signal.ts
CHANGED
|
@@ -79,7 +79,7 @@ export class StateSignal<T> extends SignalBase<T> implements IReadonlySignal<T>
|
|
|
79
79
|
});
|
|
80
80
|
this.logger_ = createLogger(`state_signal:${this.name}`);
|
|
81
81
|
this.value__ = config.initialValue;
|
|
82
|
-
this.logger_.logMethodArgs?.('constructor', {initialValue: this.value__});
|
|
82
|
+
DEV_MODE && this.logger_.logMethodArgs?.('constructor', {initialValue: this.value__});
|
|
83
83
|
}
|
|
84
84
|
|
|
85
85
|
/**
|
|
@@ -113,7 +113,7 @@ export class StateSignal<T> extends SignalBase<T> implements IReadonlySignal<T>
|
|
|
113
113
|
* mySignal.set({ ...mySignal.get(), property: 'new-value' });
|
|
114
114
|
*/
|
|
115
115
|
public set(newValue: T): void {
|
|
116
|
-
this.logger_.logMethodArgs?.('set', {newValue});
|
|
116
|
+
DEV_MODE && this.logger_.logMethodArgs?.('set', {newValue});
|
|
117
117
|
|
|
118
118
|
// For primitives (including null), do not notify if the value is the same.
|
|
119
119
|
if (Object.is(this.value__, newValue) && (typeof newValue !== 'object' || newValue === null)) {
|
|
@@ -132,7 +132,7 @@ export class StateSignal<T> extends SignalBase<T> implements IReadonlySignal<T>
|
|
|
132
132
|
* Notification is queued as a microtask for batching.
|
|
133
133
|
*/
|
|
134
134
|
public notifyChange(): void {
|
|
135
|
-
this.logger_.logMethod?.('notifyChange');
|
|
135
|
+
DEV_MODE && this.logger_.logMethod?.('notifyChange');
|
|
136
136
|
this.checkDestroyed_();
|
|
137
137
|
|
|
138
138
|
this.notifyVersion__++;
|
|
@@ -163,7 +163,7 @@ export class StateSignal<T> extends SignalBase<T> implements IReadonlySignal<T>
|
|
|
163
163
|
public update(updater: (previousValue: T) => T): void {
|
|
164
164
|
this.checkDestroyed_();
|
|
165
165
|
const newValue = updater(this.value__);
|
|
166
|
-
this.logger_.logMethodFull?.('update', this.value__, newValue);
|
|
166
|
+
DEV_MODE && this.logger_.logMethodFull?.('update', this.value__, newValue);
|
|
167
167
|
this.set(newValue);
|
|
168
168
|
}
|
|
169
169
|
|
|
@@ -178,7 +178,7 @@ export class StateSignal<T> extends SignalBase<T> implements IReadonlySignal<T>
|
|
|
178
178
|
* @returns An object with an `unsubscribe` method to remove the listener.
|
|
179
179
|
*/
|
|
180
180
|
public override subscribe(callback: ListenerCallback<T>, options: SubscribeOptions = {}): SubscribeResult {
|
|
181
|
-
this.logger_.logMethodArgs?.('subscribe', options);
|
|
181
|
+
DEV_MODE && this.logger_.logMethodArgs?.('subscribe', options);
|
|
182
182
|
this.checkDestroyed_();
|
|
183
183
|
|
|
184
184
|
const result = super.subscribe(callback, options);
|
|
@@ -189,7 +189,7 @@ export class StateSignal<T> extends SignalBase<T> implements IReadonlySignal<T>
|
|
|
189
189
|
const subscribeVersion = this.notifyVersion__;
|
|
190
190
|
|
|
191
191
|
queueMicrotask((): void => {
|
|
192
|
-
this.logger_.logStep?.('subscribe', 'immediate_callback');
|
|
192
|
+
DEV_MODE && this.logger_.logStep?.('subscribe', 'immediate_callback');
|
|
193
193
|
if (this.notifyVersion__ !== subscribeVersion) return; // A notification occurred after subscribing, so skip the immediate callback.
|
|
194
194
|
if (options.once) {
|
|
195
195
|
result.unsubscribe();
|