@fozy-labs/rx-toolkit 0.4.18 → 0.5.0-rc.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 +20 -19
- package/dist/common/devtools/reduxDevtools.d.ts +17 -0
- package/dist/common/devtools/reduxDevtools.js +98 -17
- package/dist/common/devtools/types.d.ts +1 -0
- package/dist/common/options/DefaultOptions.d.ts +0 -2
- package/dist/common/options/DefaultOptions.js +0 -2
- package/dist/common/options/SharedOptions.d.ts +0 -2
- package/dist/common/options/SharedOptions.js +0 -1
- package/dist/query/api/resetAllQueriesCache.d.ts +1 -0
- package/dist/query/api/resetAllQueriesCache.js +4 -0
- package/dist/query/core/Opertation/Operation.js +10 -7
- package/dist/query/core/Opertation/OperationAgent.d.ts +0 -2
- package/dist/query/core/Opertation/OperationAgent.js +4 -21
- package/dist/query/core/QueriesCache.d.ts +1 -1
- package/dist/query/core/QueriesCache.js +2 -6
- package/dist/query/core/{CleanAllQueriesSignal.d.ts → ResetAllQueriesSignal.d.ts} +1 -1
- package/dist/query/core/ResetAllQueriesSignal.js +11 -0
- package/dist/query/core/Resource/Resource.js +7 -3
- package/dist/query/core/Resource/ResourceAgent.d.ts +2 -3
- package/dist/query/core/Resource/ResourceAgent.js +62 -29
- package/dist/query/index.d.ts +1 -1
- package/dist/query/index.js +1 -1
- package/dist/query/lib/IndirectMap.d.ts +1 -1
- package/dist/query/lib/IndirectMap.js +1 -1
- package/dist/query/lib/ReactiveCache.d.ts +1 -1
- package/dist/query/lib/ReactiveCache.js +2 -2
- package/dist/query/react/useOperationAgent.js +2 -5
- package/dist/query/react/useResourceAgent.js +1 -4
- package/dist/query/types/Operation.types.d.ts +1 -3
- package/dist/query/types/Resource.types.d.ts +1 -3
- package/dist/signals/base/Batcher.d.ts +1 -1
- package/dist/signals/base/Batcher.js +1 -1
- package/dist/signals/base/DependencyTracker.d.ts +18 -0
- package/dist/signals/base/DependencyTracker.js +13 -0
- package/dist/signals/base/Devtools.d.ts +1 -1
- package/dist/signals/base/Devtools.js +13 -1
- package/dist/signals/base/ReadonlySignal.d.ts +5 -7
- package/dist/signals/base/ReadonlySignal.js +20 -12
- package/dist/signals/base/index.d.ts +1 -2
- package/dist/signals/base/index.js +1 -2
- package/dist/signals/operators/index.d.ts +0 -2
- package/dist/signals/operators/index.js +0 -2
- package/dist/signals/operators/signalize.d.ts +2 -2
- package/dist/signals/operators/signalize.js +1 -1
- package/dist/signals/react/useSignal.d.ts +6 -2
- package/dist/signals/react/useSignal.js +2 -21
- package/dist/signals/signals/Computed.d.ts +13 -11
- package/dist/signals/signals/Computed.js +79 -26
- package/dist/signals/signals/Effect.d.ts +11 -7
- package/dist/signals/signals/Effect.js +60 -58
- package/dist/signals/signals/LocalSignal.d.ts +14 -7
- package/dist/signals/signals/LocalSignal.js +52 -33
- package/dist/signals/signals/Signal.d.ts +13 -37
- package/dist/signals/signals/Signal.js +44 -58
- package/dist/signals/types/index.d.ts +1 -0
- package/dist/signals/types/index.js +1 -0
- package/dist/signals/types/signals.types.d.ts +16 -0
- package/docs/CHANGELOG.md +32 -0
- package/docs/devtools/README.md +162 -29
- package/docs/migrations/0.5.0.md +73 -0
- package/docs/options/README.md +89 -0
- package/docs/query/README.md +425 -89
- package/docs/release/README.md +58 -6
- package/docs/signals/README.md +207 -34
- package/docs/usage/react/README.md +261 -49
- package/package.json +1 -1
- package/dist/query/api/cleanAllQueriesCache.d.ts +0 -1
- package/dist/query/api/cleanAllQueriesCache.js +0 -4
- package/dist/query/core/CleanAllQueriesSignal.js +0 -11
- package/dist/signals/base/Tracker.d.ts +0 -10
- package/dist/signals/base/Tracker.js +0 -7
- package/dist/signals/base/types.d.ts +0 -23
- package/dist/signals/operators/filterUpdates.d.ts +0 -5
- package/dist/signals/operators/filterUpdates.js +0 -18
- package/dist/signals/operators/mapSignals.d.ts +0 -3
- package/dist/signals/operators/mapSignals.js +0 -10
- /package/dist/signals/{base/types.js → types/signals.types.js} +0 -0
package/docs/release/README.md
CHANGED
|
@@ -1,7 +1,59 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
# Релиз
|
|
2
|
+
|
|
3
|
+
Процесс выпуска новой версии RxToolkit.
|
|
4
|
+
|
|
5
|
+
## Подготовка
|
|
6
|
+
|
|
7
|
+
1. Убедитесь, что все изменения закоммичены
|
|
8
|
+
2. Обновите CHANGELOG (если есть)
|
|
9
|
+
3. Проверьте документацию
|
|
10
|
+
|
|
11
|
+
## Команды релиза
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
# 1. Проверка типов
|
|
15
|
+
npm run ts-check
|
|
16
|
+
|
|
17
|
+
# 2. Сборка проекта
|
|
18
|
+
npm run build
|
|
19
|
+
|
|
20
|
+
# 3. Обновление версии
|
|
21
|
+
npm version patch # для патч-версии (0.4.18 -> 0.4.19)
|
|
22
|
+
npm version minor # для минорной версии (0.4.18 -> 0.5.0)
|
|
23
|
+
npm version major # для мажорной версии (0.4.18 -> 1.0.0)
|
|
24
|
+
|
|
25
|
+
# 4. Публикация в npm
|
|
26
|
+
npm publish
|
|
27
|
+
|
|
28
|
+
# 5. Пуш тегов в репозиторий
|
|
29
|
+
git push origin develop --tags
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## rc
|
|
33
|
+
|
|
34
|
+
### Выпуск релиза-кандидата (RC)
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
# 1. Проверка типов
|
|
38
|
+
npm run ts-check
|
|
39
|
+
|
|
40
|
+
# 2. Сборка проекта
|
|
41
|
+
npm run build
|
|
42
|
+
|
|
43
|
+
# 3. Обновление версии до RC
|
|
44
|
+
npm version prerelease --preid=rc
|
|
45
|
+
# пример: 1.2.0 → 1.2.0-rc.0
|
|
46
|
+
|
|
47
|
+
# 4. Публикация RC (НЕ latest!)
|
|
48
|
+
npm publish --tag rc
|
|
49
|
+
|
|
50
|
+
# 5. Пуш тегов
|
|
51
|
+
git push origin develop --tags
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Переход с RC на stable
|
|
55
|
+
```bash
|
|
56
|
+
npm version <latest_version>
|
|
57
|
+
npm publish
|
|
58
|
+
git push origin develop --tags
|
|
7
59
|
```
|
package/docs/signals/README.md
CHANGED
|
@@ -6,65 +6,160 @@ RxSignals — это реактивная система управления с
|
|
|
6
6
|
|
|
7
7
|
### Signal
|
|
8
8
|
|
|
9
|
-
Базовый класс для создания реактивных
|
|
9
|
+
Базовый класс для создания реактивных сигналов с изменяемым состоянием.
|
|
10
10
|
|
|
11
11
|
**Пример использования:**
|
|
12
12
|
|
|
13
13
|
```typescript
|
|
14
|
+
import { Signal } from '@fozy-labs/rx-toolkit';
|
|
15
|
+
|
|
14
16
|
const name = new Signal('John');
|
|
15
17
|
const age = new Signal(25);
|
|
16
18
|
|
|
17
|
-
//
|
|
18
|
-
|
|
19
|
-
console.log(`Name changed to: ${newName}`);
|
|
20
|
-
}); // Выведет: "Name changed to: John" при инициализации
|
|
19
|
+
// Чтение значения (с отслеживанием зависимостей)
|
|
20
|
+
console.log(name.get()); // "John"
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
// Чтение значения без отслеживания
|
|
23
|
+
console.log(name.peek()); // "John"
|
|
24
|
+
|
|
25
|
+
// Запись нового значения
|
|
26
|
+
name.set('Jane');
|
|
27
|
+
|
|
28
|
+
// Подписка на изменения через RxJS Observable
|
|
29
|
+
const subscription = name.obs.subscribe(newName => {
|
|
30
|
+
console.log(`Name changed to: ${newName}`);
|
|
31
|
+
});
|
|
23
32
|
|
|
24
33
|
// Отписка
|
|
25
34
|
subscription.unsubscribe();
|
|
26
35
|
```
|
|
27
36
|
|
|
37
|
+
**API Signal:**
|
|
38
|
+
- `get()` — получить значение и зарегистрировать зависимость (для использования внутри Computed/Effect)
|
|
39
|
+
- `peek()` — получить значение без регистрации зависимости
|
|
40
|
+
- `set(value)` — установить новое значение
|
|
41
|
+
- `obs` — RxJS Observable для подписки на изменения
|
|
42
|
+
|
|
28
43
|
### Computed
|
|
29
44
|
|
|
30
45
|
Создает вычисляемое значение, которое автоматически обновляется при изменении зависимостей.
|
|
31
46
|
|
|
32
47
|
```typescript
|
|
48
|
+
import { Signal, Computed } from '@fozy-labs/rx-toolkit';
|
|
49
|
+
|
|
33
50
|
const firstName = new Signal('John');
|
|
34
51
|
const lastName = new Signal('Doe');
|
|
35
52
|
|
|
36
|
-
const fullName = new Computed(() => `${firstName.
|
|
53
|
+
const fullName = new Computed(() => `${firstName.get()} ${lastName.get()}`);
|
|
37
54
|
|
|
38
|
-
console.log(fullName.
|
|
55
|
+
console.log(fullName.get()); // "John Doe"
|
|
39
56
|
|
|
40
|
-
firstName.
|
|
41
|
-
console.log(fullName.
|
|
57
|
+
firstName.set('Jane');
|
|
58
|
+
console.log(fullName.get()); // "Jane Doe"
|
|
59
|
+
|
|
60
|
+
// Подписка на изменения
|
|
61
|
+
fullName.obs.subscribe(name => console.log(name));
|
|
42
62
|
```
|
|
43
63
|
|
|
64
|
+
**API Computed:**
|
|
65
|
+
- `get()` — получить вычисленное значение с регистрацией зависимости
|
|
66
|
+
- `peek()` — получить значение без регистрации зависимости
|
|
67
|
+
- `obs` — RxJS Observable для подписки на изменения
|
|
68
|
+
|
|
44
69
|
### Effect
|
|
45
70
|
|
|
46
|
-
Создает эффект, который выполняется при изменении используемых сигналов.
|
|
71
|
+
Создает побочный эффект, который автоматически выполняется при изменении используемых сигналов.
|
|
47
72
|
|
|
48
73
|
```typescript
|
|
74
|
+
import { Signal, Effect } from '@fozy-labs/rx-toolkit';
|
|
75
|
+
|
|
49
76
|
const count = new Signal(0);
|
|
50
77
|
const message = new Signal('Hello');
|
|
51
78
|
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
console.log(`${message.
|
|
79
|
+
const effect = new Effect(() => {
|
|
80
|
+
// Выведет: "Hello: 0" при инициализации
|
|
81
|
+
console.log(`${message.get()}: ${count.get()}`);
|
|
55
82
|
});
|
|
56
83
|
|
|
57
|
-
count.
|
|
58
|
-
message.
|
|
84
|
+
count.set(1); // Выведет: "Hello: 1"
|
|
85
|
+
message.set('Hi'); // Выведет: "Hi: 1"
|
|
59
86
|
|
|
60
87
|
// Остановка эффекта
|
|
61
|
-
|
|
88
|
+
effect.unsubscribe();
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
**Cleanup функция (teardown):**
|
|
92
|
+
|
|
93
|
+
Effect поддерживает возврат функции очистки, которая вызывается перед следующим выполнением или при отписке:
|
|
94
|
+
|
|
95
|
+
```typescript
|
|
96
|
+
const effect = new Effect(() => {
|
|
97
|
+
const timer = setInterval(() => console.log(count.get()), 1000);
|
|
98
|
+
|
|
99
|
+
// Cleanup - вызывается перед повторным выполнением эффекта
|
|
100
|
+
return () => {
|
|
101
|
+
clearInterval(timer);
|
|
102
|
+
};
|
|
103
|
+
});
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Функциональный стиль API
|
|
107
|
+
|
|
108
|
+
Для более компактного синтаксиса доступны статические методы `Signal.create()`, `Signal.compute()` и `Signal.effect()`:
|
|
109
|
+
|
|
110
|
+
```typescript
|
|
111
|
+
import { Signal } from '@fozy-labs/rx-toolkit';
|
|
112
|
+
|
|
113
|
+
class CounterStore {
|
|
114
|
+
// Создание сигнала в функциональном стиле (вызывается как функция)
|
|
115
|
+
count$ = Signal.create(0);
|
|
116
|
+
|
|
117
|
+
// Computed в функциональном стиле
|
|
118
|
+
doubled$ = Signal.compute(() => this.count$() * 2);
|
|
119
|
+
squared$ = Signal.compute(() => (this.doubled$() / 2) ** 2);
|
|
120
|
+
|
|
121
|
+
increment = () => this.count$.set(this.count$.peek() + 1);
|
|
122
|
+
decrement = () => this.count$.set(this.count$.peek() - 1);
|
|
123
|
+
reset = () => this.count$.set(0);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const store = new CounterStore();
|
|
127
|
+
|
|
128
|
+
// Чтение значения - вызов как функции
|
|
129
|
+
console.log(store.count$()); // 0
|
|
130
|
+
console.log(store.doubled$()); // 0
|
|
131
|
+
|
|
132
|
+
store.increment();
|
|
133
|
+
console.log(store.count$()); // 1
|
|
134
|
+
console.log(store.doubled$()); // 2
|
|
135
|
+
console.log(store.squared$()); // 1
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
**API функциональных сигналов:**
|
|
139
|
+
- `signal$()` — вызов как функции возвращает значение (аналог `get()`)
|
|
140
|
+
- `signal$.peek()` — получить значение без отслеживания
|
|
141
|
+
- `signal$.set(value)` — установить значение
|
|
142
|
+
- `signal$.obs` — RxJS Observable
|
|
143
|
+
|
|
144
|
+
### ReadonlySignal
|
|
145
|
+
|
|
146
|
+
Базовый класс для сигналов только для чтения. Используется внутри `signalize` и для создания кастомных сигналов.
|
|
147
|
+
|
|
148
|
+
```typescript
|
|
149
|
+
import { ReadonlySignal } from '@fozy-labs/rx-toolkit';
|
|
150
|
+
|
|
151
|
+
const customSignal = new ReadonlySignal((subscriber) => {
|
|
152
|
+
// Логика подписки
|
|
153
|
+
subscriber.next(initialValue);
|
|
154
|
+
return () => {
|
|
155
|
+
// Cleanup
|
|
156
|
+
};
|
|
157
|
+
});
|
|
62
158
|
```
|
|
63
159
|
|
|
64
160
|
### LocalSignal
|
|
65
161
|
|
|
66
|
-
Сигнал, который синхронизируется с
|
|
67
|
-
// TODO убрать zod из core, добавить возможность передавать "driver".
|
|
162
|
+
Сигнал, который автоматически синхронизируется с `localStorage`.
|
|
68
163
|
|
|
69
164
|
```typescript
|
|
70
165
|
import { z } from 'zod/v4';
|
|
@@ -77,25 +172,33 @@ enum FILTER {
|
|
|
77
172
|
MEETINGS = 'meetings',
|
|
78
173
|
}
|
|
79
174
|
|
|
80
|
-
const selectedFilter$ =
|
|
175
|
+
const selectedFilter$ = LocalSignal.create({
|
|
81
176
|
key: 'memberships-list-selected-filter',
|
|
82
177
|
defaultValue: FILTER.ALL,
|
|
83
|
-
zodSchema: z.
|
|
178
|
+
zodSchema: z.nativeEnum(FILTER), // Опционально: валидация через Zod
|
|
84
179
|
});
|
|
85
|
-
```
|
|
86
180
|
|
|
87
|
-
|
|
181
|
+
// Использование
|
|
182
|
+
console.log(selectedFilter$.peek()); // Значение из localStorage или FILTER.ALL
|
|
183
|
+
selectedFilter$.set(FILTER.CHANNELS); // Сохраняется в localStorage
|
|
184
|
+
```
|
|
88
185
|
|
|
89
|
-
|
|
90
|
-
|
|
186
|
+
**Опции LocalSignal:**
|
|
187
|
+
- `key` — ключ для localStorage
|
|
188
|
+
- `defaultValue` — значение по умолчанию
|
|
189
|
+
- `zodSchema` — опциональная Zod-схема для валидации
|
|
190
|
+
- `userId` — опциональный идентификатор пользователя для изоляции данных
|
|
191
|
+
- `checkEffect` — функция валидации значения
|
|
192
|
+
- `devtoolsOptions` — настройки для devtools
|
|
91
193
|
|
|
194
|
+
## Операторы
|
|
92
195
|
|
|
93
196
|
### signalize
|
|
94
197
|
|
|
95
|
-
Преобразует Observable в Signal.
|
|
198
|
+
Преобразует RxJS Observable в Signal. Позволяет использовать любой Observable как реактивный сигнал.
|
|
96
199
|
|
|
97
200
|
```typescript
|
|
98
|
-
import { interval } from 'rxjs';
|
|
201
|
+
import { interval, startWith } from 'rxjs';
|
|
99
202
|
import { signalize, Effect } from '@fozy-labs/rx-toolkit';
|
|
100
203
|
|
|
101
204
|
// Создаем Observable, который эмитит значение каждую секунду
|
|
@@ -106,17 +209,87 @@ const timer$ = interval(1000).pipe(
|
|
|
106
209
|
// Преобразуем Observable в Signal
|
|
107
210
|
const tick$ = signalize(timer$);
|
|
108
211
|
|
|
109
|
-
// Теперь можно использовать
|
|
212
|
+
// Теперь можно использовать tick$ как обычный Signal
|
|
110
213
|
new Effect(() => {
|
|
111
|
-
console.log(`Timer: ${tick$.
|
|
112
|
-
})
|
|
214
|
+
console.log(`Timer: ${tick$.get()}`);
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
// Доступ к значению без подписки
|
|
218
|
+
console.log(tick$.peek());
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
## Батчинг обновлений (Batcher)
|
|
222
|
+
|
|
223
|
+
RxSignals автоматически группирует множественные обновления сигналов в один цикл обновления. Это обеспечивает:
|
|
224
|
+
- Консистентность состояния
|
|
225
|
+
- Оптимальную производительность
|
|
226
|
+
- Предсказуемый порядок выполнения эффектов
|
|
227
|
+
|
|
228
|
+
```typescript
|
|
229
|
+
const a = Signal.create(1);
|
|
230
|
+
const b = Signal.create((2);
|
|
231
|
+
const sum = Signal.compute(() => a() + b());
|
|
232
|
+
|
|
233
|
+
new Effect(() => {
|
|
234
|
+
console.log(`Sum: ${sum()}`);
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
// Оба изменения обрабатываются в одном батче
|
|
238
|
+
Batcher.run(() => {
|
|
239
|
+
a.set(10);
|
|
240
|
+
b.set(20);
|
|
241
|
+
});
|
|
242
|
+
// Effect выведет: "Sum: 30" (один раз, а не два)
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
## Интеграция с RxJS
|
|
246
|
+
|
|
247
|
+
Сигналы полностью совместимы с RxJS. Каждый сигнал предоставляет `obs` — стандартный RxJS Observable:
|
|
248
|
+
|
|
249
|
+
```typescript
|
|
250
|
+
import { filter, take, debounceTime } from 'rxjs';
|
|
251
|
+
import { Signal, Computed, signalize } from '@fozy-labs/rx-toolkit';
|
|
252
|
+
|
|
253
|
+
const clicks = Signal.create(0);
|
|
254
|
+
|
|
255
|
+
// Используем RxJS операторы
|
|
256
|
+
const tenClicks$ = clicks.obs.pipe(
|
|
257
|
+
filter(value => value === 10),
|
|
258
|
+
take(1)
|
|
259
|
+
);
|
|
260
|
+
|
|
261
|
+
tenClicks$.subscribe(() => {
|
|
262
|
+
console.log('Reached 10 clicks!');
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
// Или наоборот - превращаем Observable в Signal
|
|
266
|
+
const debouncedClicks$ = signalize(
|
|
267
|
+
clicks.obs.pipe(
|
|
268
|
+
debounceTime(300)
|
|
269
|
+
)
|
|
270
|
+
);
|
|
271
|
+
|
|
272
|
+
// Теперь debouncedClicks$ можно использовать в Computed/Effect
|
|
273
|
+
const doubled = Signal.compute(() => debouncedClicks$() * 2);
|
|
113
274
|
```
|
|
114
275
|
|
|
115
|
-
|
|
276
|
+
## Devtools
|
|
277
|
+
|
|
278
|
+
Сигналы поддерживают интеграцию с Redux DevTools для отладки:
|
|
279
|
+
|
|
280
|
+
```typescript
|
|
281
|
+
import { Signal } from '@fozy-labs/rx-toolkit';
|
|
282
|
+
|
|
283
|
+
// С именем для devtools
|
|
284
|
+
const count$ = Signal.create(0, 'counter');
|
|
116
285
|
|
|
117
|
-
|
|
118
|
-
|
|
286
|
+
// Или с расширенными опциями
|
|
287
|
+
const user$ = Signal.create(null, {
|
|
288
|
+
isDisabled: false, // Отключить отслеживание в devtools
|
|
289
|
+
});
|
|
290
|
+
```
|
|
119
291
|
|
|
120
|
-
## React
|
|
292
|
+
## React интеграция
|
|
121
293
|
|
|
122
294
|
См. [React интеграция](../usage/react/README.md) для подробной информации о том, как использовать RxSignals в React приложениях.
|
|
295
|
+
|