UNPKG

@noony-serverless/core

Version:

A Middy base framework compatible with Firebase and GCP Cloud Functions with TypeScript

151 lines 5.62 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Handler = void 0; // Container import removed - now using containerPool for performance const core_1 = require("./core"); const containerPool_1 = require("./containerPool"); /** * The Handler class is responsible for managing and executing middleware functions * and a main handler function in a sequential and controlled manner. * * This class provides a mechanism for registering middlewares that can * process a request/response flow either before the main handler (via `before`), * after the main handler (via `after`), or handle errors (via `onError`). * * interface MessagePayload { * action: string; * data: Record<string, unknown>; * } * * const handler = new Handler<MessagePayload>() * .use(errorHandler()) * .use(bodyParser()) * .handle(async (context) => { * const { req } = context; * // Handle the request * }); * @template T Type for the input request data. * @template U Type for the additional context or response data. */ class Handler { baseMiddlewares = []; handler; // Performance optimization: Pre-computed middleware arrays reversedMiddlewares = []; errorMiddlewares = []; middlewaresPrecomputed = false; static use(middleware) { const handler = new Handler(); handler.baseMiddlewares.push(middleware); return handler; } use(middleware) { const handler = new Handler(); handler.baseMiddlewares = [ ...this.baseMiddlewares, middleware, ]; return handler; } handle(handler) { this.handler = handler; this.precomputeMiddlewareArrays(); return this; } /** * Performance optimization: Pre-compute middleware arrays to avoid runtime array operations */ precomputeMiddlewareArrays() { if (this.middlewaresPrecomputed) return; // Pre-compute reversed array for after/error middlewares this.reversedMiddlewares = [...this.baseMiddlewares].reverse(); this.errorMiddlewares = this.reversedMiddlewares.filter((m) => m.onError); this.middlewaresPrecomputed = true; } async execute(req, res) { const genericReq = (0, core_1.adaptGCPRequest)(req); const genericRes = (0, core_1.adaptGCPResponse)(res); // Performance optimization: Use container pool instead of creating new containers const container = containerPool_1.containerPool.acquire(); const context = (0, core_1.createContext)(genericReq, genericRes, { container, }); try { // Execute before middlewares with performance optimizations await this.executeBeforeMiddlewares(context); await this.handler(context); // Execute after middlewares in reverse order using pre-computed array await this.executeAfterMiddlewares(context); } catch (error) { context.error = error; // Execute error handlers using pre-computed array await this.executeErrorMiddlewares(error, context); } finally { // Always return container to pool for reuse containerPool_1.containerPool.release(container); } } /** * Execute before middlewares with optimized batching for independent middlewares */ async executeBeforeMiddlewares(context) { // For backward compatibility and simpler logic, execute all before middlewares in order for (const middleware of this.baseMiddlewares) { if (middleware.before) { await middleware.before(context); } } } /** * Execute after middlewares using pre-computed reversed array */ async executeAfterMiddlewares(context) { // For backward compatibility and simpler logic, execute all after middlewares in reverse order for (const middleware of this.reversedMiddlewares) { if (middleware.after) { await middleware.after(context); } } } /** * Execute error middlewares using pre-computed array */ async executeErrorMiddlewares(error, context) { for (const middleware of this.errorMiddlewares) { if (middleware.onError) { await middleware.onError(error, context); } } } /** * Framework-agnostic execute method that works with GenericRequest/GenericResponse */ async executeGeneric(req, res) { // Performance optimization: Use container pool instead of creating new containers const container = containerPool_1.containerPool.acquire(); const context = (0, core_1.createContext)(req, res, { container, }); try { // Execute before middlewares with performance optimizations await this.executeBeforeMiddlewares(context); await this.handler(context); // Execute after middlewares in reverse order using pre-computed array await this.executeAfterMiddlewares(context); } catch (error) { context.error = error; // Execute error handlers using pre-computed array await this.executeErrorMiddlewares(error, context); } finally { // Always return container to pool for reuse containerPool_1.containerPool.release(container); } } } exports.Handler = Handler; //# sourceMappingURL=handler.js.map