@jongleberry/api-server 1.2.0 → 1.2.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.
@@ -5,6 +5,7 @@ import Router from "find-my-way";
5
5
  import { ServerTiming } from "./server-timing.mjs";
6
6
  import { Logger } from "./logger.mjs";
7
7
  import { getRawPath } from "./request-path.mjs";
8
+ import { createRequestAbortController } from "./request-abort.mjs";
8
9
  import { applySecurityHeaders, ensureFallbackHeaders, getFallbackBody, getFallbackStatus, resolveSecurityHeaders, safeString, sendFallback, } from "./fallback-response.mjs";
9
10
  export class Application extends EventEmitter {
10
11
  router = Router();
@@ -81,14 +82,9 @@ export class Application extends EventEmitter {
81
82
  }
82
83
  }
83
84
  async runRequest(req, res) {
84
- const abortController = new AbortController();
85
+ const abortController = createRequestAbortController(res);
85
86
  const timing = new ServerTiming();
86
87
  const ContextClass = this.contextClass;
87
- res.once("close", () => {
88
- if (!res.writableEnded) {
89
- abortController.abort();
90
- }
91
- });
92
88
  const { onWriteHead, onFinish } = this.logger.onRequestStart(req);
93
89
  const ctx = new ContextClass(req, res, {}, timing, this.asyncLocalStorage, abortController, this.bodyLimit, this.trustProxy, onWriteHead, this.strictJsonContentType, this.oversizedBodyStrategy);
94
90
  applySecurityHeaders(res, this.securityHeaders);
@@ -0,0 +1,2 @@
1
+ import type { ServerResponse } from "node:http";
2
+ export declare function createRequestAbortController(response: ServerResponse): AbortController;
@@ -0,0 +1,21 @@
1
+ function isPositiveFinite(limit) {
2
+ return limit > 0 && Number.isFinite(limit);
3
+ }
4
+ export function createRequestAbortController(response) {
5
+ const abortController = new AbortController();
6
+ const initialLimit = response.getMaxListeners();
7
+ const reservedListenerSlot = isPositiveFinite(initialLimit);
8
+ if (reservedListenerSlot) {
9
+ response.setMaxListeners(initialLimit + 1);
10
+ }
11
+ response.once("close", () => {
12
+ const currentLimit = response.getMaxListeners();
13
+ if (reservedListenerSlot && isPositiveFinite(currentLimit)) {
14
+ response.setMaxListeners(currentLimit - 1);
15
+ }
16
+ if (!response.writableEnded) {
17
+ abortController.abort();
18
+ }
19
+ });
20
+ return abortController;
21
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jongleberry/api-server",
3
- "version": "1.2.0",
3
+ "version": "1.2.1",
4
4
  "description": "A Node.js HTTP server library",
5
5
  "license": "MIT",
6
6
  "author": "Jonathan Ong",
@@ -44,10 +44,10 @@
44
44
  "@types/type-is": "^1.6.7",
45
45
  "@vitest/coverage-v8": "^4.1.6",
46
46
  "husky": "^9.1.7",
47
- "oxfmt": "^0.56.0",
47
+ "oxfmt": "^0.59.0",
48
48
  "oxlint": "^1.65.0",
49
49
  "supertest": "^7.2.2",
50
- "typescript": "^6.0.3",
50
+ "typescript": "^7.0.2",
51
51
  "vitest": "^4.1.6"
52
52
  },
53
53
  "scripts": {