diff --git a/lib/server-response-adapter.ts b/lib/server-response-adapter.ts index 314f2ac..279d6de 100644 --- a/lib/server-response-adapter.ts +++ b/lib/server-response-adapter.ts @@ -16,108 +16,112 @@ export function createServerResponseAdapter( fn: (re: ServerResponse) => Promise | void, ): Promise { let writeHeadResolver: (v: WriteheadArgs) => void - const writeHeadPromise = new Promise( - async (resolve, reject) => { - writeHeadResolver = resolve - }, - ) - - return new Promise(async (resolve, reject) => { - let controller: ReadableStreamController | undefined - let shouldClose = false - let wroteHead = false - - const writeHead = ( - statusCode: number, - headers?: Record, - ) => { - if (typeof headers === 'string') { - throw new Error('Status message of writeHead not supported') - } - wroteHead = true - writeHeadResolver({ - statusCode, - headers, - }) - return fakeServerResponse - } + const writeHeadPromise = new Promise((resolve) => { + writeHeadResolver = resolve + }) - const bufferedData: Uint8Array[] = [] + return new Promise((resolve, reject) => { + ;(async () => { + let controller: ReadableStreamController | undefined + let shouldClose = false + let wroteHead = false - const write = ( - chunk: Buffer | string, - encoding?: BufferEncoding, - ): boolean => { - if (encoding) { - throw new Error('Encoding not supported') - } - if (chunk instanceof Buffer) { - throw new Error('Buffer not supported') - } - if (!wroteHead) { - writeHead(200) - } - if (!controller) { - bufferedData.push(new TextEncoder().encode(chunk as string)) - return true + const writeHead = ( + statusCode: number, + headers?: Record, + ) => { + if (typeof headers === 'string') { + throw new Error('Status message of writeHead not supported') + } + wroteHead = true + writeHeadResolver({ + statusCode, + headers, + }) + return fakeServerResponse } - controller.enqueue(new TextEncoder().encode(chunk as string)) - return true - } - const eventEmitter = new EventEmitter() + const bufferedData: Uint8Array[] = [] - const fakeServerResponse = { - writeHead, - write, - end: (data?: Buffer | string) => { - if (data) { - write(data) + const write = ( + chunk: Buffer | string, + encoding?: BufferEncoding, + ): boolean => { + if (encoding) { + throw new Error('Encoding not supported') } - - if (!controller) { - shouldClose = true - return fakeServerResponse + if (chunk instanceof Buffer) { + throw new Error('Buffer not supported') } - try { - controller.close() - } catch { - /* May be closed on tcp layer */ + if (!wroteHead) { + writeHead(200) } - return fakeServerResponse - }, - on: (event: string, listener: (...args: any[]) => void) => { - eventEmitter.on(event, listener) - return fakeServerResponse - }, - } - - signal.addEventListener('abort', () => { - eventEmitter.emit('close') - }) + if (!controller) { + bufferedData.push(new TextEncoder().encode(chunk as string)) + return true + } + controller.enqueue(new TextEncoder().encode(chunk as string)) + return true + } - fn(fakeServerResponse as ServerResponse) + const eventEmitter = new EventEmitter() - const head = await writeHeadPromise + const fakeServerResponse = { + writeHead, + write, + end: (data?: Buffer | string) => { + if (data) { + write(data) + } - const response = new Response( - new ReadableStream({ - start(c) { - controller = c - for (const chunk of bufferedData) { - controller.enqueue(chunk) + if (!controller) { + shouldClose = true + return fakeServerResponse } - if (shouldClose) { + try { controller.close() + } catch { + /* May be closed on tcp layer */ } + return fakeServerResponse + }, + on: (event: string, listener: (...args: unknown[]) => void) => { + eventEmitter.on(event, listener) + return fakeServerResponse }, - }), - { - status: head.statusCode, - headers: head.headers, - }, - ) + } + + signal.addEventListener('abort', () => { + eventEmitter.emit('close') + }) - resolve(response) + fn(fakeServerResponse as ServerResponse) + + try { + const head = await writeHeadPromise + + const response = new Response( + new ReadableStream({ + start(c) { + controller = c + for (const chunk of bufferedData) { + controller.enqueue(chunk) + } + if (shouldClose) { + controller.close() + } + }, + }), + { + status: head.statusCode, + headers: head.headers, + }, + ) + + resolve(response) + } catch (error) { + reject(error) + } + })() }) } diff --git a/lib/utils.ts b/lib/utils.ts index fed2fe9..d32b0fe 100644 --- a/lib/utils.ts +++ b/lib/utils.ts @@ -1,4 +1,4 @@ -import { clsx, type ClassValue } from 'clsx' +import { type ClassValue, clsx } from 'clsx' import { twMerge } from 'tailwind-merge' export function cn(...inputs: ClassValue[]) {