@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 • 3.57 kB
JavaScript
/**
* 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();
};
}
//# sourceMappingURL=abortSignal.js.map