mini-semaphore 1.3.7 → 1.3.9
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/class.js +7 -0
- package/cjs/core.js +7 -0
- package/cjs/flow-restrictor.js +7 -0
- package/cjs/index.d.ts +0 -2
- package/cjs/index.js +7 -0
- package/cjs/object.js +7 -0
- package/esm/class.js +8 -1
- package/esm/core.js +8 -1
- package/esm/deque.js +1 -2
- package/esm/extras.js +1 -1
- package/esm/flow-restrictor.js +8 -1
- package/esm/index.d.ts +0 -2
- package/esm/index.js +8 -1
- package/esm/object.js +8 -1
- package/index.d.ts +0 -2
- package/package.json +4 -3
- package/umd/index.d.ts +0 -2
- package/umd/index.js +7 -158
- package/umd/index.js.LICENSE.txt +7 -0
- package/webpack/index.d.ts +0 -2
- package/webpack/index.js +6 -154
- package/webpack/index.js.LICENSE.txt +7 -0
- package/webpack-esm/index.d.ts +210 -0
- package/webpack-esm/index.mjs +6 -0
- package/webpack-esm/index.mjs.LICENSE.txt +7 -0
- package/umd/index.js.map +0 -1
- package/webpack/index.js.map +0 -1
package/cjs/class.js
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
/*!
|
|
3
|
+
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
4
|
+
Copyright (C) 2020 jeffy-g <hirotom1107@gmail.com>
|
|
5
|
+
Released under the MIT license
|
|
6
|
+
https://opensource.org/licenses/mit-license.php
|
|
7
|
+
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
8
|
+
*/
|
|
2
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
10
|
exports.MiniSemaphore = void 0;
|
|
4
11
|
const core = require("./core");
|
package/cjs/core.js
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
/*!
|
|
3
|
+
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
4
|
+
Copyright (C) 2020 jeffy-g <hirotom1107@gmail.com>
|
|
5
|
+
Released under the MIT license
|
|
6
|
+
https://opensource.org/licenses/mit-license.php
|
|
7
|
+
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
8
|
+
*/
|
|
2
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
10
|
exports.release = exports.acquire = void 0;
|
|
4
11
|
const extras_1 = require("./extras");
|
package/cjs/flow-restrictor.js
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
/*!
|
|
3
|
+
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
4
|
+
Copyright (C) 2020 jeffy-g <hirotom1107@gmail.com>
|
|
5
|
+
Released under the MIT license
|
|
6
|
+
https://opensource.org/licenses/mit-license.php
|
|
7
|
+
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
8
|
+
*/
|
|
2
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
10
|
exports.restrictor = void 0;
|
|
4
11
|
const c = require("./class");
|
package/cjs/index.d.ts
CHANGED
|
@@ -94,8 +94,6 @@ export declare type TFlowableLock<T = TVoidFunction> = IFlowableLock & {
|
|
|
94
94
|
readonly q: Deque<T>;
|
|
95
95
|
};
|
|
96
96
|
export declare type TVoidFunction = () => void;
|
|
97
|
-
// export declare const acquire: (dis: TFlowableLock<TVoidFunction>, lazy?: boolean) => Promise<void>;
|
|
98
|
-
// export declare const release: (dis: TFlowableLock<TVoidFunction>) => void;
|
|
99
97
|
|
|
100
98
|
|
|
101
99
|
/**
|
package/cjs/index.js
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
/*!
|
|
3
|
+
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
4
|
+
Copyright (C) 2020 jeffy-g <hirotom1107@gmail.com>
|
|
5
|
+
Released under the MIT license
|
|
6
|
+
https://opensource.org/licenses/mit-license.php
|
|
7
|
+
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
8
|
+
*/
|
|
2
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
10
|
exports.restrictor = exports.Deque = exports.create = exports.MiniSemaphore = void 0;
|
|
4
11
|
var class_1 = require("./class");
|
package/cjs/object.js
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
/*!
|
|
3
|
+
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
4
|
+
Copyright (C) 2020 jeffy-g <hirotom1107@gmail.com>
|
|
5
|
+
Released under the MIT license
|
|
6
|
+
https://opensource.org/licenses/mit-license.php
|
|
7
|
+
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
8
|
+
*/
|
|
2
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
10
|
exports.create = void 0;
|
|
4
11
|
const core = require("./core");
|
package/esm/class.js
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
3
|
+
Copyright (C) 2020 jeffy-g <hirotom1107@gmail.com>
|
|
4
|
+
Released under the MIT license
|
|
5
|
+
https://opensource.org/licenses/mit-license.php
|
|
6
|
+
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
7
|
+
*/
|
|
1
8
|
import * as core from "./core";
|
|
2
9
|
import { Deque } from "./deque";
|
|
3
10
|
const a = core.acquire;
|
|
@@ -28,4 +35,4 @@ export class MiniSemaphore {
|
|
|
28
35
|
r(this);
|
|
29
36
|
}
|
|
30
37
|
}
|
|
31
|
-
}
|
|
38
|
+
}
|
package/esm/core.js
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
3
|
+
Copyright (C) 2020 jeffy-g <hirotom1107@gmail.com>
|
|
4
|
+
Released under the MIT license
|
|
5
|
+
https://opensource.org/licenses/mit-license.php
|
|
6
|
+
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
7
|
+
*/
|
|
1
8
|
import { THROW } from "./extras";
|
|
2
9
|
const box = (z, r) => {
|
|
3
10
|
if (z.capacity > 0) {
|
|
@@ -26,4 +33,4 @@ export const release = (dis) => {
|
|
|
26
33
|
console.warn("inconsistent release!");
|
|
27
34
|
dis.capacity = dis.limit;
|
|
28
35
|
}
|
|
29
|
-
};
|
|
36
|
+
};
|
package/esm/deque.js
CHANGED
|
@@ -15,7 +15,6 @@ const p2l = (n) => {
|
|
|
15
15
|
return n + 1;
|
|
16
16
|
};
|
|
17
17
|
const gc = (n) => {
|
|
18
|
-
// @ts-ignore typescript cannot allow (undefined | 0) expression
|
|
19
18
|
return p2l(Math.min(Math.max(16, n | 0), 1073741824));
|
|
20
19
|
};
|
|
21
20
|
export class Deque {
|
|
@@ -59,4 +58,4 @@ const rt = (dis, n) => {
|
|
|
59
58
|
const mc = (f + l) & (oc - 1);
|
|
60
59
|
am(dis._a, 0, dis._a, oc, mc);
|
|
61
60
|
}
|
|
62
|
-
};
|
|
61
|
+
};
|
package/esm/extras.js
CHANGED
package/esm/flow-restrictor.js
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
3
|
+
Copyright (C) 2020 jeffy-g <hirotom1107@gmail.com>
|
|
4
|
+
Released under the MIT license
|
|
5
|
+
https://opensource.org/licenses/mit-license.php
|
|
6
|
+
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
7
|
+
*/
|
|
1
8
|
import * as c from "./class";
|
|
2
9
|
export var restrictor;
|
|
3
10
|
(function (restrictor) {
|
|
@@ -67,4 +74,4 @@ export var restrictor;
|
|
|
67
74
|
return multi(key, 1, pb);
|
|
68
75
|
}
|
|
69
76
|
restrictor.one = one;
|
|
70
|
-
})(restrictor || (restrictor = {}));
|
|
77
|
+
})(restrictor || (restrictor = {}));
|
package/esm/index.d.ts
CHANGED
|
@@ -94,8 +94,6 @@ export declare type TFlowableLock<T = TVoidFunction> = IFlowableLock & {
|
|
|
94
94
|
readonly q: Deque<T>;
|
|
95
95
|
};
|
|
96
96
|
export declare type TVoidFunction = () => void;
|
|
97
|
-
// export declare const acquire: (dis: TFlowableLock<TVoidFunction>, lazy?: boolean) => Promise<void>;
|
|
98
|
-
// export declare const release: (dis: TFlowableLock<TVoidFunction>) => void;
|
|
99
97
|
|
|
100
98
|
|
|
101
99
|
/**
|
package/esm/index.js
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
3
|
+
Copyright (C) 2020 jeffy-g <hirotom1107@gmail.com>
|
|
4
|
+
Released under the MIT license
|
|
5
|
+
https://opensource.org/licenses/mit-license.php
|
|
6
|
+
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
7
|
+
*/
|
|
1
8
|
export { MiniSemaphore } from "./class";
|
|
2
9
|
export { create } from "./object";
|
|
3
10
|
export { Deque } from "./deque";
|
|
4
|
-
export { restrictor } from "./flow-restrictor";
|
|
11
|
+
export { restrictor } from "./flow-restrictor";
|
package/esm/object.js
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
3
|
+
Copyright (C) 2020 jeffy-g <hirotom1107@gmail.com>
|
|
4
|
+
Released under the MIT license
|
|
5
|
+
https://opensource.org/licenses/mit-license.php
|
|
6
|
+
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
7
|
+
*/
|
|
1
8
|
import * as core from "./core";
|
|
2
9
|
import { Deque } from "./deque";
|
|
3
10
|
const a = core.acquire;
|
|
@@ -29,4 +36,4 @@ export const create = (capacity) => {
|
|
|
29
36
|
}
|
|
30
37
|
}
|
|
31
38
|
};
|
|
32
|
-
};
|
|
39
|
+
};
|
package/index.d.ts
CHANGED
|
@@ -94,8 +94,6 @@ export declare type TFlowableLock<T = TVoidFunction> = IFlowableLock & {
|
|
|
94
94
|
readonly q: Deque<T>;
|
|
95
95
|
};
|
|
96
96
|
export declare type TVoidFunction = () => void;
|
|
97
|
-
// export declare const acquire: (dis: TFlowableLock<TVoidFunction>, lazy?: boolean) => Promise<void>;
|
|
98
|
-
// export declare const release: (dis: TFlowableLock<TVoidFunction>) => void;
|
|
99
97
|
|
|
100
98
|
|
|
101
99
|
/**
|
package/package.json
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mini-semaphore",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.9",
|
|
4
4
|
"description": "A lightweight version of Semaphore",
|
|
5
5
|
"private": false,
|
|
6
6
|
"main": "./cjs/index.js",
|
|
7
|
-
"module": "./esm/index.
|
|
7
|
+
"module": "./webpack-esm/index.mjs",
|
|
8
8
|
"unpkg": "./umd/index.js",
|
|
9
9
|
"sideEffects": false,
|
|
10
10
|
"types": "./index.d.ts",
|
|
11
|
-
"typings": "./index.d.ts",
|
|
12
11
|
"author": "jeffy-g",
|
|
13
12
|
"license": "MIT",
|
|
14
13
|
"bugs": {
|
|
@@ -31,9 +30,11 @@
|
|
|
31
30
|
"esm",
|
|
32
31
|
"umd",
|
|
33
32
|
"webpack",
|
|
33
|
+
"webpack-esm",
|
|
34
34
|
"*.d.ts"
|
|
35
35
|
],
|
|
36
36
|
"keywords": [
|
|
37
|
+
"async",
|
|
37
38
|
"lock",
|
|
38
39
|
"mutex",
|
|
39
40
|
"promise",
|
package/umd/index.d.ts
CHANGED
|
@@ -94,8 +94,6 @@ export declare type TFlowableLock<T = TVoidFunction> = IFlowableLock & {
|
|
|
94
94
|
readonly q: Deque<T>;
|
|
95
95
|
};
|
|
96
96
|
export declare type TVoidFunction = () => void;
|
|
97
|
-
// export declare const acquire: (dis: TFlowableLock<TVoidFunction>, lazy?: boolean) => Promise<void>;
|
|
98
|
-
// export declare const release: (dis: TFlowableLock<TVoidFunction>) => void;
|
|
99
97
|
|
|
100
98
|
|
|
101
99
|
/**
|
package/umd/index.js
CHANGED
|
@@ -1,158 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
}(
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
for (var n in i) t.o(i, n) && !t.o(e, n) && Object.defineProperty(e, n, {
|
|
9
|
-
enumerable: !0,
|
|
10
|
-
get: i[n]
|
|
11
|
-
});
|
|
12
|
-
},
|
|
13
|
-
o: (t, e) => Object.prototype.hasOwnProperty.call(t, e),
|
|
14
|
-
r: t => {
|
|
15
|
-
'undefined' != typeof Symbol && Symbol.toStringTag && Object.defineProperty(t, Symbol.toStringTag, {
|
|
16
|
-
value: 'Module'
|
|
17
|
-
}), Object.defineProperty(t, '__esModule', {
|
|
18
|
-
value: !0
|
|
19
|
-
});
|
|
20
|
-
}
|
|
21
|
-
}, e = {};
|
|
22
|
-
t.r(e), t.d(e, {
|
|
23
|
-
Deque: () => o,
|
|
24
|
-
MiniSemaphore: () => f,
|
|
25
|
-
create: () => m,
|
|
26
|
-
restrictor: () => _
|
|
27
|
-
});
|
|
28
|
-
var i = {};
|
|
29
|
-
t.r(i), t.d(i, {
|
|
30
|
-
MiniSemaphore: () => f
|
|
31
|
-
});
|
|
32
|
-
const n = () => {
|
|
33
|
-
throw new Error("mini-semaphore: inconsistent occurred");
|
|
34
|
-
}, r = (t, e) => {
|
|
35
|
-
t.capacity > 0 ? (t.capacity--, e()) : t.q.push(e);
|
|
36
|
-
}, s = (t, e = !0) => new Promise((i => {
|
|
37
|
-
e ? setTimeout((() => r(t, i)), 4) : r(t, i);
|
|
38
|
-
})), a = t => {
|
|
39
|
-
t.capacity++, t.q.length && (t.capacity -= 1, (t.q.shift() || n)()), t.capacity > t.limit && (console.warn("inconsistent release!"),
|
|
40
|
-
t.capacity = t.limit);
|
|
41
|
-
}, c = t => (t => (t >>>= 0, t -= 1, t |= t >> 1, t |= t >> 2, t |= t >> 4, t |= t >> 8,
|
|
42
|
-
1 + (t |= t >> 16)))(Math.min(Math.max(16, 0 | t), 1073741824));
|
|
43
|
-
class o {
|
|
44
|
-
constructor(t) {
|
|
45
|
-
this._c = c(t), this._l = 0, this._f = 0, this._a = [];
|
|
46
|
-
}
|
|
47
|
-
push(t) {
|
|
48
|
-
const e = this._l;
|
|
49
|
-
this._c < e + 1 && l(this, c(1.5 * this._c + 16));
|
|
50
|
-
const i = this._f + e & this._c - 1;
|
|
51
|
-
this._a[i] = t, this._l = e + 1;
|
|
52
|
-
}
|
|
53
|
-
shift() {
|
|
54
|
-
const t = this._l;
|
|
55
|
-
if (0 === t) return;
|
|
56
|
-
const e = this._f, i = this._a[e];
|
|
57
|
-
return this._a[e] = void 0, this._f = e + 1 & this._c - 1, this._l = t - 1, i;
|
|
58
|
-
}
|
|
59
|
-
get length() {
|
|
60
|
-
return this._l;
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
const l = (t, e) => {
|
|
64
|
-
const i = t._c;
|
|
65
|
-
t._c = e;
|
|
66
|
-
const n = t._f, r = t._l;
|
|
67
|
-
if (n + r > i) {
|
|
68
|
-
const e = n + r & i - 1;
|
|
69
|
-
((t, e, i, n, r) => {
|
|
70
|
-
for (let s = 0; s < r; ++s) i[s + n] = t[s + e], t[s + e] = void 0;
|
|
71
|
-
})(t._a, 0, t._a, i, e);
|
|
72
|
-
}
|
|
73
|
-
}, h = s, u = a;
|
|
74
|
-
class f {
|
|
75
|
-
constructor(t) {
|
|
76
|
-
this.limit = this.capacity = t, this.q = new o(t);
|
|
77
|
-
}
|
|
78
|
-
acquire(t) {
|
|
79
|
-
return h(this, t);
|
|
80
|
-
}
|
|
81
|
-
release() {
|
|
82
|
-
u(this);
|
|
83
|
-
}
|
|
84
|
-
setRestriction(t) {
|
|
85
|
-
this.limit = this.capacity = t;
|
|
86
|
-
}
|
|
87
|
-
get pending() {
|
|
88
|
-
return this.q.length;
|
|
89
|
-
}
|
|
90
|
-
async flow(t, e) {
|
|
91
|
-
await h(this, e);
|
|
92
|
-
try {
|
|
93
|
-
return await t();
|
|
94
|
-
} finally {
|
|
95
|
-
u(this);
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
const y = s, p = a, m = t => ({
|
|
100
|
-
capacity: t,
|
|
101
|
-
limit: t,
|
|
102
|
-
q: new o(t),
|
|
103
|
-
acquire(t) {
|
|
104
|
-
return y(this, t);
|
|
105
|
-
},
|
|
106
|
-
release() {
|
|
107
|
-
p(this);
|
|
108
|
-
},
|
|
109
|
-
setRestriction(t) {
|
|
110
|
-
this.limit = this.capacity = t;
|
|
111
|
-
},
|
|
112
|
-
get pending() {
|
|
113
|
-
return this.q.length;
|
|
114
|
-
},
|
|
115
|
-
async flow(t, e) {
|
|
116
|
-
await y(this, e);
|
|
117
|
-
try {
|
|
118
|
-
return await t();
|
|
119
|
-
} finally {
|
|
120
|
-
p(this);
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
});
|
|
124
|
-
var _;
|
|
125
|
-
return function(t) {
|
|
126
|
-
const {MiniSemaphore: e} = i, n = new e(1);
|
|
127
|
-
let r = Object.create(null);
|
|
128
|
-
async function s(t, i, s) {
|
|
129
|
-
const a = await (async (t, i) => {
|
|
130
|
-
await n.acquire(!1);
|
|
131
|
-
let s = r[t];
|
|
132
|
-
if (s || (r[t] = s = new e(i)), s.limit !== i) throw n.release(), new ReferenceError(`Cannot get object with different restriction: key: '${t}', lock.limit: ${s.limit} <-> restriction: ${i},`);
|
|
133
|
-
return n.release(), s;
|
|
134
|
-
})(t, i), c = a.flow(s);
|
|
135
|
-
return a.last = Date.now(), c;
|
|
136
|
-
}
|
|
137
|
-
t.getLockByKey = async t => {
|
|
138
|
-
await n.acquire(!1);
|
|
139
|
-
const e = r[t];
|
|
140
|
-
return n.release(), e;
|
|
141
|
-
}, t.cleanup = async (t, e) => {
|
|
142
|
-
await n.acquire(!1);
|
|
143
|
-
const i = r, s = Object.create(null), a = Object.keys(i);
|
|
144
|
-
let c, o = 0;
|
|
145
|
-
!t && (t = 1), t *= 1e3, e && (c = []);
|
|
146
|
-
for (let n = 0, r = a.length; n < r; ) {
|
|
147
|
-
const r = a[n++], l = i[r];
|
|
148
|
-
l.last && Date.now() - l.last >= t ? (o++, e && c.push(r)) : s[r] = l;
|
|
149
|
-
}
|
|
150
|
-
return r = s, n.release(), e && console.log(`eliminated: [\n${c.join(",\n")}\n]\nlived: [\n${Object.keys(s).join(",\n")}\n]`),
|
|
151
|
-
o;
|
|
152
|
-
}, t.multi = s, t.one = async function(t, e) {
|
|
153
|
-
return s(t, 1, e);
|
|
154
|
-
};
|
|
155
|
-
}(_ || (_ = {})), e;
|
|
156
|
-
})();
|
|
157
|
-
}));
|
|
158
|
-
//# sourceMappingURL=index.js.map
|
|
1
|
+
/*! For license information please see index.js.LICENSE.txt */
|
|
2
|
+
!function(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={518:(e,t,i)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.MiniSemaphore=void 0;const r=i(461),n=i(761),s=r.acquire,c=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(){c(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{c(this)}}}},461:(e,t,i)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.release=t.acquire=void 0;const r=i(669),n=(e,t)=>{e.capacity>0?(e.capacity--,
|
|
3
|
+
t()):e.q.push(t)};t.acquire=(e,t=!0)=>new Promise((i=>{t?setTimeout((()=>n(e,i)),4):n(e,i)}));t.release=e=>{e.capacity++,e.q.length&&(e.capacity-=1,(e.q.shift()||r.THROW)()),e.capacity>e.limit&&(console.warn("inconsistent release!"),e.capacity=e.limit)}},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}}
|
|
4
|
+
;const r=(e,t)=>{const i=e._c;e._c=t;const r=e._f,n=e._l;if(r+n>i){const t=r+n&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)}}},669:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.THROW=void 0;t.THROW=()=>{throw new Error("mini-semaphore: inconsistent occurred")}},464:(e,t,i)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.restrictor=void 0;const r=i(518);(e=>{const{MiniSemaphore:t}=r,i=new t(1);let n=Object.create(null);async function s(e,r,s){const c=await(async(e,r)=>{await i.acquire(!1);let s=n[e];if(s||(n[e]=s=new t(r)),s.limit!==r)throw i.release(),new ReferenceError(`Cannot get object with different restriction: key: '${e}', lock.limit: ${s.limit} <-> restriction: ${r},`);return i.release(),s})(e,r),a=c.flow(s)
|
|
5
|
+
;return c.last=Date.now(),a}e.getLockByKey=async e=>{await i.acquire(!1);const t=n[e];return i.release(),t},e.cleanup=async(e,t)=>{await i.acquire(!1);const r=n,s=Object.create(null),c=Object.keys(r);let a,o=0;!e&&(e=1),e*=1e3,t&&(a=[]);for(let i=0,n=c.length;i<n;){const n=c[i++],l=r[n];l.last&&Date.now()-l.last>=e?(o++,t&&a.push(n)):s[n]=l}return n=s,i.release(),t&&console.log(`eliminated: [\n${a.join(",\n")}\n]\nlived: [\n${Object.keys(s).join(",\n")}\n]`),o},e.multi=s,e.one=async function(e,t){return s(e,1,t)}})(t.restrictor||(t.restrictor={}))},139:(e,t,i)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.create=void 0;const r=i(461),n=i(761),s=r.acquire,c=r.release;t.create=e=>({capacity:e,limit:e,q:new n.Deque(e),acquire(e){return s(this,e)},release(){c(this)},setRestriction(e){
|
|
6
|
+
this.limit=this.capacity=e},get pending(){return this.q.length},async flow(e,t){await s(this,t);try{return await e()}finally{c(this)}}})}},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.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 c=i(464);Object.defineProperty(e,"restrictor",{enumerable:!0,get:function(){return c.restrictor}})})(),r
|
|
7
|
+
})()));
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
3
|
+
Copyright (C) 2020 jeffy-g <hirotom1107@gmail.com>
|
|
4
|
+
Released under the MIT license
|
|
5
|
+
https://opensource.org/licenses/mit-license.php
|
|
6
|
+
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
7
|
+
*/
|
package/webpack/index.d.ts
CHANGED
|
@@ -94,8 +94,6 @@ export declare type TFlowableLock<T = TVoidFunction> = IFlowableLock & {
|
|
|
94
94
|
readonly q: Deque<T>;
|
|
95
95
|
};
|
|
96
96
|
export declare type TVoidFunction = () => void;
|
|
97
|
-
// export declare const acquire: (dis: TFlowableLock<TVoidFunction>, lazy?: boolean) => Promise<void>;
|
|
98
|
-
// export declare const release: (dis: TFlowableLock<TVoidFunction>) => void;
|
|
99
97
|
|
|
100
98
|
|
|
101
99
|
/**
|
package/webpack/index.js
CHANGED
|
@@ -1,154 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
get: i[n]
|
|
8
|
-
});
|
|
9
|
-
},
|
|
10
|
-
o: (t, e) => Object.prototype.hasOwnProperty.call(t, e),
|
|
11
|
-
r: t => {
|
|
12
|
-
'undefined' != typeof Symbol && Symbol.toStringTag && Object.defineProperty(t, Symbol.toStringTag, {
|
|
13
|
-
value: 'Module'
|
|
14
|
-
}), Object.defineProperty(t, '__esModule', {
|
|
15
|
-
value: !0
|
|
16
|
-
});
|
|
17
|
-
}
|
|
18
|
-
}, e = {};
|
|
19
|
-
t.r(e), t.d(e, {
|
|
20
|
-
Deque: () => o,
|
|
21
|
-
MiniSemaphore: () => y,
|
|
22
|
-
create: () => _,
|
|
23
|
-
restrictor: () => m
|
|
24
|
-
});
|
|
25
|
-
var i = {};
|
|
26
|
-
t.r(i), t.d(i, {
|
|
27
|
-
MiniSemaphore: () => y
|
|
28
|
-
});
|
|
29
|
-
const n = () => {
|
|
30
|
-
throw new Error("mini-semaphore: inconsistent occurred");
|
|
31
|
-
}, s = (t, e) => {
|
|
32
|
-
t.capacity > 0 ? (t.capacity--, e()) : t.q.push(e);
|
|
33
|
-
}, r = (t, e = !0) => new Promise((i => {
|
|
34
|
-
e ? setTimeout((() => s(t, i)), 4) : s(t, i);
|
|
35
|
-
})), a = t => {
|
|
36
|
-
t.capacity++, t.q.length && (t.capacity -= 1, (t.q.shift() || n)()), t.capacity > t.limit && (console.warn("inconsistent release!"),
|
|
37
|
-
t.capacity = t.limit);
|
|
38
|
-
}, c = t => (t => (t >>>= 0, t -= 1, t |= t >> 1, t |= t >> 2, t |= t >> 4, t |= t >> 8,
|
|
39
|
-
1 + (t |= t >> 16)))(Math.min(Math.max(16, 0 | t), 1073741824));
|
|
40
|
-
class o {
|
|
41
|
-
constructor(t) {
|
|
42
|
-
this._c = c(t), this._l = 0, this._f = 0, this._a = [];
|
|
43
|
-
}
|
|
44
|
-
push(t) {
|
|
45
|
-
const e = this._l;
|
|
46
|
-
this._c < e + 1 && l(this, c(1.5 * this._c + 16));
|
|
47
|
-
const i = this._f + e & this._c - 1;
|
|
48
|
-
this._a[i] = t, this._l = e + 1;
|
|
49
|
-
}
|
|
50
|
-
shift() {
|
|
51
|
-
const t = this._l;
|
|
52
|
-
if (0 === t) return;
|
|
53
|
-
const e = this._f, i = this._a[e];
|
|
54
|
-
return this._a[e] = void 0, this._f = e + 1 & this._c - 1, this._l = t - 1, i;
|
|
55
|
-
}
|
|
56
|
-
get length() {
|
|
57
|
-
return this._l;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
const l = (t, e) => {
|
|
61
|
-
const i = t._c;
|
|
62
|
-
t._c = e;
|
|
63
|
-
const n = t._f, s = t._l;
|
|
64
|
-
if (n + s > i) {
|
|
65
|
-
const e = n + s & i - 1;
|
|
66
|
-
((t, e, i, n, s) => {
|
|
67
|
-
for (let r = 0; r < s; ++r) i[r + n] = t[r + e], t[r + e] = void 0;
|
|
68
|
-
})(t._a, 0, t._a, i, e);
|
|
69
|
-
}
|
|
70
|
-
}, h = r, u = a;
|
|
71
|
-
class y {
|
|
72
|
-
constructor(t) {
|
|
73
|
-
this.limit = this.capacity = t, this.q = new o(t);
|
|
74
|
-
}
|
|
75
|
-
acquire(t) {
|
|
76
|
-
return h(this, t);
|
|
77
|
-
}
|
|
78
|
-
release() {
|
|
79
|
-
u(this);
|
|
80
|
-
}
|
|
81
|
-
setRestriction(t) {
|
|
82
|
-
this.limit = this.capacity = t;
|
|
83
|
-
}
|
|
84
|
-
get pending() {
|
|
85
|
-
return this.q.length;
|
|
86
|
-
}
|
|
87
|
-
async flow(t, e) {
|
|
88
|
-
await h(this, e);
|
|
89
|
-
try {
|
|
90
|
-
return await t();
|
|
91
|
-
} finally {
|
|
92
|
-
u(this);
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
const f = r, p = a, _ = t => ({
|
|
97
|
-
capacity: t,
|
|
98
|
-
limit: t,
|
|
99
|
-
q: new o(t),
|
|
100
|
-
acquire(t) {
|
|
101
|
-
return f(this, t);
|
|
102
|
-
},
|
|
103
|
-
release() {
|
|
104
|
-
p(this);
|
|
105
|
-
},
|
|
106
|
-
setRestriction(t) {
|
|
107
|
-
this.limit = this.capacity = t;
|
|
108
|
-
},
|
|
109
|
-
get pending() {
|
|
110
|
-
return this.q.length;
|
|
111
|
-
},
|
|
112
|
-
async flow(t, e) {
|
|
113
|
-
await f(this, e);
|
|
114
|
-
try {
|
|
115
|
-
return await t();
|
|
116
|
-
} finally {
|
|
117
|
-
p(this);
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
});
|
|
121
|
-
var m;
|
|
122
|
-
!function(t) {
|
|
123
|
-
const {MiniSemaphore: e} = i, n = new e(1);
|
|
124
|
-
let s = Object.create(null);
|
|
125
|
-
async function r(t, i, r) {
|
|
126
|
-
const a = await (async (t, i) => {
|
|
127
|
-
await n.acquire(!1);
|
|
128
|
-
let r = s[t];
|
|
129
|
-
if (r || (s[t] = r = new e(i)), r.limit !== i) throw n.release(), new ReferenceError(`Cannot get object with different restriction: key: '${t}', lock.limit: ${r.limit} <-> restriction: ${i},`);
|
|
130
|
-
return n.release(), r;
|
|
131
|
-
})(t, i), c = a.flow(r);
|
|
132
|
-
return a.last = Date.now(), c;
|
|
133
|
-
}
|
|
134
|
-
t.getLockByKey = async t => {
|
|
135
|
-
await n.acquire(!1);
|
|
136
|
-
const e = s[t];
|
|
137
|
-
return n.release(), e;
|
|
138
|
-
}, t.cleanup = async (t, e) => {
|
|
139
|
-
await n.acquire(!1);
|
|
140
|
-
const i = s, r = Object.create(null), a = Object.keys(i);
|
|
141
|
-
let c, o = 0;
|
|
142
|
-
!t && (t = 1), t *= 1e3, e && (c = []);
|
|
143
|
-
for (let n = 0, s = a.length; n < s; ) {
|
|
144
|
-
const s = a[n++], l = i[s];
|
|
145
|
-
l.last && Date.now() - l.last >= t ? (o++, e && c.push(s)) : r[s] = l;
|
|
146
|
-
}
|
|
147
|
-
return s = r, n.release(), e && console.log(`eliminated: [\n${c.join(",\n")}\n]\nlived: [\n${Object.keys(r).join(",\n")}\n]`),
|
|
148
|
-
o;
|
|
149
|
-
}, t.multi = r, t.one = async function(t, e) {
|
|
150
|
-
return r(t, 1, e);
|
|
151
|
-
};
|
|
152
|
-
}(m || (m = {})), module.exports = e;
|
|
153
|
-
})();
|
|
154
|
-
//# sourceMappingURL=index.js.map
|
|
1
|
+
/*! For license information please see index.js.LICENSE.txt */
|
|
2
|
+
(()=>{"use strict";var e={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)}}}},461:(e,t,i)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.release=t.acquire=void 0;const r=i(669),n=(e,t)=>{e.capacity>0?(e.capacity--,t()):e.q.push(t)};t.acquire=(e,t=!0)=>new Promise((i=>{t?setTimeout((()=>n(e,i)),4):n(e,i)}));t.release=e=>{e.capacity++,e.q.length&&(e.capacity-=1,(e.q.shift()||r.THROW)()),
|
|
3
|
+
e.capacity>e.limit&&(console.warn("inconsistent release!"),e.capacity=e.limit)}},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,n=e._l;if(r+n>i){const t=r+n&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)}}},669:(e,t)=>{
|
|
4
|
+
Object.defineProperty(t,"__esModule",{value:!0}),t.THROW=void 0;t.THROW=()=>{throw new Error("mini-semaphore: inconsistent occurred")}},464:(e,t,i)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.restrictor=void 0;const r=i(518);(e=>{const{MiniSemaphore:t}=r,i=new t(1);let n=Object.create(null);async function s(e,r,s){const a=await(async(e,r)=>{await i.acquire(!1);let s=n[e];if(s||(n[e]=s=new t(r)),s.limit!==r)throw i.release(),new ReferenceError(`Cannot get object with different restriction: key: '${e}', lock.limit: ${s.limit} <-> restriction: ${r},`);return i.release(),s})(e,r),c=a.flow(s);return a.last=Date.now(),c}e.getLockByKey=async e=>{await i.acquire(!1);const t=n[e];return i.release(),t},e.cleanup=async(e,t)=>{await i.acquire(!1)
|
|
5
|
+
;const r=n,s=Object.create(null),a=Object.keys(r);let c,o=0;!e&&(e=1),e*=1e3,t&&(c=[]);for(let i=0,n=a.length;i<n;){const n=a[i++],l=r[n];l.last&&Date.now()-l.last>=e?(o++,t&&c.push(n)):s[n]=l}return n=s,i.release(),t&&console.log(`eliminated: [\n${c.join(",\n")}\n]\nlived: [\n${Object.keys(s).join(",\n")}\n]`),o},e.multi=s,e.one=async function(e,t){return s(e,1,t)}})(t.restrictor||(t.restrictor={}))},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)}}})}},t={}
|
|
6
|
+
;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}),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}})})(),module.exports=r})();
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
3
|
+
Copyright (C) 2020 jeffy-g <hirotom1107@gmail.com>
|
|
4
|
+
Released under the MIT license
|
|
5
|
+
https://opensource.org/licenses/mit-license.php
|
|
6
|
+
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
7
|
+
*/
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ### Implementation restricted to FIFO
|
|
3
|
+
*
|
|
4
|
+
* this class is based on https://github.com/petkaantonov/deque/blob/master/js/deque.js
|
|
5
|
+
* Released under the MIT License: https://github.com/petkaantonov/deque/blob/master/LICENSE
|
|
6
|
+
*/
|
|
7
|
+
export declare class Deque<T extends any> {
|
|
8
|
+
/**
|
|
9
|
+
* capacity
|
|
10
|
+
* @type {number}
|
|
11
|
+
*/
|
|
12
|
+
_c: number;
|
|
13
|
+
/**
|
|
14
|
+
* current length (size
|
|
15
|
+
* @type {number}
|
|
16
|
+
*/
|
|
17
|
+
_l: number;
|
|
18
|
+
/**
|
|
19
|
+
* current front position
|
|
20
|
+
* @type {number}
|
|
21
|
+
*/
|
|
22
|
+
_f: number;
|
|
23
|
+
/**
|
|
24
|
+
* @type {T[]}
|
|
25
|
+
*/
|
|
26
|
+
_a: T[];
|
|
27
|
+
/**
|
|
28
|
+
* default capacity `16`
|
|
29
|
+
* @param ic initial capacity
|
|
30
|
+
*/
|
|
31
|
+
constructor(ic?: number);
|
|
32
|
+
/**
|
|
33
|
+
* @param s subject
|
|
34
|
+
*/
|
|
35
|
+
push(s: T): void;
|
|
36
|
+
// shift(): T | undefined;
|
|
37
|
+
clear(): void;
|
|
38
|
+
get length(): number;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* basic of simplified lock interface
|
|
43
|
+
*/
|
|
44
|
+
export interface ISimplifiedLock {
|
|
45
|
+
/**
|
|
46
|
+
* acquire the process rights
|
|
47
|
+
*
|
|
48
|
+
* @param lazy Whether the privilege acquisition process is deffer. default `true`
|
|
49
|
+
*/
|
|
50
|
+
acquire(lazy?: boolean): Promise<void>;
|
|
51
|
+
/**
|
|
52
|
+
* release the pending of one
|
|
53
|
+
*/
|
|
54
|
+
release(): void;
|
|
55
|
+
/**
|
|
56
|
+
* Change sharing restrictions to the value of `restriction`
|
|
57
|
+
* @param {number} restriction
|
|
58
|
+
*/
|
|
59
|
+
setRestriction(restriction: number): void;
|
|
60
|
+
/**
|
|
61
|
+
* Get the number of currently pending processes
|
|
62
|
+
* @type {number}
|
|
63
|
+
*/
|
|
64
|
+
readonly pending: number;
|
|
65
|
+
/**
|
|
66
|
+
* limitation
|
|
67
|
+
*/
|
|
68
|
+
limit: number;
|
|
69
|
+
/**
|
|
70
|
+
* capacity
|
|
71
|
+
*/
|
|
72
|
+
capacity: number;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* extention of `ISimplifiedLock` interface
|
|
76
|
+
*/
|
|
77
|
+
export interface IFlowableLock extends ISimplifiedLock {
|
|
78
|
+
/**
|
|
79
|
+
* combination of acquire/release
|
|
80
|
+
*
|
|
81
|
+
* + acquire/release is automatic
|
|
82
|
+
*
|
|
83
|
+
* @param lazy Whether the privilege acquisition process is deffer. default `true`
|
|
84
|
+
*/
|
|
85
|
+
flow<T>(f: () => Promise<T>, lazy?: boolean): Promise<T>;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* internal type for `createMiniSemaphore`
|
|
89
|
+
*/
|
|
90
|
+
export declare type TFlowableLock<T = TVoidFunction> = IFlowableLock & {
|
|
91
|
+
/**
|
|
92
|
+
* pending
|
|
93
|
+
*/
|
|
94
|
+
readonly q: Deque<T>;
|
|
95
|
+
};
|
|
96
|
+
export declare type TVoidFunction = () => void;
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* #### Mini Semaphore
|
|
101
|
+
*
|
|
102
|
+
* + minimal implementation of semaphore
|
|
103
|
+
*
|
|
104
|
+
* @example
|
|
105
|
+
* import { MiniSemaphore } from "mini-semaphore";
|
|
106
|
+
*
|
|
107
|
+
* const s = new MiniSemaphore(10);
|
|
108
|
+
* async function fetchTypeData(type_id) {
|
|
109
|
+
* await s.acquire();
|
|
110
|
+
* try {
|
|
111
|
+
* return fetch(`https://esi.evetech.net/latest/universe/types/${type_id}/`);
|
|
112
|
+
* } finally {
|
|
113
|
+
* s.release();
|
|
114
|
+
* }
|
|
115
|
+
* }
|
|
116
|
+
*
|
|
117
|
+
* //
|
|
118
|
+
* // or automatic acquire/release
|
|
119
|
+
* //
|
|
120
|
+
* async function fetchTypeData(type_id) {
|
|
121
|
+
* return s.flow(async () => fetch(`https://esi.evetech.net/latest/universe/types/${type_id}/`));
|
|
122
|
+
* }
|
|
123
|
+
*
|
|
124
|
+
* @date 2020/2/7
|
|
125
|
+
* @version 1.0
|
|
126
|
+
*/
|
|
127
|
+
export declare class MiniSemaphore implements TFlowableLock {
|
|
128
|
+
/**
|
|
129
|
+
* spare capacity
|
|
130
|
+
*/
|
|
131
|
+
capacity: number;
|
|
132
|
+
/**
|
|
133
|
+
* limitation
|
|
134
|
+
*/
|
|
135
|
+
limit: number;
|
|
136
|
+
/**
|
|
137
|
+
* queue of Promise's `resolve`
|
|
138
|
+
*/
|
|
139
|
+
q: Deque<TVoidFunction>;
|
|
140
|
+
/**
|
|
141
|
+
* constructs a semaphore instance limited at `capacity`
|
|
142
|
+
*
|
|
143
|
+
* @param capacity limitation of concurrent async by `capacity`
|
|
144
|
+
*/
|
|
145
|
+
constructor(capacity: number);
|
|
146
|
+
/**
|
|
147
|
+
* If there is enough capacity, execute the `resolve` immediately
|
|
148
|
+
*
|
|
149
|
+
* If not, put it in a queue and wait for the currently pending process to execute `release`
|
|
150
|
+
*/
|
|
151
|
+
acquire(lazy?: boolean): Promise<void>;
|
|
152
|
+
release(): void;
|
|
153
|
+
setRestriction(restriction: number): void;
|
|
154
|
+
get pending(): number;
|
|
155
|
+
/**
|
|
156
|
+
* automatic acquire/release
|
|
157
|
+
* @param process
|
|
158
|
+
*/
|
|
159
|
+
flow<T>(process: () => Promise<T>, lazy?: boolean): Promise<T>;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* object implementation of `IFlowableLock`
|
|
164
|
+
*
|
|
165
|
+
* + constructs a semaphore object limited at `capacity`
|
|
166
|
+
*
|
|
167
|
+
* @param capacity limitation of concurrent async by `capacity`
|
|
168
|
+
* @date 2020/2/7
|
|
169
|
+
* @version 1.0
|
|
170
|
+
*/
|
|
171
|
+
export declare const create: (capacity: number) => IFlowableLock;
|
|
172
|
+
|
|
173
|
+
declare namespace fr {
|
|
174
|
+
/**
|
|
175
|
+
* Eliminate unused instances for the `timeSpan` seconds
|
|
176
|
+
*
|
|
177
|
+
* @param timeSpan specify unit as seconds
|
|
178
|
+
* @returns {Promise<number>} eliminated count
|
|
179
|
+
* @date 2020/6/19
|
|
180
|
+
*/
|
|
181
|
+
const cleanup: (timeSpan: number, debug?: true | undefined) => Promise<number>;
|
|
182
|
+
/**
|
|
183
|
+
* get the semaphore associated with the value of `key`
|
|
184
|
+
*
|
|
185
|
+
* + ⚠️ The object to be retrieved with `key` must already be created with `multi` ore `one`
|
|
186
|
+
*
|
|
187
|
+
* @param key
|
|
188
|
+
* @returns `IFlowableLock` instance or `undefined`
|
|
189
|
+
*/
|
|
190
|
+
export const getLockByKey: (key: string | number) => Promise<IFlowableLock>;
|
|
191
|
+
/**
|
|
192
|
+
* Allocate a semaphore for each `key`, and limit the number of shares with the value of `restriction`
|
|
193
|
+
*
|
|
194
|
+
* @param key number or string as tag
|
|
195
|
+
* @param restriction number of process restriction
|
|
196
|
+
* @param pb the process body
|
|
197
|
+
*/
|
|
198
|
+
export function multi<T>(key: string | number, restriction: number, pb: () => Promise<T>): Promise<T>;
|
|
199
|
+
/**
|
|
200
|
+
* synonym of `multi(key, 1, pb)`
|
|
201
|
+
*
|
|
202
|
+
* + use case
|
|
203
|
+
* * Avoid concurrent requests to the same url
|
|
204
|
+
*
|
|
205
|
+
* @param key number or string as tag
|
|
206
|
+
* @param pb the process body
|
|
207
|
+
*/
|
|
208
|
+
export function one<T>(key: string | number, pb: () => Promise<T>): Promise<T>;
|
|
209
|
+
}
|
|
210
|
+
export declare const restrictor: typeof fr;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/*! For license information please see index.mjs.LICENSE.txt */
|
|
2
|
+
var e={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)}}}},461:(e,t,i)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.release=t.acquire=void 0;const r=i(669),n=(e,t)=>{e.capacity>0?(e.capacity--,t()):e.q.push(t)};t.acquire=(e,t=!0)=>new Promise((i=>{t?setTimeout((()=>n(e,i)),4):n(e,i)}));t.release=e=>{e.capacity++,e.q.length&&(e.capacity-=1,(e.q.shift()||r.THROW)()),
|
|
3
|
+
e.capacity>e.limit&&(console.warn("inconsistent release!"),e.capacity=e.limit)}},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,n=e._l;if(r+n>i){const t=r+n&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)}}},669:(e,t)=>{
|
|
4
|
+
Object.defineProperty(t,"__esModule",{value:!0}),t.THROW=void 0;t.THROW=()=>{throw new Error("mini-semaphore: inconsistent occurred")}},464:(e,t,i)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.restrictor=void 0;const r=i(518);(e=>{const{MiniSemaphore:t}=r,i=new t(1);let n=Object.create(null);async function s(e,r,s){const a=await(async(e,r)=>{await i.acquire(!1);let s=n[e];if(s||(n[e]=s=new t(r)),s.limit!==r)throw i.release(),new ReferenceError(`Cannot get object with different restriction: key: '${e}', lock.limit: ${s.limit} <-> restriction: ${r},`);return i.release(),s})(e,r),c=a.flow(s);return a.last=Date.now(),c}e.getLockByKey=async e=>{await i.acquire(!1);const t=n[e];return i.release(),t},e.cleanup=async(e,t)=>{await i.acquire(!1)
|
|
5
|
+
;const r=n,s=Object.create(null),a=Object.keys(r);let c,o=0;!e&&(e=1),e*=1e3,t&&(c=[]);for(let i=0,n=a.length;i<n;){const n=a[i++],l=r[n];l.last&&Date.now()-l.last>=e?(o++,t&&c.push(n)):s[n]=l}return n=s,i.release(),t&&console.log(`eliminated: [\n${c.join(",\n")}\n]\nlived: [\n${Object.keys(s).join(",\n")}\n]`),o},e.multi=s,e.one=async function(e,t){return s(e,1,t)}})(t.restrictor||(t.restrictor={}))},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)}}})}},t={}
|
|
6
|
+
;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,"X$",{value:!0}),e.gD=e.P7=e.Ue=e.G3=void 0;var t=i(518);Object.defineProperty(e,"G3",{enumerable:!0,get:function(){return t.MiniSemaphore}});var n=i(139);Object.defineProperty(e,"Ue",{enumerable:!0,get:function(){return n.create}});var s=i(761);Object.defineProperty(e,"P7",{enumerable:!0,get:function(){return s.Deque}});var a=i(464);Object.defineProperty(e,"gD",{enumerable:!0,get:function(){return a.restrictor}})})();var n=r.P7,s=r.G3,a=r.X$,c=r.Ue,o=r.gD;export{n as Deque,s as MiniSemaphore,a as __esModule,c as create,o as restrictor};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
3
|
+
Copyright (C) 2020 jeffy-g <hirotom1107@gmail.com>
|
|
4
|
+
Released under the MIT license
|
|
5
|
+
https://opensource.org/licenses/mit-license.php
|
|
6
|
+
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
7
|
+
*/
|
package/umd/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","mappings":"AAAA;AACA;AADA;AAUA;;ACTA;ACAA;AACA;AAEA;AAAA;;;ACJA;ACCA;AACA;AACA;AAEA;AAAA;;;;;;;;;;;;;;ACLA;AAEA;ACEA;AACA;AAOA;AAKA;AA4CA;AACA;AAOA;ACnCA;AANA;AAgBA;AAKA;AACA;;AAQA;AACA;AAIA;AAIA;AACA;;AAeA;AACA;AAEA;AAGA;AAKA;;AAeA;AACA;;;AAsBA;AAEA;AACA;AACA;AAEA;AAGA;AApIA;AAEA;AAoIA;;AClGA;AAkCA;AAMA;AACA;;AAQA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAMA;AAEA;AACA;AACA;AAEA;AACA;;;;AC/EA;AAiBA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AAEA;AACA;AACA;AAEA;AACA;;;;ACrCA;;AAEA;AAQA;AAyFA;AACA;AAjFA;AACA;AAIA;AAOA;AAqEA;AAGA;;AA9DA;AAEA;AACA;AAGA;AASA;AAEA;AACA;AAGA;AAEA;AAKA;AACA;AAEA;;AAkBA;AAAA;AAeA;AAWA;;AAnHA;AV/BA","sources":["webpack://MiniSema/webpack/universalModuleDefinition","webpack://MiniSema/webpack/bootstrap","webpack://MiniSema/webpack/runtime/define property getters","webpack://MiniSema/webpack/runtime/hasOwnProperty shorthand","webpack://MiniSema/webpack/runtime/make namespace object","webpack://MiniSema/./src/extras.ts","webpack://MiniSema/./src/core.ts","webpack://MiniSema/./src/deque.ts","webpack://MiniSema/./src/class.ts","webpack://MiniSema/./src/object.ts","webpack://MiniSema/./src/flow-restrictor.ts"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"MiniSema\"] = factory();\n\telse\n\t\troot[\"MiniSema\"] = factory();\n})(self, function() {\nreturn ","// The require scope\nvar __webpack_require__ = {};\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","export const THROW = () => {\r\n /* istanbul ignore next */\r\n throw new Error(\"mini-semaphore: inconsistent occurred\");\r\n};\r\n","import { THROW } from \"./extras\";\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n// class or namespace exports.\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\nconst box = (z, r) => {\r\n if (z.capacity > 0) {\r\n z.capacity--, r();\r\n }\r\n else {\r\n z.q.push(r);\r\n }\r\n};\r\nexport const acquire = (dis, lazy = true) => {\r\n // return !lazy? aqtight(dis): aqlazy(dis);\r\n return new Promise(r => {\r\n // DEVNOTE: Deque object resize event is less likely to occur if overdue by timeout\r\n // - however, this is not the case if the process takes hundreds of ms\r\n if (!lazy) {\r\n box(dis, r);\r\n }\r\n else {\r\n setTimeout(() => box(dis, r), 4);\r\n }\r\n });\r\n};\r\n// export const acquire = (dis: TFlowableLock, lazy = true) => {\r\n// // return !lazy? aqtight(dis): aqlazy(dis);\r\n// return new Promise<void>(resolve => {\r\n// // DEVNOTE: In the following code, you may not be able to get the effect of\r\n// // switching with the `lazy` flag (when tight processing is required\r\n// const box = () => {\r\n// if (dis.capacity > 0) {\r\n// dis.capacity--, resolve();\r\n// }\r\n// else {\r\n// dis.q.push(resolve);\r\n// }\r\n// };\r\n// // DEVNOTE: Deque object resize event is less likely to occur if overdue by timeout\r\n// // - however, this is not the case if the process takes hundreds of ms\r\n// if (!lazy) {\r\n// box();\r\n// } else {\r\n// setTimeout(box, 4);\r\n// }\r\n// // // setTimeout(() => {\r\n// // // if (dis.capacity > 0) {\r\n// // // dis.capacity--, resolve();\r\n// // // }\r\n// // // else {\r\n// // // dis.q.push(resolve);\r\n// // // }\r\n// // // }, 4);\r\n// // if (dis.capacity > 0) {\r\n// // dis.capacity--, resolve();\r\n// // }\r\n// // else {\r\n// // dis.q.push(resolve);\r\n// // }\r\n// });\r\n// };\r\nexport const release = (dis) => {\r\n dis.capacity++;\r\n if (dis.q.length) {\r\n // DEVNOTE: Will never reach `THROW`\r\n dis.capacity -= 1, (dis.q.shift() || THROW)();\r\n }\r\n if (dis.capacity > dis.limit) {\r\n console.warn(\"inconsistent release!\");\r\n dis.capacity = dis.limit;\r\n }\r\n};\r\n// export const flow = async <T>(dis: TFlowableLock, process: () => Promise<T>, lazy?: boolean) => {\r\n// await acquire(dis, lazy);\r\n// try {\r\n// return await process();\r\n// } finally {\r\n// release(dis);\r\n// }\r\n// };\r\n","/**\r\n * arrayMove\r\n *\r\n * @param src\r\n * @param si\r\n * @param dst\r\n * @param di\r\n * @param len\r\n */\r\nconst am = (src, si, dst, di, len) => {\r\n /* istanbul ignore next */\r\n for (let j = 0; j < len; ++j) {\r\n dst[j + di] = src[j + si];\r\n src[j + si] = void 0;\r\n }\r\n};\r\n/**\r\n * pow2AtLeast\r\n * @param n\r\n */\r\nconst p2l = (n) => {\r\n n = n >>> 0;\r\n n = n - 1;\r\n n = n | (n >> 1);\r\n n = n | (n >> 2);\r\n n = n | (n >> 4);\r\n n = n | (n >> 8);\r\n n = n | (n >> 16);\r\n return n + 1;\r\n};\r\n/**\r\n * getCapacity\r\n * @param n\r\n */\r\nconst gc = (n) => {\r\n // @ts-ignore typescript cannot allow (undefined | 0) expression\r\n return p2l(Math.min(Math.max(16, n | 0), 1073741824));\r\n};\r\n/**\r\n * ### Implementation restricted to FIFO\r\n *\r\n * this class is based on https://github.com/petkaantonov/deque/blob/master/js/deque.js\r\n * Released under the MIT License: https://github.com/petkaantonov/deque/blob/master/LICENSE\r\n */\r\nexport class Deque {\r\n /**\r\n * default capacity `16`\r\n * @param ic initial capacity\r\n */\r\n constructor(ic) {\r\n this._c = gc(ic);\r\n this._l = 0;\r\n this._f = 0;\r\n this._a = [];\r\n }\r\n /**\r\n * @param s subject\r\n */\r\n push(s) {\r\n const l = this._l;\r\n /* https://coderwall.com/p/zbc2zw/the-comment-toggle-trick\r\n cc(this, l + 1);\r\n /*/\r\n if (this._c < l + 1) {\r\n rt(this, gc(this._c * 1.5 + 16));\r\n }\r\n //*/\r\n const i = (this._f + l) & (this._c - 1);\r\n this._a[i] = s;\r\n this._l = l + 1;\r\n // return l + 1;\r\n }\r\n // pop() {\r\n // const length = this._length;\r\n // if (length === 0) {\r\n // return void 0;\r\n // }\r\n // const i = (this._front + length - 1) & (this._capacity - 1);\r\n // const ret = this.arr[i];\r\n // this.arr[i] = void 0;\r\n // this._length = length - 1;\r\n // return ret;\r\n // }\r\n shift() {\r\n const l = this._l;\r\n /* istanbul ignore if */\r\n if (l === 0) {\r\n return void 0;\r\n }\r\n const f = this._f;\r\n const r = this._a[f];\r\n this._a[f] = void 0;\r\n this._f = (f + 1) & (this._c - 1);\r\n this._l = l - 1;\r\n return r;\r\n }\r\n // // this._a.forEach(n => n && console.log(n));\r\n // /* istanbul ignore next */\r\n // clear() {\r\n // const l = this._l;\r\n // const f = this._f;\r\n // const c = this._c;\r\n // const a = this._a;\r\n // for (let j = 0; j < l; ++j) {\r\n // a[(f + j) & (c - 1)] = void 0 as unknown as T;\r\n // }\r\n // this._l = 0;\r\n // this._f = 0;\r\n // }\r\n get length() {\r\n return this._l;\r\n }\r\n}\r\n// export namespace Deque {\r\n// export const MAX_CAPACITY = (1 << 30) | 0;\r\n// export const MIN_CAPACITY = 16;\r\n// }\r\n// /**\r\n// * check capacity\r\n// * \r\n// * @param size \r\n// */\r\n// const cc = <T>(dis: Deque<T>, size: number) => {\r\n// if (dis._c < size) {\r\n// rt(dis, gc(dis._c * 1.5 + 16));\r\n// }\r\n// };\r\n/**\r\n * resize to\r\n *\r\n * @param n expected capacity\r\n */\r\nconst rt = (dis, n) => {\r\n // old capacity\r\n const oc = dis._c;\r\n dis._c = n;\r\n const f = dis._f;\r\n const l = dis._l;\r\n if (f + l > oc) {\r\n // move items count\r\n /* istanbul ignore next */\r\n const mc = (f + l) & (oc - 1);\r\n /* istanbul ignore next */\r\n am(dis._a, 0, dis._a, oc, mc);\r\n }\r\n};\r\n","/*\r\n! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n The MIT License (MIT)\r\n\r\n Copyright (C) 2020 jeffy-g hirotom1107@gmail.com\r\n\r\n Permission is hereby granted, free of charge, to any person obtaining a copy\r\n of this software and associated documentation files (the \"Software\"), to deal\r\n in the Software without restriction, including without limitation the rights\r\n to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\n copies of the Software, and to permit persons to whom the Software is\r\n furnished to do so, subject to the following conditions:\r\n\r\n The above copyright notice and this permission notice shall be included in\r\n all copies or substantial portions of the Software.\r\n\r\n THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\n THE SOFTWARE.\r\n - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n*/\r\n/**\r\n * @file minimal implementation of semaphore (class implementation\r\n * @author jeffy-g <hirotom1107@gmail.com>\r\n * @version 1.0\r\n */\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n// imports.\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\nimport * as core from \"./core\";\r\nimport { Deque } from \"./deque\";\r\n// DEVNOTE: export * as ns Syntax - since ts v3.8\r\n// import type {\r\n// TVoidFunction, TFlowableLock\r\n// } from \"./core\";\r\n// export type {\r\n// TVoidFunction, IFlowableLock, ISimplifiedLock,\r\n// } from \"./core\";\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n// constants, types\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\nconst a = core.acquire;\r\nconst r = core.release;\r\n// const f = core.flow;\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n// class or namespace exports.\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n/**\r\n * #### Mini Semaphore\r\n *\r\n * + minimal implementation of semaphore\r\n *\r\n * @example\r\n * import { MiniSemaphore } from \"mini-semaphore\";\r\n *\r\n * const s = new MiniSemaphore(10);\r\n * async function fetchTypeData(type_id) {\r\n * await s.acquire();\r\n * try {\r\n * return fetch(`https://esi.evetech.net/latest/universe/types/${type_id}/`);\r\n * } finally {\r\n * s.release();\r\n * }\r\n * }\r\n *\r\n * //\r\n * // or automatic acquire/release\r\n * //\r\n * async function fetchTypeData(type_id) {\r\n * return s.flow(async () => fetch(`https://esi.evetech.net/latest/universe/types/${type_id}/`));\r\n * }\r\n *\r\n * @date 2020/2/7\r\n * @version 1.0\r\n */\r\nexport class MiniSemaphore {\r\n /**\r\n * constructs a semaphore instance limited at `capacity`\r\n *\r\n * @param capacity limitation of concurrent async by `capacity`\r\n */\r\n constructor(capacity) {\r\n this.limit = this.capacity = capacity;\r\n this.q = new Deque(capacity);\r\n }\r\n /**\r\n * If there is enough capacity, execute the `resolve` immediately\r\n *\r\n * If not, put it in a queue and wait for the currently pending process to execute `release`\r\n */\r\n acquire(lazy) {\r\n return a(this, lazy);\r\n }\r\n release() {\r\n r(this);\r\n }\r\n setRestriction(restriction) {\r\n this.limit = this.capacity = restriction;\r\n }\r\n get pending() {\r\n return this.q.length;\r\n }\r\n /**\r\n * automatic acquire/release\r\n * @param process\r\n */\r\n async flow(process, lazy) {\r\n // return f(this, process, lazy);\r\n await a(this, lazy);\r\n try {\r\n return await process();\r\n }\r\n finally {\r\n r(this);\r\n }\r\n // return this.acquire().then(async () => {\r\n // return await process().then(result => result).finally(() => this.release());\r\n // });\r\n }\r\n}\r\n","/*\r\n! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n The MIT License (MIT)\r\n\r\n Copyright (C) 2020 jeffy-g hirotom1107@gmail.com\r\n\r\n Permission is hereby granted, free of charge, to any person obtaining a copy\r\n of this software and associated documentation files (the \"Software\"), to deal\r\n in the Software without restriction, including without limitation the rights\r\n to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\n copies of the Software, and to permit persons to whom the Software is\r\n furnished to do so, subject to the following conditions:\r\n\r\n The above copyright notice and this permission notice shall be included in\r\n all copies or substantial portions of the Software.\r\n\r\n THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\n THE SOFTWARE.\r\n - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n*/\r\n/**\r\n * @file minimal implementation of semaphore (object implementation\r\n * @author jeffy-g <hirotom1107@gmail.com>\r\n * @version 1.0\r\n */\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n// imports.\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\nimport * as core from \"./core\";\r\nimport { Deque } from \"./deque\";\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n// constants, types\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\nconst a = core.acquire;\r\nconst r = core.release;\r\n// const f = core.flow;\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n// class or namespace exports.\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n/**\r\n * object implementation of `IFlowableLock`\r\n *\r\n * + constructs a semaphore object limited at `capacity`\r\n *\r\n * @param capacity limitation of concurrent async by `capacity`\r\n * @date 2020/2/7\r\n * @version 1.0\r\n */\r\nexport const create = (capacity) => {\r\n return {\r\n capacity,\r\n limit: capacity,\r\n q: new Deque(capacity),\r\n acquire(lazy) {\r\n return a(this, lazy);\r\n },\r\n release() {\r\n r(this);\r\n },\r\n setRestriction(restriction) {\r\n this.limit = this.capacity = restriction;\r\n },\r\n get pending() {\r\n return this.q.length;\r\n },\r\n async flow(process, lazy) {\r\n // return f(this, process, lazy);\r\n await a(this, lazy);\r\n try {\r\n return await process();\r\n }\r\n finally {\r\n r(this);\r\n }\r\n // await this.acquire();\r\n // try {\r\n // // DEVNOTE: Since we use the `await` keyword here,\r\n // // - we simply return a Promise object in the process function on the user side\r\n // return await process();\r\n // } finally {\r\n // this.release();\r\n // }\r\n }\r\n };\r\n};\r\n","/*\r\n! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n The MIT License (MIT)\r\n\r\n Copyright (C) 2020 jeffy-g hirotom1107@gmail.com\r\n\r\n Permission is hereby granted, free of charge, to any person obtaining a copy\r\n of this software and associated documentation files (the \"Software\"), to deal\r\n in the Software without restriction, including without limitation the rights\r\n to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\n copies of the Software, and to permit persons to whom the Software is\r\n furnished to do so, subject to the following conditions:\r\n\r\n The above copyright notice and this permission notice shall be included in\r\n all copies or substantial portions of the Software.\r\n\r\n THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\n THE SOFTWARE.\r\n - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n*/\r\n/**\r\n * @file Utility module using `MiniSemaphore`\r\n * @author jeffy-g <hirotom1107@gmail.com>\r\n * @version 1.0\r\n */\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n// imports.\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\nimport * as c from \"./class\";\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n// class or namespace exports.\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n/**\r\n * Flow Restriction\r\n */\r\nexport var restrictor;\r\n(function (restrictor) {\r\n const { MiniSemaphore: MS } = c;\r\n /**\r\n * @internal\r\n */\r\n const internalLock = new MS(1);\r\n /**\r\n *\r\n */\r\n let locks = Object.create(null);\r\n /**\r\n *\r\n * @param key\r\n * @param restriction\r\n * @throws when different restriction\r\n */\r\n const get = async (key, restriction) => {\r\n // acquire internal lock\r\n await internalLock.acquire(false);\r\n let lock = locks[key];\r\n if (!lock) {\r\n locks[key] = lock = new MS(restriction);\r\n }\r\n if (lock.limit !== restriction) {\r\n // release internal lock\r\n internalLock.release();\r\n throw new ReferenceError(`Cannot get object with different restriction: key: '${key}', lock.limit: ${lock.limit} <-> restriction: ${restriction},`);\r\n }\r\n // release internal lock\r\n internalLock.release();\r\n return lock;\r\n };\r\n /**\r\n * get the semaphore associated with the value of `key`\r\n *\r\n * + ⚠️ The object to be retrieved with `key` must already be created with `multi` ore `one`\r\n *\r\n * @param key\r\n * @returns `IFlowableLock` instance or `undefined`\r\n */\r\n restrictor.getLockByKey = async (key) => {\r\n // acquire internal lock\r\n await internalLock.acquire(false);\r\n const l = locks[key];\r\n // release internal lock\r\n internalLock.release();\r\n return l;\r\n };\r\n /**\r\n * Eliminate unused instances for the `timeSpan` seconds\r\n *\r\n * @param timeSpan specify unit as seconds\r\n * @returns {Promise<number>} eliminated count\r\n * @date 2020/6/19\r\n */\r\n restrictor.cleanup = async (timeSpan, debug) => {\r\n // acquire internal lock\r\n await internalLock.acquire(false);\r\n const currentLocks = locks;\r\n const newLocks = Object.create(null);\r\n const keys = Object.keys(currentLocks);\r\n let eliminatedCount = 0;\r\n let eliminatedKeys;\r\n !timeSpan && (timeSpan = 1); // avoid implicit bug\r\n timeSpan *= 1000;\r\n if (debug) {\r\n eliminatedKeys = [];\r\n }\r\n for (let i = 0, end = keys.length; i < end;) {\r\n const key = keys[i++];\r\n const s = currentLocks[key];\r\n if (s.last && Date.now() - s.last >= timeSpan) {\r\n eliminatedCount++;\r\n if (debug) {\r\n eliminatedKeys.push(key);\r\n }\r\n continue;\r\n }\r\n newLocks[key] = s;\r\n }\r\n // update lock registry\r\n locks = newLocks;\r\n // release internal lock\r\n internalLock.release();\r\n if (debug) {\r\n console.log(`eliminated: [\\n${eliminatedKeys.join(\",\\n\")}\\n]` +\r\n \"\\n\" +\r\n `lived: [\\n${Object.keys(newLocks).join(\",\\n\")}\\n]`);\r\n }\r\n return eliminatedCount;\r\n };\r\n /**\r\n * Allocate a semaphore for each `key`, and limit the number of shares with the value of `restriction`\r\n *\r\n * @param key number or string as tag\r\n * @param restriction number of process restriction\r\n * @param pb the process body\r\n */\r\n async function multi(key, restriction, pb) {\r\n const s = await get(key, restriction);\r\n const result = s.flow(pb);\r\n s.last = Date.now();\r\n return result;\r\n }\r\n restrictor.multi = multi;\r\n /**\r\n * synonym of `multi(key, 1, pb)`\r\n *\r\n * + use case\r\n * * Avoid concurrent requests to the same url\r\n *\r\n * @param key number or string as tag\r\n * @param pb the process body\r\n */\r\n async function one(key, pb) {\r\n return multi(key, 1, pb);\r\n }\r\n restrictor.one = one;\r\n})(restrictor || (restrictor = {}));\r\n// export class FlowRestrictor {\r\n// /**\r\n// * \r\n// */\r\n// private locks: Record<string | number, IFlowableLock> = {};\r\n// // constructor() {}\r\n// /**\r\n// * \r\n// * @param key \r\n// * @param restriction \r\n// */\r\n// private get(key: string | number, restriction: number) {\r\n// let lock = this.locks[key];\r\n// if (!lock) {\r\n// this.locks[key] = lock = new MS(restriction);\r\n// }\r\n// return lock;\r\n// }\r\n// /**\r\n// * Allocate a semaphore for each `key`, and limit the number of shares with the value of` restriction`\r\n// * \r\n// * @param key number or string as tag\r\n// * @param restriction number of process restriction\r\n// * @param pb the process body\r\n// */\r\n// async multi<T>(key: string | number, restriction: number, pb: () => Promise<T>) {\r\n// return this.get(key, restriction).flow(pb);\r\n// }\r\n// /**\r\n// * synonym of `multi(key, 1, pb)`\r\n// * \r\n// * + use case\r\n// * * Avoid concurrent requests to the same url\r\n// * \r\n// * @param key number or string as tag\r\n// * @param pb the process body\r\n// */\r\n// async one<T>(key: string | number, pb: () => Promise<T>) {\r\n// return this.multi(key, 1, pb);\r\n// }\r\n// }\r\n"],"names":[],"sourceRoot":""}
|
package/webpack/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","mappings":";;AACA;ACAA;AACA;AAEA;AAAA;;;ACJA;ACCA;AACA;AACA;AAEA;AAAA;;;;;;;;;;;;;;ACLA;AAEA;ACEA;AACA;AAOA;AAKA;AA4CA;AACA;AAOA;ACnCA;AANA;AAgBA;AAKA;AACA;;AAQA;AACA;AAIA;AAIA;AACA;;AAeA;AACA;AAEA;AAGA;AAKA;;AAeA;AACA;;;AAsBA;AAEA;AACA;AACA;AAEA;AAGA;AApIA;AAEA;AAoIA;;AClGA;AAkCA;AAMA;AACA;;AAQA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAMA;AAEA;AACA;AACA;AAEA;AACA;;;;AC/EA;AAiBA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AAEA;AACA;AACA;AAEA;AACA;;;;ACrCA;AACA;AACA;AAQA;AAyFA;AACA;AAjFA;AACA;AAIA;AAOA;AAqEA;AAGA;;AA9DA;AAEA;AACA;AAGA;AASA;AAEA;AACA;AAGA;AAEA;AAKA;AACA;AAEA;;AAkBA;AAAA;AAeA;AAWA;;AAnHA","sources":["webpack://mini-semaphore/webpack/bootstrap","webpack://mini-semaphore/webpack/runtime/define property getters","webpack://mini-semaphore/webpack/runtime/hasOwnProperty shorthand","webpack://mini-semaphore/webpack/runtime/make namespace object","webpack://mini-semaphore/./src/extras.ts","webpack://mini-semaphore/./src/core.ts","webpack://mini-semaphore/./src/deque.ts","webpack://mini-semaphore/./src/class.ts","webpack://mini-semaphore/./src/object.ts","webpack://mini-semaphore/./src/flow-restrictor.ts"],"sourcesContent":["// The require scope\nvar __webpack_require__ = {};\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","export const THROW = () => {\r\n /* istanbul ignore next */\r\n throw new Error(\"mini-semaphore: inconsistent occurred\");\r\n};\r\n","import { THROW } from \"./extras\";\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n// class or namespace exports.\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\nconst box = (z, r) => {\r\n if (z.capacity > 0) {\r\n z.capacity--, r();\r\n }\r\n else {\r\n z.q.push(r);\r\n }\r\n};\r\nexport const acquire = (dis, lazy = true) => {\r\n // return !lazy? aqtight(dis): aqlazy(dis);\r\n return new Promise(r => {\r\n // DEVNOTE: Deque object resize event is less likely to occur if overdue by timeout\r\n // - however, this is not the case if the process takes hundreds of ms\r\n if (!lazy) {\r\n box(dis, r);\r\n }\r\n else {\r\n setTimeout(() => box(dis, r), 4);\r\n }\r\n });\r\n};\r\n// export const acquire = (dis: TFlowableLock, lazy = true) => {\r\n// // return !lazy? aqtight(dis): aqlazy(dis);\r\n// return new Promise<void>(resolve => {\r\n// // DEVNOTE: In the following code, you may not be able to get the effect of\r\n// // switching with the `lazy` flag (when tight processing is required\r\n// const box = () => {\r\n// if (dis.capacity > 0) {\r\n// dis.capacity--, resolve();\r\n// }\r\n// else {\r\n// dis.q.push(resolve);\r\n// }\r\n// };\r\n// // DEVNOTE: Deque object resize event is less likely to occur if overdue by timeout\r\n// // - however, this is not the case if the process takes hundreds of ms\r\n// if (!lazy) {\r\n// box();\r\n// } else {\r\n// setTimeout(box, 4);\r\n// }\r\n// // // setTimeout(() => {\r\n// // // if (dis.capacity > 0) {\r\n// // // dis.capacity--, resolve();\r\n// // // }\r\n// // // else {\r\n// // // dis.q.push(resolve);\r\n// // // }\r\n// // // }, 4);\r\n// // if (dis.capacity > 0) {\r\n// // dis.capacity--, resolve();\r\n// // }\r\n// // else {\r\n// // dis.q.push(resolve);\r\n// // }\r\n// });\r\n// };\r\nexport const release = (dis) => {\r\n dis.capacity++;\r\n if (dis.q.length) {\r\n // DEVNOTE: Will never reach `THROW`\r\n dis.capacity -= 1, (dis.q.shift() || THROW)();\r\n }\r\n if (dis.capacity > dis.limit) {\r\n console.warn(\"inconsistent release!\");\r\n dis.capacity = dis.limit;\r\n }\r\n};\r\n// export const flow = async <T>(dis: TFlowableLock, process: () => Promise<T>, lazy?: boolean) => {\r\n// await acquire(dis, lazy);\r\n// try {\r\n// return await process();\r\n// } finally {\r\n// release(dis);\r\n// }\r\n// };\r\n","/**\r\n * arrayMove\r\n *\r\n * @param src\r\n * @param si\r\n * @param dst\r\n * @param di\r\n * @param len\r\n */\r\nconst am = (src, si, dst, di, len) => {\r\n /* istanbul ignore next */\r\n for (let j = 0; j < len; ++j) {\r\n dst[j + di] = src[j + si];\r\n src[j + si] = void 0;\r\n }\r\n};\r\n/**\r\n * pow2AtLeast\r\n * @param n\r\n */\r\nconst p2l = (n) => {\r\n n = n >>> 0;\r\n n = n - 1;\r\n n = n | (n >> 1);\r\n n = n | (n >> 2);\r\n n = n | (n >> 4);\r\n n = n | (n >> 8);\r\n n = n | (n >> 16);\r\n return n + 1;\r\n};\r\n/**\r\n * getCapacity\r\n * @param n\r\n */\r\nconst gc = (n) => {\r\n // @ts-ignore typescript cannot allow (undefined | 0) expression\r\n return p2l(Math.min(Math.max(16, n | 0), 1073741824));\r\n};\r\n/**\r\n * ### Implementation restricted to FIFO\r\n *\r\n * this class is based on https://github.com/petkaantonov/deque/blob/master/js/deque.js\r\n * Released under the MIT License: https://github.com/petkaantonov/deque/blob/master/LICENSE\r\n */\r\nexport class Deque {\r\n /**\r\n * default capacity `16`\r\n * @param ic initial capacity\r\n */\r\n constructor(ic) {\r\n this._c = gc(ic);\r\n this._l = 0;\r\n this._f = 0;\r\n this._a = [];\r\n }\r\n /**\r\n * @param s subject\r\n */\r\n push(s) {\r\n const l = this._l;\r\n /* https://coderwall.com/p/zbc2zw/the-comment-toggle-trick\r\n cc(this, l + 1);\r\n /*/\r\n if (this._c < l + 1) {\r\n rt(this, gc(this._c * 1.5 + 16));\r\n }\r\n //*/\r\n const i = (this._f + l) & (this._c - 1);\r\n this._a[i] = s;\r\n this._l = l + 1;\r\n // return l + 1;\r\n }\r\n // pop() {\r\n // const length = this._length;\r\n // if (length === 0) {\r\n // return void 0;\r\n // }\r\n // const i = (this._front + length - 1) & (this._capacity - 1);\r\n // const ret = this.arr[i];\r\n // this.arr[i] = void 0;\r\n // this._length = length - 1;\r\n // return ret;\r\n // }\r\n shift() {\r\n const l = this._l;\r\n /* istanbul ignore if */\r\n if (l === 0) {\r\n return void 0;\r\n }\r\n const f = this._f;\r\n const r = this._a[f];\r\n this._a[f] = void 0;\r\n this._f = (f + 1) & (this._c - 1);\r\n this._l = l - 1;\r\n return r;\r\n }\r\n // // this._a.forEach(n => n && console.log(n));\r\n // /* istanbul ignore next */\r\n // clear() {\r\n // const l = this._l;\r\n // const f = this._f;\r\n // const c = this._c;\r\n // const a = this._a;\r\n // for (let j = 0; j < l; ++j) {\r\n // a[(f + j) & (c - 1)] = void 0 as unknown as T;\r\n // }\r\n // this._l = 0;\r\n // this._f = 0;\r\n // }\r\n get length() {\r\n return this._l;\r\n }\r\n}\r\n// export namespace Deque {\r\n// export const MAX_CAPACITY = (1 << 30) | 0;\r\n// export const MIN_CAPACITY = 16;\r\n// }\r\n// /**\r\n// * check capacity\r\n// * \r\n// * @param size \r\n// */\r\n// const cc = <T>(dis: Deque<T>, size: number) => {\r\n// if (dis._c < size) {\r\n// rt(dis, gc(dis._c * 1.5 + 16));\r\n// }\r\n// };\r\n/**\r\n * resize to\r\n *\r\n * @param n expected capacity\r\n */\r\nconst rt = (dis, n) => {\r\n // old capacity\r\n const oc = dis._c;\r\n dis._c = n;\r\n const f = dis._f;\r\n const l = dis._l;\r\n if (f + l > oc) {\r\n // move items count\r\n /* istanbul ignore next */\r\n const mc = (f + l) & (oc - 1);\r\n /* istanbul ignore next */\r\n am(dis._a, 0, dis._a, oc, mc);\r\n }\r\n};\r\n","/*\r\n! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n The MIT License (MIT)\r\n\r\n Copyright (C) 2020 jeffy-g hirotom1107@gmail.com\r\n\r\n Permission is hereby granted, free of charge, to any person obtaining a copy\r\n of this software and associated documentation files (the \"Software\"), to deal\r\n in the Software without restriction, including without limitation the rights\r\n to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\n copies of the Software, and to permit persons to whom the Software is\r\n furnished to do so, subject to the following conditions:\r\n\r\n The above copyright notice and this permission notice shall be included in\r\n all copies or substantial portions of the Software.\r\n\r\n THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\n THE SOFTWARE.\r\n - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n*/\r\n/**\r\n * @file minimal implementation of semaphore (class implementation\r\n * @author jeffy-g <hirotom1107@gmail.com>\r\n * @version 1.0\r\n */\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n// imports.\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\nimport * as core from \"./core\";\r\nimport { Deque } from \"./deque\";\r\n// DEVNOTE: export * as ns Syntax - since ts v3.8\r\n// import type {\r\n// TVoidFunction, TFlowableLock\r\n// } from \"./core\";\r\n// export type {\r\n// TVoidFunction, IFlowableLock, ISimplifiedLock,\r\n// } from \"./core\";\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n// constants, types\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\nconst a = core.acquire;\r\nconst r = core.release;\r\n// const f = core.flow;\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n// class or namespace exports.\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n/**\r\n * #### Mini Semaphore\r\n *\r\n * + minimal implementation of semaphore\r\n *\r\n * @example\r\n * import { MiniSemaphore } from \"mini-semaphore\";\r\n *\r\n * const s = new MiniSemaphore(10);\r\n * async function fetchTypeData(type_id) {\r\n * await s.acquire();\r\n * try {\r\n * return fetch(`https://esi.evetech.net/latest/universe/types/${type_id}/`);\r\n * } finally {\r\n * s.release();\r\n * }\r\n * }\r\n *\r\n * //\r\n * // or automatic acquire/release\r\n * //\r\n * async function fetchTypeData(type_id) {\r\n * return s.flow(async () => fetch(`https://esi.evetech.net/latest/universe/types/${type_id}/`));\r\n * }\r\n *\r\n * @date 2020/2/7\r\n * @version 1.0\r\n */\r\nexport class MiniSemaphore {\r\n /**\r\n * constructs a semaphore instance limited at `capacity`\r\n *\r\n * @param capacity limitation of concurrent async by `capacity`\r\n */\r\n constructor(capacity) {\r\n this.limit = this.capacity = capacity;\r\n this.q = new Deque(capacity);\r\n }\r\n /**\r\n * If there is enough capacity, execute the `resolve` immediately\r\n *\r\n * If not, put it in a queue and wait for the currently pending process to execute `release`\r\n */\r\n acquire(lazy) {\r\n return a(this, lazy);\r\n }\r\n release() {\r\n r(this);\r\n }\r\n setRestriction(restriction) {\r\n this.limit = this.capacity = restriction;\r\n }\r\n get pending() {\r\n return this.q.length;\r\n }\r\n /**\r\n * automatic acquire/release\r\n * @param process\r\n */\r\n async flow(process, lazy) {\r\n // return f(this, process, lazy);\r\n await a(this, lazy);\r\n try {\r\n return await process();\r\n }\r\n finally {\r\n r(this);\r\n }\r\n // return this.acquire().then(async () => {\r\n // return await process().then(result => result).finally(() => this.release());\r\n // });\r\n }\r\n}\r\n","/*\r\n! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n The MIT License (MIT)\r\n\r\n Copyright (C) 2020 jeffy-g hirotom1107@gmail.com\r\n\r\n Permission is hereby granted, free of charge, to any person obtaining a copy\r\n of this software and associated documentation files (the \"Software\"), to deal\r\n in the Software without restriction, including without limitation the rights\r\n to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\n copies of the Software, and to permit persons to whom the Software is\r\n furnished to do so, subject to the following conditions:\r\n\r\n The above copyright notice and this permission notice shall be included in\r\n all copies or substantial portions of the Software.\r\n\r\n THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\n THE SOFTWARE.\r\n - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n*/\r\n/**\r\n * @file minimal implementation of semaphore (object implementation\r\n * @author jeffy-g <hirotom1107@gmail.com>\r\n * @version 1.0\r\n */\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n// imports.\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\nimport * as core from \"./core\";\r\nimport { Deque } from \"./deque\";\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n// constants, types\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\nconst a = core.acquire;\r\nconst r = core.release;\r\n// const f = core.flow;\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n// class or namespace exports.\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n/**\r\n * object implementation of `IFlowableLock`\r\n *\r\n * + constructs a semaphore object limited at `capacity`\r\n *\r\n * @param capacity limitation of concurrent async by `capacity`\r\n * @date 2020/2/7\r\n * @version 1.0\r\n */\r\nexport const create = (capacity) => {\r\n return {\r\n capacity,\r\n limit: capacity,\r\n q: new Deque(capacity),\r\n acquire(lazy) {\r\n return a(this, lazy);\r\n },\r\n release() {\r\n r(this);\r\n },\r\n setRestriction(restriction) {\r\n this.limit = this.capacity = restriction;\r\n },\r\n get pending() {\r\n return this.q.length;\r\n },\r\n async flow(process, lazy) {\r\n // return f(this, process, lazy);\r\n await a(this, lazy);\r\n try {\r\n return await process();\r\n }\r\n finally {\r\n r(this);\r\n }\r\n // await this.acquire();\r\n // try {\r\n // // DEVNOTE: Since we use the `await` keyword here,\r\n // // - we simply return a Promise object in the process function on the user side\r\n // return await process();\r\n // } finally {\r\n // this.release();\r\n // }\r\n }\r\n };\r\n};\r\n","/*\r\n! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n The MIT License (MIT)\r\n\r\n Copyright (C) 2020 jeffy-g hirotom1107@gmail.com\r\n\r\n Permission is hereby granted, free of charge, to any person obtaining a copy\r\n of this software and associated documentation files (the \"Software\"), to deal\r\n in the Software without restriction, including without limitation the rights\r\n to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\n copies of the Software, and to permit persons to whom the Software is\r\n furnished to do so, subject to the following conditions:\r\n\r\n The above copyright notice and this permission notice shall be included in\r\n all copies or substantial portions of the Software.\r\n\r\n THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\n THE SOFTWARE.\r\n - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n*/\r\n/**\r\n * @file Utility module using `MiniSemaphore`\r\n * @author jeffy-g <hirotom1107@gmail.com>\r\n * @version 1.0\r\n */\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n// imports.\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\nimport * as c from \"./class\";\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n// class or namespace exports.\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n/**\r\n * Flow Restriction\r\n */\r\nexport var restrictor;\r\n(function (restrictor) {\r\n const { MiniSemaphore: MS } = c;\r\n /**\r\n * @internal\r\n */\r\n const internalLock = new MS(1);\r\n /**\r\n *\r\n */\r\n let locks = Object.create(null);\r\n /**\r\n *\r\n * @param key\r\n * @param restriction\r\n * @throws when different restriction\r\n */\r\n const get = async (key, restriction) => {\r\n // acquire internal lock\r\n await internalLock.acquire(false);\r\n let lock = locks[key];\r\n if (!lock) {\r\n locks[key] = lock = new MS(restriction);\r\n }\r\n if (lock.limit !== restriction) {\r\n // release internal lock\r\n internalLock.release();\r\n throw new ReferenceError(`Cannot get object with different restriction: key: '${key}', lock.limit: ${lock.limit} <-> restriction: ${restriction},`);\r\n }\r\n // release internal lock\r\n internalLock.release();\r\n return lock;\r\n };\r\n /**\r\n * get the semaphore associated with the value of `key`\r\n *\r\n * + ⚠️ The object to be retrieved with `key` must already be created with `multi` ore `one`\r\n *\r\n * @param key\r\n * @returns `IFlowableLock` instance or `undefined`\r\n */\r\n restrictor.getLockByKey = async (key) => {\r\n // acquire internal lock\r\n await internalLock.acquire(false);\r\n const l = locks[key];\r\n // release internal lock\r\n internalLock.release();\r\n return l;\r\n };\r\n /**\r\n * Eliminate unused instances for the `timeSpan` seconds\r\n *\r\n * @param timeSpan specify unit as seconds\r\n * @returns {Promise<number>} eliminated count\r\n * @date 2020/6/19\r\n */\r\n restrictor.cleanup = async (timeSpan, debug) => {\r\n // acquire internal lock\r\n await internalLock.acquire(false);\r\n const currentLocks = locks;\r\n const newLocks = Object.create(null);\r\n const keys = Object.keys(currentLocks);\r\n let eliminatedCount = 0;\r\n let eliminatedKeys;\r\n !timeSpan && (timeSpan = 1); // avoid implicit bug\r\n timeSpan *= 1000;\r\n if (debug) {\r\n eliminatedKeys = [];\r\n }\r\n for (let i = 0, end = keys.length; i < end;) {\r\n const key = keys[i++];\r\n const s = currentLocks[key];\r\n if (s.last && Date.now() - s.last >= timeSpan) {\r\n eliminatedCount++;\r\n if (debug) {\r\n eliminatedKeys.push(key);\r\n }\r\n continue;\r\n }\r\n newLocks[key] = s;\r\n }\r\n // update lock registry\r\n locks = newLocks;\r\n // release internal lock\r\n internalLock.release();\r\n if (debug) {\r\n console.log(`eliminated: [\\n${eliminatedKeys.join(\",\\n\")}\\n]` +\r\n \"\\n\" +\r\n `lived: [\\n${Object.keys(newLocks).join(\",\\n\")}\\n]`);\r\n }\r\n return eliminatedCount;\r\n };\r\n /**\r\n * Allocate a semaphore for each `key`, and limit the number of shares with the value of `restriction`\r\n *\r\n * @param key number or string as tag\r\n * @param restriction number of process restriction\r\n * @param pb the process body\r\n */\r\n async function multi(key, restriction, pb) {\r\n const s = await get(key, restriction);\r\n const result = s.flow(pb);\r\n s.last = Date.now();\r\n return result;\r\n }\r\n restrictor.multi = multi;\r\n /**\r\n * synonym of `multi(key, 1, pb)`\r\n *\r\n * + use case\r\n * * Avoid concurrent requests to the same url\r\n *\r\n * @param key number or string as tag\r\n * @param pb the process body\r\n */\r\n async function one(key, pb) {\r\n return multi(key, 1, pb);\r\n }\r\n restrictor.one = one;\r\n})(restrictor || (restrictor = {}));\r\n// export class FlowRestrictor {\r\n// /**\r\n// * \r\n// */\r\n// private locks: Record<string | number, IFlowableLock> = {};\r\n// // constructor() {}\r\n// /**\r\n// * \r\n// * @param key \r\n// * @param restriction \r\n// */\r\n// private get(key: string | number, restriction: number) {\r\n// let lock = this.locks[key];\r\n// if (!lock) {\r\n// this.locks[key] = lock = new MS(restriction);\r\n// }\r\n// return lock;\r\n// }\r\n// /**\r\n// * Allocate a semaphore for each `key`, and limit the number of shares with the value of` restriction`\r\n// * \r\n// * @param key number or string as tag\r\n// * @param restriction number of process restriction\r\n// * @param pb the process body\r\n// */\r\n// async multi<T>(key: string | number, restriction: number, pb: () => Promise<T>) {\r\n// return this.get(key, restriction).flow(pb);\r\n// }\r\n// /**\r\n// * synonym of `multi(key, 1, pb)`\r\n// * \r\n// * + use case\r\n// * * Avoid concurrent requests to the same url\r\n// * \r\n// * @param key number or string as tag\r\n// * @param pb the process body\r\n// */\r\n// async one<T>(key: string | number, pb: () => Promise<T>) {\r\n// return this.multi(key, 1, pb);\r\n// }\r\n// }\r\n"],"names":[],"sourceRoot":""}
|