@whatwg-node/server 0.9.10 → 0.9.11-alpha-20230821124424-6f3a2b1

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.
@@ -161,6 +161,7 @@ function createServerAdapter(serverAdapterBaseObject, options) {
161
161
  let resAborted = false;
162
162
  res.onAborted(() => {
163
163
  resAborted = true;
164
+ request.signal.sendAbort();
164
165
  });
165
166
  let response$;
166
167
  try {
package/cjs/utils.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.handleErrorFromRequestHandler = exports.iterateAsyncVoid = exports.isPromise = exports.completeAssign = exports.isRequestInit = exports.sendNodeResponse = exports.isFetchEvent = exports.isReadableStream = exports.isServerResponse = exports.isNodeRequest = exports.isReadable = exports.normalizeNodeRequest = exports.isAsyncIterable = void 0;
3
+ exports.handleErrorFromRequestHandler = exports.iterateAsyncVoid = exports.isPromise = exports.completeAssign = exports.isRequestInit = exports.sendNodeResponse = exports.isFetchEvent = exports.isReadableStream = exports.isServerResponse = exports.isNodeRequest = exports.isReadable = exports.normalizeNodeRequest = exports.ServerAdapterRequestAbortSignal = exports.isAsyncIterable = void 0;
4
4
  const fetch_1 = require("@whatwg-node/fetch");
5
5
  function isAsyncIterable(body) {
6
6
  return (body != null && typeof body === 'object' && typeof body[Symbol.asyncIterator] === 'function');
@@ -52,6 +52,35 @@ function isRequestBody(body) {
52
52
  }
53
53
  return false;
54
54
  }
55
+ class ServerAdapterRequestAbortSignal extends EventTarget {
56
+ constructor() {
57
+ super(...arguments);
58
+ this.aborted = false;
59
+ this._onabort = null;
60
+ }
61
+ throwIfAborted() {
62
+ if (this.aborted) {
63
+ throw new DOMException('Aborted', 'AbortError');
64
+ }
65
+ }
66
+ sendAbort() {
67
+ this.aborted = true;
68
+ this.dispatchEvent(new Event('abort'));
69
+ }
70
+ get onabort() {
71
+ return this._onabort;
72
+ }
73
+ set onabort(value) {
74
+ this._onabort = value;
75
+ if (value) {
76
+ this.addEventListener('abort', value);
77
+ }
78
+ else {
79
+ this.removeEventListener('abort', value);
80
+ }
81
+ }
82
+ }
83
+ exports.ServerAdapterRequestAbortSignal = ServerAdapterRequestAbortSignal;
55
84
  function normalizeNodeRequest(nodeRequest, RequestCtor) {
56
85
  const rawRequest = nodeRequest.raw || nodeRequest.req || nodeRequest;
57
86
  let fullUrl = buildFullUrl(rawRequest);
@@ -62,10 +91,16 @@ function normalizeNodeRequest(nodeRequest, RequestCtor) {
62
91
  }
63
92
  fullUrl = url.toString();
64
93
  }
94
+ const signal = new ServerAdapterRequestAbortSignal();
95
+ if (rawRequest.once) {
96
+ rawRequest.once('end', () => signal.sendAbort());
97
+ rawRequest.once('close', () => signal.sendAbort());
98
+ }
65
99
  if (nodeRequest.method === 'GET' || nodeRequest.method === 'HEAD') {
66
100
  return new RequestCtor(fullUrl, {
67
101
  method: nodeRequest.method,
68
102
  headers: nodeRequest.headers,
103
+ signal,
69
104
  });
70
105
  }
71
106
  /**
@@ -81,11 +116,13 @@ function normalizeNodeRequest(nodeRequest, RequestCtor) {
81
116
  method: nodeRequest.method,
82
117
  headers: nodeRequest.headers,
83
118
  body: maybeParsedBody,
119
+ signal,
84
120
  });
85
121
  }
86
122
  const request = new RequestCtor(fullUrl, {
87
123
  method: nodeRequest.method,
88
124
  headers: nodeRequest.headers,
125
+ signal,
89
126
  });
90
127
  if (!request.headers.get('content-type')?.includes('json')) {
91
128
  request.headers.set('content-type', 'application/json; charset=utf-8');
@@ -108,6 +145,7 @@ function normalizeNodeRequest(nodeRequest, RequestCtor) {
108
145
  method: nodeRequest.method,
109
146
  headers: nodeRequest.headers,
110
147
  body: rawRequest,
148
+ signal,
111
149
  });
112
150
  }
113
151
  exports.normalizeNodeRequest = normalizeNodeRequest;
@@ -177,11 +215,10 @@ function sendNodeResponse(fetchResponse, serverResponse, nodeRequest) {
177
215
  serverResponse.setHeader(key, value);
178
216
  });
179
217
  // Optimizations for node-fetch
180
- if (fetchResponse.bodyType === 'Buffer' ||
181
- fetchResponse.bodyType === 'String' ||
182
- fetchResponse.bodyType === 'Uint8Array') {
218
+ const bufOfRes = fetchResponse._buffer;
219
+ if (bufOfRes) {
183
220
  // @ts-expect-error http and http2 writes are actually compatible
184
- serverResponse.write(fetchResponse.bodyInit);
221
+ serverResponse.write(bufOfRes);
185
222
  endResponse(serverResponse);
186
223
  return;
187
224
  }
@@ -1,38 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.sendResponseToUwsOpts = exports.getRequestFromUWSRequest = exports.isUWSResponse = void 0;
4
+ const utils_js_1 = require("./utils.js");
4
5
  function isUWSResponse(res) {
5
6
  return !!res.onData;
6
7
  }
7
8
  exports.isUWSResponse = isUWSResponse;
8
- class UWSAbortSignal extends EventTarget {
9
- throwIfAborted() {
10
- if (this.aborted) {
11
- throw new DOMException('Aborted', 'AbortError');
12
- }
13
- }
14
- constructor(res) {
15
- super();
16
- this.aborted = false;
17
- this._onabort = null;
18
- res.onAborted(() => {
19
- this.aborted = true;
20
- this.dispatchEvent(new Event('request aborted'));
21
- });
22
- }
23
- get onabort() {
24
- return this._onabort;
25
- }
26
- set onabort(value) {
27
- this._onabort = value;
28
- if (value) {
29
- this.addEventListener('request aborted', value);
30
- }
31
- else {
32
- this.removeEventListener('request aborted', value);
33
- }
34
- }
35
- }
36
9
  function getRequestFromUWSRequest({ req, res, fetchAPI }) {
37
10
  let body;
38
11
  const method = req.getMethod();
@@ -66,7 +39,7 @@ function getRequestFromUWSRequest({ req, res, fetchAPI }) {
66
39
  method,
67
40
  headers,
68
41
  body: body,
69
- signal: new UWSAbortSignal(res),
42
+ signal: new utils_js_1.ServerAdapterRequestAbortSignal(),
70
43
  });
71
44
  }
72
45
  exports.getRequestFromUWSRequest = getRequestFromUWSRequest;
@@ -93,9 +66,7 @@ function sendResponseToUwsOpts(uwsResponse, fetchResponse) {
93
66
  uwsResponse.end();
94
67
  return;
95
68
  }
96
- const isStringOrBuffer = fetchResponse.bodyType === 'Buffer' ||
97
- fetchResponse.bodyType === 'String' ||
98
- fetchResponse.bodyType === 'Uint8Array';
69
+ const bufferOfRes = fetchResponse._buffer;
99
70
  uwsResponse.cork(() => {
100
71
  uwsResponse.writeStatus(`${fetchResponse.status} ${fetchResponse.statusText}`);
101
72
  for (const [key, value] of fetchResponse.headers) {
@@ -113,11 +84,11 @@ function sendResponseToUwsOpts(uwsResponse, fetchResponse) {
113
84
  uwsResponse.writeHeader(key, value);
114
85
  }
115
86
  }
116
- if (isStringOrBuffer) {
117
- uwsResponse.end(fetchResponse.bodyInit);
87
+ if (bufferOfRes) {
88
+ uwsResponse.end(bufferOfRes);
118
89
  }
119
90
  });
120
- if (isStringOrBuffer) {
91
+ if (bufferOfRes) {
121
92
  return;
122
93
  }
123
94
  if (!fetchResponse.body) {
@@ -157,6 +157,7 @@ function createServerAdapter(serverAdapterBaseObject, options) {
157
157
  let resAborted = false;
158
158
  res.onAborted(() => {
159
159
  resAborted = true;
160
+ request.signal.sendAbort();
160
161
  });
161
162
  let response$;
162
163
  try {
package/esm/utils.js CHANGED
@@ -48,6 +48,34 @@ function isRequestBody(body) {
48
48
  }
49
49
  return false;
50
50
  }
51
+ export class ServerAdapterRequestAbortSignal extends EventTarget {
52
+ constructor() {
53
+ super(...arguments);
54
+ this.aborted = false;
55
+ this._onabort = null;
56
+ }
57
+ throwIfAborted() {
58
+ if (this.aborted) {
59
+ throw new DOMException('Aborted', 'AbortError');
60
+ }
61
+ }
62
+ sendAbort() {
63
+ this.aborted = true;
64
+ this.dispatchEvent(new Event('abort'));
65
+ }
66
+ get onabort() {
67
+ return this._onabort;
68
+ }
69
+ set onabort(value) {
70
+ this._onabort = value;
71
+ if (value) {
72
+ this.addEventListener('abort', value);
73
+ }
74
+ else {
75
+ this.removeEventListener('abort', value);
76
+ }
77
+ }
78
+ }
51
79
  export function normalizeNodeRequest(nodeRequest, RequestCtor) {
52
80
  const rawRequest = nodeRequest.raw || nodeRequest.req || nodeRequest;
53
81
  let fullUrl = buildFullUrl(rawRequest);
@@ -58,10 +86,16 @@ export function normalizeNodeRequest(nodeRequest, RequestCtor) {
58
86
  }
59
87
  fullUrl = url.toString();
60
88
  }
89
+ const signal = new ServerAdapterRequestAbortSignal();
90
+ if (rawRequest.once) {
91
+ rawRequest.once('end', () => signal.sendAbort());
92
+ rawRequest.once('close', () => signal.sendAbort());
93
+ }
61
94
  if (nodeRequest.method === 'GET' || nodeRequest.method === 'HEAD') {
62
95
  return new RequestCtor(fullUrl, {
63
96
  method: nodeRequest.method,
64
97
  headers: nodeRequest.headers,
98
+ signal,
65
99
  });
66
100
  }
67
101
  /**
@@ -77,11 +111,13 @@ export function normalizeNodeRequest(nodeRequest, RequestCtor) {
77
111
  method: nodeRequest.method,
78
112
  headers: nodeRequest.headers,
79
113
  body: maybeParsedBody,
114
+ signal,
80
115
  });
81
116
  }
82
117
  const request = new RequestCtor(fullUrl, {
83
118
  method: nodeRequest.method,
84
119
  headers: nodeRequest.headers,
120
+ signal,
85
121
  });
86
122
  if (!request.headers.get('content-type')?.includes('json')) {
87
123
  request.headers.set('content-type', 'application/json; charset=utf-8');
@@ -104,6 +140,7 @@ export function normalizeNodeRequest(nodeRequest, RequestCtor) {
104
140
  method: nodeRequest.method,
105
141
  headers: nodeRequest.headers,
106
142
  body: rawRequest,
143
+ signal,
107
144
  });
108
145
  }
109
146
  export function isReadable(stream) {
@@ -167,11 +204,10 @@ export function sendNodeResponse(fetchResponse, serverResponse, nodeRequest) {
167
204
  serverResponse.setHeader(key, value);
168
205
  });
169
206
  // Optimizations for node-fetch
170
- if (fetchResponse.bodyType === 'Buffer' ||
171
- fetchResponse.bodyType === 'String' ||
172
- fetchResponse.bodyType === 'Uint8Array') {
207
+ const bufOfRes = fetchResponse._buffer;
208
+ if (bufOfRes) {
173
209
  // @ts-expect-error http and http2 writes are actually compatible
174
- serverResponse.write(fetchResponse.bodyInit);
210
+ serverResponse.write(bufOfRes);
175
211
  endResponse(serverResponse);
176
212
  return;
177
213
  }
@@ -1,34 +1,7 @@
1
+ import { ServerAdapterRequestAbortSignal } from './utils.js';
1
2
  export function isUWSResponse(res) {
2
3
  return !!res.onData;
3
4
  }
4
- class UWSAbortSignal extends EventTarget {
5
- throwIfAborted() {
6
- if (this.aborted) {
7
- throw new DOMException('Aborted', 'AbortError');
8
- }
9
- }
10
- constructor(res) {
11
- super();
12
- this.aborted = false;
13
- this._onabort = null;
14
- res.onAborted(() => {
15
- this.aborted = true;
16
- this.dispatchEvent(new Event('request aborted'));
17
- });
18
- }
19
- get onabort() {
20
- return this._onabort;
21
- }
22
- set onabort(value) {
23
- this._onabort = value;
24
- if (value) {
25
- this.addEventListener('request aborted', value);
26
- }
27
- else {
28
- this.removeEventListener('request aborted', value);
29
- }
30
- }
31
- }
32
5
  export function getRequestFromUWSRequest({ req, res, fetchAPI }) {
33
6
  let body;
34
7
  const method = req.getMethod();
@@ -62,7 +35,7 @@ export function getRequestFromUWSRequest({ req, res, fetchAPI }) {
62
35
  method,
63
36
  headers,
64
37
  body: body,
65
- signal: new UWSAbortSignal(res),
38
+ signal: new ServerAdapterRequestAbortSignal(),
66
39
  });
67
40
  }
68
41
  async function forwardResponseBodyToUWSResponse(uwsResponse, fetchResponse) {
@@ -88,9 +61,7 @@ export function sendResponseToUwsOpts(uwsResponse, fetchResponse) {
88
61
  uwsResponse.end();
89
62
  return;
90
63
  }
91
- const isStringOrBuffer = fetchResponse.bodyType === 'Buffer' ||
92
- fetchResponse.bodyType === 'String' ||
93
- fetchResponse.bodyType === 'Uint8Array';
64
+ const bufferOfRes = fetchResponse._buffer;
94
65
  uwsResponse.cork(() => {
95
66
  uwsResponse.writeStatus(`${fetchResponse.status} ${fetchResponse.statusText}`);
96
67
  for (const [key, value] of fetchResponse.headers) {
@@ -108,11 +79,11 @@ export function sendResponseToUwsOpts(uwsResponse, fetchResponse) {
108
79
  uwsResponse.writeHeader(key, value);
109
80
  }
110
81
  }
111
- if (isStringOrBuffer) {
112
- uwsResponse.end(fetchResponse.bodyInit);
82
+ if (bufferOfRes) {
83
+ uwsResponse.end(bufferOfRes);
113
84
  }
114
85
  });
115
- if (isStringOrBuffer) {
86
+ if (bufferOfRes) {
116
87
  return;
117
88
  }
118
89
  if (!fetchResponse.body) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@whatwg-node/server",
3
- "version": "0.9.10",
3
+ "version": "0.9.11-alpha-20230821124424-6f3a2b1",
4
4
  "description": "Fetch API compliant HTTP Server adapter",
5
5
  "sideEffects": false,
6
6
  "dependencies": {
@@ -20,8 +20,18 @@ export interface NodeRequest {
20
20
  raw?: IncomingMessage | Http2ServerRequest;
21
21
  socket?: Socket;
22
22
  query?: any;
23
+ once?(event: string, listener: (...args: any[]) => void): void;
23
24
  }
24
25
  export type NodeResponse = ServerResponse | Http2ServerResponse;
26
+ export declare class ServerAdapterRequestAbortSignal extends EventTarget implements AbortSignal {
27
+ aborted: boolean;
28
+ _onabort: ((this: AbortSignal, ev: Event) => any) | null;
29
+ reason: any;
30
+ throwIfAborted(): void;
31
+ sendAbort(): void;
32
+ get onabort(): ((this: AbortSignal, ev: Event) => any) | null;
33
+ set onabort(value: ((this: AbortSignal, ev: Event) => any) | null);
34
+ }
25
35
  export declare function normalizeNodeRequest(nodeRequest: NodeRequest, RequestCtor: typeof Request): Request;
26
36
  export declare function isReadable(stream: any): stream is Readable;
27
37
  export declare function isNodeRequest(request: any): request is NodeRequest;
@@ -20,8 +20,18 @@ export interface NodeRequest {
20
20
  raw?: IncomingMessage | Http2ServerRequest;
21
21
  socket?: Socket;
22
22
  query?: any;
23
+ once?(event: string, listener: (...args: any[]) => void): void;
23
24
  }
24
25
  export type NodeResponse = ServerResponse | Http2ServerResponse;
26
+ export declare class ServerAdapterRequestAbortSignal extends EventTarget implements AbortSignal {
27
+ aborted: boolean;
28
+ _onabort: ((this: AbortSignal, ev: Event) => any) | null;
29
+ reason: any;
30
+ throwIfAborted(): void;
31
+ sendAbort(): void;
32
+ get onabort(): ((this: AbortSignal, ev: Event) => any) | null;
33
+ set onabort(value: ((this: AbortSignal, ev: Event) => any) | null);
34
+ }
25
35
  export declare function normalizeNodeRequest(nodeRequest: NodeRequest, RequestCtor: typeof Request): Request;
26
36
  export declare function isReadable(stream: any): stream is Readable;
27
37
  export declare function isNodeRequest(request: any): request is NodeRequest;