@alwatr/signal 5.2.2 → 6.0.1
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 +37 -0
- package/README.md +27 -15
- package/dist/core/computed-signal.d.ts +4 -4
- package/dist/core/computed-signal.d.ts.map +1 -1
- package/dist/core/effect-signal.d.ts +4 -4
- package/dist/core/effect-signal.d.ts.map +1 -1
- package/dist/core/event-signal.d.ts +2 -2
- package/dist/core/event-signal.d.ts.map +1 -1
- package/dist/core/signal-base.d.ts +1 -1
- package/dist/core/signal-base.d.ts.map +1 -1
- package/dist/core/state-signal.d.ts +2 -1
- package/dist/core/state-signal.d.ts.map +1 -1
- package/dist/creators/computed.d.ts +3 -3
- package/dist/creators/effect.d.ts +2 -2
- package/dist/creators/event.d.ts +1 -1
- package/dist/creators/state.d.ts +1 -1
- package/dist/main.cjs +2 -2
- package/dist/main.cjs.map +2 -2
- package/dist/main.mjs +2 -2
- package/dist/main.mjs.map +2 -2
- package/dist/operators/debounce.d.ts +1 -1
- package/dist/operators/filter.d.ts +3 -3
- package/dist/operators/filter.d.ts.map +1 -1
- package/dist/operators/map.d.ts +3 -3
- package/dist/operators/map.d.ts.map +1 -1
- package/dist/type.d.ts +6 -6
- package/dist/type.d.ts.map +1 -1
- package/package.json +11 -10
- package/src/core/computed-signal.test.js +7 -7
- package/src/core/effect-signal.test.js +2 -2
- package/src/core/event-signal.test.js +25 -9
- package/src/core/state-signal.test.js +10 -10
- package/src/operators/debounce.test.js +6 -6
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,43 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [6.0.1](https://github.com/Alwatr/flux/compare/v6.0.0...v6.0.1) (2025-09-20)
|
|
7
|
+
|
|
8
|
+
### 🐛 Bug Fixes
|
|
9
|
+
|
|
10
|
+
* add sideEffects property to package.json for fsm and signal packages ([37d175c](https://github.com/Alwatr/flux/commit/37d175c2cd16144449dfa72e7504a4d179f1cb01))
|
|
11
|
+
|
|
12
|
+
### 🔨 Code Refactoring
|
|
13
|
+
|
|
14
|
+
* remove public access modifier from constructors in signal classes ([afb42da](https://github.com/Alwatr/flux/commit/afb42da7fd812cd09555c43ac9489ef15efce96a))
|
|
15
|
+
|
|
16
|
+
### 🔗 Dependencies update
|
|
17
|
+
|
|
18
|
+
* update alwatr dependencies ([19bd8a5](https://github.com/Alwatr/flux/commit/19bd8a597a4e74b620e04a497eff7247a03bf8b8))
|
|
19
|
+
|
|
20
|
+
## [6.0.0](https://github.com/Alwatr/flux/compare/v5.2.2...v6.0.0) (2025-09-19)
|
|
21
|
+
|
|
22
|
+
### ✨ Features
|
|
23
|
+
|
|
24
|
+
* add asReadonly method to StateSignal for improved interface exposure ([e8be13a](https://github.com/Alwatr/flux/commit/e8be13aa1b49c0e67b8022b0bef02fb80e5499f4))
|
|
25
|
+
|
|
26
|
+
### 🐛 Bug Fixes
|
|
27
|
+
|
|
28
|
+
* remove space in logger initialization for signal classes ([6e3b071](https://github.com/Alwatr/flux/commit/6e3b0710b67f67849c4dce390e9bfa7b2f80a9f7))
|
|
29
|
+
|
|
30
|
+
### 🔨 Code Refactoring
|
|
31
|
+
|
|
32
|
+
* enhance logging during EffectSignal construction for dependency subscriptions ([062da7e](https://github.com/Alwatr/flux/commit/062da7e5a91070576579731ac21870ffcafa7033))
|
|
33
|
+
* enhance logging in update method to track value changes ([5b0bb00](https://github.com/Alwatr/flux/commit/5b0bb000a7aeb37ab90405f34959b230ca575232))
|
|
34
|
+
* replace signalId with name in signal implementation ([0c2f065](https://github.com/Alwatr/flux/commit/0c2f065bb0afa49980537e42773cbbf21013a2a3))
|
|
35
|
+
* update internal signal name format and enhance logging during dependency subscription ([1670726](https://github.com/Alwatr/flux/commit/1670726059b77b058b9daa3841bb7bb1ded61af3))
|
|
36
|
+
|
|
37
|
+
### 🔗 Dependencies update
|
|
38
|
+
|
|
39
|
+
* update @alwatr/logger to version 6.0.2 and @types/node to version 22.18.6; upgrade esbuild and other dependencies ([95dfaba](https://github.com/Alwatr/flux/commit/95dfabab2a4d4ea2b0e42a70bee1f3e68a67bffc))
|
|
40
|
+
* update dependencies for logger, nano-build, type-helper, and node types ([23fe723](https://github.com/Alwatr/flux/commit/23fe7236ffa0bfd2551a6dfc52c23689ce4b036e))
|
|
41
|
+
* update package dependencies for improved compatibility and performance ([1e91063](https://github.com/Alwatr/flux/commit/1e9106343d01330089c33d9591969a66625a1e7b))
|
|
42
|
+
|
|
6
43
|
## [5.2.2](https://github.com/Alwatr/flux/compare/v5.2.1...v5.2.2) (2025-09-15)
|
|
7
44
|
|
|
8
45
|
### 🐛 Bug Fixes
|
package/README.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Alwatr Signal
|
|
2
2
|
|
|
3
|
+
[](https://www.google.com/search?q=alwatr+flux)
|
|
4
|
+
[](https://www.google.com/search?q=alwatr+signal)
|
|
5
|
+
[](https://www.google.com/search?q=alwatr)
|
|
6
|
+
[](https://www.npmjs.com/package/%40alwatr/flux)
|
|
7
|
+
[](https://www.npmjs.com/package/%40alwatr/signal)
|
|
8
|
+
|
|
3
9
|
Alwatr Signal is a powerful, lightweight, and modern reactive programming library. It is inspired by the best concepts from major reactive libraries but engineered to be faster and more efficient than all of them. It provides a robust and elegant way to manage application state through a system of signals, offering fine-grained reactivity, predictability, and excellent performance.
|
|
4
10
|
|
|
5
11
|
It's designed to be simple to learn, yet capable of handling complex state management scenarios.
|
|
@@ -11,7 +17,7 @@ It's designed to be simple to learn, yet capable of handling complex state manag
|
|
|
11
17
|
- **Performant**: Smart change detection and batched updates prevent unnecessary computations and re-renders.
|
|
12
18
|
- **Predictable**: Asynchronous, non-blocking notifications ensure a consistent and understandable data flow.
|
|
13
19
|
- **Lifecycle Management**: Built-in `destroy()` methods for easy cleanup and memory leak prevention.
|
|
14
|
-
- **Easy to Debug**: Unique `
|
|
20
|
+
- **Easy to Debug**: Unique `name` for each signal makes logging and tracing a breeze.
|
|
15
21
|
|
|
16
22
|
## Core Concepts
|
|
17
23
|
|
|
@@ -48,13 +54,13 @@ import {StateSignal} from '@alwatr/signal';
|
|
|
48
54
|
|
|
49
55
|
// A signal to hold the user's first name.
|
|
50
56
|
const firstName = new StateSignal<string>({
|
|
51
|
-
|
|
57
|
+
name: 'user-firstName',
|
|
52
58
|
initialValue: 'John',
|
|
53
59
|
});
|
|
54
60
|
|
|
55
61
|
// A signal to hold a simple counter.
|
|
56
62
|
const counter = new StateSignal<number>({
|
|
57
|
-
|
|
63
|
+
name: 'app-counter',
|
|
58
64
|
initialValue: 0,
|
|
59
65
|
});
|
|
60
66
|
```
|
|
@@ -67,7 +73,7 @@ A `ComputedSignal` combines other signals into a new, read-only value. Let's cre
|
|
|
67
73
|
import {ComputedSignal} from '@alwatr/signal';
|
|
68
74
|
|
|
69
75
|
const fullName = new ComputedSignal<string>({
|
|
70
|
-
|
|
76
|
+
name: 'user-fullName',
|
|
71
77
|
deps: [firstName], // This computed signal depends on firstName.
|
|
72
78
|
get: () => `User: ${firstName.get()}`,
|
|
73
79
|
});
|
|
@@ -165,7 +171,7 @@ The `subscribe` method accepts an optional second argument to customize its beha
|
|
|
165
171
|
### `StateSignal<T>`
|
|
166
172
|
|
|
167
173
|
- **`constructor(config)`**: Creates a new state signal.
|
|
168
|
-
- `config.
|
|
174
|
+
- `config.name`: `string`
|
|
169
175
|
- `config.initialValue`: `T`
|
|
170
176
|
- **`.get()`**: `T` - Gets the current value.
|
|
171
177
|
- **`.set(newValue: T)`**: Sets a new value and notifies listeners.
|
|
@@ -173,7 +179,7 @@ The `subscribe` method accepts an optional second argument to customize its beha
|
|
|
173
179
|
### `ComputedSignal<T>`
|
|
174
180
|
|
|
175
181
|
- **`constructor(config)`**: Creates a new computed signal.
|
|
176
|
-
- `config.
|
|
182
|
+
- `config.name`: `string`
|
|
177
183
|
- `config.deps`: `IReadonlySignal<unknown>[]` - Array of dependency signals.
|
|
178
184
|
- `config.get`: `() => T` - The function to compute the value.
|
|
179
185
|
- **`.get()`**: `T` - Gets the current (memoized) value.
|
|
@@ -190,7 +196,7 @@ The `subscribe` method accepts an optional second argument to customize its beha
|
|
|
190
196
|
### `EventSignal<T>`
|
|
191
197
|
|
|
192
198
|
- **`constructor(config)`**: Creates a new event signal.
|
|
193
|
-
- `config.
|
|
199
|
+
- `config.name`: `string`
|
|
194
200
|
- **`.dispatch(payload: T)`**: Dispatches an event to all listeners.
|
|
195
201
|
|
|
196
202
|
### Common Methods
|
|
@@ -215,6 +221,12 @@ Contributions are welcome! Please read our [contribution guidelines](https://git
|
|
|
215
221
|
|
|
216
222
|
# Alwatr Signal (راهنمای فارسی)
|
|
217
223
|
|
|
224
|
+
[](https://www.google.com/search?q=alwatr+flux)
|
|
225
|
+
[](https://www.google.com/search?q=alwatr+signal)
|
|
226
|
+
[](https://www.google.com/search?q=alwatr)
|
|
227
|
+
[](https://www.npmjs.com/package/%40alwatr/flux)
|
|
228
|
+
[](https://www.npmjs.com/package/%40alwatr/signal)
|
|
229
|
+
|
|
218
230
|
کتابخانه Alwatr Signal یک ابزار قدرتمند، سبک و مدرن برای برنامهنویسی واکنشی (Reactive Programming) است. این کتابخانه با الگوبرداری از بهترین مفاهیم بزرگترین کتابخانههای واکنشی طراحی شده، اما مهندسی آن به گونهای است که از تمام آنها سریعتر و کارآمدتر باشد. این کتابخانه روشی استوار و زیبا برای مدیریت وضعیت برنامه از طریق سیگنالها ارائه میدهد و واکنشپذیری دقیق (fine-grained reactivity)، پیشبینیپذیری و عملکرد عالی را به ارمغان میآورد.
|
|
219
231
|
|
|
220
232
|
طراحی آن به گونهای است که یادگیری آن ساده باشد، اما در عین حال قادر به مدیریت سناریوهای پیچیده مدیریت وضعیت نیز باشد.
|
|
@@ -226,7 +238,7 @@ Contributions are welcome! Please read our [contribution guidelines](https://git
|
|
|
226
238
|
- **عملکرد بالا**: تشخیص هوشمند تغییرات و بهروزرسانیهای دستهای از محاسبات و رندرهای غیرضروری جلوگیری میکند.
|
|
227
239
|
- **پیشبینیپذیر**: نوتیفیکیشنهای ناهمزمان (asynchronous) و غیرمسدودکننده (non-blocking) جریان دادهای سازگار و قابل فهم را تضمین میکنند.
|
|
228
240
|
- **مدیریت چرخه حیات (Lifecycle)**: متدهای داخلی `destroy()` برای پاکسازی آسان و جلوگیری از نشت حافظه (memory leak).
|
|
229
|
-
- **اشکالزدایی آسان**: شناسههای منحصر به فرد (`
|
|
241
|
+
- **اشکالزدایی آسان**: شناسههای منحصر به فرد (`name`) برای هر سیگنال، لاگگیری و ردیابی را بسیار ساده میکند.
|
|
230
242
|
|
|
231
243
|
## مفاهیم اصلی
|
|
232
244
|
|
|
@@ -263,13 +275,13 @@ import {StateSignal} from '@alwatr/signal';
|
|
|
263
275
|
|
|
264
276
|
// سیگنالی برای نگهداری نام کوچک کاربر
|
|
265
277
|
const firstName = new StateSignal<string>({
|
|
266
|
-
|
|
278
|
+
name: 'user-firstName',
|
|
267
279
|
initialValue: 'John',
|
|
268
280
|
});
|
|
269
281
|
|
|
270
282
|
// سیگنالی برای نگهداری یک شمارنده ساده
|
|
271
283
|
const counter = new StateSignal<number>({
|
|
272
|
-
|
|
284
|
+
name: 'app-counter',
|
|
273
285
|
initialValue: 0,
|
|
274
286
|
});
|
|
275
287
|
```
|
|
@@ -282,7 +294,7 @@ const counter = new StateSignal<number>({
|
|
|
282
294
|
import {ComputedSignal} from '@alwatr/signal';
|
|
283
295
|
|
|
284
296
|
const fullName = new ComputedSignal<string>({
|
|
285
|
-
|
|
297
|
+
name: 'user-fullName',
|
|
286
298
|
deps: [firstName], // این سیگنال محاسباتی به firstName وابسته است
|
|
287
299
|
get: () => `User: ${firstName.get()}`,
|
|
288
300
|
});
|
|
@@ -358,7 +370,7 @@ const isEven = new ComputedSignal({
|
|
|
358
370
|
isEven.destroy();
|
|
359
371
|
```
|
|
360
372
|
|
|
361
|
-
فراخوانی `destroy()` اشتراک سیگنال را از تمام وابستگیهایش لغو میکند و به
|
|
373
|
+
فراخوانی `destroy()` اشتراک سیگنال را از تمام وابستگیهایش لغو میکند و به جمعآورنده زباله (garbage collector) اجازه میدهد آن را با خیال راحت پاک کند.
|
|
362
374
|
|
|
363
375
|
### نوتیفیکیشنهای ناهمزمان (Asynchronous)
|
|
364
376
|
|
|
@@ -380,7 +392,7 @@ Alwatr Signal از یک مدل ناهمزمان قابل پیشبینی بر
|
|
|
380
392
|
### `StateSignal<T>`
|
|
381
393
|
|
|
382
394
|
- **`constructor(config)`**: یک سیگنال وضعیت جدید ایجاد میکند.
|
|
383
|
-
- `config.
|
|
395
|
+
- `config.name`: `string`
|
|
384
396
|
- `config.initialValue`: `T`
|
|
385
397
|
- **`.get()`**: `T` - مقدار فعلی را دریافت میکند.
|
|
386
398
|
- **`.set(newValue: T)`**: مقدار جدیدی را تنظیم کرده و شنوندگان را مطلع میکند.
|
|
@@ -388,7 +400,7 @@ Alwatr Signal از یک مدل ناهمزمان قابل پیشبینی بر
|
|
|
388
400
|
### `ComputedSignal<T>`
|
|
389
401
|
|
|
390
402
|
- **`constructor(config)`**: یک سیگنال محاسباتی جدید ایجاد میکند.
|
|
391
|
-
- `config.
|
|
403
|
+
- `config.name`: `string`
|
|
392
404
|
- `config.deps`: `IReadonlySignal<unknown>[]` - آرایهای از سیگنالهای وابسته.
|
|
393
405
|
- `config.get`: `() => T` - تابعی برای محاسبه مقدار.
|
|
394
406
|
- **`.get()`**: `T` - مقدار فعلی (کش شده) را دریافت میکند.
|
|
@@ -405,7 +417,7 @@ Alwatr Signal از یک مدل ناهمزمان قابل پیشبینی بر
|
|
|
405
417
|
### `EventSignal<T>`
|
|
406
418
|
|
|
407
419
|
- **`constructor(config)`**: یک سیگنال رویداد جدید ایجاد میکند.
|
|
408
|
-
- `config.
|
|
420
|
+
- `config.name`: `string`
|
|
409
421
|
- **`.dispatch(payload: T)`**: یک رویداد را به تمام شنوندگان ارسال میکند.
|
|
410
422
|
|
|
411
423
|
### متدهای مشترک
|
|
@@ -14,12 +14,12 @@ import type { ComputedSignalConfig, IReadonlySignal, SubscribeResult, SubscribeO
|
|
|
14
14
|
*
|
|
15
15
|
* @example
|
|
16
16
|
* // --- Create dependency signals ---
|
|
17
|
-
* const firstName = new StateSignal({
|
|
18
|
-
* const lastName = new StateSignal({
|
|
17
|
+
* const firstName = new StateSignal({ name: 'firstName', initialValue: 'John' });
|
|
18
|
+
* const lastName = new StateSignal({ name: 'lastName', initialValue: 'Doe' });
|
|
19
19
|
*
|
|
20
20
|
* // --- Create a computed signal ---
|
|
21
21
|
* const fullName = new ComputedSignal({
|
|
22
|
-
*
|
|
22
|
+
* name: 'fullName',
|
|
23
23
|
* deps: [firstName, lastName],
|
|
24
24
|
* get: () => `${firstName.get()} ${lastName.get()}`,
|
|
25
25
|
* });
|
|
@@ -43,7 +43,7 @@ export declare class ComputedSignal<T> implements IReadonlySignal<T> {
|
|
|
43
43
|
/**
|
|
44
44
|
* The unique identifier for this signal instance.
|
|
45
45
|
*/
|
|
46
|
-
readonly
|
|
46
|
+
readonly name: string;
|
|
47
47
|
/**
|
|
48
48
|
* The logger instance for this signal.
|
|
49
49
|
* @protected
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"computed-signal.d.ts","sourceRoot":"","sources":["../../src/core/computed-signal.ts"],"names":[],"mappings":"AAGA,OAAO,EAAC,WAAW,EAAC,MAAM,mBAAmB,CAAC;AAE9C,OAAO,KAAK,EAAC,oBAAoB,EAAE,eAAe,EAAE,eAAe,EAAE,gBAAgB,EAAC,MAAM,YAAY,CAAC;AAEzG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,qBAAa,cAAc,CAAC,CAAC,CAAE,YAAW,eAAe,CAAC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"computed-signal.d.ts","sourceRoot":"","sources":["../../src/core/computed-signal.ts"],"names":[],"mappings":"AAGA,OAAO,EAAC,WAAW,EAAC,MAAM,mBAAmB,CAAC;AAE9C,OAAO,KAAK,EAAC,oBAAoB,EAAE,eAAe,EAAE,eAAe,EAAE,gBAAgB,EAAC,MAAM,YAAY,CAAC;AAEzG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,qBAAa,cAAc,CAAC,CAAC,CAAE,YAAW,eAAe,CAAC,CAAC,CAAC;IAmC9C,SAAS,CAAC,OAAO,EAAE,oBAAoB,CAAC,CAAC,CAAC;IAlCtD;;OAEG;IACH,SAAgB,IAAI,SAAqB;IAEzC;;;OAGG;IACH,SAAS,CAAC,QAAQ,CAAC,OAAO,wCAAgD;IAE1E;;;;OAIG;IACH,SAAS,CAAC,QAAQ,CAAC,eAAe,iBAG/B;IAEH;;;OAGG;IAEH,OAAO,CAAC,QAAQ,CAAC,yBAAyB,CAAyB;IAEnE;;;OAGG;IACH,OAAO,CAAC,iBAAiB,CAAS;gBAEZ,OAAO,EAAE,oBAAoB,CAAC,CAAC,CAAC;IAWtD;;;;;;OAMG;IACI,GAAG,IAAI,CAAC;IAIf;;;;OAIG;IACH,IAAW,WAAW,IAAI,OAAO,CAEhC;IAED;;;;;;;OAOG;IACI,SAAS,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,eAAe;IAI3F;;;;OAIG;IACI,SAAS,IAAI,OAAO,CAAC,CAAC,CAAC;IAI9B;;;;;;;;OAQG;IACI,OAAO,IAAI,IAAI;IAqBtB;;;;;;;OAOG;cACa,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;CAwC9C"}
|
|
@@ -14,12 +14,12 @@ import type { EffectSignalConfig, IEffectSignal } from '../type.js';
|
|
|
14
14
|
*
|
|
15
15
|
* @example
|
|
16
16
|
* // --- Create dependency signals ---
|
|
17
|
-
* const counter = new StateSignal({ initialValue: 0,
|
|
18
|
-
* const user = new StateSignal({ initialValue: 'guest',
|
|
17
|
+
* const counter = new StateSignal({ initialValue: 0, name: 'counter' });
|
|
18
|
+
* const user = new StateSignal({ initialValue: 'guest', name: 'user' });
|
|
19
19
|
*
|
|
20
20
|
* // --- Create an effect ---
|
|
21
21
|
* const analyticsEffect = new EffectSignal({
|
|
22
|
-
*
|
|
22
|
+
* name: 'analytics-effect',
|
|
23
23
|
* deps: [counter, user],
|
|
24
24
|
* run: () => {
|
|
25
25
|
* console.log(`Analytics: User '${user.get()}' clicked ${counter.get()} times.`);
|
|
@@ -43,7 +43,7 @@ export declare class EffectSignal implements IEffectSignal {
|
|
|
43
43
|
/**
|
|
44
44
|
* The unique identifier for this signal instance.
|
|
45
45
|
*/
|
|
46
|
-
readonly
|
|
46
|
+
readonly name: string;
|
|
47
47
|
/**
|
|
48
48
|
* The logger instance for this signal.
|
|
49
49
|
* @protected
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"effect-signal.d.ts","sourceRoot":"","sources":["../../src/core/effect-signal.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAC,kBAAkB,EAAE,aAAa,EAAkB,MAAM,YAAY,CAAC;AAEnF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,qBAAa,YAAa,YAAW,aAAa;
|
|
1
|
+
{"version":3,"file":"effect-signal.d.ts","sourceRoot":"","sources":["../../src/core/effect-signal.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAC,kBAAkB,EAAE,aAAa,EAAkB,MAAM,YAAY,CAAC;AAEnF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,qBAAa,YAAa,YAAW,aAAa;IAwCpC,SAAS,CAAC,OAAO,EAAE,kBAAkB;IAvCjD;;OAEG;IACH,SAAgB,IAAI,SAAmF;IAEvG;;;OAGG;IACH,SAAS,CAAC,QAAQ,CAAC,OAAO,wCAA8C;IAExE;;;OAGG;IACH,OAAO,CAAC,QAAQ,CAAC,yBAAyB,CAAyB;IAEnE;;;OAGG;IACH,OAAO,CAAC,WAAW,CAAS;IAE5B;;;OAGG;IACH,OAAO,CAAC,aAAa,CAAS;IAE9B;;;;;OAKG;IACH,IAAW,WAAW,IAAI,OAAO,CAEhC;gBAEqB,OAAO,EAAE,kBAAkB;IAmBjD;;;;;;;OAOG;cACa,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC;IAmCnD;;;;;;OAMG;IACI,OAAO,IAAI,IAAI;CAmBvB"}
|
|
@@ -12,7 +12,7 @@ import type { SignalConfig } from '../type.js';
|
|
|
12
12
|
*
|
|
13
13
|
* @example
|
|
14
14
|
* // Create a signal for user click events.
|
|
15
|
-
* const onUserClick = new EventSignal<{ x: number, y: number }>({
|
|
15
|
+
* const onUserClick = new EventSignal<{ x: number, y: number }>({ name: 'on-user-click' });
|
|
16
16
|
*
|
|
17
17
|
* // Subscribe to the event.
|
|
18
18
|
* onUserClick.subscribe(clickPosition => {
|
|
@@ -23,7 +23,7 @@ import type { SignalConfig } from '../type.js';
|
|
|
23
23
|
* onUserClick.dispatch({ x: 100, y: 250 }); // Notifies the listener.
|
|
24
24
|
*
|
|
25
25
|
* // --- Example with no payload ---
|
|
26
|
-
* const onAppReady = new EventSignal({
|
|
26
|
+
* const onAppReady = new EventSignal({ name: 'on-app-ready' });
|
|
27
27
|
* onAppReady.subscribe(() => console.log('Application is ready!'));
|
|
28
28
|
* onAppReady.dispatch(); // Notifies the listener.
|
|
29
29
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"event-signal.d.ts","sourceRoot":"","sources":["../../src/core/event-signal.ts"],"names":[],"mappings":"AAGA,OAAO,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AAE5C,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,YAAY,CAAC;AAE7C;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,qBAAa,WAAW,CAAC,CAAC,GAAG,IAAI,CAAE,SAAQ,UAAU,CAAC,CAAC,CAAC;IACtD;;;OAGG;IACH,SAAS,CAAC,OAAO,
|
|
1
|
+
{"version":3,"file":"event-signal.d.ts","sourceRoot":"","sources":["../../src/core/event-signal.ts"],"names":[],"mappings":"AAGA,OAAO,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AAE5C,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,YAAY,CAAC;AAE7C;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,qBAAa,WAAW,CAAC,CAAC,GAAG,IAAI,CAAE,SAAQ,UAAU,CAAC,CAAC,CAAC;IACtD;;;OAGG;IACH,SAAS,CAAC,OAAO,wCAA6C;gBAElD,MAAM,EAAE,YAAY;IAKhC;;;;;;OAMG;IACI,QAAQ,CAAC,OAAO,EAAE,CAAC,GAAG,IAAI;CAMlC"}
|
|
@@ -12,7 +12,7 @@ export declare abstract class SignalBase<T> {
|
|
|
12
12
|
* The unique identifier for this signal instance.
|
|
13
13
|
* Useful for debugging and logging.
|
|
14
14
|
*/
|
|
15
|
-
readonly
|
|
15
|
+
readonly name: string;
|
|
16
16
|
/**
|
|
17
17
|
* The logger instance for this signal.
|
|
18
18
|
* @protected
|
|
@@ -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;AAGjD;;;;;GAKG;AACH,8BAAsB,UAAU,CAAC,CAAC;
|
|
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;AAGjD;;;;;GAKG;AACH,8BAAsB,UAAU,CAAC,CAAC;IAmCpB,SAAS,CAAC,OAAO,EAAE,YAAY;IAlC3C;;;OAGG;IACH,SAAgB,IAAI,SAAqB;IAEzC;;;OAGG;IACH,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAC;IAEzC;;;OAGG;IACH,SAAS,CAAC,QAAQ,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,CAAM;IAEnD;;;OAGG;IACH,OAAO,CAAC,aAAa,CAAS;IAE9B;;;;;OAKG;IACH,IAAW,WAAW,IAAI,OAAO,CAEhC;gBAEqB,OAAO,EAAE,YAAY;IAE3C;;;;;OAKG;IACH,SAAS,CAAC,eAAe,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,IAAI;IAcvD;;;;;;;;OAQG;IACI,SAAS,CAAC,QAAQ,EAAE,gBAAgB,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,eAAe;IAoB5F;;;;;;;;OAQG;IACH,SAAS,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI;IA6BjC;;;;;;;;;;;;OAYG;IACI,SAAS,IAAI,OAAO,CAAC,CAAC,CAAC;IAY9B;;;;;;OAMG;IACI,OAAO,IAAI,IAAI;IAYtB;;;;OAIG;IACH,SAAS,CAAC,eAAe,IAAI,IAAI;CAMlC"}
|
|
@@ -12,7 +12,7 @@ import type { StateSignalConfig, ListenerCallback, SubscribeOptions, SubscribeRe
|
|
|
12
12
|
* @example
|
|
13
13
|
* // Create a new state signal with an initial value.
|
|
14
14
|
* const counter = new StateSignal<number>({
|
|
15
|
-
*
|
|
15
|
+
* name: 'counter-signal',
|
|
16
16
|
* initialValue: 0,
|
|
17
17
|
* });
|
|
18
18
|
*
|
|
@@ -102,5 +102,6 @@ export declare class StateSignal<T> extends SignalBase<T> implements IReadonlySi
|
|
|
102
102
|
* This is crucial for memory management to prevent leaks.
|
|
103
103
|
*/
|
|
104
104
|
destroy(): void;
|
|
105
|
+
asReadonly(): IReadonlySignal<T>;
|
|
105
106
|
}
|
|
106
107
|
//# 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":"AAGA,OAAO,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AAE5C,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;;;OAGG;IACH,OAAO,CAAC,OAAO,CAAI;IAEnB;;;OAGG;IACH,SAAS,CAAC,OAAO,
|
|
1
|
+
{"version":3,"file":"state-signal.d.ts","sourceRoot":"","sources":["../../src/core/state-signal.ts"],"names":[],"mappings":"AAGA,OAAO,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AAE5C,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;;;OAGG;IACH,OAAO,CAAC,OAAO,CAAI;IAEnB;;;OAGG;IACH,SAAS,CAAC,OAAO,wCAA6C;gBAElD,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAAC;IAMxC;;;;;;;OAOG;IACI,GAAG,IAAI,CAAC;IAKf;;;;;;;;;;;;;;OAcG;IACI,GAAG,CAAC,QAAQ,EAAE,CAAC,GAAG,IAAI;IAe7B;;;;;;;;;;;;;;OAcG;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;IAKxB,UAAU,IAAI,eAAe,CAAC,CAAC,CAAC;CAGxC"}
|
|
@@ -16,11 +16,11 @@ import type { ComputedSignalConfig } from '../type.js';
|
|
|
16
16
|
* @returns A new, read-only computed signal.
|
|
17
17
|
*
|
|
18
18
|
* @example
|
|
19
|
-
* const firstName = createStateSignal({
|
|
20
|
-
* const lastName = createStateSignal({
|
|
19
|
+
* const firstName = createStateSignal({ name: 'firstName', initialValue: 'John' });
|
|
20
|
+
* const lastName = createStateSignal({ name: 'lastName', initialValue: 'Doe' });
|
|
21
21
|
*
|
|
22
22
|
* const fullName = createComputedSignal({
|
|
23
|
-
*
|
|
23
|
+
* name: 'fullName',
|
|
24
24
|
* deps: [firstName, lastName],
|
|
25
25
|
* get: () => `${firstName.get()} ${lastName.get()}`,
|
|
26
26
|
* });
|
|
@@ -16,8 +16,8 @@ import type { EffectSignalConfig } from '../type.js';
|
|
|
16
16
|
*
|
|
17
17
|
* @example
|
|
18
18
|
* // --- Create dependency signals ---
|
|
19
|
-
* const counter = createStateSignal({ initialValue: 0,
|
|
20
|
-
* const user = createStateSignal({ initialValue: 'guest',
|
|
19
|
+
* const counter = createStateSignal({ initialValue: 0, name: 'counter' });
|
|
20
|
+
* const user = createStateSignal({ initialValue: 'guest', name: 'user' });
|
|
21
21
|
*
|
|
22
22
|
* // --- Create an effect ---
|
|
23
23
|
* const analyticsEffect = createEffect({
|
package/dist/creators/event.d.ts
CHANGED
package/dist/creators/state.d.ts
CHANGED
package/dist/main.cjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
"use strict";var __defProp=Object.defineProperty;var __getOwnPropDesc=Object.getOwnPropertyDescriptor;var __getOwnPropNames=Object.getOwnPropertyNames;var __hasOwnProp=Object.prototype.hasOwnProperty;var __export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:true})};var __copyProps=(to,from,except,desc)=>{if(from&&typeof from==="object"||typeof from==="function"){for(let key of __getOwnPropNames(from))if(!__hasOwnProp.call(to,key)&&key!==except)__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable})}return to};var __toCommonJS=mod=>__copyProps(__defProp({},"__esModule",{value:true}),mod);var main_exports={};__export(main_exports,{ComputedSignal:()=>ComputedSignal,EffectSignal:()=>EffectSignal,EventSignal:()=>EventSignal,SignalBase:()=>SignalBase,StateSignal:()=>StateSignal,createComputedSignal:()=>createComputedSignal,createDebouncedSignal:()=>createDebouncedSignal,createEffect:()=>createEffect,createEventSignal:()=>createEventSignal,createStateSignal:()=>createStateSignal});module.exports=__toCommonJS(main_exports);var SignalBase=class{constructor(config_){this.config_=config_;this.
|
|
1
|
+
/** 📦 @alwatr/signal v6.0.1 */ __dev_mode__: console.log("📦 @alwatr/signal v6.0.1");
|
|
2
|
+
"use strict";var __defProp=Object.defineProperty;var __getOwnPropDesc=Object.getOwnPropertyDescriptor;var __getOwnPropNames=Object.getOwnPropertyNames;var __hasOwnProp=Object.prototype.hasOwnProperty;var __export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:true})};var __copyProps=(to,from,except,desc)=>{if(from&&typeof from==="object"||typeof from==="function"){for(let key of __getOwnPropNames(from))if(!__hasOwnProp.call(to,key)&&key!==except)__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable})}return to};var __toCommonJS=mod=>__copyProps(__defProp({},"__esModule",{value:true}),mod);var main_exports={};__export(main_exports,{ComputedSignal:()=>ComputedSignal,EffectSignal:()=>EffectSignal,EventSignal:()=>EventSignal,SignalBase:()=>SignalBase,StateSignal:()=>StateSignal,createComputedSignal:()=>createComputedSignal,createDebouncedSignal:()=>createDebouncedSignal,createEffect:()=>createEffect,createEventSignal:()=>createEventSignal,createStateSignal:()=>createStateSignal});module.exports=__toCommonJS(main_exports);var SignalBase=class{constructor(config_){this.config_=config_;this.name=this.config_.name;this.observers_=[];this.isDestroyed__=false}get isDestroyed(){return this.isDestroyed__}removeObserver_(observer){this.logger_.logMethod?.("removeObserver_");if(this.isDestroyed__){this.logger_.incident?.("removeObserver_","remove_observer_on_destroyed_signal");return}const index=this.observers_.indexOf(observer);if(index!==-1){this.observers_.splice(index,1)}}subscribe(callback,options){this.logger_.logMethodArgs?.("subscribe.base",options);this.checkDestroyed_();const observer={callback,options};if(options?.priority){this.observers_.unshift(observer)}else{this.observers_.push(observer)}return{unsubscribe:()=>this.removeObserver_(observer)}}notify_(value){this.logger_.logMethodArgs?.("notify_",value);if(this.isDestroyed__){this.logger_.incident?.("notify_","notify_on_destroyed_signal");return}const currentObservers=[...this.observers_];for(const observer of currentObservers){if(observer.options?.once){this.removeObserver_(observer)}try{const result=observer.callback(value);if(result instanceof Promise){result.catch(err=>this.logger_.error("notify_","async_callback_failed",err,{observer}))}}catch(err){this.logger_.error("notify_","sync_callback_failed",err)}}}untilNext(){this.logger_.logMethod?.("untilNext");this.checkDestroyed_();return new Promise(resolve=>{this.subscribe(resolve,{once:true,priority:true,receivePrevious:false})})}destroy(){this.logger_.logMethod?.("destroy");if(this.isDestroyed__){this.logger_.incident?.("destroy_","double_destroy_attempt");return}this.isDestroyed__=true;this.observers_.length=0;this.config_.onDestroy?.();this.config_=null}checkDestroyed_(){if(this.isDestroyed__){this.logger_.accident("checkDestroyed_","attempt_to_use_destroyed_signal");throw new Error(`Cannot interact with a destroyed signal (id: ${this.name})`)}}};var import_delay=require("@alwatr/delay");var import_logger=require("@alwatr/logger");var EventSignal=class extends SignalBase{constructor(config){super(config);this.logger_=(0,import_logger.createLogger)(`event-signal:${this.name}`);this.logger_.logMethod?.("constructor")}dispatch(payload){this.logger_.logMethodArgs?.("dispatch",{payload});this.checkDestroyed_();import_delay.delay.nextMicrotask().then(()=>this.notify_(payload))}};var import_delay2=require("@alwatr/delay");var import_logger2=require("@alwatr/logger");var StateSignal=class extends SignalBase{constructor(config){super(config);this.logger_=(0,import_logger2.createLogger)(`state-signal:${this.name}`);this.value__=config.initialValue;this.logger_.logMethodArgs?.("constructor",{initialValue:this.value__})}get(){this.checkDestroyed_();return this.value__}set(newValue){this.logger_.logMethodArgs?.("set",{newValue});this.checkDestroyed_();if(Object.is(this.value__,newValue)&&(typeof newValue!=="object"||newValue===null)){return}this.value__=newValue;import_delay2.delay.nextMicrotask().then(()=>this.notify_(newValue))}update(updater){this.checkDestroyed_();const newValue=updater(this.value__);this.logger_.logMethodFull?.("update",this.value__,newValue);this.set(newValue)}subscribe(callback,options={}){this.logger_.logMethodArgs?.("subscribe",options);this.checkDestroyed_();if(options.receivePrevious!==false){import_delay2.delay.nextMicrotask().then(()=>{this.logger_.logStep?.("subscribe","immediate_callback");callback(this.value__)}).catch(err=>this.logger_.error("subscribe","immediate_callback_failed",err));if(options.once){return{unsubscribe:()=>{}}}}return super.subscribe(callback,options)}destroy(){this.value__=null;super.destroy()}asReadonly(){return this}};var import_delay3=require("@alwatr/delay");var import_logger3=require("@alwatr/logger");var ComputedSignal=class{constructor(config_){this.config_=config_;this.name=this.config_.name;this.logger_=(0,import_logger3.createLogger)(`computed-signal:${this.name}`);this.internalSignal_=new StateSignal({name:`compute-${this.name}_`,initialValue:this.config_.get()});this.dependencySubscriptions__=[];this.isRecalculating__=false;this.logger_.logMethod?.("constructor");this.recalculate_=this.recalculate_.bind(this);for(const signal of config_.deps){this.logger_.logStep?.("constructor","subscribing_to_dependency",{signal:signal.name});this.dependencySubscriptions__.push(signal.subscribe(this.recalculate_,{receivePrevious:false}))}}get(){return this.internalSignal_.get()}get isDestroyed(){return this.internalSignal_.isDestroyed}subscribe(callback,options){return this.internalSignal_.subscribe(callback,options)}untilNext(){return this.internalSignal_.untilNext()}destroy(){this.logger_.logMethod?.("destroy");if(this.isDestroyed){this.logger_.incident?.("destroy","already_destroyed");return}for(const subscription of this.dependencySubscriptions__){subscription.unsubscribe()}this.dependencySubscriptions__.length=0;this.internalSignal_.destroy();this.config_.onDestroy?.();this.config_=null}async recalculate_(){this.logger_.logMethod?.("recalculate_");if(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__=true;try{await import_delay3.delay.nextMacrotask();if(this.isDestroyed){this.logger_.incident?.("recalculate_","destroyed_during_delay");this.isRecalculating__=false;return}this.logger_.logStep?.("recalculate_","recalculating_value");this.internalSignal_.set(this.config_.get())}catch(err){this.logger_.error("recalculate_","recalculation_failed",err)}this.isRecalculating__=false}};var import_delay4=require("@alwatr/delay");var import_logger4=require("@alwatr/logger");var EffectSignal=class{constructor(config_){this.config_=config_;this.name=this.config_.name??`[${this.config_.deps.map(dep=>dep.name).join(", ")}]`;this.logger_=(0,import_logger4.createLogger)(`effect-signal:${this.name}`);this.dependencySubscriptions__=[];this.isRunning__=false;this.isDestroyed__=false;this.logger_.logMethod?.("constructor");this.scheduleExecution_=this.scheduleExecution_.bind(this);for(const signal of config_.deps){this.logger_.logStep?.("constructor","subscribing_to_dependency",{signal:signal.name});this.dependencySubscriptions__.push(signal.subscribe(this.scheduleExecution_,{receivePrevious:false}))}if(config_.runImmediately===true){this.logger_.logStep?.("constructor","scheduling_initial_execution");void this.scheduleExecution_()}}get isDestroyed(){return this.isDestroyed__}async scheduleExecution_(){this.logger_.logMethod?.("scheduleExecution_");if(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__=true;try{await import_delay4.delay.nextMacrotask();if(this.isDestroyed__){this.logger_.incident?.("scheduleExecution_","destroyed_during_delay");this.isRunning__=false;return}this.logger_.logStep?.("scheduleExecution_","executing_effect");await this.config_.run()}catch(err){this.logger_.error("scheduleExecution_","effect_failed",err)}this.isRunning__=false}destroy(){this.logger_.logMethod?.("destroy");if(this.isDestroyed__){this.logger_.incident?.("destroy","already_destroyed");return}this.isDestroyed__=true;for(const subscription of this.dependencySubscriptions__){subscription.unsubscribe()}this.dependencySubscriptions__.length=0;this.config_.onDestroy?.();this.config_=null}};function createEventSignal(config){return new EventSignal(config)}function createStateSignal(config){return new StateSignal(config)}function createComputedSignal(config){return new ComputedSignal(config)}function createEffect(config){return new EffectSignal(config)}var import_debounce=require("@alwatr/debounce");function createDebouncedSignal(sourceSignal,config){const name=config.name??`${sourceSignal.name}-debounced`;const internalSignal=new StateSignal({name:`${name}-internal`,initialValue:sourceSignal.get()});const debouncer=(0,import_debounce.createDebouncer)({...config,func:value=>{internalSignal.set(value)}});const subscription=sourceSignal.subscribe(value=>debouncer.trigger(value),{receivePrevious:false});return createComputedSignal({name,deps:[internalSignal],get:()=>internalSignal.get(),onDestroy:()=>{if(internalSignal.isDestroyed)return;subscription.unsubscribe();debouncer.cancel();internalSignal.destroy();config.onDestroy?.();config=null}})}0&&(module.exports={ComputedSignal,EffectSignal,EventSignal,SignalBase,StateSignal,createComputedSignal,createDebouncedSignal,createEffect,createEventSignal,createStateSignal});
|
|
3
3
|
//# sourceMappingURL=main.cjs.map
|