Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@whatwg-node/server

Package Overview
Dependencies
Maintainers
0
Versions
736
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@whatwg-node/server - npm Package Compare versions

Comparing version 0.9.56 to 0.9.57-alpha-20241123125835-498ddbef3a79038cbe04d8cef8c2cc1d83e7573c

60

cjs/createServerAdapter.js

@@ -6,8 +6,6 @@ "use strict";

/* eslint-disable @typescript-eslint/ban-types */
const disposablestack_1 = require("@whatwg-node/disposablestack");
const DefaultFetchAPI = tslib_1.__importStar(require("@whatwg-node/fetch"));
const utils_js_1 = require("./utils.js");
const uwebsockets_js_1 = require("./uwebsockets.js");
async function handleWaitUntils(waitUntilPromises) {
await Promise.allSettled(waitUntilPromises);
}
// Required for envs like nextjs edge runtime

@@ -33,2 +31,32 @@ function isRequestAccessible(serverContext) {

const onResponseHooks = [];
const waitUntilPromises = new Set();
const disposableStack = new disposablestack_1.AsyncDisposableStack();
const signals = new Set();
function registerSignal(signal) {
signals.add(signal);
signal.addEventListener('abort', () => {
signals.delete(signal);
});
}
disposableStack.defer(() => {
for (const signal of signals) {
signal.sendAbort();
}
});
function handleWaitUntils() {
return Promise.allSettled(waitUntilPromises).then(() => { }, () => { });
}
disposableStack.defer(handleWaitUntils);
function waitUntil(promiseLike) {
// If it is a Node.js environment, we should register the disposable stack to handle process termination events
if (globalThis.process) {
(0, utils_js_1.ensureDisposableStackRegisteredForTerminateEvents)(disposableStack);
}
waitUntilPromises.add(promiseLike.then(() => {
waitUntilPromises.delete(promiseLike);
}, err => {
console.error(`Unexpected error while waiting: ${err.message || err}`);
waitUntilPromises.delete(promiseLike);
}));
}
if (options?.plugins != null) {

@@ -114,3 +142,3 @@ for (const plugin of options.plugins) {

const serverContext = ctx.length > 1 ? (0, utils_js_1.completeAssign)(...ctx) : ctx[0] || {};
const request = (0, utils_js_1.normalizeNodeRequest)(nodeRequest, fetchAPI);
const request = (0, utils_js_1.normalizeNodeRequest)(nodeRequest, fetchAPI, registerSignal);
return handleRequest(request, serverContext);

@@ -124,9 +152,6 @@ }

function requestListener(nodeRequest, nodeResponse, ...ctx) {
const waitUntilPromises = [];
const defaultServerContext = {
req: nodeRequest,
res: nodeResponse,
waitUntil(cb) {
waitUntilPromises.push(cb.catch(err => console.error(err)));
},
waitUntil,
};

@@ -156,9 +181,6 @@ let response$;

function handleUWS(res, req, ...ctx) {
const waitUntilPromises = [];
const defaultServerContext = {
res,
req,
waitUntil(cb) {
waitUntilPromises.push(cb.catch(err => console.error(err)));
},
waitUntil,
};

@@ -170,2 +192,3 @@ const filteredCtxParts = ctx.filter(partCtx => partCtx != null);

const signal = new utils_js_1.ServerAdapterRequestAbortSignal();
registerSignal(signal);
const originalResEnd = res.end.bind(res);

@@ -231,13 +254,8 @@ let resEnded = false;

const filteredCtxParts = ctx.filter(partCtx => partCtx != null);
let waitUntilPromises;
const serverContext = filteredCtxParts.length > 1
? (0, utils_js_1.completeAssign)({}, ...filteredCtxParts)
: (0, utils_js_1.isolateObject)(filteredCtxParts[0], filteredCtxParts[0] == null || filteredCtxParts[0].waitUntil == null
? (waitUntilPromises = [])
? waitUntil
: undefined);
const response$ = handleRequest(request, serverContext);
if (waitUntilPromises?.length) {
return handleWaitUntils(waitUntilPromises).then(() => response$);
}
return response$;
return handleRequest(request, serverContext);
}

@@ -295,2 +313,6 @@ const fetchFn = (input, ...maybeCtx) => {

handle: genericRequestHandler,
disposableStack,
[disposablestack_1.DisposableSymbols.asyncDispose]() {
return disposableStack.disposeAsync();
},
};

@@ -297,0 +319,0 @@ const serverAdapter = new Proxy(genericRequestHandler, {

@@ -22,2 +22,3 @@ "use strict";

exports.handleResponseDecompression = handleResponseDecompression;
exports.ensureDisposableStackRegisteredForTerminateEvents = ensureDisposableStackRegisteredForTerminateEvents;
function isAsyncIterable(body) {

@@ -105,3 +106,3 @@ return (body != null && typeof body === 'object' && typeof body[Symbol.asyncIterator] === 'function');

exports.nodeRequestResponseMap = new WeakMap();
function normalizeNodeRequest(nodeRequest, fetchAPI) {
function normalizeNodeRequest(nodeRequest, fetchAPI, registerSignal) {
const rawRequest = nodeRequest.raw || nodeRequest.req || nodeRequest;

@@ -132,3 +133,5 @@ let fullUrl = buildFullUrl(rawRequest);

if (fetchAPI.Request !== globalThis.Request) {
signal = new ServerAdapterRequestAbortSignal();
const newSignal = new ServerAdapterRequestAbortSignal();
registerSignal?.(newSignal);
signal = newSignal;
sendAbortSignal = () => signal.sendAbort();

@@ -446,17 +449,13 @@ }

}
function isolateObject(originalCtx, waitUntilPromises) {
function isolateObject(originalCtx, waitUntilFn) {
if (originalCtx == null) {
if (waitUntilPromises == null) {
if (waitUntilFn == null) {
return {};
}
return {
waitUntil(promise) {
waitUntilPromises.push(promise.catch(err => console.error(err)));
},
waitUntil: waitUntilFn,
};
}
return completeAssign(Object.create(originalCtx), {
waitUntil(promise) {
waitUntilPromises?.push(promise.catch(err => console.error(err)));
},
waitUntil: waitUntilFn,
}, originalCtx);

@@ -555,1 +554,28 @@ }

}
const terminateEvents = ['SIGINT', 'SIGTERM', 'exit'];
const disposableStacks = new Set();
let eventListenerRegistered = false;
function ensureEventListenerForDisposableStacks() {
if (eventListenerRegistered) {
return;
}
eventListenerRegistered = true;
for (const event of terminateEvents) {
globalThis.process.once(event, function terminateHandler() {
return Promise.allSettled([...disposableStacks].map(stack => stack.disposeAsync().catch(e => {
console.error('Error while disposing:', e);
})));
});
}
}
function ensureDisposableStackRegisteredForTerminateEvents(disposableStack) {
if (globalThis.process) {
ensureEventListenerForDisposableStacks();
if (!disposableStacks.has(disposableStack)) {
disposableStacks.add(disposableStack);
disposableStack.defer(() => {
disposableStacks.delete(disposableStack);
});
}
}
}
/* eslint-disable @typescript-eslint/ban-types */
import { AsyncDisposableStack, DisposableSymbols } from '@whatwg-node/disposablestack';
import * as DefaultFetchAPI from '@whatwg-node/fetch';
import { completeAssign, handleAbortSignalAndPromiseResponse, handleErrorFromRequestHandler, isFetchEvent, isNodeRequest, isolateObject, isPromise, isRequestInit, isServerResponse, iterateAsyncVoid, nodeRequestResponseMap, normalizeNodeRequest, sendNodeResponse, ServerAdapterRequestAbortSignal, } from './utils.js';
import { completeAssign, ensureDisposableStackRegisteredForTerminateEvents, handleAbortSignalAndPromiseResponse, handleErrorFromRequestHandler, isFetchEvent, isNodeRequest, isolateObject, isPromise, isRequestInit, isServerResponse, iterateAsyncVoid, nodeRequestResponseMap, normalizeNodeRequest, sendNodeResponse, ServerAdapterRequestAbortSignal, } from './utils.js';
import { getRequestFromUWSRequest, isUWSResponse, sendResponseToUwsOpts, } from './uwebsockets.js';
async function handleWaitUntils(waitUntilPromises) {
await Promise.allSettled(waitUntilPromises);
}
// Required for envs like nextjs edge runtime

@@ -28,2 +26,32 @@ function isRequestAccessible(serverContext) {

const onResponseHooks = [];
const waitUntilPromises = new Set();
const disposableStack = new AsyncDisposableStack();
const signals = new Set();
function registerSignal(signal) {
signals.add(signal);
signal.addEventListener('abort', () => {
signals.delete(signal);
});
}
disposableStack.defer(() => {
for (const signal of signals) {
signal.sendAbort();
}
});
function handleWaitUntils() {
return Promise.allSettled(waitUntilPromises).then(() => { }, () => { });
}
disposableStack.defer(handleWaitUntils);
function waitUntil(promiseLike) {
// If it is a Node.js environment, we should register the disposable stack to handle process termination events
if (globalThis.process) {
ensureDisposableStackRegisteredForTerminateEvents(disposableStack);
}
waitUntilPromises.add(promiseLike.then(() => {
waitUntilPromises.delete(promiseLike);
}, err => {
console.error(`Unexpected error while waiting: ${err.message || err}`);
waitUntilPromises.delete(promiseLike);
}));
}
if (options?.plugins != null) {

@@ -109,3 +137,3 @@ for (const plugin of options.plugins) {

const serverContext = ctx.length > 1 ? completeAssign(...ctx) : ctx[0] || {};
const request = normalizeNodeRequest(nodeRequest, fetchAPI);
const request = normalizeNodeRequest(nodeRequest, fetchAPI, registerSignal);
return handleRequest(request, serverContext);

@@ -119,9 +147,6 @@ }

function requestListener(nodeRequest, nodeResponse, ...ctx) {
const waitUntilPromises = [];
const defaultServerContext = {
req: nodeRequest,
res: nodeResponse,
waitUntil(cb) {
waitUntilPromises.push(cb.catch(err => console.error(err)));
},
waitUntil,
};

@@ -151,9 +176,6 @@ let response$;

function handleUWS(res, req, ...ctx) {
const waitUntilPromises = [];
const defaultServerContext = {
res,
req,
waitUntil(cb) {
waitUntilPromises.push(cb.catch(err => console.error(err)));
},
waitUntil,
};

@@ -165,2 +187,3 @@ const filteredCtxParts = ctx.filter(partCtx => partCtx != null);

const signal = new ServerAdapterRequestAbortSignal();
registerSignal(signal);
const originalResEnd = res.end.bind(res);

@@ -226,13 +249,8 @@ let resEnded = false;

const filteredCtxParts = ctx.filter(partCtx => partCtx != null);
let waitUntilPromises;
const serverContext = filteredCtxParts.length > 1
? completeAssign({}, ...filteredCtxParts)
: isolateObject(filteredCtxParts[0], filteredCtxParts[0] == null || filteredCtxParts[0].waitUntil == null
? (waitUntilPromises = [])
? waitUntil
: undefined);
const response$ = handleRequest(request, serverContext);
if (waitUntilPromises?.length) {
return handleWaitUntils(waitUntilPromises).then(() => response$);
}
return response$;
return handleRequest(request, serverContext);
}

@@ -290,2 +308,6 @@ const fetchFn = (input, ...maybeCtx) => {

handle: genericRequestHandler,
disposableStack,
[DisposableSymbols.asyncDispose]() {
return disposableStack.disposeAsync();
},
};

@@ -292,0 +314,0 @@ const serverAdapter = new Proxy(genericRequestHandler, {

@@ -82,3 +82,3 @@ export function isAsyncIterable(body) {

export const nodeRequestResponseMap = new WeakMap();
export function normalizeNodeRequest(nodeRequest, fetchAPI) {
export function normalizeNodeRequest(nodeRequest, fetchAPI, registerSignal) {
const rawRequest = nodeRequest.raw || nodeRequest.req || nodeRequest;

@@ -109,3 +109,5 @@ let fullUrl = buildFullUrl(rawRequest);

if (fetchAPI.Request !== globalThis.Request) {
signal = new ServerAdapterRequestAbortSignal();
const newSignal = new ServerAdapterRequestAbortSignal();
registerSignal?.(newSignal);
signal = newSignal;
sendAbortSignal = () => signal.sendAbort();

@@ -423,17 +425,13 @@ }

}
export function isolateObject(originalCtx, waitUntilPromises) {
export function isolateObject(originalCtx, waitUntilFn) {
if (originalCtx == null) {
if (waitUntilPromises == null) {
if (waitUntilFn == null) {
return {};
}
return {
waitUntil(promise) {
waitUntilPromises.push(promise.catch(err => console.error(err)));
},
waitUntil: waitUntilFn,
};
}
return completeAssign(Object.create(originalCtx), {
waitUntil(promise) {
waitUntilPromises?.push(promise.catch(err => console.error(err)));
},
waitUntil: waitUntilFn,
}, originalCtx);

@@ -532,1 +530,28 @@ }

}
const terminateEvents = ['SIGINT', 'SIGTERM', 'exit'];
const disposableStacks = new Set();
let eventListenerRegistered = false;
function ensureEventListenerForDisposableStacks() {
if (eventListenerRegistered) {
return;
}
eventListenerRegistered = true;
for (const event of terminateEvents) {
globalThis.process.once(event, function terminateHandler() {
return Promise.allSettled([...disposableStacks].map(stack => stack.disposeAsync().catch(e => {
console.error('Error while disposing:', e);
})));
});
}
}
export function ensureDisposableStackRegisteredForTerminateEvents(disposableStack) {
if (globalThis.process) {
ensureEventListenerForDisposableStacks();
if (!disposableStacks.has(disposableStack)) {
disposableStacks.add(disposableStack);
disposableStack.defer(() => {
disposableStacks.delete(disposableStack);
});
}
}
}
{
"name": "@whatwg-node/server",
"version": "0.9.56",
"version": "0.9.57-alpha-20241123125835-498ddbef3a79038cbe04d8cef8c2cc1d83e7573c",
"description": "Fetch API compliant HTTP Server adapter",
"sideEffects": false,
"dependencies": {
"@whatwg-node/disposablestack": "^0.0.5",
"@whatwg-node/fetch": "^0.10.0",

@@ -8,0 +9,0 @@ "tslib": "^2.6.3"

@@ -16,3 +16,3 @@ import type { RequestListener } from 'http';

}
export interface ServerAdapterObject<TServerContext> extends EventListenerObject {
export interface ServerAdapterObject<TServerContext> extends EventListenerObject, AsyncDisposable {
/**

@@ -60,2 +60,3 @@ * A basic request listener that takes a `Request` with the server context and returns a `Response`.

} & Partial<TServerContext & ServerAdapterInitialContext>, ...ctx: Partial<TServerContext & ServerAdapterInitialContext>[]): Promise<Response> | Response;
disposableStack: AsyncDisposableStack;
}

@@ -62,0 +63,0 @@ export interface RequestLike {

@@ -34,3 +34,3 @@ import type { IncomingMessage, ServerResponse } from 'http';

export declare const nodeRequestResponseMap: WeakMap<NodeRequest, NodeResponse>;
export declare function normalizeNodeRequest(nodeRequest: NodeRequest, fetchAPI: FetchAPI): Request;
export declare function normalizeNodeRequest(nodeRequest: NodeRequest, fetchAPI: FetchAPI, registerSignal?: (signal: ServerAdapterRequestAbortSignal) => void): Request;
export declare function isReadable(stream: any): stream is Readable;

@@ -47,3 +47,3 @@ export declare function isNodeRequest(request: any): request is NodeRequest;

export declare function handleErrorFromRequestHandler(error: any, ResponseCtor: typeof Response): Response;
export declare function isolateObject<TIsolatedObject extends object>(originalCtx: TIsolatedObject, waitUntilPromises?: Promise<unknown>[]): TIsolatedObject;
export declare function isolateObject<TIsolatedObject extends object>(originalCtx: TIsolatedObject, waitUntilFn?: (promiseLike: PromiseLike<unknown>) => void): TIsolatedObject;
export interface DeferredPromise<T = void> {

@@ -59,1 +59,2 @@ promise: Promise<T>;

export declare function handleResponseDecompression(response: Response, fetchAPI: FetchAPI): Response;
export declare function ensureDisposableStackRegisteredForTerminateEvents(disposableStack: AsyncDisposableStack): void;

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc