UNPKG

@decaf-ts/db-decorators

Version:

Agnostic database decorators and repository

109 lines (108 loc) 4.42 kB
import { ContextArgs } from "./utils"; import { Contextual } from "../interfaces/Contextual"; import { OperationKeys } from "../operations/constants"; import { Constructor, Model } from "@decaf-ts/decorator-validation"; import { ObjectAccumulator } from "typed-object-accumulator"; import { RepositoryFlags } from "./types"; /** * @description Factory type for creating context instances. * @summary Defines a function type that creates context instances with specific repository flags. * @template F - The repository flags type extending RepositoryFlags * @typedef {Function} ContextFactory * @memberOf module:db-decorators */ export type ContextFactory<F extends RepositoryFlags> = <C extends Context<F>>(arg: Omit<F, "timestamp">) => C; /** * @description Default factory for creating context instances. * @summary A factory function that creates new Context instances with the provided repository flags. * It automatically adds a timestamp to the context and returns a properly typed context instance. * @const DefaultContextFactory * @memberOf module:db-decorators */ export declare const DefaultContextFactory: ContextFactory<any>; /** * @description A context management class for handling repository operations. * @summary The Context class provides a mechanism for managing repository operations with flags, * parent-child relationships, and state accumulation. It allows for hierarchical context chains * and maintains operation-specific configurations while supporting type safety through generics. * * @template F - Type extending RepositoryFlags that defines the context configuration * * @param {ObjectAccumulator<F>} cache - The internal cache storing accumulated values * * @class * * @example * ```typescript * // Creating a new context with repository flags * const context = new Context<RepositoryFlags>(); * * // Accumulating values * const enrichedContext = context.accumulate({ * writeOperation: true, * affectedTables: ['users'], * operation: OperationKeys.CREATE * }); * * // Accessing values * const isWrite = enrichedContext.get('writeOperation'); // true * const tables = enrichedContext.get('affectedTables'); // ['users'] * ``` * * @mermaid * sequenceDiagram * participant C as Client * participant Ctx as Context * participant Cache as ObjectAccumulator * * C->>Ctx: new Context() * Ctx->>Cache: create cache * * C->>Ctx: accumulate(value) * Ctx->>Cache: accumulate(value) * Cache-->>Ctx: updated cache * Ctx-->>C: updated context * * C->>Ctx: get(key) * Ctx->>Cache: get(key) * alt Key exists in cache * Cache-->>Ctx: value * else Key not found * Ctx->>Ctx: check parent context * alt Parent exists * Ctx->>Parent: get(key) * Parent-->>Ctx: value * else No parent * Ctx-->>C: throw error * end * end * Ctx-->>C: requested value */ export declare class Context<F extends RepositoryFlags> { constructor(); static factory: ContextFactory<any>; readonly cache: RepositoryFlags & ObjectAccumulator<any>; /** * @description Accumulates new values into the context. * @summary Merges the provided value object with the existing context state, * creating a new immutable cache state. */ accumulate<V extends object>(value: V): Context<F & V>; get timestamp(): F["timestamp"]; /** * @description Retrieves a value from the context by key. */ get<K extends keyof F>(key: K): F[K]; /** * @description Creates a child context from another context */ static childFrom<F extends RepositoryFlags, C extends Context<F>>(context: C, overrides?: Partial<F>): C; /** * @description Creates a new context from operation parameters */ static from<M extends Model, F extends RepositoryFlags, C extends Context<F>>(operation: OperationKeys.CREATE | OperationKeys.READ | OperationKeys.UPDATE | OperationKeys.DELETE, overrides: Partial<F>, model: Constructor<M>, ...args: any[]): Promise<C>; /** * @description Prepares arguments for context operations */ static args<M extends Model<any>, C extends Context<F>, F extends RepositoryFlags>(operation: OperationKeys.CREATE | OperationKeys.READ | OperationKeys.UPDATE | OperationKeys.DELETE, model: Constructor<M>, args: any[], contextual?: Contextual<F>, overrides?: Partial<F>): Promise<ContextArgs<F, C>>; }