@whatwg-node/server 0.8.0 → 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,9 +2,9 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createServerAdapter = void 0;
4
4
  const tslib_1 = require("tslib");
5
- /* eslint-disable @typescript-eslint/ban-types */
6
5
  const DefaultFetchAPI = tslib_1.__importStar(require("@whatwg-node/fetch"));
7
6
  const utils_js_1 = require("./utils.js");
7
+ const uwebsockets_js_1 = require("./uwebsockets.js");
8
8
  async function handleWaitUntils(waitUntilPromises) {
9
9
  const waitUntils = await Promise.allSettled(waitUntilPromises);
10
10
  waitUntils.forEach(waitUntil => {
@@ -16,23 +16,23 @@ async function handleWaitUntils(waitUntilPromises) {
16
16
  // Required for envs like nextjs edge runtime
17
17
  function isRequestAccessible(serverContext) {
18
18
  try {
19
- return !!(serverContext === null || serverContext === void 0 ? void 0 : serverContext.request);
19
+ return !!serverContext?.request;
20
20
  }
21
- catch (_a) {
21
+ catch {
22
22
  return false;
23
23
  }
24
24
  }
25
25
  function createServerAdapter(serverAdapterBaseObject, options) {
26
26
  const fetchAPI = {
27
27
  ...DefaultFetchAPI,
28
- ...options === null || options === void 0 ? void 0 : options.fetchAPI,
28
+ ...options?.fetchAPI,
29
29
  };
30
30
  const givenHandleRequest = typeof serverAdapterBaseObject === 'function'
31
31
  ? serverAdapterBaseObject
32
32
  : serverAdapterBaseObject.handle;
33
33
  const onRequestHooks = [];
34
34
  const onResponseHooks = [];
35
- if ((options === null || options === void 0 ? void 0 : options.plugins) != null) {
35
+ if (options?.plugins != null) {
36
36
  for (const plugin of options.plugins) {
37
37
  if (plugin.onRequest) {
38
38
  onRequestHooks.push(plugin.onRequest);
@@ -112,6 +112,85 @@ function createServerAdapter(serverAdapterBaseObject, options) {
112
112
  await handleWaitUntils(waitUntilPromises);
113
113
  }
114
114
  }
115
+ async function handleUWS(res, req, ...ctx) {
116
+ const waitUntilPromises = [];
117
+ const serverContext = completeAssign({
118
+ res,
119
+ req,
120
+ waitUntil(promise) {
121
+ if (promise != null) {
122
+ waitUntilPromises.push(promise);
123
+ }
124
+ },
125
+ }, ...ctx);
126
+ let body;
127
+ const method = req.getMethod();
128
+ let resAborted = false;
129
+ res.onAborted(function () {
130
+ resAborted = true;
131
+ body?.readable.push(null);
132
+ });
133
+ if (method !== 'get' && method !== 'head') {
134
+ body = new fetchAPI.ReadableStream({});
135
+ res.onData(function (chunk, isLast) {
136
+ body?.readable.push(Buffer.from(chunk, 0, chunk.byteLength));
137
+ if (isLast) {
138
+ body?.readable.push(null);
139
+ }
140
+ });
141
+ }
142
+ const headers = {};
143
+ req.forEach((key, value) => {
144
+ headers[key] = value;
145
+ });
146
+ const url = `http://localhost${req.getUrl()}`;
147
+ const request = new fetchAPI.Request(url, {
148
+ method,
149
+ headers,
150
+ body,
151
+ });
152
+ const response = await handleRequest(request, serverContext);
153
+ if (resAborted) {
154
+ return;
155
+ }
156
+ if (!response) {
157
+ res.writeStatus('404 Not Found');
158
+ res.end();
159
+ return;
160
+ }
161
+ res.cork(() => {
162
+ res.writeStatus(`${response.status} ${response.statusText}`);
163
+ });
164
+ response.headers.forEach((value, key) => {
165
+ // content-length causes an error with Node.js's fetch
166
+ if (key.toLowerCase() !== 'content-length') {
167
+ res.cork(() => {
168
+ res.writeHeader(key, value);
169
+ });
170
+ }
171
+ });
172
+ if (!response.body) {
173
+ res.end();
174
+ return;
175
+ }
176
+ if (response.bodyType === 'String' || response.bodyType === 'Uint8Array') {
177
+ res.cork(() => {
178
+ res.end(response.bodyInit);
179
+ });
180
+ return;
181
+ }
182
+ for await (const chunk of response.body.readable) {
183
+ if (resAborted) {
184
+ return;
185
+ }
186
+ res.cork(() => {
187
+ res.write(chunk);
188
+ });
189
+ }
190
+ res.cork(() => {
191
+ res.end();
192
+ });
193
+ }
115
194
  function handleEvent(event, ...ctx) {
116
195
  if (!event.respondWith || !event.request) {
117
196
  throw new TypeError(`Expected FetchEvent, got ${event}`);
@@ -152,6 +231,9 @@ function createServerAdapter(serverAdapterBaseObject, options) {
152
231
  const genericRequestHandler = (input, ...maybeCtx) => {
153
232
  // If it is a Node request
154
233
  const [initOrCtxOrRes, ...restOfCtx] = maybeCtx;
234
+ if ((0, uwebsockets_js_1.isUWSResponse)(input)) {
235
+ return handleUWS(input, initOrCtxOrRes, ...restOfCtx);
236
+ }
155
237
  if ((0, utils_js_1.isNodeRequest)(input)) {
156
238
  if (!(0, utils_js_1.isServerResponse)(initOrCtxOrRes)) {
157
239
  throw new TypeError(`Expected ServerResponse, got ${initOrCtxOrRes}`);
@@ -180,6 +262,7 @@ function createServerAdapter(serverAdapterBaseObject, options) {
180
262
  handleNodeRequest,
181
263
  requestListener,
182
264
  handleEvent,
265
+ handleUWS,
183
266
  handle: genericRequestHandler,
184
267
  };
185
268
  const serverAdapter = new Proxy(genericRequestHandler, {
@@ -2,7 +2,6 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.useCORS = exports.getCORSHeadersByRequestAndOptions = void 0;
4
4
  function getCORSHeadersByRequestAndOptions(request, corsOptions) {
5
- var _a, _b;
6
5
  const currentOrigin = request.headers.get('origin');
7
6
  if (corsOptions === false || currentOrigin == null) {
8
7
  return null;
@@ -36,7 +35,7 @@ function getCORSHeadersByRequestAndOptions(request, corsOptions) {
36
35
  headers['Access-Control-Allow-Origin'] = 'null';
37
36
  }
38
37
  }
39
- if ((_a = corsOptions.methods) === null || _a === void 0 ? void 0 : _a.length) {
38
+ if (corsOptions.methods?.length) {
40
39
  headers['Access-Control-Allow-Methods'] = corsOptions.methods.join(', ');
41
40
  }
42
41
  else {
@@ -45,7 +44,7 @@ function getCORSHeadersByRequestAndOptions(request, corsOptions) {
45
44
  headers['Access-Control-Allow-Methods'] = requestMethod;
46
45
  }
47
46
  }
48
- if ((_b = corsOptions.allowedHeaders) === null || _b === void 0 ? void 0 : _b.length) {
47
+ if (corsOptions.allowedHeaders?.length) {
49
48
  headers['Access-Control-Allow-Headers'] = corsOptions.allowedHeaders.join(', ');
50
49
  }
51
50
  else {
package/cjs/utils.js CHANGED
@@ -7,31 +7,29 @@ function isAsyncIterable(body) {
7
7
  }
8
8
  exports.isAsyncIterable = isAsyncIterable;
9
9
  function getPort(nodeRequest) {
10
- var _a, _b, _c, _d, _e;
11
- if ((_a = nodeRequest.socket) === null || _a === void 0 ? void 0 : _a.localPort) {
12
- return (_b = nodeRequest.socket) === null || _b === void 0 ? void 0 : _b.localPort;
10
+ if (nodeRequest.socket?.localPort) {
11
+ return nodeRequest.socket?.localPort;
13
12
  }
14
- const hostInHeader = ((_c = nodeRequest.headers) === null || _c === void 0 ? void 0 : _c[':authority']) || ((_d = nodeRequest.headers) === null || _d === void 0 ? void 0 : _d.host);
15
- const portInHeader = (_e = hostInHeader === null || hostInHeader === void 0 ? void 0 : hostInHeader.split(':')) === null || _e === void 0 ? void 0 : _e[1];
13
+ const hostInHeader = nodeRequest.headers?.[':authority'] || nodeRequest.headers?.host;
14
+ const portInHeader = hostInHeader?.split(':')?.[1];
16
15
  if (portInHeader) {
17
16
  return portInHeader;
18
17
  }
19
18
  return 80;
20
19
  }
21
20
  function getHostnameWithPort(nodeRequest) {
22
- var _a, _b, _c, _d, _e;
23
- if ((_a = nodeRequest.headers) === null || _a === void 0 ? void 0 : _a[':authority']) {
24
- return (_b = nodeRequest.headers) === null || _b === void 0 ? void 0 : _b[':authority'];
21
+ if (nodeRequest.headers?.[':authority']) {
22
+ return nodeRequest.headers?.[':authority'];
25
23
  }
26
- if ((_c = nodeRequest.headers) === null || _c === void 0 ? void 0 : _c.host) {
27
- return (_d = nodeRequest.headers) === null || _d === void 0 ? void 0 : _d.host;
24
+ if (nodeRequest.headers?.host) {
25
+ return nodeRequest.headers?.host;
28
26
  }
29
27
  const port = getPort(nodeRequest);
30
28
  if (nodeRequest.hostname) {
31
29
  return nodeRequest.hostname + ':' + port;
32
30
  }
33
- const localIp = (_e = nodeRequest.socket) === null || _e === void 0 ? void 0 : _e.localAddress;
34
- if (localIp && !(localIp === null || localIp === void 0 ? void 0 : localIp.includes('::')) && !(localIp === null || localIp === void 0 ? void 0 : localIp.includes('ffff'))) {
31
+ const localIp = nodeRequest.socket?.localAddress;
32
+ if (localIp && !localIp?.includes('::') && !localIp?.includes('ffff')) {
35
33
  return `${localIp}:${port}`;
36
34
  }
37
35
  return 'localhost';
@@ -55,7 +53,6 @@ function isRequestBody(body) {
55
53
  return false;
56
54
  }
57
55
  function normalizeNodeRequest(nodeRequest, RequestCtor) {
58
- var _a;
59
56
  const rawRequest = nodeRequest.raw || nodeRequest.req || nodeRequest;
60
57
  let fullUrl = buildFullUrl(rawRequest);
61
58
  if (nodeRequest.query) {
@@ -90,7 +87,7 @@ function normalizeNodeRequest(nodeRequest, RequestCtor) {
90
87
  method: nodeRequest.method,
91
88
  headers: nodeRequest.headers,
92
89
  });
93
- if (!((_a = request.headers.get('content-type')) === null || _a === void 0 ? void 0 : _a.includes('json'))) {
90
+ if (!request.headers.get('content-type')?.includes('json')) {
94
91
  request.headers.set('content-type', 'application/json');
95
92
  }
96
93
  return new Proxy(request, {
@@ -140,10 +137,9 @@ function isFetchEvent(event) {
140
137
  }
141
138
  exports.isFetchEvent = isFetchEvent;
142
139
  function configureSocket(rawRequest) {
143
- var _a, _b, _c, _d, _e, _f;
144
- (_b = (_a = rawRequest === null || rawRequest === void 0 ? void 0 : rawRequest.socket) === null || _a === void 0 ? void 0 : _a.setTimeout) === null || _b === void 0 ? void 0 : _b.call(_a, 0);
145
- (_d = (_c = rawRequest === null || rawRequest === void 0 ? void 0 : rawRequest.socket) === null || _c === void 0 ? void 0 : _c.setNoDelay) === null || _d === void 0 ? void 0 : _d.call(_c, true);
146
- (_f = (_e = rawRequest === null || rawRequest === void 0 ? void 0 : rawRequest.socket) === null || _e === void 0 ? void 0 : _e.setKeepAlive) === null || _f === void 0 ? void 0 : _f.call(_e, true);
140
+ rawRequest?.socket?.setTimeout?.(0);
141
+ rawRequest?.socket?.setNoDelay?.(true);
142
+ rawRequest?.socket?.setKeepAlive?.(true);
147
143
  }
148
144
  function endResponse(serverResponse) {
149
145
  // @ts-expect-error Avoid arguments adaptor trampoline https://v8.dev/blog/adaptor-frame
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isUWSResponse = void 0;
4
+ function isUWSResponse(res) {
5
+ return typeof res === 'object' && typeof res.onData === 'function';
6
+ }
7
+ exports.isUWSResponse = isUWSResponse;
@@ -1,6 +1,6 @@
1
- /* eslint-disable @typescript-eslint/ban-types */
2
1
  import * as DefaultFetchAPI from '@whatwg-node/fetch';
3
2
  import { isFetchEvent, isNodeRequest, isRequestInit, isServerResponse, normalizeNodeRequest, sendNodeResponse, } from './utils.js';
3
+ import { isUWSResponse } from './uwebsockets.js';
4
4
  async function handleWaitUntils(waitUntilPromises) {
5
5
  const waitUntils = await Promise.allSettled(waitUntilPromises);
6
6
  waitUntils.forEach(waitUntil => {
@@ -12,23 +12,23 @@ async function handleWaitUntils(waitUntilPromises) {
12
12
  // Required for envs like nextjs edge runtime
13
13
  function isRequestAccessible(serverContext) {
14
14
  try {
15
- return !!(serverContext === null || serverContext === void 0 ? void 0 : serverContext.request);
15
+ return !!serverContext?.request;
16
16
  }
17
- catch (_a) {
17
+ catch {
18
18
  return false;
19
19
  }
20
20
  }
21
21
  function createServerAdapter(serverAdapterBaseObject, options) {
22
22
  const fetchAPI = {
23
23
  ...DefaultFetchAPI,
24
- ...options === null || options === void 0 ? void 0 : options.fetchAPI,
24
+ ...options?.fetchAPI,
25
25
  };
26
26
  const givenHandleRequest = typeof serverAdapterBaseObject === 'function'
27
27
  ? serverAdapterBaseObject
28
28
  : serverAdapterBaseObject.handle;
29
29
  const onRequestHooks = [];
30
30
  const onResponseHooks = [];
31
- if ((options === null || options === void 0 ? void 0 : options.plugins) != null) {
31
+ if (options?.plugins != null) {
32
32
  for (const plugin of options.plugins) {
33
33
  if (plugin.onRequest) {
34
34
  onRequestHooks.push(plugin.onRequest);
@@ -108,6 +108,85 @@ function createServerAdapter(serverAdapterBaseObject, options) {
108
108
  await handleWaitUntils(waitUntilPromises);
109
109
  }
110
110
  }
111
+ async function handleUWS(res, req, ...ctx) {
112
+ const waitUntilPromises = [];
113
+ const serverContext = completeAssign({
114
+ res,
115
+ req,
116
+ waitUntil(promise) {
117
+ if (promise != null) {
118
+ waitUntilPromises.push(promise);
119
+ }
120
+ },
121
+ }, ...ctx);
122
+ let body;
123
+ const method = req.getMethod();
124
+ let resAborted = false;
125
+ res.onAborted(function () {
126
+ resAborted = true;
127
+ body?.readable.push(null);
128
+ });
129
+ if (method !== 'get' && method !== 'head') {
130
+ body = new fetchAPI.ReadableStream({});
131
+ res.onData(function (chunk, isLast) {
132
+ body?.readable.push(Buffer.from(chunk, 0, chunk.byteLength));
133
+ if (isLast) {
134
+ body?.readable.push(null);
135
+ }
136
+ });
137
+ }
138
+ const headers = {};
139
+ req.forEach((key, value) => {
140
+ headers[key] = value;
141
+ });
142
+ const url = `http://localhost${req.getUrl()}`;
143
+ const request = new fetchAPI.Request(url, {
144
+ method,
145
+ headers,
146
+ body,
147
+ });
148
+ const response = await handleRequest(request, serverContext);
149
+ if (resAborted) {
150
+ return;
151
+ }
152
+ if (!response) {
153
+ res.writeStatus('404 Not Found');
154
+ res.end();
155
+ return;
156
+ }
157
+ res.cork(() => {
158
+ res.writeStatus(`${response.status} ${response.statusText}`);
159
+ });
160
+ response.headers.forEach((value, key) => {
161
+ // content-length causes an error with Node.js's fetch
162
+ if (key.toLowerCase() !== 'content-length') {
163
+ res.cork(() => {
164
+ res.writeHeader(key, value);
165
+ });
166
+ }
167
+ });
168
+ if (!response.body) {
169
+ res.end();
170
+ return;
171
+ }
172
+ if (response.bodyType === 'String' || response.bodyType === 'Uint8Array') {
173
+ res.cork(() => {
174
+ res.end(response.bodyInit);
175
+ });
176
+ return;
177
+ }
178
+ for await (const chunk of response.body.readable) {
179
+ if (resAborted) {
180
+ return;
181
+ }
182
+ res.cork(() => {
183
+ res.write(chunk);
184
+ });
185
+ }
186
+ res.cork(() => {
187
+ res.end();
188
+ });
189
+ }
111
190
  function handleEvent(event, ...ctx) {
112
191
  if (!event.respondWith || !event.request) {
113
192
  throw new TypeError(`Expected FetchEvent, got ${event}`);
@@ -148,6 +227,9 @@ function createServerAdapter(serverAdapterBaseObject, options) {
148
227
  const genericRequestHandler = (input, ...maybeCtx) => {
149
228
  // If it is a Node request
150
229
  const [initOrCtxOrRes, ...restOfCtx] = maybeCtx;
230
+ if (isUWSResponse(input)) {
231
+ return handleUWS(input, initOrCtxOrRes, ...restOfCtx);
232
+ }
151
233
  if (isNodeRequest(input)) {
152
234
  if (!isServerResponse(initOrCtxOrRes)) {
153
235
  throw new TypeError(`Expected ServerResponse, got ${initOrCtxOrRes}`);
@@ -176,6 +258,7 @@ function createServerAdapter(serverAdapterBaseObject, options) {
176
258
  handleNodeRequest,
177
259
  requestListener,
178
260
  handleEvent,
261
+ handleUWS,
179
262
  handle: genericRequestHandler,
180
263
  };
181
264
  const serverAdapter = new Proxy(genericRequestHandler, {
@@ -1,5 +1,4 @@
1
1
  export function getCORSHeadersByRequestAndOptions(request, corsOptions) {
2
- var _a, _b;
3
2
  const currentOrigin = request.headers.get('origin');
4
3
  if (corsOptions === false || currentOrigin == null) {
5
4
  return null;
@@ -33,7 +32,7 @@ export function getCORSHeadersByRequestAndOptions(request, corsOptions) {
33
32
  headers['Access-Control-Allow-Origin'] = 'null';
34
33
  }
35
34
  }
36
- if ((_a = corsOptions.methods) === null || _a === void 0 ? void 0 : _a.length) {
35
+ if (corsOptions.methods?.length) {
37
36
  headers['Access-Control-Allow-Methods'] = corsOptions.methods.join(', ');
38
37
  }
39
38
  else {
@@ -42,7 +41,7 @@ export function getCORSHeadersByRequestAndOptions(request, corsOptions) {
42
41
  headers['Access-Control-Allow-Methods'] = requestMethod;
43
42
  }
44
43
  }
45
- if ((_b = corsOptions.allowedHeaders) === null || _b === void 0 ? void 0 : _b.length) {
44
+ if (corsOptions.allowedHeaders?.length) {
46
45
  headers['Access-Control-Allow-Headers'] = corsOptions.allowedHeaders.join(', ');
47
46
  }
48
47
  else {
package/esm/utils.js CHANGED
@@ -3,31 +3,29 @@ export function isAsyncIterable(body) {
3
3
  return (body != null && typeof body === 'object' && typeof body[Symbol.asyncIterator] === 'function');
4
4
  }
5
5
  function getPort(nodeRequest) {
6
- var _a, _b, _c, _d, _e;
7
- if ((_a = nodeRequest.socket) === null || _a === void 0 ? void 0 : _a.localPort) {
8
- return (_b = nodeRequest.socket) === null || _b === void 0 ? void 0 : _b.localPort;
6
+ if (nodeRequest.socket?.localPort) {
7
+ return nodeRequest.socket?.localPort;
9
8
  }
10
- const hostInHeader = ((_c = nodeRequest.headers) === null || _c === void 0 ? void 0 : _c[':authority']) || ((_d = nodeRequest.headers) === null || _d === void 0 ? void 0 : _d.host);
11
- const portInHeader = (_e = hostInHeader === null || hostInHeader === void 0 ? void 0 : hostInHeader.split(':')) === null || _e === void 0 ? void 0 : _e[1];
9
+ const hostInHeader = nodeRequest.headers?.[':authority'] || nodeRequest.headers?.host;
10
+ const portInHeader = hostInHeader?.split(':')?.[1];
12
11
  if (portInHeader) {
13
12
  return portInHeader;
14
13
  }
15
14
  return 80;
16
15
  }
17
16
  function getHostnameWithPort(nodeRequest) {
18
- var _a, _b, _c, _d, _e;
19
- if ((_a = nodeRequest.headers) === null || _a === void 0 ? void 0 : _a[':authority']) {
20
- return (_b = nodeRequest.headers) === null || _b === void 0 ? void 0 : _b[':authority'];
17
+ if (nodeRequest.headers?.[':authority']) {
18
+ return nodeRequest.headers?.[':authority'];
21
19
  }
22
- if ((_c = nodeRequest.headers) === null || _c === void 0 ? void 0 : _c.host) {
23
- return (_d = nodeRequest.headers) === null || _d === void 0 ? void 0 : _d.host;
20
+ if (nodeRequest.headers?.host) {
21
+ return nodeRequest.headers?.host;
24
22
  }
25
23
  const port = getPort(nodeRequest);
26
24
  if (nodeRequest.hostname) {
27
25
  return nodeRequest.hostname + ':' + port;
28
26
  }
29
- const localIp = (_e = nodeRequest.socket) === null || _e === void 0 ? void 0 : _e.localAddress;
30
- if (localIp && !(localIp === null || localIp === void 0 ? void 0 : localIp.includes('::')) && !(localIp === null || localIp === void 0 ? void 0 : localIp.includes('ffff'))) {
27
+ const localIp = nodeRequest.socket?.localAddress;
28
+ if (localIp && !localIp?.includes('::') && !localIp?.includes('ffff')) {
31
29
  return `${localIp}:${port}`;
32
30
  }
33
31
  return 'localhost';
@@ -51,7 +49,6 @@ function isRequestBody(body) {
51
49
  return false;
52
50
  }
53
51
  export function normalizeNodeRequest(nodeRequest, RequestCtor) {
54
- var _a;
55
52
  const rawRequest = nodeRequest.raw || nodeRequest.req || nodeRequest;
56
53
  let fullUrl = buildFullUrl(rawRequest);
57
54
  if (nodeRequest.query) {
@@ -86,7 +83,7 @@ export function normalizeNodeRequest(nodeRequest, RequestCtor) {
86
83
  method: nodeRequest.method,
87
84
  headers: nodeRequest.headers,
88
85
  });
89
- if (!((_a = request.headers.get('content-type')) === null || _a === void 0 ? void 0 : _a.includes('json'))) {
86
+ if (!request.headers.get('content-type')?.includes('json')) {
90
87
  request.headers.set('content-type', 'application/json');
91
88
  }
92
89
  return new Proxy(request, {
@@ -130,10 +127,9 @@ export function isFetchEvent(event) {
130
127
  return event != null && event.request != null && event.respondWith != null;
131
128
  }
132
129
  function configureSocket(rawRequest) {
133
- var _a, _b, _c, _d, _e, _f;
134
- (_b = (_a = rawRequest === null || rawRequest === void 0 ? void 0 : rawRequest.socket) === null || _a === void 0 ? void 0 : _a.setTimeout) === null || _b === void 0 ? void 0 : _b.call(_a, 0);
135
- (_d = (_c = rawRequest === null || rawRequest === void 0 ? void 0 : rawRequest.socket) === null || _c === void 0 ? void 0 : _c.setNoDelay) === null || _d === void 0 ? void 0 : _d.call(_c, true);
136
- (_f = (_e = rawRequest === null || rawRequest === void 0 ? void 0 : rawRequest.socket) === null || _e === void 0 ? void 0 : _e.setKeepAlive) === null || _f === void 0 ? void 0 : _f.call(_e, true);
130
+ rawRequest?.socket?.setTimeout?.(0);
131
+ rawRequest?.socket?.setNoDelay?.(true);
132
+ rawRequest?.socket?.setKeepAlive?.(true);
137
133
  }
138
134
  function endResponse(serverResponse) {
139
135
  // @ts-expect-error Avoid arguments adaptor trampoline https://v8.dev/blog/adaptor-frame
@@ -0,0 +1,3 @@
1
+ export function isUWSResponse(res) {
2
+ return typeof res === 'object' && typeof res.onData === 'function';
3
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@whatwg-node/server",
3
- "version": "0.8.0",
3
+ "version": "0.8.1",
4
4
  "description": "Fetch API compliant HTTP Server adapter",
5
5
  "sideEffects": false,
6
6
  "dependencies": {
@@ -1,6 +1,7 @@
1
1
  /// <reference types="node" />
2
2
  import type { RequestListener } from 'node:http';
3
3
  import type { NodeRequest, NodeResponse } from './utils.cjs';
4
+ import { UWSHandler, UWSRequest, UWSResponse } from './uwebsockets.cjs';
4
5
  export interface FetchEvent extends Event {
5
6
  waitUntil(f: Promise<void> | void): void;
6
7
  request: Request;
@@ -39,9 +40,11 @@ export interface ServerAdapterObject<TServerContext> extends EventListenerObject
39
40
  * A request listener function that can be used with any Node server variation.
40
41
  */
41
42
  requestListener: RequestListener;
43
+ handleUWS: UWSHandler;
42
44
  handle(req: NodeRequest, res: NodeResponse, ...ctx: Partial<TServerContext>[]): Promise<void>;
43
45
  handle(request: Request, ...ctx: Partial<TServerContext>[]): Promise<Response> | Response;
44
46
  handle(fetchEvent: FetchEvent & Partial<TServerContext>, ...ctx: Partial<TServerContext>[]): void;
47
+ handle(res: UWSResponse, req: UWSRequest, ...ctx: Partial<TServerContext>[]): Promise<void>;
45
48
  handle(container: {
46
49
  request: Request;
47
50
  } & Partial<TServerContext>, ...ctx: Partial<TServerContext>[]): Promise<Response> | Response;
@@ -1,6 +1,7 @@
1
1
  /// <reference types="node" />
2
2
  import type { RequestListener } from 'node:http';
3
3
  import type { NodeRequest, NodeResponse } from './utils.js';
4
+ import { UWSHandler, UWSRequest, UWSResponse } from './uwebsockets.js';
4
5
  export interface FetchEvent extends Event {
5
6
  waitUntil(f: Promise<void> | void): void;
6
7
  request: Request;
@@ -39,9 +40,11 @@ export interface ServerAdapterObject<TServerContext> extends EventListenerObject
39
40
  * A request listener function that can be used with any Node server variation.
40
41
  */
41
42
  requestListener: RequestListener;
43
+ handleUWS: UWSHandler;
42
44
  handle(req: NodeRequest, res: NodeResponse, ...ctx: Partial<TServerContext>[]): Promise<void>;
43
45
  handle(request: Request, ...ctx: Partial<TServerContext>[]): Promise<Response> | Response;
44
46
  handle(fetchEvent: FetchEvent & Partial<TServerContext>, ...ctx: Partial<TServerContext>[]): void;
47
+ handle(res: UWSResponse, req: UWSRequest, ...ctx: Partial<TServerContext>[]): Promise<void>;
45
48
  handle(container: {
46
49
  request: Request;
47
50
  } & Partial<TServerContext>, ...ctx: Partial<TServerContext>[]): Promise<Response> | Response;
@@ -0,0 +1,16 @@
1
+ export interface UWSRequest {
2
+ getMethod(): string;
3
+ forEach(callback: (key: string, value: string) => void): void;
4
+ getUrl(): string;
5
+ }
6
+ export interface UWSResponse {
7
+ onData(callback: (chunk: ArrayBuffer, isLast: boolean) => void): void;
8
+ onAborted(callback: () => void): void;
9
+ writeStatus(status: string): void;
10
+ writeHeader(key: string, value: string): void;
11
+ end(body?: any): void;
12
+ write(body: any): boolean;
13
+ cork(callback: () => void): void;
14
+ }
15
+ export type UWSHandler = (res: UWSResponse, req: UWSRequest) => void | Promise<void>;
16
+ export declare function isUWSResponse(res: any): res is UWSResponse;
@@ -0,0 +1,16 @@
1
+ export interface UWSRequest {
2
+ getMethod(): string;
3
+ forEach(callback: (key: string, value: string) => void): void;
4
+ getUrl(): string;
5
+ }
6
+ export interface UWSResponse {
7
+ onData(callback: (chunk: ArrayBuffer, isLast: boolean) => void): void;
8
+ onAborted(callback: () => void): void;
9
+ writeStatus(status: string): void;
10
+ writeHeader(key: string, value: string): void;
11
+ end(body?: any): void;
12
+ write(body: any): boolean;
13
+ cork(callback: () => void): void;
14
+ }
15
+ export type UWSHandler = (res: UWSResponse, req: UWSRequest) => void | Promise<void>;
16
+ export declare function isUWSResponse(res: any): res is UWSResponse;