synapse-storage 4.1.2 → 5.0.3
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 +142 -12
- package/dist/_utils/chunk.util.d.ts +0 -1
- package/dist/_utils/deepMerge.util.d.ts +0 -1
- package/dist/_utils/error-handling.util.d.ts +0 -1
- package/dist/_utils/flatMap.util.d.ts +0 -1
- package/dist/_utils/index.d.ts +0 -1
- package/dist/_utils/logger-console.util.d.ts +0 -1
- package/dist/api/api.module.d.ts +0 -1
- package/dist/api/components/endpoint.d.ts +11 -12
- package/dist/api/components/endpoint.js.map +1 -1
- package/dist/api/components/query-storage.d.ts +0 -1
- package/dist/api/components/query-storage.js +1 -1
- package/dist/api/components/query-storage.js.map +1 -1
- package/dist/api/index.d.ts +0 -1
- package/dist/api/types/api.interface.d.ts +0 -1
- package/dist/api/types/endpoint.interface.d.ts +0 -1
- package/dist/api/types/query.interface.d.ts +0 -1
- package/dist/api/utils/api-helpers.d.ts +0 -1
- package/dist/{core/storage → api}/utils/cache.util.d.ts +3 -6
- package/dist/{core/storage → api}/utils/cache.util.js +4 -7
- package/dist/api/utils/cache.util.js.map +1 -0
- package/dist/api/utils/create-header-context.d.ts +0 -1
- package/dist/api/utils/endpoint-headers.d.ts +0 -1
- package/dist/api/utils/fetch-base-query.d.ts +0 -1
- package/dist/api/utils/file-utils.d.ts +0 -1
- package/dist/api/utils/get-cacheable-headers.d.ts +0 -1
- package/dist/core/index.d.ts +0 -1
- package/dist/core/selector/index.d.ts +1 -1
- package/dist/core/selector/index.js +2 -0
- package/dist/core/selector/index.js.map +1 -1
- package/dist/core/selector/selector.interface.d.ts +15 -30
- package/dist/core/selector/selector.interface.js +2 -2
- package/dist/core/selector/selector.interface.js.map +1 -1
- package/dist/core/selector/selector.module.d.ts +16 -1
- package/dist/core/selector/selector.module.js +82 -20
- package/dist/core/selector/selector.module.js.map +1 -1
- package/dist/core/selector/selectors.base.d.ts +56 -0
- package/dist/core/selector/selectors.base.js +118 -0
- package/dist/core/selector/selectors.base.js.map +1 -0
- package/dist/core/storage/adapters/async-base-storage.service.d.ts +15 -4
- package/dist/core/storage/adapters/async-base-storage.service.js +106 -36
- package/dist/core/storage/adapters/async-base-storage.service.js.map +1 -1
- package/dist/core/storage/adapters/indexed-DB.service.d.ts +4 -5
- package/dist/core/storage/adapters/indexed-DB.service.js +66 -14
- package/dist/core/storage/adapters/indexed-DB.service.js.map +1 -1
- package/dist/core/storage/adapters/local-storage.service.d.ts +9 -4
- package/dist/core/storage/adapters/local-storage.service.js +25 -5
- package/dist/core/storage/adapters/local-storage.service.js.map +1 -1
- package/dist/core/storage/adapters/memory-storage.service.d.ts +2 -4
- package/dist/core/storage/adapters/memory-storage.service.js +5 -5
- package/dist/core/storage/adapters/memory-storage.service.js.map +1 -1
- package/dist/core/storage/adapters/path.utils.d.ts +0 -1
- package/dist/core/storage/adapters/storage-core.d.ts +6 -2
- package/dist/core/storage/adapters/storage-core.js +6 -3
- package/dist/core/storage/adapters/storage-core.js.map +1 -1
- package/dist/core/storage/adapters/sync-base-storage.service.d.ts +20 -4
- package/dist/core/storage/adapters/sync-base-storage.service.js +110 -35
- package/dist/core/storage/adapters/sync-base-storage.service.js.map +1 -1
- package/dist/core/storage/index.d.ts +2 -5
- package/dist/core/storage/index.js +1 -5
- package/dist/core/storage/index.js.map +1 -1
- package/dist/core/storage/middlewares/broadcast.middleware.d.ts +0 -1
- package/dist/core/storage/middlewares/index.d.ts +3 -1
- package/dist/core/storage/middlewares/index.js +6 -0
- package/dist/core/storage/middlewares/index.js.map +1 -1
- package/dist/core/storage/middlewares/storage-batching.middleware.d.ts +0 -1
- package/dist/core/storage/middlewares/storage-logger.middleware.d.ts +20 -0
- package/dist/core/storage/middlewares/storage-logger.middleware.js +53 -0
- package/dist/core/storage/middlewares/storage-logger.middleware.js.map +1 -0
- package/dist/core/storage/middlewares/storage-shallow-compare.middleware.d.ts +0 -1
- package/dist/core/storage/middlewares/storage-shallow-compare.middleware.js +4 -10
- package/dist/core/storage/middlewares/storage-shallow-compare.middleware.js.map +1 -1
- package/dist/core/storage/middlewares/sync-broadcast.middleware.d.ts +0 -1
- package/dist/core/storage/middlewares/sync-storage-batching.middleware.d.ts +0 -1
- package/dist/core/storage/middlewares/sync-storage-logger.middleware.d.ts +7 -0
- package/dist/core/storage/middlewares/sync-storage-logger.middleware.js +48 -0
- package/dist/core/storage/middlewares/sync-storage-logger.middleware.js.map +1 -0
- package/dist/core/storage/middlewares/sync-storage-shallow-compare.middleware.d.ts +0 -1
- package/dist/core/storage/middlewares/sync-storage-shallow-compare.middleware.js +4 -10
- package/dist/core/storage/middlewares/sync-storage-shallow-compare.middleware.js.map +1 -1
- package/dist/core/storage/modules/singleton/mixin.util.d.ts +0 -1
- package/dist/core/storage/modules/singleton/models.d.ts +0 -1
- package/dist/core/storage/modules/singleton/singleton.util.d.ts +0 -1
- package/dist/core/storage/storage.interface.d.ts +59 -4
- package/dist/core/storage/storage.interface.js +0 -2
- package/dist/core/storage/storage.interface.js.map +1 -1
- package/dist/core/storage/utils/broadcast.util.d.ts +0 -1
- package/dist/core/storage/utils/middleware-module.d.ts +0 -3
- package/dist/core/storage/utils/middleware-module.js +0 -8
- package/dist/core/storage/utils/middleware-module.js.map +1 -1
- package/dist/core/storage/utils/migration.util.d.ts +38 -0
- package/dist/core/storage/utils/migration.util.js +48 -0
- package/dist/core/storage/utils/migration.util.js.map +1 -0
- package/dist/core/storage/utils/path-selector.util.d.ts +0 -1
- package/dist/core/storage/utils/state-diff.util.d.ts +8 -1
- package/dist/core/storage/utils/state-diff.util.js +17 -1
- package/dist/core/storage/utils/state-diff.util.js.map +1 -1
- package/dist/core/storage/utils/storage-factory.util.d.ts +7 -9
- package/dist/core/storage/utils/storage-factory.util.js +10 -10
- package/dist/core/storage/utils/storage-factory.util.js.map +1 -1
- package/dist/core/storage/utils/storage-key.d.ts +0 -1
- package/dist/index.d.ts +0 -1
- package/dist/react/hooks/index.d.ts +2 -1
- package/dist/react/hooks/index.js +4 -0
- package/dist/react/hooks/index.js.map +1 -1
- package/dist/react/hooks/useCreateStorage.d.ts +5 -6
- package/dist/react/hooks/useCreateStorage.js +2 -2
- package/dist/react/hooks/useCreateStorage.js.map +1 -1
- package/dist/react/hooks/useObservable.d.ts +17 -0
- package/dist/react/hooks/useObservable.js +38 -0
- package/dist/react/hooks/useObservable.js.map +1 -0
- package/dist/react/hooks/useSelector.d.ts +0 -1
- package/dist/react/hooks/useSelector.js +5 -2
- package/dist/react/hooks/useSelector.js.map +1 -1
- package/dist/react/hooks/useStorage.d.ts +0 -1
- package/dist/react/hooks/useStorageSubscribe.d.ts +0 -1
- package/dist/react/hooks/useSubscription.d.ts +13 -0
- package/dist/react/hooks/useSubscription.js +23 -0
- package/dist/react/hooks/useSubscription.js.map +1 -0
- package/dist/react/index.d.ts +0 -1
- package/dist/react/utils/awaitSynapse.d.ts +9 -10
- package/dist/react/utils/awaitSynapse.js +3 -2
- package/dist/react/utils/awaitSynapse.js.map +1 -1
- package/dist/react/utils/createSynapseCtx.d.ts +18 -23
- package/dist/react/utils/createSynapseCtx.js +64 -39
- package/dist/react/utils/createSynapseCtx.js.map +1 -1
- package/dist/react/utils/index.d.ts +0 -1
- package/dist/reactive/dispatcher/dispatcher.base.d.ts +122 -0
- package/dist/reactive/dispatcher/dispatcher.base.js +294 -0
- package/dist/reactive/dispatcher/dispatcher.base.js.map +1 -0
- package/dist/reactive/dispatcher/dispatcher.module.d.ts +12 -67
- package/dist/reactive/dispatcher/dispatcher.module.js +13 -72
- package/dist/reactive/dispatcher/dispatcher.module.js.map +1 -1
- package/dist/reactive/dispatcher/index.d.ts +1 -1
- package/dist/reactive/dispatcher/index.js +2 -0
- package/dist/reactive/dispatcher/index.js.map +1 -1
- package/dist/reactive/dispatcher/middlewares/index.d.ts +0 -1
- package/dist/reactive/dispatcher/middlewares/logger.middleware.d.ts +0 -1
- package/dist/reactive/dispatcher/path.util.d.ts +15 -0
- package/dist/reactive/dispatcher/path.util.js +34 -0
- package/dist/reactive/dispatcher/path.util.js.map +1 -0
- package/dist/reactive/dispatcher/standalone.d.ts +1 -150
- package/dist/reactive/dispatcher/standalone.js +6 -217
- package/dist/reactive/dispatcher/standalone.js.map +1 -1
- package/dist/reactive/effects/effects.base.d.ts +62 -0
- package/dist/reactive/effects/effects.base.js +90 -0
- package/dist/reactive/effects/effects.base.js.map +1 -0
- package/dist/reactive/effects/effects.module.d.ts +122 -11
- package/dist/reactive/effects/effects.module.js +129 -17
- package/dist/reactive/effects/effects.module.js.map +1 -1
- package/dist/reactive/effects/index.d.ts +1 -1
- package/dist/reactive/effects/index.js +2 -0
- package/dist/reactive/effects/index.js.map +1 -1
- package/dist/reactive/effects/utils/chunkRequestConsistent.d.ts +0 -1
- package/dist/reactive/effects/utils/chunkRequestParallel.d.ts +0 -1
- package/dist/reactive/effects/utils/fromRequest.d.ts +0 -1
- package/dist/reactive/effects/utils/index.d.ts +0 -1
- package/dist/reactive/effects/utils/toObservable.d.ts +0 -1
- package/dist/reactive/index.d.ts +0 -1
- package/dist/utils/createEventBus.d.ts +47 -46
- package/dist/utils/createEventBus.js +152 -174
- package/dist/utils/createEventBus.js.map +1 -1
- package/dist/utils/createSynapse/createSynapse.d.ts +25 -7
- package/dist/utils/createSynapse/createSynapse.js +28 -98
- package/dist/utils/createSynapse/createSynapse.js.map +1 -1
- package/dist/utils/createSynapse/factory.d.ts +6 -0
- package/dist/utils/createSynapse/factory.js +256 -0
- package/dist/utils/createSynapse/factory.js.map +1 -0
- package/dist/utils/createSynapse/index.d.ts +2 -2
- package/dist/utils/createSynapse/index.js.map +1 -1
- package/dist/utils/createSynapse/synapse.types.d.ts +87 -0
- package/dist/utils/createSynapse/synapse.types.js +11 -0
- package/dist/utils/createSynapse/synapse.types.js.map +1 -0
- package/dist/utils/createSynapse/types.d.ts +6 -85
- package/dist/utils/createSynapse/types.js +2 -1
- package/dist/utils/createSynapse/types.js.map +1 -1
- package/dist/utils/createSynapse/waitForDependencies.d.ts +0 -1
- package/dist/utils/createSynapse/waitForDependencies.js +1 -1
- package/dist/utils/createSynapse/waitForDependencies.js.map +1 -1
- package/dist/utils/createSynapseAwaiter.d.ts +13 -10
- package/dist/utils/createSynapseAwaiter.js +30 -3
- package/dist/utils/createSynapseAwaiter.js.map +1 -1
- package/dist/utils/dehydrateModule.d.ts +6 -0
- package/dist/utils/dehydrateModule.js +43 -0
- package/dist/utils/dehydrateModule.js.map +1 -0
- package/dist/utils/index.d.ts +3 -3
- package/dist/utils/index.js +3 -0
- package/dist/utils/index.js.map +1 -1
- package/package.json +12 -2
- package/dist/_utils/chunk.util.d.ts.map +0 -1
- package/dist/_utils/deepMerge.util.d.ts.map +0 -1
- package/dist/_utils/error-handling.util.d.ts.map +0 -1
- package/dist/_utils/flatMap.util.d.ts.map +0 -1
- package/dist/_utils/index.d.ts.map +0 -1
- package/dist/_utils/logger-console.util.d.ts.map +0 -1
- package/dist/api/api.module.d.ts.map +0 -1
- package/dist/api/components/endpoint.d.ts.map +0 -1
- package/dist/api/components/query-storage.d.ts.map +0 -1
- package/dist/api/example.d.ts +0 -83
- package/dist/api/example.d.ts.map +0 -1
- package/dist/api/example.js +0 -90
- package/dist/api/example.js.map +0 -1
- package/dist/api/index.d.ts.map +0 -1
- package/dist/api/types/api.interface.d.ts.map +0 -1
- package/dist/api/types/endpoint.interface.d.ts.map +0 -1
- package/dist/api/types/query.interface.d.ts.map +0 -1
- package/dist/api/utils/api-helpers.d.ts.map +0 -1
- package/dist/api/utils/create-header-context.d.ts.map +0 -1
- package/dist/api/utils/endpoint-headers.d.ts.map +0 -1
- package/dist/api/utils/fetch-base-query.d.ts.map +0 -1
- package/dist/api/utils/file-utils.d.ts.map +0 -1
- package/dist/api/utils/get-cacheable-headers.d.ts.map +0 -1
- package/dist/core/index.d.ts.map +0 -1
- package/dist/core/selector/index.d.ts.map +0 -1
- package/dist/core/selector/selector.interface.d.ts.map +0 -1
- package/dist/core/selector/selector.module.d.ts.map +0 -1
- package/dist/core/storage/adapters/async-base-storage.service.d.ts.map +0 -1
- package/dist/core/storage/adapters/indexed-DB.service.d.ts.map +0 -1
- package/dist/core/storage/adapters/local-storage.service.d.ts.map +0 -1
- package/dist/core/storage/adapters/memory-storage.service.d.ts.map +0 -1
- package/dist/core/storage/adapters/path.utils.d.ts.map +0 -1
- package/dist/core/storage/adapters/storage-core.d.ts.map +0 -1
- package/dist/core/storage/adapters/sync-base-storage.service.d.ts.map +0 -1
- package/dist/core/storage/index.d.ts.map +0 -1
- package/dist/core/storage/middlewares/broadcast.middleware.d.ts.map +0 -1
- package/dist/core/storage/middlewares/index.d.ts.map +0 -1
- package/dist/core/storage/middlewares/storage-batching.middleware.d.ts.map +0 -1
- package/dist/core/storage/middlewares/storage-shallow-compare.middleware.d.ts.map +0 -1
- package/dist/core/storage/middlewares/sync-broadcast.middleware.d.ts.map +0 -1
- package/dist/core/storage/middlewares/sync-storage-batching.middleware.d.ts.map +0 -1
- package/dist/core/storage/middlewares/sync-storage-shallow-compare.middleware.d.ts.map +0 -1
- package/dist/core/storage/modules/plugin/plugin.interface.d.ts +0 -101
- package/dist/core/storage/modules/plugin/plugin.interface.d.ts.map +0 -1
- package/dist/core/storage/modules/plugin/plugin.interface.js +0 -8
- package/dist/core/storage/modules/plugin/plugin.interface.js.map +0 -1
- package/dist/core/storage/modules/plugin/plugin.service.d.ts +0 -49
- package/dist/core/storage/modules/plugin/plugin.service.d.ts.map +0 -1
- package/dist/core/storage/modules/plugin/plugin.service.js +0 -406
- package/dist/core/storage/modules/plugin/plugin.service.js.map +0 -1
- package/dist/core/storage/modules/singleton/mixin.util.d.ts.map +0 -1
- package/dist/core/storage/modules/singleton/models.d.ts.map +0 -1
- package/dist/core/storage/modules/singleton/singleton.util.d.ts.map +0 -1
- package/dist/core/storage/storage.interface.d.ts.map +0 -1
- package/dist/core/storage/utils/broadcast.util.d.ts.map +0 -1
- package/dist/core/storage/utils/cache.util.d.ts.map +0 -1
- package/dist/core/storage/utils/cache.util.js.map +0 -1
- package/dist/core/storage/utils/middleware-module.d.ts.map +0 -1
- package/dist/core/storage/utils/path-selector.util.d.ts.map +0 -1
- package/dist/core/storage/utils/state-diff.util.d.ts.map +0 -1
- package/dist/core/storage/utils/storage-factory.util.d.ts.map +0 -1
- package/dist/core/storage/utils/storage-key.d.ts.map +0 -1
- package/dist/core/storage/utils/storage.utils.d.ts +0 -17
- package/dist/core/storage/utils/storage.utils.d.ts.map +0 -1
- package/dist/core/storage/utils/storage.utils.js +0 -57
- package/dist/core/storage/utils/storage.utils.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/react/hooks/index.d.ts.map +0 -1
- package/dist/react/hooks/useCreateStorage.d.ts.map +0 -1
- package/dist/react/hooks/useSelector.d.ts.map +0 -1
- package/dist/react/hooks/useStorage.d.ts.map +0 -1
- package/dist/react/hooks/useStorageSubscribe.d.ts.map +0 -1
- package/dist/react/index.d.ts.map +0 -1
- package/dist/react/utils/awaitSynapse.d.ts.map +0 -1
- package/dist/react/utils/createSynapseCtx.d.ts.map +0 -1
- package/dist/react/utils/index.d.ts.map +0 -1
- package/dist/reactive/dispatcher/dispatcher.module.d.ts.map +0 -1
- package/dist/reactive/dispatcher/index.d.ts.map +0 -1
- package/dist/reactive/dispatcher/middlewares/index.d.ts.map +0 -1
- package/dist/reactive/dispatcher/middlewares/logger.middleware.d.ts.map +0 -1
- package/dist/reactive/dispatcher/standalone.d.ts.map +0 -1
- package/dist/reactive/effects/effects.module.d.ts.map +0 -1
- package/dist/reactive/effects/index.d.ts.map +0 -1
- package/dist/reactive/effects/utils/chunkRequestConsistent.d.ts.map +0 -1
- package/dist/reactive/effects/utils/chunkRequestParallel.d.ts.map +0 -1
- package/dist/reactive/effects/utils/fromRequest.d.ts.map +0 -1
- package/dist/reactive/effects/utils/index.d.ts.map +0 -1
- package/dist/reactive/effects/utils/toObservable.d.ts.map +0 -1
- package/dist/reactive/index.d.ts.map +0 -1
- package/dist/utils/createEventBus.d.ts.map +0 -1
- package/dist/utils/createSynapse/createSynapse.d.ts.map +0 -1
- package/dist/utils/createSynapse/index.d.ts.map +0 -1
- package/dist/utils/createSynapse/types.d.ts.map +0 -1
- package/dist/utils/createSynapse/validate.d.ts +0 -2
- package/dist/utils/createSynapse/validate.d.ts.map +0 -1
- package/dist/utils/createSynapse/validate.js +0 -76
- package/dist/utils/createSynapse/validate.js.map +0 -1
- package/dist/utils/createSynapse/waitForDependencies.d.ts.map +0 -1
- package/dist/utils/createSynapseAwaiter.d.ts.map +0 -1
- package/dist/utils/index.d.ts.map +0 -1
|
@@ -6,8 +6,15 @@ import { handleCallbackError } from "../../_utils/error-handling.util.js";
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
|
-
*
|
|
10
|
-
|
|
9
|
+
* Внутренний движок диспетчера для интеграции хранилищ с реактивной системой.
|
|
10
|
+
*
|
|
11
|
+
* Прежнее имя — `Dispatcher`. Переименован в `DispatcherCore`, поскольку публичным
|
|
12
|
+
* `Dispatcher` теперь является abstract class-based слой (`dispatcher.base.ts`),
|
|
13
|
+
* который строится поверх этого движка.
|
|
14
|
+
*
|
|
15
|
+
* `TActionsFn` — фантомный слот для вывода форм экшенов (`ActionsResult`); сам движок
|
|
16
|
+
* его не использует в рантайме.
|
|
17
|
+
*/ class DispatcherCore {
|
|
11
18
|
// Поток действий
|
|
12
19
|
actions$ = new Subject();
|
|
13
20
|
// Публичный Observable для действий
|
|
@@ -108,16 +115,6 @@ import { handleCallbackError } from "../../_utils/error-handling.util.js";
|
|
|
108
115
|
return this.dispatch;
|
|
109
116
|
}
|
|
110
117
|
/**
|
|
111
|
-
* Получает типизированные действия диспетчера
|
|
112
|
-
*/ getTypedDispatch() {
|
|
113
|
-
return this.dispatch;
|
|
114
|
-
}
|
|
115
|
-
/**
|
|
116
|
-
* Получает типизированные watcher'ы
|
|
117
|
-
*/ getTypedWatchers() {
|
|
118
|
-
return this.watchers;
|
|
119
|
-
}
|
|
120
|
-
/**
|
|
121
118
|
* Находит действие по типу
|
|
122
119
|
*/ findActionByType(actionType) {
|
|
123
120
|
return Object.values(this.dispatch).find((action)=>{
|
|
@@ -160,7 +157,7 @@ import { handleCallbackError } from "../../_utils/error-handling.util.js";
|
|
|
160
157
|
// Создаем функцию диспетчеризации
|
|
161
158
|
const dispatchFn = async (params)=>{
|
|
162
159
|
if (!actionType) {
|
|
163
|
-
throw new Error('Action type not assigned. Provide "type" in config or
|
|
160
|
+
throw new Error('Action type not assigned. Provide "type" in config or declare the action as a field of a Dispatcher subclass.');
|
|
164
161
|
}
|
|
165
162
|
// Проверяем мемоизацию
|
|
166
163
|
if (executionOptions?.memoize && hasCached) {
|
|
@@ -199,7 +196,7 @@ import { handleCallbackError } from "../../_utils/error-handling.util.js";
|
|
|
199
196
|
enumerable: true
|
|
200
197
|
});
|
|
201
198
|
}
|
|
202
|
-
// Deferred type assignment — используется
|
|
199
|
+
// Deferred type assignment — используется при финализации Dispatcher для авто-генерации типа из имени поля
|
|
203
200
|
if (!hasExplicitType) {
|
|
204
201
|
;
|
|
205
202
|
dispatchFn._assignType = (name)=>{
|
|
@@ -305,7 +302,7 @@ import { handleCallbackError } from "../../_utils/error-handling.util.js";
|
|
|
305
302
|
writable: false,
|
|
306
303
|
enumerable: true
|
|
307
304
|
});
|
|
308
|
-
// Deferred type assignment — используется
|
|
305
|
+
// Deferred type assignment — используется при финализации Dispatcher для авто-генерации типа из имени поля
|
|
309
306
|
if (!hasExplicitType) {
|
|
310
307
|
;
|
|
311
308
|
watcherFn._assignType = (name)=>{
|
|
@@ -322,63 +319,7 @@ import { handleCallbackError } from "../../_utils/error-handling.util.js";
|
|
|
322
319
|
return watcherFn;
|
|
323
320
|
}
|
|
324
321
|
}
|
|
325
|
-
// Implementation
|
|
326
|
-
function createDispatcher(options, actionsOrSetup) {
|
|
327
|
-
// Создаем экземпляр диспетчера
|
|
328
|
-
const dispatcher = new Dispatcher(options);
|
|
329
|
-
// Получаем объект действий: из функции или напрямую
|
|
330
|
-
const actions = typeof actionsOrSetup === 'function' ? actionsOrSetup(options.storage, {
|
|
331
|
-
createAction: (actionConfig, executionOptions)=>dispatcher.createAction(actionConfig, executionOptions),
|
|
332
|
-
createWatcher: (config)=>dispatcher.createWatcher(config)
|
|
333
|
-
}) : actionsOrSetup;
|
|
334
|
-
// Регистрируем все созданные объекты в соответствующих коллекциях
|
|
335
|
-
for (const [key, fn] of Object.entries(actions)){
|
|
336
|
-
// Standalone action recipe — привязываем к storage и создаём реальный action
|
|
337
|
-
if (typeof fn === 'object' && fn !== null && fn._type === 'action-recipe') {
|
|
338
|
-
const recipe = fn;
|
|
339
|
-
const boundConfig = {
|
|
340
|
-
meta: recipe._config.meta,
|
|
341
|
-
action: (params)=>recipe._config.action(options.storage, params)
|
|
342
|
-
};
|
|
343
|
-
const dispatchFn = dispatcher.createAction(boundConfig, recipe._executionOptions);
|
|
344
|
-
if (typeof dispatchFn._assignType === 'function') {
|
|
345
|
-
;
|
|
346
|
-
dispatchFn._assignType(key);
|
|
347
|
-
delete dispatchFn._assignType;
|
|
348
|
-
}
|
|
349
|
-
dispatcher.dispatch[key] = dispatchFn;
|
|
350
|
-
continue;
|
|
351
|
-
}
|
|
352
|
-
// Standalone watcher recipe — привязываем к storage и создаём реальный watcher
|
|
353
|
-
if (typeof fn === 'object' && fn !== null && fn._type === 'watcher-recipe') {
|
|
354
|
-
const recipe = fn;
|
|
355
|
-
const watcherFn = dispatcher.createWatcher(recipe._config);
|
|
356
|
-
if (typeof watcherFn._assignType === 'function') {
|
|
357
|
-
;
|
|
358
|
-
watcherFn._assignType(key);
|
|
359
|
-
delete watcherFn._assignType;
|
|
360
|
-
}
|
|
361
|
-
dispatcher.watchers[key] = watcherFn;
|
|
362
|
-
continue;
|
|
363
|
-
}
|
|
364
|
-
// Inline action/watcher (существующая логика)
|
|
365
|
-
if (typeof fn === 'function') {
|
|
366
|
-
const type = fn._type;
|
|
367
|
-
if (type === 'dispatch' || type === 'watchers') {
|
|
368
|
-
// Авто-назначение типа из имени ключа, если type не был указан явно
|
|
369
|
-
if (typeof fn._assignType === 'function') {
|
|
370
|
-
;
|
|
371
|
-
fn._assignType(key);
|
|
372
|
-
delete fn._assignType;
|
|
373
|
-
}
|
|
374
|
-
// @ts-ignore
|
|
375
|
-
dispatcher[type][key] = fn;
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
return dispatcher;
|
|
380
|
-
}
|
|
381
322
|
|
|
382
|
-
export {
|
|
323
|
+
export { DispatcherCore };
|
|
383
324
|
|
|
384
325
|
//# sourceMappingURL=dispatcher.module.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reactive/dispatcher/dispatcher.module.js","sources":["../../../src/reactive/dispatcher/dispatcher.module.ts"],"sourcesContent":["import { Observable, share, Subject } from 'rxjs'\n\nimport { handleCallbackError } from '../../_utils/error-handling.util'\nimport type { IStorage } from '../../core'\nimport { TypedAction } from '../effects'\nimport type { ActionExecutionOptions, ActionRecipe, WatcherRecipe } from './standalone'\n\n/**\n * Расширенное API для middleware\n */\nexport interface EnhancedMiddlewareAPI<T extends Record<string, any>> {\n // Базовые возможности\n getState: () => T | Promise<T>\n dispatch: (action: Action) => Promise<any>\n\n // Доступ к хранилищу напрямую\n storage: IStorage<T>\n\n // Доступ к потоку действий\n actions$: Observable<Action>\n\n // Доступ к зарегистрированным действиям\n actions: Record<string, DispatchFunction<any, any>>\n\n // Доступ к зарегистрированным наблюдателям\n watchers: Record<string, WatcherFunction<any>>\n\n // Вспомогательные методы\n findActionByType: (actionType: string) => DispatchFunction<any, any> | undefined\n findWatcherByType: (actionType: string) => WatcherFunction<any> | undefined\n}\n\n/**\n * Расширенное определение middleware\n */\nexport interface EnhancedMiddleware<T extends Record<string, any> = any> {\n (api: EnhancedMiddlewareAPI<T>): (next: (action: Action) => Promise<any>) => (action: Action) => Promise<any>\n}\n\n/**\n * Базовая структура действия\n */\nexport interface Action<T = unknown> {\n type: string\n payload?: T\n meta?: Record<string, any>\n}\n\n// ActionExecutionOptions импортирован из ./standalone\n\n/**\n * Параметры для создания действия\n */\nexport interface ActionDefinition<TParams, TResult> {\n /** Тип действия для идентификации в потоке и эффектах. Если не указан — будет выведен из имени ключа в createDispatcher */\n type?: string\n /** Функция, выполняющая действие и возвращающая результат (payload) */\n action: (params: TParams) => Promise<TResult> | TResult\n /** Дополнительные метаданные (опционально) */\n meta?: Record<string, any>\n}\n\n/**\n * Определение типа для watcher'а\n */\ninterface WatcherDefinition<T, R> {\n /** Тип watcher'а для идентификации в потоке. Если не указан — будет выведен из имени ключа в createDispatcher */\n type?: string\n selector: (state: T) => R\n meta?: Record<string, any>\n // Опционально - функция для определения, изменилось ли значение\n shouldTrigger?: (prev: R | undefined, current: R) => boolean\n // Эмитить текущее значение при подписке\n notifyAfterSubscribe?: boolean\n}\n\n/**\n * Тип для функции watcher\n */\nexport interface WatcherFunction<R> {\n (): Observable<TypedAction<R>>\n actionType: string\n meta?: Record<string, any>\n unsubscribe: VoidFunction\n}\n\n/**\n * Расширенный тип для функции настройки действий с поддержкой дополнительных утилит\n */\nexport type ActionsSetupWithUtils<T extends Record<string, any>> = (\n storage: IStorage<T>,\n utils: {\n createAction: ActionCreatorFactory\n createWatcher: <R>(config: WatcherDefinition<T, R>) => WatcherFunction<R>\n },\n) => Record<string, DispatchFunction<any, any> | WatcherFunction<any> | ActionRecipe<T, any, any> | WatcherRecipe<T, any>>\n\n/**\n * Расширенная функция диспетчеризации\n */\nexport interface DispatchFunction<TParams, TResult> {\n /** Функция для вызова действия с параметрами */\n (params: TParams): Promise<TResult>\n /** Тип действия для использования в эффектах */\n actionType: string\n /** Метаданные действия */\n meta?: Record<string, any>\n /** Внутренний тип для идентификации */\n _type?: 'dispatch' | 'watchers'\n}\n\n/**\n * Тип для фабрики создателей действий\n */\ntype ActionCreatorFactory = <TParams = void, TResult = void>(\n config: ActionDefinition<TParams, TResult>,\n executionOptions?: ActionExecutionOptions<TParams, TResult>,\n) => DispatchFunction<TParams, TResult>\n\n/**\n * Извлекает тип результата из функции диспетчера\n */\nexport type ExtractResultType<T> = T extends DispatchFunction<any, infer R> ? R : never\n\n/**\n * Извлекает типы из функции настройки действий\n */\nexport type ActionsResult<F> = F extends (create: ActionCreatorFactory, storage: any, ...args: any[]) => infer R ? R : Record<string, DispatchFunction<any, any>>\n\n/**\n * Типизированный объект действий\n */\ntype ResolveDispatch<T> = T extends DispatchFunction<any, any> ? T : T extends ActionRecipe<any, infer P, infer R> ? DispatchFunction<P, R> : never\n\nexport type DispatchActions<T> = {\n [K in keyof T]: ResolveDispatch<T[K]>\n}\n\n/**\n * Типизированный объект watchers\n */\ntype ResolveWatcher<T> = T extends WatcherFunction<any> ? T : T extends WatcherRecipe<any, infer R> ? WatcherFunction<R> : never\n\nexport type WatcherActions<T> = {\n [K in keyof T]: ResolveWatcher<T[K]>\n}\n\n/**\n * Параметры для Dispatcher\n */\ninterface DispatcherOptions<T extends Record<string, any>> {\n // Хранилище - обязательный параметр\n storage: IStorage<T>\n // DispatcherMiddleware для обработки действий\n middlewares?: EnhancedMiddleware<T>[]\n}\n\n/**\n * Класс Dispatcher для интеграции хранилищ с реактивной системой\n */\nexport class Dispatcher<T extends Record<string, any>, TActionsFn extends ActionsSetupWithUtils<T> = ActionsSetupWithUtils<T>> {\n // Поток действий\n private actions$ = new Subject<Action>()\n\n // Публичный Observable для действий\n public readonly actions: Observable<Action> = this.actions$.asObservable()\n\n // Методы диспетчеризации действий с типизацией\n public dispatch: Record<string, DispatchFunction<any, any>> = {}\n\n // Watcher'ы для реактивной подписки на изменения\n public watchers: Record<string, WatcherFunction<any>> = {}\n\n // Ссылка на хранилище\n private storage: IStorage<T>\n\n // Только один массив для хранения инициализированных middleware\n private middlewareFunctions: Array<(next: (action: Action) => Promise<any>) => (action: Action) => Promise<any>> = []\n\n // Pre-built middleware chain (null if no middlewares)\n private dispatchChain: ((action: Action) => Promise<any>) | null = null\n\n // Registry of action executors by action type\n private actionRegistry = new Map<string, { action: (params: any) => Promise<any> | any }>()\n\n // Temporary storage for passing params through middleware chain without polluting action object\n private actionParams = new WeakMap<object, any>()\n\n // API для инициализации middleware\n private middlewareAPI: EnhancedMiddlewareAPI<T>\n\n /**\n * Создает новый экземпляр Dispatcher\n */\n constructor(options: DispatcherOptions<T>) {\n this.storage = options.storage\n\n // Создаем API для middleware сразу\n this.middlewareAPI = {\n getState: () => this.storage.getState(),\n dispatch: (action: Action) => this.executeChain(action),\n storage: this.storage,\n actions$: this.actions,\n actions: this.dispatch,\n watchers: this.watchers,\n findActionByType: (type) => this.findActionByType(type),\n findWatcherByType: (type) => this.findWatcherByType(type),\n }\n\n // Если есть middleware в options, добавляем их\n if (options.middlewares && options.middlewares.length > 0) {\n this.use(...options.middlewares)\n }\n }\n\n /**\n * Добавляет middleware в цепочку обработки\n */\n public use(...middlewares: EnhancedMiddleware<T>[]): this {\n // Инициализируем каждый middleware и добавляем только инициализированную версию\n for (let i = 0; i < middlewares.length; i++) {\n try {\n // Инициализируем middleware с API\n const initializedMiddleware = middlewares[i](this.middlewareAPI)\n this.middlewareFunctions.push(initializedMiddleware)\n } catch (error) {\n handleCallbackError(`Dispatcher: error initializing middleware [${i}]`, error)\n }\n }\n this.rebuildChain()\n return this\n }\n\n /**\n * Base executor: runs the registered action handler or passes through\n */\n private baseExecute = async (action: Action): Promise<any> => {\n // No params in WeakMap means this is a pass-through dispatch (via api.dispatch)\n if (!this.actionParams.has(action)) {\n return action.payload\n }\n\n const entry = this.actionRegistry.get(action.type)\n if (!entry) {\n return action.payload\n }\n\n const params = this.actionParams.get(action)\n return Promise.resolve(entry.action(params))\n }\n\n /**\n * Executes action through middleware chain and emits to actions$ (single emission point)\n */\n private async executeChain(action: Action): Promise<any> {\n const executor = this.dispatchChain ?? this.baseExecute\n const result = await executor(action)\n\n // Single emission point for all dispatches\n action.payload = result\n this.actionParams.delete(action)\n this.actions$.next(action)\n\n return result\n }\n\n /**\n * Rebuilds the pre-composed middleware chain. Called once on use(), not on every dispatch.\n */\n private rebuildChain(): void {\n if (this.middlewareFunctions.length === 0) {\n this.dispatchChain = null\n return\n }\n\n let chain = this.baseExecute as (action: Action) => Promise<any>\n for (let i = this.middlewareFunctions.length - 1; i >= 0; i--) {\n chain = this.middlewareFunctions[i](chain)\n }\n this.dispatchChain = chain\n }\n\n /**\n * Получает все действия с улучшенной типизацией\n */\n public getActions(): ActionsResult<TActionsFn> {\n return this.dispatch as ActionsResult<TActionsFn>\n }\n\n /**\n * Получает типизированные действия диспетчера\n */\n public getTypedDispatch<A extends Record<string, any>>(): DispatchActions<A> {\n return this.dispatch as DispatchActions<A>\n }\n\n /**\n * Получает типизированные watcher'ы\n */\n public getTypedWatchers<A extends Record<string, any>>(): WatcherActions<A> {\n return this.watchers as WatcherActions<A>\n }\n\n /**\n * Находит действие по типу\n */\n public findActionByType(actionType: string): DispatchFunction<any, any> | undefined {\n return Object.values(this.dispatch).find((action) => {\n return action.actionType.split(`[${this.storage.name}]`)[1] === actionType\n })\n }\n\n /**\n * Находит наблюдатель по типу\n */\n public findWatcherByType(actionType: string): WatcherFunction<any> | undefined {\n return Object.values(this.watchers).find((watcher) => {\n return watcher.actionType.split(`[${this.storage.name}]`)[1] === actionType\n })\n }\n\n /**\n * Уничтожает dispatcher: отписывает watchers, завершает поток действий, очищает состояние\n */\n public destroy(): void {\n Object.values(this.watchers).forEach((w) => w.unsubscribe())\n this.actions$.complete()\n this.dispatch = {}\n this.watchers = {}\n this.middlewareFunctions = []\n this.dispatchChain = null\n this.actionRegistry.clear()\n }\n\n /**\n * Создает действие\n */\n public createAction<TParams = void, TResult = void>(\n actionConfig: ActionDefinition<TParams, TResult>,\n executionOptions?: ActionExecutionOptions<TParams, TResult>,\n ): DispatchFunction<TParams, TResult> {\n const hasExplicitType = !!actionConfig.type\n let actionType = hasExplicitType ? `[${this.storage.name}]${actionConfig.type}` : ''\n\n // Register action executor in the registry (сразу, если тип известен)\n if (hasExplicitType) {\n this.actionRegistry.set(actionType, { action: actionConfig.action })\n }\n\n // Для мемоизации храним последние аргументы и результат\n let lastParams: TParams | undefined\n let lastResult: TResult | undefined\n let hasCached = false\n\n // Создаем функцию диспетчеризации\n const dispatchFn = async (params: TParams): Promise<TResult> => {\n if (!actionType) {\n throw new Error('Action type not assigned. Provide \"type\" in config or use within createDispatcher.')\n }\n\n // Проверяем мемоизацию\n if (executionOptions?.memoize && hasCached) {\n if (executionOptions.memoize(params, lastParams!, lastResult!)) {\n return lastResult!\n }\n }\n\n // Создаем объект действия\n const actionObject: Action<TResult> = {\n type: actionType,\n meta: actionConfig.meta,\n }\n\n // Store params for base executor to retrieve via WeakMap\n this.actionParams.set(actionObject, params)\n\n // Execute through middleware chain (includes single emission to actions$)\n const result = (await this.executeChain(actionObject)) as TResult\n\n // Сохраняем аргументы и результат для мемоизации\n lastParams = params\n lastResult = result\n hasCached = true\n\n return result\n }\n\n dispatchFn._type = 'dispatch'\n // Добавляем тип действия как свойство функции (configurable для deferred assignment)\n Object.defineProperty(dispatchFn, 'actionType', {\n value: actionType,\n writable: false,\n enumerable: true,\n configurable: true,\n })\n\n // Добавляем метаданные, если они есть\n if (actionConfig.meta) {\n Object.defineProperty(dispatchFn, 'meta', {\n value: actionConfig.meta,\n writable: false,\n enumerable: true,\n })\n }\n\n // Deferred type assignment — используется в createDispatcher для авто-генерации типа из имени ключа\n if (!hasExplicitType) {\n ;(dispatchFn as any)._assignType = (name: string) => {\n actionType = `[${this.storage.name}]${name}`\n\n this.actionRegistry.set(actionType, { action: actionConfig.action })\n\n Object.defineProperty(dispatchFn, 'actionType', {\n value: actionType,\n writable: false,\n enumerable: true,\n configurable: true,\n })\n }\n }\n\n return dispatchFn as DispatchFunction<TParams, TResult>\n }\n /**\n * Создает watcher для отслеживания изменений в хранилище\n */\n public createWatcher<R>(config: WatcherDefinition<T, R>): WatcherFunction<R> {\n const hasExplicitType = !!config.type\n let actionType = hasExplicitType ? `[${this.storage.name}]${config.type}` : ''\n\n // Lazy-подписка: подписываемся на storage только при первом subscribe на Observable\n let storageUnsubscribe: VoidFunction | null = null\n\n const sharedObservable = new Observable<TypedAction<R>>((subscriber) => {\n // Инициализируем prevValue текущим значением при первой подписке\n let prevValue: R | undefined\n let disposed = false\n\n const initAndSubscribe = async () => {\n try {\n const currentState = await Promise.resolve(this.storage.getState())\n prevValue = config.selector(currentState)\n } catch {\n // Если не удалось получить начальное значение — продолжаем с undefined\n }\n\n if (disposed) return\n\n // Если нужно уведомить о текущем значении при подписке\n if (config.notifyAfterSubscribe && prevValue !== undefined) {\n if (!config.shouldTrigger || config.shouldTrigger(undefined, prevValue)) {\n const initialAction: TypedAction<R> = {\n type: actionType,\n payload: prevValue,\n meta: {\n ...config.meta,\n isInitial: true,\n },\n }\n this.actions$.next(initialAction)\n subscriber.next(initialAction)\n }\n }\n\n // Подписываемся на изменения storage\n storageUnsubscribe = this.storage.subscribe(config.selector, (value: R) => {\n if (!config.shouldTrigger || config.shouldTrigger(prevValue, value)) {\n const action: TypedAction<R> = {\n type: actionType,\n payload: value,\n meta: config.meta,\n }\n\n this.actions$.next(action)\n subscriber.next(action)\n\n prevValue = value\n }\n })\n\n // Если отписались пока шла асинхронная инициализация — сразу очищаем\n if (disposed) {\n storageUnsubscribe()\n storageUnsubscribe = null\n }\n }\n\n initAndSubscribe()\n\n return () => {\n disposed = true\n if (storageUnsubscribe) {\n storageUnsubscribe()\n storageUnsubscribe = null\n }\n }\n }).pipe(share())\n\n // Создаем функцию watcher'а\n const watcherFn = () => sharedObservable\n\n watcherFn._type = 'watchers'\n\n Object.defineProperty(watcherFn, 'actionType', {\n value: actionType,\n writable: false,\n enumerable: true,\n configurable: true,\n })\n\n if (config.meta) {\n Object.defineProperty(watcherFn, 'meta', {\n value: config.meta,\n writable: false,\n enumerable: true,\n })\n }\n\n Object.defineProperty(watcherFn, 'unsubscribe', {\n value: () => {\n if (storageUnsubscribe) {\n storageUnsubscribe()\n storageUnsubscribe = null\n }\n },\n writable: false,\n enumerable: true,\n })\n\n // Deferred type assignment — используется в createDispatcher для авто-генерации типа из имени ключа\n if (!hasExplicitType) {\n ;(watcherFn as any)._assignType = (name: string) => {\n actionType = `[${this.storage.name}]${name}`\n\n Object.defineProperty(watcherFn, 'actionType', {\n value: actionType,\n writable: false,\n enumerable: true,\n configurable: true,\n })\n }\n }\n\n //@ts-ignore\n return watcherFn as WatcherFunction<R>\n }\n}\n\n/**\n * Функция для создания типизированного диспетчера.\n *\n * Поддерживает два варианта:\n * 1. Объект standalone-рецептов (ActionRecipe / WatcherRecipe)\n * 2. Setup-функция с доступом к createAction / createWatcher (inline-определение)\n *\n * @example\n * ```ts\n * // Вариант 1: объект рецептов (рекомендуемый)\n * createDispatcher({ storage }, {\n * loadList,\n * loadListLoading: listRequest.loading,\n * watchCount,\n * })\n *\n * // Вариант 2: setup-функция (для смешанного использования)\n * createDispatcher({ storage }, (storage, { createAction }) => ({\n * loadList,\n * custom: createAction({ action: () => { ... } }),\n * }))\n * ```\n */\n\n// Overload: объект standalone-рецептов\nexport function createDispatcher<TState extends Record<string, any>, TRecord extends Record<string, ActionRecipe<TState, any, any> | WatcherRecipe<TState, any>>>(\n options: DispatcherOptions<TState>,\n actions: TRecord,\n): Dispatcher<TState> & {\n dispatch: DispatchActions<TRecord>\n watchers: WatcherActions<TRecord>\n}\n\n// Overload: setup-функция\nexport function createDispatcher<TState extends Record<string, any>, TActions extends ActionsSetupWithUtils<TState>>(\n options: DispatcherOptions<TState>,\n actionsSetup: TActions,\n): Dispatcher<TState, TActions> & {\n dispatch: DispatchActions<ReturnType<TActions>>\n watchers: WatcherActions<ReturnType<TActions>>\n}\n\n// Implementation\nexport function createDispatcher<TState extends Record<string, any>>(options: DispatcherOptions<TState>, actionsOrSetup: Record<string, any> | ((...args: any[]) => any)) {\n // Создаем экземпляр диспетчера\n const dispatcher = new Dispatcher<TState>(options)\n\n // Получаем объект действий: из функции или напрямую\n const actions =\n typeof actionsOrSetup === 'function'\n ? actionsOrSetup(options.storage, {\n createAction: (actionConfig: any, executionOptions: any) => dispatcher.createAction(actionConfig, executionOptions),\n createWatcher: (config: any) => dispatcher.createWatcher(config),\n })\n : actionsOrSetup\n\n // Регистрируем все созданные объекты в соответствующих коллекциях\n for (const [key, fn] of Object.entries(actions)) {\n // Standalone action recipe — привязываем к storage и создаём реальный action\n if (typeof fn === 'object' && fn !== null && (fn as any)._type === 'action-recipe') {\n const recipe = fn as ActionRecipe<TState, any, any>\n const boundConfig = {\n meta: recipe._config.meta,\n action: (params: any) => recipe._config.action(options.storage, params),\n }\n const dispatchFn = dispatcher.createAction(boundConfig, recipe._executionOptions)\n if (typeof (dispatchFn as any)._assignType === 'function') {\n ;(dispatchFn as any)._assignType(key)\n delete (dispatchFn as any)._assignType\n }\n dispatcher.dispatch[key] = dispatchFn\n continue\n }\n\n // Standalone watcher recipe — привязываем к storage и создаём реальный watcher\n if (typeof fn === 'object' && fn !== null && (fn as any)._type === 'watcher-recipe') {\n const recipe = fn as WatcherRecipe<TState, any>\n const watcherFn = dispatcher.createWatcher(recipe._config)\n if (typeof (watcherFn as any)._assignType === 'function') {\n ;(watcherFn as any)._assignType(key)\n delete (watcherFn as any)._assignType\n }\n dispatcher.watchers[key] = watcherFn\n continue\n }\n\n // Inline action/watcher (существующая логика)\n if (typeof fn === 'function') {\n const type = (fn as any)._type\n if (type === 'dispatch' || type === 'watchers') {\n // Авто-назначение типа из имени ключа, если type не был указан явно\n if (typeof (fn as any)._assignType === 'function') {\n ;(fn as any)._assignType(key)\n delete (fn as any)._assignType\n }\n // @ts-ignore\n dispatcher[type][key] = fn\n }\n }\n }\n\n return dispatcher\n}\nexport type CreateDispatcherType = ReturnType<typeof createDispatcher>\n"],"names":["Observable","share","Subject","handleCallbackError","Dispatcher","Map","WeakMap","options","action","type","middlewares","i","initializedMiddleware","error","entry","params","Promise","executor","result","chain","actionType","Object","watcher","w","actionConfig","executionOptions","hasExplicitType","lastParams","lastResult","hasCached","dispatchFn","Error","actionObject","name","config","storageUnsubscribe","sharedObservable","subscriber","prevValue","disposed","initAndSubscribe","currentState","undefined","initialAction","value","watcherFn","createDispatcher","actionsOrSetup","dispatcher","actions","key","fn","recipe","boundConfig"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"reactive/dispatcher/dispatcher.module.js","sources":["../../../src/reactive/dispatcher/dispatcher.module.ts"],"sourcesContent":["import { Observable, share, Subject } from 'rxjs'\n\nimport { handleCallbackError } from '../../_utils/error-handling.util'\nimport type { IStorage } from '../../core'\nimport { TypedAction } from '../effects'\nimport type { ActionExecutionOptions } from './standalone'\n\n/**\n * Расширенное API для middleware\n */\nexport interface EnhancedMiddlewareAPI<T extends Record<string, any>> {\n // Базовые возможности\n getState: () => T | Promise<T>\n dispatch: (action: Action) => Promise<any>\n\n // Доступ к хранилищу напрямую\n storage: IStorage<T>\n\n // Доступ к потоку действий\n actions$: Observable<Action>\n\n // Доступ к зарегистрированным действиям\n actions: Record<string, DispatchFunction<any, any>>\n\n // Доступ к зарегистрированным наблюдателям\n watchers: Record<string, WatcherFunction<any>>\n\n // Вспомогательные методы\n findActionByType: (actionType: string) => DispatchFunction<any, any> | undefined\n findWatcherByType: (actionType: string) => WatcherFunction<any> | undefined\n}\n\n/**\n * Расширенное определение middleware\n */\nexport interface EnhancedMiddleware<T extends Record<string, any> = any> {\n (api: EnhancedMiddlewareAPI<T>): (next: (action: Action) => Promise<any>) => (action: Action) => Promise<any>\n}\n\n/**\n * Базовая структура действия\n */\nexport interface Action<T = unknown> {\n type: string\n payload?: T\n meta?: Record<string, any>\n}\n\n// ActionExecutionOptions импортирован из ./standalone\n\n/**\n * Параметры для создания действия\n */\nexport interface ActionDefinition<TParams, TResult> {\n /** Тип действия для идентификации в потоке и эффектах. Если не указан — будет выведен из имени поля при финализации `Dispatcher`. */\n type?: string\n /** Функция, выполняющая действие и возвращающая результат (payload) */\n action: (params: TParams) => Promise<TResult> | TResult\n /** Дополнительные метаданные (опционально) */\n meta?: Record<string, any>\n}\n\n/**\n * Определение типа для watcher'а\n */\ninterface WatcherDefinition<T, R> {\n /** Тип watcher'а для идентификации в потоке. Если не указан — будет выведен из имени поля при финализации `Dispatcher`. */\n type?: string\n selector: (state: T) => R\n meta?: Record<string, any>\n // Опционально - функция для определения, изменилось ли значение\n shouldTrigger?: (prev: R | undefined, current: R) => boolean\n // Эмитить текущее значение при подписке\n notifyAfterSubscribe?: boolean\n}\n\n/**\n * Тип для функции watcher\n */\nexport interface WatcherFunction<R> {\n (): Observable<TypedAction<R>>\n actionType: string\n meta?: Record<string, any>\n unsubscribe: VoidFunction\n}\n\n/**\n * Расширенная функция диспетчеризации\n */\nexport interface DispatchFunction<TParams, TResult> {\n /** Функция для вызова действия с параметрами */\n (params: TParams): Promise<TResult>\n /** Тип действия для использования в эффектах */\n actionType: string\n /** Метаданные действия */\n meta?: Record<string, any>\n /** Внутренний тип для идентификации */\n _type?: 'dispatch' | 'watchers'\n}\n\n/**\n * Тип для фабрики создателей действий\n */\ntype ActionCreatorFactory = <TParams = void, TResult = void>(\n config: ActionDefinition<TParams, TResult>,\n executionOptions?: ActionExecutionOptions<TParams, TResult>,\n) => DispatchFunction<TParams, TResult>\n\n/**\n * Извлекает тип результата из функции диспетчера\n */\nexport type ExtractResultType<T> = T extends DispatchFunction<any, infer R> ? R : never\n\n/**\n * Извлекает типы из функции настройки действий\n */\nexport type ActionsResult<F> = F extends (create: ActionCreatorFactory, storage: any, ...args: any[]) => infer R ? R : Record<string, DispatchFunction<any, any>>\n\n/**\n * Параметры для Dispatcher\n */\ninterface DispatcherOptions<T extends Record<string, any>> {\n // Хранилище - обязательный параметр\n storage: IStorage<T>\n // DispatcherMiddleware для обработки действий\n middlewares?: EnhancedMiddleware<T>[]\n}\n\n/**\n * Внутренний движок диспетчера для интеграции хранилищ с реактивной системой.\n *\n * Прежнее имя — `Dispatcher`. Переименован в `DispatcherCore`, поскольку публичным\n * `Dispatcher` теперь является abstract class-based слой (`dispatcher.base.ts`),\n * который строится поверх этого движка.\n *\n * `TActionsFn` — фантомный слот для вывода форм экшенов (`ActionsResult`); сам движок\n * его не использует в рантайме.\n */\nexport class DispatcherCore<T extends Record<string, any>, TActionsFn extends (...args: any[]) => any = (...args: any[]) => Record<string, DispatchFunction<any, any>>> {\n // Поток действий\n private actions$ = new Subject<Action>()\n\n // Публичный Observable для действий\n public readonly actions: Observable<Action> = this.actions$.asObservable()\n\n // Методы диспетчеризации действий с типизацией\n public dispatch: Record<string, DispatchFunction<any, any>> = {}\n\n // Watcher'ы для реактивной подписки на изменения\n public watchers: Record<string, WatcherFunction<any>> = {}\n\n // Ссылка на хранилище\n private storage: IStorage<T>\n\n // Только один массив для хранения инициализированных middleware\n private middlewareFunctions: Array<(next: (action: Action) => Promise<any>) => (action: Action) => Promise<any>> = []\n\n // Pre-built middleware chain (null if no middlewares)\n private dispatchChain: ((action: Action) => Promise<any>) | null = null\n\n // Registry of action executors by action type\n private actionRegistry = new Map<string, { action: (params: any) => Promise<any> | any }>()\n\n // Temporary storage for passing params through middleware chain without polluting action object\n private actionParams = new WeakMap<object, any>()\n\n // API для инициализации middleware\n private middlewareAPI: EnhancedMiddlewareAPI<T>\n\n /**\n * Создает новый экземпляр Dispatcher\n */\n constructor(options: DispatcherOptions<T>) {\n this.storage = options.storage\n\n // Создаем API для middleware сразу\n this.middlewareAPI = {\n getState: () => this.storage.getState(),\n dispatch: (action: Action) => this.executeChain(action),\n storage: this.storage,\n actions$: this.actions,\n actions: this.dispatch,\n watchers: this.watchers,\n findActionByType: (type) => this.findActionByType(type),\n findWatcherByType: (type) => this.findWatcherByType(type),\n }\n\n // Если есть middleware в options, добавляем их\n if (options.middlewares && options.middlewares.length > 0) {\n this.use(...options.middlewares)\n }\n }\n\n /**\n * Добавляет middleware в цепочку обработки\n */\n public use(...middlewares: EnhancedMiddleware<T>[]): this {\n // Инициализируем каждый middleware и добавляем только инициализированную версию\n for (let i = 0; i < middlewares.length; i++) {\n try {\n // Инициализируем middleware с API\n const initializedMiddleware = middlewares[i](this.middlewareAPI)\n this.middlewareFunctions.push(initializedMiddleware)\n } catch (error) {\n handleCallbackError(`Dispatcher: error initializing middleware [${i}]`, error)\n }\n }\n this.rebuildChain()\n return this\n }\n\n /**\n * Base executor: runs the registered action handler or passes through\n */\n private baseExecute = async (action: Action): Promise<any> => {\n // No params in WeakMap means this is a pass-through dispatch (via api.dispatch)\n if (!this.actionParams.has(action)) {\n return action.payload\n }\n\n const entry = this.actionRegistry.get(action.type)\n if (!entry) {\n return action.payload\n }\n\n const params = this.actionParams.get(action)\n return Promise.resolve(entry.action(params))\n }\n\n /**\n * Executes action through middleware chain and emits to actions$ (single emission point)\n */\n private async executeChain(action: Action): Promise<any> {\n const executor = this.dispatchChain ?? this.baseExecute\n const result = await executor(action)\n\n // Single emission point for all dispatches\n action.payload = result\n this.actionParams.delete(action)\n this.actions$.next(action)\n\n return result\n }\n\n /**\n * Rebuilds the pre-composed middleware chain. Called once on use(), not on every dispatch.\n */\n private rebuildChain(): void {\n if (this.middlewareFunctions.length === 0) {\n this.dispatchChain = null\n return\n }\n\n let chain = this.baseExecute as (action: Action) => Promise<any>\n for (let i = this.middlewareFunctions.length - 1; i >= 0; i--) {\n chain = this.middlewareFunctions[i](chain)\n }\n this.dispatchChain = chain\n }\n\n /**\n * Получает все действия с улучшенной типизацией\n */\n public getActions(): ActionsResult<TActionsFn> {\n return this.dispatch as ActionsResult<TActionsFn>\n }\n\n /**\n * Находит действие по типу\n */\n public findActionByType(actionType: string): DispatchFunction<any, any> | undefined {\n return Object.values(this.dispatch).find((action) => {\n return action.actionType.split(`[${this.storage.name}]`)[1] === actionType\n })\n }\n\n /**\n * Находит наблюдатель по типу\n */\n public findWatcherByType(actionType: string): WatcherFunction<any> | undefined {\n return Object.values(this.watchers).find((watcher) => {\n return watcher.actionType.split(`[${this.storage.name}]`)[1] === actionType\n })\n }\n\n /**\n * Уничтожает dispatcher: отписывает watchers, завершает поток действий, очищает состояние\n */\n public destroy(): void {\n Object.values(this.watchers).forEach((w) => w.unsubscribe())\n this.actions$.complete()\n this.dispatch = {}\n this.watchers = {}\n this.middlewareFunctions = []\n this.dispatchChain = null\n this.actionRegistry.clear()\n }\n\n /**\n * Создает действие\n */\n public createAction<TParams = void, TResult = void>(\n actionConfig: ActionDefinition<TParams, TResult>,\n executionOptions?: ActionExecutionOptions<TParams, TResult>,\n ): DispatchFunction<TParams, TResult> {\n const hasExplicitType = !!actionConfig.type\n let actionType = hasExplicitType ? `[${this.storage.name}]${actionConfig.type}` : ''\n\n // Register action executor in the registry (сразу, если тип известен)\n if (hasExplicitType) {\n this.actionRegistry.set(actionType, { action: actionConfig.action })\n }\n\n // Для мемоизации храним последние аргументы и результат\n let lastParams: TParams | undefined\n let lastResult: TResult | undefined\n let hasCached = false\n\n // Создаем функцию диспетчеризации\n const dispatchFn = async (params: TParams): Promise<TResult> => {\n if (!actionType) {\n throw new Error('Action type not assigned. Provide \"type\" in config or declare the action as a field of a Dispatcher subclass.')\n }\n\n // Проверяем мемоизацию\n if (executionOptions?.memoize && hasCached) {\n if (executionOptions.memoize(params, lastParams!, lastResult!)) {\n return lastResult!\n }\n }\n\n // Создаем объект действия\n const actionObject: Action<TResult> = {\n type: actionType,\n meta: actionConfig.meta,\n }\n\n // Store params for base executor to retrieve via WeakMap\n this.actionParams.set(actionObject, params)\n\n // Execute through middleware chain (includes single emission to actions$)\n const result = (await this.executeChain(actionObject)) as TResult\n\n // Сохраняем аргументы и результат для мемоизации\n lastParams = params\n lastResult = result\n hasCached = true\n\n return result\n }\n\n dispatchFn._type = 'dispatch'\n // Добавляем тип действия как свойство функции (configurable для deferred assignment)\n Object.defineProperty(dispatchFn, 'actionType', {\n value: actionType,\n writable: false,\n enumerable: true,\n configurable: true,\n })\n\n // Добавляем метаданные, если они есть\n if (actionConfig.meta) {\n Object.defineProperty(dispatchFn, 'meta', {\n value: actionConfig.meta,\n writable: false,\n enumerable: true,\n })\n }\n\n // Deferred type assignment — используется при финализации Dispatcher для авто-генерации типа из имени поля\n if (!hasExplicitType) {\n ;(dispatchFn as any)._assignType = (name: string) => {\n actionType = `[${this.storage.name}]${name}`\n\n this.actionRegistry.set(actionType, { action: actionConfig.action })\n\n Object.defineProperty(dispatchFn, 'actionType', {\n value: actionType,\n writable: false,\n enumerable: true,\n configurable: true,\n })\n }\n }\n\n return dispatchFn as DispatchFunction<TParams, TResult>\n }\n /**\n * Создает watcher для отслеживания изменений в хранилище\n */\n public createWatcher<R>(config: WatcherDefinition<T, R>): WatcherFunction<R> {\n const hasExplicitType = !!config.type\n let actionType = hasExplicitType ? `[${this.storage.name}]${config.type}` : ''\n\n // Lazy-подписка: подписываемся на storage только при первом subscribe на Observable\n let storageUnsubscribe: VoidFunction | null = null\n\n const sharedObservable = new Observable<TypedAction<R>>((subscriber) => {\n // Инициализируем prevValue текущим значением при первой подписке\n let prevValue: R | undefined\n let disposed = false\n\n const initAndSubscribe = async () => {\n try {\n const currentState = await Promise.resolve(this.storage.getState())\n prevValue = config.selector(currentState)\n } catch {\n // Если не удалось получить начальное значение — продолжаем с undefined\n }\n\n if (disposed) return\n\n // Если нужно уведомить о текущем значении при подписке\n if (config.notifyAfterSubscribe && prevValue !== undefined) {\n if (!config.shouldTrigger || config.shouldTrigger(undefined, prevValue)) {\n const initialAction: TypedAction<R> = {\n type: actionType,\n payload: prevValue,\n meta: {\n ...config.meta,\n isInitial: true,\n },\n }\n this.actions$.next(initialAction)\n subscriber.next(initialAction)\n }\n }\n\n // Подписываемся на изменения storage\n storageUnsubscribe = this.storage.subscribe(config.selector, (value: R) => {\n if (!config.shouldTrigger || config.shouldTrigger(prevValue, value)) {\n const action: TypedAction<R> = {\n type: actionType,\n payload: value,\n meta: config.meta,\n }\n\n this.actions$.next(action)\n subscriber.next(action)\n\n prevValue = value\n }\n })\n\n // Если отписались пока шла асинхронная инициализация — сразу очищаем\n if (disposed) {\n storageUnsubscribe()\n storageUnsubscribe = null\n }\n }\n\n initAndSubscribe()\n\n return () => {\n disposed = true\n if (storageUnsubscribe) {\n storageUnsubscribe()\n storageUnsubscribe = null\n }\n }\n }).pipe(share())\n\n // Создаем функцию watcher'а\n const watcherFn = () => sharedObservable\n\n watcherFn._type = 'watchers'\n\n Object.defineProperty(watcherFn, 'actionType', {\n value: actionType,\n writable: false,\n enumerable: true,\n configurable: true,\n })\n\n if (config.meta) {\n Object.defineProperty(watcherFn, 'meta', {\n value: config.meta,\n writable: false,\n enumerable: true,\n })\n }\n\n Object.defineProperty(watcherFn, 'unsubscribe', {\n value: () => {\n if (storageUnsubscribe) {\n storageUnsubscribe()\n storageUnsubscribe = null\n }\n },\n writable: false,\n enumerable: true,\n })\n\n // Deferred type assignment — используется при финализации Dispatcher для авто-генерации типа из имени поля\n if (!hasExplicitType) {\n ;(watcherFn as any)._assignType = (name: string) => {\n actionType = `[${this.storage.name}]${name}`\n\n Object.defineProperty(watcherFn, 'actionType', {\n value: actionType,\n writable: false,\n enumerable: true,\n configurable: true,\n })\n }\n }\n\n //@ts-ignore\n return watcherFn as WatcherFunction<R>\n }\n}\n"],"names":["Observable","share","Subject","handleCallbackError","DispatcherCore","Map","WeakMap","options","action","type","middlewares","i","initializedMiddleware","error","entry","params","Promise","executor","result","chain","actionType","Object","watcher","w","actionConfig","executionOptions","hasExplicitType","lastParams","lastResult","hasCached","dispatchFn","Error","actionObject","name","config","storageUnsubscribe","sharedObservable","subscriber","prevValue","disposed","initAndSubscribe","currentState","undefined","initialAction","value","watcherFn"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reactive/dispatcher/index.js","sources":["../../../src/reactive/dispatcher/index.ts"],"sourcesContent":["export * from './dispatcher.module'\nexport * from './middlewares'\nexport * from './standalone'\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"reactive/dispatcher/index.js","sources":["../../../src/reactive/dispatcher/index.ts"],"sourcesContent":["export * from './dispatcher.base'\nexport * from './dispatcher.module'\nexport * from './middlewares'\nexport * from './standalone'\n"],"names":[],"mappings":";;;;AAAiC;AACE;AACN;AACD"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Общие утилиты вычисления/записи пути по accessor'у.
|
|
3
|
+
*
|
|
4
|
+
* Используются базовым классом `Dispatcher` (`this.apiActions`/`this.keyedApiActions`).
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Вычисляет путь к свойству через Proxy-перехват обращений.
|
|
8
|
+
*
|
|
9
|
+
* @example resolvePath((s) => s.api.listRequest) // ['api', 'listRequest']
|
|
10
|
+
*/
|
|
11
|
+
export declare function resolvePath<T>(accessor: (draft: T) => any): string[];
|
|
12
|
+
/**
|
|
13
|
+
* Записывает значение по пути в объекте (мутирует переданный draft).
|
|
14
|
+
*/
|
|
15
|
+
export declare function setByPath(obj: any, path: string[], value: any): void;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Общие утилиты вычисления/записи пути по accessor'у.
|
|
3
|
+
*
|
|
4
|
+
* Используются базовым классом `Dispatcher` (`this.apiActions`/`this.keyedApiActions`).
|
|
5
|
+
*/ /**
|
|
6
|
+
* Вычисляет путь к свойству через Proxy-перехват обращений.
|
|
7
|
+
*
|
|
8
|
+
* @example resolvePath((s) => s.api.listRequest) // ['api', 'listRequest']
|
|
9
|
+
*/ function resolvePath(accessor) {
|
|
10
|
+
const path = [];
|
|
11
|
+
const handler = {
|
|
12
|
+
get (_, prop) {
|
|
13
|
+
if (typeof prop === 'string') {
|
|
14
|
+
path.push(prop);
|
|
15
|
+
}
|
|
16
|
+
return new Proxy({}, handler);
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
accessor(new Proxy({}, handler));
|
|
20
|
+
return path;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Записывает значение по пути в объекте (мутирует переданный draft).
|
|
24
|
+
*/ function setByPath(obj, path, value) {
|
|
25
|
+
let current = obj;
|
|
26
|
+
for(let i = 0; i < path.length - 1; i++){
|
|
27
|
+
current = current[path[i]];
|
|
28
|
+
}
|
|
29
|
+
current[path[path.length - 1]] = value;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export { resolvePath, setByPath };
|
|
33
|
+
|
|
34
|
+
//# sourceMappingURL=path.util.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reactive/dispatcher/path.util.js","sources":["../../../src/reactive/dispatcher/path.util.ts"],"sourcesContent":["/**\n * Общие утилиты вычисления/записи пути по accessor'у.\n *\n * Используются базовым классом `Dispatcher` (`this.apiActions`/`this.keyedApiActions`).\n */\n\n/**\n * Вычисляет путь к свойству через Proxy-перехват обращений.\n *\n * @example resolvePath((s) => s.api.listRequest) // ['api', 'listRequest']\n */\nexport function resolvePath<T>(accessor: (draft: T) => any): string[] {\n const path: string[] = []\n const handler: ProxyHandler<any> = {\n get(_, prop) {\n if (typeof prop === 'string') {\n path.push(prop)\n }\n return new Proxy({}, handler)\n },\n }\n accessor(new Proxy({}, handler) as T)\n return path\n}\n\n/**\n * Записывает значение по пути в объекте (мутирует переданный draft).\n */\nexport function setByPath(obj: any, path: string[], value: any): void {\n let current = obj\n for (let i = 0; i < path.length - 1; i++) {\n current = current[path[i]]\n }\n current[path[path.length - 1]] = value\n}\n"],"names":["resolvePath","accessor","path","handler","_","prop","Proxy","setByPath","obj","value","current","i"],"mappings":"AAAA;;;;CAIC,GAED;;;;CAIC,GACM,SAASA,WAAWA,CAAIC,QAA2B;IACxD,MAAMC,OAAiB,EAAE;IACzB,MAAMC,UAA6B;QACjC,KAAIC,CAAC,EAAEC,IAAI;YACT,IAAI,OAAOA,SAAS,UAAU;gBAC5BH,KAAK,IAAI,CAACG;YACZ;YACA,OAAO,IAAIC,MAAM,CAAC,GAAGH;QACvB;IACF;IACAF,SAAS,IAAIK,MAAM,CAAC,GAAGH;IACvB,OAAOD;AACT;AAEA;;CAEC,GACM,SAASK,SAASA,CAACC,GAAQ,EAAEN,IAAc,EAAEO,KAAU;IAC5D,IAAIC,UAAUF;IACd,IAAK,IAAIG,IAAI,GAAGA,IAAIT,KAAK,MAAM,GAAG,GAAGS,IAAK;QACxCD,UAAUA,OAAO,CAACR,IAAI,CAACS,EAAE,CAAC;IAC5B;IACAD,OAAO,CAACR,IAAI,CAACA,KAAK,MAAM,GAAG,EAAE,CAAC,GAAGO;AACnC"}
|
|
@@ -1,34 +1,9 @@
|
|
|
1
|
-
import type { IStorage } from '../../core';
|
|
2
1
|
/**
|
|
3
2
|
* Параметры исполнения действия (мемоизация)
|
|
4
3
|
*/
|
|
5
4
|
export interface ActionExecutionOptions<TParams, TResult> {
|
|
6
5
|
memoize?: (currentArgs: TParams, previousArgs: TParams, previousResult: TResult) => boolean;
|
|
7
6
|
}
|
|
8
|
-
/**
|
|
9
|
-
* Рецепт действия — standalone-определение, не привязанное к хранилищу.
|
|
10
|
-
* Привязывается к storage при регистрации в createDispatcher.
|
|
11
|
-
*/
|
|
12
|
-
export interface ActionRecipe<TState extends Record<string, any>, TParams, TResult> {
|
|
13
|
-
readonly _type: 'action-recipe';
|
|
14
|
-
readonly _config: {
|
|
15
|
-
action: (storage: IStorage<TState>, params: TParams) => Promise<TResult> | TResult;
|
|
16
|
-
meta?: Record<string, any>;
|
|
17
|
-
};
|
|
18
|
-
readonly _executionOptions?: ActionExecutionOptions<TParams, TResult>;
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* Рецепт watcher'а — standalone-определение, не привязанное к хранилищу.
|
|
22
|
-
*/
|
|
23
|
-
export interface WatcherRecipe<TState extends Record<string, any>, R> {
|
|
24
|
-
readonly _type: 'watcher-recipe';
|
|
25
|
-
readonly _config: {
|
|
26
|
-
selector: (state: TState) => R;
|
|
27
|
-
meta?: Record<string, any>;
|
|
28
|
-
shouldTrigger?: (prev: R | undefined, current: R) => boolean;
|
|
29
|
-
notifyAfterSubscribe?: boolean;
|
|
30
|
-
};
|
|
31
|
-
}
|
|
32
7
|
/**
|
|
33
8
|
* Статусы жизненного цикла API-запроса.
|
|
34
9
|
*
|
|
@@ -49,133 +24,9 @@ export declare const ApiStatus: {
|
|
|
49
24
|
};
|
|
50
25
|
export type ApiStatus = (typeof ApiStatus)[keyof typeof ApiStatus];
|
|
51
26
|
/**
|
|
52
|
-
* Состояние API-запроса
|
|
27
|
+
* Состояние API-запроса (`this.apiActions` / `this.keyedApiActions`)
|
|
53
28
|
*/
|
|
54
29
|
export interface ApiRequestState {
|
|
55
30
|
status: ApiStatus;
|
|
56
31
|
error: string | null;
|
|
57
32
|
}
|
|
58
|
-
/**
|
|
59
|
-
* Создаёт standalone-определение действия.
|
|
60
|
-
* Фиксирует TState через первый вызов, TParams/TResult инферятся из action.
|
|
61
|
-
*
|
|
62
|
-
* @example
|
|
63
|
-
* ```ts
|
|
64
|
-
* const action = defineAction<MyState>()
|
|
65
|
-
*
|
|
66
|
-
* export const increment = action({
|
|
67
|
-
* action: (storage, amount: number) => {
|
|
68
|
-
* storage.update((s) => { s.count += amount })
|
|
69
|
-
* return amount
|
|
70
|
-
* },
|
|
71
|
-
* })
|
|
72
|
-
*
|
|
73
|
-
* // Void action (без параметров и возврата):
|
|
74
|
-
* export const reset = action({
|
|
75
|
-
* action: (storage) => {
|
|
76
|
-
* storage.update((s) => { s.count = 0 })
|
|
77
|
-
* },
|
|
78
|
-
* })
|
|
79
|
-
* ```
|
|
80
|
-
*/
|
|
81
|
-
export declare function defineAction<TState extends Record<string, any>>(): <TParams = void, TResult = void>(config: {
|
|
82
|
-
action: (storage: IStorage<TState>, params: TParams) => Promise<TResult> | TResult;
|
|
83
|
-
meta?: Record<string, any>;
|
|
84
|
-
}, executionOptions?: ActionExecutionOptions<TParams, TResult>) => ActionRecipe<TState, TParams, TResult>;
|
|
85
|
-
/**
|
|
86
|
-
* Создаёт standalone-определение watcher'а.
|
|
87
|
-
*
|
|
88
|
-
* @example
|
|
89
|
-
* ```ts
|
|
90
|
-
* export const watchCount = defineWatcher<MyState>()({
|
|
91
|
-
* selector: (s) => s.items.length,
|
|
92
|
-
* notifyAfterSubscribe: true,
|
|
93
|
-
* })
|
|
94
|
-
* ```
|
|
95
|
-
*/
|
|
96
|
-
export declare function defineWatcher<TState extends Record<string, any>>(): <R>(config: {
|
|
97
|
-
selector: (state: TState) => R;
|
|
98
|
-
meta?: Record<string, any>;
|
|
99
|
-
shouldTrigger?: (prev: R | undefined, current: R) => boolean;
|
|
100
|
-
notifyAfterSubscribe?: boolean;
|
|
101
|
-
}) => WatcherRecipe<TState, R>;
|
|
102
|
-
/**
|
|
103
|
-
* Создаёт набор шаблонных lifecycle-действий для API-запроса.
|
|
104
|
-
* Accessor указывает на поле ApiRequestState в стейте — путь вычисляется автоматически.
|
|
105
|
-
*
|
|
106
|
-
* @param accessor - Функция-accessor, указывающая на поле ApiRequestState в стейте
|
|
107
|
-
*
|
|
108
|
-
* @typeParam TInitPayload - Тип payload'а `init`-экшена. По умолчанию `void`
|
|
109
|
-
* (init без параметров). Если задать — `init` принимает payload и возвращает
|
|
110
|
-
* его, что удобно для intent-паттерна: эффект слушает `init` и читает payload
|
|
111
|
-
* намерения (target, фильтры и т.п.), а статус при этом сбрасывается в `idle`.
|
|
112
|
-
*
|
|
113
|
-
* @example
|
|
114
|
-
* ```ts
|
|
115
|
-
* const listRequest = createApiActions<MyState>(
|
|
116
|
-
* (draft) => draft.api.listRequest
|
|
117
|
-
* )
|
|
118
|
-
*
|
|
119
|
-
* // В dispatcher:
|
|
120
|
-
* createDispatcher({ storage }, {
|
|
121
|
-
* loadListInit: listRequest.init,
|
|
122
|
-
* loadListLoading: listRequest.loading,
|
|
123
|
-
* loadListSuccess: listRequest.success,
|
|
124
|
-
* loadListFailure: listRequest.failure,
|
|
125
|
-
* loadListReset: listRequest.reset,
|
|
126
|
-
* })
|
|
127
|
-
*
|
|
128
|
-
* // init с payload (intent): эффект получит { entityId } из возврата экшена.
|
|
129
|
-
* const usersReq = createApiActions<MyState, { entityId: string }>(
|
|
130
|
-
* (draft) => draft.api.usersRequest
|
|
131
|
-
* )
|
|
132
|
-
* ```
|
|
133
|
-
*/
|
|
134
|
-
export declare function createApiActions<TState extends Record<string, any>, TInitPayload = void>(accessor: (draft: TState) => ApiRequestState): {
|
|
135
|
-
init: ActionRecipe<TState, TInitPayload, TInitPayload>;
|
|
136
|
-
loading: ActionRecipe<TState, void, void>;
|
|
137
|
-
success: ActionRecipe<TState, void, void>;
|
|
138
|
-
failure: ActionRecipe<TState, string, void>;
|
|
139
|
-
reset: ActionRecipe<TState, void, void>;
|
|
140
|
-
};
|
|
141
|
-
/**
|
|
142
|
-
* Keyed-вариант createApiActions: статус хранится ПО КЛЮЧУ в `Record<string,
|
|
143
|
-
* ApiRequestState>`, а не один на весь запрос. Нужен, когда один и тот же запрос
|
|
144
|
-
* летит параллельно для нескольких независимых ключей и у каждого свой
|
|
145
|
-
* loading/error: комменты по таргетам, детали сущностей по id, per-row действия
|
|
146
|
-
* в таблице/ленте, пагинация по секциям — всё, что лежит как `Record<key, data>`.
|
|
147
|
-
*
|
|
148
|
-
* Все статус-экшены принимают `key` (и возвращают его — удобно эффектам), кроме
|
|
149
|
-
* `failure`, который принимает `{ key, error }`. Записи мутируются иммутабельно
|
|
150
|
-
* по одному ключу — соседние ключи (их срезы) по ссылке не затрагиваются, что и
|
|
151
|
-
* нужно для гранулярной изоляции ре-рендеров (см. useKeyedSliceSelector).
|
|
152
|
-
*
|
|
153
|
-
* @param accessor - Функция-accessor, указывающая на поле `Record<string, ApiRequestState>`
|
|
154
|
-
*
|
|
155
|
-
* @example
|
|
156
|
-
* ```ts
|
|
157
|
-
* const commentsReq = createKeyedApiActions<MyState>((d) => d.api.commentsRequest)
|
|
158
|
-
*
|
|
159
|
-
* createDispatcher({ storage }, {
|
|
160
|
-
* commentsInit: commentsReq.init, // (key) => key
|
|
161
|
-
* commentsLoading: commentsReq.loading, // (key) => key
|
|
162
|
-
* commentsSuccess: commentsReq.success, // (key) => key
|
|
163
|
-
* commentsFailure: commentsReq.failure, // ({ key, error })
|
|
164
|
-
* commentsReset: commentsReq.reset, // (key) => key
|
|
165
|
-
* })
|
|
166
|
-
* ```
|
|
167
|
-
*/
|
|
168
|
-
export declare function createKeyedApiActions<TState extends Record<string, any>>(accessor: (draft: TState) => Record<string, ApiRequestState>): {
|
|
169
|
-
init: ActionRecipe<TState, string, string>;
|
|
170
|
-
loading: ActionRecipe<TState, string, string>;
|
|
171
|
-
success: ActionRecipe<TState, string, string>;
|
|
172
|
-
reset: ActionRecipe<TState, string, string>;
|
|
173
|
-
failure: ActionRecipe<TState, {
|
|
174
|
-
key: string;
|
|
175
|
-
error: string;
|
|
176
|
-
}, {
|
|
177
|
-
key: string;
|
|
178
|
-
error: string;
|
|
179
|
-
}>;
|
|
180
|
-
};
|
|
181
|
-
//# sourceMappingURL=standalone.d.ts.map
|