UNPKG

@daiso-tech/core

Version:

The library offers flexible, framework-agnostic solutions for modern web applications, built on adaptable components that integrate seamlessly with popular frameworks like Next Js.

193 lines (192 loc) 7.16 kB
/** * @module Middleware */ import { type IContext } from "../../execution-context/contracts/_module.js"; import { type InvokableFn, type IInvokableObject, type OneOrMore, type Invokable } from "../../utilities/_module.js"; /** * Represents the next middleware function in the chain. * * When invoked, continues execution to the next middleware or the final function. * Allows middleware to decide whether to proceed with execution and with what arguments. * * @typeParam TParameters - Type of arguments passed through the middleware chain * @typeParam TReturn - Type of value returned from the function * * @example * ```ts * // In middleware * next() // Continue with original args * next([newArg1, newArg2]) // Continue with modified args * ``` * * @see {@link MiddlewareArgs | `MiddlewareArgs`} * @see {@link MiddlewareFn | `MiddlewareFn`} * * IMPORT_PATH: `@daiso-tech/core/middleware` * @group Contracts */ export type NextFn<TParameters extends Array<unknown> = Array<unknown>, TReturn = unknown> = InvokableFn<[args?: TParameters], TReturn>; /** * Arguments passed to middleware functions during execution. * * Contains the original function arguments, a reference to the next middleware in the chain, * and the execution context for accessing and modifying state. * * @typeParam TParameters - Type of arguments passed to the function * @typeParam TReturn - Type of value returned from the function * * @example * ```ts * const loggingMiddleware: MiddlewareFn = ({ args, next, context }) => { * console.log('Before:', args); * const result = next(args); * console.log('After:', result); * return result; * }; * ``` * * @see {@link NextFn | `NextFn`} * @see {@link MiddlewareFn | `MiddlewareFn`} * @see {@link IContext | `IContext`} * * IMPORT_PATH: `@daiso-tech/core/middleware` * @group Contracts */ export type MiddlewareArgs<TParameters extends Array<unknown> = Array<unknown>, TReturn = unknown> = { /** The arguments passed to the original function */ args: TParameters; /** Function to call the next middleware or final function */ next: NextFn<TParameters, TReturn>; /** Execution context for state management */ context: IContext; }; /** * Middleware implementation as an object with invocation method. * * Allows middleware to be defined as a class or object with an `invoke` method. * The priority property determines the order of execution (lower priority executes first). * * @typeParam TParameters - Type of arguments passed to the function * @typeParam TReturn - Type of value returned from the function * * @example * ```ts * class LoggingMiddleware implements IMiddlewareObject { * priority = 10; * * invoke({ args, next }: MiddlewareArgs) { * console.log('Executing with:', args); * return next(args); * } * } * ``` * * @see {@link MiddlewareFn | `MiddlewareFn`} * @see {@link Middleware | `Middleware`} * * IMPORT_PATH: `@daiso-tech/core/middleware` * @group Contracts */ export type IMiddlewareObject<TParameters extends Array<unknown> = Array<unknown>, TReturn = unknown> = IInvokableObject<[args: MiddlewareArgs<TParameters, TReturn>], TReturn> & { /** Execution priority. Lower values execute first. Defaults to 0. */ priority?: number; }; /** * Middleware implementation as a function. * * A function-based middleware that receives {@link MiddlewareArgs | `MiddlewareArgs`} and returns the result * of processing. This is the most common and flexible way to define middleware. * * @typeParam TParameters - Type of arguments passed to the function * @typeParam TReturn - Type of value returned from the function * * @example * ```ts * const cacheToken = contextToken<Map<string, unknown>>("cache"); * * const cacheMiddleware: MiddlewareFn = async ({ args, next, context }) => { * const cacheKey = JSON.stringify(args); * const cache = context.getOr(cacheToken, () => new Map()); * if (cache.has(cacheKey)) return cache.get(cacheKey); * * const result = await next(args); * cache.set(cacheKey, result); * context.put(cacheToken, cache); * return result; * }; * ``` * * @see {@link IMiddlewareObject | `IMiddlewareObject`} * @see {@link Middleware | `Middleware`} * * IMPORT_PATH: `@daiso-tech/core/middleware` * @group Contracts */ export type MiddlewareFn<TParameters extends Array<unknown> = Array<unknown>, TReturn = unknown> = InvokableFn<[args: MiddlewareArgs<TParameters, TReturn>], TReturn>; /** * A middleware in the execution chain. * * Can be either a function or an object implementation. Both forms have access to * the original arguments, the next middleware function, and the execution context. * * Middlewares are executed in order of priority (lower priority first), and each * middleware can: * - Log or monitor function calls * - Modify arguments before passing to next middleware * - Cache results * - Handle errors * - Modify return values * - Access and manipulate execution context * * @typeParam TParameters - Type of arguments passed to the function * @typeParam TReturn - Type of value returned from the function * * @see {@link MiddlewareFn | `MiddlewareFn`} * @see {@link IMiddlewareObject | `IMiddlewareObject`} * @see {@link MiddlewareArgs | `MiddlewareArgs`} * * IMPORT_PATH: `@daiso-tech/core/middleware` * @group Contracts */ export type Middleware<TParameters extends Array<unknown> = Array<unknown>, TReturn = unknown> = MiddlewareFn<TParameters, TReturn> | IMiddlewareObject<TParameters, TReturn>; /** * Function that applies a middleware chain to an invokable function or object. * * Wraps the provided invokable with the specified middlewares, creating a new function * that executes all middlewares in priority order before delegating to the original * invokable. The execution happens within the provided execution context. * * @typeParam TParameters - Type of arguments passed to the invokable * @typeParam TReturn - Type of value returned from the invokable * * @param invokable - The function or object to wrap with middleware * @param middlewares - One or more middleware to apply, executed in priority order * * @returns A new invokable function that applies the middleware chain * * @example * ```ts * const use = useFactory(); * * // Apply a single middleware * const logged = use(fetchData, loggingMiddleware); * * // Apply multiple middlewares (executed in priority order) * const enhanced = use(fetchData, [ * { priority: 0, invoke: authMiddleware }, * { priority: 10, invoke: cacheMiddleware }, * { priority: 20, invoke: loggingMiddleware } * ]); * * // Call the wrapped function * const result = logged(arg1, arg2); * ``` * * @see {@link UseFactorySettings | `UseFactorySettings`} * @see {@link Middleware | `Middleware`} * @see {@link Invokable | `Invokable`} * * IMPORT_PATH: `@daiso-tech/core/middleware` * @group Contracts */ export type Use = <TParameters extends Array<unknown>, TReturn>(invokable: Invokable<TParameters, TReturn>, middlewares: OneOrMore<Middleware<TParameters, TReturn>>) => InvokableFn<TParameters, TReturn>;