synapse-storage 3.0.19 → 4.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +28 -168
- package/dist/_utils/chunk.util.d.ts +8 -0
- package/dist/_utils/chunk.util.d.ts.map +1 -0
- package/dist/_utils/chunk.util.js +21 -0
- package/dist/_utils/chunk.util.js.map +1 -0
- package/dist/_utils/deepMerge.util.d.ts +2 -0
- package/dist/_utils/deepMerge.util.d.ts.map +1 -0
- package/dist/_utils/deepMerge.util.js +19 -0
- package/dist/_utils/deepMerge.util.js.map +1 -0
- package/dist/_utils/error-handling.util.d.ts +50 -0
- package/dist/_utils/error-handling.util.d.ts.map +1 -0
- package/dist/_utils/error-handling.util.js +67 -0
- package/dist/_utils/error-handling.util.js.map +1 -0
- package/dist/_utils/flatMap.util.d.ts +10 -0
- package/dist/_utils/flatMap.util.d.ts.map +1 -0
- package/dist/_utils/flatMap.util.js +23 -0
- package/dist/_utils/flatMap.util.js.map +1 -0
- package/dist/_utils/index.d.ts +6 -0
- package/dist/_utils/index.d.ts.map +1 -0
- package/dist/_utils/index.js +13 -0
- package/dist/_utils/index.js.map +1 -0
- package/dist/_utils/logger-console.util.d.ts +9 -0
- package/dist/_utils/logger-console.util.d.ts.map +1 -0
- package/dist/_utils/logger-console.util.js +14 -0
- package/dist/_utils/logger-console.util.js.map +1 -0
- package/dist/api/api.module.d.ts +46 -0
- package/dist/api/api.module.d.ts.map +1 -0
- package/dist/api/api.module.js +121 -0
- package/dist/api/api.module.js.map +1 -0
- package/dist/api/components/endpoint.d.ts +57 -0
- package/dist/api/components/endpoint.d.ts.map +1 -0
- package/dist/api/components/endpoint.js +385 -0
- package/dist/api/components/endpoint.js.map +1 -0
- package/dist/api/components/query-storage.d.ts +100 -0
- package/dist/api/components/query-storage.d.ts.map +1 -0
- package/dist/api/components/query-storage.js +293 -0
- package/dist/api/components/query-storage.js.map +1 -0
- package/dist/api/example.d.ts +83 -0
- package/dist/api/example.d.ts.map +1 -0
- package/dist/api/example.js +90 -0
- package/dist/api/example.js.map +1 -0
- package/dist/api/index.d.ts +4 -0
- package/dist/api/index.d.ts.map +1 -0
- package/dist/api/index.js +11 -0
- package/dist/api/index.js.map +1 -0
- package/dist/api/types/api.interface.d.ts +126 -0
- package/dist/api/types/api.interface.d.ts.map +1 -0
- package/dist/api/types/api.interface.js +15 -0
- package/dist/api/types/api.interface.js.map +1 -0
- package/dist/api/types/endpoint.interface.d.ts +118 -0
- package/dist/api/types/endpoint.interface.d.ts.map +1 -0
- package/dist/api/types/endpoint.interface.js +6 -0
- package/dist/api/types/endpoint.interface.js.map +1 -0
- package/dist/api/types/query.interface.d.ts +85 -0
- package/dist/api/types/query.interface.d.ts.map +1 -0
- package/dist/api/types/query.interface.js +6 -0
- package/dist/api/types/query.interface.js.map +1 -0
- package/dist/api/utils/api-helpers.d.ts +22 -0
- package/dist/api/utils/api-helpers.d.ts.map +1 -0
- package/dist/api/utils/api-helpers.js +44 -0
- package/dist/api/utils/api-helpers.js.map +1 -0
- package/dist/api/utils/create-header-context.d.ts +10 -0
- package/dist/api/utils/create-header-context.d.ts.map +1 -0
- package/dist/api/utils/create-header-context.js +40 -0
- package/dist/api/utils/create-header-context.js.map +1 -0
- package/dist/api/utils/endpoint-headers.d.ts +23 -0
- package/dist/api/utils/endpoint-headers.d.ts.map +1 -0
- package/dist/api/utils/endpoint-headers.js +61 -0
- package/dist/api/utils/endpoint-headers.js.map +1 -0
- package/dist/api/utils/fetch-base-query.d.ts +9 -0
- package/dist/api/utils/fetch-base-query.d.ts.map +1 -0
- package/dist/api/utils/fetch-base-query.js +242 -0
- package/dist/api/utils/fetch-base-query.js.map +1 -0
- package/dist/api/utils/file-utils.d.ts +43 -0
- package/dist/api/utils/file-utils.d.ts.map +1 -0
- package/dist/api/utils/file-utils.js +102 -0
- package/dist/api/utils/file-utils.js.map +1 -0
- package/dist/api/utils/get-cacheable-headers.d.ts +8 -0
- package/dist/api/utils/get-cacheable-headers.d.ts.map +1 -0
- package/dist/api/utils/get-cacheable-headers.js +23 -0
- package/dist/api/utils/get-cacheable-headers.js.map +1 -0
- package/dist/core/index.d.ts +3 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +7 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/selector/index.d.ts +3 -0
- package/dist/core/selector/index.d.ts.map +1 -0
- package/dist/core/selector/index.js +5 -0
- package/dist/core/selector/index.js.map +1 -0
- package/dist/{selector.interface-CA5y-kD_.d.ts → core/selector/selector.interface.d.ts} +41 -8
- package/dist/core/selector/selector.interface.d.ts.map +1 -0
- package/dist/core/selector/selector.interface.js +7 -0
- package/dist/core/selector/selector.interface.js.map +1 -0
- package/dist/core/selector/selector.module.d.ts +36 -0
- package/dist/core/selector/selector.module.d.ts.map +1 -0
- package/dist/core/selector/selector.module.js +412 -0
- package/dist/core/selector/selector.module.js.map +1 -0
- package/dist/core/storage/adapters/async-base-storage.service.d.ts +49 -0
- package/dist/core/storage/adapters/async-base-storage.service.d.ts.map +1 -0
- package/dist/core/storage/adapters/async-base-storage.service.js +505 -0
- package/dist/core/storage/adapters/async-base-storage.service.js.map +1 -0
- package/dist/core/storage/adapters/indexed-DB.service.d.ts +89 -0
- package/dist/core/storage/adapters/indexed-DB.service.d.ts.map +1 -0
- package/dist/core/storage/adapters/indexed-DB.service.js +596 -0
- package/dist/core/storage/adapters/indexed-DB.service.js.map +1 -0
- package/dist/core/storage/adapters/local-storage.service.d.ts +23 -0
- package/dist/core/storage/adapters/local-storage.service.d.ts.map +1 -0
- package/dist/core/storage/adapters/local-storage.service.js +111 -0
- package/dist/core/storage/adapters/local-storage.service.js.map +1 -0
- package/dist/core/storage/adapters/memory-storage.service.d.ts +24 -0
- package/dist/core/storage/adapters/memory-storage.service.d.ts.map +1 -0
- package/dist/core/storage/adapters/memory-storage.service.js +110 -0
- package/dist/core/storage/adapters/memory-storage.service.js.map +1 -0
- package/dist/core/storage/adapters/path.utils.d.ts +5 -0
- package/dist/core/storage/adapters/path.utils.d.ts.map +1 -0
- package/dist/core/storage/adapters/path.utils.js +42 -0
- package/dist/core/storage/adapters/path.utils.js.map +1 -0
- package/dist/core/storage/adapters/storage-core.d.ts +61 -0
- package/dist/core/storage/adapters/storage-core.d.ts.map +1 -0
- package/dist/core/storage/adapters/storage-core.js +221 -0
- package/dist/core/storage/adapters/storage-core.js.map +1 -0
- package/dist/core/storage/adapters/sync-base-storage.service.d.ts +56 -0
- package/dist/core/storage/adapters/sync-base-storage.service.d.ts.map +1 -0
- package/dist/core/storage/adapters/sync-base-storage.service.js +481 -0
- package/dist/core/storage/adapters/sync-base-storage.service.js.map +1 -0
- package/dist/core/storage/index.d.ts +16 -0
- package/dist/core/storage/index.d.ts.map +1 -0
- package/dist/core/storage/index.js +38 -0
- package/dist/core/storage/index.js.map +1 -0
- package/dist/core/storage/middlewares/broadcast.middleware.d.ts +9 -0
- package/dist/core/storage/middlewares/broadcast.middleware.d.ts.map +1 -0
- package/dist/core/storage/middlewares/broadcast.middleware.js +197 -0
- package/dist/core/storage/middlewares/broadcast.middleware.js.map +1 -0
- package/dist/core/storage/middlewares/index.d.ts +9 -0
- package/dist/core/storage/middlewares/index.d.ts.map +1 -0
- package/dist/core/storage/middlewares/index.js +17 -0
- package/dist/core/storage/middlewares/index.js.map +1 -0
- package/dist/core/storage/middlewares/storage-batching.middleware.d.ts +7 -0
- package/dist/core/storage/middlewares/storage-batching.middleware.d.ts.map +1 -0
- package/dist/core/storage/middlewares/storage-batching.middleware.js +108 -0
- package/dist/core/storage/middlewares/storage-batching.middleware.js.map +1 -0
- package/dist/core/storage/middlewares/storage-shallow-compare.middleware.d.ts +7 -0
- package/dist/core/storage/middlewares/storage-shallow-compare.middleware.d.ts.map +1 -0
- package/dist/core/storage/middlewares/storage-shallow-compare.middleware.js +43 -0
- package/dist/core/storage/middlewares/storage-shallow-compare.middleware.js.map +1 -0
- package/dist/core/storage/middlewares/sync-broadcast.middleware.d.ts +9 -0
- package/dist/core/storage/middlewares/sync-broadcast.middleware.d.ts.map +1 -0
- package/dist/core/storage/middlewares/sync-broadcast.middleware.js +177 -0
- package/dist/core/storage/middlewares/sync-broadcast.middleware.js.map +1 -0
- package/dist/core/storage/middlewares/sync-storage-batching.middleware.d.ts +6 -0
- package/dist/core/storage/middlewares/sync-storage-batching.middleware.d.ts.map +1 -0
- package/dist/core/storage/middlewares/sync-storage-batching.middleware.js +56 -0
- package/dist/core/storage/middlewares/sync-storage-batching.middleware.js.map +1 -0
- package/dist/core/storage/middlewares/sync-storage-shallow-compare.middleware.d.ts +7 -0
- package/dist/core/storage/middlewares/sync-storage-shallow-compare.middleware.d.ts.map +1 -0
- package/dist/core/storage/middlewares/sync-storage-shallow-compare.middleware.js +39 -0
- package/dist/core/storage/middlewares/sync-storage-shallow-compare.middleware.js.map +1 -0
- package/dist/core/storage/modules/plugin/plugin.interface.d.ts +101 -0
- package/dist/core/storage/modules/plugin/plugin.interface.d.ts.map +1 -0
- package/dist/core/storage/modules/plugin/plugin.interface.js +8 -0
- package/dist/core/storage/modules/plugin/plugin.interface.js.map +1 -0
- package/dist/core/storage/modules/plugin/plugin.service.d.ts +49 -0
- package/dist/core/storage/modules/plugin/plugin.service.d.ts.map +1 -0
- package/dist/core/storage/modules/plugin/plugin.service.js +406 -0
- package/dist/core/storage/modules/plugin/plugin.service.js.map +1 -0
- package/dist/core/storage/modules/singleton/mixin.util.d.ts +6 -0
- package/dist/core/storage/modules/singleton/mixin.util.d.ts.map +1 -0
- package/dist/core/storage/modules/singleton/mixin.util.js +30 -0
- package/dist/core/storage/modules/singleton/mixin.util.js.map +1 -0
- package/dist/core/storage/modules/singleton/models.d.ts +143 -0
- package/dist/core/storage/modules/singleton/models.d.ts.map +1 -0
- package/dist/core/storage/modules/singleton/models.js +60 -0
- package/dist/core/storage/modules/singleton/models.js.map +1 -0
- package/dist/core/storage/modules/singleton/singleton.util.d.ts +36 -0
- package/dist/core/storage/modules/singleton/singleton.util.d.ts.map +1 -0
- package/dist/core/storage/modules/singleton/singleton.util.js +216 -0
- package/dist/core/storage/modules/singleton/singleton.util.js.map +1 -0
- package/dist/core/storage/storage.interface.d.ts +168 -0
- package/dist/core/storage/storage.interface.d.ts.map +1 -0
- package/dist/core/storage/storage.interface.js +23 -0
- package/dist/core/storage/storage.interface.js.map +1 -0
- package/dist/core/storage/utils/broadcast.util.d.ts +49 -0
- package/dist/core/storage/utils/broadcast.util.d.ts.map +1 -0
- package/dist/core/storage/utils/broadcast.util.js +141 -0
- package/dist/core/storage/utils/broadcast.util.js.map +1 -0
- package/dist/core/storage/utils/cache.util.d.ts +33 -0
- package/dist/core/storage/utils/cache.util.d.ts.map +1 -0
- package/dist/core/storage/utils/cache.util.js +54 -0
- package/dist/core/storage/utils/cache.util.js.map +1 -0
- package/dist/core/storage/utils/middleware-module.d.ts +94 -0
- package/dist/core/storage/utils/middleware-module.d.ts.map +1 -0
- package/dist/core/storage/utils/middleware-module.js +258 -0
- package/dist/core/storage/utils/middleware-module.js.map +1 -0
- package/dist/core/storage/utils/path-selector.util.d.ts +15 -0
- package/dist/core/storage/utils/path-selector.util.d.ts.map +1 -0
- package/dist/core/storage/utils/path-selector.util.js +58 -0
- package/dist/core/storage/utils/path-selector.util.js.map +1 -0
- package/dist/core/storage/utils/state-diff.util.d.ts +14 -0
- package/dist/core/storage/utils/state-diff.util.d.ts.map +1 -0
- package/dist/core/storage/utils/state-diff.util.js +88 -0
- package/dist/core/storage/utils/state-diff.util.js.map +1 -0
- package/dist/core/storage/utils/storage-factory.util.d.ts +21 -0
- package/dist/core/storage/utils/storage-factory.util.d.ts.map +1 -0
- package/dist/core/storage/utils/storage-factory.util.js +40 -0
- package/dist/core/storage/utils/storage-factory.util.js.map +1 -0
- package/dist/core/storage/utils/storage-key.d.ts +11 -0
- package/dist/core/storage/utils/storage-key.d.ts.map +1 -0
- package/dist/core/storage/utils/storage-key.js +24 -0
- package/dist/core/storage/utils/storage-key.js.map +1 -0
- package/dist/core/storage/utils/storage.utils.d.ts +17 -0
- package/dist/core/storage/utils/storage.utils.d.ts.map +1 -0
- package/dist/core/storage/utils/storage.utils.js +57 -0
- package/dist/core/storage/utils/storage.utils.js.map +1 -0
- package/dist/index.d.ts +10 -12
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -1
- package/dist/index.js.map +1 -0
- package/dist/react/hooks/index.d.ts +5 -0
- package/dist/react/hooks/index.d.ts.map +1 -0
- package/dist/react/hooks/index.js +11 -0
- package/dist/react/hooks/index.js.map +1 -0
- package/dist/react/hooks/useCreateStorage.d.ts +39 -0
- package/dist/react/hooks/useCreateStorage.d.ts.map +1 -0
- package/dist/react/hooks/useCreateStorage.js +137 -0
- package/dist/react/hooks/useCreateStorage.js.map +1 -0
- package/dist/react/hooks/useSelector.d.ts +21 -0
- package/dist/react/hooks/useSelector.d.ts.map +1 -0
- package/dist/react/hooks/useSelector.js +56 -0
- package/dist/react/hooks/useSelector.js.map +1 -0
- package/dist/react/hooks/useStorage.d.ts +39 -0
- package/dist/react/hooks/useStorage.d.ts.map +1 -0
- package/dist/react/hooks/useStorage.js +78 -0
- package/dist/react/hooks/useStorage.js.map +1 -0
- package/dist/react/hooks/useStorageSubscribe.d.ts +16 -0
- package/dist/react/hooks/useStorageSubscribe.d.ts.map +1 -0
- package/dist/react/hooks/useStorageSubscribe.js +55 -0
- package/dist/react/hooks/useStorageSubscribe.js.map +1 -0
- package/dist/react/index.d.ts +3 -0
- package/dist/react/index.d.ts.map +1 -0
- package/dist/react/index.js +7 -0
- package/dist/react/index.js.map +1 -0
- package/dist/react/utils/awaitSynapse.d.ts +34 -0
- package/dist/react/utils/awaitSynapse.d.ts.map +1 -0
- package/dist/react/utils/awaitSynapse.js +87 -0
- package/dist/react/utils/awaitSynapse.js.map +1 -0
- package/dist/react/utils/createSynapseCtx.d.ts +33 -0
- package/dist/react/utils/createSynapseCtx.d.ts.map +1 -0
- package/dist/react/utils/createSynapseCtx.js +139 -0
- package/dist/react/utils/createSynapseCtx.js.map +1 -0
- package/dist/react/utils/index.d.ts +3 -0
- package/dist/react/utils/index.d.ts.map +1 -0
- package/dist/react/utils/index.js +9 -0
- package/dist/react/utils/index.js.map +1 -0
- package/dist/reactive/dispatcher/dispatcher.module.d.ts +216 -0
- package/dist/reactive/dispatcher/dispatcher.module.d.ts.map +1 -0
- package/dist/reactive/dispatcher/dispatcher.module.js +384 -0
- package/dist/reactive/dispatcher/dispatcher.module.js.map +1 -0
- package/dist/reactive/dispatcher/index.d.ts +4 -0
- package/dist/reactive/dispatcher/index.d.ts.map +1 -0
- package/dist/reactive/dispatcher/index.js +9 -0
- package/dist/reactive/dispatcher/index.js.map +1 -0
- package/dist/reactive/dispatcher/middlewares/index.d.ts +2 -0
- package/dist/reactive/dispatcher/middlewares/index.d.ts.map +1 -0
- package/dist/reactive/dispatcher/middlewares/index.js +5 -0
- package/dist/reactive/dispatcher/middlewares/index.js.map +1 -0
- package/dist/reactive/dispatcher/middlewares/logger.middleware.d.ts +37 -0
- package/dist/reactive/dispatcher/middlewares/logger.middleware.d.ts.map +1 -0
- package/dist/reactive/dispatcher/middlewares/logger.middleware.js +188 -0
- package/dist/reactive/dispatcher/middlewares/logger.middleware.js.map +1 -0
- package/dist/reactive/dispatcher/standalone.d.ts +112 -0
- package/dist/reactive/dispatcher/standalone.d.ts.map +1 -0
- package/dist/reactive/dispatcher/standalone.js +142 -0
- package/dist/reactive/dispatcher/standalone.js.map +1 -0
- package/dist/reactive/effects/effects.module.d.ts +225 -0
- package/dist/reactive/effects/effects.module.d.ts.map +1 -0
- package/dist/reactive/effects/effects.module.js +356 -0
- package/dist/reactive/effects/effects.module.js.map +1 -0
- package/dist/reactive/effects/index.d.ts +4 -0
- package/dist/reactive/effects/index.d.ts.map +1 -0
- package/dist/reactive/effects/index.js +11 -0
- package/dist/reactive/effects/index.js.map +1 -0
- package/dist/reactive/effects/utils/chunkRequestConsistent.d.ts +12 -0
- package/dist/reactive/effects/utils/chunkRequestConsistent.d.ts.map +1 -0
- package/dist/reactive/effects/utils/chunkRequestConsistent.js +25 -0
- package/dist/reactive/effects/utils/chunkRequestConsistent.js.map +1 -0
- package/dist/reactive/effects/utils/chunkRequestParallel.d.ts +12 -0
- package/dist/reactive/effects/utils/chunkRequestParallel.d.ts.map +1 -0
- package/dist/reactive/effects/utils/chunkRequestParallel.js +22 -0
- package/dist/reactive/effects/utils/chunkRequestParallel.js.map +1 -0
- package/dist/reactive/effects/utils/fromRequest.d.ts +40 -0
- package/dist/reactive/effects/utils/fromRequest.d.ts.map +1 -0
- package/dist/reactive/effects/utils/fromRequest.js +64 -0
- package/dist/reactive/effects/utils/fromRequest.js.map +1 -0
- package/dist/reactive/effects/utils/index.d.ts +5 -0
- package/dist/reactive/effects/utils/index.d.ts.map +1 -0
- package/dist/reactive/effects/utils/index.js +11 -0
- package/dist/reactive/effects/utils/index.js.map +1 -0
- package/dist/reactive/effects/utils/toObservable.d.ts +23 -0
- package/dist/reactive/effects/utils/toObservable.d.ts.map +1 -0
- package/dist/reactive/effects/utils/toObservable.js +39 -0
- package/dist/reactive/effects/utils/toObservable.js.map +1 -0
- package/dist/reactive/index.d.ts +3 -0
- package/dist/reactive/index.d.ts.map +1 -0
- package/dist/reactive/index.js +7 -0
- package/dist/reactive/index.js.map +1 -0
- package/dist/utils/createEventBus.d.ts +87 -0
- package/dist/utils/createEventBus.d.ts.map +1 -0
- package/dist/utils/createEventBus.js +215 -0
- package/dist/utils/createEventBus.js.map +1 -0
- package/dist/utils/createSynapse/createSynapse.d.ts +9 -0
- package/dist/utils/createSynapse/createSynapse.d.ts.map +1 -0
- package/dist/utils/createSynapse/createSynapse.js +103 -0
- package/dist/utils/createSynapse/createSynapse.js.map +1 -0
- package/dist/utils/createSynapse/index.d.ts +3 -0
- package/dist/utils/createSynapse/index.d.ts.map +1 -0
- package/dist/utils/createSynapse/index.js +6 -0
- package/dist/utils/createSynapse/index.js.map +1 -0
- package/dist/utils/createSynapse/types.d.ts +93 -0
- package/dist/utils/createSynapse/types.d.ts.map +1 -0
- package/dist/utils/createSynapse/types.js +6 -0
- package/dist/utils/createSynapse/types.js.map +1 -0
- package/dist/utils/createSynapse/validate.d.ts +2 -0
- package/dist/utils/createSynapse/validate.d.ts.map +1 -0
- package/dist/utils/createSynapse/validate.js +76 -0
- package/dist/utils/createSynapse/validate.js.map +1 -0
- package/dist/utils/createSynapse/waitForDependencies.d.ts +3 -0
- package/dist/utils/createSynapse/waitForDependencies.d.ts.map +1 -0
- package/dist/utils/createSynapse/waitForDependencies.js +40 -0
- package/dist/utils/createSynapse/waitForDependencies.js.map +1 -0
- package/dist/utils/createSynapseAwaiter.d.ts +46 -0
- package/dist/utils/createSynapseAwaiter.d.ts.map +1 -0
- package/dist/utils/createSynapseAwaiter.js +102 -0
- package/dist/utils/createSynapseAwaiter.js.map +1 -0
- package/dist/utils/index.d.ts +4 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +12 -0
- package/dist/utils/index.js.map +1 -0
- package/package.json +17 -21
- package/dist/api.d.ts +0 -365
- package/dist/api.js +0 -1
- package/dist/core.d.ts +0 -106
- package/dist/core.js +0 -1
- package/dist/createSynapse-vkfKjRob.d.ts +0 -97
- package/dist/dispatcher.module-BOsMHbD5.d.ts +0 -360
- package/dist/react.d.ts +0 -119
- package/dist/react.js +0 -1
- package/dist/reactive.d.ts +0 -35
- package/dist/reactive.js +0 -1
- package/dist/storage.interface-BA_ktyDz.d.ts +0 -591
- package/dist/utils.d.ts +0 -139
- package/dist/utils.js +0 -1
|
@@ -0,0 +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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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/reactive/dispatcher/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAA;AACnC,cAAc,eAAe,CAAA;AAC7B,cAAc,cAAc,CAAA"}
|
|
@@ -0,0 +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":";;;AAAmC;AACN;AACD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/reactive/dispatcher/middlewares/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reactive/dispatcher/middlewares/index.js","sources":["../../../../src/reactive/dispatcher/middlewares/index.ts"],"sourcesContent":["export * from './logger.middleware'\n"],"names":[],"mappings":";AAAmC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { EnhancedMiddleware } from '../dispatcher.module';
|
|
2
|
+
interface LoggerTranslations {
|
|
3
|
+
action: string;
|
|
4
|
+
prevState: string;
|
|
5
|
+
nextState: string;
|
|
6
|
+
duration: string;
|
|
7
|
+
error: string;
|
|
8
|
+
diff: string;
|
|
9
|
+
changesCount: string;
|
|
10
|
+
showFullState: string;
|
|
11
|
+
}
|
|
12
|
+
interface LoggerColors {
|
|
13
|
+
title: string;
|
|
14
|
+
prevState: string;
|
|
15
|
+
fullState: string;
|
|
16
|
+
action: string;
|
|
17
|
+
nextState: string;
|
|
18
|
+
error: string;
|
|
19
|
+
diff: string;
|
|
20
|
+
}
|
|
21
|
+
interface LoggerOptions {
|
|
22
|
+
collapsed?: boolean;
|
|
23
|
+
duration?: boolean;
|
|
24
|
+
diff?: boolean;
|
|
25
|
+
showFullState?: boolean;
|
|
26
|
+
translations?: Partial<LoggerTranslations>;
|
|
27
|
+
colors?: Partial<LoggerColors>;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Dev-only middleware для логирования действий dispatcher'а.
|
|
31
|
+
*
|
|
32
|
+
* **Внимание:** вызывает `getState()` дважды (до и после действия) для получения prev/next состояния.
|
|
33
|
+
* Это добавляет overhead и не рекомендуется для production. Используйте только в dev-окружении.
|
|
34
|
+
*/
|
|
35
|
+
export declare const loggerDispatcherMiddleware: <State extends Record<string, any>>(options?: LoggerOptions) => EnhancedMiddleware<State>;
|
|
36
|
+
export {};
|
|
37
|
+
//# sourceMappingURL=logger.middleware.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.middleware.d.ts","sourceRoot":"","sources":["../../../../src/reactive/dispatcher/middlewares/logger.middleware.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AAE9D,UAAU,kBAAkB;IAC1B,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,YAAY,EAAE,MAAM,CAAA;IACpB,aAAa,EAAE,MAAM,CAAA;CACtB;AAED,UAAU,YAAY;IACpB,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;CACb;AAED,UAAU,aAAa;IACrB,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,YAAY,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,CAAA;IAC1C,MAAM,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAA;CAC/B;AAyED;;;;;GAKG;AACH,eAAO,MAAM,0BAA0B,GAAI,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,UAAS,aAAkB,KAAG,kBAAkB,CAAC,KAAK,CAuGnI,CAAA"}
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import { loggerConsole } from "../../../_utils/index.js";
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
// Определяем типы для переводов и опций
|
|
5
|
+
|
|
6
|
+
// Функция для вычисления разницы между двумя объектами состояния
|
|
7
|
+
const MAX_DIFF_DEPTH = 10;
|
|
8
|
+
function getStateDiff(prevState, nextState, seen = new WeakSet(), depth = 0) {
|
|
9
|
+
// Guard для null/undefined
|
|
10
|
+
if (prevState == null && nextState == null) return {};
|
|
11
|
+
if (prevState == null) return {
|
|
12
|
+
_root: {
|
|
13
|
+
PREV: prevState,
|
|
14
|
+
NEXT: nextState
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
if (nextState == null) return {
|
|
18
|
+
_root: {
|
|
19
|
+
PREV: prevState,
|
|
20
|
+
NEXT: nextState
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
// Лимит глубины рекурсии
|
|
24
|
+
if (depth >= MAX_DIFF_DEPTH) {
|
|
25
|
+
return prevState !== nextState ? {
|
|
26
|
+
_truncated: {
|
|
27
|
+
PREV: '[max depth]',
|
|
28
|
+
NEXT: '[max depth]'
|
|
29
|
+
}
|
|
30
|
+
} : {};
|
|
31
|
+
}
|
|
32
|
+
// Защита от циклических ссылок
|
|
33
|
+
if (typeof prevState === 'object') {
|
|
34
|
+
if (seen.has(prevState)) return {
|
|
35
|
+
_circular: '[circular reference]'
|
|
36
|
+
};
|
|
37
|
+
seen.add(prevState);
|
|
38
|
+
}
|
|
39
|
+
if (typeof nextState === 'object') {
|
|
40
|
+
if (seen.has(nextState)) return {
|
|
41
|
+
_circular: '[circular reference]'
|
|
42
|
+
};
|
|
43
|
+
seen.add(nextState);
|
|
44
|
+
}
|
|
45
|
+
const diff = {};
|
|
46
|
+
// Проверяем изменения в свойствах верхнего уровня
|
|
47
|
+
const allKeys = [
|
|
48
|
+
...new Set([
|
|
49
|
+
...Object.keys(prevState),
|
|
50
|
+
...Object.keys(nextState)
|
|
51
|
+
])
|
|
52
|
+
];
|
|
53
|
+
allKeys.forEach((key)=>{
|
|
54
|
+
// Если ключ существует в обоих состояниях
|
|
55
|
+
if (key in prevState && key in nextState) {
|
|
56
|
+
// Если это объекты, рекурсивно проверяем их
|
|
57
|
+
if (typeof prevState[key] === 'object' && prevState[key] !== null && typeof nextState[key] === 'object' && nextState[key] !== null && !Array.isArray(prevState[key]) && !Array.isArray(nextState[key])) {
|
|
58
|
+
const nestedDiff = getStateDiff(prevState[key], nextState[key], seen, depth + 1);
|
|
59
|
+
if (Object.keys(nestedDiff).length > 0) {
|
|
60
|
+
diff[key] = nestedDiff;
|
|
61
|
+
}
|
|
62
|
+
} else if (prevState[key] !== nextState[key]) {
|
|
63
|
+
try {
|
|
64
|
+
if (JSON.stringify(prevState[key]) !== JSON.stringify(nextState[key])) {
|
|
65
|
+
diff[key] = {
|
|
66
|
+
PREV: prevState[key],
|
|
67
|
+
NEXT: nextState[key]
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
} catch {
|
|
71
|
+
// JSON.stringify может упасть на циклических ссылках внутри значений
|
|
72
|
+
diff[key] = {
|
|
73
|
+
PREV: prevState[key],
|
|
74
|
+
NEXT: nextState[key]
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
} else if (key in prevState) {
|
|
79
|
+
diff[key] = {
|
|
80
|
+
PREV: prevState[key],
|
|
81
|
+
NEXT: undefined
|
|
82
|
+
};
|
|
83
|
+
} else {
|
|
84
|
+
diff[key] = {
|
|
85
|
+
PREV: undefined,
|
|
86
|
+
NEXT: nextState[key]
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
return diff;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Dev-only middleware для логирования действий dispatcher'а.
|
|
94
|
+
*
|
|
95
|
+
* **Внимание:** вызывает `getState()` дважды (до и после действия) для получения prev/next состояния.
|
|
96
|
+
* Это добавляет overhead и не рекомендуется для production. Используйте только в dev-окружении.
|
|
97
|
+
*/ const loggerDispatcherMiddleware = (options = {})=>{
|
|
98
|
+
const defaultTranslations = {
|
|
99
|
+
action: 'Действие',
|
|
100
|
+
prevState: 'Предыдущее состояние',
|
|
101
|
+
nextState: 'Следующее состояние',
|
|
102
|
+
duration: 'Длительность',
|
|
103
|
+
error: 'Ошибка в действии',
|
|
104
|
+
diff: 'Изменения',
|
|
105
|
+
changesCount: 'Количество изменений',
|
|
106
|
+
showFullState: 'Полное состояние'
|
|
107
|
+
};
|
|
108
|
+
const defaultOptions = {
|
|
109
|
+
collapsed: false,
|
|
110
|
+
duration: true,
|
|
111
|
+
diff: false,
|
|
112
|
+
showFullState: true,
|
|
113
|
+
translations: defaultTranslations,
|
|
114
|
+
colors: {
|
|
115
|
+
title: '#3498db',
|
|
116
|
+
prevState: '#9E9E9E',
|
|
117
|
+
fullState: '#008a15',
|
|
118
|
+
action: '#03A9F4',
|
|
119
|
+
nextState: '#4CAF50',
|
|
120
|
+
error: '#F20404',
|
|
121
|
+
diff: '#9C27B0'
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
// Объединяем пользовательские настройки с настройками по умолчанию
|
|
125
|
+
const mergedOptions = {
|
|
126
|
+
...defaultOptions,
|
|
127
|
+
...options,
|
|
128
|
+
// Объединяем переводы отдельно, чтобы позволить частичное переопределение
|
|
129
|
+
translations: {
|
|
130
|
+
...defaultTranslations,
|
|
131
|
+
...options.translations || {}
|
|
132
|
+
},
|
|
133
|
+
// Объединяем цвета отдельно, чтобы позволить частичное переопределение
|
|
134
|
+
colors: {
|
|
135
|
+
...defaultOptions.colors,
|
|
136
|
+
...options.colors || {}
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
const { collapsed, duration, colors, translations } = mergedOptions;
|
|
140
|
+
return (api)=>(next)=>async (action)=>{
|
|
141
|
+
// Собираем информацию перед выполнением
|
|
142
|
+
const started = Date.now();
|
|
143
|
+
const prevState = await api.getState();
|
|
144
|
+
// Выполняем действие без группировки логов
|
|
145
|
+
try {
|
|
146
|
+
// Выполняем действие
|
|
147
|
+
const result = await next(action);
|
|
148
|
+
// Собираем информацию после выполнения
|
|
149
|
+
const nextState = await api.getState();
|
|
150
|
+
const ended = Date.now();
|
|
151
|
+
const time = ended - started;
|
|
152
|
+
// Теперь выводим всю информацию в группе
|
|
153
|
+
const title = `${action.type}`;
|
|
154
|
+
const groupMethod = collapsed ? loggerConsole.groupCollapsed : loggerConsole.group;
|
|
155
|
+
groupMethod(`%c ${title}`, `color: ${colors.title}; font-weight: bold`);
|
|
156
|
+
// Выводим информацию о действии
|
|
157
|
+
loggerConsole.log(`%c ${translations.action}:`, `color: ${colors.action}; font-weight: bold`, action);
|
|
158
|
+
// Если включена опция diff, вычисляем и показываем изменения
|
|
159
|
+
if (mergedOptions.diff) {
|
|
160
|
+
const stateDiff = getStateDiff(prevState, nextState);
|
|
161
|
+
const changesCount = Object.keys(stateDiff).length;
|
|
162
|
+
loggerConsole.log(`%c ${translations.diff} (${translations.changesCount}: ${changesCount}):`, `color: ${colors.diff}; font-weight: bold`, stateDiff);
|
|
163
|
+
}
|
|
164
|
+
// Если showFullState включен, показываем полные состояния
|
|
165
|
+
if (mergedOptions.showFullState) {
|
|
166
|
+
// Создаем подгруппу для полного состояния
|
|
167
|
+
loggerConsole.groupCollapsed(`%c ${translations.showFullState}`, `color: ${colors.fullState}; font-weight: bold`);
|
|
168
|
+
loggerConsole.log(`%c ${translations.prevState}:`, `color: ${colors.prevState}; font-weight: bold`, prevState);
|
|
169
|
+
loggerConsole.log(`%c ${translations.nextState}:`, `color: ${colors.nextState}; font-weight: bold`, nextState);
|
|
170
|
+
loggerConsole.groupEnd();
|
|
171
|
+
}
|
|
172
|
+
if (duration) {
|
|
173
|
+
loggerConsole.log(`%c ${translations.duration}: %c ${time}ms`, 'font-weight: bold', 'color: #4CAF50');
|
|
174
|
+
}
|
|
175
|
+
loggerConsole.groupEnd();
|
|
176
|
+
return result;
|
|
177
|
+
} catch (error) {
|
|
178
|
+
// В случае ошибки логируем её отдельно, не в группе
|
|
179
|
+
loggerConsole.error(`%c ${translations.error}:`, `color: ${colors.error}; font-weight: bold`, action.type, error);
|
|
180
|
+
// Пробрасываем ошибку дальше
|
|
181
|
+
throw error;
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
export { loggerDispatcherMiddleware };
|
|
187
|
+
|
|
188
|
+
//# sourceMappingURL=logger.middleware.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reactive/dispatcher/middlewares/logger.middleware.js","sources":["../../../../src/reactive/dispatcher/middlewares/logger.middleware.ts"],"sourcesContent":["// Определяем типы для переводов и опций\nimport { loggerConsole } from '../../../_utils'\nimport type { EnhancedMiddleware } from '../dispatcher.module'\n\ninterface LoggerTranslations {\n action: string\n prevState: string\n nextState: string\n duration: string\n error: string\n diff: string\n changesCount: string\n showFullState: string\n}\n\ninterface LoggerColors {\n title: string\n prevState: string\n fullState: string\n action: string\n nextState: string\n error: string\n diff: string\n}\n\ninterface LoggerOptions {\n collapsed?: boolean\n duration?: boolean\n diff?: boolean\n showFullState?: boolean\n translations?: Partial<LoggerTranslations>\n colors?: Partial<LoggerColors>\n}\n\n// Функция для вычисления разницы между двумя объектами состояния\nconst MAX_DIFF_DEPTH = 10\n\nfunction getStateDiff(prevState: any, nextState: any, seen = new WeakSet(), depth = 0): { [key: string]: any } {\n // Guard для null/undefined\n if (prevState == null && nextState == null) return {}\n if (prevState == null) return { _root: { PREV: prevState, NEXT: nextState } }\n if (nextState == null) return { _root: { PREV: prevState, NEXT: nextState } }\n\n // Лимит глубины рекурсии\n if (depth >= MAX_DIFF_DEPTH) {\n return prevState !== nextState ? { _truncated: { PREV: '[max depth]', NEXT: '[max depth]' } } : {}\n }\n\n // Защита от циклических ссылок\n if (typeof prevState === 'object') {\n if (seen.has(prevState)) return { _circular: '[circular reference]' }\n seen.add(prevState)\n }\n if (typeof nextState === 'object') {\n if (seen.has(nextState)) return { _circular: '[circular reference]' }\n seen.add(nextState)\n }\n\n const diff: { [key: string]: any } = {}\n\n // Проверяем изменения в свойствах верхнего уровня\n const allKeys = [...new Set([...Object.keys(prevState), ...Object.keys(nextState)])]\n\n allKeys.forEach((key) => {\n // Если ключ существует в обоих состояниях\n if (key in prevState && key in nextState) {\n // Если это объекты, рекурсивно проверяем их\n if (\n typeof prevState[key] === 'object' &&\n prevState[key] !== null &&\n typeof nextState[key] === 'object' &&\n nextState[key] !== null &&\n !Array.isArray(prevState[key]) &&\n !Array.isArray(nextState[key])\n ) {\n const nestedDiff = getStateDiff(prevState[key], nextState[key], seen, depth + 1)\n if (Object.keys(nestedDiff).length > 0) {\n diff[key] = nestedDiff\n }\n }\n // Для массивов и примитивов просто сравниваем значения\n else if (prevState[key] !== nextState[key]) {\n try {\n if (JSON.stringify(prevState[key]) !== JSON.stringify(nextState[key])) {\n diff[key] = { PREV: prevState[key], NEXT: nextState[key] }\n }\n } catch {\n // JSON.stringify может упасть на циклических ссылках внутри значений\n diff[key] = { PREV: prevState[key], NEXT: nextState[key] }\n }\n }\n }\n // Если ключ существует только в предыдущем состоянии\n else if (key in prevState) {\n diff[key] = { PREV: prevState[key], NEXT: undefined }\n }\n // Если ключ существует только в новом состоянии\n else {\n diff[key] = { PREV: undefined, NEXT: nextState[key] }\n }\n })\n\n return diff\n}\n\n/**\n * Dev-only middleware для логирования действий dispatcher'а.\n *\n * **Внимание:** вызывает `getState()` дважды (до и после действия) для получения prev/next состояния.\n * Это добавляет overhead и не рекомендуется для production. Используйте только в dev-окружении.\n */\nexport const loggerDispatcherMiddleware = <State extends Record<string, any>>(options: LoggerOptions = {}): EnhancedMiddleware<State> => {\n const defaultTranslations = {\n action: 'Действие',\n prevState: 'Предыдущее состояние',\n nextState: 'Следующее состояние',\n duration: 'Длительность',\n error: 'Ошибка в действии',\n diff: 'Изменения',\n changesCount: 'Количество изменений',\n showFullState: 'Полное состояние',\n }\n\n const defaultOptions = {\n collapsed: false,\n duration: true,\n diff: false,\n showFullState: true, // Показывать полное состояние по умолчанию\n translations: defaultTranslations,\n colors: {\n title: '#3498db',\n prevState: '#9E9E9E',\n fullState: '#008a15',\n action: '#03A9F4',\n nextState: '#4CAF50',\n error: '#F20404',\n diff: '#9C27B0',\n },\n }\n\n // Объединяем пользовательские настройки с настройками по умолчанию\n const mergedOptions = {\n ...defaultOptions,\n ...options,\n // Объединяем переводы отдельно, чтобы позволить частичное переопределение\n translations: {\n ...defaultTranslations,\n ...(options.translations || {}),\n },\n // Объединяем цвета отдельно, чтобы позволить частичное переопределение\n colors: {\n ...defaultOptions.colors,\n ...(options.colors || {}),\n },\n }\n\n const { collapsed, duration, colors, translations } = mergedOptions\n\n return (api) => (next) => async (action) => {\n // Собираем информацию перед выполнением\n const started = Date.now()\n const prevState = await api.getState()\n\n // Выполняем действие без группировки логов\n try {\n // Выполняем действие\n const result = await next(action)\n\n // Собираем информацию после выполнения\n const nextState = await api.getState()\n const ended = Date.now()\n const time = ended - started\n\n // Теперь выводим всю информацию в группе\n const title = `${action.type}`\n const groupMethod = collapsed ? loggerConsole.groupCollapsed : loggerConsole.group\n\n groupMethod(`%c ${title}`, `color: ${colors.title}; font-weight: bold`)\n\n // Выводим информацию о действии\n loggerConsole.log(`%c ${translations.action}:`, `color: ${colors.action}; font-weight: bold`, action)\n\n // Если включена опция diff, вычисляем и показываем изменения\n if (mergedOptions.diff) {\n const stateDiff = getStateDiff(prevState, nextState)\n const changesCount = Object.keys(stateDiff).length\n\n loggerConsole.log(`%c ${translations.diff} (${translations.changesCount}: ${changesCount}):`, `color: ${colors.diff}; font-weight: bold`, stateDiff)\n }\n\n // Если showFullState включен, показываем полные состояния\n if (mergedOptions.showFullState) {\n // Создаем подгруппу для полного состояния\n loggerConsole.groupCollapsed(`%c ${translations.showFullState}`, `color: ${colors.fullState}; font-weight: bold`)\n loggerConsole.log(`%c ${translations.prevState}:`, `color: ${colors.prevState}; font-weight: bold`, prevState)\n loggerConsole.log(`%c ${translations.nextState}:`, `color: ${colors.nextState}; font-weight: bold`, nextState)\n loggerConsole.groupEnd()\n }\n\n if (duration) {\n loggerConsole.log(`%c ${translations.duration}: %c ${time}ms`, 'font-weight: bold', 'color: #4CAF50')\n }\n\n loggerConsole.groupEnd()\n\n return result\n } catch (error) {\n // В случае ошибки логируем её отдельно, не в группе\n loggerConsole.error(`%c ${translations.error}:`, `color: ${colors.error}; font-weight: bold`, action.type, error)\n\n // Пробрасываем ошибку дальше\n throw error\n }\n }\n}\n"],"names":["loggerConsole","MAX_DIFF_DEPTH","getStateDiff","prevState","nextState","seen","WeakSet","depth","diff","allKeys","Set","Object","key","Array","nestedDiff","JSON","undefined","loggerDispatcherMiddleware","options","defaultTranslations","defaultOptions","mergedOptions","collapsed","duration","colors","translations","api","next","action","started","Date","result","ended","time","title","groupMethod","stateDiff","changesCount","error"],"mappings":"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"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import type { IStorage } from '../../core';
|
|
2
|
+
/**
|
|
3
|
+
* Параметры исполнения действия (мемоизация)
|
|
4
|
+
*/
|
|
5
|
+
export interface ActionExecutionOptions<TParams, TResult> {
|
|
6
|
+
memoize?: (currentArgs: TParams, previousArgs: TParams, previousResult: TResult) => boolean;
|
|
7
|
+
}
|
|
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
|
+
/**
|
|
33
|
+
* Состояние API-запроса для createApiActions
|
|
34
|
+
*/
|
|
35
|
+
export interface ApiRequestState {
|
|
36
|
+
status: 'idle' | 'loading' | 'success' | 'error' | 'reset';
|
|
37
|
+
error: string | null;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Создаёт standalone-определение действия.
|
|
41
|
+
* Фиксирует TState через первый вызов, TParams/TResult инферятся из action.
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```ts
|
|
45
|
+
* const action = defineAction<MyState>()
|
|
46
|
+
*
|
|
47
|
+
* export const increment = action({
|
|
48
|
+
* action: (storage, amount: number) => {
|
|
49
|
+
* storage.update((s) => { s.count += amount })
|
|
50
|
+
* return amount
|
|
51
|
+
* },
|
|
52
|
+
* })
|
|
53
|
+
*
|
|
54
|
+
* // Void action (без параметров и возврата):
|
|
55
|
+
* export const reset = action({
|
|
56
|
+
* action: (storage) => {
|
|
57
|
+
* storage.update((s) => { s.count = 0 })
|
|
58
|
+
* },
|
|
59
|
+
* })
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
62
|
+
export declare function defineAction<TState extends Record<string, any>>(): <TParams = void, TResult = void>(config: {
|
|
63
|
+
action: (storage: IStorage<TState>, params: TParams) => Promise<TResult> | TResult;
|
|
64
|
+
meta?: Record<string, any>;
|
|
65
|
+
}, executionOptions?: ActionExecutionOptions<TParams, TResult>) => ActionRecipe<TState, TParams, TResult>;
|
|
66
|
+
/**
|
|
67
|
+
* Создаёт standalone-определение watcher'а.
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* ```ts
|
|
71
|
+
* export const watchCount = defineWatcher<MyState>()({
|
|
72
|
+
* selector: (s) => s.items.length,
|
|
73
|
+
* notifyAfterSubscribe: true,
|
|
74
|
+
* })
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
77
|
+
export declare function defineWatcher<TState extends Record<string, any>>(): <R>(config: {
|
|
78
|
+
selector: (state: TState) => R;
|
|
79
|
+
meta?: Record<string, any>;
|
|
80
|
+
shouldTrigger?: (prev: R | undefined, current: R) => boolean;
|
|
81
|
+
notifyAfterSubscribe?: boolean;
|
|
82
|
+
}) => WatcherRecipe<TState, R>;
|
|
83
|
+
/**
|
|
84
|
+
* Создаёт набор шаблонных lifecycle-действий для API-запроса.
|
|
85
|
+
* Accessor указывает на поле ApiRequestState в стейте — путь вычисляется автоматически.
|
|
86
|
+
*
|
|
87
|
+
* @param accessor - Функция-accessor, указывающая на поле ApiRequestState в стейте
|
|
88
|
+
*
|
|
89
|
+
* @example
|
|
90
|
+
* ```ts
|
|
91
|
+
* const listRequest = createApiActions<MyState>(
|
|
92
|
+
* (draft) => draft.api.listRequest
|
|
93
|
+
* )
|
|
94
|
+
*
|
|
95
|
+
* // В dispatcher:
|
|
96
|
+
* createDispatcher({ storage }, {
|
|
97
|
+
* loadListInit: listRequest.init,
|
|
98
|
+
* loadListLoading: listRequest.loading,
|
|
99
|
+
* loadListSuccess: listRequest.success,
|
|
100
|
+
* loadListFailure: listRequest.failure,
|
|
101
|
+
* loadListReset: listRequest.reset,
|
|
102
|
+
* })
|
|
103
|
+
* ```
|
|
104
|
+
*/
|
|
105
|
+
export declare function createApiActions<TState extends Record<string, any>>(accessor: (draft: TState) => ApiRequestState): {
|
|
106
|
+
init: ActionRecipe<TState, void, void>;
|
|
107
|
+
loading: ActionRecipe<TState, void, void>;
|
|
108
|
+
success: ActionRecipe<TState, void, void>;
|
|
109
|
+
failure: ActionRecipe<TState, string, void>;
|
|
110
|
+
reset: ActionRecipe<TState, void, void>;
|
|
111
|
+
};
|
|
112
|
+
//# sourceMappingURL=standalone.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"standalone.d.ts","sourceRoot":"","sources":["../../../src/reactive/dispatcher/standalone.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
// ────────────────────────────────────────────────────────────────────────────
|
|
2
|
+
// defineAction
|
|
3
|
+
// ────────────────────────────────────────────────────────────────────────────
|
|
4
|
+
/**
|
|
5
|
+
* Создаёт standalone-определение действия.
|
|
6
|
+
* Фиксирует TState через первый вызов, TParams/TResult инферятся из action.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* const action = defineAction<MyState>()
|
|
11
|
+
*
|
|
12
|
+
* export const increment = action({
|
|
13
|
+
* action: (storage, amount: number) => {
|
|
14
|
+
* storage.update((s) => { s.count += amount })
|
|
15
|
+
* return amount
|
|
16
|
+
* },
|
|
17
|
+
* })
|
|
18
|
+
*
|
|
19
|
+
* // Void action (без параметров и возврата):
|
|
20
|
+
* export const reset = action({
|
|
21
|
+
* action: (storage) => {
|
|
22
|
+
* storage.update((s) => { s.count = 0 })
|
|
23
|
+
* },
|
|
24
|
+
* })
|
|
25
|
+
* ```
|
|
26
|
+
*/ function defineAction() {
|
|
27
|
+
return (config, executionOptions)=>({
|
|
28
|
+
_type: 'action-recipe',
|
|
29
|
+
_config: config,
|
|
30
|
+
_executionOptions: executionOptions
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
// ────────────────────────────────────────────────────────────────────────────
|
|
34
|
+
// defineWatcher
|
|
35
|
+
// ────────────────────────────────────────────────────────────────────────────
|
|
36
|
+
/**
|
|
37
|
+
* Создаёт standalone-определение watcher'а.
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```ts
|
|
41
|
+
* export const watchCount = defineWatcher<MyState>()({
|
|
42
|
+
* selector: (s) => s.items.length,
|
|
43
|
+
* notifyAfterSubscribe: true,
|
|
44
|
+
* })
|
|
45
|
+
* ```
|
|
46
|
+
*/ function defineWatcher() {
|
|
47
|
+
return (config)=>({
|
|
48
|
+
_type: 'watcher-recipe',
|
|
49
|
+
_config: config
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
// ────────────────────────────────────────────────────────────────────────────
|
|
53
|
+
// createApiActions
|
|
54
|
+
// ────────────────────────────────────────────────────────────────────────────
|
|
55
|
+
/**
|
|
56
|
+
* Вычисляет путь к свойству через Proxy-перехват обращений.
|
|
57
|
+
*/ function resolvePath(accessor) {
|
|
58
|
+
const path = [];
|
|
59
|
+
const handler = {
|
|
60
|
+
get (_, prop) {
|
|
61
|
+
if (typeof prop === 'string') {
|
|
62
|
+
path.push(prop);
|
|
63
|
+
}
|
|
64
|
+
return new Proxy({}, handler);
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
accessor(new Proxy({}, handler));
|
|
68
|
+
return path;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Записывает значение по пути в объекте.
|
|
72
|
+
*/ function setByPath(obj, path, value) {
|
|
73
|
+
let current = obj;
|
|
74
|
+
for(let i = 0; i < path.length - 1; i++){
|
|
75
|
+
current = current[path[i]];
|
|
76
|
+
}
|
|
77
|
+
current[path[path.length - 1]] = value;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Создаёт набор шаблонных lifecycle-действий для API-запроса.
|
|
81
|
+
* Accessor указывает на поле ApiRequestState в стейте — путь вычисляется автоматически.
|
|
82
|
+
*
|
|
83
|
+
* @param accessor - Функция-accessor, указывающая на поле ApiRequestState в стейте
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* ```ts
|
|
87
|
+
* const listRequest = createApiActions<MyState>(
|
|
88
|
+
* (draft) => draft.api.listRequest
|
|
89
|
+
* )
|
|
90
|
+
*
|
|
91
|
+
* // В dispatcher:
|
|
92
|
+
* createDispatcher({ storage }, {
|
|
93
|
+
* loadListInit: listRequest.init,
|
|
94
|
+
* loadListLoading: listRequest.loading,
|
|
95
|
+
* loadListSuccess: listRequest.success,
|
|
96
|
+
* loadListFailure: listRequest.failure,
|
|
97
|
+
* loadListReset: listRequest.reset,
|
|
98
|
+
* })
|
|
99
|
+
* ```
|
|
100
|
+
*/ function createApiActions(accessor) {
|
|
101
|
+
const path = resolvePath(accessor);
|
|
102
|
+
const action = defineAction();
|
|
103
|
+
const update = (storage, request)=>{
|
|
104
|
+
storage.update((s)=>setByPath(s, path, request));
|
|
105
|
+
};
|
|
106
|
+
return {
|
|
107
|
+
init: action({
|
|
108
|
+
action: (storage)=>update(storage, {
|
|
109
|
+
status: 'idle',
|
|
110
|
+
error: null
|
|
111
|
+
})
|
|
112
|
+
}),
|
|
113
|
+
loading: action({
|
|
114
|
+
action: (storage)=>update(storage, {
|
|
115
|
+
status: 'loading',
|
|
116
|
+
error: null
|
|
117
|
+
})
|
|
118
|
+
}),
|
|
119
|
+
success: action({
|
|
120
|
+
action: (storage)=>update(storage, {
|
|
121
|
+
status: 'success',
|
|
122
|
+
error: null
|
|
123
|
+
})
|
|
124
|
+
}),
|
|
125
|
+
failure: action({
|
|
126
|
+
action: (storage, error)=>update(storage, {
|
|
127
|
+
status: 'error',
|
|
128
|
+
error
|
|
129
|
+
})
|
|
130
|
+
}),
|
|
131
|
+
reset: action({
|
|
132
|
+
action: (storage)=>update(storage, {
|
|
133
|
+
status: 'reset',
|
|
134
|
+
error: null
|
|
135
|
+
})
|
|
136
|
+
})
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export { createApiActions, defineAction, defineWatcher };
|
|
141
|
+
|
|
142
|
+
//# sourceMappingURL=standalone.js.map
|