/** * @module Middleware */ import { type InvocableFn, type IInvocableObject, type OneOrMore, type Invocable } 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 = Array, TReturn = unknown> = InvocableFn<[args?: TParameters], TReturn>; /** * Arguments passed to middleware functions during execution. * * Contains the original function arguments, a reference to the next middleware in the chain. * * @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 }) => { * 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 = Array, TReturn = unknown> = { /** * The arguments passed to the original function */ args: TParameters; /** * Function to call the next middleware or final function */ next: NextFn; /** * The name of the function. */ name: string; }; /** * 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 = Array, TReturn = unknown> = IInvocableObject<[args: MiddlewareArgs], 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 * * IMPORT_PATH: `@daiso-tech/core/middleware` * @group Contracts */ export type MiddlewareFn = Array, TReturn = unknown> = InvocableFn<[args: MiddlewareArgs], TReturn>; /** * Defines a middleware function with type inference. * * A convenience helper that ensures the provided handler conforms to the * {@link MiddlewareFn} signature while preserving exact parameter and * return types. This allows TypeScript to infer narrower types for * `TParameters` and `TReturn` without needing explicit generic annotations * on the handler. * * Use this when defining middleware functions to get accurate type checking * and IntelliSense without sacrificing type safety. * * @typeParam TParameters - Type of arguments passed through the middleware chain * @typeParam TReturn - Type of value returned from the function * @param middleware - A function conforming to {@link MiddlewareFn}. * @returns The same handler, typed as {@link MiddlewareFn}. * * @example * ```ts * const loggingMiddleware = defineMiddleware(({ args, next, context }) => { * console.log('Before:', args); * const result = next(args); * console.log('After:', result); * return result; * }); * ``` * * IMPORT_PATH: `@daiso-tech/core/middleware` * @group Contracts */ export declare function defineMiddleware = Array, TReturn = unknown>(middleware: MiddlewareFn): MiddlewareFn; /** * 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. * * 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 * * @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 = Array, TReturn = unknown> = MiddlewareFn | IMiddlewareObject; /** * Function that applies a middleware chain to an invocable function or object. * * Wraps the provided invocable with the specified middlewares, creating a new function * that executes all middlewares in priority order before delegating to the original * invocable. * * @typeParam TParameters - Type of arguments passed to the invocable * @typeParam TReturn - Type of value returned from the invocable * * @param invocable - The function or object to wrap with middleware * @param middlewares - One or more middleware to apply, executed in priority order * * @returns A new invocable function that applies the middleware chain * * @example * ```ts * function main(use: Use): void { * // 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 Invocable | `Invocable`} * * IMPORT_PATH: `@daiso-tech/core/middleware` * @group Contracts */ export type Use = , TReturn>(invocable: Invocable, middlewares: OneOrMore>) => InvocableFn;