UNPKG

ngx-statewise

Version:

A lightweight and intuitive state management for Angular. Simpler than NgRx, more structured than DIY.

266 lines (251 loc) 10.2 kB
import { Observable } from 'rxjs'; import * as i0 from '@angular/core'; import { Type, EnvironmentProviders } from '@angular/core'; /** * Represents an action with no payload. * * @returns `undefined` — used as a placeholder for actions without data. */ type EmptyPayloadFn = () => undefined; /** * Function that receives and returns a typed payload. * * @template T - The payload type. * @param payload - The input data. * @returns The same payload. */ type ValuePayloadFn<T> = (payload: T) => T; /** * Defines a payload function based on the payload type: * - If `T` is `undefined`, resolves to `EmptyPayloadFn`. * - Otherwise, resolves to `ValuePayloadFn<T>`. * * @template T - Payload type. */ type SingleAction<T> = T extends undefined ? EmptyPayloadFn : ValuePayloadFn<T>; /** * Base structure for all actions. * * @property type - The action type string. * @property payload - Optional data attached to the action. */ type Action = { type: string; payload?: any; }; /** * Converts a CamelCase or PascalCase string to snake_case. * * @template S - Input string type. * * @example * type A = CamelToSnakeCase<'loadFailure'> // 'load_failure' * type B = CamelToSnakeCase<'UserLogin'> // 'user_login' */ type CamelToSnakeCase<S extends string> = S extends `${infer Head}${infer Tail}` ? Tail extends Uncapitalize<Tail> ? `${Lowercase<Head>}${CamelToSnakeCase<Tail>}` : `${Lowercase<Head>}_${CamelToSnakeCase<Tail>}` : S; /** * Represents an empty payload for actions without data. * * @returns `undefined` */ declare const emptyPayload: EmptyPayloadFn; /** * Creates a typed identity function for payloads. * * Useful to define payload handlers with a specific type. * * @template T - The expected payload type. * @returns A function that returns the same payload it receives. */ declare function payload<T>(): ValuePayloadFn<T>; /** * Extracts the action type string from an action creator or object. * * @param action - Either an action creator (function with `.type`) or an action object. * @returns The `type` string. * * @example * ofType(someActionCreator) // 'SOME_ACTION' * ofType({ type: 'MY_ACTION' }) // 'MY_ACTION' */ declare function ofType<T extends (...args: any[]) => Action>(action: T): string; declare function ofType(action: { type: string; }): string; /** * Defines a group of related actions with a common source * * This function provides a convenient way to define action groups without * directly injecting the ActionService * * @param config - Object containing source prefix and events map * @returns An object with action creators for each event */ declare function defineActionsGroup<Source extends string, Events extends Record<string, SingleAction<any>>>(config: { source: Source; events: Events; }): { [K in keyof Events]: Events[K] extends EmptyPayloadFn ? () => { type: `${Uppercase<Source>}_${Uppercase<CamelToSnakeCase<string & K>>}`; } : (payload: Parameters<Events[K]>[0]) => { type: `${Uppercase<Source>}_${Uppercase<CamelToSnakeCase<string & K>>}`; payload: Parameters<Events[K]>[0]; }; }; /** * Defines a single action with a source prefix * * This function provides a convenient way to define a single action without * directly injecting the ActionService * * @param source - Source prefix for the action type * @param payload - Payload handler function * @returns An object with an action creator */ declare function defineSingleAction<Source extends string, ActionPayload>(source: Source, payload: SingleAction<ActionPayload>): { action: ActionPayload extends undefined ? () => { type: `${Source}_ACTION`; } : (payload: ActionPayload) => { type: `${Source}_ACTION`; payload: ActionPayload; }; }; type SWEffects = Promise<Observable<Action> | Action | Action[] | void> | Observable<Action | Action[]> | Action | Action[] | void; /** * Registers an effect that listens to a specific action and executes a handler. * * @param action - The action creator function. * @param handler - A function called when the action is dispatched. * - Receives the payload if the action defines one. * - Can return an action, array of actions, observable, or promise. */ declare function createEffect<T extends (payload: any) => Action>(action: T, handler: (payload: Parameters<T>[0]) => SWEffects): void; /** * Registers an effect for an action without payload. * * @param action - Action creator with no payload. * @param handler - Function executed when the action is dispatched. */ declare function createEffect(action: () => Action, handler: () => SWEffects): void; /** * Waits for all currently pending effects to resolve. * * This function ensures that all side effects triggered by actions are completed * before continuing with the execution flow. * * @returns A promise that resolves when all pending effects are completed. */ declare function waitForAllEffects(): Promise<void>; /** * Waits for pending effects associated with a specific action type to resolve. * * Useful for scenarios where you need to wait for effects triggered by a particular * action before proceeding. * * @param actionType - The action type whose effects should be waited for. * @returns A promise that resolves when all pending effects for the specified action type are completed. */ declare function waitForEffect(actionType: string): Promise<void>; /** * Interface representing an updator for state management. * * The `IUpdator` holds the current state and a registry of functions * (updators) that can modify that state based on different action types. * * @template S - The type of the state. */ interface IUpdator<S> { /** * The current state that the updators will modify. */ readonly state: S; /** * A registry of updators, where each action type is associated with a function * that modifies the state. */ readonly updators: UpdatorGlobalRegistry<S>; } /** * Type representing a function that updates the state based on an action. * * @template S - The type of the state. * @template P - The type of the payload (optional). * * @param state - The current state to be updated. * @param payload - The data to modify the state (optional). */ type Updator<S, P = any> = (state: S, payload?: P) => void; /** * A registry of updators, where each action type is mapped to an `Updator` function. * * The key is the action type (usually a string), and the value is the corresponding * function that modifies the state when the action is dispatched. * * @template S - The type of the state. */ interface UpdatorGlobalRegistry<S> { /** * Maps action types to their corresponding `Updator` function. * * The key is an action type, and the value is an `Updator` that modifies the state. */ [actionType: string]: Updator<S>; } /** * Registers a local updater for a given manager context. * * This function should be used within an Angular injection context (e.g. during component initialization). * * @template S - The state type handled by the updater. * @param {object} manager - The local context object (e.g., a component or a service) to associate the updater with. * @param {IUpdator<S>} updator - The updater instance defining actions and their update logic for the given state. */ declare function registerLocalUpdator<S>(manager: object, updator: IUpdator<S>): void; /** * Dispatches an action with optional updator registration. * * This function provides a flexible way to dispatch actions: * - If only an action is provided, it will be dispatched through the ActionDispatcher * - If an updator is also provided, it will be registered (if needed) and used to update state * * @template T - The action type. * @template S - The state type (inferred from updator if provided). * @param action - The action to dispatch. * @param updator - Optional updator to handle state updates for this action. */ declare function dispatch<T extends Action>(action: T, context?: object): void; declare function dispatch<T extends Action, S>(action: T, updator: IUpdator<S>): void; /** * Asynchronously dispatches an action and waits for effects to complete. * * Similar to `dispatch`, but returns a Promise that resolves when all associated * effects are completed. Supports both global and local updators. * * @template T - The action type. * @template S - The state type (inferred from updator if provided). * @param action - The action to dispatch. * @param updator - Optional updator to handle state updates for this action. * @returns A Promise that resolves when all effects for this action are completed. */ declare function dispatchAsync<T extends Action>(action: T, context?: object): Promise<void>; declare function dispatchAsync<T extends Action, S>(action: T, updator: IUpdator<S>): Promise<void>; declare function provideStatewise(): i0.EnvironmentProviders; /** * Registers and instantiates a list of effect classes at application startup. * * @param effectClasses - Array of effect class types to initialize. * @returns EnvironmentProviders to include in your application bootstrap. */ declare function provideEffects(effectClasses: Type<any>[]): EnvironmentProviders; /** * Registers an array of updators globally at application startup. * * This function provides a way to register state updators during the Angular * application initialization phase, making them available throughout the application * without needing to register them with each dispatch call. * * @param updators - An array of Updator class to be registered globally. * @returns Angular EnvironmentProviders to be included in your application bootstrap. * */ declare function provideUpdators(updatorClasses: Type<IUpdator<any>>[]): EnvironmentProviders; export { createEffect, defineActionsGroup, defineSingleAction, dispatch, dispatchAsync, emptyPayload, ofType, payload, provideEffects, provideStatewise, provideUpdators, registerLocalUpdator, waitForAllEffects, waitForEffect }; export type { IUpdator, UpdatorGlobalRegistry as UpdatorRegistry };