mini-semaphore 1.3.16 → 1.4.2

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/cjs/core.js CHANGED
@@ -1,9 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.release = exports.acquire = void 0;
3
+ exports.releaseWithAbort = exports.acquireWithAbort = exports.release = exports.acquire = void 0;
4
4
  /**
5
5
  * @typedef {import("./index").TVoidFunction} TVoidFunction
6
6
  * @typedef {import("./index").Deque<TVoidFunction>} Deque
7
+ * @typedef {import("./index").TFlowableLockWithAbort} TFlowableLockWithAbort
8
+ * @typedef {import("./index").Deque<TResolver>} DequeWithAbort
7
9
  * @typedef {import("./index").ISimplifiedLock} ISimplifiedLock
8
10
  * @typedef {import("./index").TFlowableLock} TFlowableLock
9
11
  * @typedef {import("./index").IFlowableLock} IFlowableLock
@@ -62,4 +64,45 @@ const release = (dis) => {
62
64
  dis.capacity = dis.limit;
63
65
  }
64
66
  };
65
- exports.release = release;
67
+ exports.release = release;
68
+ /**
69
+ * @param {TFlowableLockWithAbort} dis
70
+ * @returns {Promise<void>}
71
+ */
72
+ const acquireWithAbort = (dis) => {
73
+ return new Promise((resolve, reject) => {
74
+ if (dis.capacity > 0) {
75
+ dis.capacity--, resolve();
76
+ }
77
+ else {
78
+ dis.q.push({
79
+ resolve, reject
80
+ });
81
+ }
82
+ });
83
+ };
84
+ exports.acquireWithAbort = acquireWithAbort;
85
+ /**
86
+ * @param {TFlowableLockWithAbort} dis
87
+ * @returns {void}
88
+ */
89
+ const releaseWithAbort = (dis) => {
90
+ /** @type {DequeWithAbort} */
91
+ let dq;
92
+ if ((dq = dis.q).length) {
93
+ const resolver = dq.shift();
94
+ /* istanbul ignore next */
95
+ if (!resolver) {
96
+ THROW();
97
+ }
98
+ else {
99
+ resolver.resolve();
100
+ }
101
+ }
102
+ else {
103
+ if (dis.capacity < dis.limit) {
104
+ dis.capacity++;
105
+ }
106
+ }
107
+ };
108
+ exports.releaseWithAbort = releaseWithAbort;
package/cjs/deque.js CHANGED
@@ -23,26 +23,28 @@ const am = (src, si, dst, di, len) => {
23
23
  */
24
24
  const p2l = (n) => {
25
25
  n = n >>> 0;
26
- n = n - 1;
27
- n = n | (n >> 1);
28
- n = n | (n >> 2);
29
- n = n | (n >> 4);
30
- n = n | (n >> 8);
31
- n = n | (n >> 16);
26
+ n--;
27
+ n |= n >> 1;
28
+ n |= n >> 2;
29
+ n |= n >> 4;
30
+ n |= n >> 8;
31
+ n |= n >> 16;
32
32
  return n + 1;
33
33
  };
34
34
  /**
35
35
  * getCapacity
36
- * @param {number=} n
36
+ * @param {number} n
37
37
  */
38
38
  const gc = (n) => {
39
- // @ts-ignore typescript cannot allow (undefined | 0) expression
40
39
  return p2l(Math.min(Math.max(16, n | 0), 1073741824));
41
40
  };
42
41
  /**
43
42
  * ### Implementation restricted to FIFO
44
43
  *
45
- * this class is based on https://github.com/petkaantonov/deque/blob/master/js/deque.js
44
+ * This class uses a ring buffer for efficient FIFO operations.
45
+ * The maximum buffer size is **`1073741824`**.
46
+ *
47
+ * This class is based on https://github.com/petkaantonov/deque/blob/master/js/deque.js
46
48
  * Released under the MIT License: https://github.com/petkaantonov/deque/blob/master/LICENSE
47
49
  *
48
50
  * @template {any} T
@@ -55,23 +57,28 @@ class Deque {
55
57
  constructor(ic) {
56
58
  /**
57
59
  * capacity
58
- * @type {number}
60
+ * @internal
59
61
  */
60
- this._c = gc(ic);
62
+ this._c = gc(ic || 16);
61
63
  /**
62
64
  * current length (size
63
- * @type {number}
65
+ * @internal
64
66
  */
65
67
  this._l = 0;
66
68
  /**
67
69
  * current front position
68
- * @type {number}
70
+ * @internal
69
71
  */
70
72
  this._f = 0;
71
73
  /**
72
74
  * @type {T[]}
75
+ * @internal
73
76
  */
74
77
  this._a = [];
78
+ /**
79
+ * current length (size
80
+ */
81
+ this.length = 0;
75
82
  }
76
83
  /**
77
84
  * @param {T} s subject
@@ -83,7 +90,7 @@ class Deque {
83
90
  }
84
91
  const i = (this._f + l) & (this._c - 1);
85
92
  this._a[i] = s;
86
- this._l = l + 1;
93
+ this.length = this._l = l + 1;
87
94
  }
88
95
  shift() {
89
96
  const l = this._l;
@@ -95,12 +102,9 @@ class Deque {
95
102
  const r = this._a[f];
96
103
  this._a[f] = /** @type {T} */ (void 0);
97
104
  this._f = (f + 1) & (this._c - 1);
98
- this._l = l - 1;
105
+ this.length = this._l = l - 1;
99
106
  return r;
100
107
  }
101
- get length() {
102
- return this._l;
103
- }
104
108
  }
105
109
  exports.Deque = Deque;
106
110
  /**
@@ -109,6 +113,7 @@ exports.Deque = Deque;
109
113
  * @template {any} T
110
114
  * @param {Deque<T>} dis
111
115
  * @param {number} n expected capacity
116
+ * @todo test code
112
117
  */
113
118
  const rt = (dis, n) => {
114
119
  const oc = dis._c;
package/cjs/index.d.ts CHANGED
@@ -7,23 +7,24 @@
7
7
  export declare class Deque<T extends any> {
8
8
  /**
9
9
  * capacity
10
- * @type {number}
10
+ * @internal
11
11
  */
12
12
  _c: number;
13
13
  /**
14
14
  * current length (size
15
- * @type {number}
15
+ * @internal
16
16
  */
17
17
  _l: number;
18
18
  /**
19
19
  * current front position
20
- * @type {number}
20
+ * @internal
21
21
  */
22
22
  _f: number;
23
23
  /**
24
- * @type {T[]}
24
+ * @internal
25
25
  */
26
26
  _a: T[];
27
+
27
28
  /**
28
29
  * default capacity `16`
29
30
  * @param ic initial capacity
@@ -35,7 +36,7 @@ export declare class Deque<T extends any> {
35
36
  push(s: T): void;
36
37
  shift(): T | undefined;
37
38
  // clear(): void;
38
- get length(): number;
39
+ readonly length: number;
39
40
  }
40
41
 
41
42
  /**
@@ -95,6 +96,14 @@ export declare type TFlowableLock<T = TVoidFunction> = IFlowableLock & {
95
96
  };
96
97
  export declare type TVoidFunction = () => void;
97
98
 
99
+ export declare type TResolver = {
100
+ resolve: () => void;
101
+ reject: (reason: any) => void;
102
+ };
103
+ export declare type TFlowableLockWithAbort = IFlowableLock & {
104
+ readonly q: Deque<TResolver>;
105
+ abort(): void;
106
+ };
98
107
 
99
108
  /**
100
109
  * #### Mini Semaphore
@@ -160,7 +169,7 @@ export declare class MiniSemaphore implements TFlowableLock {
160
169
  }
161
170
 
162
171
  /**
163
- * object implementation of `IFlowableLock`
172
+ * object implementation of `TFlowableLock`
164
173
  *
165
174
  * + constructs a semaphore object limited at `capacity`
166
175
  *
@@ -168,7 +177,18 @@ export declare class MiniSemaphore implements TFlowableLock {
168
177
  * @date 2020/2/7
169
178
  * @version 1.0
170
179
  */
171
- export declare const create: (capacity: number) => IFlowableLock;
180
+ export declare const create: (capacity: number) => TFlowableLock;
181
+ /**
182
+ * object implementation of `TFlowableLockWithAbort`
183
+ *
184
+ * + constructs a semaphore object limited at `capacity`
185
+ *
186
+ * @param {number} capacity limitation of concurrent async by `capacity`
187
+ * @date 2025/5/12
188
+ * @version 1.4
189
+ */
190
+ export declare const createWithAbort: (capacity: number) => TFlowableLockWithAbort;
191
+
172
192
 
173
193
  declare namespace fr {
174
194
  /**
package/cjs/index.js CHANGED
@@ -1,12 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.version = exports.restrictor = exports.Deque = exports.create = exports.MiniSemaphore = void 0;
3
+ exports.version = exports.restrictor = exports.Deque = exports.createWithAbort = exports.create = exports.MiniSemaphore = void 0;
4
4
  var class_1 = require("./class");
5
5
  Object.defineProperty(exports, "MiniSemaphore", { enumerable: true, get: function () { return class_1.MiniSemaphore; } });
6
6
  var object_1 = require("./object");
7
7
  Object.defineProperty(exports, "create", { enumerable: true, get: function () { return object_1.create; } });
8
+ Object.defineProperty(exports, "createWithAbort", { enumerable: true, get: function () { return object_1.createWithAbort; } });
8
9
  var deque_1 = require("./deque");
9
10
  Object.defineProperty(exports, "Deque", { enumerable: true, get: function () { return deque_1.Deque; } });
10
11
  var flow_restrictor_1 = require("./flow-restrictor");
11
12
  Object.defineProperty(exports, "restrictor", { enumerable: true, get: function () { return flow_restrictor_1.restrictor; } });
12
- exports.version = "v1.3.16";
13
+ exports.version = "v1.4.2";
package/cjs/object.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.create = void 0;
3
+ exports.createWithAbort = exports.create = void 0;
4
4
  /*!
5
5
  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
6
6
  Copyright (C) 2020 jeffy-g <hirotom1107@gmail.com>
@@ -17,6 +17,26 @@ const core = require("./core");
17
17
  const deque_1 = require("./deque");
18
18
  const a = core.acquire;
19
19
  const r = core.release;
20
+ const aa = core.acquireWithAbort;
21
+ const ra = core.releaseWithAbort;
22
+ /**
23
+ * @template {core.IFlowableLock & { q: Deque<unknown>}} T
24
+ * @param {number} capacity
25
+ * @returns
26
+ */
27
+ const createBase = (capacity) => {
28
+ return /** @type {T} */ ({
29
+ capacity,
30
+ limit: capacity,
31
+ q: new deque_1.Deque(capacity),
32
+ /**
33
+ * @param {number} restriction
34
+ */
35
+ setRestriction(restriction) {
36
+ this.limit = this.capacity = restriction;
37
+ },
38
+ });
39
+ };
20
40
  /**
21
41
  * object implementation of `IFlowableLock`
22
42
  *
@@ -27,10 +47,13 @@ const r = core.release;
27
47
  * @version 1.0
28
48
  */
29
49
  const create = (capacity) => {
50
+ /** @type {core.TFlowableLock} */
51
+ const base = createBase(capacity);
30
52
  return /** @satisfies {core.TFlowableLock} */ ({
31
- capacity,
32
- limit: capacity,
33
- q: new deque_1.Deque(capacity),
53
+ ...base,
54
+ get pending() {
55
+ return this.q.length;
56
+ },
34
57
  /**
35
58
  *
36
59
  * @param {boolean} [lazy]
@@ -43,29 +66,77 @@ const create = (capacity) => {
43
66
  r(this);
44
67
  },
45
68
  /**
46
- * @param {number} restriction
69
+ * @template {any} T
70
+ * @param {() => Promise<T>} process
71
+ * @param {boolean} [lazy]
72
+ * @returns {Promise<T>}
47
73
  */
48
- setRestriction(restriction) {
49
- this.limit = this.capacity = restriction;
50
- },
74
+ async flow(process, lazy) {
75
+ await a(this, lazy);
76
+ try {
77
+ return await process();
78
+ }
79
+ finally {
80
+ r(this);
81
+ }
82
+ }
83
+ });
84
+ };
85
+ exports.create = create;
86
+ /**
87
+ * object implementation of `TFlowableLockWithAbort`
88
+ *
89
+ * + constructs a semaphore object limited at `capacity`
90
+ *
91
+ * @param {number} capacity limitation of concurrent async by `capacity`
92
+ * @date 2025/5/12
93
+ * @version 1.4
94
+ */
95
+ const createWithAbort = (capacity) => {
96
+ /** @type {core.TFlowableLockWithAbort} */
97
+ const base = createBase(capacity);
98
+ return /** @satisfies {core.TFlowableLockWithAbort} */ ({
99
+ ...base,
51
100
  get pending() {
52
101
  return this.q.length;
53
102
  },
103
+ /**
104
+ * @returns {Promise<void>}
105
+ */
106
+ acquire() {
107
+ return aa(this);
108
+ },
109
+ release() {
110
+ ra(this);
111
+ },
54
112
  /**
55
113
  * @template {any} T
56
114
  * @param {() => Promise<T>} process
57
- * @param {boolean} [lazy]
58
115
  * @returns {Promise<T>}
59
116
  */
60
- async flow(process, lazy) {
61
- await a(this, lazy);
117
+ async flow(process) {
118
+ await aa(this);
62
119
  try {
63
120
  return await process();
64
121
  }
65
122
  finally {
66
- r(this);
123
+ ra(this);
124
+ }
125
+ },
126
+ /**
127
+ * @throws {AggregateError} description
128
+ */
129
+ abort() {
130
+ const dq = this.q;
131
+ let resolver;
132
+ const reason = {
133
+ message: "Process Aborted"
134
+ };
135
+ while (resolver = dq.shift()) {
136
+ resolver.reject(reason);
67
137
  }
138
+ this.capacity = this.limit;
68
139
  }
69
140
  });
70
141
  };
71
- exports.create = create;
142
+ exports.createWithAbort = createWithAbort;
package/esm/core.mjs CHANGED
@@ -1,6 +1,8 @@
1
1
  /**
2
2
  * @typedef {import("./index.mjs").TVoidFunction} TVoidFunction
3
3
  * @typedef {import("./index.mjs").Deque<TVoidFunction>} Deque
4
+ * @typedef {import("./index.mjs").TFlowableLockWithAbort} TFlowableLockWithAbort
5
+ * @typedef {import("./index.mjs").Deque<TResolver>} DequeWithAbort
4
6
  * @typedef {import("./index.mjs").ISimplifiedLock} ISimplifiedLock
5
7
  * @typedef {import("./index.mjs").TFlowableLock} TFlowableLock
6
8
  * @typedef {import("./index.mjs").IFlowableLock} IFlowableLock
@@ -57,4 +59,43 @@ export const release = (dis) => {
57
59
  console.warn("inconsistent release!");
58
60
  dis.capacity = dis.limit;
59
61
  }
62
+ };
63
+ /**
64
+ * @param {TFlowableLockWithAbort} dis
65
+ * @returns {Promise<void>}
66
+ */
67
+ export const acquireWithAbort = (dis) => {
68
+ return new Promise((resolve, reject) => {
69
+ if (dis.capacity > 0) {
70
+ dis.capacity--, resolve();
71
+ }
72
+ else {
73
+ dis.q.push({
74
+ resolve, reject
75
+ });
76
+ }
77
+ });
78
+ };
79
+ /**
80
+ * @param {TFlowableLockWithAbort} dis
81
+ * @returns {void}
82
+ */
83
+ export const releaseWithAbort = (dis) => {
84
+ /** @type {DequeWithAbort} */
85
+ let dq;
86
+ if ((dq = dis.q).length) {
87
+ const resolver = dq.shift();
88
+ /* istanbul ignore next */
89
+ if (!resolver) {
90
+ THROW();
91
+ }
92
+ else {
93
+ resolver.resolve();
94
+ }
95
+ }
96
+ else {
97
+ if (dis.capacity < dis.limit) {
98
+ dis.capacity++;
99
+ }
100
+ }
60
101
  };
package/esm/deque.mjs CHANGED
@@ -20,26 +20,28 @@ const am = (src, si, dst, di, len) => {
20
20
  */
21
21
  const p2l = (n) => {
22
22
  n = n >>> 0;
23
- n = n - 1;
24
- n = n | (n >> 1);
25
- n = n | (n >> 2);
26
- n = n | (n >> 4);
27
- n = n | (n >> 8);
28
- n = n | (n >> 16);
23
+ n--;
24
+ n |= n >> 1;
25
+ n |= n >> 2;
26
+ n |= n >> 4;
27
+ n |= n >> 8;
28
+ n |= n >> 16;
29
29
  return n + 1;
30
30
  };
31
31
  /**
32
32
  * getCapacity
33
- * @param {number=} n
33
+ * @param {number} n
34
34
  */
35
35
  const gc = (n) => {
36
- // @ts-ignore typescript cannot allow (undefined | 0) expression
37
36
  return p2l(Math.min(Math.max(16, n | 0), 1073741824));
38
37
  };
39
38
  /**
40
39
  * ### Implementation restricted to FIFO
41
40
  *
42
- * this class is based on https://github.com/petkaantonov/deque/blob/master/js/deque.js
41
+ * This class uses a ring buffer for efficient FIFO operations.
42
+ * The maximum buffer size is **`1073741824`**.
43
+ *
44
+ * This class is based on https://github.com/petkaantonov/deque/blob/master/js/deque.js
43
45
  * Released under the MIT License: https://github.com/petkaantonov/deque/blob/master/LICENSE
44
46
  *
45
47
  * @template {any} T
@@ -52,23 +54,28 @@ export class Deque {
52
54
  constructor(ic) {
53
55
  /**
54
56
  * capacity
55
- * @type {number}
57
+ * @internal
56
58
  */
57
- this._c = gc(ic);
59
+ this._c = gc(ic || 16);
58
60
  /**
59
61
  * current length (size
60
- * @type {number}
62
+ * @internal
61
63
  */
62
64
  this._l = 0;
63
65
  /**
64
66
  * current front position
65
- * @type {number}
67
+ * @internal
66
68
  */
67
69
  this._f = 0;
68
70
  /**
69
71
  * @type {T[]}
72
+ * @internal
70
73
  */
71
74
  this._a = [];
75
+ /**
76
+ * current length (size
77
+ */
78
+ this.length = 0;
72
79
  }
73
80
  /**
74
81
  * @param {T} s subject
@@ -80,7 +87,7 @@ export class Deque {
80
87
  }
81
88
  const i = (this._f + l) & (this._c - 1);
82
89
  this._a[i] = s;
83
- this._l = l + 1;
90
+ this.length = this._l = l + 1;
84
91
  }
85
92
  shift() {
86
93
  const l = this._l;
@@ -92,12 +99,9 @@ export class Deque {
92
99
  const r = this._a[f];
93
100
  this._a[f] = /** @type {T} */ (void 0);
94
101
  this._f = (f + 1) & (this._c - 1);
95
- this._l = l - 1;
102
+ this.length = this._l = l - 1;
96
103
  return r;
97
104
  }
98
- get length() {
99
- return this._l;
100
- }
101
105
  }
102
106
  /**
103
107
  * resize to
@@ -105,6 +109,7 @@ export class Deque {
105
109
  * @template {any} T
106
110
  * @param {Deque<T>} dis
107
111
  * @param {number} n expected capacity
112
+ * @todo test code
108
113
  */
109
114
  const rt = (dis, n) => {
110
115
  const oc = dis._c;
package/esm/index.d.mts CHANGED
@@ -7,23 +7,24 @@
7
7
  export declare class Deque<T extends any> {
8
8
  /**
9
9
  * capacity
10
- * @type {number}
10
+ * @internal
11
11
  */
12
12
  _c: number;
13
13
  /**
14
14
  * current length (size
15
- * @type {number}
15
+ * @internal
16
16
  */
17
17
  _l: number;
18
18
  /**
19
19
  * current front position
20
- * @type {number}
20
+ * @internal
21
21
  */
22
22
  _f: number;
23
23
  /**
24
- * @type {T[]}
24
+ * @internal
25
25
  */
26
26
  _a: T[];
27
+
27
28
  /**
28
29
  * default capacity `16`
29
30
  * @param ic initial capacity
@@ -35,7 +36,7 @@ export declare class Deque<T extends any> {
35
36
  push(s: T): void;
36
37
  shift(): T | undefined;
37
38
  // clear(): void;
38
- get length(): number;
39
+ readonly length: number;
39
40
  }
40
41
 
41
42
  /**
@@ -95,6 +96,14 @@ export declare type TFlowableLock<T = TVoidFunction> = IFlowableLock & {
95
96
  };
96
97
  export declare type TVoidFunction = () => void;
97
98
 
99
+ export declare type TResolver = {
100
+ resolve: () => void;
101
+ reject: (reason: any) => void;
102
+ };
103
+ export declare type TFlowableLockWithAbort = IFlowableLock & {
104
+ readonly q: Deque<TResolver>;
105
+ abort(): void;
106
+ };
98
107
 
99
108
  /**
100
109
  * #### Mini Semaphore
@@ -160,7 +169,7 @@ export declare class MiniSemaphore implements TFlowableLock {
160
169
  }
161
170
 
162
171
  /**
163
- * object implementation of `IFlowableLock`
172
+ * object implementation of `TFlowableLock`
164
173
  *
165
174
  * + constructs a semaphore object limited at `capacity`
166
175
  *
@@ -168,7 +177,18 @@ export declare class MiniSemaphore implements TFlowableLock {
168
177
  * @date 2020/2/7
169
178
  * @version 1.0
170
179
  */
171
- export declare const create: (capacity: number) => IFlowableLock;
180
+ export declare const create: (capacity: number) => TFlowableLock;
181
+ /**
182
+ * object implementation of `TFlowableLockWithAbort`
183
+ *
184
+ * + constructs a semaphore object limited at `capacity`
185
+ *
186
+ * @param {number} capacity limitation of concurrent async by `capacity`
187
+ * @date 2025/5/12
188
+ * @version 1.4
189
+ */
190
+ export declare const createWithAbort: (capacity: number) => TFlowableLockWithAbort;
191
+
172
192
 
173
193
  declare namespace fr {
174
194
  /**
package/esm/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  export { MiniSemaphore } from "./class.mjs";
2
- export { create } from "./object.mjs";
2
+ export { create, createWithAbort } from "./object.mjs";
3
3
  export { Deque } from "./deque.mjs";
4
4
  export { restrictor } from "./flow-restrictor.mjs";
5
- export const version = "v1.3.16";
5
+ export const version = "v1.4.2";
package/esm/object.mjs CHANGED
@@ -14,6 +14,26 @@ import * as core from "./core.mjs";
14
14
  import { Deque } from "./deque.mjs";
15
15
  const a = core.acquire;
16
16
  const r = core.release;
17
+ const aa = core.acquireWithAbort;
18
+ const ra = core.releaseWithAbort;
19
+ /**
20
+ * @template {core.IFlowableLock & { q: Deque<unknown>}} T
21
+ * @param {number} capacity
22
+ * @returns
23
+ */
24
+ const createBase = (capacity) => {
25
+ return /** @type {T} */ ({
26
+ capacity,
27
+ limit: capacity,
28
+ q: new Deque(capacity),
29
+ /**
30
+ * @param {number} restriction
31
+ */
32
+ setRestriction(restriction) {
33
+ this.limit = this.capacity = restriction;
34
+ },
35
+ });
36
+ };
17
37
  /**
18
38
  * object implementation of `IFlowableLock`
19
39
  *
@@ -24,10 +44,13 @@ const r = core.release;
24
44
  * @version 1.0
25
45
  */
26
46
  export const create = (capacity) => {
47
+ /** @type {core.TFlowableLock} */
48
+ const base = createBase(capacity);
27
49
  return /** @satisfies {core.TFlowableLock} */ ({
28
- capacity,
29
- limit: capacity,
30
- q: new Deque(capacity),
50
+ ...base,
51
+ get pending() {
52
+ return this.q.length;
53
+ },
31
54
  /**
32
55
  *
33
56
  * @param {boolean} [lazy]
@@ -40,28 +63,75 @@ export const create = (capacity) => {
40
63
  r(this);
41
64
  },
42
65
  /**
43
- * @param {number} restriction
66
+ * @template {any} T
67
+ * @param {() => Promise<T>} process
68
+ * @param {boolean} [lazy]
69
+ * @returns {Promise<T>}
44
70
  */
45
- setRestriction(restriction) {
46
- this.limit = this.capacity = restriction;
47
- },
71
+ async flow(process, lazy) {
72
+ await a(this, lazy);
73
+ try {
74
+ return await process();
75
+ }
76
+ finally {
77
+ r(this);
78
+ }
79
+ }
80
+ });
81
+ };
82
+ /**
83
+ * object implementation of `TFlowableLockWithAbort`
84
+ *
85
+ * + constructs a semaphore object limited at `capacity`
86
+ *
87
+ * @param {number} capacity limitation of concurrent async by `capacity`
88
+ * @date 2025/5/12
89
+ * @version 1.4
90
+ */
91
+ export const createWithAbort = (capacity) => {
92
+ /** @type {core.TFlowableLockWithAbort} */
93
+ const base = createBase(capacity);
94
+ return /** @satisfies {core.TFlowableLockWithAbort} */ ({
95
+ ...base,
48
96
  get pending() {
49
97
  return this.q.length;
50
98
  },
99
+ /**
100
+ * @returns {Promise<void>}
101
+ */
102
+ acquire() {
103
+ return aa(this);
104
+ },
105
+ release() {
106
+ ra(this);
107
+ },
51
108
  /**
52
109
  * @template {any} T
53
110
  * @param {() => Promise<T>} process
54
- * @param {boolean} [lazy]
55
111
  * @returns {Promise<T>}
56
112
  */
57
- async flow(process, lazy) {
58
- await a(this, lazy);
113
+ async flow(process) {
114
+ await aa(this);
59
115
  try {
60
116
  return await process();
61
117
  }
62
118
  finally {
63
- r(this);
119
+ ra(this);
120
+ }
121
+ },
122
+ /**
123
+ * @throws {AggregateError} description
124
+ */
125
+ abort() {
126
+ const dq = this.q;
127
+ let resolver;
128
+ const reason = {
129
+ message: "Process Aborted"
130
+ };
131
+ while (resolver = dq.shift()) {
132
+ resolver.reject(reason);
64
133
  }
134
+ this.capacity = this.limit;
65
135
  }
66
136
  });
67
137
  };
package/index.d.ts CHANGED
@@ -7,23 +7,24 @@
7
7
  export declare class Deque<T extends any> {
8
8
  /**
9
9
  * capacity
10
- * @type {number}
10
+ * @internal
11
11
  */
12
12
  _c: number;
13
13
  /**
14
14
  * current length (size
15
- * @type {number}
15
+ * @internal
16
16
  */
17
17
  _l: number;
18
18
  /**
19
19
  * current front position
20
- * @type {number}
20
+ * @internal
21
21
  */
22
22
  _f: number;
23
23
  /**
24
- * @type {T[]}
24
+ * @internal
25
25
  */
26
26
  _a: T[];
27
+
27
28
  /**
28
29
  * default capacity `16`
29
30
  * @param ic initial capacity
@@ -35,7 +36,7 @@ export declare class Deque<T extends any> {
35
36
  push(s: T): void;
36
37
  shift(): T | undefined;
37
38
  // clear(): void;
38
- get length(): number;
39
+ readonly length: number;
39
40
  }
40
41
 
41
42
  /**
@@ -95,6 +96,14 @@ export declare type TFlowableLock<T = TVoidFunction> = IFlowableLock & {
95
96
  };
96
97
  export declare type TVoidFunction = () => void;
97
98
 
99
+ export declare type TResolver = {
100
+ resolve: () => void;
101
+ reject: (reason: any) => void;
102
+ };
103
+ export declare type TFlowableLockWithAbort = IFlowableLock & {
104
+ readonly q: Deque<TResolver>;
105
+ abort(): void;
106
+ };
98
107
 
99
108
  /**
100
109
  * #### Mini Semaphore
@@ -160,7 +169,7 @@ export declare class MiniSemaphore implements TFlowableLock {
160
169
  }
161
170
 
162
171
  /**
163
- * object implementation of `IFlowableLock`
172
+ * object implementation of `TFlowableLock`
164
173
  *
165
174
  * + constructs a semaphore object limited at `capacity`
166
175
  *
@@ -168,7 +177,18 @@ export declare class MiniSemaphore implements TFlowableLock {
168
177
  * @date 2020/2/7
169
178
  * @version 1.0
170
179
  */
171
- export declare const create: (capacity: number) => IFlowableLock;
180
+ export declare const create: (capacity: number) => TFlowableLock;
181
+ /**
182
+ * object implementation of `TFlowableLockWithAbort`
183
+ *
184
+ * + constructs a semaphore object limited at `capacity`
185
+ *
186
+ * @param {number} capacity limitation of concurrent async by `capacity`
187
+ * @date 2025/5/12
188
+ * @version 1.4
189
+ */
190
+ export declare const createWithAbort: (capacity: number) => TFlowableLockWithAbort;
191
+
172
192
 
173
193
  declare namespace fr {
174
194
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mini-semaphore",
3
- "version": "1.3.16",
3
+ "version": "1.4.2",
4
4
  "description": "A lightweight version of Semaphore",
5
5
  "private": false,
6
6
  "main": "./cjs/index.js",
package/umd/index.d.ts CHANGED
@@ -7,23 +7,24 @@
7
7
  export declare class Deque<T extends any> {
8
8
  /**
9
9
  * capacity
10
- * @type {number}
10
+ * @internal
11
11
  */
12
12
  _c: number;
13
13
  /**
14
14
  * current length (size
15
- * @type {number}
15
+ * @internal
16
16
  */
17
17
  _l: number;
18
18
  /**
19
19
  * current front position
20
- * @type {number}
20
+ * @internal
21
21
  */
22
22
  _f: number;
23
23
  /**
24
- * @type {T[]}
24
+ * @internal
25
25
  */
26
26
  _a: T[];
27
+
27
28
  /**
28
29
  * default capacity `16`
29
30
  * @param ic initial capacity
@@ -35,7 +36,7 @@ export declare class Deque<T extends any> {
35
36
  push(s: T): void;
36
37
  shift(): T | undefined;
37
38
  // clear(): void;
38
- get length(): number;
39
+ readonly length: number;
39
40
  }
40
41
 
41
42
  /**
@@ -95,6 +96,14 @@ export declare type TFlowableLock<T = TVoidFunction> = IFlowableLock & {
95
96
  };
96
97
  export declare type TVoidFunction = () => void;
97
98
 
99
+ export declare type TResolver = {
100
+ resolve: () => void;
101
+ reject: (reason: any) => void;
102
+ };
103
+ export declare type TFlowableLockWithAbort = IFlowableLock & {
104
+ readonly q: Deque<TResolver>;
105
+ abort(): void;
106
+ };
98
107
 
99
108
  /**
100
109
  * #### Mini Semaphore
@@ -160,7 +169,7 @@ export declare class MiniSemaphore implements TFlowableLock {
160
169
  }
161
170
 
162
171
  /**
163
- * object implementation of `IFlowableLock`
172
+ * object implementation of `TFlowableLock`
164
173
  *
165
174
  * + constructs a semaphore object limited at `capacity`
166
175
  *
@@ -168,7 +177,18 @@ export declare class MiniSemaphore implements TFlowableLock {
168
177
  * @date 2020/2/7
169
178
  * @version 1.0
170
179
  */
171
- export declare const create: (capacity: number) => IFlowableLock;
180
+ export declare const create: (capacity: number) => TFlowableLock;
181
+ /**
182
+ * object implementation of `TFlowableLockWithAbort`
183
+ *
184
+ * + constructs a semaphore object limited at `capacity`
185
+ *
186
+ * @param {number} capacity limitation of concurrent async by `capacity`
187
+ * @date 2025/5/12
188
+ * @version 1.4
189
+ */
190
+ export declare const createWithAbort: (capacity: number) => TFlowableLockWithAbort;
191
+
172
192
 
173
193
  declare namespace fr {
174
194
  /**
package/umd/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  /*! For license information please see index.js.LICENSE.txt */
2
- ((e,t)=>{'object'==typeof exports&&'object'==typeof module?module.exports=t():'function'==typeof define&&define.amd?define([],t):'object'==typeof exports?exports.MiniSema=t():e.MiniSema=t()})(globalThis,(()=>(()=>{"use strict";var e={139:(e,t,i)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.create=void 0;const r=i(461),n=i(761),s=r.acquire,o=r.release;t.create=e=>({capacity:e,limit:e,q:new n.Deque(e),acquire(e){return s(this,e)},release(){o(this)},setRestriction(e){this.limit=this.capacity=e},get pending(){return this.q.length},async flow(e,t){await s(this,t);try{return await e()}finally{o(this)}}})},461:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.release=t.acquire=void 0;const i=()=>{
3
- throw new Error("mini-semaphore: Detected an inconsistent state, possibly due to a logic error or unexpected behavior.")},r=(e,t)=>{e.capacity>0?(e.capacity--,t()):e.q.push(t)};t.acquire=(e,t=!0)=>new Promise((i=>{t?setTimeout((()=>r(e,i)),4):r(e,i)}));t.release=e=>{let t;(t=e.q).length?(t.shift()||i)():e.capacity++,e.capacity>e.limit&&(console.warn("inconsistent release!"),e.capacity=e.limit)}},464:(e,t,i)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.restrictor=void 0;const r=i(518);t.restrictor=(()=>{const{MiniSemaphore:e}=r,t=new e(1);let i=Object.create(null);async function n(r,n,s){const o=await(async(r,n)=>{await t.acquire(!1);let s=i[r];if(s||(i[r]=s=new e(n)),s.limit!==n)throw t.release(),
4
- new ReferenceError(`Cannot get object with different restriction: key: '${String(r)}', lock.limit: ${s.limit} <-> restriction: ${n},`);return t.release(),s})(r,n),a=o.flow(s);return o.last=Date.now(),a}return{getLockByKey:async e=>{await t.acquire(!1);const r=i[e];return t.release(),r},cleanup:async(e,r)=>{await t.acquire(!1);const n=i,s=Object.create(null),o=Object.keys(n);let a,c=0;!e&&(e=1),e*=1e3,r&&(a=[]);for(let t=0,i=o.length;t<i;){const i=o[t++],l=n[i];l.last&&Date.now()-l.last>=e?(c++,r&&a.push(i)):s[i]=l}return i=s,t.release(),r&&console.log(`eliminated: [\n${a.join(",\n")}\n]\nlived: [\n${Object.keys(s).join(",\n")}\n]`),c},multi:n,one:async function(e,t){return n(e,1,t)}}})()},518:(e,t,i)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.MiniSemaphore=void 0
5
- ;const r=i(461),n=i(761),s=r.acquire,o=r.release;t.MiniSemaphore=class{constructor(e){this.limit=this.capacity=e,this.q=new n.Deque(e)}acquire(e){return s(this,e)}release(){o(this)}setRestriction(e){this.limit=this.capacity=e}get pending(){return this.q.length}async flow(e,t){await s(this,t);try{return await e()}finally{o(this)}}}},761:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.Deque=void 0;const i=e=>(e=>(e>>>=0,e-=1,e|=e>>1,e|=e>>2,e|=e>>4,e|=e>>8,1+(e|=e>>16)))(Math.min(Math.max(16,0|e),1073741824));t.Deque=class{constructor(e){this._c=i(e),this._l=0,this._f=0,this._a=[]}push(e){const t=this._l;this._c<t+1&&r(this,i(1.5*this._c+16));const n=this._f+t&this._c-1;this._a[n]=e,this._l=t+1}shift(){const e=this._l;if(0===e)return;const t=this._f,i=this._a[t]
6
- ;return this._a[t]=void 0,this._f=t+1&this._c-1,this._l=e-1,i}get length(){return this._l}};const r=(e,t)=>{const i=e._c;e._c=t;const r=e._f+e._l;if(r>i){const t=r&i-1;((e,t,i,r,n)=>{for(let s=0;s<n;++s)i[s+r]=e[s+t],e[s+t]=void 0})(e._a,0,e._a,i,t)}}}},t={};function i(r){var n=t[r];if(void 0!==n)return n.exports;var s=t[r]={exports:{}};return e[r](s,s.exports,i),s.exports}var r={};return(()=>{var e=r;Object.defineProperty(e,"__esModule",{value:!0}),e.version=e.restrictor=e.Deque=e.create=e.MiniSemaphore=void 0;var t=i(518);Object.defineProperty(e,"MiniSemaphore",{enumerable:!0,get:function(){return t.MiniSemaphore}});var n=i(139);Object.defineProperty(e,"create",{enumerable:!0,get:function(){return n.create}});var s=i(761);Object.defineProperty(e,"Deque",{enumerable:!0,get:function(){
7
- return s.Deque}});var o=i(464);Object.defineProperty(e,"restrictor",{enumerable:!0,get:function(){return o.restrictor}}),e.version="v1.3.16"})(),r})()));
2
+ ((e,t)=>{'object'==typeof exports&&'object'==typeof module?module.exports=t():'function'==typeof define&&define.amd?define([],t):'object'==typeof exports?exports.MiniSema=t():e.MiniSema=t()})(globalThis,(()=>(()=>{"use strict";var e={139:(e,t,i)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.createWithAbort=t.create=void 0;const r=i(461),n=i(761),s=r.acquire,a=r.release,o=r.acquireWithAbort,c=r.releaseWithAbort,l=e=>({capacity:e,limit:e,q:new n.Deque(e),setRestriction(e){this.limit=this.capacity=e}});t.create=e=>({...l(e),get pending(){return this.q.length},acquire(e){return s(this,e)},release(){a(this)},async flow(e,t){await s(this,t);try{return await e()}finally{a(this)}}});t.createWithAbort=e=>({...l(e),get pending(){return this.q.length},acquire(){return o(this)},release(){
3
+ c(this)},async flow(e){await o(this);try{return await e()}finally{c(this)}},abort(){const e=this.q;let t;const i={message:"Process Aborted"};for(;t=e.shift();)t.reject(i);this.capacity=this.limit}})},461:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.releaseWithAbort=t.acquireWithAbort=t.release=t.acquire=void 0;const i=()=>{throw new Error("mini-semaphore: Detected an inconsistent state, possibly due to a logic error or unexpected behavior.")},r=(e,t)=>{e.capacity>0?(e.capacity--,t()):e.q.push(t)};t.acquire=(e,t=!0)=>new Promise((i=>{t?setTimeout((()=>r(e,i)),4):r(e,i)}));t.release=e=>{let t;(t=e.q).length?(t.shift()||i)():e.capacity++,e.capacity>e.limit&&(console.warn("inconsistent release!"),e.capacity=e.limit)};t.acquireWithAbort=e=>new Promise(((t,i)=>{
4
+ e.capacity>0?(e.capacity--,t()):e.q.push({resolve:t,reject:i})}));t.releaseWithAbort=e=>{let t;if((t=e.q).length){const e=t.shift();e?e.resolve():i()}else e.capacity<e.limit&&e.capacity++}},464:(e,t,i)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.restrictor=void 0;const r=i(518);t.restrictor=(()=>{const{MiniSemaphore:e}=r,t=new e(1);let i=Object.create(null);async function n(r,n,s){const a=await(async(r,n)=>{await t.acquire(!1);let s=i[r];if(s||(i[r]=s=new e(n)),s.limit!==n)throw t.release(),new ReferenceError(`Cannot get object with different restriction: key: '${String(r)}', lock.limit: ${s.limit} <-> restriction: ${n},`);return t.release(),s})(r,n),o=a.flow(s);return a.last=Date.now(),o}return{getLockByKey:async e=>{await t.acquire(!1);const r=i[e];return t.release(),r},
5
+ cleanup:async(e,r)=>{await t.acquire(!1);const n=i,s=Object.create(null),a=Object.keys(n);let o,c=0;!e&&(e=1),e*=1e3,r&&(o=[]);for(let t=0,i=a.length;t<i;){const i=a[t++],l=n[i];l.last&&Date.now()-l.last>=e?(c++,r&&o.push(i)):s[i]=l}return i=s,t.release(),r&&console.log(`eliminated: [\n${o.join(",\n")}\n]\nlived: [\n${Object.keys(s).join(",\n")}\n]`),c},multi:n,one:async function(e,t){return n(e,1,t)}}})()},518:(e,t,i)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.MiniSemaphore=void 0;const r=i(461),n=i(761),s=r.acquire,a=r.release;t.MiniSemaphore=class{constructor(e){this.limit=this.capacity=e,this.q=new n.Deque(e)}acquire(e){return s(this,e)}release(){a(this)}setRestriction(e){this.limit=this.capacity=e}get pending(){return this.q.length}async flow(e,t){await s(this,t);try{
6
+ return await e()}finally{a(this)}}}},761:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.Deque=void 0;const i=e=>(e=>(e>>>=0,e--,e|=e>>1,e|=e>>2,e|=e>>4,e|=e>>8,1+(e|=e>>16)))(Math.min(Math.max(16,0|e),1073741824));t.Deque=class{constructor(e){this._c=i(e||16),this._l=0,this._f=0,this._a=[],this.length=0}push(e){const t=this._l;this._c<t+1&&r(this,i(1.5*this._c+16));const n=this._f+t&this._c-1;this._a[n]=e,this.length=this._l=t+1}shift(){const e=this._l;if(0===e)return;const t=this._f,i=this._a[t];return this._a[t]=void 0,this._f=t+1&this._c-1,this.length=this._l=e-1,i}};const r=(e,t)=>{const i=e._c;e._c=t;const r=e._f+e._l;if(r>i){const t=r&i-1;((e,t,i,r,n)=>{for(let s=0;s<n;++s)i[s+r]=e[s+t],e[s+t]=void 0})(e._a,0,e._a,i,t)}}}},t={};function i(r){var n=t[r]
7
+ ;if(void 0!==n)return n.exports;var s=t[r]={exports:{}};return e[r](s,s.exports,i),s.exports}var r={};return(()=>{var e=r;Object.defineProperty(e,"__esModule",{value:!0}),e.version=e.restrictor=e.Deque=e.createWithAbort=e.create=e.MiniSemaphore=void 0;var t=i(518);Object.defineProperty(e,"MiniSemaphore",{enumerable:!0,get:function(){return t.MiniSemaphore}});var n=i(139);Object.defineProperty(e,"create",{enumerable:!0,get:function(){return n.create}}),Object.defineProperty(e,"createWithAbort",{enumerable:!0,get:function(){return n.createWithAbort}});var s=i(761);Object.defineProperty(e,"Deque",{enumerable:!0,get:function(){return s.Deque}});var a=i(464);Object.defineProperty(e,"restrictor",{enumerable:!0,get:function(){return a.restrictor}}),e.version="v1.4.2"})(),r})()));
@@ -7,23 +7,24 @@
7
7
  export declare class Deque<T extends any> {
8
8
  /**
9
9
  * capacity
10
- * @type {number}
10
+ * @internal
11
11
  */
12
12
  _c: number;
13
13
  /**
14
14
  * current length (size
15
- * @type {number}
15
+ * @internal
16
16
  */
17
17
  _l: number;
18
18
  /**
19
19
  * current front position
20
- * @type {number}
20
+ * @internal
21
21
  */
22
22
  _f: number;
23
23
  /**
24
- * @type {T[]}
24
+ * @internal
25
25
  */
26
26
  _a: T[];
27
+
27
28
  /**
28
29
  * default capacity `16`
29
30
  * @param ic initial capacity
@@ -35,7 +36,7 @@ export declare class Deque<T extends any> {
35
36
  push(s: T): void;
36
37
  shift(): T | undefined;
37
38
  // clear(): void;
38
- get length(): number;
39
+ readonly length: number;
39
40
  }
40
41
 
41
42
  /**
@@ -95,6 +96,14 @@ export declare type TFlowableLock<T = TVoidFunction> = IFlowableLock & {
95
96
  };
96
97
  export declare type TVoidFunction = () => void;
97
98
 
99
+ export declare type TResolver = {
100
+ resolve: () => void;
101
+ reject: (reason: any) => void;
102
+ };
103
+ export declare type TFlowableLockWithAbort = IFlowableLock & {
104
+ readonly q: Deque<TResolver>;
105
+ abort(): void;
106
+ };
98
107
 
99
108
  /**
100
109
  * #### Mini Semaphore
@@ -160,7 +169,7 @@ export declare class MiniSemaphore implements TFlowableLock {
160
169
  }
161
170
 
162
171
  /**
163
- * object implementation of `IFlowableLock`
172
+ * object implementation of `TFlowableLock`
164
173
  *
165
174
  * + constructs a semaphore object limited at `capacity`
166
175
  *
@@ -168,7 +177,18 @@ export declare class MiniSemaphore implements TFlowableLock {
168
177
  * @date 2020/2/7
169
178
  * @version 1.0
170
179
  */
171
- export declare const create: (capacity: number) => IFlowableLock;
180
+ export declare const create: (capacity: number) => TFlowableLock;
181
+ /**
182
+ * object implementation of `TFlowableLockWithAbort`
183
+ *
184
+ * + constructs a semaphore object limited at `capacity`
185
+ *
186
+ * @param {number} capacity limitation of concurrent async by `capacity`
187
+ * @date 2025/5/12
188
+ * @version 1.4
189
+ */
190
+ export declare const createWithAbort: (capacity: number) => TFlowableLockWithAbort;
191
+
172
192
 
173
193
  declare namespace fr {
174
194
  /**
package/webpack/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  /*! For license information please see index.js.LICENSE.txt */
2
- (()=>{"use strict";var e={139:(e,t,i)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.create=void 0;const r=i(461),n=i(761),s=r.acquire,a=r.release;t.create=e=>({capacity:e,limit:e,q:new n.Deque(e),acquire(e){return s(this,e)},release(){a(this)},setRestriction(e){this.limit=this.capacity=e},get pending(){return this.q.length},async flow(e,t){await s(this,t);try{return await e()}finally{a(this)}}})},461:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.release=t.acquire=void 0;const i=()=>{throw new Error("mini-semaphore: Detected an inconsistent state, possibly due to a logic error or unexpected behavior.")},r=(e,t)=>{e.capacity>0?(e.capacity--,t()):e.q.push(t)};t.acquire=(e,t=!0)=>new Promise((i=>{t?setTimeout((()=>r(e,i)),4):r(e,i)}));t.release=e=>{let t
3
- ;(t=e.q).length?(t.shift()||i)():e.capacity++,e.capacity>e.limit&&(console.warn("inconsistent release!"),e.capacity=e.limit)}},464:(e,t,i)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.restrictor=void 0;const r=i(518);t.restrictor=(()=>{const{MiniSemaphore:e}=r,t=new e(1);let i=Object.create(null);async function n(r,n,s){const a=await(async(r,n)=>{await t.acquire(!1);let s=i[r];if(s||(i[r]=s=new e(n)),s.limit!==n)throw t.release(),new ReferenceError(`Cannot get object with different restriction: key: '${String(r)}', lock.limit: ${s.limit} <-> restriction: ${n},`);return t.release(),s})(r,n),c=a.flow(s);return a.last=Date.now(),c}return{getLockByKey:async e=>{await t.acquire(!1);const r=i[e];return t.release(),r},cleanup:async(e,r)=>{await t.acquire(!1)
4
- ;const n=i,s=Object.create(null),a=Object.keys(n);let c,o=0;!e&&(e=1),e*=1e3,r&&(c=[]);for(let t=0,i=a.length;t<i;){const i=a[t++],l=n[i];l.last&&Date.now()-l.last>=e?(o++,r&&c.push(i)):s[i]=l}return i=s,t.release(),r&&console.log(`eliminated: [\n${c.join(",\n")}\n]\nlived: [\n${Object.keys(s).join(",\n")}\n]`),o},multi:n,one:async function(e,t){return n(e,1,t)}}})()},518:(e,t,i)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.MiniSemaphore=void 0;const r=i(461),n=i(761),s=r.acquire,a=r.release;t.MiniSemaphore=class{constructor(e){this.limit=this.capacity=e,this.q=new n.Deque(e)}acquire(e){return s(this,e)}release(){a(this)}setRestriction(e){this.limit=this.capacity=e}get pending(){return this.q.length}async flow(e,t){await s(this,t);try{return await e()}finally{a(this)}}}},
5
- 761:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.Deque=void 0;const i=e=>(e=>(e>>>=0,e-=1,e|=e>>1,e|=e>>2,e|=e>>4,e|=e>>8,1+(e|=e>>16)))(Math.min(Math.max(16,0|e),1073741824));t.Deque=class{constructor(e){this._c=i(e),this._l=0,this._f=0,this._a=[]}push(e){const t=this._l;this._c<t+1&&r(this,i(1.5*this._c+16));const n=this._f+t&this._c-1;this._a[n]=e,this._l=t+1}shift(){const e=this._l;if(0===e)return;const t=this._f,i=this._a[t];return this._a[t]=void 0,this._f=t+1&this._c-1,this._l=e-1,i}get length(){return this._l}};const r=(e,t)=>{const i=e._c;e._c=t;const r=e._f+e._l;if(r>i){const t=r&i-1;((e,t,i,r,n)=>{for(let s=0;s<n;++s)i[s+r]=e[s+t],e[s+t]=void 0})(e._a,0,e._a,i,t)}}}},t={};function i(r){var n=t[r];if(void 0!==n)return n.exports;var s=t[r]={exports:{}}
6
- ;return e[r](s,s.exports,i),s.exports}var r={};(()=>{var e=r;Object.defineProperty(e,"__esModule",{value:!0}),e.version=e.restrictor=e.Deque=e.create=e.MiniSemaphore=void 0;var t=i(518);Object.defineProperty(e,"MiniSemaphore",{enumerable:!0,get:function(){return t.MiniSemaphore}});var n=i(139);Object.defineProperty(e,"create",{enumerable:!0,get:function(){return n.create}});var s=i(761);Object.defineProperty(e,"Deque",{enumerable:!0,get:function(){return s.Deque}});var a=i(464);Object.defineProperty(e,"restrictor",{enumerable:!0,get:function(){return a.restrictor}}),e.version="v1.3.16"})(),module.exports=r})();
2
+ (()=>{"use strict";var e={139:(e,t,i)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.createWithAbort=t.create=void 0;const r=i(461),n=i(761),s=r.acquire,a=r.release,c=r.acquireWithAbort,o=r.releaseWithAbort,l=e=>({capacity:e,limit:e,q:new n.Deque(e),setRestriction(e){this.limit=this.capacity=e}});t.create=e=>({...l(e),get pending(){return this.q.length},acquire(e){return s(this,e)},release(){a(this)},async flow(e,t){await s(this,t);try{return await e()}finally{a(this)}}});t.createWithAbort=e=>({...l(e),get pending(){return this.q.length},acquire(){return c(this)},release(){o(this)},async flow(e){await c(this);try{return await e()}finally{o(this)}},abort(){const e=this.q;let t;const i={message:"Process Aborted"};for(;t=e.shift();)t.reject(i);this.capacity=this.limit}})},461:(e,t)=>{
3
+ Object.defineProperty(t,"__esModule",{value:!0}),t.releaseWithAbort=t.acquireWithAbort=t.release=t.acquire=void 0;const i=()=>{throw new Error("mini-semaphore: Detected an inconsistent state, possibly due to a logic error or unexpected behavior.")},r=(e,t)=>{e.capacity>0?(e.capacity--,t()):e.q.push(t)};t.acquire=(e,t=!0)=>new Promise((i=>{t?setTimeout((()=>r(e,i)),4):r(e,i)}));t.release=e=>{let t;(t=e.q).length?(t.shift()||i)():e.capacity++,e.capacity>e.limit&&(console.warn("inconsistent release!"),e.capacity=e.limit)};t.acquireWithAbort=e=>new Promise(((t,i)=>{e.capacity>0?(e.capacity--,t()):e.q.push({resolve:t,reject:i})}));t.releaseWithAbort=e=>{let t;if((t=e.q).length){const e=t.shift();e?e.resolve():i()}else e.capacity<e.limit&&e.capacity++}},464:(e,t,i)=>{
4
+ Object.defineProperty(t,"__esModule",{value:!0}),t.restrictor=void 0;const r=i(518);t.restrictor=(()=>{const{MiniSemaphore:e}=r,t=new e(1);let i=Object.create(null);async function n(r,n,s){const a=await(async(r,n)=>{await t.acquire(!1);let s=i[r];if(s||(i[r]=s=new e(n)),s.limit!==n)throw t.release(),new ReferenceError(`Cannot get object with different restriction: key: '${String(r)}', lock.limit: ${s.limit} <-> restriction: ${n},`);return t.release(),s})(r,n),c=a.flow(s);return a.last=Date.now(),c}return{getLockByKey:async e=>{await t.acquire(!1);const r=i[e];return t.release(),r},cleanup:async(e,r)=>{await t.acquire(!1);const n=i,s=Object.create(null),a=Object.keys(n);let c,o=0;!e&&(e=1),e*=1e3,r&&(c=[]);for(let t=0,i=a.length;t<i;){const i=a[t++],l=n[i];l.last&&Date.now()-l.last>=e?(o++,
5
+ r&&c.push(i)):s[i]=l}return i=s,t.release(),r&&console.log(`eliminated: [\n${c.join(",\n")}\n]\nlived: [\n${Object.keys(s).join(",\n")}\n]`),o},multi:n,one:async function(e,t){return n(e,1,t)}}})()},518:(e,t,i)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.MiniSemaphore=void 0;const r=i(461),n=i(761),s=r.acquire,a=r.release;t.MiniSemaphore=class{constructor(e){this.limit=this.capacity=e,this.q=new n.Deque(e)}acquire(e){return s(this,e)}release(){a(this)}setRestriction(e){this.limit=this.capacity=e}get pending(){return this.q.length}async flow(e,t){await s(this,t);try{return await e()}finally{a(this)}}}},761:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.Deque=void 0;const i=e=>(e=>(e>>>=0,e--,e|=e>>1,e|=e>>2,e|=e>>4,e|=e>>8,
6
+ 1+(e|=e>>16)))(Math.min(Math.max(16,0|e),1073741824));t.Deque=class{constructor(e){this._c=i(e||16),this._l=0,this._f=0,this._a=[],this.length=0}push(e){const t=this._l;this._c<t+1&&r(this,i(1.5*this._c+16));const n=this._f+t&this._c-1;this._a[n]=e,this.length=this._l=t+1}shift(){const e=this._l;if(0===e)return;const t=this._f,i=this._a[t];return this._a[t]=void 0,this._f=t+1&this._c-1,this.length=this._l=e-1,i}};const r=(e,t)=>{const i=e._c;e._c=t;const r=e._f+e._l;if(r>i){const t=r&i-1;((e,t,i,r,n)=>{for(let s=0;s<n;++s)i[s+r]=e[s+t],e[s+t]=void 0})(e._a,0,e._a,i,t)}}}},t={};function i(r){var n=t[r];if(void 0!==n)return n.exports;var s=t[r]={exports:{}};return e[r](s,s.exports,i),s.exports}var r={};(()=>{var e=r;Object.defineProperty(e,"__esModule",{value:!0}),
7
+ e.version=e.restrictor=e.Deque=e.createWithAbort=e.create=e.MiniSemaphore=void 0;var t=i(518);Object.defineProperty(e,"MiniSemaphore",{enumerable:!0,get:function(){return t.MiniSemaphore}});var n=i(139);Object.defineProperty(e,"create",{enumerable:!0,get:function(){return n.create}}),Object.defineProperty(e,"createWithAbort",{enumerable:!0,get:function(){return n.createWithAbort}});var s=i(761);Object.defineProperty(e,"Deque",{enumerable:!0,get:function(){return s.Deque}});var a=i(464);Object.defineProperty(e,"restrictor",{enumerable:!0,get:function(){return a.restrictor}}),e.version="v1.4.2"})(),module.exports=r})();
@@ -7,23 +7,24 @@
7
7
  export declare class Deque<T extends any> {
8
8
  /**
9
9
  * capacity
10
- * @type {number}
10
+ * @internal
11
11
  */
12
12
  _c: number;
13
13
  /**
14
14
  * current length (size
15
- * @type {number}
15
+ * @internal
16
16
  */
17
17
  _l: number;
18
18
  /**
19
19
  * current front position
20
- * @type {number}
20
+ * @internal
21
21
  */
22
22
  _f: number;
23
23
  /**
24
- * @type {T[]}
24
+ * @internal
25
25
  */
26
26
  _a: T[];
27
+
27
28
  /**
28
29
  * default capacity `16`
29
30
  * @param ic initial capacity
@@ -35,7 +36,7 @@ export declare class Deque<T extends any> {
35
36
  push(s: T): void;
36
37
  shift(): T | undefined;
37
38
  // clear(): void;
38
- get length(): number;
39
+ readonly length: number;
39
40
  }
40
41
 
41
42
  /**
@@ -95,6 +96,14 @@ export declare type TFlowableLock<T = TVoidFunction> = IFlowableLock & {
95
96
  };
96
97
  export declare type TVoidFunction = () => void;
97
98
 
99
+ export declare type TResolver = {
100
+ resolve: () => void;
101
+ reject: (reason: any) => void;
102
+ };
103
+ export declare type TFlowableLockWithAbort = IFlowableLock & {
104
+ readonly q: Deque<TResolver>;
105
+ abort(): void;
106
+ };
98
107
 
99
108
  /**
100
109
  * #### Mini Semaphore
@@ -160,7 +169,7 @@ export declare class MiniSemaphore implements TFlowableLock {
160
169
  }
161
170
 
162
171
  /**
163
- * object implementation of `IFlowableLock`
172
+ * object implementation of `TFlowableLock`
164
173
  *
165
174
  * + constructs a semaphore object limited at `capacity`
166
175
  *
@@ -168,7 +177,18 @@ export declare class MiniSemaphore implements TFlowableLock {
168
177
  * @date 2020/2/7
169
178
  * @version 1.0
170
179
  */
171
- export declare const create: (capacity: number) => IFlowableLock;
180
+ export declare const create: (capacity: number) => TFlowableLock;
181
+ /**
182
+ * object implementation of `TFlowableLockWithAbort`
183
+ *
184
+ * + constructs a semaphore object limited at `capacity`
185
+ *
186
+ * @param {number} capacity limitation of concurrent async by `capacity`
187
+ * @date 2025/5/12
188
+ * @version 1.4
189
+ */
190
+ export declare const createWithAbort: (capacity: number) => TFlowableLockWithAbort;
191
+
172
192
 
173
193
  declare namespace fr {
174
194
  /**
@@ -1,6 +1,7 @@
1
1
  /*! For license information please see index.js.LICENSE.txt */
2
- var e={139:(e,t,i)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.create=void 0;const r=i(461),n=i(761),s=r.acquire,a=r.release;t.create=e=>({capacity:e,limit:e,q:new n.Deque(e),acquire(e){return s(this,e)},release(){a(this)},setRestriction(e){this.limit=this.capacity=e},get pending(){return this.q.length},async flow(e,t){await s(this,t);try{return await e()}finally{a(this)}}})},461:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.release=t.acquire=void 0;const i=()=>{throw new Error("mini-semaphore: Detected an inconsistent state, possibly due to a logic error or unexpected behavior.")},r=(e,t)=>{e.capacity>0?(e.capacity--,t()):e.q.push(t)};t.acquire=(e,t=!0)=>new Promise((i=>{t?setTimeout((()=>r(e,i)),4):r(e,i)}));t.release=e=>{let t
3
- ;(t=e.q).length?(t.shift()||i)():e.capacity++,e.capacity>e.limit&&(console.warn("inconsistent release!"),e.capacity=e.limit)}},464:(e,t,i)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.restrictor=void 0;const r=i(518);t.restrictor=(()=>{const{MiniSemaphore:e}=r,t=new e(1);let i=Object.create(null);async function n(r,n,s){const a=await(async(r,n)=>{await t.acquire(!1);let s=i[r];if(s||(i[r]=s=new e(n)),s.limit!==n)throw t.release(),new ReferenceError(`Cannot get object with different restriction: key: '${String(r)}', lock.limit: ${s.limit} <-> restriction: ${n},`);return t.release(),s})(r,n),c=a.flow(s);return a.last=Date.now(),c}return{getLockByKey:async e=>{await t.acquire(!1);const r=i[e];return t.release(),r},cleanup:async(e,r)=>{await t.acquire(!1)
4
- ;const n=i,s=Object.create(null),a=Object.keys(n);let c,o=0;!e&&(e=1),e*=1e3,r&&(c=[]);for(let t=0,i=a.length;t<i;){const i=a[t++],l=n[i];l.last&&Date.now()-l.last>=e?(o++,r&&c.push(i)):s[i]=l}return i=s,t.release(),r&&console.log(`eliminated: [\n${c.join(",\n")}\n]\nlived: [\n${Object.keys(s).join(",\n")}\n]`),o},multi:n,one:async function(e,t){return n(e,1,t)}}})()},518:(e,t,i)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.MiniSemaphore=void 0;const r=i(461),n=i(761),s=r.acquire,a=r.release;t.MiniSemaphore=class{constructor(e){this.limit=this.capacity=e,this.q=new n.Deque(e)}acquire(e){return s(this,e)}release(){a(this)}setRestriction(e){this.limit=this.capacity=e}get pending(){return this.q.length}async flow(e,t){await s(this,t);try{return await e()}finally{a(this)}}}},
5
- 761:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.Deque=void 0;const i=e=>(e=>(e>>>=0,e-=1,e|=e>>1,e|=e>>2,e|=e>>4,e|=e>>8,1+(e|=e>>16)))(Math.min(Math.max(16,0|e),1073741824));t.Deque=class{constructor(e){this._c=i(e),this._l=0,this._f=0,this._a=[]}push(e){const t=this._l;this._c<t+1&&r(this,i(1.5*this._c+16));const n=this._f+t&this._c-1;this._a[n]=e,this._l=t+1}shift(){const e=this._l;if(0===e)return;const t=this._f,i=this._a[t];return this._a[t]=void 0,this._f=t+1&this._c-1,this._l=e-1,i}get length(){return this._l}};const r=(e,t)=>{const i=e._c;e._c=t;const r=e._f+e._l;if(r>i){const t=r&i-1;((e,t,i,r,n)=>{for(let s=0;s<n;++s)i[s+r]=e[s+t],e[s+t]=void 0})(e._a,0,e._a,i,t)}}}},t={};function i(r){var n=t[r];if(void 0!==n)return n.exports;var s=t[r]={exports:{}}
6
- ;return e[r](s,s.exports,i),s.exports}var r={};(()=>{var e=r;Object.defineProperty(e,"BJ",{value:!0}),e.rE=e.Ws=e.Jj=e.vt=e.C=void 0;var t=i(518);Object.defineProperty(e,"C",{enumerable:!0,get:function(){return t.MiniSemaphore}});var n=i(139);Object.defineProperty(e,"vt",{enumerable:!0,get:function(){return n.create}});var s=i(761);Object.defineProperty(e,"Jj",{enumerable:!0,get:function(){return s.Deque}});var a=i(464);Object.defineProperty(e,"Ws",{enumerable:!0,get:function(){return a.restrictor}}),e.rE="v1.3.16"})();const n=r.Jj,s=r.C,a=r.BJ,c=r.vt,o=r.Ws,l=r.rE;export{n as Deque,s as MiniSemaphore,a as __esModule,c as create,o as restrictor,l as version};
2
+ var e={139:(e,t,i)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.createWithAbort=t.create=void 0;const r=i(461),s=i(761),n=r.acquire,a=r.release,c=r.acquireWithAbort,o=r.releaseWithAbort,l=e=>({capacity:e,limit:e,q:new s.Deque(e),setRestriction(e){this.limit=this.capacity=e}});t.create=e=>({...l(e),get pending(){return this.q.length},acquire(e){return n(this,e)},release(){a(this)},async flow(e,t){await n(this,t);try{return await e()}finally{a(this)}}});t.createWithAbort=e=>({...l(e),get pending(){return this.q.length},acquire(){return c(this)},release(){o(this)},async flow(e){await c(this);try{return await e()}finally{o(this)}},abort(){const e=this.q;let t;const i={message:"Process Aborted"};for(;t=e.shift();)t.reject(i);this.capacity=this.limit}})},461:(e,t)=>{
3
+ Object.defineProperty(t,"__esModule",{value:!0}),t.releaseWithAbort=t.acquireWithAbort=t.release=t.acquire=void 0;const i=()=>{throw new Error("mini-semaphore: Detected an inconsistent state, possibly due to a logic error or unexpected behavior.")},r=(e,t)=>{e.capacity>0?(e.capacity--,t()):e.q.push(t)};t.acquire=(e,t=!0)=>new Promise((i=>{t?setTimeout((()=>r(e,i)),4):r(e,i)}));t.release=e=>{let t;(t=e.q).length?(t.shift()||i)():e.capacity++,e.capacity>e.limit&&(console.warn("inconsistent release!"),e.capacity=e.limit)};t.acquireWithAbort=e=>new Promise(((t,i)=>{e.capacity>0?(e.capacity--,t()):e.q.push({resolve:t,reject:i})}));t.releaseWithAbort=e=>{let t;if((t=e.q).length){const e=t.shift();e?e.resolve():i()}else e.capacity<e.limit&&e.capacity++}},464:(e,t,i)=>{
4
+ Object.defineProperty(t,"__esModule",{value:!0}),t.restrictor=void 0;const r=i(518);t.restrictor=(()=>{const{MiniSemaphore:e}=r,t=new e(1);let i=Object.create(null);async function s(r,s,n){const a=await(async(r,s)=>{await t.acquire(!1);let n=i[r];if(n||(i[r]=n=new e(s)),n.limit!==s)throw t.release(),new ReferenceError(`Cannot get object with different restriction: key: '${String(r)}', lock.limit: ${n.limit} <-> restriction: ${s},`);return t.release(),n})(r,s),c=a.flow(n);return a.last=Date.now(),c}return{getLockByKey:async e=>{await t.acquire(!1);const r=i[e];return t.release(),r},cleanup:async(e,r)=>{await t.acquire(!1);const s=i,n=Object.create(null),a=Object.keys(s);let c,o=0;!e&&(e=1),e*=1e3,r&&(c=[]);for(let t=0,i=a.length;t<i;){const i=a[t++],l=s[i];l.last&&Date.now()-l.last>=e?(o++,
5
+ r&&c.push(i)):n[i]=l}return i=n,t.release(),r&&console.log(`eliminated: [\n${c.join(",\n")}\n]\nlived: [\n${Object.keys(n).join(",\n")}\n]`),o},multi:s,one:async function(e,t){return s(e,1,t)}}})()},518:(e,t,i)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.MiniSemaphore=void 0;const r=i(461),s=i(761),n=r.acquire,a=r.release;t.MiniSemaphore=class{constructor(e){this.limit=this.capacity=e,this.q=new s.Deque(e)}acquire(e){return n(this,e)}release(){a(this)}setRestriction(e){this.limit=this.capacity=e}get pending(){return this.q.length}async flow(e,t){await n(this,t);try{return await e()}finally{a(this)}}}},761:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.Deque=void 0;const i=e=>(e=>(e>>>=0,e--,e|=e>>1,e|=e>>2,e|=e>>4,e|=e>>8,
6
+ 1+(e|=e>>16)))(Math.min(Math.max(16,0|e),1073741824));t.Deque=class{constructor(e){this._c=i(e||16),this._l=0,this._f=0,this._a=[],this.length=0}push(e){const t=this._l;this._c<t+1&&r(this,i(1.5*this._c+16));const s=this._f+t&this._c-1;this._a[s]=e,this.length=this._l=t+1}shift(){const e=this._l;if(0===e)return;const t=this._f,i=this._a[t];return this._a[t]=void 0,this._f=t+1&this._c-1,this.length=this._l=e-1,i}};const r=(e,t)=>{const i=e._c;e._c=t;const r=e._f+e._l;if(r>i){const t=r&i-1;((e,t,i,r,s)=>{for(let n=0;n<s;++n)i[n+r]=e[n+t],e[n+t]=void 0})(e._a,0,e._a,i,t)}}}},t={};function i(r){var s=t[r];if(void 0!==s)return s.exports;var n=t[r]={exports:{}};return e[r](n,n.exports,i),n.exports}var r={};(()=>{var e=r;Object.defineProperty(e,"BJ",{value:!0}),e.rE=e.Ws=e.Jj=e.Xz=e.vt=e.C=void 0
7
+ ;var t=i(518);Object.defineProperty(e,"C",{enumerable:!0,get:function(){return t.MiniSemaphore}});var s=i(139);Object.defineProperty(e,"vt",{enumerable:!0,get:function(){return s.create}}),Object.defineProperty(e,"Xz",{enumerable:!0,get:function(){return s.createWithAbort}});var n=i(761);Object.defineProperty(e,"Jj",{enumerable:!0,get:function(){return n.Deque}});var a=i(464);Object.defineProperty(e,"Ws",{enumerable:!0,get:function(){return a.restrictor}}),e.rE="v1.4.2"})();const s=r.Jj,n=r.C,a=r.BJ,c=r.vt,o=r.Xz,l=r.Ws,h=r.rE;export{s as Deque,n as MiniSemaphore,a as __esModule,c as create,o as createWithAbort,l as restrictor,h as version};