@alwatr/signal 5.0.0 → 5.2.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/CHANGELOG.md +63 -0
- package/dist/{computed-signal.d.ts → core/computed-signal.d.ts} +32 -9
- package/dist/core/computed-signal.d.ts.map +1 -0
- package/dist/{effect-signal.d.ts → core/effect-signal.d.ts} +25 -7
- package/dist/core/effect-signal.d.ts.map +1 -0
- package/dist/{event-signal.d.ts → core/event-signal.d.ts} +4 -4
- package/dist/core/event-signal.d.ts.map +1 -0
- package/dist/{signal-base.d.ts → core/signal-base.d.ts} +19 -14
- package/dist/core/signal-base.d.ts.map +1 -0
- package/dist/{state-signal.d.ts → core/state-signal.d.ts} +27 -4
- package/dist/core/state-signal.d.ts.map +1 -0
- package/dist/creators/computed.d.ts +34 -0
- package/dist/creators/computed.d.ts.map +1 -0
- package/dist/creators/effect.d.ts +43 -0
- package/dist/creators/effect.d.ts.map +1 -0
- package/dist/creators/event.d.ts +28 -0
- package/dist/creators/event.d.ts.map +1 -0
- package/dist/creators/state.d.ts +25 -0
- package/dist/creators/state.d.ts.map +1 -0
- package/dist/main.cjs +225 -92
- package/dist/main.cjs.map +3 -3
- package/dist/main.d.ts +10 -5
- package/dist/main.d.ts.map +1 -1
- package/dist/main.mjs +219 -91
- package/dist/main.mjs.map +3 -3
- package/dist/operators/debounce.d.ts +57 -0
- package/dist/operators/debounce.d.ts.map +1 -0
- package/dist/operators/filter.d.ts +47 -0
- package/dist/operators/filter.d.ts.map +1 -0
- package/dist/operators/map.d.ts +36 -0
- package/dist/operators/map.d.ts.map +1 -0
- package/dist/type.d.ts +57 -15
- package/dist/type.d.ts.map +1 -1
- package/package.json +8 -8
- package/dist/computed-signal.d.ts.map +0 -1
- package/dist/effect-signal.d.ts.map +0 -1
- package/dist/event-signal.d.ts.map +0 -1
- package/dist/signal-base.d.ts.map +0 -1
- package/dist/state-signal.d.ts.map +0 -1
- /package/src/{computed-signal.test.js → core/computed-signal.test.js} +0 -0
- /package/src/{effect-signal.test.js → core/effect-signal.test.js} +0 -0
- /package/src/{event-signal.test.js → core/event-signal.test.js} +0 -0
- /package/src/{state-signal.test.js → core/state-signal.test.js} +0 -0
package/dist/main.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* @alwatr/signal v5.
|
|
1
|
+
/* @alwatr/signal v5.2.0 */
|
|
2
2
|
"use strict";
|
|
3
3
|
var __defProp = Object.defineProperty;
|
|
4
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
@@ -25,57 +25,56 @@ __export(main_exports, {
|
|
|
25
25
|
EffectSignal: () => EffectSignal,
|
|
26
26
|
EventSignal: () => EventSignal,
|
|
27
27
|
SignalBase: () => SignalBase,
|
|
28
|
-
StateSignal: () => StateSignal
|
|
28
|
+
StateSignal: () => StateSignal,
|
|
29
|
+
createComputedSignal: () => createComputedSignal,
|
|
30
|
+
createDebouncedSignal: () => createDebouncedSignal,
|
|
31
|
+
createEffect: () => createEffect,
|
|
32
|
+
createEventSignal: () => createEventSignal,
|
|
33
|
+
createStateSignal: () => createStateSignal
|
|
29
34
|
});
|
|
30
35
|
module.exports = __toCommonJS(main_exports);
|
|
31
36
|
|
|
32
|
-
// src/signal-base.ts
|
|
33
|
-
var import_package_tracer = require("@alwatr/package-tracer");
|
|
34
|
-
__dev_mode__: import_package_tracer.packageTracer.add("@alwatr/signal", "5.0.0");
|
|
37
|
+
// src/core/signal-base.ts
|
|
35
38
|
var SignalBase = class {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
39
|
+
constructor(config_) {
|
|
40
|
+
this.config_ = config_;
|
|
41
|
+
/**
|
|
42
|
+
* The unique identifier for this signal instance.
|
|
43
|
+
* Useful for debugging and logging.
|
|
44
|
+
*/
|
|
45
|
+
this.signalId = this.config_.signalId;
|
|
41
46
|
/**
|
|
42
47
|
* The list of observers (listeners) subscribed to this signal.
|
|
43
48
|
* @protected
|
|
44
49
|
*/
|
|
45
50
|
this.observers_ = [];
|
|
46
|
-
this.isDestroyed_ = false;
|
|
47
51
|
/**
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
* @protected
|
|
52
|
+
* A flag indicating whether the signal has been destroyed.
|
|
53
|
+
* @private
|
|
51
54
|
*/
|
|
52
|
-
this.
|
|
53
|
-
if (this.isDestroyed_) {
|
|
54
|
-
this.logger_.accident("checkDestroyed_", "attempt_to_use_destroyed_signal");
|
|
55
|
-
throw new Error(`Cannot interact with a destroyed signal (id: ${this.signalId})`);
|
|
56
|
-
}
|
|
57
|
-
};
|
|
58
|
-
this.signalId = config.signalId;
|
|
55
|
+
this.isDestroyed__ = false;
|
|
59
56
|
}
|
|
60
57
|
/**
|
|
61
58
|
* Indicates whether the signal has been destroyed.
|
|
62
59
|
* A destroyed signal cannot be used and will throw an error if interacted with.
|
|
60
|
+
*
|
|
63
61
|
* @returns `true` if the signal is destroyed, `false` otherwise.
|
|
64
62
|
*/
|
|
65
63
|
get isDestroyed() {
|
|
66
|
-
return this.
|
|
64
|
+
return this.isDestroyed__;
|
|
67
65
|
}
|
|
68
66
|
/**
|
|
69
67
|
* Removes a specific observer from the observers list.
|
|
68
|
+
*
|
|
70
69
|
* @param observer The observer instance to remove.
|
|
71
70
|
* @protected
|
|
72
71
|
*/
|
|
73
72
|
removeObserver_(observer) {
|
|
74
|
-
|
|
73
|
+
this.logger_.logMethod?.("removeObserver_");
|
|
74
|
+
if (this.isDestroyed__) {
|
|
75
75
|
this.logger_.incident?.("removeObserver_", "remove_observer_on_destroyed_signal");
|
|
76
76
|
return;
|
|
77
77
|
}
|
|
78
|
-
this.logger_.logMethod?.("removeObserver_");
|
|
79
78
|
const index = this.observers_.indexOf(observer);
|
|
80
79
|
if (index !== -1) {
|
|
81
80
|
this.observers_.splice(index, 1);
|
|
@@ -99,8 +98,9 @@ var SignalBase = class {
|
|
|
99
98
|
} else {
|
|
100
99
|
this.observers_.push(observer);
|
|
101
100
|
}
|
|
102
|
-
|
|
103
|
-
|
|
101
|
+
return {
|
|
102
|
+
unsubscribe: () => this.removeObserver_(observer)
|
|
103
|
+
};
|
|
104
104
|
}
|
|
105
105
|
/**
|
|
106
106
|
* Notifies all registered observers about a new value.
|
|
@@ -112,11 +112,11 @@ var SignalBase = class {
|
|
|
112
112
|
* @protected
|
|
113
113
|
*/
|
|
114
114
|
notify_(value) {
|
|
115
|
-
|
|
115
|
+
this.logger_.logMethodArgs?.("notify_", value);
|
|
116
|
+
if (this.isDestroyed__) {
|
|
116
117
|
this.logger_.incident?.("notify_", "notify_on_destroyed_signal");
|
|
117
118
|
return;
|
|
118
119
|
}
|
|
119
|
-
this.logger_.logMethodArgs?.("notify_", value);
|
|
120
120
|
const currentObservers = [...this.observers_];
|
|
121
121
|
for (const observer of currentObservers) {
|
|
122
122
|
if (observer.options?.once) {
|
|
@@ -125,9 +125,7 @@ var SignalBase = class {
|
|
|
125
125
|
try {
|
|
126
126
|
const result = observer.callback(value);
|
|
127
127
|
if (result instanceof Promise) {
|
|
128
|
-
result.catch((err) => {
|
|
129
|
-
this.logger_.error("notify_", "async_callback_failed", err, { observer });
|
|
130
|
-
});
|
|
128
|
+
result.catch((err) => this.logger_.error("notify_", "async_callback_failed", err, { observer }));
|
|
131
129
|
}
|
|
132
130
|
} catch (err) {
|
|
133
131
|
this.logger_.error("notify_", "sync_callback_failed", err);
|
|
@@ -169,21 +167,38 @@ var SignalBase = class {
|
|
|
169
167
|
*/
|
|
170
168
|
destroy() {
|
|
171
169
|
this.logger_.logMethod?.("destroy");
|
|
172
|
-
this.
|
|
170
|
+
if (this.isDestroyed__) {
|
|
171
|
+
this.logger_.incident?.("destroy_", "double_destroy_attempt");
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
this.isDestroyed__ = true;
|
|
173
175
|
this.observers_.length = 0;
|
|
176
|
+
this.config_.onDestroy?.();
|
|
177
|
+
this.config_ = null;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Throws an error if the signal has been destroyed.
|
|
181
|
+
* This is a safeguard to prevent interaction with a defunct signal.
|
|
182
|
+
* @protected
|
|
183
|
+
*/
|
|
184
|
+
checkDestroyed_() {
|
|
185
|
+
if (this.isDestroyed__) {
|
|
186
|
+
this.logger_.accident("checkDestroyed_", "attempt_to_use_destroyed_signal");
|
|
187
|
+
throw new Error(`Cannot interact with a destroyed signal (id: ${this.signalId})`);
|
|
188
|
+
}
|
|
174
189
|
}
|
|
175
190
|
};
|
|
176
191
|
|
|
177
|
-
// src/event-signal.ts
|
|
192
|
+
// src/core/event-signal.ts
|
|
178
193
|
var import_delay = require("@alwatr/delay");
|
|
179
194
|
var import_logger = require("@alwatr/logger");
|
|
180
195
|
var EventSignal = class extends SignalBase {
|
|
181
|
-
/**
|
|
182
|
-
* Initializes a new `EventSignal`.
|
|
183
|
-
* @param config The configuration for the signal, containing its `signalId`.
|
|
184
|
-
*/
|
|
185
196
|
constructor(config) {
|
|
186
197
|
super(config);
|
|
198
|
+
/**
|
|
199
|
+
* The logger instance for this signal.
|
|
200
|
+
* @protected
|
|
201
|
+
*/
|
|
187
202
|
this.logger_ = (0, import_logger.createLogger)(`event-signal: ${this.signalId}`);
|
|
188
203
|
this.logger_.logMethod?.("constructor");
|
|
189
204
|
}
|
|
@@ -195,24 +210,22 @@ var EventSignal = class extends SignalBase {
|
|
|
195
210
|
* @param payload The data to send with the event.
|
|
196
211
|
*/
|
|
197
212
|
dispatch(payload) {
|
|
198
|
-
this.logger_.logMethodArgs?.("dispatch", payload);
|
|
213
|
+
this.logger_.logMethodArgs?.("dispatch", { payload });
|
|
199
214
|
this.checkDestroyed_();
|
|
200
|
-
import_delay.delay.nextMicrotask().then(() =>
|
|
201
|
-
this.notify_(payload);
|
|
202
|
-
});
|
|
215
|
+
import_delay.delay.nextMicrotask().then(() => this.notify_(payload));
|
|
203
216
|
}
|
|
204
217
|
};
|
|
205
218
|
|
|
206
|
-
// src/state-signal.ts
|
|
219
|
+
// src/core/state-signal.ts
|
|
207
220
|
var import_delay2 = require("@alwatr/delay");
|
|
208
221
|
var import_logger2 = require("@alwatr/logger");
|
|
209
222
|
var StateSignal = class extends SignalBase {
|
|
210
|
-
/**
|
|
211
|
-
* Initializes a new `StateSignal`.
|
|
212
|
-
* @param config The configuration for the state signal, including `signalId` and `initialValue`.
|
|
213
|
-
*/
|
|
214
223
|
constructor(config) {
|
|
215
224
|
super(config);
|
|
225
|
+
/**
|
|
226
|
+
* The logger instance for this signal.
|
|
227
|
+
* @protected
|
|
228
|
+
*/
|
|
216
229
|
this.logger_ = (0, import_logger2.createLogger)(`state-signal: ${this.signalId}`);
|
|
217
230
|
this.value__ = config.initialValue;
|
|
218
231
|
this.logger_.logMethodArgs?.("constructor", { initialValue: this.value__ });
|
|
@@ -247,11 +260,31 @@ var StateSignal = class extends SignalBase {
|
|
|
247
260
|
set(newValue) {
|
|
248
261
|
this.logger_.logMethodArgs?.("set", { newValue });
|
|
249
262
|
this.checkDestroyed_();
|
|
250
|
-
if (Object.is(this.value__, newValue) && (typeof newValue !== "object" || newValue === null))
|
|
263
|
+
if (Object.is(this.value__, newValue) && (typeof newValue !== "object" || newValue === null)) {
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
251
266
|
this.value__ = newValue;
|
|
252
|
-
import_delay2.delay.nextMicrotask().then(() =>
|
|
253
|
-
|
|
254
|
-
|
|
267
|
+
import_delay2.delay.nextMicrotask().then(() => this.notify_(newValue));
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Updates the signal's value based on its previous value.
|
|
271
|
+
*
|
|
272
|
+
* This method is particularly useful for state transitions that depend on the current value,
|
|
273
|
+
* especially for objects or arrays, as it promotes an immutable update pattern.
|
|
274
|
+
*
|
|
275
|
+
* @param updater A function that receives the current value and returns the new value.
|
|
276
|
+
*
|
|
277
|
+
* @example
|
|
278
|
+
* // For a counter
|
|
279
|
+
* counterSignal.update(current => current + 1);
|
|
280
|
+
*
|
|
281
|
+
* // For an object state
|
|
282
|
+
* userSignal.update(currentUser => ({ ...currentUser, loggedIn: true }));
|
|
283
|
+
*/
|
|
284
|
+
update(updater) {
|
|
285
|
+
this.logger_.logMethod?.("update");
|
|
286
|
+
this.checkDestroyed_();
|
|
287
|
+
this.set(updater(this.value__));
|
|
255
288
|
}
|
|
256
289
|
/**
|
|
257
290
|
* Subscribes a listener to this signal.
|
|
@@ -266,11 +299,8 @@ var StateSignal = class extends SignalBase {
|
|
|
266
299
|
subscribe(callback, options = {}) {
|
|
267
300
|
this.logger_.logMethodArgs?.("subscribe", { options });
|
|
268
301
|
this.checkDestroyed_();
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
import_delay2.delay.nextMicrotask().then(() => callback(this.value__)).catch((err) => {
|
|
272
|
-
this.logger_.error("subscribe", "run_callback_immediate_failed", err);
|
|
273
|
-
});
|
|
302
|
+
if (options.receivePrevious !== false) {
|
|
303
|
+
import_delay2.delay.nextMicrotask().then(() => callback(this.value__)).catch((err) => this.logger_.error("subscribe", "immediate_callback_failed", err));
|
|
274
304
|
if (options.once) {
|
|
275
305
|
return { unsubscribe: () => {
|
|
276
306
|
} };
|
|
@@ -283,22 +313,25 @@ var StateSignal = class extends SignalBase {
|
|
|
283
313
|
* This is crucial for memory management to prevent leaks.
|
|
284
314
|
*/
|
|
285
315
|
destroy() {
|
|
286
|
-
super.destroy();
|
|
287
316
|
this.value__ = null;
|
|
317
|
+
super.destroy();
|
|
288
318
|
}
|
|
289
319
|
};
|
|
290
320
|
|
|
291
|
-
// src/computed-signal.ts
|
|
321
|
+
// src/core/computed-signal.ts
|
|
292
322
|
var import_delay3 = require("@alwatr/delay");
|
|
293
323
|
var import_logger3 = require("@alwatr/logger");
|
|
294
324
|
var ComputedSignal = class {
|
|
295
|
-
/**
|
|
296
|
-
* Initializes a new `ComputedSignal`.
|
|
297
|
-
* @param config The configuration, including dependencies (`deps`) and the getter function (`get`).
|
|
298
|
-
*/
|
|
299
325
|
constructor(config_) {
|
|
300
326
|
this.config_ = config_;
|
|
327
|
+
/**
|
|
328
|
+
* The unique identifier for this signal instance.
|
|
329
|
+
*/
|
|
301
330
|
this.signalId = this.config_.signalId;
|
|
331
|
+
/**
|
|
332
|
+
* The logger instance for this signal.
|
|
333
|
+
* @protected
|
|
334
|
+
*/
|
|
302
335
|
this.logger_ = (0, import_logger3.createLogger)(`computed-signal: ${this.signalId}`);
|
|
303
336
|
/**
|
|
304
337
|
* The internal `StateSignal` that holds the computed value.
|
|
@@ -306,17 +339,23 @@ var ComputedSignal = class {
|
|
|
306
339
|
* @protected
|
|
307
340
|
*/
|
|
308
341
|
this.internalSignal_ = new StateSignal({
|
|
309
|
-
signalId: this.signalId
|
|
342
|
+
signalId: `${this.signalId}-internal`,
|
|
310
343
|
initialValue: this.config_.get()
|
|
311
344
|
});
|
|
312
|
-
|
|
345
|
+
/**
|
|
346
|
+
* A list of subscriptions to dependency signals.
|
|
347
|
+
* @private
|
|
348
|
+
*/
|
|
349
|
+
this.dependencySubscriptions__ = [];
|
|
350
|
+
/**
|
|
351
|
+
* A flag to prevent concurrent recalculations.
|
|
352
|
+
* @private
|
|
353
|
+
*/
|
|
313
354
|
this.isRecalculating__ = false;
|
|
314
|
-
this.subscribe = this.internalSignal_.subscribe.bind(this.internalSignal_);
|
|
315
|
-
this.untilNext = this.internalSignal_.untilNext.bind(this.internalSignal_);
|
|
316
355
|
this.logger_.logMethod?.("constructor");
|
|
317
356
|
this.recalculate_ = this.recalculate_.bind(this);
|
|
318
357
|
for (const signal of config_.deps) {
|
|
319
|
-
this.
|
|
358
|
+
this.dependencySubscriptions__.push(signal.subscribe(this.recalculate_, { receivePrevious: false }));
|
|
320
359
|
}
|
|
321
360
|
}
|
|
322
361
|
/**
|
|
@@ -337,6 +376,25 @@ var ComputedSignal = class {
|
|
|
337
376
|
get isDestroyed() {
|
|
338
377
|
return this.internalSignal_.isDestroyed;
|
|
339
378
|
}
|
|
379
|
+
/**
|
|
380
|
+
* Subscribes a listener to this signal.
|
|
381
|
+
* The listener will be called whenever the computed value changes.
|
|
382
|
+
*
|
|
383
|
+
* @param callback The function to be called with the new value.
|
|
384
|
+
* @param options Subscription options.
|
|
385
|
+
* @returns A `SubscribeResult` object with an `unsubscribe` method.
|
|
386
|
+
*/
|
|
387
|
+
subscribe(callback, options) {
|
|
388
|
+
return this.internalSignal_.subscribe(callback, options);
|
|
389
|
+
}
|
|
390
|
+
/**
|
|
391
|
+
* Returns a Promise that resolves with the next computed value.
|
|
392
|
+
*
|
|
393
|
+
* @returns A Promise that resolves with the next value.
|
|
394
|
+
*/
|
|
395
|
+
untilNext() {
|
|
396
|
+
return this.internalSignal_.untilNext();
|
|
397
|
+
}
|
|
340
398
|
/**
|
|
341
399
|
* Permanently disposes of the computed signal.
|
|
342
400
|
*
|
|
@@ -348,15 +406,16 @@ var ComputedSignal = class {
|
|
|
348
406
|
*/
|
|
349
407
|
destroy() {
|
|
350
408
|
this.logger_.logMethod?.("destroy");
|
|
351
|
-
if (this.
|
|
409
|
+
if (this.isDestroyed) {
|
|
352
410
|
this.logger_.incident?.("destroy", "already_destroyed");
|
|
353
411
|
return;
|
|
354
412
|
}
|
|
355
|
-
for (const subscription of this.
|
|
413
|
+
for (const subscription of this.dependencySubscriptions__) {
|
|
356
414
|
subscription.unsubscribe();
|
|
357
415
|
}
|
|
358
|
-
this.
|
|
416
|
+
this.dependencySubscriptions__.length = 0;
|
|
359
417
|
this.internalSignal_.destroy();
|
|
418
|
+
this.config_.onDestroy?.();
|
|
360
419
|
this.config_ = null;
|
|
361
420
|
}
|
|
362
421
|
/**
|
|
@@ -368,23 +427,24 @@ var ComputedSignal = class {
|
|
|
368
427
|
* @protected
|
|
369
428
|
*/
|
|
370
429
|
async recalculate_() {
|
|
430
|
+
this.logger_.logMethod?.("recalculate_");
|
|
371
431
|
if (this.internalSignal_.isDestroyed) {
|
|
372
|
-
this.logger_.incident?.("
|
|
432
|
+
this.logger_.incident?.("recalculate_", "recalculate_on_destroyed_signal");
|
|
373
433
|
return;
|
|
374
434
|
}
|
|
375
435
|
if (this.isRecalculating__) {
|
|
376
|
-
this.logger_.
|
|
436
|
+
this.logger_.logStep?.("recalculate_", "skipping_recalculation_already_scheduled");
|
|
377
437
|
return;
|
|
378
438
|
}
|
|
379
|
-
this.logger_.logMethod?.("recalculate_//scheduled");
|
|
380
439
|
this.isRecalculating__ = true;
|
|
381
440
|
try {
|
|
382
441
|
await import_delay3.delay.nextMacrotask();
|
|
383
|
-
if (this.
|
|
384
|
-
this.logger_.incident?.("
|
|
442
|
+
if (this.isDestroyed) {
|
|
443
|
+
this.logger_.incident?.("recalculate_", "destroyed_during_delay");
|
|
444
|
+
this.isRecalculating__ = false;
|
|
385
445
|
return;
|
|
386
446
|
}
|
|
387
|
-
this.logger_.
|
|
447
|
+
this.logger_.logStep?.("recalculate_", "recalculating_value");
|
|
388
448
|
this.internalSignal_.set(this.config_.get());
|
|
389
449
|
} catch (err) {
|
|
390
450
|
this.logger_.error("recalculate_", "recalculation_failed", err);
|
|
@@ -393,24 +453,40 @@ var ComputedSignal = class {
|
|
|
393
453
|
}
|
|
394
454
|
};
|
|
395
455
|
|
|
396
|
-
// src/effect-signal.ts
|
|
456
|
+
// src/core/effect-signal.ts
|
|
397
457
|
var import_delay4 = require("@alwatr/delay");
|
|
398
458
|
var import_logger4 = require("@alwatr/logger");
|
|
399
459
|
var EffectSignal = class {
|
|
400
|
-
/**
|
|
401
|
-
* Initializes a new `EffectSignal`.
|
|
402
|
-
* @param config The configuration, including dependencies (`deps`) and the `run` function.
|
|
403
|
-
*/
|
|
404
460
|
constructor(config_) {
|
|
405
461
|
this.config_ = config_;
|
|
406
|
-
|
|
407
|
-
|
|
462
|
+
/**
|
|
463
|
+
* The unique identifier for this signal instance.
|
|
464
|
+
*/
|
|
465
|
+
this.signalId = this.config_.signalId ? this.config_.signalId : `[${this.config_.deps.map((dep) => dep.signalId).join(", ")}]`;
|
|
466
|
+
/**
|
|
467
|
+
* The logger instance for this signal.
|
|
468
|
+
* @protected
|
|
469
|
+
*/
|
|
470
|
+
this.logger_ = (0, import_logger4.createLogger)(`effect-signal: ${this.signalId}`);
|
|
471
|
+
/**
|
|
472
|
+
* A list of subscriptions to dependency signals.
|
|
473
|
+
* @private
|
|
474
|
+
*/
|
|
475
|
+
this.dependencySubscriptions__ = [];
|
|
476
|
+
/**
|
|
477
|
+
* A flag to prevent concurrent executions of the effect.
|
|
478
|
+
* @private
|
|
479
|
+
*/
|
|
408
480
|
this.isRunning__ = false;
|
|
481
|
+
/**
|
|
482
|
+
* A flag indicating whether the effect has been destroyed.
|
|
483
|
+
* @private
|
|
484
|
+
*/
|
|
409
485
|
this.isDestroyed__ = false;
|
|
410
486
|
this.logger_.logMethod?.("constructor");
|
|
411
487
|
this.run_ = this.run_.bind(this);
|
|
412
488
|
for (const signal of config_.deps) {
|
|
413
|
-
this.
|
|
489
|
+
this.dependencySubscriptions__.push(signal.subscribe(this.run_, { receivePrevious: false }));
|
|
414
490
|
}
|
|
415
491
|
if (config_.runImmediately === true) {
|
|
416
492
|
void this.run_();
|
|
@@ -418,7 +494,8 @@ var EffectSignal = class {
|
|
|
418
494
|
}
|
|
419
495
|
/**
|
|
420
496
|
* Indicates whether the effect signal has been destroyed.
|
|
421
|
-
* A destroyed signal
|
|
497
|
+
* A destroyed signal will no longer execute its effect and cannot be reused.
|
|
498
|
+
*
|
|
422
499
|
* @returns `true` if the signal is destroyed, `false` otherwise.
|
|
423
500
|
*/
|
|
424
501
|
get isDestroyed() {
|
|
@@ -433,29 +510,29 @@ var EffectSignal = class {
|
|
|
433
510
|
* @protected
|
|
434
511
|
*/
|
|
435
512
|
async run_() {
|
|
513
|
+
this.logger_.logMethod?.("run_");
|
|
436
514
|
if (this.isDestroyed__) {
|
|
437
515
|
this.logger_.incident?.("run_", "run_on_destroyed_signal");
|
|
438
516
|
return;
|
|
439
517
|
}
|
|
440
518
|
if (this.isRunning__) {
|
|
441
|
-
this.logger_.
|
|
519
|
+
this.logger_.logStep?.("run_", "skipped_because_already_running");
|
|
442
520
|
return;
|
|
443
521
|
}
|
|
444
|
-
this.logger_.logMethod?.("run_//scheduled");
|
|
445
522
|
this.isRunning__ = true;
|
|
446
523
|
try {
|
|
447
524
|
await import_delay4.delay.nextMacrotask();
|
|
448
525
|
if (this.isDestroyed__) {
|
|
449
526
|
this.logger_.incident?.("run_", "destroyed_during_delay");
|
|
527
|
+
this.isRunning__ = false;
|
|
450
528
|
return;
|
|
451
529
|
}
|
|
452
|
-
this.logger_.
|
|
530
|
+
this.logger_.logStep?.("run_", "executing_effect");
|
|
453
531
|
await this.config_.run();
|
|
454
532
|
} catch (err) {
|
|
455
533
|
this.logger_.error("run_", "effect_failed", err);
|
|
456
|
-
} finally {
|
|
457
|
-
this.isRunning__ = false;
|
|
458
534
|
}
|
|
535
|
+
this.isRunning__ = false;
|
|
459
536
|
}
|
|
460
537
|
/**
|
|
461
538
|
* Permanently disposes of the effect signal.
|
|
@@ -471,19 +548,75 @@ var EffectSignal = class {
|
|
|
471
548
|
return;
|
|
472
549
|
}
|
|
473
550
|
this.isDestroyed__ = true;
|
|
474
|
-
for (const subscription of this.
|
|
551
|
+
for (const subscription of this.dependencySubscriptions__) {
|
|
475
552
|
subscription.unsubscribe();
|
|
476
553
|
}
|
|
477
|
-
this.
|
|
554
|
+
this.dependencySubscriptions__.length = 0;
|
|
555
|
+
this.config_.onDestroy?.();
|
|
478
556
|
this.config_ = null;
|
|
479
557
|
}
|
|
480
558
|
};
|
|
559
|
+
|
|
560
|
+
// src/creators/event.ts
|
|
561
|
+
function createEventSignal(config) {
|
|
562
|
+
return new EventSignal(config);
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
// src/creators/state.ts
|
|
566
|
+
function createStateSignal(config) {
|
|
567
|
+
return new StateSignal(config);
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
// src/creators/computed.ts
|
|
571
|
+
function createComputedSignal(config) {
|
|
572
|
+
return new ComputedSignal(config);
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
// src/creators/effect.ts
|
|
576
|
+
function createEffect(config) {
|
|
577
|
+
return new EffectSignal(config);
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
// src/operators/debounce.ts
|
|
581
|
+
var import_debounce = require("@alwatr/debounce");
|
|
582
|
+
function createDebouncedSignal(sourceSignal, config) {
|
|
583
|
+
const signalId = config.signalId ?? `${sourceSignal.signalId}-debounced`;
|
|
584
|
+
const internalSignal = new StateSignal({
|
|
585
|
+
signalId: `${signalId}-internal`,
|
|
586
|
+
initialValue: sourceSignal.value
|
|
587
|
+
});
|
|
588
|
+
const debouncer = (0, import_debounce.createDebouncer)({
|
|
589
|
+
...config,
|
|
590
|
+
func: (value) => {
|
|
591
|
+
internalSignal.set(value);
|
|
592
|
+
}
|
|
593
|
+
});
|
|
594
|
+
const subscription = sourceSignal.subscribe(debouncer.trigger);
|
|
595
|
+
return createComputedSignal({
|
|
596
|
+
signalId,
|
|
597
|
+
deps: [internalSignal],
|
|
598
|
+
get: () => internalSignal.value,
|
|
599
|
+
onDestroy: () => {
|
|
600
|
+
if (internalSignal.isDestroyed) return;
|
|
601
|
+
subscription.unsubscribe();
|
|
602
|
+
debouncer.cancel();
|
|
603
|
+
internalSignal.destroy();
|
|
604
|
+
config.onDestroy?.();
|
|
605
|
+
config = null;
|
|
606
|
+
}
|
|
607
|
+
});
|
|
608
|
+
}
|
|
481
609
|
// Annotate the CommonJS export names for ESM import in node:
|
|
482
610
|
0 && (module.exports = {
|
|
483
611
|
ComputedSignal,
|
|
484
612
|
EffectSignal,
|
|
485
613
|
EventSignal,
|
|
486
614
|
SignalBase,
|
|
487
|
-
StateSignal
|
|
615
|
+
StateSignal,
|
|
616
|
+
createComputedSignal,
|
|
617
|
+
createDebouncedSignal,
|
|
618
|
+
createEffect,
|
|
619
|
+
createEventSignal,
|
|
620
|
+
createStateSignal
|
|
488
621
|
});
|
|
489
622
|
//# sourceMappingURL=main.cjs.map
|