UNPKG

@mic-rexjs/usecases-react

Version:

React-based solution for use usecases of Clean Architecture

63 lines (62 loc) 4.49 kB
import { UseCase } from '@mic-rexjs/usecases'; import { UseCaseProvider } from '../useProvider/types'; import { ContextualEntityReducers } from '../../usecases/contextUseCase/types'; import { EntityReducerMap, EntityReducers, InferableEntityUseCase, ReducerMap, SymbolSet, SymbolSetTarget } from '@mic-rexjs/usecases/es/types'; export interface NonEntitySymbolSet extends SymbolSet { entity?: never; } export type RootCoreCollection<T, TEntityReducers extends EntityReducerMap<T>> = [ entity: T, reducers: ContextualEntityReducers<T, TEntityReducers>, Provider: UseCaseProvider ]; export type ContextualCoreCollection<T, TEntityReducers extends EntityReducerMap<T>> = [ entity: T, reducers: ContextualEntityReducers<T, TEntityReducers> ]; export type CoreCollection<T, TEntityReducers extends EntityReducerMap<T>> = RootCoreCollection<T, TEntityReducers> | ContextualCoreCollection<T, TEntityReducers>; export interface EntityGetter<T> { (): T; } export interface EntityWatchEvent<T, TValue = unknown> { fieldPaths: string[]; newEntity: T; newValue: TValue; oldEntity: T; oldValue: TValue; } export interface EntityWatcher<T, TValue = unknown> { (event: EntityWatchEvent<T, TValue>): void; } export type PathTemplate = '1.2.3'; export type NextPathTemplate<T extends string> = T extends `${string}.${infer U}` ? U : T; export type PropertyPath<T, TTemplate extends string, K extends keyof T = keyof T & string> = TTemplate extends `${string}.${string}` ? K extends infer TKey ? `${TKey & (string | number)}${'' | DotAccessorFieldPath<T[TKey & keyof T], TTemplate>}` : never : never; export type DotAccessorFieldPath<T, TTemplate extends string> = TTemplate extends `${string}.${string}` ? T extends unknown[] ? '.length' | `${'' | `.${number}`}${DotAccessorFieldPath<T[number], NextPathTemplate<TTemplate>>}` : T extends object ? `.${PropertyPath<T, NextPathTemplate<TTemplate>>}` : '' : ''; export type FieldPath<T, TTemplate extends string = PathTemplate> = TTemplate extends `${string}.${string}` ? T extends unknown[] ? FieldPath<T[number], NextPathTemplate<TTemplate>> | 'length' : T extends object ? PropertyPath<T, TTemplate> : never : never; export type ExtractPropertyType<T, TPath> = TPath extends `${infer TKey}.${infer TSubPath}` ? T extends unknown[] ? ExtractPropertyType<T[number], TKey extends `${number}` ? TSubPath : TPath> : ExtractPropertyType<T[TKey & keyof T], TSubPath> : T extends unknown[] ? TPath extends 'length' ? T[TPath] : TPath extends `${number}` ? T[number] : ExtractPropertyType<T[number], TPath> : T[TPath & keyof T]; export type ExtractFieldType<T, TPath> = TPath extends `${infer TKey}.${infer TSubProperty}` ? ExtractPropertyType<T[TKey & keyof T], TSubProperty> : T[TPath & keyof T]; export type EntityWatchMap<T> = { [K in FieldPath<T>]?: EntityWatcher<T, ExtractFieldType<T, K>>; }; export interface UseCaseHookContextualOptions<T> { watch?: EntityWatchMap<T>; onChange?(newEntity: T, oldEntity: T): void; } export interface UseCaseHookOwnOptions<T, TUseCaseOptions extends object> extends UseCaseHookContextualOptions<T> { options?: TUseCaseOptions; } export type UseCaseHookOptions<T, TUseCaseOptions extends object = object> = TUseCaseOptions & UseCaseHookOwnOptions<T, TUseCaseOptions>; export interface ReducersHook { <T extends ReducerMap, TUseCaseOptions extends object = object>(usecase: UseCase<T & SymbolSetTarget<NonEntitySymbolSet>, TUseCaseOptions>, options?: TUseCaseOptions, deps?: unknown[]): T; } export interface ContextualCoreCollectionHook { <T, TEntityReducers extends EntityReducerMap<T>>(usecase: InferableEntityUseCase<T, TEntityReducers>, options?: UseCaseHookContextualOptions<T>, deps?: unknown[]): ContextualCoreCollection<T, TEntityReducers>; } export interface RootCoreCollectionHook { <T, TEntityReducers extends EntityReducerMap<T>, TUseCaseOptions extends object = object>(entity: T | EntityGetter<T>, usecase: InferableEntityUseCase<T, TEntityReducers & EntityReducers<T>, TUseCaseOptions>, options?: UseCaseHookOptions<T, TUseCaseOptions>, deps?: unknown[]): RootCoreCollection<T, EntityReducers<T, TEntityReducers>>; } export interface CoreCollectionHook extends ContextualCoreCollectionHook, RootCoreCollectionHook { } export type UseCaseHookParameters = Parameters<ReducersHook> | Parameters<ContextualCoreCollectionHook> | Parameters<RootCoreCollectionHook>; export interface UseCaseHook extends ReducersHook, CoreCollectionHook { }