@fatcherjs/middleware-aborter 1.8.0 → 2.0.0

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.
package/README.md CHANGED
@@ -2,6 +2,12 @@
2
2
 
3
3
  A middleware for aborting fatcher request.
4
4
 
5
+ [![codecov](https://codecov.io/gh/fatcherjs/middleware-aborter/branch/master/graph/badge.svg?token=TFKUGW6YNI)](https://codecov.io/gh/fatcherjs/middleware-aborter)
6
+ [![install size](https://packagephobia.com/badge?p=@fatcherjs/middleware-aborter)](https://packagephobia.com/result?p=@fatcherjs/middleware-aborter)
7
+ <a href="https://unpkg.com/@fatcherjs/middleware-aborter"><img alt="Size" src="https://img.badgesize.io/https://unpkg.com/@fatcherjs/middleware-aborter"></a>
8
+ <a href="https://npmjs.com/package/@fatcherjs/middleware-aborter"><img src="https://img.shields.io/npm/v/@fatcherjs/middleware-aborter.svg" alt="npm package"></a>
9
+ <a href="https://github.com/fatcherjs/middleware-aborter/actions/workflows/ci.yml"><img src="https://github.com/fatcherjs/middleware-aborter/actions/workflows/ci.yml/badge.svg?branch=master" alt="build status"></a>
10
+
5
11
  ## Install
6
12
 
7
13
  ### NPM
@@ -19,8 +25,8 @@ A middleware for aborting fatcher request.
19
25
  ## Usage
20
26
 
21
27
  ```ts
22
- import { aborter } from '@fatcherjs/middleware-aborter';
23
- import { fatcher, isAbortError } from 'fatcher';
28
+ import { aborter, isAbortError } from '@fatcherjs/middleware-aborter';
29
+ import { fatcher } from 'fatcher';
24
30
 
25
31
  fatcher({
26
32
  url: '/bar/foo',
package/dist/aborter.d.ts CHANGED
@@ -1,13 +1,20 @@
1
- import { Context, Middleware } from 'fatcher';
1
+ import * as fatcher from 'fatcher';
2
+ import { Context } from 'fatcher';
2
3
 
3
- declare type AbortReason = 'concurrency' | 'timeout' | 'manual';
4
- declare type AbortEventHandler = (type: AbortReason) => void;
5
4
  declare type RoadSign = {
6
- abort: (type: AbortReason) => void;
7
- timer: NodeJS.Timeout | null;
5
+ abort: () => void;
8
6
  signal: AbortSignal;
9
7
  };
10
8
  declare type RoadMap = Record<string, RoadSign[]>;
9
+ interface AborterMiddlewareContext extends Readonly<Context> {
10
+ /**
11
+ * Provides with aborter
12
+ *
13
+ * @require `@fatcherjs/middleware-aborter`
14
+ */
15
+ abort: () => void;
16
+ signal: AbortSignal;
17
+ }
11
18
  interface AborterOptions {
12
19
  /**
13
20
  * Request timeout
@@ -22,7 +29,7 @@ interface AborterOptions {
22
29
  *
23
30
  * @default null
24
31
  */
25
- onAbort?: AbortEventHandler | null;
32
+ onAbort?: (() => void) | null;
26
33
  /**
27
34
  * Request concurrency restrictions
28
35
  *
@@ -40,7 +47,7 @@ interface AborterOptions {
40
47
  * @param options
41
48
  * @returns
42
49
  */
43
- declare function aborter(options?: AborterOptions): Middleware;
50
+ declare function aborter(options?: AborterOptions): fatcher.Middleware[];
44
51
 
45
52
  /**
46
53
  * Confirm an error whether is DOMException
@@ -49,4 +56,4 @@ declare function aborter(options?: AborterOptions): Middleware;
49
56
  */
50
57
  declare function isAbortError(error: unknown): error is DOMException;
51
58
 
52
- export { AbortEventHandler, AbortReason, AborterOptions, RoadMap, RoadSign, aborter, isAbortError };
59
+ export { AborterMiddlewareContext, AborterOptions, RoadMap, RoadSign, aborter, isAbortError };
@@ -1,51 +1,68 @@
1
+ import { defineMiddleware } from 'fatcher';
2
+
1
3
  const roadMap = {};
2
4
  function aborter(options = {}) {
3
5
  const { timeout = 0, onAbort = null, concurrency, groupBy } = options;
4
6
  let _timeout = timeout;
5
- if (isNaN(timeout) || ~~timeout < 0) {
7
+ if (isNaN(_timeout) || ~~_timeout < 0) {
6
8
  console.warn("[fatcher-middleware-aborter] Timeout is not a valid number.");
7
9
  _timeout = 0;
8
10
  }
9
- return {
10
- name: "fatcher-middleware-aborter",
11
- async use(context, next) {
12
- var _a, _b, _c;
13
- const abortController = new AbortController();
14
- const { abort, signal } = abortController;
15
- const requestTask = next({ signal });
16
- const group = (_a = groupBy == null ? void 0 : groupBy(context)) != null ? _a : `${context.url}_${context.method}_${new URLSearchParams(context.params).toString()}`;
17
- if (((_b = roadMap[group]) == null ? void 0 : _b.length) && concurrency) {
18
- roadMap[group].forEach((item) => {
19
- item.abort("concurrency");
20
- });
11
+ const baseAborter = defineMiddleware(async (context, next) => {
12
+ const abortController = new AbortController();
13
+ if (onAbort) {
14
+ abortController.signal.addEventListener("abort", () => onAbort());
15
+ }
16
+ return next({
17
+ signal: abortController.signal,
18
+ abort: abortController.abort.bind(abortController)
19
+ });
20
+ }, "fatcher-middleware-aborter");
21
+ const timeoutAborter = defineMiddleware(async (context, next) => {
22
+ const { signal, abort } = context;
23
+ let timer = setTimeout(abort, _timeout);
24
+ const release = () => {
25
+ if (timer) {
26
+ clearTimeout(timer);
21
27
  }
22
- (_c = roadMap[group]) != null ? _c : roadMap[group] = [];
23
- const trigger = (reason) => {
24
- abort.call(abortController);
25
- onAbort == null ? void 0 : onAbort(reason);
26
- };
27
- roadMap[group].push({
28
- abort: trigger,
29
- timer: _timeout ? setTimeout(() => trigger("timeout"), _timeout) : null,
30
- signal
31
- });
32
- signal.addEventListener("abort", () => {
33
- roadMap[group] = roadMap[group].filter((item) => {
34
- if (item.signal === signal) {
35
- if (item.timer) {
36
- clearTimeout(item.timer);
37
- }
38
- return false;
39
- }
40
- return true;
41
- });
42
- if (!roadMap[group].length) {
43
- delete roadMap[group];
44
- }
45
- });
46
- return requestTask;
28
+ timer = null;
29
+ };
30
+ signal.addEventListener("abort", release);
31
+ const result = await next();
32
+ release();
33
+ return result;
34
+ }, "fatcher-middleware-timeout-aborter");
35
+ const concurrencyAborter = defineMiddleware(async (context, next) => {
36
+ const { signal, abort } = context;
37
+ const group = groupBy ? groupBy(context) : `${context.url}_${context.method}_${new URLSearchParams(context.params)}`;
38
+ if (roadMap[group] && roadMap[group].length) {
39
+ roadMap[group].forEach((item) => item.abort());
40
+ }
41
+ if (!roadMap[group]) {
42
+ roadMap[group] = [];
47
43
  }
48
- };
44
+ roadMap[group].push({ abort, signal });
45
+ const release = () => {
46
+ roadMap[group] = roadMap[group].filter((item) => {
47
+ return item.signal !== signal;
48
+ });
49
+ if (!roadMap[group].length) {
50
+ delete roadMap[group];
51
+ }
52
+ };
53
+ signal.addEventListener("abort", release);
54
+ const result = await next();
55
+ release();
56
+ return result;
57
+ }, "fatcher-middleware-concurrency-aborter");
58
+ const middlewares = [baseAborter];
59
+ if (_timeout) {
60
+ middlewares.push(timeoutAborter);
61
+ }
62
+ if (concurrency) {
63
+ middlewares.push(concurrencyAborter);
64
+ }
65
+ return middlewares;
49
66
  }
50
67
 
51
68
  function isAbortError(error) {
package/dist/aborter.js CHANGED
@@ -2,54 +2,71 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
+ var fatcher = require('fatcher');
6
+
5
7
  const roadMap = {};
6
8
  function aborter(options = {}) {
7
9
  const { timeout = 0, onAbort = null, concurrency, groupBy } = options;
8
10
  let _timeout = timeout;
9
- if (isNaN(timeout) || ~~timeout < 0) {
11
+ if (isNaN(_timeout) || ~~_timeout < 0) {
10
12
  console.warn("[fatcher-middleware-aborter] Timeout is not a valid number.");
11
13
  _timeout = 0;
12
14
  }
13
- return {
14
- name: "fatcher-middleware-aborter",
15
- async use(context, next) {
16
- var _a, _b, _c;
17
- const abortController = new AbortController();
18
- const { abort, signal } = abortController;
19
- const requestTask = next({ signal });
20
- const group = (_a = groupBy == null ? void 0 : groupBy(context)) != null ? _a : `${context.url}_${context.method}_${new URLSearchParams(context.params).toString()}`;
21
- if (((_b = roadMap[group]) == null ? void 0 : _b.length) && concurrency) {
22
- roadMap[group].forEach((item) => {
23
- item.abort("concurrency");
24
- });
15
+ const baseAborter = fatcher.defineMiddleware(async (context, next) => {
16
+ const abortController = new AbortController();
17
+ if (onAbort) {
18
+ abortController.signal.addEventListener("abort", () => onAbort());
19
+ }
20
+ return next({
21
+ signal: abortController.signal,
22
+ abort: abortController.abort.bind(abortController)
23
+ });
24
+ }, "fatcher-middleware-aborter");
25
+ const timeoutAborter = fatcher.defineMiddleware(async (context, next) => {
26
+ const { signal, abort } = context;
27
+ let timer = setTimeout(abort, _timeout);
28
+ const release = () => {
29
+ if (timer) {
30
+ clearTimeout(timer);
25
31
  }
26
- (_c = roadMap[group]) != null ? _c : roadMap[group] = [];
27
- const trigger = (reason) => {
28
- abort.call(abortController);
29
- onAbort == null ? void 0 : onAbort(reason);
30
- };
31
- roadMap[group].push({
32
- abort: trigger,
33
- timer: _timeout ? setTimeout(() => trigger("timeout"), _timeout) : null,
34
- signal
35
- });
36
- signal.addEventListener("abort", () => {
37
- roadMap[group] = roadMap[group].filter((item) => {
38
- if (item.signal === signal) {
39
- if (item.timer) {
40
- clearTimeout(item.timer);
41
- }
42
- return false;
43
- }
44
- return true;
45
- });
46
- if (!roadMap[group].length) {
47
- delete roadMap[group];
48
- }
49
- });
50
- return requestTask;
32
+ timer = null;
33
+ };
34
+ signal.addEventListener("abort", release);
35
+ const result = await next();
36
+ release();
37
+ return result;
38
+ }, "fatcher-middleware-timeout-aborter");
39
+ const concurrencyAborter = fatcher.defineMiddleware(async (context, next) => {
40
+ const { signal, abort } = context;
41
+ const group = groupBy ? groupBy(context) : `${context.url}_${context.method}_${new URLSearchParams(context.params)}`;
42
+ if (roadMap[group] && roadMap[group].length) {
43
+ roadMap[group].forEach((item) => item.abort());
44
+ }
45
+ if (!roadMap[group]) {
46
+ roadMap[group] = [];
51
47
  }
52
- };
48
+ roadMap[group].push({ abort, signal });
49
+ const release = () => {
50
+ roadMap[group] = roadMap[group].filter((item) => {
51
+ return item.signal !== signal;
52
+ });
53
+ if (!roadMap[group].length) {
54
+ delete roadMap[group];
55
+ }
56
+ };
57
+ signal.addEventListener("abort", release);
58
+ const result = await next();
59
+ release();
60
+ return result;
61
+ }, "fatcher-middleware-concurrency-aborter");
62
+ const middlewares = [baseAborter];
63
+ if (_timeout) {
64
+ middlewares.push(timeoutAborter);
65
+ }
66
+ if (concurrency) {
67
+ middlewares.push(concurrencyAborter);
68
+ }
69
+ return middlewares;
53
70
  }
54
71
 
55
72
  function isAbortError(error) {
@@ -1 +1 @@
1
- (function(t,e){typeof exports=="object"&&typeof module!="undefined"?e(exports):typeof define=="function"&&define.amd?define(["exports"],e):(t=typeof globalThis!="undefined"?globalThis:t||self,e(t.FatcherMiddlewareAborter={}))})(this,function(t){"use strict";const e={};function p(o={}){const{timeout:u=0,onAbort:s=null,concurrency:_,groupBy:c}=o;let l=u;return(isNaN(u)||~~u<0)&&(console.warn("[fatcher-middleware-aborter] Timeout is not a valid number."),l=0),{name:"fatcher-middleware-aborter",async use(i,v){var d,f,b;const m=new AbortController,{abort:y,signal:a}=m,w=v({signal:a}),r=(d=c==null?void 0:c(i))!=null?d:`${i.url}_${i.method}_${new URLSearchParams(i.params).toString()}`;((f=e[r])==null?void 0:f.length)&&_&&e[r].forEach(n=>{n.abort("concurrency")}),(b=e[r])!=null||(e[r]=[]);const h=n=>{y.call(m),s==null||s(n)};return e[r].push({abort:h,timer:l?setTimeout(()=>h("timeout"),l):null,signal:a}),a.addEventListener("abort",()=>{e[r]=e[r].filter(n=>n.signal===a?(n.timer&&clearTimeout(n.timer),!1):!0),e[r].length||delete e[r]}),w}}}function g(o){return o instanceof DOMException&&o.name==="AbortError"}t.aborter=p,t.isAbortError=g,Object.defineProperty(t,"__esModule",{value:!0})});
1
+ (function(n,i){typeof exports=="object"&&typeof module!="undefined"?i(exports,require("fatcher")):typeof define=="function"&&define.amd?define(["exports","fatcher"],i):(n=typeof globalThis!="undefined"?globalThis:n||self,i(n.FatcherMiddlewareAborter={},n.Fatcher))})(this,function(n,i){"use strict";const r={};function p(c={}){const{timeout:y=0,onAbort:m=null,concurrency:g,groupBy:h}=c;let a=y;(isNaN(a)||~~a<0)&&(console.warn("[fatcher-middleware-aborter] Timeout is not a valid number."),a=0);const A=i.defineMiddleware(async(o,s)=>{const t=new AbortController;return m&&t.signal.addEventListener("abort",()=>m()),s({signal:t.signal,abort:t.abort.bind(t)})},"fatcher-middleware-aborter"),E=i.defineMiddleware(async(o,s)=>{const{signal:t,abort:l}=o;let e=setTimeout(l,a);const d=()=>{e&&clearTimeout(e),e=null};t.addEventListener("abort",d);const f=await s();return d(),f},"fatcher-middleware-timeout-aborter"),M=i.defineMiddleware(async(o,s)=>{const{signal:t,abort:l}=o,e=h?h(o):`${o.url}_${o.method}_${new URLSearchParams(o.params)}`;r[e]&&r[e].length&&r[e].forEach(b=>b.abort()),r[e]||(r[e]=[]),r[e].push({abort:l,signal:t});const d=()=>{r[e]=r[e].filter(b=>b.signal!==t),r[e].length||delete r[e]};t.addEventListener("abort",d);const f=await s();return d(),f},"fatcher-middleware-concurrency-aborter"),u=[A];return a&&u.push(E),g&&u.push(M),u}function w(c){return c instanceof DOMException&&c.name==="AbortError"}n.aborter=p,n.isAbortError=w,Object.defineProperty(n,"__esModule",{value:!0})});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fatcherjs/middleware-aborter",
3
- "version": "1.8.0",
3
+ "version": "2.0.0",
4
4
  "main": "dist/aborter.js",
5
5
  "module": "dist/aborter.esm.js",
6
6
  "browser": "dist/aborter.min.js",
@@ -14,12 +14,36 @@
14
14
  "type": "git",
15
15
  "url": "git+https://github.com/fatcherjs/fatcher.git"
16
16
  },
17
- "dependencies": {
18
- "fatcher": "^1.8.0"
17
+ "devDependencies": {
18
+ "@fansy/eslint-config": "^1.1.0",
19
+ "@fansy/prettier-config": "^1.0.0",
20
+ "@jest/types": "^29.1.2",
21
+ "@rollup/plugin-node-resolve": "^15.0.0",
22
+ "@types/jest": "^29.1.2",
23
+ "@types/node": "^18.8.5",
24
+ "esbuild": "^0.15.10",
25
+ "fatcher": "^2.0.0",
26
+ "jest": "^29.1.2",
27
+ "jest-fetch-mock": "^3.0.3",
28
+ "rimraf": "^3.0.2",
29
+ "rollup": "^2.79.1",
30
+ "rollup-plugin-dts": "^4.2.3",
31
+ "rollup-plugin-esbuild": "^4.10.1",
32
+ "ts-jest": "^29.0.3",
33
+ "ts-node": "^10.9.1",
34
+ "typescript": "^4.8.4"
35
+ },
36
+ "peerDependencies": {
37
+ "fatcher": "^2.0.0"
19
38
  },
20
39
  "scripts": {
21
40
  "dev": "rimraf dist && rollup -c rollup.config.ts -w",
22
41
  "build": "rimraf dist && rollup -c rollup.config.ts",
23
- "deploy": "pnpm run build && pnpm publish --no-git-check"
42
+ "deploy": "pnpm run build && pnpm publish --no-git-check",
43
+ "test": "jest",
44
+ "test:cov": "jest --coverage",
45
+ "eslint": "eslint .",
46
+ "tsc": "tsc --noEmit",
47
+ "ci": "npm run eslint && npm run tsc && npm run build && npm run test"
24
48
  }
25
49
  }