mini-semaphore 1.3.0 → 1.3.7

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,5 @@
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)
1
+ [![CircleCI](https://circleci.com/gh/jeffy-g/mini-semaphore/tree/master.svg?style=svg)](https://circleci.com/gh/jeffy-g/mini-semaphore/tree/master)
2
+ ![GitHub](https://img.shields.io/github/license/jeffy-g/mini-semaphore?style=plastic)
2
3
 
3
4
  # Mini Semaphore (mini-semaphore
4
5
 
package/cjs/core.js CHANGED
@@ -10,7 +10,7 @@ const box = (z, r) => {
10
10
  z.q.push(r);
11
11
  }
12
12
  };
13
- exports.acquire = (dis, lazy = true) => {
13
+ const acquire = (dis, lazy = true) => {
14
14
  return new Promise(r => {
15
15
  if (!lazy) {
16
16
  box(dis, r);
@@ -20,7 +20,8 @@ exports.acquire = (dis, lazy = true) => {
20
20
  }
21
21
  });
22
22
  };
23
- exports.release = (dis) => {
23
+ exports.acquire = acquire;
24
+ const release = (dis) => {
24
25
  dis.capacity++;
25
26
  if (dis.q.length) {
26
27
  dis.capacity -= 1, (dis.q.shift() || extras_1.THROW)();
@@ -30,3 +31,4 @@ exports.release = (dis) => {
30
31
  dis.capacity = dis.limit;
31
32
  }
32
33
  };
34
+ exports.release = release;
package/cjs/deque.js CHANGED
@@ -35,7 +35,6 @@ class Deque {
35
35
  const i = (this._f + l) & (this._c - 1);
36
36
  this._a[i] = s;
37
37
  this._l = l + 1;
38
- return l + 1;
39
38
  }
40
39
  shift() {
41
40
  const l = this._l;
@@ -49,17 +48,6 @@ class Deque {
49
48
  this._l = l - 1;
50
49
  return r;
51
50
  }
52
- clear() {
53
- const l = this._l;
54
- const f = this._f;
55
- const c = this._c;
56
- const a = this._a;
57
- for (let j = 0; j < l; ++j) {
58
- a[(f + j) & (c - 1)] = void 0;
59
- }
60
- this._l = 0;
61
- this._f = 0;
62
- }
63
51
  get length() {
64
52
  return this._l;
65
53
  }
package/cjs/extras.js CHANGED
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.THROW = void 0;
4
- exports.THROW = () => {
4
+ const THROW = () => {
5
5
  throw new Error("mini-semaphore: inconsistent occurred");
6
6
  };
7
+ exports.THROW = THROW;
@@ -2,24 +2,24 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.restrictor = void 0;
4
4
  const c = require("./class");
5
- const { MiniSemaphore: MS } = c;
6
- const internalLock = new MS(1);
7
- let locks = Object.create(null);
8
- const get = async (key, restriction) => {
9
- await internalLock.acquire(false);
10
- let lock = locks[key];
11
- if (!lock) {
12
- locks[key] = lock = new MS(restriction);
13
- }
14
- if (lock.limit !== restriction) {
15
- internalLock.release();
16
- throw new ReferenceError(`Cannot get object with different restriction: key: '${key}', lock.limit: ${lock.limit} <-> restriction: ${restriction},`);
17
- }
18
- internalLock.release();
19
- return lock;
20
- };
21
5
  var restrictor;
22
6
  (function (restrictor) {
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
23
  restrictor.getLockByKey = async (key) => {
24
24
  await internalLock.acquire(false);
25
25
  const l = locks[key];
@@ -31,19 +31,20 @@ var restrictor;
31
31
  const currentLocks = locks;
32
32
  const newLocks = Object.create(null);
33
33
  const keys = Object.keys(currentLocks);
34
- let purgeCount = 0;
35
- let purgedKeys;
34
+ let eliminatedCount = 0;
35
+ let eliminatedKeys;
36
+ !timeSpan && (timeSpan = 1);
36
37
  timeSpan *= 1000;
37
38
  if (debug) {
38
- purgedKeys = [];
39
+ eliminatedKeys = [];
39
40
  }
40
41
  for (let i = 0, end = keys.length; i < end;) {
41
42
  const key = keys[i++];
42
43
  const s = currentLocks[key];
43
44
  if (s.last && Date.now() - s.last >= timeSpan) {
44
- purgeCount++;
45
+ eliminatedCount++;
45
46
  if (debug) {
46
- purgedKeys.push(key);
47
+ eliminatedKeys.push(key);
47
48
  }
48
49
  continue;
49
50
  }
@@ -52,24 +53,21 @@ var restrictor;
52
53
  locks = newLocks;
53
54
  internalLock.release();
54
55
  if (debug) {
55
- console.log(`purged: [\n${purgedKeys.join(",\n")}\n]` +
56
+ console.log(`eliminated: [\n${eliminatedKeys.join(",\n")}\n]` +
56
57
  "\n" +
57
- `lived: [\n${Object.keys(newLocks).join(",\n")}\n]`);
58
+ `lived: [\n${Object.keys(newLocks).join(",\n")}\n]`);
58
59
  }
59
- return purgeCount;
60
+ return eliminatedCount;
60
61
  };
61
- const fire = async (key, restriction, pb) => {
62
+ async function multi(key, restriction, pb) {
62
63
  const s = await get(key, restriction);
63
64
  const result = s.flow(pb);
64
65
  s.last = Date.now();
65
66
  return result;
66
- };
67
- async function multi(key, restriction, pb) {
68
- return fire(key, restriction, pb);
69
67
  }
70
68
  restrictor.multi = multi;
71
69
  async function one(key, pb) {
72
- return fire(key, 1, pb);
70
+ return multi(key, 1, pb);
73
71
  }
74
72
  restrictor.one = one;
75
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,5 +1,6 @@
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
5
  Object.defineProperty(exports, "MiniSemaphore", { enumerable: true, get: function () { return class_1.MiniSemaphore; } });
5
6
  var object_1 = require("./object");
package/cjs/object.js CHANGED
@@ -5,7 +5,7 @@ const core = require("./core");
5
5
  const deque_1 = require("./deque");
6
6
  const a = core.acquire;
7
7
  const r = core.release;
8
- exports.create = (capacity) => {
8
+ const create = (capacity) => {
9
9
  return {
10
10
  capacity,
11
11
  limit: capacity,
@@ -33,3 +33,4 @@ exports.create = (capacity) => {
33
33
  }
34
34
  };
35
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
@@ -15,6 +15,7 @@ const p2l = (n) => {
15
15
  return n + 1;
16
16
  };
17
17
  const gc = (n) => {
18
+ // @ts-ignore typescript cannot allow (undefined | 0) expression
18
19
  return p2l(Math.min(Math.max(16, n | 0), 1073741824));
19
20
  };
20
21
  export class Deque {
@@ -32,7 +33,6 @@ export class Deque {
32
33
  const i = (this._f + l) & (this._c - 1);
33
34
  this._a[i] = s;
34
35
  this._l = l + 1;
35
- return l + 1;
36
36
  }
37
37
  shift() {
38
38
  const l = this._l;
@@ -46,17 +46,6 @@ export class Deque {
46
46
  this._l = l - 1;
47
47
  return r;
48
48
  }
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
49
  get length() {
61
50
  return this._l;
62
51
  }
@@ -70,4 +59,4 @@ const rt = (dis, n) => {
70
59
  const mc = (f + l) & (oc - 1);
71
60
  am(dis._a, 0, dis._a, oc, mc);
72
61
  }
73
- };
62
+ };
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,22 +1,22 @@
1
1
  import * as c from "./class";
2
- const { MiniSemaphore: MS } = c;
3
- const internalLock = new MS(1);
4
- let locks = Object.create(null);
5
- const get = async (key, restriction) => {
6
- await internalLock.acquire(false);
7
- let lock = locks[key];
8
- if (!lock) {
9
- locks[key] = lock = new MS(restriction);
10
- }
11
- if (lock.limit !== restriction) {
12
- internalLock.release();
13
- throw new ReferenceError(`Cannot get object with different restriction: key: '${key}', lock.limit: ${lock.limit} <-> restriction: ${restriction},`);
14
- }
15
- internalLock.release();
16
- return lock;
17
- };
18
2
  export var restrictor;
19
3
  (function (restrictor) {
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
20
  restrictor.getLockByKey = async (key) => {
21
21
  await internalLock.acquire(false);
22
22
  const l = locks[key];
@@ -28,19 +28,20 @@ export var restrictor;
28
28
  const currentLocks = locks;
29
29
  const newLocks = Object.create(null);
30
30
  const keys = Object.keys(currentLocks);
31
- let purgeCount = 0;
32
- let purgedKeys;
31
+ let eliminatedCount = 0;
32
+ let eliminatedKeys;
33
+ !timeSpan && (timeSpan = 1);
33
34
  timeSpan *= 1000;
34
35
  if (debug) {
35
- purgedKeys = [];
36
+ eliminatedKeys = [];
36
37
  }
37
38
  for (let i = 0, end = keys.length; i < end;) {
38
39
  const key = keys[i++];
39
40
  const s = currentLocks[key];
40
41
  if (s.last && Date.now() - s.last >= timeSpan) {
41
- purgeCount++;
42
+ eliminatedCount++;
42
43
  if (debug) {
43
- purgedKeys.push(key);
44
+ eliminatedKeys.push(key);
44
45
  }
45
46
  continue;
46
47
  }
@@ -49,24 +50,21 @@ export var restrictor;
49
50
  locks = newLocks;
50
51
  internalLock.release();
51
52
  if (debug) {
52
- console.log(`purged: [\n${purgedKeys.join(",\n")}\n]` +
53
+ console.log(`eliminated: [\n${eliminatedKeys.join(",\n")}\n]` +
53
54
  "\n" +
54
- `lived: [\n${Object.keys(newLocks).join(",\n")}\n]`);
55
+ `lived: [\n${Object.keys(newLocks).join(",\n")}\n]`);
55
56
  }
56
- return purgeCount;
57
+ return eliminatedCount;
57
58
  };
58
- const fire = async (key, restriction, pb) => {
59
+ async function multi(key, restriction, pb) {
59
60
  const s = await get(key, restriction);
60
61
  const result = s.flow(pb);
61
62
  s.last = Date.now();
62
63
  return result;
63
- };
64
- async function multi(key, restriction, pb) {
65
- return fire(key, restriction, pb);
66
64
  }
67
65
  restrictor.multi = multi;
68
66
  async function one(key, pb) {
69
- return fire(key, 1, pb);
67
+ return multi(key, 1, pb);
70
68
  }
71
69
  restrictor.one = one;
72
- })(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.3.0",
3
+ "version": "1.3.7",
4
4
  "description": "A lightweight version of Semaphore",
5
5
  "private": false,
6
6
  "main": "./cjs/index.js",
@@ -20,7 +20,7 @@
20
20
  "url": "git+https://github.com/jeffy-g/mini-semaphore.git"
21
21
  },
22
22
  "engines": {
23
- "node": ">=10",
23
+ "node": ">=v12.22.10",
24
24
  "yarn": "^1.22.4"
25
25
  },
26
26
  "files": [
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
  *