From 2d7db14210a1b482196b337d608a7dced2d56cf3 Mon Sep 17 00:00:00 2001 From: ViniciusCestarii Date: Tue, 25 Feb 2025 11:40:41 -0300 Subject: [PATCH 1/2] feat: add stop function to adapter interface --- src/adapter/bun/index.ts | 101 ++++++++++++++++++++++----------------- src/adapter/types.ts | 15 ++++++ src/index.ts | 14 +----- 3 files changed, 75 insertions(+), 55 deletions(-) diff --git a/src/adapter/bun/index.ts b/src/adapter/bun/index.ts index ff83e33a..0eb00d7d 100644 --- a/src/adapter/bun/index.ts +++ b/src/adapter/bun/index.ts @@ -38,8 +38,8 @@ export const BunAdapter: ElysiaAdapter = { headers: hasHeaderShorthand ? 'c.headers = c.request.headers.toJSON()\n' : 'c.headers = {}\n' + - 'for (const [key, value] of c.request.headers.entries())' + - 'c.headers[key] = value\n' + 'for (const [key, value] of c.request.headers.entries())' + + 'c.headers[key] = value\n' }, listen(app) { return (options, callback) => { @@ -62,38 +62,38 @@ export const BunAdapter: ElysiaAdapter = { const serve = typeof options === 'object' ? ({ - development: !isProduction, - reusePort: true, - ...(app.config.serve || {}), - ...(options || {}), - // @ts-ignore - static: { - ...app.router.static.http.static, - ...app.config.serve?.static - }, - websocket: { - ...(app.config.websocket || {}), - ...(websocket || {}) - }, - fetch, - // @ts-expect-error private property - error: app.outerErrorHandler - } as Serve) + development: !isProduction, + reusePort: true, + ...(app.config.serve || {}), + ...(options || {}), + // @ts-ignore + static: { + ...app.router.static.http.static, + ...app.config.serve?.static + }, + websocket: { + ...(app.config.websocket || {}), + ...(websocket || {}) + }, + fetch, + // @ts-expect-error private property + error: app.outerErrorHandler + } as Serve) : ({ - development: !isProduction, - reusePort: true, - ...(app.config.serve || {}), - // @ts-ignore - static: app.router.static.http.static, - websocket: { - ...(app.config.websocket || {}), - ...(websocket || {}) - }, - port: options, - fetch, - // @ts-expect-error private property - error: app.outerErrorHandler - } as Serve) + development: !isProduction, + reusePort: true, + ...(app.config.serve || {}), + // @ts-ignore + static: app.router.static.http.static, + websocket: { + ...(app.config.websocket || {}), + ...(websocket || {}) + }, + port: options, + fetch, + // @ts-expect-error private property + error: app.outerErrorHandler + } as Serve) app.server = Bun?.serve(serve) @@ -120,6 +120,21 @@ export const BunAdapter: ElysiaAdapter = { }) } }, + async stop(app, closeActiveConnections) { + if (!app.server) + throw new Error( + "Elysia isn't running. Call `app.listen` to start the server." + ) + + if (app.server) { + app.server.stop(closeActiveConnections) + app.server = null + + if (app.event.stop?.length) + for (let i = 0; i < app.event.stop.length; i++) + app.event.stop[i].fn(app) + } + }, ws(app, path, options) { // eslint-disable-next-line @typescript-eslint/no-unused-vars const { parse, body, response, ...rest } = options @@ -195,20 +210,20 @@ export const BunAdapter: ElysiaAdapter = { ] const handleErrors = !errorHandlers.length - ? () => {} + ? () => { } : async (ws: ServerWebSocket, error: unknown) => { - for (const handleError of errorHandlers) { - let response = handleError( - Object.assign(context, { error }) - ) - if (response instanceof Promise) - response = await response + for (const handleError of errorHandlers) { + let response = handleError( + Object.assign(context, { error }) + ) + if (response instanceof Promise) + response = await response - await handleResponse(ws, response) + await handleResponse(ws, response) - if (response) break - } + if (response) break } + } if ( server?.upgrade(context.request, { diff --git a/src/adapter/types.ts b/src/adapter/types.ts index e64eb45e..85f83776 100644 --- a/src/adapter/types.ts +++ b/src/adapter/types.ts @@ -15,6 +15,21 @@ export interface ElysiaAdapter { options: string | number | Partial, callback?: ListenCallback ) => void + /** + * Stop server from serving + * + * --- + * @example + * ```typescript + * app.stop() + * ``` + * + * @example + * ```typescript + * app.stop(true) // Abruptly any requests inflight + * ``` + */ + stop(app: AnyElysia, closeActiveConnections?: boolean): Promise isWebStandard?: boolean handler: { /** diff --git a/src/index.ts b/src/index.ts index 402c7534..5554d9bc 100644 --- a/src/index.ts +++ b/src/index.ts @@ -6397,19 +6397,9 @@ export default class Elysia< * ``` */ stop = async (closeActiveConnections?: boolean) => { - if (!this.server) - throw new Error( - "Elysia isn't running. Call `app.listen` to start the server." - ) - - if (this.server) { - this.server.stop(closeActiveConnections) - this.server = null + await this['~adapter'].stop(this, closeActiveConnections) - if (this.event.stop?.length) - for (let i = 0; i < this.event.stop.length; i++) - this.event.stop[i].fn(this) - } + return this } /** From d3bb0ed0627b6f134abc0743bca83ebc240269d8 Mon Sep 17 00:00:00 2001 From: ViniciusCestarii Date: Tue, 25 Feb 2025 11:46:03 -0300 Subject: [PATCH 2/2] feat: add stop function WebStandardAdapter --- src/adapter/web-standard/index.ts | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/adapter/web-standard/index.ts b/src/adapter/web-standard/index.ts index 8867da88..6de2e239 100644 --- a/src/adapter/web-standard/index.ts +++ b/src/adapter/web-standard/index.ts @@ -61,6 +61,21 @@ export const WebStandardAdapter: ElysiaAdapter = { } } }, + async stop(app, closeActiveConnections) { + if (!app.server) + throw new Error( + "Elysia isn't running. Call `app.listen` to start the server." + ) + + if (app.server) { + app.server.stop(closeActiveConnections) + app.server = null + + if (app.event.stop?.length) + for (let i = 0; i < app.event.stop.length; i++) + app.event.stop[i].fn(app) + } + }, composeGeneralHandler: { parameters: 'r', createContext(app) {