@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.
105 lines • 3.65 kB
JavaScript
/**
* @module Middleware
*/
import {} from "../../../execution-context/contracts/_module.js";
import { NoOpExecutionContextAdapter } from "../../../execution-context/implementations/adapters/no-op-execution-context-adapter/no-op-execution-context-adapter.js";
import { ExecutionContext } from "../../../execution-context/implementations/derivables/_module.js";
import {} from "../../../middleware/contracts/_module.js";
import { resolveOneOrMore, isInvokableObject, resolveInvokable, } from "../../../utilities/_module.js";
/**
* @internal
*/
function isMiddlewareObject(middleware) {
return isInvokableObject(middleware);
}
/**
* @internal
*/
function resolveMiddleware(middleware, defaultPriority) {
if (isMiddlewareObject(middleware)) {
const { priority = defaultPriority } = middleware;
return {
priority,
invoke: middleware.invoke.bind(middleware),
};
}
else {
return {
priority: defaultPriority,
invoke: middleware,
};
}
}
/**
* @internal
*/
function resolveMiddlewares(middlewares, defaultPriority) {
return [
...resolveOneOrMore(middlewares).map((middleware) => resolveMiddleware(middleware, defaultPriority)),
].sort((a, b) => a.priority - b.priority);
}
/**
* Creates a middleware application function with optional custom settings.
*
* Returns a {@link Use | `Use`} function that can wrap invokables with middleware chains.
* The factory pattern allows reusing the same configuration across multiple invokables,
* including shared execution context and default middleware priority.
*
* @param settings - Configuration for the middleware application function
*
* @returns A {@link Use | `Use`} function configured with the provided settings
*
* @example
* ```ts
* import { useFactory } from '@daiso-tech/core/middleware';
*
* // Create with default settings
* const use = useFactory();
*
* // Create with custom execution context
* const customContext = new ExecutionContext(new MyAdapter());
* const useWithContext = useFactory({ executionContext: customContext });
*
* // Create with custom default priority
* const useWithPriority = useFactory({ defaultPriority: 50 });
*
* // Use the middleware application function
* const wrappedFunc = use(myFunction, [middleware1, middleware2]);
* const result = wrappedFunc(...args);
* ```
*
* @see {@link Use | `Use`}
* @see {@link UseFactorySettings | `UseFactorySettings`}
* @see {@link Middleware | `Middleware`}
*
* IMPORT_PATH: `@daiso-tech/core/middleware`
* @group Implementations
*/
export function useFactory(settings = {}) {
const { defaultPriority = 0, executionContext = new ExecutionContext(new NoOpExecutionContextAdapter()), } = settings;
return (invokable, middlewares) => {
const resolvedMiddlewares = resolveMiddlewares(middlewares, defaultPriority);
let func = resolveInvokable(invokable);
for (const middleware of [...resolvedMiddlewares].reverse()) {
const prevFunc = func;
func = (...args_) => {
const next = (args = args_) => {
return prevFunc(...args);
};
return middleware.invoke({
args: args_,
next,
context: executionContext,
});
};
}
const prevFunc = func;
func = (...args_) => {
return executionContext.run(() => {
return prevFunc(...args_);
});
};
return func;
};
}
//# sourceMappingURL=use-factory.js.map