diff --git a/README.md b/README.md
index 9537d05..0665985 100644
--- a/README.md
+++ b/README.md
@@ -9,7 +9,7 @@
-
+
@@ -46,7 +46,7 @@ import { initRequestInterrupts, getAbortSignal } from '@saborter/server/express'
const app = express();
const port = process.env.PORT || 3000;
-initRequestInterrupts(app, { endpointName: '/api/abort' });
+initRequestInterrupts(app);
app.use(express.json());
app.get('/', async (req, res) => {
diff --git a/demo/express/package-lock.json b/demo/express/package-lock.json
index 401d2e3..171fd00 100644
--- a/demo/express/package-lock.json
+++ b/demo/express/package-lock.json
@@ -63,9 +63,9 @@
}
},
"node_modules/@saborter/server": {
- "version": "1.0.0",
+ "version": "1.0.1",
"resolved": "file:saborter-server-1.0.1.tgz",
- "integrity": "sha512-B4WuIeOlR3DEqcO/VsKAj2dm4gGrxeGcSI/32W8qmQKkJd9a9inoXl5Zq1XYf32mDDcGjbjl4EgKDbvw4Aznmw==",
+ "integrity": "sha512-Wc0GR9zyUYXZFxhOeyQiQfgaoBIRXwdLZRsf+2VE1tscOSdSlDJLTxRY/FnD3LSVpKJbU3vBRrOkBODNZi7yOQ==",
"license": "MIT",
"peerDependencies": {
"express": "^4.17.0 || ^5.0.0",
diff --git a/demo/express/package.json b/demo/express/package.json
index dc747f5..80da26e 100644
--- a/demo/express/package.json
+++ b/demo/express/package.json
@@ -5,7 +5,7 @@
"scripts": {
"start": "node dist/index.js",
"build": "tsc",
- "dev": "nodemon src/index.ts"
+ "dev": "nodemon src/index.ts -watch"
},
"keywords": [],
"author": "",
@@ -14,7 +14,7 @@
"dependencies": {
"cors": "^2.8.6",
"express": "^5.2.1",
- "@saborter/server": "file:./saborter-server-1.0.0.tgz"
+ "@saborter/server": "file:./saborter-server-1.0.1.tgz"
},
"devDependencies": {
"@types/express": "^5.0.6",
diff --git a/demo/express/saborter-server-1.0.0.tgz b/demo/express/saborter-server-1.0.0.tgz
deleted file mode 100644
index 0f5d000..0000000
Binary files a/demo/express/saborter-server-1.0.0.tgz and /dev/null differ
diff --git a/demo/express/saborter-server-1.0.1.tgz b/demo/express/saborter-server-1.0.1.tgz
new file mode 100644
index 0000000..f1a25e3
Binary files /dev/null and b/demo/express/saborter-server-1.0.1.tgz differ
diff --git a/demo/express/src/index.ts b/demo/express/src/index.ts
index 814e094..081e13e 100644
--- a/demo/express/src/index.ts
+++ b/demo/express/src/index.ts
@@ -6,7 +6,7 @@ import { initRequestInterrupts, getAbortSignal } from '@saborter/server/express'
const app = express();
const port = process.env['PORT'] || 3000;
-initRequestInterrupts(app, { endpointName: '/api/cancel' });
+initRequestInterrupts(app);
app.use(cors());
app.use(express.json());
diff --git a/package.json b/package.json
index 5b37fbf..7634383 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@saborter/server",
- "version": "1.0.0",
+ "version": "1.0.1",
"description": "Lightweight, tree‑shakeable utility to cancel server tasks on client abort",
"main": "dist/express.cjs.js",
"module": "dist/express.es.js",
diff --git a/src/packages/frameworks/express/express.constants.ts b/src/packages/frameworks/express/express.constants.ts
new file mode 100644
index 0000000..568f03d
--- /dev/null
+++ b/src/packages/frameworks/express/express.constants.ts
@@ -0,0 +1 @@
+export const ENDPOINT_WAS_INTERRUPTED_MESSAGE = 'The endpoint was interrupted';
diff --git a/src/packages/frameworks/express/express.service.ts b/src/packages/frameworks/express/express.service.ts
index 7a4d0db..26dc9a0 100644
--- a/src/packages/frameworks/express/express.service.ts
+++ b/src/packages/frameworks/express/express.service.ts
@@ -1,6 +1,7 @@
import { Request, Response, NextFunction, Express } from 'express';
import { AbortError } from 'saborter/errors';
import { setSignalInExpressRequest } from './express.utils';
+import * as Constants from './express.constants';
import * as Shared from '../../../shared';
/**
@@ -76,7 +77,7 @@ class ExpressRequestInterruptionService {
setSignalInExpressRequest(req, controller);
this.registerAbortableFunction(requestId, () => {
- controller.abort(new AbortError('The endpoint was interrupted', { initiator: 'server' }));
+ controller.abort(new AbortError(Constants.ENDPOINT_WAS_INTERRUPTED_MESSAGE, { initiator: 'server' }));
});
req.on('close', () => {
@@ -85,6 +86,7 @@ class ExpressRequestInterruptionService {
}
});
+ // Triggers clearing of request id when request completes or fails, excluding the case of abort.
res.on('finish', () => {
if (!controller.signal.aborted) {
this.abortRegistries.delete(requestId);
@@ -100,65 +102,14 @@ class ExpressRequestInterruptionService {
*
* This function:
* - Adds a middleware that attaches an `AbortSignal` to every request.
- * - Adds a POST endpoint (default `/api/cancel`) that can be called to abort a
- * specific request by sending its request ID in the request body.
*
* @param app - Express application instance.
- * @param options - Configuration options.
- * @param options.endpointName - The path where the abort endpoint will be mounted.
- * Defaults to `/api/cancel`.
+
* @returns An `ExpressRequestInterruptionService` instance, which can be used
* to manually abort requests if needed.
*/
-export const initRequestInterrupts = (
- app: Express,
- { endpointName = '/api/cancel' }: { endpointName?: string } = {}
-) => {
+export const initRequestInterrupts = (app: Express): void => {
const requestInterruptionService = new ExpressRequestInterruptionService();
app.use(requestInterruptionService.expressMiddleware);
-
- app.post(`${endpointName}`, async (req, res) => {
- const requestId = await new Promise((resolve) => {
- let rawBody = '';
-
- req.on('data', (chunk) => {
- rawBody += chunk;
- });
- req.on('end', () => {
- resolve(rawBody);
- });
- });
-
- if (requestId && requestInterruptionService.abort(requestId)) {
- res.status(200).json({ aborted: true });
- } else {
- res.status(404).json({ error: 'Request not found' });
- }
- });
};
-
-/**
- * Retrieves the `signal` property from an Express Request object.
- *
- * @param {import('express').Request} req - The Express request object.
- * @returns {AbortSignal | undefined} The abort signal attached to the request,
- * or `undefined` if the property does not exist.
- *
- * @example
- * // In a route handler
- * app.get('/data', (req, res) => {
- * const signal = getAbortSignal(req);
- * fetch('https://api.example.com/data', { signal })
- * .then(response => response.json())
- * .then(data => res.json(data))
- * .catch(err => {
- * if (err.name === 'AbortError') {
- * res.status(499).end();
- * } else {
- * res.status(500).end();
- * }
- * });
- * });
- */
-export const getAbortSignal = (req: Request): AbortSignal | undefined => (req as any).signal;
diff --git a/src/packages/frameworks/express/express.utils.ts b/src/packages/frameworks/express/express.utils.ts
index 02991d8..977f570 100644
--- a/src/packages/frameworks/express/express.utils.ts
+++ b/src/packages/frameworks/express/express.utils.ts
@@ -21,3 +21,28 @@ import { Request } from 'express';
export const setSignalInExpressRequest = (req: Request, controller: AbortController): void => {
(req as any).signal = controller.signal;
};
+
+/**
+ * Retrieves the `signal` property from an Express Request object.
+ *
+ * @param {import('express').Request} req - The Express request object.
+ * @returns {AbortSignal | undefined} The abort signal attached to the request,
+ * or `undefined` if the property does not exist.
+ *
+ * @example
+ * // In a route handler
+ * app.get('/data', (req, res) => {
+ * const signal = getAbortSignal(req);
+ * fetch('https://api.example.com/data', { signal })
+ * .then(response => response.json())
+ * .then(data => res.json(data))
+ * .catch(err => {
+ * if (err.name === 'AbortError') {
+ * res.status(499).end();
+ * } else {
+ * res.status(500).end();
+ * }
+ * });
+ * });
+ */
+export const getAbortSignal = (req: Request): AbortSignal | undefined => (req as any).signal;
diff --git a/src/packages/frameworks/express/index.ts b/src/packages/frameworks/express/index.ts
index c4fc744..30f6ee8 100644
--- a/src/packages/frameworks/express/index.ts
+++ b/src/packages/frameworks/express/index.ts
@@ -1 +1,2 @@
export * from './express.service';
+export { getAbortSignal } from './express.utils';
diff --git a/src/shared/utils/get-request-id/get-request-id.util.ts b/src/shared/utils/get-request-id/get-request-id.util.ts
index f86f9f4..4ca87fc 100644
--- a/src/shared/utils/get-request-id/get-request-id.util.ts
+++ b/src/shared/utils/get-request-id/get-request-id.util.ts
@@ -1,7 +1,7 @@
import * as Constants from './get-request-id.constants';
export const getRequestId = (req: T): string => {
- const requestId = req.headers[Constants.X_REQUEST_ID_HEADER]?.toString().split(',');
+ const requestId = req.headers[Constants.X_REQUEST_ID_HEADER]?.toString();
- return requestId?.[0] ?? '';
+ return requestId ?? '';
};