@whatwg-node/server
Advanced tools
Comparing version 0.10.0-alpha-20250205002109-e61c2d65aed8aa582581368511e66b20e33632b8 to 0.10.0-alpha-20250205010145-5ab5edf75d82f8174c999dc970ad9a042ea5547d
@@ -278,3 +278,7 @@ "use strict"; | ||
const res$ = handleRequestWithWaitUntil(request, ...restOfCtx); | ||
return (0, utils_js_1.handleAbortSignalAndPromiseResponse)(res$, initOrCtx?.signal); | ||
const signal = initOrCtx.signal; | ||
if (signal) { | ||
return (0, utils_js_1.handleAbortSignalAndPromiseResponse)(res$, signal); | ||
} | ||
return res$; | ||
} | ||
@@ -281,0 +285,0 @@ const request = new fetchAPI.Request(input); |
@@ -49,5 +49,4 @@ "use strict"; | ||
}, | ||
onResponse({ request, response, setResponse, fetchAPI, serverContext }) { | ||
// Hack for avoiding to create whatwg-node to create a readable stream until it's needed | ||
if (response['bodyInit'] || response.body) { | ||
onResponse({ request, response, setResponse, fetchAPI }) { | ||
if (response.body) { | ||
const encodings = encodingMap.get(request); | ||
@@ -58,38 +57,8 @@ if (encodings) { | ||
const compressionStream = new fetchAPI.CompressionStream(supportedEncoding); | ||
// To calculate final content-length | ||
const contentLength = response.headers.get('content-length'); | ||
if (contentLength) { | ||
const bufOfRes = response._buffer; | ||
if (bufOfRes) { | ||
const writer = compressionStream.writable.getWriter(); | ||
const write$ = writer.write(bufOfRes); | ||
serverContext.waitUntil?.(write$); | ||
const close$ = writer.close(); | ||
serverContext.waitUntil?.(close$); | ||
const uint8Arrays$ = (0, utils_js_1.isReadable)(compressionStream.readable['readable']) | ||
? collectReadableValues(compressionStream.readable['readable']) | ||
: (0, utils_js_1.isAsyncIterable)(compressionStream.readable) | ||
? collectAsyncIterableValues(compressionStream.readable) | ||
: collectReadableStreamValues(compressionStream.readable); | ||
return uint8Arrays$.then(uint8Arrays => { | ||
const chunks = uint8Arrays.flatMap(uint8Array => [...uint8Array]); | ||
const uint8Array = new Uint8Array(chunks); | ||
const newHeaders = new fetchAPI.Headers(response.headers); | ||
newHeaders.set('content-encoding', supportedEncoding); | ||
newHeaders.set('content-length', uint8Array.byteLength.toString()); | ||
const compressedResponse = new fetchAPI.Response(uint8Array, { | ||
...response, | ||
headers: newHeaders, | ||
}); | ||
utils_js_1.decompressedResponseMap.set(compressedResponse, response); | ||
setResponse(compressedResponse); | ||
const close$ = compressionStream.writable.close(); | ||
serverContext.waitUntil?.(close$); | ||
}); | ||
} | ||
} | ||
const newHeaders = new fetchAPI.Headers(response.headers); | ||
newHeaders.set('content-encoding', supportedEncoding); | ||
newHeaders.delete('content-length'); | ||
const compressedBody = response.body.pipeThrough(compressionStream); | ||
const compressedBody = response.body.pipeThrough(compressionStream, { | ||
signal: request.signal, | ||
}); | ||
const compressedResponse = new fetchAPI.Response(compressedBody, { | ||
@@ -108,31 +77,1 @@ status: response.status, | ||
} | ||
function collectReadableValues(readable) { | ||
const values = []; | ||
readable.on('data', value => values.push(value)); | ||
return new Promise((resolve, reject) => { | ||
readable.once('end', () => resolve(values)); | ||
readable.once('error', reject); | ||
}); | ||
} | ||
async function collectAsyncIterableValues(asyncIterable) { | ||
const values = []; | ||
for await (const value of asyncIterable) { | ||
values.push(value); | ||
} | ||
return values; | ||
} | ||
async function collectReadableStreamValues(readableStream) { | ||
const reader = readableStream.getReader(); | ||
const values = []; | ||
while (true) { | ||
const { done, value } = await reader.read(); | ||
if (done) { | ||
reader.releaseLock(); | ||
break; | ||
} | ||
else if (value) { | ||
values.push(value); | ||
} | ||
} | ||
return values; | ||
} |
@@ -451,5 +451,6 @@ "use strict"; | ||
const deferred$ = createDeferredPromise(); | ||
abortSignal.addEventListener('abort', function abortSignalFetchErrorHandler() { | ||
function abortSignalFetchErrorHandler() { | ||
deferred$.reject(abortSignal.reason); | ||
}, { once: true }); | ||
} | ||
abortSignal.addEventListener('abort', abortSignalFetchErrorHandler, { once: true }); | ||
response$ | ||
@@ -461,2 +462,5 @@ .then(function fetchSuccessHandler(res) { | ||
deferred$.reject(err); | ||
}) | ||
.finally(() => { | ||
abortSignal.removeEventListener('abort', abortSignalFetchErrorHandler); | ||
}); | ||
@@ -463,0 +467,0 @@ return deferred$.promise; |
@@ -274,3 +274,7 @@ import { AsyncDisposableStack, DisposableSymbols } from '@whatwg-node/disposablestack'; | ||
const res$ = handleRequestWithWaitUntil(request, ...restOfCtx); | ||
return handleAbortSignalAndPromiseResponse(res$, initOrCtx?.signal); | ||
const signal = initOrCtx.signal; | ||
if (signal) { | ||
return handleAbortSignalAndPromiseResponse(res$, signal); | ||
} | ||
return res$; | ||
} | ||
@@ -277,0 +281,0 @@ const request = new fetchAPI.Request(input); |
@@ -1,2 +0,2 @@ | ||
import { decompressedResponseMap, getSupportedEncodings, isAsyncIterable, isReadable, } from '../utils.js'; | ||
import { decompressedResponseMap, getSupportedEncodings } from '../utils.js'; | ||
export function useContentEncoding() { | ||
@@ -46,5 +46,4 @@ const encodingMap = new WeakMap(); | ||
}, | ||
onResponse({ request, response, setResponse, fetchAPI, serverContext }) { | ||
// Hack for avoiding to create whatwg-node to create a readable stream until it's needed | ||
if (response['bodyInit'] || response.body) { | ||
onResponse({ request, response, setResponse, fetchAPI }) { | ||
if (response.body) { | ||
const encodings = encodingMap.get(request); | ||
@@ -55,38 +54,8 @@ if (encodings) { | ||
const compressionStream = new fetchAPI.CompressionStream(supportedEncoding); | ||
// To calculate final content-length | ||
const contentLength = response.headers.get('content-length'); | ||
if (contentLength) { | ||
const bufOfRes = response._buffer; | ||
if (bufOfRes) { | ||
const writer = compressionStream.writable.getWriter(); | ||
const write$ = writer.write(bufOfRes); | ||
serverContext.waitUntil?.(write$); | ||
const close$ = writer.close(); | ||
serverContext.waitUntil?.(close$); | ||
const uint8Arrays$ = isReadable(compressionStream.readable['readable']) | ||
? collectReadableValues(compressionStream.readable['readable']) | ||
: isAsyncIterable(compressionStream.readable) | ||
? collectAsyncIterableValues(compressionStream.readable) | ||
: collectReadableStreamValues(compressionStream.readable); | ||
return uint8Arrays$.then(uint8Arrays => { | ||
const chunks = uint8Arrays.flatMap(uint8Array => [...uint8Array]); | ||
const uint8Array = new Uint8Array(chunks); | ||
const newHeaders = new fetchAPI.Headers(response.headers); | ||
newHeaders.set('content-encoding', supportedEncoding); | ||
newHeaders.set('content-length', uint8Array.byteLength.toString()); | ||
const compressedResponse = new fetchAPI.Response(uint8Array, { | ||
...response, | ||
headers: newHeaders, | ||
}); | ||
decompressedResponseMap.set(compressedResponse, response); | ||
setResponse(compressedResponse); | ||
const close$ = compressionStream.writable.close(); | ||
serverContext.waitUntil?.(close$); | ||
}); | ||
} | ||
} | ||
const newHeaders = new fetchAPI.Headers(response.headers); | ||
newHeaders.set('content-encoding', supportedEncoding); | ||
newHeaders.delete('content-length'); | ||
const compressedBody = response.body.pipeThrough(compressionStream); | ||
const compressedBody = response.body.pipeThrough(compressionStream, { | ||
signal: request.signal, | ||
}); | ||
const compressedResponse = new fetchAPI.Response(compressedBody, { | ||
@@ -105,31 +74,1 @@ status: response.status, | ||
} | ||
function collectReadableValues(readable) { | ||
const values = []; | ||
readable.on('data', value => values.push(value)); | ||
return new Promise((resolve, reject) => { | ||
readable.once('end', () => resolve(values)); | ||
readable.once('error', reject); | ||
}); | ||
} | ||
async function collectAsyncIterableValues(asyncIterable) { | ||
const values = []; | ||
for await (const value of asyncIterable) { | ||
values.push(value); | ||
} | ||
return values; | ||
} | ||
async function collectReadableStreamValues(readableStream) { | ||
const reader = readableStream.getReader(); | ||
const values = []; | ||
while (true) { | ||
const { done, value } = await reader.read(); | ||
if (done) { | ||
reader.releaseLock(); | ||
break; | ||
} | ||
else if (value) { | ||
values.push(value); | ||
} | ||
} | ||
return values; | ||
} |
@@ -429,5 +429,6 @@ export function isAsyncIterable(body) { | ||
const deferred$ = createDeferredPromise(); | ||
abortSignal.addEventListener('abort', function abortSignalFetchErrorHandler() { | ||
function abortSignalFetchErrorHandler() { | ||
deferred$.reject(abortSignal.reason); | ||
}, { once: true }); | ||
} | ||
abortSignal.addEventListener('abort', abortSignalFetchErrorHandler, { once: true }); | ||
response$ | ||
@@ -439,2 +440,5 @@ .then(function fetchSuccessHandler(res) { | ||
deferred$.reject(err); | ||
}) | ||
.finally(() => { | ||
abortSignal.removeEventListener('abort', abortSignalFetchErrorHandler); | ||
}); | ||
@@ -441,0 +445,0 @@ return deferred$.promise; |
{ | ||
"name": "@whatwg-node/server", | ||
"version": "0.10.0-alpha-20250205002109-e61c2d65aed8aa582581368511e66b20e33632b8", | ||
"version": "0.10.0-alpha-20250205010145-5ab5edf75d82f8174c999dc970ad9a042ea5547d", | ||
"description": "Fetch API compliant HTTP Server adapter", | ||
@@ -5,0 +5,0 @@ "sideEffects": false, |
@@ -43,3 +43,3 @@ import type { IncomingMessage, ServerResponse } from 'node:http'; | ||
export declare function createDeferredPromise<T = void>(): DeferredPromise<T>; | ||
export declare function handleAbortSignalAndPromiseResponse(response$: Promise<Response> | Response, abortSignal?: AbortSignal | null): Response | Promise<Response>; | ||
export declare function handleAbortSignalAndPromiseResponse(response$: Promise<Response> | Response, abortSignal: AbortSignal): Response | Promise<Response>; | ||
export declare const decompressedResponseMap: WeakMap<Response, Response>; | ||
@@ -46,0 +46,0 @@ export declare function getSupportedEncodings(fetchAPI: FetchAPI): CompressionFormat[]; |
Sorry, the diff of this file is not supported yet
162732
3173