synapse-storage 3.0.3 → 3.0.5

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.
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/react/index.ts","../src/react/hooks/useSelector.ts","../src/react/hooks/useStorageSubscribe.ts","../src/react/utils/createSynapseCtx.tsx","../src/_utils/deepMerge.util.ts"],"sourcesContent":["export * from './hooks'\nexport * from './utils'\n","import { useEffect, useRef, useState } from 'react'\n\nimport type { SelectorAPI } from '../../core'\n\ninterface UseSelectorOptions<T> {\n /** Начальное значение до загрузки данных из селектора */\n initialValue?: T\n /** Функция сравнения для предотвращения лишних ререндеров */\n equals?: (a: T, b: T) => boolean\n /** Включать ли статус загрузки в возвращаемый результат */\n withLoading?: boolean\n}\n\n/**\n * Глобальный реестр селекторов с активными подписками.\n * Хранит последние значения селекторов и список callbacks для обновления всех компонентов.\n */\nconst SELECTOR_REGISTRY = new Map<\n string,\n {\n lastValue: any\n listeners: Set<(value: any) => void>\n unsubscribe: VoidFunction | null\n }\n>()\n\n/**\n * Хук для использования селекторов в компонентах React.\n * Обеспечивает согласованность значений между всеми экземплярами хука.\n */\nexport function useSelector<T>(selector: SelectorAPI<T>): T | undefined\nexport function useSelector<T>(selector: SelectorAPI<T>, options: UseSelectorOptions<T> & { withLoading?: true }): { data: T | undefined; isLoading: boolean }\nexport function useSelector<T>(selector: SelectorAPI<T>, options?: UseSelectorOptions<T>): { data: T | undefined; isLoading: boolean } | T | undefined {\n // Базовые состояния\n const [state, setState] = useState<T | undefined>(options?.initialValue)\n const [isLoading, setIsLoading] = useState<boolean>(!!options?.withLoading)\n\n // Для предотвращения лишних ререндеров\n const prevValueRef = useRef<T | undefined>(options?.initialValue)\n const equalsRef = useRef(options?.equals || ((a: T, b: T) => a === b))\n\n // Получаем ID селектора с помощью метода getId()\n const selectorId = selector.getId()\n\n // Обновляем состояние компонента при изменении значения\n const updateComponentState = (newValue: T) => {\n // Сравниваем с предыдущим значением компонента\n if (prevValueRef.current === undefined || !equalsRef.current(newValue, prevValueRef.current)) {\n prevValueRef.current = newValue\n setState(newValue)\n }\n }\n\n useEffect(() => {\n // Создаем запись в реестре, если её ещё нет\n if (!SELECTOR_REGISTRY.has(selectorId)) {\n SELECTOR_REGISTRY.set(selectorId, {\n lastValue: undefined,\n listeners: new Set(),\n unsubscribe: null,\n })\n }\n\n const registry = SELECTOR_REGISTRY.get(selectorId)!\n\n // Добавляем текущий компонент в список слушателей\n registry.listeners.add(updateComponentState)\n\n // Если у нас уже есть значение, сразу устанавливаем его\n if (registry.lastValue !== undefined) {\n updateComponentState(registry.lastValue)\n\n // Если был запрошен режим загрузки, сразу сбрасываем его\n if (options?.withLoading) {\n setIsLoading(false)\n }\n } else {\n // Запрашиваем начальное значение\n if (options?.withLoading) setIsLoading(true)\n\n selector\n .select()\n .then((initialValue) => {\n // Обновляем значение в реестре\n registry.lastValue = initialValue\n\n // Уведомляем все компоненты\n registry.listeners.forEach((listener) => listener(initialValue))\n\n if (options?.withLoading) setIsLoading(false)\n })\n .catch((error) => {\n console.error(`useSelector: Ошибка при получении начального значения для ${selectorId}`, error)\n if (options?.withLoading) setIsLoading(false)\n })\n }\n\n // Создаем подписку только один раз для селектора\n if (!registry.unsubscribe) {\n registry.unsubscribe = selector.subscribe({\n notify: (newValue: T) => {\n // Обновляем значение в реестре\n registry.lastValue = newValue\n\n // Уведомляем все компоненты\n registry.listeners.forEach((listener) => {\n try {\n listener(newValue)\n } catch (error) {\n console.error(`useSelector: Ошибка при уведомлении слушателя для ${selectorId}`, error)\n }\n })\n },\n })\n }\n\n // При размонтировании компонента\n return () => {\n const registry = SELECTOR_REGISTRY.get(selectorId)\n if (registry) {\n // Удаляем текущий компонент из списка слушателей\n registry.listeners.delete(updateComponentState)\n\n // Если больше нет слушателей, можно очистить подписку\n if (registry.listeners.size === 0) {\n if (registry.unsubscribe) {\n registry.unsubscribe()\n }\n SELECTOR_REGISTRY.delete(selectorId)\n }\n }\n }\n }, [selector, selectorId])\n\n // Возвращаем данные в нужном формате\n if (options?.withLoading) {\n return { data: state, isLoading }\n }\n\n return state\n}\n","import { useEffect, useState } from 'react'\n\nimport { IStorage } from '../../core'\n\n/**\n * Хук для подписки на изменения в хранилище\n *\n * @template S - Тип состояния хранилища\n * @template R - Тип возвращаемого значения\n * @param storage - Экземпляр хранилища\n * @param selector - Функция-селектор для выбора данных\n * @returns Значение из хранилища\n */\nexport const useStorageSubscribe = <S extends Record<string, any>, R = any>(storage: IStorage<S>, selector: (state: S) => R): R | undefined => {\n const [value, setValue] = useState<R | undefined>(undefined)\n\n useEffect(() => {\n // Флаг монтирования для предотвращения обновления состояния при размонтировании\n let isMounted = true\n\n const initializeValue = async () => {\n try {\n const state = await storage.getState()\n const selectedValue = selector(state) as R\n\n if (isMounted) {\n setValue(selectedValue)\n }\n } catch (error) {\n console.error('Failed to initialize storage value:', error)\n }\n }\n\n // Инициализируем значение\n initializeValue()\n\n let unsubscribe: VoidFunction\n try {\n unsubscribe = storage.subscribe(selector, (newValue: R) => {\n if (isMounted) {\n setValue(newValue)\n }\n })\n } catch (error) {\n console.error('Failed to subscribe to storage:', error)\n unsubscribe = () => {}\n }\n\n return () => {\n isMounted = false\n unsubscribe()\n }\n }, [storage, selector])\n\n return value\n}\n","import { ComponentType, createContext, PropsWithChildren, useContext, useEffect, useRef, useState } from 'react'\nimport { Observable } from 'rxjs'\n\nimport { deepMerge } from '../../_utils'\nimport { IStorage } from '../../core'\nimport { AnySynapseStore, SynapseStoreBasic, SynapseStoreWithDispatcher, SynapseStoreWithEffects } from '../../utils'\n\nconst ERROR_HOOK_MESSAGE = 'useSynapseActions необходимо использовать внутри компонента contextSynapse'\nconst ERROR_CONTEXT_INIT = 'Ошибка при инициализации контекста:'\n\ninterface Options<TStore extends Record<string, any>> {\n loadingComponent?: any\n mergeFn?: (target: TStore, source: Record<string, any>) => void\n}\n\n/**\n * Перегрузки для createSynapseCtx в зависимости от типа хранилища\n */\n\n// Для хранилища с effects\nexport function createSynapseCtx<TStore extends Record<string, any>, TStorage extends IStorage<TStore>, TSelectors, TActions>(\n synapseStorePromise: Promise<SynapseStoreWithEffects<TStore, TStorage, TSelectors, TActions>> | SynapseStoreWithEffects<TStore, TStorage, TSelectors, TActions>,\n options?: Options<TStore>,\n): {\n contextSynapse: <SelfComponentProps, PublicContextProps = Record<string, any>>(\n Component: ComponentType<SelfComponentProps>,\n ) => ComponentType<SelfComponentProps & { contextProps?: PublicContextProps }>\n useSynapseStorage: () => TStorage\n useSynapseSelectors: () => TSelectors\n useSynapseActions: () => TActions\n useSynapseState$: () => Observable<TStore>\n cleanupSynapse: () => Promise<void>\n}\n\n// Для хранилища с dispatcher (без effects)\nexport function createSynapseCtx<TStore extends Record<string, any>, TStorage extends IStorage<TStore>, TSelectors, TActions>(\n synapseStorePromise: Promise<SynapseStoreWithDispatcher<TStore, TStorage, TSelectors, TActions>> | SynapseStoreWithDispatcher<TStore, TStorage, TSelectors, TActions>,\n options?: Options<TStore>,\n): {\n contextSynapse: <SelfComponentProps, PublicContextProps = Record<string, any>>(\n Component: ComponentType<SelfComponentProps>,\n ) => ComponentType<SelfComponentProps & { contextProps?: PublicContextProps }>\n useSynapseStorage: () => TStorage\n useSynapseSelectors: () => TSelectors\n useSynapseActions: () => TActions\n cleanupSynapse: () => Promise<void>\n}\n\n// Для базового хранилища\nexport function createSynapseCtx<TStore extends Record<string, any>, TStorage extends IStorage<TStore>, TSelectors>(\n synapseStorePromise: Promise<SynapseStoreBasic<TStore, TStorage, TSelectors>> | SynapseStoreBasic<TStore, TStorage, TSelectors>,\n options?: Options<TStore>,\n): {\n contextSynapse: <SelfComponentProps, PublicContextProps = Record<string, any>>(\n Component: ComponentType<SelfComponentProps>,\n ) => ComponentType<SelfComponentProps & { contextProps?: PublicContextProps }>\n useSynapseStorage: () => TStorage\n useSynapseSelectors: () => TSelectors\n cleanupSynapse: () => Promise<void>\n}\n\n// Основная реализация\nexport function createSynapseCtx<TStore extends Record<string, any>, TStorage extends IStorage<TStore>, TSelectors = any, TActions = any>(\n synapseStorePromise: Promise<AnySynapseStore<TStore, TStorage, TSelectors, TActions>> | AnySynapseStore<TStore, TStorage, TSelectors, TActions>,\n options?: Options<TStore>,\n) {\n const { loadingComponent = null, mergeFn = deepMerge } = options || {}\n\n // Храним ссылку на store\n let synapseStore: AnySynapseStore<TStore, TStorage, TSelectors, TActions> | null = null\n\n // Флаг готовности хранилища\n let storeReady = false\n\n // Если передан Promise, начинаем его обработку\n const initPromise = (async () => {\n try {\n synapseStore = await (synapseStorePromise instanceof Promise ? synapseStorePromise : Promise.resolve(synapseStorePromise))\n storeReady = true\n } catch (error) {\n console.error('Ошибка инициализации хранилища Synapse:', error)\n }\n })()\n\n const SynapseContext = createContext<AnySynapseStore<TStore, TStorage, TSelectors, TActions> | null>(null)\n\n const useSynapseStorage = (): TStorage => {\n const context = useContext(SynapseContext)\n if (!context) throw new Error(ERROR_HOOK_MESSAGE)\n\n return context.storage\n }\n\n const useSynapseSelectors = (): TSelectors => {\n const context = useContext(SynapseContext)\n if (!context) throw new Error(ERROR_HOOK_MESSAGE)\n\n return context.selectors\n }\n\n // Условный хук для actions (только если есть dispatcher)\n const useSynapseActions = (): TActions => {\n const context = useContext(SynapseContext)\n if (!context) throw new Error(ERROR_HOOK_MESSAGE)\n\n if ('actions' in context) {\n return (context as SynapseStoreWithDispatcher<TStore, TStorage, TSelectors, TActions> | SynapseStoreWithEffects<TStore, TStorage, TSelectors, TActions>).actions\n }\n\n throw new Error('useSynapseActions: actions недоступны для этого типа хранилища. Убедитесь, что передана функция createDispatcherFn при создании хранилища.')\n }\n\n // Условный хук для state$ (только если есть effects)\n const useSynapseState$ = (): Observable<TStore> => {\n const context = useContext(SynapseContext)\n if (!context) throw new Error(ERROR_HOOK_MESSAGE)\n\n if ('state$' in context) {\n return (context as SynapseStoreWithEffects<TStore, TStorage, TSelectors, TActions>).state$\n }\n\n throw new Error('useSynapseState$: state$ недоступен для этого типа хранилища. Убедитесь, что переданы функции createDispatcherFn и createEffectConfig при создании хранилища.')\n }\n\n /**\n * Декоратор для обертывания компонентов в контекст Synapse\n */\n function contextSynapse<SelfComponentProps, PublicContextProps = Record<string, any>>(Component: ComponentType<SelfComponentProps>) {\n type WrappedComponentProps = SelfComponentProps & { contextProps?: PublicContextProps }\n\n function WrappedComponent({ contextProps, ...props }: WrappedComponentProps) {\n const [initialized, setInitialized] = useState(false)\n const [storeInitialized, setStoreInitialized] = useState(storeReady)\n const debugIdRef = useRef(`synapse-${synapseStore?.storage.name || 'initializing'}`)\n\n // Отслеживаем инициализацию хранилища, если оно еще не готово\n useEffect(() => {\n if (!storeReady) {\n initPromise.then(() => {\n setStoreInitialized(true)\n })\n }\n }, [])\n\n // Инициализируем контекст при монтировании компонента\n useEffect(() => {\n // Не начинаем инициализацию контекста, пока хранилище не готово\n if (!storeInitialized) return\n\n let mounted = true\n\n const initializeContext = async () => {\n try {\n if (synapseStore && contextProps && Object.keys(contextProps).length > 0) {\n await synapseStore.storage.update((state) => {\n mergeFn(state, contextProps)\n })\n }\n\n if (mounted) {\n setInitialized(true)\n }\n } catch (error) {\n console.error(`[${debugIdRef.current}] ${ERROR_CONTEXT_INIT}`, error)\n }\n }\n\n initializeContext()\n\n return () => {\n mounted = false\n }\n }, [contextProps, storeInitialized])\n\n // Проверяем инициализацию хранилища и контекста\n if (!storeInitialized) {\n return loadingComponent || <div>Загрузка хранилища...</div>\n }\n\n if (!initialized) {\n return loadingComponent || <div>Инициализация контекста...</div>\n }\n\n return (\n <SynapseContext.Provider value={synapseStore}>\n <Component {...(props as PropsWithChildren<SelfComponentProps>)} />\n </SynapseContext.Provider>\n )\n }\n\n // Устанавливаем отображаемое имя для отладки\n const componentName = Component.displayName || Component.name || 'Component'\n WrappedComponent.displayName = `SynapseContext(${componentName})`\n\n return WrappedComponent\n }\n\n const cleanupSynapse = async (): Promise<void> => {\n await initPromise // Ждем завершения инициализации\n return synapseStore?.destroy() || Promise.resolve()\n }\n\n return {\n contextSynapse,\n useSynapseStorage,\n useSynapseSelectors,\n useSynapseActions,\n useSynapseState$,\n cleanupSynapse,\n }\n}\n","export const deepMerge = (target: any, source: any) => {\n for (const key in source) {\n if (Object.prototype.hasOwnProperty.call(source, key)) {\n if (typeof source[key] === 'object' && source[key] !== null && !Array.isArray(source[key])) {\n if (!target[key] || typeof target[key] !== 'object') {\n target[key] = {}\n }\n deepMerge(target[key], source[key])\n } else {\n target[key] = source[key]\n }\n }\n }\n}\n"],"mappings":"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","names":["registry","import_react","import_react"]}
package/dist/react.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/react/hooks/useSelector.ts","../src/react/hooks/useStorageSubscribe.ts","../src/react/utils/createSynapseCtx.tsx","../src/_utils/deepMerge.util.ts"],"sourcesContent":["import { useEffect, useRef, useState } from 'react'\n\nimport type { SelectorAPI } from '../../core'\n\ninterface UseSelectorOptions<T> {\n /** Начальное значение до загрузки данных из селектора */\n initialValue?: T\n /** Функция сравнения для предотвращения лишних ререндеров */\n equals?: (a: T, b: T) => boolean\n /** Включать ли статус загрузки в возвращаемый результат */\n withLoading?: boolean\n}\n\n/**\n * Глобальный реестр селекторов с активными подписками.\n * Хранит последние значения селекторов и список callbacks для обновления всех компонентов.\n */\nconst SELECTOR_REGISTRY = new Map<\n string,\n {\n lastValue: any\n listeners: Set<(value: any) => void>\n unsubscribe: VoidFunction | null\n }\n>()\n\n/**\n * Хук для использования селекторов в компонентах React.\n * Обеспечивает согласованность значений между всеми экземплярами хука.\n */\nexport function useSelector<T>(selector: SelectorAPI<T>): T | undefined\nexport function useSelector<T>(selector: SelectorAPI<T>, options: UseSelectorOptions<T> & { withLoading?: true }): { data: T | undefined; isLoading: boolean }\nexport function useSelector<T>(selector: SelectorAPI<T>, options?: UseSelectorOptions<T>): { data: T | undefined; isLoading: boolean } | T | undefined {\n // Базовые состояния\n const [state, setState] = useState<T | undefined>(options?.initialValue)\n const [isLoading, setIsLoading] = useState<boolean>(!!options?.withLoading)\n\n // Для предотвращения лишних ререндеров\n const prevValueRef = useRef<T | undefined>(options?.initialValue)\n const equalsRef = useRef(options?.equals || ((a: T, b: T) => a === b))\n\n // Получаем ID селектора с помощью метода getId()\n const selectorId = selector.getId()\n\n // Обновляем состояние компонента при изменении значения\n const updateComponentState = (newValue: T) => {\n // Сравниваем с предыдущим значением компонента\n if (prevValueRef.current === undefined || !equalsRef.current(newValue, prevValueRef.current)) {\n prevValueRef.current = newValue\n setState(newValue)\n }\n }\n\n useEffect(() => {\n // Создаем запись в реестре, если её ещё нет\n if (!SELECTOR_REGISTRY.has(selectorId)) {\n SELECTOR_REGISTRY.set(selectorId, {\n lastValue: undefined,\n listeners: new Set(),\n unsubscribe: null,\n })\n }\n\n const registry = SELECTOR_REGISTRY.get(selectorId)!\n\n // Добавляем текущий компонент в список слушателей\n registry.listeners.add(updateComponentState)\n\n // Если у нас уже есть значение, сразу устанавливаем его\n if (registry.lastValue !== undefined) {\n updateComponentState(registry.lastValue)\n\n // Если был запрошен режим загрузки, сразу сбрасываем его\n if (options?.withLoading) {\n setIsLoading(false)\n }\n } else {\n // Запрашиваем начальное значение\n if (options?.withLoading) setIsLoading(true)\n\n selector\n .select()\n .then((initialValue) => {\n // Обновляем значение в реестре\n registry.lastValue = initialValue\n\n // Уведомляем все компоненты\n registry.listeners.forEach((listener) => listener(initialValue))\n\n if (options?.withLoading) setIsLoading(false)\n })\n .catch((error) => {\n console.error(`useSelector: Ошибка при получении начального значения для ${selectorId}`, error)\n if (options?.withLoading) setIsLoading(false)\n })\n }\n\n // Создаем подписку только один раз для селектора\n if (!registry.unsubscribe) {\n registry.unsubscribe = selector.subscribe({\n notify: (newValue: T) => {\n // Обновляем значение в реестре\n registry.lastValue = newValue\n\n // Уведомляем все компоненты\n registry.listeners.forEach((listener) => {\n try {\n listener(newValue)\n } catch (error) {\n console.error(`useSelector: Ошибка при уведомлении слушателя для ${selectorId}`, error)\n }\n })\n },\n })\n }\n\n // При размонтировании компонента\n return () => {\n const registry = SELECTOR_REGISTRY.get(selectorId)\n if (registry) {\n // Удаляем текущий компонент из списка слушателей\n registry.listeners.delete(updateComponentState)\n\n // Если больше нет слушателей, можно очистить подписку\n if (registry.listeners.size === 0) {\n if (registry.unsubscribe) {\n registry.unsubscribe()\n }\n SELECTOR_REGISTRY.delete(selectorId)\n }\n }\n }\n }, [selector, selectorId])\n\n // Возвращаем данные в нужном формате\n if (options?.withLoading) {\n return { data: state, isLoading }\n }\n\n return state\n}\n","import { useEffect, useState } from 'react'\n\nimport { IStorage } from '../../core'\n\n/**\n * Хук для подписки на изменения в хранилище\n *\n * @template S - Тип состояния хранилища\n * @template R - Тип возвращаемого значения\n * @param storage - Экземпляр хранилища\n * @param selector - Функция-селектор для выбора данных\n * @returns Значение из хранилища\n */\nexport const useStorageSubscribe = <S extends Record<string, any>, R = any>(storage: IStorage<S>, selector: (state: S) => R): R | undefined => {\n const [value, setValue] = useState<R | undefined>(undefined)\n\n useEffect(() => {\n // Флаг монтирования для предотвращения обновления состояния при размонтировании\n let isMounted = true\n\n const initializeValue = async () => {\n try {\n const state = await storage.getState()\n const selectedValue = selector(state) as R\n\n if (isMounted) {\n setValue(selectedValue)\n }\n } catch (error) {\n console.error('Failed to initialize storage value:', error)\n }\n }\n\n // Инициализируем значение\n initializeValue()\n\n let unsubscribe: VoidFunction\n try {\n unsubscribe = storage.subscribe(selector, (newValue: R) => {\n if (isMounted) {\n setValue(newValue)\n }\n })\n } catch (error) {\n console.error('Failed to subscribe to storage:', error)\n unsubscribe = () => {}\n }\n\n return () => {\n isMounted = false\n unsubscribe()\n }\n }, [storage, selector])\n\n return value\n}\n","import { ComponentType, createContext, PropsWithChildren, useContext, useEffect, useRef, useState } from 'react'\nimport { Observable } from 'rxjs'\n\nimport { deepMerge } from '../../_utils'\nimport { IStorage } from '../../core'\nimport { AnySynapseStore, SynapseStoreBasic, SynapseStoreWithDispatcher, SynapseStoreWithEffects } from '../../utils'\n\nconst ERROR_HOOK_MESSAGE = 'useSynapseActions необходимо использовать внутри компонента contextSynapse'\nconst ERROR_CONTEXT_INIT = 'Ошибка при инициализации контекста:'\n\ninterface Options<TStore extends Record<string, any>> {\n loadingComponent?: any\n mergeFn?: (target: TStore, source: Record<string, any>) => void\n}\n\n/**\n * Перегрузки для createSynapseCtx в зависимости от типа хранилища\n */\n\n// Для хранилища с effects\nexport function createSynapseCtx<TStore extends Record<string, any>, TStorage extends IStorage<TStore>, TSelectors, TActions>(\n synapseStorePromise: Promise<SynapseStoreWithEffects<TStore, TStorage, TSelectors, TActions>> | SynapseStoreWithEffects<TStore, TStorage, TSelectors, TActions>,\n options?: Options<TStore>,\n): {\n contextSynapse: <SelfComponentProps, PublicContextProps = Record<string, any>>(\n Component: ComponentType<SelfComponentProps>,\n ) => ComponentType<SelfComponentProps & { contextProps?: PublicContextProps }>\n useSynapseStorage: () => TStorage\n useSynapseSelectors: () => TSelectors\n useSynapseActions: () => TActions\n useSynapseState$: () => Observable<TStore>\n cleanupSynapse: () => Promise<void>\n}\n\n// Для хранилища с dispatcher (без effects)\nexport function createSynapseCtx<TStore extends Record<string, any>, TStorage extends IStorage<TStore>, TSelectors, TActions>(\n synapseStorePromise: Promise<SynapseStoreWithDispatcher<TStore, TStorage, TSelectors, TActions>> | SynapseStoreWithDispatcher<TStore, TStorage, TSelectors, TActions>,\n options?: Options<TStore>,\n): {\n contextSynapse: <SelfComponentProps, PublicContextProps = Record<string, any>>(\n Component: ComponentType<SelfComponentProps>,\n ) => ComponentType<SelfComponentProps & { contextProps?: PublicContextProps }>\n useSynapseStorage: () => TStorage\n useSynapseSelectors: () => TSelectors\n useSynapseActions: () => TActions\n cleanupSynapse: () => Promise<void>\n}\n\n// Для базового хранилища\nexport function createSynapseCtx<TStore extends Record<string, any>, TStorage extends IStorage<TStore>, TSelectors>(\n synapseStorePromise: Promise<SynapseStoreBasic<TStore, TStorage, TSelectors>> | SynapseStoreBasic<TStore, TStorage, TSelectors>,\n options?: Options<TStore>,\n): {\n contextSynapse: <SelfComponentProps, PublicContextProps = Record<string, any>>(\n Component: ComponentType<SelfComponentProps>,\n ) => ComponentType<SelfComponentProps & { contextProps?: PublicContextProps }>\n useSynapseStorage: () => TStorage\n useSynapseSelectors: () => TSelectors\n cleanupSynapse: () => Promise<void>\n}\n\n// Основная реализация\nexport function createSynapseCtx<TStore extends Record<string, any>, TStorage extends IStorage<TStore>, TSelectors = any, TActions = any>(\n synapseStorePromise: Promise<AnySynapseStore<TStore, TStorage, TSelectors, TActions>> | AnySynapseStore<TStore, TStorage, TSelectors, TActions>,\n options?: Options<TStore>,\n) {\n const { loadingComponent = null, mergeFn = deepMerge } = options || {}\n\n // Храним ссылку на store\n let synapseStore: AnySynapseStore<TStore, TStorage, TSelectors, TActions> | null = null\n\n // Флаг готовности хранилища\n let storeReady = false\n\n // Если передан Promise, начинаем его обработку\n const initPromise = (async () => {\n try {\n synapseStore = await (synapseStorePromise instanceof Promise ? synapseStorePromise : Promise.resolve(synapseStorePromise))\n storeReady = true\n } catch (error) {\n console.error('Ошибка инициализации хранилища Synapse:', error)\n }\n })()\n\n const SynapseContext = createContext<AnySynapseStore<TStore, TStorage, TSelectors, TActions> | null>(null)\n\n const useSynapseStorage = (): TStorage => {\n const context = useContext(SynapseContext)\n if (!context) throw new Error(ERROR_HOOK_MESSAGE)\n\n return context.storage\n }\n\n const useSynapseSelectors = (): TSelectors => {\n const context = useContext(SynapseContext)\n if (!context) throw new Error(ERROR_HOOK_MESSAGE)\n\n return context.selectors\n }\n\n // Условный хук для actions (только если есть dispatcher)\n const useSynapseActions = (): TActions => {\n const context = useContext(SynapseContext)\n if (!context) throw new Error(ERROR_HOOK_MESSAGE)\n\n if ('actions' in context) {\n return (context as SynapseStoreWithDispatcher<TStore, TStorage, TSelectors, TActions> | SynapseStoreWithEffects<TStore, TStorage, TSelectors, TActions>).actions\n }\n\n throw new Error('useSynapseActions: actions недоступны для этого типа хранилища. Убедитесь, что передана функция createDispatcherFn при создании хранилища.')\n }\n\n // Условный хук для state$ (только если есть effects)\n const useSynapseState$ = (): Observable<TStore> => {\n const context = useContext(SynapseContext)\n if (!context) throw new Error(ERROR_HOOK_MESSAGE)\n\n if ('state$' in context) {\n return (context as SynapseStoreWithEffects<TStore, TStorage, TSelectors, TActions>).state$\n }\n\n throw new Error('useSynapseState$: state$ недоступен для этого типа хранилища. Убедитесь, что переданы функции createDispatcherFn и createEffectConfig при создании хранилища.')\n }\n\n /**\n * Декоратор для обертывания компонентов в контекст Synapse\n */\n function contextSynapse<SelfComponentProps, PublicContextProps = Record<string, any>>(Component: ComponentType<SelfComponentProps>) {\n type WrappedComponentProps = SelfComponentProps & { contextProps?: PublicContextProps }\n\n function WrappedComponent({ contextProps, ...props }: WrappedComponentProps) {\n const [initialized, setInitialized] = useState(false)\n const [storeInitialized, setStoreInitialized] = useState(storeReady)\n const debugIdRef = useRef(`synapse-${synapseStore?.storage.name || 'initializing'}`)\n\n // Отслеживаем инициализацию хранилища, если оно еще не готово\n useEffect(() => {\n if (!storeReady) {\n initPromise.then(() => {\n setStoreInitialized(true)\n })\n }\n }, [])\n\n // Инициализируем контекст при монтировании компонента\n useEffect(() => {\n // Не начинаем инициализацию контекста, пока хранилище не готово\n if (!storeInitialized) return\n\n let mounted = true\n\n const initializeContext = async () => {\n try {\n if (synapseStore && contextProps && Object.keys(contextProps).length > 0) {\n await synapseStore.storage.update((state) => {\n mergeFn(state, contextProps)\n })\n }\n\n if (mounted) {\n setInitialized(true)\n }\n } catch (error) {\n console.error(`[${debugIdRef.current}] ${ERROR_CONTEXT_INIT}`, error)\n }\n }\n\n initializeContext()\n\n return () => {\n mounted = false\n }\n }, [contextProps, storeInitialized])\n\n // Проверяем инициализацию хранилища и контекста\n if (!storeInitialized) {\n return loadingComponent || <div>Загрузка хранилища...</div>\n }\n\n if (!initialized) {\n return loadingComponent || <div>Инициализация контекста...</div>\n }\n\n return (\n <SynapseContext.Provider value={synapseStore}>\n <Component {...(props as PropsWithChildren<SelfComponentProps>)} />\n </SynapseContext.Provider>\n )\n }\n\n // Устанавливаем отображаемое имя для отладки\n const componentName = Component.displayName || Component.name || 'Component'\n WrappedComponent.displayName = `SynapseContext(${componentName})`\n\n return WrappedComponent\n }\n\n const cleanupSynapse = async (): Promise<void> => {\n await initPromise // Ждем завершения инициализации\n return synapseStore?.destroy() || Promise.resolve()\n }\n\n return {\n contextSynapse,\n useSynapseStorage,\n useSynapseSelectors,\n useSynapseActions,\n useSynapseState$,\n cleanupSynapse,\n }\n}\n","export const deepMerge = (target: any, source: any) => {\n for (const key in source) {\n if (Object.prototype.hasOwnProperty.call(source, key)) {\n if (typeof source[key] === 'object' && source[key] !== null && !Array.isArray(source[key])) {\n if (!target[key] || typeof target[key] !== 'object') {\n target[key] = {}\n }\n deepMerge(target[key], source[key])\n } else {\n target[key] = source[key]\n }\n }\n }\n}\n"],"mappings":"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","names":["registry","useEffect","useState","useEffect","useRef","useState","useState","useRef","useEffect"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/reactive/index.ts","../src/reactive/dispatcher/dispatcher.module.ts","../src/reactive/dispatcher/middlewares/logger.middleware.ts","../src/reactive/effects/effects.module.ts","../src/reactive/effects/utils/chunkRequestConsistent.ts","../src/_utils/chunk.util.ts","../src/reactive/effects/utils/chunkRequestParallel.ts"],"sourcesContent":["export * from './dispatcher'\nexport * from './effects'\n","import { Observable, Subject } from 'rxjs'\n\nimport type { IStorage } from '../../core'\nimport { TypedAction } from '../effects'\n\n/**\n * Расширенное API для middleware\n */\nexport interface EnhancedMiddlewareAPI<T extends Record<string, any>> {\n // Базовые возможности\n getState: () => 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// Параметры исполнения функции действия\ninterface ActionExecutionOptions {\n // Веб-воркер для выполнения действия\n worker?: Worker\n // Функция мемоизации\n memoize?: (currentArgs: any[], previousArgs: any[], previousResult: any) => boolean\n}\n\n/**\n * Параметры для создания действия\n */\nexport interface ActionDefinition<TParams, TResult> {\n /** Тип действия для идентификации в потоке и эффектах */\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 type: string\n selector: (state: T) => R\n meta?: Record<string, any>\n // Опционально - функция для определения, изменилось ли значение\n shouldTrigger?: (prev: R | undefined, current: R) => 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, unknown>> = (\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>>\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, TResult>(config: ActionDefinition<TParams, TResult>, executionOptions?: ActionExecutionOptions) => DispatchFunction<TParams, TResult>\n\n/**\n * Тип для функции настройки действий\n */\nexport type ActionsSetup<T extends Record<string, unknown>> = (create: ActionCreatorFactory, storage: IStorage<T>) => Record<string, DispatchFunction<any, any>>\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 */\nexport type DispatchActions<T> = {\n [K in keyof T]: T[K] extends DispatchFunction<any, any> ? T[K] : never\n}\n\n/**\n * Типизированный объект watchers\n */\nexport type WatcherActions<T> = {\n [K in keyof T]: T[K] extends WatcherFunction<any> ? T[K] : never\n}\n\n/**\n * Параметры для Dispatcher\n */\ninterface DispatcherOptions<T extends Record<string, any>> {\n // Хранилище - обязательный параметр\n storage: IStorage<T>\n // Опциональные параметры\n worker?: Worker\n // DispatcherMiddleware для обработки действий\n middlewares?: EnhancedMiddleware<T>[]\n}\n\n/**\n * Интерфейс для API middleware\n */\nexport interface DispatcherMiddlewareAPI<T extends Record<string, any>> {\n getState: () => Promise<T>\n dispatch: (action: Action) => Promise<any>\n}\n\n/**\n * Интерфейс для middleware\n */\nexport interface DispatcherMiddleware<T extends Record<string, any> = any> {\n (api: DispatcherMiddlewareAPI<T>): (next: (action: Action) => Promise<any>) => (action: Action) => Promise<any>\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 // API для инициализации middleware\n private middlewareAPI: EnhancedMiddlewareAPI<T>\n\n /**\n * Создает новый экземпляр Dispatcher\n */\n constructor(private options: DispatcherOptions<T>) {\n this.storage = options.storage\n\n // Создаем API для middleware сразу\n this.middlewareAPI = {\n getState: () => this.storage.getState(),\n dispatch: async (action: Action) => {\n this.actions$.next(action)\n return action.payload\n },\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 console.error(`Error initializing middleware [${i}]:`, error)\n }\n }\n return this\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) => watcher.actionType === actionType)\n }\n\n /**\n * Создает действие\n */\n public createAction<TParams, TResult>(actionConfig: ActionDefinition<TParams, TResult>, executionOptions?: ActionExecutionOptions): DispatchFunction<TParams, TResult> {\n const actionType = `[${this.storage.name}]${actionConfig.type}`\n\n // Для мемоизации храним последние аргументы и результат\n let lastArgs: TParams[] | null = null\n let lastResult: TResult | null = null\n\n // Создаем функцию диспетчеризации\n const dispatchFn = async (params: TParams): Promise<TResult> => {\n const args = [params] as TParams[]\n\n // Проверяем мемоизацию\n if (executionOptions?.memoize && lastArgs && lastResult) {\n if (executionOptions.memoize(args, lastArgs, lastResult)) {\n return lastResult\n }\n }\n\n // Создаем объект действия\n const actionObject: Action<TResult> = {\n type: actionType,\n meta: actionConfig.meta,\n }\n\n // Применяем middleware цепочку\n let result: TResult\n\n if (this.middlewareFunctions.length > 0) {\n // Базовая функция выполнения действия\n // Строим цепочку middleware в обратном порядке\n let chain = async (action: Action): Promise<TResult> => {\n if (executionOptions?.worker) {\n return this.executeInWorker(executionOptions.worker, actionType, args, actionConfig.action)\n } else {\n return Promise.resolve(actionConfig.action(params))\n }\n }\n\n // Проходим по middleware в обратном порядке\n // Важно: сначала создаем всю цепочку, затем выполняем\n for (let i = this.middlewareFunctions.length - 1; i >= 0; i--) {\n const currentMiddleware = this.middlewareFunctions[i]\n const nextChain = chain // Сохраняем предыдущую цепочку\n\n // Создаем новую цепочку, которая вызывает текущий middleware,\n // передавая предыдущую цепочку как функцию next\n chain = async (action: Action) => {\n // Создаем функцию next для передачи в middleware\n const next = async (nextAction: Action) => nextChain(nextAction)\n\n // Получаем обработчик действия и сразу вызываем его\n return currentMiddleware(next)(action)\n }\n }\n\n // Выполняем действие через цепочку middleware\n result = await chain(actionObject)\n } else {\n // Выполняем действие напрямую без middleware\n if (executionOptions?.worker) {\n result = await this.executeInWorker(executionOptions.worker, actionType, args, actionConfig.action)\n } else {\n result = await actionConfig.action(params)\n }\n }\n\n // Обновляем объект действия результатом\n actionObject.payload = result\n\n // Сохраняем аргументы и результат для мемоизации\n lastArgs = [...args]\n lastResult = result\n\n // Отправляем информацию о действии в поток\n this.actions$.next(actionObject)\n\n return result\n }\n\n dispatchFn._type = 'dispatch'\n // Добавляем тип действия как свойство функции\n Object.defineProperty(dispatchFn, 'actionType', {\n value: actionType,\n writable: false,\n enumerable: 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 return dispatchFn as DispatchFunction<TParams, TResult>\n }\n /**\n * Создает watcher для отслеживания изменений в хранилище\n */\n public createWatcher<R>(config: WatcherDefinition<T, R>): WatcherFunction<R> {\n // Логика остается без изменений\n const actionType = `[${this.storage.name}]${config.type}`\n\n // Создаем Subject для этого watcher'а\n const subject = new Subject<TypedAction<R>>()\n\n // Предыдущее значение для сравнения\n let prevValue: R | undefined\n\n // Подписываемся на изменения состояния\n const unsubscribe = this.storage.subscribe(config.selector, (value: R) => {\n // Проверяем, нужно ли генерировать событие\n if (!config.shouldTrigger || config.shouldTrigger(prevValue, value)) {\n // Создаем действие\n const action: TypedAction<R> = {\n type: actionType,\n payload: value,\n meta: config.meta,\n }\n\n // Отправляем в основной поток действий\n this.actions$.next(action)\n\n // Отправляем в поток этого watcher'а\n subject.next(action)\n\n // Обновляем предыдущее значение\n prevValue = value\n }\n })\n\n // Создаем функцию watcher'а\n const watcherFn = () => subject.asObservable()\n watcherFn._type = 'watchers'\n // Добавляем свойства\n Object.defineProperty(watcherFn, 'actionType', {\n value: actionType,\n writable: false,\n enumerable: 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 // Добавляем метод для отписки\n Object.defineProperty(watcherFn, 'unsubscribe', {\n value: unsubscribe,\n writable: false,\n enumerable: true,\n })\n\n //@ts-ignore\n return watcherFn as WatcherFunction<R>\n }\n\n /**\n * Выполняет действие в worker\n */\n private async executeInWorker<TParams, TResult>(\n worker: Worker,\n actionType: string,\n args: TParams[],\n fallbackAction?: (params: TParams) => Promise<TResult> | TResult,\n ): Promise<TResult> {\n // Логика остается без изменений\n return new Promise((resolve, reject) => {\n const requestId = `${actionType}_${Date.now()}_${Math.random()}`\n\n const handleMessage = (event: MessageEvent) => {\n if (event.data.requestId === requestId) {\n worker.removeEventListener('message', handleMessage)\n\n if (event.data.error) {\n reject(new Error(event.data.error))\n } else {\n resolve(event.data.result)\n }\n }\n }\n\n worker.addEventListener('message', handleMessage)\n\n worker.postMessage({\n type: actionType,\n args,\n requestId,\n })\n\n // Опционально: таймаут\n setTimeout(() => {\n worker.removeEventListener('message', handleMessage)\n reject(new Error(`Worker execution timeout for action: ${actionType}`))\n }, 30000) // 30 секунд таймаут\n })\n }\n}\n\n/**\n * Функция для создания типизированного диспетчера\n */\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 const dispatcher = new Dispatcher<TState, TActions>(options)\n\n // Вызываем функцию настройки действий с обновленной структурой аргументов\n const actions = actionsSetup(options.storage, {\n createAction: (actionConfig, executionOptions) => dispatcher.createAction(actionConfig, executionOptions),\n createWatcher: (config) => dispatcher.createWatcher(config),\n })\n\n // Регистрируем все созданные объекты в соответствующих коллекциях\n for (const [key, fn] of Object.entries(actions)) {\n if (typeof fn === 'function') {\n const type = (fn as any)._type\n // @ts-ignore\n dispatcher[type][key] = fn\n }\n }\n\n return dispatcher as Dispatcher<TState, TActions> & {\n dispatch: DispatchActions<ReturnType<TActions>>\n watchers: WatcherActions<ReturnType<TActions>>\n }\n}\nexport type CreateDispatcherType = ReturnType<typeof createDispatcher>\n","// Определяем типы для переводов и опций\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// Функция для вычисления разницы между двумя объектами состояния\nfunction getStateDiff(prevState: any, nextState: any): { [key: string]: any } {\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])\n if (Object.keys(nestedDiff).length > 0) {\n diff[key] = nestedDiff\n }\n }\n // Для массивов и примитивов просто сравниваем значения\n else if (JSON.stringify(prevState[key]) !== JSON.stringify(nextState[key])) {\n diff[key] = { PREV: prevState[key], NEXT: nextState[key] }\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\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 ? console.groupCollapsed : console.group\n\n groupMethod(`%c ${title}`, `color: ${colors.title}; font-weight: bold`)\n\n // Выводим информацию о действии\n console.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 console.log(`%c ${translations.diff} (${translations.changesCount}: ${changesCount}):`, `color: ${colors.diff}; font-weight: bold`, stateDiff)\n }\n\n // Если showFullState включен, показываем полные состояния\n if (mergedOptions.showFullState) {\n // Создаем подгруппу для полного состояния\n console.groupCollapsed(`%c ${translations.showFullState}`, `color: ${colors.fullState}; font-weight: bold`)\n console.log(`%c ${translations.prevState}:`, `color: ${colors.prevState}; font-weight: bold`, prevState)\n console.log(`%c ${translations.nextState}:`, `color: ${colors.nextState}; font-weight: bold`, nextState)\n console.groupEnd()\n }\n\n if (duration) {\n console.log(`%c ${translations.duration}: %c ${time}ms`, 'font-weight: bold', 'color: #4CAF50')\n }\n\n console.groupEnd()\n\n return result\n } catch (error) {\n // В случае ошибки логируем её отдельно, не в группе\n console.error(`%c ${translations.error}:`, `color: ${colors.error}; font-weight: bold`, action.type, error)\n\n // Пробрасываем ошибку дальше\n throw error\n }\n }\n}\n","import { combineLatest, merge, Observable, of, OperatorFunction, pipe, Subject } from 'rxjs'\nimport { catchError, filter, map, share, switchMap, take, withLatestFrom } from 'rxjs/operators'\n\nimport { IStorage } from '../../core'\nimport { Action, ActionsResult, Dispatcher, DispatchFunction, ExtractResultType, WatcherFunction } from '../dispatcher'\nimport { ChunkRequestConsistent, chunkRequestConsistent, ChunkRequestParallel, chunkRequestParallel } from './utils'\n\n/**\n * Тип действия с типизированным payload\n */\nexport interface TypedAction<P> extends Action<P> {\n type: string\n payload: P\n}\n\n/**\n * Тип для внешних состояний\n */\nexport type ExternalStates = Record<string, Observable<any>>\n\n/**\n * Тип для базового эффекта без доступа к состоянию\n */\nexport type EffectBase<TDispatchers extends Record<string, Dispatcher<any, any>> = Record<string, never>, TServices extends Record<string, any> = Record<string, never>> = (\n action$: Observable<Action>,\n dispatchers: TDispatchers,\n services: TServices,\n) => Observable<unknown>\n\n/**\n * Тип для эффекта с доступом к состоянию и конфигурации - это основной тип, который используется по умолчанию\n */\nexport type Effect<\n TState extends Record<string, any> = any,\n TDispatchers extends Record<string, Dispatcher<any, any>> = Record<string, never>,\n TServices extends Record<string, any> = Record<string, never>,\n TConfig extends Record<string, any> = Record<string, never>,\n TExternalStates extends ExternalStates = Record<string, never>,\n> = (\n action$: Observable<Action>,\n state$: Observable<TState>,\n externalStates: TExternalStates,\n dispatchers: TDispatchers,\n services: TServices,\n config: TConfig,\n) => Observable<unknown>\n\n/**\n * Тип для получения типов действий диспетчера\n */\nexport type DispatcherActions<T> = T extends Dispatcher<any, infer A> ? ActionsResult<A> : Record<string, DispatchFunction<any, any>>\n\n/**\n * Конфигурация для валидации в validateMap\n */\nexport interface ValidateConfig {\n conditions: boolean[]\n skipAction: (() => any) | any | ((() => any) | any)[]\n}\n\n/**\n * Утилиты для запросов в validateMap\n */\nexport interface ValidateMapRequestUtils {\n chunkRequest: ChunkRequestParallel\n chunkRequestConsistent: ChunkRequestConsistent\n}\n\n/**\n * Оператор для фильтрации действий по типу с сохранением типа payload\n */\nexport function ofType<T extends DispatchFunction<any, any> | WatcherFunction<any>>(\n actionFn: T,\n): OperatorFunction<Action, TypedAction<T extends WatcherFunction<infer R> ? R : ExtractResultType<T>>> {\n const { actionType } = actionFn\n\n if (!actionType) {\n console.warn('ofType: Action function does not have actionType property', actionFn)\n return filter(() => false) as any\n }\n\n // Определяем тип payload в зависимости от типа функции\n type PayloadType = T extends WatcherFunction<infer R> ? R : ExtractResultType<T>\n\n // Улучшенная реализация с явными типами\n return (source$: Observable<Action>): Observable<TypedAction<PayloadType>> => {\n return source$.pipe(filter((action): action is TypedAction<PayloadType> => action !== undefined && action.type === actionType))\n }\n}\n\n/**\n * Оператор для фильтрации действий по нескольким типам с объединением типов payload\n * @param actionFns Массив функций действий\n */\nexport function ofTypes<T extends DispatchFunction<any, any>[]>(actionFns: [...T]): OperatorFunction<Action, TypedAction<ExtractResultType<T[number]>>> {\n // Получаем типы действий\n const actionTypes = actionFns.map((fn) => fn.actionType).filter(Boolean)\n\n if (actionTypes.length === 0) {\n console.warn('ofTypes: No valid action types found in array', actionFns)\n return filter(() => false) as OperatorFunction<Action, TypedAction<ExtractResultType<T[number]>>>\n }\n\n // Union тип для payload из всех действий\n type CombinedPayloadType = ExtractResultType<T[number]>\n\n // Улучшенная реализация с явными типами\n return (source$: Observable<Action>): Observable<TypedAction<CombinedPayloadType>> => {\n return source$.pipe(filter((action): action is TypedAction<CombinedPayloadType> => action !== undefined && actionTypes.includes(action.type)))\n }\n}\n\n/**\n * Оператор для ожидания выполнения всех указанных действий\n * @param actionFns Массив функций действий\n */\nexport function ofTypesWaitAll<T extends DispatchFunction<any, any>[]>(actionFns: [...T]) {\n return (source$: Observable<Action>): Observable<{ [K in keyof T]: TypedAction<ExtractResultType<T[K]>> }> => {\n // Создаем потоки для каждого типа действия\n const actionTypes = actionFns.map((fn) => fn.actionType).filter(Boolean)\n\n if (actionTypes.length === 0) {\n console.warn('ofTypesWaitAll: No valid action types found in array', actionFns)\n return of([]) as any\n }\n\n // Для каждого типа действия создаем поток,\n // который берет первое срабатывание\n const actionStreams = actionTypes.map((type, index) =>\n source$.pipe(\n filter((action) => action.type === type),\n take(1),\n map((action) =>\n // Сохраняем ассоциацию с индексом, чтобы соответствовать\n // порядку в исходном массиве actionFns\n ({ index, action }),\n ),\n ),\n )\n\n // Ждем, пока все потоки выдадут значения, и сортируем результаты\n // по индексу для сохранения порядка\n return combineLatest(actionStreams).pipe(\n map((results) => {\n // Сортируем по индексу\n results.sort((a, b) => a.index - b.index)\n // Убираем индекс и возвращаем только действия\n return results.map((r) => r.action) as any\n }),\n )\n }\n}\n\n/**\n * Создает Observable с выбранными данными из состояния\n * @param state$ Поток состояния\n * @param selectors Селекторы для выбора частей состояния\n * @returns Observable с массивом выбранных значений\n */\nexport function selectorMap<TState, TResults extends any[]>(\n state$: Observable<TState>,\n ...selectors: { [K in keyof TResults]: (state: TState) => TResults[K] }\n): Observable<TResults> {\n return state$.pipe(\n map((state) => {\n return selectors.map((selector) => selector(state)) as TResults\n }),\n )\n}\n\n/**\n * Создает именованный объект вместо массива\n * @param state$ Поток состояния\n * @param selectors Объект с селекторами\n * @returns Observable с объектом выбранных значений\n */\nexport function selectorObject<TState, TResult extends Record<string, any>>(\n state$: Observable<TState>,\n selectors: { [K in keyof TResult]: (state: TState) => TResult[K] },\n): Observable<TResult> {\n return state$.pipe(\n map((state) => {\n const result = {} as TResult\n for (const [key, selector] of Object.entries(selectors)) {\n result[key as keyof TResult] = selector(state)\n }\n return result\n }),\n )\n}\n\n/**\n * Оператор validateMap для валидации данных и условного вызова API\n */\nexport function validateMap<T, TResult = any>({\n validator,\n apiCall,\n}: {\n validator?: (value: T) => ValidateConfig\n apiCall: (value: T, utils: ValidateMapRequestUtils) => Observable<TResult>\n}): OperatorFunction<T, any> {\n return pipe(\n switchMap((pipeData) => {\n /**\n * Функция вызова API-метода\n */\n const callApi = () =>\n apiCall(pipeData, {\n chunkRequest: chunkRequestParallel,\n chunkRequestConsistent: chunkRequestConsistent,\n })\n\n /**\n * Если валидацию не используем - сразу вызываем запрос\n */\n if (!validator) return callApi()\n\n const validateConfig = validator(pipeData)\n const { conditions, skipAction } = validateConfig\n const conditionMet = conditions.every(Boolean)\n\n /**\n * Если валидация не пройдена - вызываем экшн сброса\n */\n if (!conditionMet) {\n if (Array.isArray(skipAction)) {\n // eslint-disable-next-line no-unsafe-optional-chaining\n return of(...skipAction?.filter(Boolean).map((action) => (typeof action === 'function' ? action() : action)))\n }\n return of(typeof skipAction === 'function' ? skipAction() : skipAction)\n }\n\n return callApi()\n }),\n )\n}\n\n/**\n * Класс для управления эффектами с поддержкой доступа к состоянию и конфигурации\n * Основной класс, который следует использовать\n */\nexport class EffectsModule<\n TState extends Record<string, any> = any,\n TDispatchers extends Record<string, Dispatcher<any, any>> = Record<string, never>,\n TServices extends Record<string, any> = Record<string, never>,\n TConfig extends Record<string, any> = Record<string, never>,\n TExternalStates extends ExternalStates = Record<string, never>,\n> {\n private effects: Effect<TState, TDispatchers, TServices, TConfig, TExternalStates>[] = []\n private subscriptions: Array<{ unsubscribe: VoidFunction }> = []\n private running = false\n private action$ = new Subject<Action>()\n\n /**\n * Поток состояния\n */\n public readonly state$: Observable<TState>\n\n /**\n * Создает модуль эффектов с доступом к состоянию, внешним состояниям и конфигурации\n * @param storage Хранилище состояния\n * @param externalStates Внешние состояния\n * @param dispatchers Объект с диспетчерами\n * @param services Объект с сервисами\n * @param config Глобальная конфигурация для всех эффектов\n */\n constructor(\n private storage: IStorage<TState>,\n private externalStates: TExternalStates = {} as TExternalStates,\n private dispatchers: TDispatchers,\n private services: TServices = {} as TServices,\n private config: TConfig = {} as TConfig,\n ) {\n this.subscribeToDispatchers()\n\n // Создаем поток состояния\n this.state$ = new Observable<TState>((observer) => {\n // Отправляем начальное состояние\n this.storage.getState().then((state) => observer.next(state))\n\n // Подписываемся на все изменения\n const unsubscribe = this.storage.subscribeToAll(() => {\n this.storage.getState().then((state) => observer.next(state))\n })\n\n // Отписываемся при завершении\n return () => unsubscribe()\n }).pipe(share())\n }\n\n /**\n * Подписывается на действия от всех диспетчеров\n */\n private subscribeToDispatchers() {\n for (const [_, dispatcher] of Object.entries(this.dispatchers)) {\n const subscription = dispatcher.actions.subscribe((action) => {\n this.action$.next(action)\n })\n\n this.subscriptions.push(subscription)\n }\n }\n\n add(effect: Effect<TState, TDispatchers, TServices, TConfig, TExternalStates>): this {\n this.effects.push(effect)\n\n if (this.running) {\n this.subscribeToEffect(effect)\n }\n\n return this\n }\n\n /**\n * Добавляет несколько эффектов\n * @param effects Эффекты для добавления\n * @returns Текущий модуль\n */\n addEffects(effects: Effect<TState, TDispatchers, TServices, TConfig, TExternalStates>[]): this {\n effects.forEach((effect) => this.add(effect))\n return this\n }\n\n /**\n * Запускает все эффекты\n * @returns Текущий модуль\n */\n start(): this {\n if (this.running) {\n return this\n }\n\n this.effects.forEach((effect) => this.subscribeToEffect(effect))\n this.running = true\n\n return this\n }\n\n /**\n * Останавливает все эффекты\n * @returns Текущий модуль\n */\n stop(): this {\n this.subscriptions.forEach((sub) => sub.unsubscribe())\n this.subscriptions = []\n this.running = false\n\n return this\n }\n\n /**\n * Подписывается на конкретный эффект\n * @param effect Эффект для подписки\n */\n private subscribeToEffect(effect: Effect<TState, TDispatchers, TServices, TConfig, TExternalStates>): void {\n try {\n const output$ = effect(this.action$.asObservable(), this.state$, this.externalStates, this.dispatchers, this.services, this.config).pipe(\n catchError((err) => {\n console.error('Error in effect:', err)\n return of(null)\n }),\n )\n\n const subscription = output$.subscribe((result) => {\n if (result === null || result === undefined) {\n return\n }\n\n if (typeof result === 'function') {\n try {\n result()\n } catch (callError) {\n console.error('Error calling effect result function:', callError)\n }\n }\n })\n\n this.subscriptions.push(subscription)\n } catch (setupError) {\n console.error('Error setting up effect:', setupError)\n }\n }\n}\n\n/**\n * Вспомогательная функция для создания типизированного эффекта без состояния\n * @deprecated Используйте createEffect вместо этого\n */\nexport function createEffectBase<TDispatchers extends Record<string, Dispatcher<any, any>>, TServices extends Record<string, any>>(\n effect: EffectBase<TDispatchers, TServices>,\n): EffectBase<TDispatchers, TServices> {\n return effect\n}\n\n/**\n * Вспомогательная функция для создания типизированного эффекта с состоянием и конфигурацией\n */\nexport function createEffect<\n TState extends Record<string, any>,\n TDispatchers extends Record<string, Dispatcher<any, any>>,\n TServices extends Record<string, any>,\n TConfig extends Record<string, any> = Record<string, never>,\n TExternalStates extends ExternalStates = Record<string, never>,\n>(effect: Effect<TState, TDispatchers, TServices, TConfig, TExternalStates>): Effect<TState, TDispatchers, TServices, TConfig, TExternalStates> {\n return effect\n}\n\n/**\n * Объединяет несколько эффектов в один\n * @param effects Эффекты для объединения\n * @returns Объединенный эффект\n */\nexport function combineEffects<\n TState extends Record<string, any>,\n TDispatchers extends Record<string, Dispatcher<any, any>>,\n TServices extends Record<string, any>,\n TConfig extends Record<string, any> = Record<string, never>,\n TExternalStates extends ExternalStates = Record<string, never>,\n>(...effects: Effect<TState, TDispatchers, TServices, TConfig, TExternalStates>[]): Effect<TState, TDispatchers, TServices, TConfig, TExternalStates> {\n return (action$, state$, externalStates, dispatchers, services, config) => {\n const outputs = effects.map((effect) => {\n try {\n return effect(action$, state$, externalStates, dispatchers, services, config)\n } catch (error) {\n console.error('Error in one of combined effects:', error)\n return of(null)\n }\n })\n return merge(...outputs)\n }\n}\n","import { Observable, of } from 'rxjs'\nimport { concatAll, delay, mergeMap, toArray } from 'rxjs/operators'\n\nimport { chunk } from '../../../_utils'\n\n/**\n * Разбиение запроса на порции\n * Отправляется ПОСЛЕДОВАТЕЛЬНО n-запросов и дожидается ответа от каждого\n * @param fn - функция в которую передается chunk и возвращается функция api\n * @param arr - массив который нужно поделить\n * @param size - размер порции\n * @param delayMs - задержка между запросами в миллисекундах\n */\nexport const chunkRequestConsistent = <T, R>(fn: (chunk: T[]) => Observable<R>, arr: T[], size: number, delayMs = 0): Observable<R[]> => {\n const chunks = chunk(arr, size).map((chunkItem) => of(chunkItem).pipe(delay(delayMs), mergeMap(fn)))\n return of(...chunks).pipe(concatAll(), toArray())\n}\nexport type ChunkRequestConsistent = typeof chunkRequestConsistent\n","/**\n * Разбивает массив на группы элементов указанного размера.\n * @param array - Массив для разбиения\n * @param size - Размер каждой группы\n * @returns Массив групп элементов\n */\nexport function chunk<T>(array: T[], size: number = 1): T[][] {\n if (size <= 0) throw new Error('Size must be greater than 0')\n\n if (!array || !array.length) return []\n\n const result: T[][] = []\n const length = array.length\n let index = 0\n\n while (index < length) {\n result.push(array.slice(index, index + size))\n index += size\n }\n\n return result\n}\n","import { forkJoin, Observable, timer } from 'rxjs'\nimport { mergeMap } from 'rxjs/operators'\n\nimport { chunk } from '../../../_utils'\n\n/**\n * Разбиение запроса на порции\n * Отправляется ПАРАЛЛЕЛЬНО n-запросов и дожидается ответа от каждого\n * @param fn - функция в которую передается chunk и возвращается функция api\n * @param arr - массив который нужно поделить\n * @param size - размер порции\n * @param delayMs - задержка между запросами в миллисекундах\n */\nexport const chunkRequestParallel = <T, R>(fn: (chunk: T[]) => Observable<R>, arr: T[], size: number, delayMs = 0): Observable<R[]> =>\n forkJoin(chunk(arr, size).map((chunkItem, index) => timer(index * delayMs).pipe(mergeMap(() => fn(chunkItem)))))\nexport type ChunkRequestParallel = typeof chunkRequestParallel\n"],"mappings":"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","names":["import_rxjs","import_operators","import_rxjs","import_rxjs","import_operators"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/reactive/dispatcher/dispatcher.module.ts","../src/reactive/dispatcher/middlewares/logger.middleware.ts","../src/reactive/effects/effects.module.ts","../src/reactive/effects/utils/chunkRequestConsistent.ts","../src/_utils/chunk.util.ts","../src/reactive/effects/utils/chunkRequestParallel.ts"],"sourcesContent":["import { Observable, Subject } from 'rxjs'\n\nimport type { IStorage } from '../../core'\nimport { TypedAction } from '../effects'\n\n/**\n * Расширенное API для middleware\n */\nexport interface EnhancedMiddlewareAPI<T extends Record<string, any>> {\n // Базовые возможности\n getState: () => 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// Параметры исполнения функции действия\ninterface ActionExecutionOptions {\n // Веб-воркер для выполнения действия\n worker?: Worker\n // Функция мемоизации\n memoize?: (currentArgs: any[], previousArgs: any[], previousResult: any) => boolean\n}\n\n/**\n * Параметры для создания действия\n */\nexport interface ActionDefinition<TParams, TResult> {\n /** Тип действия для идентификации в потоке и эффектах */\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 type: string\n selector: (state: T) => R\n meta?: Record<string, any>\n // Опционально - функция для определения, изменилось ли значение\n shouldTrigger?: (prev: R | undefined, current: R) => 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, unknown>> = (\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>>\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, TResult>(config: ActionDefinition<TParams, TResult>, executionOptions?: ActionExecutionOptions) => DispatchFunction<TParams, TResult>\n\n/**\n * Тип для функции настройки действий\n */\nexport type ActionsSetup<T extends Record<string, unknown>> = (create: ActionCreatorFactory, storage: IStorage<T>) => Record<string, DispatchFunction<any, any>>\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 */\nexport type DispatchActions<T> = {\n [K in keyof T]: T[K] extends DispatchFunction<any, any> ? T[K] : never\n}\n\n/**\n * Типизированный объект watchers\n */\nexport type WatcherActions<T> = {\n [K in keyof T]: T[K] extends WatcherFunction<any> ? T[K] : never\n}\n\n/**\n * Параметры для Dispatcher\n */\ninterface DispatcherOptions<T extends Record<string, any>> {\n // Хранилище - обязательный параметр\n storage: IStorage<T>\n // Опциональные параметры\n worker?: Worker\n // DispatcherMiddleware для обработки действий\n middlewares?: EnhancedMiddleware<T>[]\n}\n\n/**\n * Интерфейс для API middleware\n */\nexport interface DispatcherMiddlewareAPI<T extends Record<string, any>> {\n getState: () => Promise<T>\n dispatch: (action: Action) => Promise<any>\n}\n\n/**\n * Интерфейс для middleware\n */\nexport interface DispatcherMiddleware<T extends Record<string, any> = any> {\n (api: DispatcherMiddlewareAPI<T>): (next: (action: Action) => Promise<any>) => (action: Action) => Promise<any>\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 // API для инициализации middleware\n private middlewareAPI: EnhancedMiddlewareAPI<T>\n\n /**\n * Создает новый экземпляр Dispatcher\n */\n constructor(private options: DispatcherOptions<T>) {\n this.storage = options.storage\n\n // Создаем API для middleware сразу\n this.middlewareAPI = {\n getState: () => this.storage.getState(),\n dispatch: async (action: Action) => {\n this.actions$.next(action)\n return action.payload\n },\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 console.error(`Error initializing middleware [${i}]:`, error)\n }\n }\n return this\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) => watcher.actionType === actionType)\n }\n\n /**\n * Создает действие\n */\n public createAction<TParams, TResult>(actionConfig: ActionDefinition<TParams, TResult>, executionOptions?: ActionExecutionOptions): DispatchFunction<TParams, TResult> {\n const actionType = `[${this.storage.name}]${actionConfig.type}`\n\n // Для мемоизации храним последние аргументы и результат\n let lastArgs: TParams[] | null = null\n let lastResult: TResult | null = null\n\n // Создаем функцию диспетчеризации\n const dispatchFn = async (params: TParams): Promise<TResult> => {\n const args = [params] as TParams[]\n\n // Проверяем мемоизацию\n if (executionOptions?.memoize && lastArgs && lastResult) {\n if (executionOptions.memoize(args, lastArgs, lastResult)) {\n return lastResult\n }\n }\n\n // Создаем объект действия\n const actionObject: Action<TResult> = {\n type: actionType,\n meta: actionConfig.meta,\n }\n\n // Применяем middleware цепочку\n let result: TResult\n\n if (this.middlewareFunctions.length > 0) {\n // Базовая функция выполнения действия\n // Строим цепочку middleware в обратном порядке\n let chain = async (action: Action): Promise<TResult> => {\n if (executionOptions?.worker) {\n return this.executeInWorker(executionOptions.worker, actionType, args, actionConfig.action)\n } else {\n return Promise.resolve(actionConfig.action(params))\n }\n }\n\n // Проходим по middleware в обратном порядке\n // Важно: сначала создаем всю цепочку, затем выполняем\n for (let i = this.middlewareFunctions.length - 1; i >= 0; i--) {\n const currentMiddleware = this.middlewareFunctions[i]\n const nextChain = chain // Сохраняем предыдущую цепочку\n\n // Создаем новую цепочку, которая вызывает текущий middleware,\n // передавая предыдущую цепочку как функцию next\n chain = async (action: Action) => {\n // Создаем функцию next для передачи в middleware\n const next = async (nextAction: Action) => nextChain(nextAction)\n\n // Получаем обработчик действия и сразу вызываем его\n return currentMiddleware(next)(action)\n }\n }\n\n // Выполняем действие через цепочку middleware\n result = await chain(actionObject)\n } else {\n // Выполняем действие напрямую без middleware\n if (executionOptions?.worker) {\n result = await this.executeInWorker(executionOptions.worker, actionType, args, actionConfig.action)\n } else {\n result = await actionConfig.action(params)\n }\n }\n\n // Обновляем объект действия результатом\n actionObject.payload = result\n\n // Сохраняем аргументы и результат для мемоизации\n lastArgs = [...args]\n lastResult = result\n\n // Отправляем информацию о действии в поток\n this.actions$.next(actionObject)\n\n return result\n }\n\n dispatchFn._type = 'dispatch'\n // Добавляем тип действия как свойство функции\n Object.defineProperty(dispatchFn, 'actionType', {\n value: actionType,\n writable: false,\n enumerable: 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 return dispatchFn as DispatchFunction<TParams, TResult>\n }\n /**\n * Создает watcher для отслеживания изменений в хранилище\n */\n public createWatcher<R>(config: WatcherDefinition<T, R>): WatcherFunction<R> {\n // Логика остается без изменений\n const actionType = `[${this.storage.name}]${config.type}`\n\n // Создаем Subject для этого watcher'а\n const subject = new Subject<TypedAction<R>>()\n\n // Предыдущее значение для сравнения\n let prevValue: R | undefined\n\n // Подписываемся на изменения состояния\n const unsubscribe = this.storage.subscribe(config.selector, (value: R) => {\n // Проверяем, нужно ли генерировать событие\n if (!config.shouldTrigger || config.shouldTrigger(prevValue, value)) {\n // Создаем действие\n const action: TypedAction<R> = {\n type: actionType,\n payload: value,\n meta: config.meta,\n }\n\n // Отправляем в основной поток действий\n this.actions$.next(action)\n\n // Отправляем в поток этого watcher'а\n subject.next(action)\n\n // Обновляем предыдущее значение\n prevValue = value\n }\n })\n\n // Создаем функцию watcher'а\n const watcherFn = () => subject.asObservable()\n watcherFn._type = 'watchers'\n // Добавляем свойства\n Object.defineProperty(watcherFn, 'actionType', {\n value: actionType,\n writable: false,\n enumerable: 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 // Добавляем метод для отписки\n Object.defineProperty(watcherFn, 'unsubscribe', {\n value: unsubscribe,\n writable: false,\n enumerable: true,\n })\n\n //@ts-ignore\n return watcherFn as WatcherFunction<R>\n }\n\n /**\n * Выполняет действие в worker\n */\n private async executeInWorker<TParams, TResult>(\n worker: Worker,\n actionType: string,\n args: TParams[],\n fallbackAction?: (params: TParams) => Promise<TResult> | TResult,\n ): Promise<TResult> {\n // Логика остается без изменений\n return new Promise((resolve, reject) => {\n const requestId = `${actionType}_${Date.now()}_${Math.random()}`\n\n const handleMessage = (event: MessageEvent) => {\n if (event.data.requestId === requestId) {\n worker.removeEventListener('message', handleMessage)\n\n if (event.data.error) {\n reject(new Error(event.data.error))\n } else {\n resolve(event.data.result)\n }\n }\n }\n\n worker.addEventListener('message', handleMessage)\n\n worker.postMessage({\n type: actionType,\n args,\n requestId,\n })\n\n // Опционально: таймаут\n setTimeout(() => {\n worker.removeEventListener('message', handleMessage)\n reject(new Error(`Worker execution timeout for action: ${actionType}`))\n }, 30000) // 30 секунд таймаут\n })\n }\n}\n\n/**\n * Функция для создания типизированного диспетчера\n */\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 const dispatcher = new Dispatcher<TState, TActions>(options)\n\n // Вызываем функцию настройки действий с обновленной структурой аргументов\n const actions = actionsSetup(options.storage, {\n createAction: (actionConfig, executionOptions) => dispatcher.createAction(actionConfig, executionOptions),\n createWatcher: (config) => dispatcher.createWatcher(config),\n })\n\n // Регистрируем все созданные объекты в соответствующих коллекциях\n for (const [key, fn] of Object.entries(actions)) {\n if (typeof fn === 'function') {\n const type = (fn as any)._type\n // @ts-ignore\n dispatcher[type][key] = fn\n }\n }\n\n return dispatcher as Dispatcher<TState, TActions> & {\n dispatch: DispatchActions<ReturnType<TActions>>\n watchers: WatcherActions<ReturnType<TActions>>\n }\n}\nexport type CreateDispatcherType = ReturnType<typeof createDispatcher>\n","// Определяем типы для переводов и опций\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// Функция для вычисления разницы между двумя объектами состояния\nfunction getStateDiff(prevState: any, nextState: any): { [key: string]: any } {\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])\n if (Object.keys(nestedDiff).length > 0) {\n diff[key] = nestedDiff\n }\n }\n // Для массивов и примитивов просто сравниваем значения\n else if (JSON.stringify(prevState[key]) !== JSON.stringify(nextState[key])) {\n diff[key] = { PREV: prevState[key], NEXT: nextState[key] }\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\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 ? console.groupCollapsed : console.group\n\n groupMethod(`%c ${title}`, `color: ${colors.title}; font-weight: bold`)\n\n // Выводим информацию о действии\n console.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 console.log(`%c ${translations.diff} (${translations.changesCount}: ${changesCount}):`, `color: ${colors.diff}; font-weight: bold`, stateDiff)\n }\n\n // Если showFullState включен, показываем полные состояния\n if (mergedOptions.showFullState) {\n // Создаем подгруппу для полного состояния\n console.groupCollapsed(`%c ${translations.showFullState}`, `color: ${colors.fullState}; font-weight: bold`)\n console.log(`%c ${translations.prevState}:`, `color: ${colors.prevState}; font-weight: bold`, prevState)\n console.log(`%c ${translations.nextState}:`, `color: ${colors.nextState}; font-weight: bold`, nextState)\n console.groupEnd()\n }\n\n if (duration) {\n console.log(`%c ${translations.duration}: %c ${time}ms`, 'font-weight: bold', 'color: #4CAF50')\n }\n\n console.groupEnd()\n\n return result\n } catch (error) {\n // В случае ошибки логируем её отдельно, не в группе\n console.error(`%c ${translations.error}:`, `color: ${colors.error}; font-weight: bold`, action.type, error)\n\n // Пробрасываем ошибку дальше\n throw error\n }\n }\n}\n","import { combineLatest, merge, Observable, of, OperatorFunction, pipe, Subject } from 'rxjs'\nimport { catchError, filter, map, share, switchMap, take, withLatestFrom } from 'rxjs/operators'\n\nimport { IStorage } from '../../core'\nimport { Action, ActionsResult, Dispatcher, DispatchFunction, ExtractResultType, WatcherFunction } from '../dispatcher'\nimport { ChunkRequestConsistent, chunkRequestConsistent, ChunkRequestParallel, chunkRequestParallel } from './utils'\n\n/**\n * Тип действия с типизированным payload\n */\nexport interface TypedAction<P> extends Action<P> {\n type: string\n payload: P\n}\n\n/**\n * Тип для внешних состояний\n */\nexport type ExternalStates = Record<string, Observable<any>>\n\n/**\n * Тип для базового эффекта без доступа к состоянию\n */\nexport type EffectBase<TDispatchers extends Record<string, Dispatcher<any, any>> = Record<string, never>, TServices extends Record<string, any> = Record<string, never>> = (\n action$: Observable<Action>,\n dispatchers: TDispatchers,\n services: TServices,\n) => Observable<unknown>\n\n/**\n * Тип для эффекта с доступом к состоянию и конфигурации - это основной тип, который используется по умолчанию\n */\nexport type Effect<\n TState extends Record<string, any> = any,\n TDispatchers extends Record<string, Dispatcher<any, any>> = Record<string, never>,\n TServices extends Record<string, any> = Record<string, never>,\n TConfig extends Record<string, any> = Record<string, never>,\n TExternalStates extends ExternalStates = Record<string, never>,\n> = (\n action$: Observable<Action>,\n state$: Observable<TState>,\n externalStates: TExternalStates,\n dispatchers: TDispatchers,\n services: TServices,\n config: TConfig,\n) => Observable<unknown>\n\n/**\n * Тип для получения типов действий диспетчера\n */\nexport type DispatcherActions<T> = T extends Dispatcher<any, infer A> ? ActionsResult<A> : Record<string, DispatchFunction<any, any>>\n\n/**\n * Конфигурация для валидации в validateMap\n */\nexport interface ValidateConfig {\n conditions: boolean[]\n skipAction: (() => any) | any | ((() => any) | any)[]\n}\n\n/**\n * Утилиты для запросов в validateMap\n */\nexport interface ValidateMapRequestUtils {\n chunkRequest: ChunkRequestParallel\n chunkRequestConsistent: ChunkRequestConsistent\n}\n\n/**\n * Оператор для фильтрации действий по типу с сохранением типа payload\n */\nexport function ofType<T extends DispatchFunction<any, any> | WatcherFunction<any>>(\n actionFn: T,\n): OperatorFunction<Action, TypedAction<T extends WatcherFunction<infer R> ? R : ExtractResultType<T>>> {\n const { actionType } = actionFn\n\n if (!actionType) {\n console.warn('ofType: Action function does not have actionType property', actionFn)\n return filter(() => false) as any\n }\n\n // Определяем тип payload в зависимости от типа функции\n type PayloadType = T extends WatcherFunction<infer R> ? R : ExtractResultType<T>\n\n // Улучшенная реализация с явными типами\n return (source$: Observable<Action>): Observable<TypedAction<PayloadType>> => {\n return source$.pipe(filter((action): action is TypedAction<PayloadType> => action !== undefined && action.type === actionType))\n }\n}\n\n/**\n * Оператор для фильтрации действий по нескольким типам с объединением типов payload\n * @param actionFns Массив функций действий\n */\nexport function ofTypes<T extends DispatchFunction<any, any>[]>(actionFns: [...T]): OperatorFunction<Action, TypedAction<ExtractResultType<T[number]>>> {\n // Получаем типы действий\n const actionTypes = actionFns.map((fn) => fn.actionType).filter(Boolean)\n\n if (actionTypes.length === 0) {\n console.warn('ofTypes: No valid action types found in array', actionFns)\n return filter(() => false) as OperatorFunction<Action, TypedAction<ExtractResultType<T[number]>>>\n }\n\n // Union тип для payload из всех действий\n type CombinedPayloadType = ExtractResultType<T[number]>\n\n // Улучшенная реализация с явными типами\n return (source$: Observable<Action>): Observable<TypedAction<CombinedPayloadType>> => {\n return source$.pipe(filter((action): action is TypedAction<CombinedPayloadType> => action !== undefined && actionTypes.includes(action.type)))\n }\n}\n\n/**\n * Оператор для ожидания выполнения всех указанных действий\n * @param actionFns Массив функций действий\n */\nexport function ofTypesWaitAll<T extends DispatchFunction<any, any>[]>(actionFns: [...T]) {\n return (source$: Observable<Action>): Observable<{ [K in keyof T]: TypedAction<ExtractResultType<T[K]>> }> => {\n // Создаем потоки для каждого типа действия\n const actionTypes = actionFns.map((fn) => fn.actionType).filter(Boolean)\n\n if (actionTypes.length === 0) {\n console.warn('ofTypesWaitAll: No valid action types found in array', actionFns)\n return of([]) as any\n }\n\n // Для каждого типа действия создаем поток,\n // который берет первое срабатывание\n const actionStreams = actionTypes.map((type, index) =>\n source$.pipe(\n filter((action) => action.type === type),\n take(1),\n map((action) =>\n // Сохраняем ассоциацию с индексом, чтобы соответствовать\n // порядку в исходном массиве actionFns\n ({ index, action }),\n ),\n ),\n )\n\n // Ждем, пока все потоки выдадут значения, и сортируем результаты\n // по индексу для сохранения порядка\n return combineLatest(actionStreams).pipe(\n map((results) => {\n // Сортируем по индексу\n results.sort((a, b) => a.index - b.index)\n // Убираем индекс и возвращаем только действия\n return results.map((r) => r.action) as any\n }),\n )\n }\n}\n\n/**\n * Создает Observable с выбранными данными из состояния\n * @param state$ Поток состояния\n * @param selectors Селекторы для выбора частей состояния\n * @returns Observable с массивом выбранных значений\n */\nexport function selectorMap<TState, TResults extends any[]>(\n state$: Observable<TState>,\n ...selectors: { [K in keyof TResults]: (state: TState) => TResults[K] }\n): Observable<TResults> {\n return state$.pipe(\n map((state) => {\n return selectors.map((selector) => selector(state)) as TResults\n }),\n )\n}\n\n/**\n * Создает именованный объект вместо массива\n * @param state$ Поток состояния\n * @param selectors Объект с селекторами\n * @returns Observable с объектом выбранных значений\n */\nexport function selectorObject<TState, TResult extends Record<string, any>>(\n state$: Observable<TState>,\n selectors: { [K in keyof TResult]: (state: TState) => TResult[K] },\n): Observable<TResult> {\n return state$.pipe(\n map((state) => {\n const result = {} as TResult\n for (const [key, selector] of Object.entries(selectors)) {\n result[key as keyof TResult] = selector(state)\n }\n return result\n }),\n )\n}\n\n/**\n * Оператор validateMap для валидации данных и условного вызова API\n */\nexport function validateMap<T, TResult = any>({\n validator,\n apiCall,\n}: {\n validator?: (value: T) => ValidateConfig\n apiCall: (value: T, utils: ValidateMapRequestUtils) => Observable<TResult>\n}): OperatorFunction<T, any> {\n return pipe(\n switchMap((pipeData) => {\n /**\n * Функция вызова API-метода\n */\n const callApi = () =>\n apiCall(pipeData, {\n chunkRequest: chunkRequestParallel,\n chunkRequestConsistent: chunkRequestConsistent,\n })\n\n /**\n * Если валидацию не используем - сразу вызываем запрос\n */\n if (!validator) return callApi()\n\n const validateConfig = validator(pipeData)\n const { conditions, skipAction } = validateConfig\n const conditionMet = conditions.every(Boolean)\n\n /**\n * Если валидация не пройдена - вызываем экшн сброса\n */\n if (!conditionMet) {\n if (Array.isArray(skipAction)) {\n // eslint-disable-next-line no-unsafe-optional-chaining\n return of(...skipAction?.filter(Boolean).map((action) => (typeof action === 'function' ? action() : action)))\n }\n return of(typeof skipAction === 'function' ? skipAction() : skipAction)\n }\n\n return callApi()\n }),\n )\n}\n\n/**\n * Класс для управления эффектами с поддержкой доступа к состоянию и конфигурации\n * Основной класс, который следует использовать\n */\nexport class EffectsModule<\n TState extends Record<string, any> = any,\n TDispatchers extends Record<string, Dispatcher<any, any>> = Record<string, never>,\n TServices extends Record<string, any> = Record<string, never>,\n TConfig extends Record<string, any> = Record<string, never>,\n TExternalStates extends ExternalStates = Record<string, never>,\n> {\n private effects: Effect<TState, TDispatchers, TServices, TConfig, TExternalStates>[] = []\n private subscriptions: Array<{ unsubscribe: VoidFunction }> = []\n private running = false\n private action$ = new Subject<Action>()\n\n /**\n * Поток состояния\n */\n public readonly state$: Observable<TState>\n\n /**\n * Создает модуль эффектов с доступом к состоянию, внешним состояниям и конфигурации\n * @param storage Хранилище состояния\n * @param externalStates Внешние состояния\n * @param dispatchers Объект с диспетчерами\n * @param services Объект с сервисами\n * @param config Глобальная конфигурация для всех эффектов\n */\n constructor(\n private storage: IStorage<TState>,\n private externalStates: TExternalStates = {} as TExternalStates,\n private dispatchers: TDispatchers,\n private services: TServices = {} as TServices,\n private config: TConfig = {} as TConfig,\n ) {\n this.subscribeToDispatchers()\n\n // Создаем поток состояния\n this.state$ = new Observable<TState>((observer) => {\n // Отправляем начальное состояние\n this.storage.getState().then((state) => observer.next(state))\n\n // Подписываемся на все изменения\n const unsubscribe = this.storage.subscribeToAll(() => {\n this.storage.getState().then((state) => observer.next(state))\n })\n\n // Отписываемся при завершении\n return () => unsubscribe()\n }).pipe(share())\n }\n\n /**\n * Подписывается на действия от всех диспетчеров\n */\n private subscribeToDispatchers() {\n for (const [_, dispatcher] of Object.entries(this.dispatchers)) {\n const subscription = dispatcher.actions.subscribe((action) => {\n this.action$.next(action)\n })\n\n this.subscriptions.push(subscription)\n }\n }\n\n add(effect: Effect<TState, TDispatchers, TServices, TConfig, TExternalStates>): this {\n this.effects.push(effect)\n\n if (this.running) {\n this.subscribeToEffect(effect)\n }\n\n return this\n }\n\n /**\n * Добавляет несколько эффектов\n * @param effects Эффекты для добавления\n * @returns Текущий модуль\n */\n addEffects(effects: Effect<TState, TDispatchers, TServices, TConfig, TExternalStates>[]): this {\n effects.forEach((effect) => this.add(effect))\n return this\n }\n\n /**\n * Запускает все эффекты\n * @returns Текущий модуль\n */\n start(): this {\n if (this.running) {\n return this\n }\n\n this.effects.forEach((effect) => this.subscribeToEffect(effect))\n this.running = true\n\n return this\n }\n\n /**\n * Останавливает все эффекты\n * @returns Текущий модуль\n */\n stop(): this {\n this.subscriptions.forEach((sub) => sub.unsubscribe())\n this.subscriptions = []\n this.running = false\n\n return this\n }\n\n /**\n * Подписывается на конкретный эффект\n * @param effect Эффект для подписки\n */\n private subscribeToEffect(effect: Effect<TState, TDispatchers, TServices, TConfig, TExternalStates>): void {\n try {\n const output$ = effect(this.action$.asObservable(), this.state$, this.externalStates, this.dispatchers, this.services, this.config).pipe(\n catchError((err) => {\n console.error('Error in effect:', err)\n return of(null)\n }),\n )\n\n const subscription = output$.subscribe((result) => {\n if (result === null || result === undefined) {\n return\n }\n\n if (typeof result === 'function') {\n try {\n result()\n } catch (callError) {\n console.error('Error calling effect result function:', callError)\n }\n }\n })\n\n this.subscriptions.push(subscription)\n } catch (setupError) {\n console.error('Error setting up effect:', setupError)\n }\n }\n}\n\n/**\n * Вспомогательная функция для создания типизированного эффекта без состояния\n * @deprecated Используйте createEffect вместо этого\n */\nexport function createEffectBase<TDispatchers extends Record<string, Dispatcher<any, any>>, TServices extends Record<string, any>>(\n effect: EffectBase<TDispatchers, TServices>,\n): EffectBase<TDispatchers, TServices> {\n return effect\n}\n\n/**\n * Вспомогательная функция для создания типизированного эффекта с состоянием и конфигурацией\n */\nexport function createEffect<\n TState extends Record<string, any>,\n TDispatchers extends Record<string, Dispatcher<any, any>>,\n TServices extends Record<string, any>,\n TConfig extends Record<string, any> = Record<string, never>,\n TExternalStates extends ExternalStates = Record<string, never>,\n>(effect: Effect<TState, TDispatchers, TServices, TConfig, TExternalStates>): Effect<TState, TDispatchers, TServices, TConfig, TExternalStates> {\n return effect\n}\n\n/**\n * Объединяет несколько эффектов в один\n * @param effects Эффекты для объединения\n * @returns Объединенный эффект\n */\nexport function combineEffects<\n TState extends Record<string, any>,\n TDispatchers extends Record<string, Dispatcher<any, any>>,\n TServices extends Record<string, any>,\n TConfig extends Record<string, any> = Record<string, never>,\n TExternalStates extends ExternalStates = Record<string, never>,\n>(...effects: Effect<TState, TDispatchers, TServices, TConfig, TExternalStates>[]): Effect<TState, TDispatchers, TServices, TConfig, TExternalStates> {\n return (action$, state$, externalStates, dispatchers, services, config) => {\n const outputs = effects.map((effect) => {\n try {\n return effect(action$, state$, externalStates, dispatchers, services, config)\n } catch (error) {\n console.error('Error in one of combined effects:', error)\n return of(null)\n }\n })\n return merge(...outputs)\n }\n}\n","import { Observable, of } from 'rxjs'\nimport { concatAll, delay, mergeMap, toArray } from 'rxjs/operators'\n\nimport { chunk } from '../../../_utils'\n\n/**\n * Разбиение запроса на порции\n * Отправляется ПОСЛЕДОВАТЕЛЬНО n-запросов и дожидается ответа от каждого\n * @param fn - функция в которую передается chunk и возвращается функция api\n * @param arr - массив который нужно поделить\n * @param size - размер порции\n * @param delayMs - задержка между запросами в миллисекундах\n */\nexport const chunkRequestConsistent = <T, R>(fn: (chunk: T[]) => Observable<R>, arr: T[], size: number, delayMs = 0): Observable<R[]> => {\n const chunks = chunk(arr, size).map((chunkItem) => of(chunkItem).pipe(delay(delayMs), mergeMap(fn)))\n return of(...chunks).pipe(concatAll(), toArray())\n}\nexport type ChunkRequestConsistent = typeof chunkRequestConsistent\n","/**\n * Разбивает массив на группы элементов указанного размера.\n * @param array - Массив для разбиения\n * @param size - Размер каждой группы\n * @returns Массив групп элементов\n */\nexport function chunk<T>(array: T[], size: number = 1): T[][] {\n if (size <= 0) throw new Error('Size must be greater than 0')\n\n if (!array || !array.length) return []\n\n const result: T[][] = []\n const length = array.length\n let index = 0\n\n while (index < length) {\n result.push(array.slice(index, index + size))\n index += size\n }\n\n return result\n}\n","import { forkJoin, Observable, timer } from 'rxjs'\nimport { mergeMap } from 'rxjs/operators'\n\nimport { chunk } from '../../../_utils'\n\n/**\n * Разбиение запроса на порции\n * Отправляется ПАРАЛЛЕЛЬНО n-запросов и дожидается ответа от каждого\n * @param fn - функция в которую передается chunk и возвращается функция api\n * @param arr - массив который нужно поделить\n * @param size - размер порции\n * @param delayMs - задержка между запросами в миллисекундах\n */\nexport const chunkRequestParallel = <T, R>(fn: (chunk: T[]) => Observable<R>, arr: T[], size: number, delayMs = 0): Observable<R[]> =>\n forkJoin(chunk(arr, size).map((chunkItem, index) => timer(index * delayMs).pipe(mergeMap(() => fn(chunkItem)))))\nexport type ChunkRequestParallel = typeof chunkRequestParallel\n"],"mappings":"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","names":["Observable","of","Subject","mergeMap","mergeMap","of","Observable","Subject"]}