UNPKG

@juspay/neurolink

Version:

Universal AI Development Platform with working MCP integration, multi-provider support, voice (TTS/STT/realtime), and professional CLI. 58+ external MCP servers discoverable, multimodal file processing, RAG pipelines. Build, test, and deploy AI applicatio

112 lines (111 loc) 3.54 kB
/** * Abort Signal Middleware * Provides client disconnection handling for long-running requests */ /** * Create abort signal middleware for handling client disconnections. * * This middleware creates an AbortController and attaches its signal to the context, * allowing route handlers to check for client disconnection during long-running operations. * * @param options - Optional configuration * @returns Middleware that attaches abort signal to context * * @example * ```typescript * const abortMiddleware = createAbortSignalMiddleware(); * server.registerMiddleware(abortMiddleware); * * // In route handler: * const signal = ctx.abortSignal; * await longRunningOperation({ signal }); * ``` */ export function createAbortSignalMiddleware(options) { const { onAbort, timeout } = options ?? {}; return { name: "abort-signal", order: 5, // Early in middleware chain handler: async (ctx, next) => { const controller = new AbortController(); let timeoutId; // Set up timeout if configured if (timeout && timeout > 0) { timeoutId = setTimeout(() => { controller.abort(new Error(`Request timeout after ${timeout}ms`)); }, timeout); } // Framework-specific abort handling setupFrameworkAbortHandler(ctx, controller, onAbort); // Attach signal to context ctx.abortSignal = controller.signal; ctx.abortController = controller; try { return await next(); } finally { // Clean up timeout if (timeoutId) { clearTimeout(timeoutId); } } }, }; } /** * Set up framework-specific abort handling */ function setupFrameworkAbortHandler(ctx, controller, onAbort) { const frameworkResponse = ctx.rawResponse; if (!frameworkResponse) { return; } // Express: res.on('close') if (typeof frameworkResponse.on === "function") { const res = frameworkResponse; res.on("close", () => { if (!res.writableFinished) { controller.abort(new Error("Client disconnected")); onAbort?.(ctx); } }); } // Hono/Fastify: May have different event patterns // Add additional framework support as needed } /** * Express-specific middleware factory. * Use this directly with Express adapter for optimal handling. * * This is a lower-level middleware that works directly with Express * request/response objects rather than the unified ServerContext. * * @param options - Optional configuration * @returns Express middleware function * * @example * ```typescript * // In Express adapter * app.use(createExpressAbortMiddleware()); * * // Access in route handler * app.get('/api/stream', (req, res) => { * const signal = res.locals.abortSignal; * // Use signal for cancellation * }); * ``` */ export function createExpressAbortMiddleware(options) { return (_req, res, next) => { const controller = new AbortController(); res.on("close", () => { if (!res.writableFinished) { controller.abort(new Error("Client disconnected")); options?.onAbort?.({}); } }); res.locals.abortSignal = controller.signal; res.locals.abortController = controller; next(); }; }