mini-semaphore 1.1.0 → 1.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- ![GitHub](https://img.shields.io/github/license/jeffy-g/mini-semaphore?style=plastic)
1
+ [![Build Status](https://travis-ci.com/jeffy-g/mini-semaphore.svg?branch=master)](https://travis-ci.com/jeffy-g/mini-semaphore) ![GitHub](https://img.shields.io/github/license/jeffy-g/mini-semaphore?style=plastic)
2
2
 
3
3
  # Mini Semaphore (mini-semaphore
4
4
 
package/cjs/class.js CHANGED
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MiniSemaphore = void 0;
3
4
  const core = require("./core");
4
5
  const deque_1 = require("./deque");
5
6
  const a = core.acquire;
package/cjs/core.js CHANGED
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.release = exports.acquire = void 0;
3
4
  const extras_1 = require("./extras");
4
5
  const box = (z, r) => {
5
6
  if (z.capacity > 0) {
@@ -9,7 +10,7 @@ const box = (z, r) => {
9
10
  z.q.push(r);
10
11
  }
11
12
  };
12
- exports.acquire = (dis, lazy = true) => {
13
+ const acquire = (dis, lazy = true) => {
13
14
  return new Promise(r => {
14
15
  if (!lazy) {
15
16
  box(dis, r);
@@ -19,7 +20,8 @@ exports.acquire = (dis, lazy = true) => {
19
20
  }
20
21
  });
21
22
  };
22
- exports.release = (dis) => {
23
+ exports.acquire = acquire;
24
+ const release = (dis) => {
23
25
  dis.capacity++;
24
26
  if (dis.q.length) {
25
27
  dis.capacity -= 1, (dis.q.shift() || extras_1.THROW)();
@@ -29,3 +31,4 @@ exports.release = (dis) => {
29
31
  dis.capacity = dis.limit;
30
32
  }
31
33
  };
34
+ exports.release = release;
package/cjs/deque.js CHANGED
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Deque = void 0;
3
4
  const am = (src, si, dst, di, len) => {
4
5
  for (let j = 0; j < len; ++j) {
5
6
  dst[j + di] = src[j + si];
@@ -34,7 +35,6 @@ class Deque {
34
35
  const i = (this._f + l) & (this._c - 1);
35
36
  this._a[i] = s;
36
37
  this._l = l + 1;
37
- return l + 1;
38
38
  }
39
39
  shift() {
40
40
  const l = this._l;
@@ -48,17 +48,6 @@ class Deque {
48
48
  this._l = l - 1;
49
49
  return r;
50
50
  }
51
- clear() {
52
- const l = this._l;
53
- const f = this._f;
54
- const c = this._c;
55
- const a = this._a;
56
- for (let j = 0; j < l; ++j) {
57
- a[(f + j) & (c - 1)] = void 0;
58
- }
59
- this._l = 0;
60
- this._f = 0;
61
- }
62
51
  get length() {
63
52
  return this._l;
64
53
  }
package/cjs/extras.js CHANGED
@@ -1,5 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.THROW = () => {
3
+ exports.THROW = void 0;
4
+ const THROW = () => {
4
5
  throw new Error("mini-semaphore: inconsistent occurred");
5
6
  };
7
+ exports.THROW = THROW;
@@ -1,27 +1,73 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.restrictor = void 0;
3
4
  const c = require("./class");
4
- const { MiniSemaphore: MS } = c;
5
- const locks = {};
6
- const get = (key, restriction) => {
7
- let lock = locks[key];
8
- if (!lock) {
9
- locks[key] = lock = new MS(restriction);
10
- }
11
- if (lock.limit !== restriction) {
12
- throw new ReferenceError(`Cannot get object with different restriction: key: '${key}', lock.limit: ${lock.limit} <-> restriction: ${restriction},`);
13
- }
14
- return lock;
15
- };
16
5
  var restrictor;
17
6
  (function (restrictor) {
18
- restrictor.getLockByKey = (key) => locks[key];
7
+ const { MiniSemaphore: MS } = c;
8
+ const internalLock = new MS(1);
9
+ let locks = Object.create(null);
10
+ const get = async (key, restriction) => {
11
+ await internalLock.acquire(false);
12
+ let lock = locks[key];
13
+ if (!lock) {
14
+ locks[key] = lock = new MS(restriction);
15
+ }
16
+ if (lock.limit !== restriction) {
17
+ internalLock.release();
18
+ throw new ReferenceError(`Cannot get object with different restriction: key: '${key}', lock.limit: ${lock.limit} <-> restriction: ${restriction},`);
19
+ }
20
+ internalLock.release();
21
+ return lock;
22
+ };
23
+ restrictor.getLockByKey = async (key) => {
24
+ await internalLock.acquire(false);
25
+ const l = locks[key];
26
+ internalLock.release();
27
+ return l;
28
+ };
29
+ restrictor.cleanup = async (timeSpan, debug) => {
30
+ await internalLock.acquire(false);
31
+ const currentLocks = locks;
32
+ const newLocks = Object.create(null);
33
+ const keys = Object.keys(currentLocks);
34
+ let eliminatedCount = 0;
35
+ let eliminatedKeys;
36
+ !timeSpan && (timeSpan = 1);
37
+ timeSpan *= 1000;
38
+ if (debug) {
39
+ eliminatedKeys = [];
40
+ }
41
+ for (let i = 0, end = keys.length; i < end;) {
42
+ const key = keys[i++];
43
+ const s = currentLocks[key];
44
+ if (s.last && Date.now() - s.last >= timeSpan) {
45
+ eliminatedCount++;
46
+ if (debug) {
47
+ eliminatedKeys.push(key);
48
+ }
49
+ continue;
50
+ }
51
+ newLocks[key] = s;
52
+ }
53
+ locks = newLocks;
54
+ internalLock.release();
55
+ if (debug) {
56
+ console.log(`eliminated: [\n${eliminatedKeys.join(",\n")}\n]` +
57
+ "\n" +
58
+ `lived: [\n${Object.keys(newLocks).join(",\n")}\n]`);
59
+ }
60
+ return eliminatedCount;
61
+ };
19
62
  async function multi(key, restriction, pb) {
20
- return get(key, restriction).flow(pb);
63
+ const s = await get(key, restriction);
64
+ const result = s.flow(pb);
65
+ s.last = Date.now();
66
+ return result;
21
67
  }
22
68
  restrictor.multi = multi;
23
69
  async function one(key, pb) {
24
- return get(key, 1).flow(pb);
70
+ return multi(key, 1, pb);
25
71
  }
26
72
  restrictor.one = one;
27
73
  })(restrictor = exports.restrictor || (exports.restrictor = {}));
package/cjs/index.d.ts CHANGED
@@ -32,8 +32,8 @@ export declare class Deque<T extends any> {
32
32
  /**
33
33
  * @param s subject
34
34
  */
35
- push(s: T): number;
36
- shift(): T | undefined;
35
+ push(s: T): void;
36
+ // shift(): T | undefined;
37
37
  clear(): void;
38
38
  get length(): number;
39
39
  }
@@ -94,8 +94,8 @@ 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;
97
+ // export declare const acquire: (dis: TFlowableLock<TVoidFunction>, lazy?: boolean) => Promise<void>;
98
+ // export declare const release: (dis: TFlowableLock<TVoidFunction>) => void;
99
99
 
100
100
 
101
101
  /**
@@ -173,6 +173,14 @@ export declare class MiniSemaphore implements TFlowableLock {
173
173
  export declare const create: (capacity: number) => IFlowableLock;
174
174
 
175
175
  declare namespace fr {
176
+ /**
177
+ * Eliminate unused instances for the `timeSpan` seconds
178
+ *
179
+ * @param timeSpan specify unit as seconds
180
+ * @returns {Promise<number>} eliminated count
181
+ * @date 2020/6/19
182
+ */
183
+ const cleanup: (timeSpan: number, debug?: true | undefined) => Promise<number>;
176
184
  /**
177
185
  * get the semaphore associated with the value of `key`
178
186
  *
@@ -181,7 +189,7 @@ declare namespace fr {
181
189
  * @param key
182
190
  * @returns `IFlowableLock` instance or `undefined`
183
191
  */
184
- export const getLockByKey: (key: string | number) => IFlowableLock;
192
+ export const getLockByKey: (key: string | number) => Promise<IFlowableLock>;
185
193
  /**
186
194
  * Allocate a semaphore for each `key`, and limit the number of shares with the value of `restriction`
187
195
  *
package/cjs/index.js CHANGED
@@ -1,10 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.restrictor = exports.Deque = exports.create = exports.MiniSemaphore = void 0;
3
4
  var class_1 = require("./class");
4
- exports.MiniSemaphore = class_1.MiniSemaphore;
5
+ Object.defineProperty(exports, "MiniSemaphore", { enumerable: true, get: function () { return class_1.MiniSemaphore; } });
5
6
  var object_1 = require("./object");
6
- exports.create = object_1.create;
7
+ Object.defineProperty(exports, "create", { enumerable: true, get: function () { return object_1.create; } });
7
8
  var deque_1 = require("./deque");
8
- exports.Deque = deque_1.Deque;
9
+ Object.defineProperty(exports, "Deque", { enumerable: true, get: function () { return deque_1.Deque; } });
9
10
  var flow_restrictor_1 = require("./flow-restrictor");
10
- exports.restrictor = flow_restrictor_1.restrictor;
11
+ Object.defineProperty(exports, "restrictor", { enumerable: true, get: function () { return flow_restrictor_1.restrictor; } });
package/cjs/object.js CHANGED
@@ -1,10 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.create = void 0;
3
4
  const core = require("./core");
4
5
  const deque_1 = require("./deque");
5
6
  const a = core.acquire;
6
7
  const r = core.release;
7
- exports.create = (capacity) => {
8
+ const create = (capacity) => {
8
9
  return {
9
10
  capacity,
10
11
  limit: capacity,
@@ -32,3 +33,4 @@ exports.create = (capacity) => {
32
33
  }
33
34
  };
34
35
  };
36
+ exports.create = create;
package/esm/class.js CHANGED
@@ -28,4 +28,4 @@ export class MiniSemaphore {
28
28
  r(this);
29
29
  }
30
30
  }
31
- }
31
+ }
package/esm/core.js CHANGED
@@ -26,4 +26,4 @@ export const release = (dis) => {
26
26
  console.warn("inconsistent release!");
27
27
  dis.capacity = dis.limit;
28
28
  }
29
- };
29
+ };
package/esm/deque.js CHANGED
@@ -32,7 +32,6 @@ export class Deque {
32
32
  const i = (this._f + l) & (this._c - 1);
33
33
  this._a[i] = s;
34
34
  this._l = l + 1;
35
- return l + 1;
36
35
  }
37
36
  shift() {
38
37
  const l = this._l;
@@ -46,17 +45,6 @@ export class Deque {
46
45
  this._l = l - 1;
47
46
  return r;
48
47
  }
49
- clear() {
50
- const l = this._l;
51
- const f = this._f;
52
- const c = this._c;
53
- const a = this._a;
54
- for (let j = 0; j < l; ++j) {
55
- a[(f + j) & (c - 1)] = void 0;
56
- }
57
- this._l = 0;
58
- this._f = 0;
59
- }
60
48
  get length() {
61
49
  return this._l;
62
50
  }
@@ -70,4 +58,4 @@ const rt = (dis, n) => {
70
58
  const mc = (f + l) & (oc - 1);
71
59
  am(dis._a, 0, dis._a, oc, mc);
72
60
  }
73
- };
61
+ };
package/esm/extras.js CHANGED
@@ -1,3 +1,3 @@
1
1
  export const THROW = () => {
2
2
  throw new Error("mini-semaphore: inconsistent occurred");
3
- };
3
+ };
@@ -1,25 +1,70 @@
1
1
  import * as c from "./class";
2
- const { MiniSemaphore: MS } = c;
3
- const locks = {};
4
- const get = (key, restriction) => {
5
- let lock = locks[key];
6
- if (!lock) {
7
- locks[key] = lock = new MS(restriction);
8
- }
9
- if (lock.limit !== restriction) {
10
- throw new ReferenceError(`Cannot get object with different restriction: key: '${key}', lock.limit: ${lock.limit} <-> restriction: ${restriction},`);
11
- }
12
- return lock;
13
- };
14
2
  export var restrictor;
15
3
  (function (restrictor) {
16
- restrictor.getLockByKey = (key) => locks[key];
4
+ const { MiniSemaphore: MS } = c;
5
+ const internalLock = new MS(1);
6
+ let locks = Object.create(null);
7
+ const get = async (key, restriction) => {
8
+ await internalLock.acquire(false);
9
+ let lock = locks[key];
10
+ if (!lock) {
11
+ locks[key] = lock = new MS(restriction);
12
+ }
13
+ if (lock.limit !== restriction) {
14
+ internalLock.release();
15
+ throw new ReferenceError(`Cannot get object with different restriction: key: '${key}', lock.limit: ${lock.limit} <-> restriction: ${restriction},`);
16
+ }
17
+ internalLock.release();
18
+ return lock;
19
+ };
20
+ restrictor.getLockByKey = async (key) => {
21
+ await internalLock.acquire(false);
22
+ const l = locks[key];
23
+ internalLock.release();
24
+ return l;
25
+ };
26
+ restrictor.cleanup = async (timeSpan, debug) => {
27
+ await internalLock.acquire(false);
28
+ const currentLocks = locks;
29
+ const newLocks = Object.create(null);
30
+ const keys = Object.keys(currentLocks);
31
+ let eliminatedCount = 0;
32
+ let eliminatedKeys;
33
+ !timeSpan && (timeSpan = 1);
34
+ timeSpan *= 1000;
35
+ if (debug) {
36
+ eliminatedKeys = [];
37
+ }
38
+ for (let i = 0, end = keys.length; i < end;) {
39
+ const key = keys[i++];
40
+ const s = currentLocks[key];
41
+ if (s.last && Date.now() - s.last >= timeSpan) {
42
+ eliminatedCount++;
43
+ if (debug) {
44
+ eliminatedKeys.push(key);
45
+ }
46
+ continue;
47
+ }
48
+ newLocks[key] = s;
49
+ }
50
+ locks = newLocks;
51
+ internalLock.release();
52
+ if (debug) {
53
+ console.log(`eliminated: [\n${eliminatedKeys.join(",\n")}\n]` +
54
+ "\n" +
55
+ `lived: [\n${Object.keys(newLocks).join(",\n")}\n]`);
56
+ }
57
+ return eliminatedCount;
58
+ };
17
59
  async function multi(key, restriction, pb) {
18
- return get(key, restriction).flow(pb);
60
+ const s = await get(key, restriction);
61
+ const result = s.flow(pb);
62
+ s.last = Date.now();
63
+ return result;
19
64
  }
20
65
  restrictor.multi = multi;
21
66
  async function one(key, pb) {
22
- return get(key, 1).flow(pb);
67
+ return multi(key, 1, pb);
23
68
  }
24
69
  restrictor.one = one;
25
- })(restrictor || (restrictor = {}));
70
+ })(restrictor || (restrictor = {}));
package/esm/index.d.ts CHANGED
@@ -32,8 +32,8 @@ export declare class Deque<T extends any> {
32
32
  /**
33
33
  * @param s subject
34
34
  */
35
- push(s: T): number;
36
- shift(): T | undefined;
35
+ push(s: T): void;
36
+ // shift(): T | undefined;
37
37
  clear(): void;
38
38
  get length(): number;
39
39
  }
@@ -94,8 +94,8 @@ 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;
97
+ // export declare const acquire: (dis: TFlowableLock<TVoidFunction>, lazy?: boolean) => Promise<void>;
98
+ // export declare const release: (dis: TFlowableLock<TVoidFunction>) => void;
99
99
 
100
100
 
101
101
  /**
@@ -173,6 +173,14 @@ export declare class MiniSemaphore implements TFlowableLock {
173
173
  export declare const create: (capacity: number) => IFlowableLock;
174
174
 
175
175
  declare namespace fr {
176
+ /**
177
+ * Eliminate unused instances for the `timeSpan` seconds
178
+ *
179
+ * @param timeSpan specify unit as seconds
180
+ * @returns {Promise<number>} eliminated count
181
+ * @date 2020/6/19
182
+ */
183
+ const cleanup: (timeSpan: number, debug?: true | undefined) => Promise<number>;
176
184
  /**
177
185
  * get the semaphore associated with the value of `key`
178
186
  *
@@ -181,7 +189,7 @@ declare namespace fr {
181
189
  * @param key
182
190
  * @returns `IFlowableLock` instance or `undefined`
183
191
  */
184
- export const getLockByKey: (key: string | number) => IFlowableLock;
192
+ export const getLockByKey: (key: string | number) => Promise<IFlowableLock>;
185
193
  /**
186
194
  * Allocate a semaphore for each `key`, and limit the number of shares with the value of `restriction`
187
195
  *
package/esm/index.js CHANGED
@@ -1,4 +1,4 @@
1
1
  export { MiniSemaphore } from "./class";
2
2
  export { create } from "./object";
3
3
  export { Deque } from "./deque";
4
- export { restrictor } from "./flow-restrictor";
4
+ export { restrictor } from "./flow-restrictor";
package/esm/object.js CHANGED
@@ -29,4 +29,4 @@ export const create = (capacity) => {
29
29
  }
30
30
  }
31
31
  };
32
- };
32
+ };
package/index.d.ts CHANGED
@@ -32,8 +32,8 @@ export declare class Deque<T extends any> {
32
32
  /**
33
33
  * @param s subject
34
34
  */
35
- push(s: T): number;
36
- shift(): T | undefined;
35
+ push(s: T): void;
36
+ // shift(): T | undefined;
37
37
  clear(): void;
38
38
  get length(): number;
39
39
  }
@@ -94,8 +94,8 @@ 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;
97
+ // export declare const acquire: (dis: TFlowableLock<TVoidFunction>, lazy?: boolean) => Promise<void>;
98
+ // export declare const release: (dis: TFlowableLock<TVoidFunction>) => void;
99
99
 
100
100
 
101
101
  /**
@@ -173,6 +173,14 @@ export declare class MiniSemaphore implements TFlowableLock {
173
173
  export declare const create: (capacity: number) => IFlowableLock;
174
174
 
175
175
  declare namespace fr {
176
+ /**
177
+ * Eliminate unused instances for the `timeSpan` seconds
178
+ *
179
+ * @param timeSpan specify unit as seconds
180
+ * @returns {Promise<number>} eliminated count
181
+ * @date 2020/6/19
182
+ */
183
+ const cleanup: (timeSpan: number, debug?: true | undefined) => Promise<number>;
176
184
  /**
177
185
  * get the semaphore associated with the value of `key`
178
186
  *
@@ -181,7 +189,7 @@ declare namespace fr {
181
189
  * @param key
182
190
  * @returns `IFlowableLock` instance or `undefined`
183
191
  */
184
- export const getLockByKey: (key: string | number) => IFlowableLock;
192
+ export const getLockByKey: (key: string | number) => Promise<IFlowableLock>;
185
193
  /**
186
194
  * Allocate a semaphore for each `key`, and limit the number of shares with the value of `restriction`
187
195
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mini-semaphore",
3
- "version": "1.1.0",
3
+ "version": "1.3.4",
4
4
  "description": "A lightweight version of Semaphore",
5
5
  "private": false,
6
6
  "main": "./cjs/index.js",
@@ -19,6 +19,10 @@
19
19
  "type": "git",
20
20
  "url": "git+https://github.com/jeffy-g/mini-semaphore.git"
21
21
  },
22
+ "engines": {
23
+ "node": ">=10",
24
+ "yarn": "^1.22.4"
25
+ },
22
26
  "files": [
23
27
  "package.json",
24
28
  "README.md",
@@ -37,36 +41,5 @@
37
41
  "concurrency",
38
42
  "javascript",
39
43
  "typescript"
40
- ],
41
- "scripts": {
42
- "all": "yarn clean && yarn lint && yarn dist && yarn webpack && yarn copy:types",
43
- "build": "tsc",
44
- "build:esm": "tsc -p src/tsconfig.json && node ./scripts/tools -cmd rmc -basePath ./build/esm -test \"/.js$/\"",
45
- "clean": "rimraf build/* dist/* logs/*.tsbuildinfo",
46
- "copy:types": "cpx src/index.d.ts dist -v && cpx src/index.d.ts dist/cjs -v && cpx src/index.d.ts dist/esm -v && cpx src/index.d.ts dist/umd -v && cpx src/index.d.ts dist/webpack -v",
47
- "dist": "rimraf dist/!(webpack) && yarn build && yarn build:esm && cpx ./{package.json,README.md,LICENSE} dist -v && cpx \"./build/**/*.js\" dist -v",
48
- "inst:clean": "rimraf yarn.lock node_modules && yarn install",
49
- "lint": "eslint src/**/*.ts",
50
- "test": "jest --coverage --silent=false -c=jest.config.js",
51
- "update:packages": "yarn upgrade-interactive --latest",
52
- "webpack": "rimraf ./dist/webpack/* ./dist/umd/* && npx webpack && cpx ./dist/*.d.ts ./dist/webpack/ -v"
53
- },
54
- "devDependencies": {
55
- "@types/jest": "^25.1.4",
56
- "@types/webpack": "^4.41.6",
57
- "@typescript-eslint/eslint-plugin": "^2.23.0",
58
- "@typescript-eslint/eslint-plugin-tslint": "^2.23.0",
59
- "@typescript-eslint/parser": "^2.23.0",
60
- "cpx": "latest",
61
- "eslint": "^6.8.0",
62
- "jest": "^25.1.0",
63
- "rimraf": "^3.0.2",
64
- "rm-cstyle-cmts": "latest",
65
- "terser-webpack-plugin": "^2.3.5",
66
- "ts-jest": "^25.2.1",
67
- "ts-loader": "^6.2.1",
68
- "typescript": "^3.8.3",
69
- "webpack": "^4.42.0",
70
- "webpack-cli": "^3.3.11"
71
- }
72
- }
44
+ ]
45
+ }
package/umd/index.d.ts CHANGED
@@ -32,8 +32,8 @@ export declare class Deque<T extends any> {
32
32
  /**
33
33
  * @param s subject
34
34
  */
35
- push(s: T): number;
36
- shift(): T | undefined;
35
+ push(s: T): void;
36
+ // shift(): T | undefined;
37
37
  clear(): void;
38
38
  get length(): number;
39
39
  }
@@ -94,8 +94,8 @@ 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;
97
+ // export declare const acquire: (dis: TFlowableLock<TVoidFunction>, lazy?: boolean) => Promise<void>;
98
+ // export declare const release: (dis: TFlowableLock<TVoidFunction>) => void;
99
99
 
100
100
 
101
101
  /**
@@ -173,6 +173,14 @@ export declare class MiniSemaphore implements TFlowableLock {
173
173
  export declare const create: (capacity: number) => IFlowableLock;
174
174
 
175
175
  declare namespace fr {
176
+ /**
177
+ * Eliminate unused instances for the `timeSpan` seconds
178
+ *
179
+ * @param timeSpan specify unit as seconds
180
+ * @returns {Promise<number>} eliminated count
181
+ * @date 2020/6/19
182
+ */
183
+ const cleanup: (timeSpan: number, debug?: true | undefined) => Promise<number>;
176
184
  /**
177
185
  * get the semaphore associated with the value of `key`
178
186
  *
@@ -181,7 +189,7 @@ declare namespace fr {
181
189
  * @param key
182
190
  * @returns `IFlowableLock` instance or `undefined`
183
191
  */
184
- export const getLockByKey: (key: string | number) => IFlowableLock;
192
+ export const getLockByKey: (key: string | number) => Promise<IFlowableLock>;
185
193
  /**
186
194
  * Allocate a semaphore for each `key`, and limit the number of shares with the value of `restriction`
187
195
  *
package/umd/index.js CHANGED
@@ -1,84 +1,54 @@
1
1
  !function(t, e) {
2
2
  'object' == typeof exports && 'object' == typeof module ? module.exports = e() : 'function' == typeof define && define.amd ? define([], e) : 'object' == typeof exports ? exports.MiniSema = e() : t.MiniSema = e();
3
- }(window, (function() {
4
- return function(t) {
5
- var e = {};
6
- function i(n) {
7
- if (e[n]) return e[n].exports;
8
- var r = e[n] = {
9
- i: n,
10
- l: !1,
11
- exports: {}
12
- };
13
- return t[n].call(r.exports, r, r.exports, i), r.l = !0, r.exports;
14
- }
15
- return i.m = t, i.c = e, i.d = function(t, e, n) {
16
- i.o(t, e) || Object.defineProperty(t, e, {
17
- enumerable: !0,
18
- get: n
19
- });
20
- }, i.r = function(t) {
21
- 'undefined' != typeof Symbol && Symbol.toStringTag && Object.defineProperty(t, Symbol.toStringTag, {
22
- value: 'Module'
23
- }), Object.defineProperty(t, '__esModule', {
24
- value: !0
25
- });
26
- }, i.t = function(t, e) {
27
- if (1 & e && (t = i(t)), 8 & e) return t;
28
- if (4 & e && 'object' == typeof t && t && t.__esModule) return t;
29
- var n = Object.create(null);
30
- if (i.r(n), Object.defineProperty(n, 'default', {
31
- enumerable: !0,
32
- value: t
33
- }), 2 & e && 'string' != typeof t) for (var r in t) i.d(n, r, function(e) {
34
- return t[e];
35
- }.bind(null, r));
36
- return n;
37
- }, i.n = function(t) {
38
- var e = t && t.__esModule ? function() {
39
- return t.default;
40
- } : function() {
41
- return t;
42
- };
43
- return i.d(e, 'a', e), e;
44
- }, i.o = function(t, e) {
45
- return Object.prototype.hasOwnProperty.call(t, e);
46
- }, i.p = "", i(i.s = 0);
47
- }([ function(t, e, i) {
3
+ }(self, (function() {
4
+ return (() => {
48
5
  "use strict";
49
- i.r(e), i.d(e, "MiniSemaphore", (function() {
50
- return p;
51
- })), i.d(e, "create", (function() {
52
- return d;
53
- })), i.d(e, "Deque", (function() {
54
- return u;
55
- })), i.d(e, "restrictor", (function() {
56
- return g;
57
- }));
58
- var n = {};
59
- i.r(n), i.d(n, "MiniSemaphore", (function() {
60
- return p;
61
- }));
62
- const r = () => {
6
+ var t = {
7
+ d: (e, i) => {
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 = () => {
63
33
  throw new Error("mini-semaphore: inconsistent occurred");
64
- }, o = (t, e) => {
34
+ }, r = (t, e) => {
65
35
  t.capacity > 0 ? (t.capacity--, e()) : t.q.push(e);
66
- }, c = (t, e = !0) => new Promise(i => {
67
- e ? setTimeout(() => o(t, i), 4) : o(t, i);
68
- }), s = t => {
69
- t.capacity++, t.q.length && (t.capacity -= 1, (t.q.shift() || r)()), t.capacity > t.limit && (console.warn("inconsistent release!"),
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!"),
70
40
  t.capacity = t.limit);
71
- }, a = t => (t => (t >>>= 0, t -= 1, t |= t >> 1, t |= t >> 2, t |= t >> 4, t |= t >> 8,
72
- (t |= t >> 16) + 1))(Math.min(Math.max(16, 0 | t), 1073741824));
73
- class u {
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 {
74
44
  constructor(t) {
75
- this._c = a(t), this._l = 0, this._f = 0, this._a = [];
45
+ this._c = c(t), this._l = 0, this._f = 0, this._a = [];
76
46
  }
77
47
  push(t) {
78
48
  const e = this._l;
79
- this._c < e + 1 && l(this, a(1.5 * this._c + 16));
49
+ this._c < e + 1 && l(this, c(1.5 * this._c + 16));
80
50
  const i = this._f + e & this._c - 1;
81
- return this._a[i] = t, this._l = e + 1, e + 1;
51
+ this._a[i] = t, this._l = e + 1;
82
52
  }
83
53
  shift() {
84
54
  const t = this._l;
@@ -86,11 +56,6 @@
86
56
  const e = this._f, i = this._a[e];
87
57
  return this._a[e] = void 0, this._f = e + 1 & this._c - 1, this._l = t - 1, i;
88
58
  }
89
- clear() {
90
- const t = this._l, e = this._f, i = this._c, n = this._a;
91
- for (let r = 0; r < t; ++r) n[e + r & i - 1] = void 0;
92
- this._l = 0, this._f = 0;
93
- }
94
59
  get length() {
95
60
  return this._l;
96
61
  }
@@ -102,19 +67,19 @@
102
67
  if (n + r > i) {
103
68
  const e = n + r & i - 1;
104
69
  ((t, e, i, n, r) => {
105
- for (let o = 0; o < r; ++o) i[o + n] = t[o + e], t[o + e] = void 0;
70
+ for (let s = 0; s < r; ++s) i[s + n] = t[s + e], t[s + e] = void 0;
106
71
  })(t._a, 0, t._a, i, e);
107
72
  }
108
- }, f = c, h = s;
109
- class p {
73
+ }, h = s, u = a;
74
+ class f {
110
75
  constructor(t) {
111
- this.limit = this.capacity = t, this.q = new u(t);
76
+ this.limit = this.capacity = t, this.q = new o(t);
112
77
  }
113
78
  acquire(t) {
114
- return f(this, t);
79
+ return h(this, t);
115
80
  }
116
81
  release() {
117
- h(this);
82
+ u(this);
118
83
  }
119
84
  setRestriction(t) {
120
85
  this.limit = this.capacity = t;
@@ -123,23 +88,23 @@
123
88
  return this.q.length;
124
89
  }
125
90
  async flow(t, e) {
126
- await f(this, e);
91
+ await h(this, e);
127
92
  try {
128
93
  return await t();
129
94
  } finally {
130
- h(this);
95
+ u(this);
131
96
  }
132
97
  }
133
98
  }
134
- const y = c, _ = s, d = t => ({
99
+ const y = s, p = a, m = t => ({
135
100
  capacity: t,
136
101
  limit: t,
137
- q: new u(t),
102
+ q: new o(t),
138
103
  acquire(t) {
139
104
  return y(this, t);
140
105
  },
141
106
  release() {
142
- _(this);
107
+ p(this);
143
108
  },
144
109
  setRestriction(t) {
145
110
  this.limit = this.capacity = t;
@@ -152,22 +117,42 @@
152
117
  try {
153
118
  return await t();
154
119
  } finally {
155
- _(this);
120
+ p(this);
156
121
  }
157
122
  }
158
- }), {MiniSemaphore: m} = n, w = {}, b = (t, e) => {
159
- let i = w[t];
160
- if (i || (w[t] = i = new m(e)), i.limit !== e) throw new ReferenceError(`Cannot get object with different restriction: key: '${t}', lock.limit: ${i.limit} <-> restriction: ${e},`);
161
- return i;
162
- };
163
- var g;
164
- !function(t) {
165
- t.getLockByKey = t => w[t], t.multi = async function(t, e, i) {
166
- return b(t, e).flow(i);
167
- }, t.one = async function(t, e) {
168
- return b(t, 1).flow(e);
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);
169
154
  };
170
- }(g || (g = {}));
171
- } ]);
155
+ }(_ || (_ = {})), e;
156
+ })();
172
157
  }));
173
158
  //# sourceMappingURL=index.js.map
package/umd/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["webpack://MiniSema/index.js"],"sourcesContent":["!function(t, e) {\n 'object' == typeof exports && 'object' == typeof module ? module.exports = e() : 'function' == typeof define && define.amd ? define([], e) : 'object' == typeof exports ? exports.MiniSema = e() : t.MiniSema = e();\n}(window, (function() {\n return function(t) {\n var e = {};\n function i(n) {\n if (e[n]) return e[n].exports;\n var r = e[n] = {\n i: n,\n l: !1,\n exports: {}\n };\n return t[n].call(r.exports, r, r.exports, i), r.l = !0, r.exports;\n }\n return i.m = t, i.c = e, i.d = function(t, e, n) {\n i.o(t, e) || Object.defineProperty(t, e, {\n enumerable: !0,\n get: n\n });\n }, i.r = function(t) {\n 'undefined' != typeof Symbol && Symbol.toStringTag && Object.defineProperty(t, Symbol.toStringTag, {\n value: 'Module'\n }), Object.defineProperty(t, '__esModule', {\n value: !0\n });\n }, i.t = function(t, e) {\n if (1 & e && (t = i(t)), 8 & e) return t;\n if (4 & e && 'object' == typeof t && t && t.__esModule) return t;\n var n = Object.create(null);\n if (i.r(n), Object.defineProperty(n, 'default', {\n enumerable: !0,\n value: t\n }), 2 & e && 'string' != typeof t) for (var r in t) i.d(n, r, function(e) {\n return t[e];\n }.bind(null, r));\n return n;\n }, i.n = function(t) {\n var e = t && t.__esModule ? function() {\n return t.default;\n } : function() {\n return t;\n };\n return i.d(e, 'a', e), e;\n }, i.o = function(t, e) {\n return Object.prototype.hasOwnProperty.call(t, e);\n }, i.p = \"\", i(i.s = 0);\n }([ function(t, e, i) {\n \"use strict\";\n i.r(e), i.d(e, \"MiniSemaphore\", (function() {\n return p;\n })), i.d(e, \"create\", (function() {\n return d;\n })), i.d(e, \"Deque\", (function() {\n return u;\n })), i.d(e, \"restrictor\", (function() {\n return g;\n }));\n var n = {};\n i.r(n), i.d(n, \"MiniSemaphore\", (function() {\n return p;\n }));\n const r = () => {\n throw new Error(\"mini-semaphore: inconsistent occurred\");\n }, o = (t, e) => {\n t.capacity > 0 ? (t.capacity--, e()) : t.q.push(e);\n }, c = (t, e = !0) => new Promise(i => {\n e ? setTimeout(() => o(t, i), 4) : o(t, i);\n }), s = t => {\n t.capacity++, t.q.length && (t.capacity -= 1, (t.q.shift() || r)()), t.capacity > t.limit && (console.warn(\"inconsistent release!\"), \n t.capacity = t.limit);\n }, a = t => (t => (t >>>= 0, t -= 1, t |= t >> 1, t |= t >> 2, t |= t >> 4, t |= t >> 8, \n (t |= t >> 16) + 1))(Math.min(Math.max(16, 0 | t), 1073741824));\n class u {\n constructor(t) {\n this._c = a(t), this._l = 0, this._f = 0, this._a = [];\n }\n push(t) {\n const e = this._l;\n this._c < e + 1 && l(this, a(1.5 * this._c + 16));\n const i = this._f + e & this._c - 1;\n return this._a[i] = t, this._l = e + 1, e + 1;\n }\n shift() {\n const t = this._l;\n if (0 === t) return;\n const e = this._f, i = this._a[e];\n return this._a[e] = void 0, this._f = e + 1 & this._c - 1, this._l = t - 1, i;\n }\n clear() {\n const t = this._l, e = this._f, i = this._c, n = this._a;\n for (let r = 0; r < t; ++r) n[e + r & i - 1] = void 0;\n this._l = 0, this._f = 0;\n }\n get length() {\n return this._l;\n }\n }\n const l = (t, e) => {\n const i = t._c;\n t._c = e;\n const n = t._f, r = t._l;\n if (n + r > i) {\n const e = n + r & i - 1;\n ((t, e, i, n, r) => {\n for (let o = 0; o < r; ++o) i[o + n] = t[o + e], t[o + e] = void 0;\n })(t._a, 0, t._a, i, e);\n }\n }, f = c, h = s;\n class p {\n constructor(t) {\n this.limit = this.capacity = t, this.q = new u(t);\n }\n acquire(t) {\n return f(this, t);\n }\n release() {\n h(this);\n }\n setRestriction(t) {\n this.limit = this.capacity = t;\n }\n get pending() {\n return this.q.length;\n }\n async flow(t, e) {\n await f(this, e);\n try {\n return await t();\n } finally {\n h(this);\n }\n }\n }\n const y = c, _ = s, d = t => ({\n capacity: t,\n limit: t,\n q: new u(t),\n acquire(t) {\n return y(this, t);\n },\n release() {\n _(this);\n },\n setRestriction(t) {\n this.limit = this.capacity = t;\n },\n get pending() {\n return this.q.length;\n },\n async flow(t, e) {\n await y(this, e);\n try {\n return await t();\n } finally {\n _(this);\n }\n }\n }), {MiniSemaphore: m} = n, w = {}, b = (t, e) => {\n let i = w[t];\n if (i || (w[t] = i = new m(e)), i.limit !== e) throw new ReferenceError(`Cannot get object with different restriction: key: '${t}', lock.limit: ${i.limit} <-> restriction: ${e},`);\n return i;\n };\n var g;\n !function(t) {\n t.getLockByKey = t => w[t], t.multi = async function(t, e, i) {\n return b(t, e).flow(i);\n }, t.one = async function(t, e) {\n return b(t, 1).flow(e);\n };\n }(g || (g = {}));\n } ]);\n}));"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","sourceRoot":""}
1
+ {"version":3,"file":"index.js","mappings":"AAAA;AACA;AADA;AAUA;;ACTA;ACAA;AACA;AAEA;AAAA;;;ACJA;ACCA;AACA;AACA;AAEA;AAAA;;;;;;;;;;;;;;ACLA;AACA;ACAA;AACA;AAOA;AAEA;AAQA;AACA;AAMA;ACVA;AAFA;AAKA;AACA;AACA;;AAKA;AACA;AACA;AAGA;AACA;;AAGA;AACA;AACA;AAGA;AAKA;;AAEA;AACA;;;AAGA;AACA;AACA;AACA;AAEA;AACA;AAzDA;AACA;AAyDA;;ACxDA;AAEA;AACA;AACA;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AAEA;AACA;;;;ACzBA;AAIA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AAEA;AACA;;;;AC1BA;;AAEA;AAEA;AAqDA;AACA;AApDA;AACA;AAIA;AAKA;AA0CA;AAGA;;AA3CA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAGA;AAEA;AAKA;AACA;AAEA;;AAgBA;AAAA;AAQA;AAEA;;AAhEA;AVQA","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 throw new Error(\"mini-semaphore: inconsistent occurred\");\r\n};\r\n","import { THROW } from \"./extras\";\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 new Promise(r => {\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\nexport const release = (dis) => {\r\n dis.capacity++;\r\n if (dis.q.length) {\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","const am = (src, si, dst, di, len) => {\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\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\nconst gc = (n) => {\r\n return p2l(Math.min(Math.max(16, n | 0), 1073741824));\r\n};\r\nexport class Deque {\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 push(s) {\r\n const l = this._l;\r\n if (this._c < l + 1) {\r\n rt(this, gc(this._c * 1.5 + 16));\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 }\r\n shift() {\r\n const l = this._l;\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 get length() {\r\n return this._l;\r\n }\r\n}\r\nconst rt = (dis, n) => {\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 const mc = (f + l) & (oc - 1);\r\n am(dis._a, 0, dis._a, oc, mc);\r\n }\r\n};\r\n","import * as core from \"./core\";\r\nimport { Deque } from \"./deque\";\r\nconst a = core.acquire;\r\nconst r = core.release;\r\nexport class MiniSemaphore {\r\n constructor(capacity) {\r\n this.limit = this.capacity = capacity;\r\n this.q = new Deque(capacity);\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 async flow(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 }\r\n}\r\n","import * as core from \"./core\";\r\nimport { Deque } from \"./deque\";\r\nconst a = core.acquire;\r\nconst r = core.release;\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 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 }\r\n };\r\n};\r\n","import * as c from \"./class\";\r\nexport var restrictor;\r\n(function (restrictor) {\r\n const { MiniSemaphore: MS } = c;\r\n const internalLock = new MS(1);\r\n let locks = Object.create(null);\r\n const get = async (key, restriction) => {\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 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 internalLock.release();\r\n return lock;\r\n };\r\n restrictor.getLockByKey = async (key) => {\r\n await internalLock.acquire(false);\r\n const l = locks[key];\r\n internalLock.release();\r\n return l;\r\n };\r\n restrictor.cleanup = async (timeSpan, debug) => {\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);\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 locks = newLocks;\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 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 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"],"names":[],"sourceRoot":""}
@@ -32,8 +32,8 @@ export declare class Deque<T extends any> {
32
32
  /**
33
33
  * @param s subject
34
34
  */
35
- push(s: T): number;
36
- shift(): T | undefined;
35
+ push(s: T): void;
36
+ // shift(): T | undefined;
37
37
  clear(): void;
38
38
  get length(): number;
39
39
  }
@@ -94,8 +94,8 @@ 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;
97
+ // export declare const acquire: (dis: TFlowableLock<TVoidFunction>, lazy?: boolean) => Promise<void>;
98
+ // export declare const release: (dis: TFlowableLock<TVoidFunction>) => void;
99
99
 
100
100
 
101
101
  /**
@@ -173,6 +173,14 @@ export declare class MiniSemaphore implements TFlowableLock {
173
173
  export declare const create: (capacity: number) => IFlowableLock;
174
174
 
175
175
  declare namespace fr {
176
+ /**
177
+ * Eliminate unused instances for the `timeSpan` seconds
178
+ *
179
+ * @param timeSpan specify unit as seconds
180
+ * @returns {Promise<number>} eliminated count
181
+ * @date 2020/6/19
182
+ */
183
+ const cleanup: (timeSpan: number, debug?: true | undefined) => Promise<number>;
176
184
  /**
177
185
  * get the semaphore associated with the value of `key`
178
186
  *
@@ -181,7 +189,7 @@ declare namespace fr {
181
189
  * @param key
182
190
  * @returns `IFlowableLock` instance or `undefined`
183
191
  */
184
- export const getLockByKey: (key: string | number) => IFlowableLock;
192
+ export const getLockByKey: (key: string | number) => Promise<IFlowableLock>;
185
193
  /**
186
194
  * Allocate a semaphore for each `key`, and limit the number of shares with the value of `restriction`
187
195
  *
package/webpack/index.js CHANGED
@@ -1,81 +1,51 @@
1
- module.exports = function(t) {
2
- var e = {};
3
- function i(n) {
4
- if (e[n]) return e[n].exports;
5
- var r = e[n] = {
6
- i: n,
7
- l: !1,
8
- exports: {}
9
- };
10
- return t[n].call(r.exports, r, r.exports, i), r.l = !0, r.exports;
11
- }
12
- return i.m = t, i.c = e, i.d = function(t, e, n) {
13
- i.o(t, e) || Object.defineProperty(t, e, {
14
- enumerable: !0,
15
- get: n
16
- });
17
- }, i.r = function(t) {
18
- 'undefined' != typeof Symbol && Symbol.toStringTag && Object.defineProperty(t, Symbol.toStringTag, {
19
- value: 'Module'
20
- }), Object.defineProperty(t, '__esModule', {
21
- value: !0
22
- });
23
- }, i.t = function(t, e) {
24
- if (1 & e && (t = i(t)), 8 & e) return t;
25
- if (4 & e && 'object' == typeof t && t && t.__esModule) return t;
26
- var n = Object.create(null);
27
- if (i.r(n), Object.defineProperty(n, 'default', {
28
- enumerable: !0,
29
- value: t
30
- }), 2 & e && 'string' != typeof t) for (var r in t) i.d(n, r, function(e) {
31
- return t[e];
32
- }.bind(null, r));
33
- return n;
34
- }, i.n = function(t) {
35
- var e = t && t.__esModule ? function() {
36
- return t.default;
37
- } : function() {
38
- return t;
39
- };
40
- return i.d(e, 'a', e), e;
41
- }, i.o = function(t, e) {
42
- return Object.prototype.hasOwnProperty.call(t, e);
43
- }, i.p = "", i(i.s = 0);
44
- }([ function(t, e, i) {
1
+ (() => {
45
2
  "use strict";
46
- i.r(e), i.d(e, "MiniSemaphore", (function() {
47
- return _;
48
- })), i.d(e, "create", (function() {
49
- return d;
50
- })), i.d(e, "Deque", (function() {
51
- return u;
52
- })), i.d(e, "restrictor", (function() {
53
- return b;
54
- }));
55
- var n = {};
56
- i.r(n), i.d(n, "MiniSemaphore", (function() {
57
- return _;
58
- }));
59
- const r = () => {
3
+ var t = {
4
+ d: (e, i) => {
5
+ for (var n in i) t.o(i, n) && !t.o(e, n) && Object.defineProperty(e, n, {
6
+ enumerable: !0,
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 = () => {
60
30
  throw new Error("mini-semaphore: inconsistent occurred");
61
31
  }, s = (t, e) => {
62
32
  t.capacity > 0 ? (t.capacity--, e()) : t.q.push(e);
63
- }, c = (t, e = !0) => new Promise(i => {
64
- e ? setTimeout(() => s(t, i), 4) : s(t, i);
65
- }), o = t => {
66
- t.capacity++, t.q.length && (t.capacity -= 1, (t.q.shift() || r)()), t.capacity > t.limit && (console.warn("inconsistent release!"),
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!"),
67
37
  t.capacity = t.limit);
68
- }, a = t => (t => (t >>>= 0, t -= 1, t |= t >> 1, t |= t >> 2, t |= t >> 4, t |= t >> 8,
69
- (t |= t >> 16) + 1))(Math.min(Math.max(16, 0 | t), 1073741824));
70
- class u {
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 {
71
41
  constructor(t) {
72
- this._c = a(t), this._l = 0, this._f = 0, this._a = [];
42
+ this._c = c(t), this._l = 0, this._f = 0, this._a = [];
73
43
  }
74
44
  push(t) {
75
45
  const e = this._l;
76
- this._c < e + 1 && l(this, a(1.5 * this._c + 16));
46
+ this._c < e + 1 && l(this, c(1.5 * this._c + 16));
77
47
  const i = this._f + e & this._c - 1;
78
- return this._a[i] = t, this._l = e + 1, e + 1;
48
+ this._a[i] = t, this._l = e + 1;
79
49
  }
80
50
  shift() {
81
51
  const t = this._l;
@@ -83,11 +53,6 @@ module.exports = function(t) {
83
53
  const e = this._f, i = this._a[e];
84
54
  return this._a[e] = void 0, this._f = e + 1 & this._c - 1, this._l = t - 1, i;
85
55
  }
86
- clear() {
87
- const t = this._l, e = this._f, i = this._c, n = this._a;
88
- for (let r = 0; r < t; ++r) n[e + r & i - 1] = void 0;
89
- this._l = 0, this._f = 0;
90
- }
91
56
  get length() {
92
57
  return this._l;
93
58
  }
@@ -95,23 +60,23 @@ module.exports = function(t) {
95
60
  const l = (t, e) => {
96
61
  const i = t._c;
97
62
  t._c = e;
98
- const n = t._f, r = t._l;
99
- if (n + r > i) {
100
- const e = n + r & i - 1;
101
- ((t, e, i, n, r) => {
102
- for (let s = 0; s < r; ++s) i[s + n] = t[s + e], t[s + e] = void 0;
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;
103
68
  })(t._a, 0, t._a, i, e);
104
69
  }
105
- }, h = c, f = o;
106
- class _ {
70
+ }, h = r, u = a;
71
+ class y {
107
72
  constructor(t) {
108
- this.limit = this.capacity = t, this.q = new u(t);
73
+ this.limit = this.capacity = t, this.q = new o(t);
109
74
  }
110
75
  acquire(t) {
111
76
  return h(this, t);
112
77
  }
113
78
  release() {
114
- f(this);
79
+ u(this);
115
80
  }
116
81
  setRestriction(t) {
117
82
  this.limit = this.capacity = t;
@@ -124,19 +89,19 @@ module.exports = function(t) {
124
89
  try {
125
90
  return await t();
126
91
  } finally {
127
- f(this);
92
+ u(this);
128
93
  }
129
94
  }
130
95
  }
131
- const p = c, y = o, d = t => ({
96
+ const f = r, p = a, _ = t => ({
132
97
  capacity: t,
133
98
  limit: t,
134
- q: new u(t),
99
+ q: new o(t),
135
100
  acquire(t) {
136
- return p(this, t);
101
+ return f(this, t);
137
102
  },
138
103
  release() {
139
- y(this);
104
+ p(this);
140
105
  },
141
106
  setRestriction(t) {
142
107
  this.limit = this.capacity = t;
@@ -145,25 +110,45 @@ module.exports = function(t) {
145
110
  return this.q.length;
146
111
  },
147
112
  async flow(t, e) {
148
- await p(this, e);
113
+ await f(this, e);
149
114
  try {
150
115
  return await t();
151
116
  } finally {
152
- y(this);
117
+ p(this);
153
118
  }
154
119
  }
155
- }), {MiniSemaphore: m} = n, w = {}, g = (t, e) => {
156
- let i = w[t];
157
- if (i || (w[t] = i = new m(e)), i.limit !== e) throw new ReferenceError(`Cannot get object with different restriction: key: '${t}', lock.limit: ${i.limit} <-> restriction: ${e},`);
158
- return i;
159
- };
160
- var b;
120
+ });
121
+ var m;
161
122
  !function(t) {
162
- t.getLockByKey = t => w[t], t.multi = async function(t, e, i) {
163
- return g(t, e).flow(i);
164
- }, t.one = async function(t, e) {
165
- return g(t, 1).flow(e);
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);
166
151
  };
167
- }(b || (b = {}));
168
- } ]);
152
+ }(m || (m = {})), module.exports = e;
153
+ })();
169
154
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["webpack:///index.js"],"sourcesContent":["module.exports = function(t) {\n var e = {};\n function i(n) {\n if (e[n]) return e[n].exports;\n var r = e[n] = {\n i: n,\n l: !1,\n exports: {}\n };\n return t[n].call(r.exports, r, r.exports, i), r.l = !0, r.exports;\n }\n return i.m = t, i.c = e, i.d = function(t, e, n) {\n i.o(t, e) || Object.defineProperty(t, e, {\n enumerable: !0,\n get: n\n });\n }, i.r = function(t) {\n 'undefined' != typeof Symbol && Symbol.toStringTag && Object.defineProperty(t, Symbol.toStringTag, {\n value: 'Module'\n }), Object.defineProperty(t, '__esModule', {\n value: !0\n });\n }, i.t = function(t, e) {\n if (1 & e && (t = i(t)), 8 & e) return t;\n if (4 & e && 'object' == typeof t && t && t.__esModule) return t;\n var n = Object.create(null);\n if (i.r(n), Object.defineProperty(n, 'default', {\n enumerable: !0,\n value: t\n }), 2 & e && 'string' != typeof t) for (var r in t) i.d(n, r, function(e) {\n return t[e];\n }.bind(null, r));\n return n;\n }, i.n = function(t) {\n var e = t && t.__esModule ? function() {\n return t.default;\n } : function() {\n return t;\n };\n return i.d(e, 'a', e), e;\n }, i.o = function(t, e) {\n return Object.prototype.hasOwnProperty.call(t, e);\n }, i.p = \"\", i(i.s = 0);\n}([ function(t, e, i) {\n \"use strict\";\n i.r(e), i.d(e, \"MiniSemaphore\", (function() {\n return _;\n })), i.d(e, \"create\", (function() {\n return d;\n })), i.d(e, \"Deque\", (function() {\n return u;\n })), i.d(e, \"restrictor\", (function() {\n return b;\n }));\n var n = {};\n i.r(n), i.d(n, \"MiniSemaphore\", (function() {\n return _;\n }));\n const r = () => {\n throw new Error(\"mini-semaphore: inconsistent occurred\");\n }, s = (t, e) => {\n t.capacity > 0 ? (t.capacity--, e()) : t.q.push(e);\n }, c = (t, e = !0) => new Promise(i => {\n e ? setTimeout(() => s(t, i), 4) : s(t, i);\n }), o = t => {\n t.capacity++, t.q.length && (t.capacity -= 1, (t.q.shift() || r)()), t.capacity > t.limit && (console.warn(\"inconsistent release!\"), \n t.capacity = t.limit);\n }, a = t => (t => (t >>>= 0, t -= 1, t |= t >> 1, t |= t >> 2, t |= t >> 4, t |= t >> 8, \n (t |= t >> 16) + 1))(Math.min(Math.max(16, 0 | t), 1073741824));\n class u {\n constructor(t) {\n this._c = a(t), this._l = 0, this._f = 0, this._a = [];\n }\n push(t) {\n const e = this._l;\n this._c < e + 1 && l(this, a(1.5 * this._c + 16));\n const i = this._f + e & this._c - 1;\n return this._a[i] = t, this._l = e + 1, e + 1;\n }\n shift() {\n const t = this._l;\n if (0 === t) return;\n const e = this._f, i = this._a[e];\n return this._a[e] = void 0, this._f = e + 1 & this._c - 1, this._l = t - 1, i;\n }\n clear() {\n const t = this._l, e = this._f, i = this._c, n = this._a;\n for (let r = 0; r < t; ++r) n[e + r & i - 1] = void 0;\n this._l = 0, this._f = 0;\n }\n get length() {\n return this._l;\n }\n }\n const l = (t, e) => {\n const i = t._c;\n t._c = e;\n const n = t._f, r = t._l;\n if (n + r > i) {\n const e = n + r & i - 1;\n ((t, e, i, n, r) => {\n for (let s = 0; s < r; ++s) i[s + n] = t[s + e], t[s + e] = void 0;\n })(t._a, 0, t._a, i, e);\n }\n }, h = c, f = o;\n class _ {\n constructor(t) {\n this.limit = this.capacity = t, this.q = new u(t);\n }\n acquire(t) {\n return h(this, t);\n }\n release() {\n f(this);\n }\n setRestriction(t) {\n this.limit = this.capacity = t;\n }\n get pending() {\n return this.q.length;\n }\n async flow(t, e) {\n await h(this, e);\n try {\n return await t();\n } finally {\n f(this);\n }\n }\n }\n const p = c, y = o, d = t => ({\n capacity: t,\n limit: t,\n q: new u(t),\n acquire(t) {\n return p(this, t);\n },\n release() {\n y(this);\n },\n setRestriction(t) {\n this.limit = this.capacity = t;\n },\n get pending() {\n return this.q.length;\n },\n async flow(t, e) {\n await p(this, e);\n try {\n return await t();\n } finally {\n y(this);\n }\n }\n }), {MiniSemaphore: m} = n, w = {}, g = (t, e) => {\n let i = w[t];\n if (i || (w[t] = i = new m(e)), i.limit !== e) throw new ReferenceError(`Cannot get object with different restriction: key: '${t}', lock.limit: ${i.limit} <-> restriction: ${e},`);\n return i;\n };\n var b;\n !function(t) {\n t.getLockByKey = t => w[t], t.multi = async function(t, e, i) {\n return g(t, e).flow(i);\n }, t.one = async function(t, e) {\n return g(t, 1).flow(e);\n };\n }(b || (b = {}));\n} ]);"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","sourceRoot":""}
1
+ {"version":3,"file":"index.js","mappings":";;AACA;ACAA;AACA;AAEA;AAAA;;;ACJA;ACCA;AACA;AACA;AAEA;AAAA;;;;;;;;;;;;;;ACLA;AACA;ACAA;AACA;AAOA;AAEA;AAQA;AACA;AAMA;ACVA;AAFA;AAKA;AACA;AACA;;AAKA;AACA;AACA;AAGA;AACA;;AAGA;AACA;AACA;AAGA;AAKA;;AAEA;AACA;;;AAGA;AACA;AACA;AACA;AAEA;AACA;AAzDA;AACA;AAyDA;;ACxDA;AAEA;AACA;AACA;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AAEA;AACA;;;;ACzBA;AAIA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AAEA;AACA;;;;AC1BA;AACA;AACA;AAEA;AAqDA;AACA;AApDA;AACA;AAIA;AAKA;AA0CA;AAGA;;AA3CA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAGA;AAEA;AAKA;AACA;AAEA;;AAgBA;AAAA;AAQA;AAEA;;AAhEA","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 throw new Error(\"mini-semaphore: inconsistent occurred\");\r\n};\r\n","import { THROW } from \"./extras\";\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 new Promise(r => {\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\nexport const release = (dis) => {\r\n dis.capacity++;\r\n if (dis.q.length) {\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","const am = (src, si, dst, di, len) => {\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\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\nconst gc = (n) => {\r\n return p2l(Math.min(Math.max(16, n | 0), 1073741824));\r\n};\r\nexport class Deque {\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 push(s) {\r\n const l = this._l;\r\n if (this._c < l + 1) {\r\n rt(this, gc(this._c * 1.5 + 16));\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 }\r\n shift() {\r\n const l = this._l;\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 get length() {\r\n return this._l;\r\n }\r\n}\r\nconst rt = (dis, n) => {\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 const mc = (f + l) & (oc - 1);\r\n am(dis._a, 0, dis._a, oc, mc);\r\n }\r\n};\r\n","import * as core from \"./core\";\r\nimport { Deque } from \"./deque\";\r\nconst a = core.acquire;\r\nconst r = core.release;\r\nexport class MiniSemaphore {\r\n constructor(capacity) {\r\n this.limit = this.capacity = capacity;\r\n this.q = new Deque(capacity);\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 async flow(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 }\r\n}\r\n","import * as core from \"./core\";\r\nimport { Deque } from \"./deque\";\r\nconst a = core.acquire;\r\nconst r = core.release;\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 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 }\r\n };\r\n};\r\n","import * as c from \"./class\";\r\nexport var restrictor;\r\n(function (restrictor) {\r\n const { MiniSemaphore: MS } = c;\r\n const internalLock = new MS(1);\r\n let locks = Object.create(null);\r\n const get = async (key, restriction) => {\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 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 internalLock.release();\r\n return lock;\r\n };\r\n restrictor.getLockByKey = async (key) => {\r\n await internalLock.acquire(false);\r\n const l = locks[key];\r\n internalLock.release();\r\n return l;\r\n };\r\n restrictor.cleanup = async (timeSpan, debug) => {\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);\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 locks = newLocks;\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 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 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"],"names":[],"sourceRoot":""}