@fozy-labs/rx-toolkit 0.4.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.
Files changed (98) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +131 -0
  3. package/dist/index.d.ts +3 -0
  4. package/dist/index.js +3 -0
  5. package/dist/query/SKIP_TOKEN.d.ts +1 -0
  6. package/dist/query/SKIP_TOKEN.js +1 -0
  7. package/dist/query/api/DefaultOptions.d.ts +9 -0
  8. package/dist/query/api/DefaultOptions.js +9 -0
  9. package/dist/query/api/createDevtools.d.ts +1 -0
  10. package/dist/query/api/createDevtools.js +6 -0
  11. package/dist/query/api/createOperation.d.ts +7 -0
  12. package/dist/query/api/createOperation.js +6 -0
  13. package/dist/query/api/createResource.d.ts +3 -0
  14. package/dist/query/api/createResource.js +2 -0
  15. package/dist/query/api/createSubResource.d.ts +0 -0
  16. package/dist/query/api/createSubResource.js +1 -0
  17. package/dist/query/core/Opertation/Operation.d.ts +34 -0
  18. package/dist/query/core/Opertation/Operation.js +176 -0
  19. package/dist/query/core/Opertation/OperationAgent.d.ts +20 -0
  20. package/dist/query/core/Opertation/OperationAgent.js +54 -0
  21. package/dist/query/core/QueriesCache.d.ts +8 -0
  22. package/dist/query/core/QueriesCache.js +31 -0
  23. package/dist/query/core/Resource/Resource.d.ts +40 -0
  24. package/dist/query/core/Resource/Resource.js +154 -0
  25. package/dist/query/core/Resource/ResourceAgent.d.ts +34 -0
  26. package/dist/query/core/Resource/ResourceAgent.js +87 -0
  27. package/dist/query/core/Resource/ResourceRef.d.ts +18 -0
  28. package/dist/query/core/Resource/ResourceRef.js +52 -0
  29. package/dist/query/core/SharedOptions.d.ts +5 -0
  30. package/dist/query/core/SharedOptions.js +4 -0
  31. package/dist/query/index.d.ts +7 -0
  32. package/dist/query/index.js +7 -0
  33. package/dist/query/lib/IndirectMap.d.ts +18 -0
  34. package/dist/query/lib/IndirectMap.js +85 -0
  35. package/dist/query/lib/ReactiveCache.d.ts +77 -0
  36. package/dist/query/lib/ReactiveCache.js +96 -0
  37. package/dist/query/lib/shallowEqual.d.ts +1 -0
  38. package/dist/query/lib/shallowEqual.js +21 -0
  39. package/dist/query/react/useOperationAgent.d.ts +9 -0
  40. package/dist/query/react/useOperationAgent.js +22 -0
  41. package/dist/query/react/useResourceAgent.d.ts +9 -0
  42. package/dist/query/react/useResourceAgent.js +25 -0
  43. package/dist/query/types/Operation.types.d.ts +91 -0
  44. package/dist/query/types/Operation.types.js +1 -0
  45. package/dist/query/types/Resource.types.d.ts +90 -0
  46. package/dist/query/types/Resource.types.js +1 -0
  47. package/dist/query/types/shared.types.d.ts +4 -0
  48. package/dist/query/types/shared.types.js +1 -0
  49. package/dist/react-hooks/index.d.ts +5 -0
  50. package/dist/react-hooks/index.js +5 -0
  51. package/dist/react-hooks/useConstant.d.ts +4 -0
  52. package/dist/react-hooks/useConstant.js +19 -0
  53. package/dist/react-hooks/useEventHandler.d.ts +1 -0
  54. package/dist/react-hooks/useEventHandler.js +6 -0
  55. package/dist/react-hooks/useObservable.d.ts +12 -0
  56. package/dist/react-hooks/useObservable.js +48 -0
  57. package/dist/react-hooks/useSignal.d.ts +2 -0
  58. package/dist/react-hooks/useSignal.js +12 -0
  59. package/dist/react-hooks/useSyncObservable.d.ts +16 -0
  60. package/dist/react-hooks/useSyncObservable.js +52 -0
  61. package/dist/signal/base/Batcher.d.ts +7 -0
  62. package/dist/signal/base/Batcher.js +21 -0
  63. package/dist/signal/base/Computed.d.ts +10 -0
  64. package/dist/signal/base/Computed.js +26 -0
  65. package/dist/signal/base/Effect.d.ts +12 -0
  66. package/dist/signal/base/Effect.js +69 -0
  67. package/dist/signal/base/ReadonlySignal.d.ts +12 -0
  68. package/dist/signal/base/ReadonlySignal.js +20 -0
  69. package/dist/signal/base/Signal.d.ts +30 -0
  70. package/dist/signal/base/Signal.js +44 -0
  71. package/dist/signal/base/SyncObservable.d.ts +5 -0
  72. package/dist/signal/base/SyncObservable.js +18 -0
  73. package/dist/signal/base/Tracker.d.ts +5 -0
  74. package/dist/signal/base/Tracker.js +7 -0
  75. package/dist/signal/base/index.d.ts +8 -0
  76. package/dist/signal/base/index.js +8 -0
  77. package/dist/signal/base/types.d.ts +15 -0
  78. package/dist/signal/base/types.js +1 -0
  79. package/dist/signal/extends/LocalSignal.d.ts +24 -0
  80. package/dist/signal/extends/LocalSignal.js +66 -0
  81. package/dist/signal/extends/index.d.ts +1 -0
  82. package/dist/signal/extends/index.js +1 -0
  83. package/dist/signal/index.d.ts +3 -0
  84. package/dist/signal/index.js +3 -0
  85. package/dist/signal/operators/batch.d.ts +2 -0
  86. package/dist/signal/operators/batch.js +27 -0
  87. package/dist/signal/operators/filterUpdates.d.ts +5 -0
  88. package/dist/signal/operators/filterUpdates.js +18 -0
  89. package/dist/signal/operators/index.d.ts +4 -0
  90. package/dist/signal/operators/index.js +4 -0
  91. package/dist/signal/operators/mapSignals.d.ts +3 -0
  92. package/dist/signal/operators/mapSignals.js +10 -0
  93. package/dist/signal/operators/signalize.d.ts +3 -0
  94. package/dist/signal/operators/signalize.js +6 -0
  95. package/docs/query/README.md +224 -0
  96. package/docs/signals/README.md +119 -0
  97. package/docs/usage/react/README.md +144 -0
  98. package/package.json +57 -0
@@ -0,0 +1,119 @@
1
+ # RxSignals
2
+
3
+ RxSignals — это реактивная система управления состоянием, вдохновленная современными фреймворками типа SolidJS и Angular Signals. Она предоставляет эффективные инструменты для создания реактивных приложений.
4
+
5
+ ## Основные концепции
6
+
7
+ ### Signal
8
+
9
+ Базовый класс для создания реактивных сигналов.
10
+
11
+ **Пример использования:**
12
+
13
+ ```typescript
14
+ const name = new Signal('John');
15
+ const age = new Signal(25);
16
+
17
+ // Подписка на изменения
18
+ const subscription = name.subscribe(newName => {
19
+ console.log(`Name changed to: ${newName}`);
20
+ });
21
+
22
+ name.value = 'Jane'; // Выведет: "Name changed to: Jane"
23
+
24
+ // Отписка
25
+ subscription.unsubscribe();
26
+ ```
27
+
28
+ ### Computed
29
+
30
+ Создает вычисляемое значение, которое автоматически обновляется при изменении зависимостей.
31
+
32
+ ```typescript
33
+ const firstName = new Signal('John');
34
+ const lastName = new Signal('Doe');
35
+
36
+ const fullName = new Computed(() => `${firstName.value} ${lastName.value}`);
37
+
38
+ console.log(fullName.value); // "John Doe"
39
+
40
+ firstName.value = 'Jane';
41
+ console.log(fullName.value); // "Jane Doe"
42
+ ```
43
+
44
+ ### Effect
45
+
46
+ Создает эффект, который выполняется при изменении используемых сигналов.
47
+
48
+ ```typescript
49
+ const count = new Signal(0);
50
+ const message = new Signal('Hello');
51
+
52
+ const sub = new Effect(() => {
53
+ // Выведет: "Hello: 0" при инициализации
54
+ console.log(`${message.value}: ${count.value}`);
55
+ });
56
+
57
+ count.value = 1; // Выведет: "Hello: 1"
58
+ message.value = 'Hi'; // Выведет: "Hi: 1"
59
+
60
+ // Остановка эффекта
61
+ sub.unsubscribe();
62
+ ```
63
+
64
+ ### LocalSignal
65
+
66
+ Сигнал, который синхронизируется с локальным хранилищем (localStorage).
67
+ // TODO убрать zod из core, добавить возможность передавать "driver".
68
+
69
+ ```typescript
70
+ import { LocalSignal } from '@fozy-labs/rx-toolkit';
71
+
72
+ const selectedFilter$ = new LocalSignal({
73
+ key: 'projects-list-selected-filter',
74
+ defaultValue: FILTER.ALL,
75
+ zodSchema: z.enum(FILTER),
76
+ });
77
+ ```
78
+
79
+ ## Operators (Операторы)
80
+
81
+ ### batched
82
+ Группирует несколько обновлений в одну транзакцию для оптимизации производительности.
83
+ // TODO: проверить, тк не используется в fozy, добавить пример использования
84
+
85
+ ### mapSignals
86
+ // TODO: добавить описание
87
+
88
+
89
+ ### signalize
90
+
91
+ Преобразует Observable в Signal.
92
+
93
+ ```typescript
94
+ import { signalize } from '@fozy-labs/rx-toolkit';
95
+ import { interval } from 'rxjs';
96
+ import { Effect } from "src/signal/base/Effect";
97
+
98
+ // Создаем Observable, который эмитит значение каждую секунду
99
+ const timer$ = interval(1000).pipe(
100
+ startWith(0),
101
+ );
102
+
103
+ // Преобразуем Observable в Signal
104
+ const tick$ = signalize(timer$);
105
+
106
+ // Теперь можно использовать timerSignal как обычный Signal
107
+ new Effect(() => {
108
+ console.log(`Timer: ${tick$.value}`);
109
+ })
110
+ ```
111
+
112
+ ### filterUpdates
113
+
114
+ Фильтрует обновления сигнала.
115
+ // TODO: добавить пример использования, подумать над целесообразностью
116
+
117
+ ## React Integration
118
+
119
+ См. [React интеграция](../usage/react/README.md) для подробной информации о том, как использовать RxSignals в React приложениях.
@@ -0,0 +1,144 @@
1
+ # React интеграция
2
+
3
+ RxToolkit предоставляет набор React хуков для эффективной интеграции с реактивными системами библиотеки. Все хуки оптимизированы для минимальных ре-рендеров и максимальной производительности.
4
+
5
+ ## Основные хуки
6
+
7
+ ### useSignal
8
+
9
+ Подписывается на изменения сигнала и возвращает текущее значение.
10
+
11
+ ```tsx
12
+ import { useSignal } from '@fozy-labs/rx-toolkit';
13
+
14
+ function Counter() {
15
+ const count = useSignal(countSignal);
16
+
17
+ return (
18
+ <div>
19
+ <p>Count: {count}</p>
20
+ <button onClick={() => countSignal.value++}>
21
+ Increment
22
+ </button>
23
+ </div>
24
+ );
25
+ }
26
+ ```
27
+
28
+ **Особенности:**
29
+ - Автоматическая подписка и отписка
30
+ - Использует `useSyncExternalStore` для оптимальной производительности
31
+ - Не вызывает ре-рендер, если значение не изменилось
32
+
33
+ ### useObservable
34
+
35
+ Подписывается на RxJS Observable и возвращает текущее значение.
36
+
37
+ ```typescript
38
+ import { useObservable } from '@fozy-labs/rx-toolkit';
39
+ import { interval, map } from 'rxjs';
40
+
41
+ const timer$ = interval(1000).pipe(
42
+ map(count => `Timer: ${count}`)
43
+ );
44
+
45
+ function Timer() {
46
+ const timerValue = useObservable(timer$, 'Timer: 0');
47
+
48
+ return <div>{timerValue}</div>;
49
+ }
50
+ ```
51
+
52
+ **Параметры:**
53
+ - `observable$` — RxJS Observable для подписки
54
+ - `initialValue` — начальное значение до первой эмиссии
55
+
56
+ ### useSyncObservable
57
+
58
+ Синхронная версия `useObservable` для Observable, которые могут выдать значение немедленно.
59
+ Если Observable не может выдать значение сразу, будет выброшена ошибка.
60
+
61
+ ```tsx
62
+ import { useSyncObservable } from '@fozy-labs/rx-toolkit';
63
+ import { BehaviorSubject } from 'rxjs';
64
+
65
+ const data$ = new BehaviorSubject('initial data');
66
+
67
+ function DataComponent() {
68
+ const data = useSyncObservable(data$);
69
+
70
+ return <div>Data: {data}</div>;
71
+ }
72
+ ```
73
+
74
+ **Отличия от useObservable:**
75
+ - Не требует начального значения
76
+ - Получает значение синхронно при первом рендере
77
+ - Подходит для BehaviorSubject и других синхронных Observable
78
+
79
+ ## RxQuery хуки
80
+
81
+ ### useResourceAgent
82
+
83
+ Подписывается на состояние ресурса и автоматически инициирует запрос.
84
+
85
+ ```tsx
86
+ import { useResourceAgent, SKIP } from '@fozy-labs/rx-toolkit';
87
+ import { userResource } from '../api/userResource.ts';
88
+
89
+ // Автоматическая инициация
90
+ function UserProfile({ userId }: { userId: string | null }) {
91
+ const userState = useResourceAgent(userResource, userId ? { id: userId } : SKIP);
92
+
93
+ if (userState.isLoading || !userId) return <div>Загрузка...</div>;
94
+ if (userState.isError) return <div>Ошибка: {userState.error?.message}</div>;
95
+
96
+ return (
97
+ <div>
98
+ <h1>{userState.data?.name}</h1>
99
+ <p>{userState.data?.email}</p>
100
+ </div>
101
+ );
102
+ }
103
+ ```
104
+
105
+ **Особенности:**
106
+ - Автоматическая подписка на состояние ресурса
107
+ - Умная инициация: не повторяет запрос для тех же аргументов
108
+ - Поддержка SKIP токена для ручного управления
109
+
110
+ ### useOperationAgent
111
+
112
+ Подписывается на состояние операции для отслеживания выполнения мутаций.
113
+
114
+ ```tsx
115
+ import { useOperationAgent } from '@fozy-labs/rx-toolkit';
116
+ import { updateUserOperation } from '../api/updateUserOperation.ts';
117
+ import { User } from '../types/user.ts';
118
+
119
+ function EditUserForm({ user }: { user: User }) {
120
+ const [updateUser, updateUserQuery] = useOperationAgent(updateUserOperation);
121
+
122
+ const handleSubmit = async (event: React.FormEvent) => {
123
+ event.preventDefault();
124
+ const formData = new FormData(event.target as HTMLFormElement);
125
+ try {
126
+ await agent.initiate({ id: user.id, data: formData });
127
+ alert('Пользователь обновлен');
128
+ } catch (error) {
129
+ alert('Ошибка при обновлении пользователя');
130
+ }
131
+ };
132
+
133
+ return (
134
+ <form onSubmit={handleSubmit}>
135
+ <input name="name" defaultValue={user.name} />
136
+ <input name="email" defaultValue={user.email} />
137
+ <button type="submit" disabled={updateUserQuery.isLoading}>
138
+ {updateUserQuery.isLoading ? 'Обновление...' : 'Обновить'}
139
+ </button>
140
+ {updateUserQuery.isError && <p>Ошибка: {updateUserQuery.error?.message}</p>}
141
+ </form>
142
+ );
143
+ }
144
+ ```
package/package.json ADDED
@@ -0,0 +1,57 @@
1
+ {
2
+ "name": "@fozy-labs/rx-toolkit",
3
+ "version": "0.4.1",
4
+ "main": "./dist/index.js",
5
+ "types": "./dist/index.d.ts",
6
+ "type": "module",
7
+ "scripts": {
8
+ "build": "rimraf ./dist && tsc && tsc-alias",
9
+ "build:watch": "rimraf ./dist && (concurrently \"tsc -w\" \"tsc-alias -w\")",
10
+ "ts-check": "tsc --noEmit"
11
+ },
12
+ "dependencies": {
13
+ "@reatom/devtools": "0.13.1"
14
+ },
15
+ "devDependencies": {
16
+ "rimraf": "6.0.1",
17
+ "tsc-alias": "^1.8.16",
18
+ "tsconfig-paths": "4.2.0",
19
+ "concurrently": "9.2.0",
20
+ "typescript": "5.9.2",
21
+ "zod": "4.1.11"
22
+ },
23
+ "peerDependencies": {
24
+ "react": "19.1.1",
25
+ "rxjs": "7.8.2",
26
+ "zod": "4.1.11"
27
+ },
28
+ "description": "Набор инструментов для реактивного управления состоянием, построенный поверх RxJS.",
29
+ "author": "Vladimir Panev <vova6255@gmail.com>",
30
+ "homepage": "https://github.com/fozy-labs/rx-toolkit",
31
+ "license": "MIT",
32
+ "keywords": ["react", "rxjs", "toolkit", "state-management"],
33
+ "repository": {
34
+ "type": "git",
35
+ "url": "git+https://github.com/fozy-labs/rx-toolkit.git"
36
+ },
37
+ "bugs": {
38
+ "url": "https://github.com/fozy-labs/rx-toolkit/issues"
39
+ },
40
+ "files": [
41
+ "dist",
42
+ "docs",
43
+ "README.md",
44
+ "LICENSE"
45
+ ],
46
+ "exports": {
47
+ ".": {
48
+ "import": "./dist/index.js",
49
+ "types": "./dist/index.d.ts"
50
+ }
51
+ },
52
+ "sideEffects": false,
53
+ "publishConfig": {
54
+ "access": "public"
55
+ },
56
+ "preferGlobal": false
57
+ }