@chriscdn/promise-semaphore 2.0.0 → 2.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,143 +1,143 @@
1
- import Semaphore from '../src/index'
1
+ import Semaphore from "../src/index";
2
2
 
3
- const pause = async (ms) => new Promise((resolve) => setTimeout(resolve, ms))
3
+ const pause = async (ms) => new Promise((resolve) => setTimeout(resolve, ms));
4
4
 
5
- test('Acquire & Release Basic', async () => {
6
- const semaphore = new Semaphore()
7
- expect(semaphore.canAcquire()).toBe(true)
8
- await semaphore.acquire()
9
- expect(semaphore.canAcquire()).toBe(false)
10
- expect(semaphore.hasTasks()).toBe(true)
11
- expect(semaphore.count()).toBe(1)
12
- semaphore.release()
13
- expect(semaphore.canAcquire()).toBe(true)
14
- expect(semaphore.count()).toBe(0)
15
- })
5
+ test("Acquire & Release Basic", async () => {
6
+ const semaphore = new Semaphore();
7
+ expect(semaphore.canAcquire()).toBe(true);
8
+ await semaphore.acquire();
9
+ expect(semaphore.canAcquire()).toBe(false);
10
+ expect(semaphore.hasTasks()).toBe(true);
11
+ expect(semaphore.count()).toBe(1);
12
+ semaphore.release();
13
+ expect(semaphore.canAcquire()).toBe(true);
14
+ expect(semaphore.count()).toBe(0);
15
+ });
16
16
 
17
- test('Semaphore 1', async () => {
18
- const semaphore = new Semaphore()
17
+ test("Semaphore 1", async () => {
18
+ const semaphore = new Semaphore();
19
19
 
20
20
  semaphore
21
21
  .acquire()
22
22
  .then(async () => await pause(1000))
23
- .finally(() => semaphore.release())
23
+ .finally(() => semaphore.release());
24
24
 
25
- expect(semaphore.canAcquire()).toBe(false)
25
+ expect(semaphore.canAcquire()).toBe(false);
26
26
 
27
- await pause(600)
27
+ await pause(600);
28
28
 
29
- expect(semaphore.canAcquire()).toBe(false)
29
+ expect(semaphore.canAcquire()).toBe(false);
30
30
 
31
- await pause(600)
31
+ await pause(600);
32
32
 
33
- expect(semaphore.canAcquire()).toBe(true)
34
- })
33
+ expect(semaphore.canAcquire()).toBe(true);
34
+ });
35
35
 
36
- test('Semaphore 2', async () => {
37
- const semaphore = new Semaphore()
36
+ test("Semaphore 2", async () => {
37
+ const semaphore = new Semaphore();
38
38
 
39
- let tester = 0
39
+ let tester = 0;
40
40
 
41
41
  semaphore
42
42
  .acquire()
43
43
  .then(() => pause(1000))
44
44
  .then(() => (tester = 10))
45
- .finally(() => semaphore.release())
45
+ .finally(() => semaphore.release());
46
46
 
47
47
  // tests acquire waits for previous to complete
48
48
  await semaphore
49
49
  .acquire()
50
50
  .then(() => expect(tester).toBe(10))
51
- .finally(() => semaphore.release())
52
- })
51
+ .finally(() => semaphore.release());
52
+ });
53
53
 
54
- test('Semaphore 3', async () => {
55
- const semaphore = new Semaphore(2)
54
+ test("Semaphore 3", async () => {
55
+ const semaphore = new Semaphore(2);
56
56
 
57
- let tester = 0
57
+ let tester = 0;
58
58
 
59
59
  semaphore
60
60
  .acquire()
61
61
  .then(() => pause(1000))
62
62
  .then(() => (tester = 20))
63
- .finally(() => semaphore.release())
63
+ .finally(() => semaphore.release());
64
64
 
65
65
  semaphore
66
66
  .acquire()
67
67
  .then(() => pause(500))
68
68
  .then(() => (tester = 10))
69
- .finally(() => semaphore.release())
69
+ .finally(() => semaphore.release());
70
70
 
71
- expect(semaphore.count()).toBe(2)
72
- expect(semaphore.hasTasks()).toBe(true)
71
+ expect(semaphore.count()).toBe(2);
72
+ expect(semaphore.hasTasks()).toBe(true);
73
73
 
74
74
  // expect 10 since this next block will run before the first has completed
75
75
  await semaphore
76
76
  .acquire()
77
77
  .then(() => expect(tester).toBe(10))
78
- .finally(() => semaphore.release())
78
+ .finally(() => semaphore.release());
79
79
 
80
- expect(semaphore.count()).toBe(1)
81
- expect(semaphore.hasTasks()).toBe(true)
82
- expect(semaphore.canAcquire()).toBe(true)
83
- })
80
+ expect(semaphore.count()).toBe(1);
81
+ expect(semaphore.hasTasks()).toBe(true);
82
+ expect(semaphore.canAcquire()).toBe(true);
83
+ });
84
84
 
85
- test('Request 1', async () => {
86
- const semaphore = new Semaphore()
85
+ test("Request 1", async () => {
86
+ const semaphore = new Semaphore();
87
87
 
88
- let tester = 0
88
+ let tester = 0;
89
89
 
90
90
  semaphore.request(async () => {
91
- await pause(1000)
92
- tester = 20
93
- })
91
+ await pause(1000);
92
+ tester = 20;
93
+ });
94
94
 
95
95
  semaphore.request(async () => {
96
- await pause(500)
97
- tester = 10
98
- })
96
+ await pause(500);
97
+ tester = 10;
98
+ });
99
99
 
100
100
  await semaphore.request(async () => {
101
- expect(tester).toBe(10)
102
- })
103
- })
101
+ expect(tester).toBe(10);
102
+ });
103
+ });
104
104
 
105
- test('Request 2', async () => {
106
- const semaphore = new Semaphore(2)
105
+ test("Request 2", async () => {
106
+ const semaphore = new Semaphore(2);
107
107
 
108
- let tester = 0
108
+ let tester = 0;
109
109
 
110
110
  semaphore.request(async () => {
111
- await pause(1000)
112
- tester = 20
113
- })
111
+ await pause(1000);
112
+ tester = 20;
113
+ });
114
114
 
115
115
  semaphore.request(async () => {
116
- await pause(500)
117
- tester = 10
118
- })
116
+ await pause(500);
117
+ tester = 10;
118
+ });
119
119
 
120
120
  await semaphore.request(async () => {
121
- expect(tester).toBe(10)
122
- })
123
- })
121
+ expect(tester).toBe(10);
122
+ });
123
+ });
124
124
 
125
- test('Request 3', async () => {
126
- const semaphore = new Semaphore(3)
125
+ test("Request 3", async () => {
126
+ const semaphore = new Semaphore(3);
127
127
 
128
- let tester = 0
128
+ let tester = 0;
129
129
 
130
130
  semaphore.request(async () => {
131
- await pause(1000)
132
- tester = 20
133
- })
131
+ await pause(1000);
132
+ tester = 20;
133
+ });
134
134
 
135
135
  semaphore.request(async () => {
136
- await pause(500)
137
- tester = 10
138
- })
136
+ await pause(500);
137
+ tester = 10;
138
+ });
139
139
 
140
140
  await semaphore.request(async () => {
141
- expect(tester).toBe(0)
142
- })
143
- })
141
+ expect(tester).toBe(0);
142
+ });
143
+ });
package/lib/index.cjs.js CHANGED
@@ -139,3 +139,4 @@ class Semaphore {
139
139
  }
140
140
 
141
141
  module.exports = Semaphore;
142
+ //# sourceMappingURL=index.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs.js","sources":["../src/index.ts"],"sourcesContent":["class SemaphoreItem {\n private queue: Array<Function>;\n private maxConcurrent: number;\n /**\n * The number of locks.\n */\n public count: number;\n\n constructor(maxConcurrent: number) {\n this.queue = [];\n this.maxConcurrent = maxConcurrent;\n this.count = 0;\n }\n\n get canAcquire(): boolean {\n return this.count < this.maxConcurrent;\n }\n\n acquire(): Promise<void> {\n if (this.canAcquire) {\n this.count++;\n return Promise.resolve();\n } else {\n return new Promise((resolve) => this.queue.push(resolve));\n }\n }\n\n release(): void {\n const resolveFunc = this.queue.shift();\n\n if (resolveFunc) {\n // Give the micro task queue a small break instead of calling resolveFunc() directly\n setTimeout(resolveFunc, 0);\n // resolveFunc()\n } else {\n this.count--;\n }\n }\n}\n\nconst defaultKey = \"_default\";\n\nclass Semaphore {\n private semaphoreInstances: Record<string | number, SemaphoreItem>;\n private maxConcurrent: number;\n\n /**\n *\n * @param {number} [maxConcurrent] The maximum number of concurrent locks.\n */\n constructor(maxConcurrent: number = 1) {\n this.semaphoreInstances = {};\n this.maxConcurrent = maxConcurrent;\n }\n\n private hasSemaphoreInstance(key: string | number = defaultKey) {\n return Boolean(this.semaphoreInstances[key]);\n }\n\n private getSemaphoreInstance(key: string | number = defaultKey) {\n if (!this.hasSemaphoreInstance(key)) {\n this.semaphoreInstances[key] = new SemaphoreItem(this.maxConcurrent);\n }\n return this.semaphoreInstances[key];\n }\n\n /**\n *\n * @param {string | number} [key]- Optional, the semaphore key.\n */\n private tidy(key: string | number = defaultKey): void {\n if (\n this.hasSemaphoreInstance(key) &&\n this.getSemaphoreInstance(key).count == 0\n ) {\n delete this.semaphoreInstances[key];\n }\n }\n\n /**\n * A synchronous function to determine whether a lock can be acquired.\n *\n * @param {string | number} [key]- Optional, the semaphore key.\n * @returns {boolean} Returns true if the lock on `key` can be acquired, false\n * otherwise.\n */\n canAcquire(key: string | number = defaultKey): boolean {\n return this.getSemaphoreInstance(key).canAcquire;\n }\n\n /**\n *\n * @param {string | number} [key]- Optional, the semaphore key.\n */\n acquire(key: string | number = defaultKey) {\n return this.getSemaphoreInstance(key).acquire();\n }\n\n /**\n *\n * @param {string | number} [key]- Optional, the semaphore key.\n */\n release(key: string | number = defaultKey): void {\n this.getSemaphoreInstance(key).release();\n this.tidy(key);\n }\n\n /**\n * The number of active locks. Will always be less or equal to `max`.\n *\n * @param {string | number} [key]- Optional, the semaphore key.\n */\n count(key: string | number = defaultKey): number {\n if (this.hasSemaphoreInstance(key)) {\n return this.getSemaphoreInstance(key).count;\n } else {\n return 0;\n }\n }\n\n /**\n *\n * @param {string | number} [key]- Optional, the semaphore key.\n * @returns {boolean} True if the semaphore and key has locks, false otherwise.\n */\n hasTasks(key: string | number = defaultKey): boolean {\n return this.count(key) > 0;\n }\n\n /**\n *\n * @param {Function<T>} fn The function to execute.\n * @param {string | number} [key]- Optional, the semaphore key.\n * @returns {Promise<T>}\n */\n async request<T>(\n fn: Function,\n key: string | number = defaultKey\n ): Promise<T> {\n try {\n await this.acquire(key);\n return await fn();\n } finally {\n this.release(key);\n }\n }\n\n /**\n * Asynchronously executes `fn` if a lock can be immediately acquired.\n * Otherwise, returns null.\n *\n * @param {Function<T>} fn The function to execute.\n * @param {string | number} [key]- Optional, the semaphore key.\n * @returns {Promise<T>}\n */\n async requestIfAvailable<T>(\n fn: Function,\n key: string | number = defaultKey\n ): Promise<T | null> {\n if (this.canAcquire(key)) {\n return this.request(fn, key);\n } else {\n return null;\n }\n }\n}\n\nexport default Semaphore;\n"],"names":[],"mappings":"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"}
package/lib/index.es.js CHANGED
@@ -137,3 +137,4 @@ class Semaphore {
137
137
  }
138
138
 
139
139
  export { Semaphore as default };
140
+ //# sourceMappingURL=index.es.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.es.js","sources":["../src/index.ts"],"sourcesContent":["class SemaphoreItem {\n private queue: Array<Function>;\n private maxConcurrent: number;\n /**\n * The number of locks.\n */\n public count: number;\n\n constructor(maxConcurrent: number) {\n this.queue = [];\n this.maxConcurrent = maxConcurrent;\n this.count = 0;\n }\n\n get canAcquire(): boolean {\n return this.count < this.maxConcurrent;\n }\n\n acquire(): Promise<void> {\n if (this.canAcquire) {\n this.count++;\n return Promise.resolve();\n } else {\n return new Promise((resolve) => this.queue.push(resolve));\n }\n }\n\n release(): void {\n const resolveFunc = this.queue.shift();\n\n if (resolveFunc) {\n // Give the micro task queue a small break instead of calling resolveFunc() directly\n setTimeout(resolveFunc, 0);\n // resolveFunc()\n } else {\n this.count--;\n }\n }\n}\n\nconst defaultKey = \"_default\";\n\nclass Semaphore {\n private semaphoreInstances: Record<string | number, SemaphoreItem>;\n private maxConcurrent: number;\n\n /**\n *\n * @param {number} [maxConcurrent] The maximum number of concurrent locks.\n */\n constructor(maxConcurrent: number = 1) {\n this.semaphoreInstances = {};\n this.maxConcurrent = maxConcurrent;\n }\n\n private hasSemaphoreInstance(key: string | number = defaultKey) {\n return Boolean(this.semaphoreInstances[key]);\n }\n\n private getSemaphoreInstance(key: string | number = defaultKey) {\n if (!this.hasSemaphoreInstance(key)) {\n this.semaphoreInstances[key] = new SemaphoreItem(this.maxConcurrent);\n }\n return this.semaphoreInstances[key];\n }\n\n /**\n *\n * @param {string | number} [key]- Optional, the semaphore key.\n */\n private tidy(key: string | number = defaultKey): void {\n if (\n this.hasSemaphoreInstance(key) &&\n this.getSemaphoreInstance(key).count == 0\n ) {\n delete this.semaphoreInstances[key];\n }\n }\n\n /**\n * A synchronous function to determine whether a lock can be acquired.\n *\n * @param {string | number} [key]- Optional, the semaphore key.\n * @returns {boolean} Returns true if the lock on `key` can be acquired, false\n * otherwise.\n */\n canAcquire(key: string | number = defaultKey): boolean {\n return this.getSemaphoreInstance(key).canAcquire;\n }\n\n /**\n *\n * @param {string | number} [key]- Optional, the semaphore key.\n */\n acquire(key: string | number = defaultKey) {\n return this.getSemaphoreInstance(key).acquire();\n }\n\n /**\n *\n * @param {string | number} [key]- Optional, the semaphore key.\n */\n release(key: string | number = defaultKey): void {\n this.getSemaphoreInstance(key).release();\n this.tidy(key);\n }\n\n /**\n * The number of active locks. Will always be less or equal to `max`.\n *\n * @param {string | number} [key]- Optional, the semaphore key.\n */\n count(key: string | number = defaultKey): number {\n if (this.hasSemaphoreInstance(key)) {\n return this.getSemaphoreInstance(key).count;\n } else {\n return 0;\n }\n }\n\n /**\n *\n * @param {string | number} [key]- Optional, the semaphore key.\n * @returns {boolean} True if the semaphore and key has locks, false otherwise.\n */\n hasTasks(key: string | number = defaultKey): boolean {\n return this.count(key) > 0;\n }\n\n /**\n *\n * @param {Function<T>} fn The function to execute.\n * @param {string | number} [key]- Optional, the semaphore key.\n * @returns {Promise<T>}\n */\n async request<T>(\n fn: Function,\n key: string | number = defaultKey\n ): Promise<T> {\n try {\n await this.acquire(key);\n return await fn();\n } finally {\n this.release(key);\n }\n }\n\n /**\n * Asynchronously executes `fn` if a lock can be immediately acquired.\n * Otherwise, returns null.\n *\n * @param {Function<T>} fn The function to execute.\n * @param {string | number} [key]- Optional, the semaphore key.\n * @returns {Promise<T>}\n */\n async requestIfAvailable<T>(\n fn: Function,\n key: string | number = defaultKey\n ): Promise<T | null> {\n if (this.canAcquire(key)) {\n return this.request(fn, key);\n } else {\n return null;\n }\n }\n}\n\nexport default Semaphore;\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chriscdn/promise-semaphore",
3
- "version": "2.0.0",
3
+ "version": "2.0.2",
4
4
  "description": "Limit or throttle the simultaneous execution of asynchronous code in separate iterations of the event loop.",
5
5
  "main": "lib/index.cjs.js",
6
6
  "module": "lib/index.es.js",
@@ -14,14 +14,14 @@
14
14
  "test": "jest"
15
15
  },
16
16
  "devDependencies": {
17
- "@types/jest": "^29.4.0",
18
- "esbuild": "^0.17.10",
19
- "jest": "^29.4.3",
20
- "rollup": "^3.17.3",
21
- "rollup-plugin-dts": "^5.2.0",
17
+ "@types/jest": "^29.5.4",
18
+ "esbuild": "^0.19.2",
19
+ "jest": "^29.7.0",
20
+ "rollup": "^3.29.1",
21
+ "rollup-plugin-dts": "^6.0.2",
22
22
  "rollup-plugin-esbuild": "^5.0.0",
23
- "ts-jest": "^29.0.5",
24
- "typescript": "^4.9.5"
23
+ "ts-jest": "^29.1.1",
24
+ "typescript": "^5.2.2"
25
25
  },
26
26
  "keywords": [
27
27
  "promise",
package/rollup.config.mjs CHANGED
@@ -12,8 +12,7 @@ export default [
12
12
  {
13
13
  file: pkg.main,
14
14
  format: 'cjs',
15
- // sourcemap: true,
16
- // exports: 'default',
15
+ sourcemap: true,
17
16
  },
18
17
  ],
19
18
  },
@@ -24,8 +23,7 @@ export default [
24
23
  {
25
24
  file: pkg.module,
26
25
  format: 'es',
27
- // sourcemap: true,
28
- // exports: 'default',
26
+ sourcemap: true,
29
27
  },
30
28
  ],
31
29
  },
@@ -33,8 +31,7 @@ export default [
33
31
  input,
34
32
  plugins: [dts()],
35
33
  output: {
36
- file: 'lib/index.d.ts',
37
- format: 'es',
34
+ file: pkg.types,
38
35
  },
39
36
  },
40
37
  ]
package/src/index.ts CHANGED
@@ -1,67 +1,67 @@
1
1
  class SemaphoreItem {
2
- private queue: Array<Function>
3
- private maxConcurrent: number
2
+ private queue: Array<Function>;
3
+ private maxConcurrent: number;
4
4
  /**
5
5
  * The number of locks.
6
6
  */
7
- public count: number
7
+ public count: number;
8
8
 
9
9
  constructor(maxConcurrent: number) {
10
- this.queue = []
11
- this.maxConcurrent = maxConcurrent
12
- this.count = 0
10
+ this.queue = [];
11
+ this.maxConcurrent = maxConcurrent;
12
+ this.count = 0;
13
13
  }
14
14
 
15
15
  get canAcquire(): boolean {
16
- return this.count < this.maxConcurrent
16
+ return this.count < this.maxConcurrent;
17
17
  }
18
18
 
19
19
  acquire(): Promise<void> {
20
20
  if (this.canAcquire) {
21
- this.count++
22
- return Promise.resolve()
21
+ this.count++;
22
+ return Promise.resolve();
23
23
  } else {
24
- return new Promise((resolve) => this.queue.push(resolve))
24
+ return new Promise((resolve) => this.queue.push(resolve));
25
25
  }
26
26
  }
27
27
 
28
28
  release(): void {
29
- const resolveFunc = this.queue.shift()
29
+ const resolveFunc = this.queue.shift();
30
30
 
31
31
  if (resolveFunc) {
32
32
  // Give the micro task queue a small break instead of calling resolveFunc() directly
33
- setTimeout(resolveFunc, 0)
33
+ setTimeout(resolveFunc, 0);
34
34
  // resolveFunc()
35
35
  } else {
36
- this.count--
36
+ this.count--;
37
37
  }
38
38
  }
39
39
  }
40
40
 
41
- const defaultKey = '_default'
41
+ const defaultKey = "_default";
42
42
 
43
43
  class Semaphore {
44
- private semaphoreInstances: Record<string | number, SemaphoreItem>
45
- private maxConcurrent: number
44
+ private semaphoreInstances: Record<string | number, SemaphoreItem>;
45
+ private maxConcurrent: number;
46
46
 
47
47
  /**
48
48
  *
49
49
  * @param {number} [maxConcurrent] The maximum number of concurrent locks.
50
50
  */
51
51
  constructor(maxConcurrent: number = 1) {
52
- this.semaphoreInstances = {}
53
- this.maxConcurrent = maxConcurrent
52
+ this.semaphoreInstances = {};
53
+ this.maxConcurrent = maxConcurrent;
54
54
  }
55
55
 
56
56
  private hasSemaphoreInstance(key: string | number = defaultKey) {
57
- return Boolean(this.semaphoreInstances[key])
57
+ return Boolean(this.semaphoreInstances[key]);
58
58
  }
59
59
 
60
60
  private getSemaphoreInstance(key: string | number = defaultKey) {
61
61
  if (!this.hasSemaphoreInstance(key)) {
62
- this.semaphoreInstances[key] = new SemaphoreItem(this.maxConcurrent)
62
+ this.semaphoreInstances[key] = new SemaphoreItem(this.maxConcurrent);
63
63
  }
64
- return this.semaphoreInstances[key]
64
+ return this.semaphoreInstances[key];
65
65
  }
66
66
 
67
67
  /**
@@ -73,7 +73,7 @@ class Semaphore {
73
73
  this.hasSemaphoreInstance(key) &&
74
74
  this.getSemaphoreInstance(key).count == 0
75
75
  ) {
76
- delete this.semaphoreInstances[key]
76
+ delete this.semaphoreInstances[key];
77
77
  }
78
78
  }
79
79
 
@@ -85,7 +85,7 @@ class Semaphore {
85
85
  * otherwise.
86
86
  */
87
87
  canAcquire(key: string | number = defaultKey): boolean {
88
- return this.getSemaphoreInstance(key).canAcquire
88
+ return this.getSemaphoreInstance(key).canAcquire;
89
89
  }
90
90
 
91
91
  /**
@@ -93,7 +93,7 @@ class Semaphore {
93
93
  * @param {string | number} [key]- Optional, the semaphore key.
94
94
  */
95
95
  acquire(key: string | number = defaultKey) {
96
- return this.getSemaphoreInstance(key).acquire()
96
+ return this.getSemaphoreInstance(key).acquire();
97
97
  }
98
98
 
99
99
  /**
@@ -101,8 +101,8 @@ class Semaphore {
101
101
  * @param {string | number} [key]- Optional, the semaphore key.
102
102
  */
103
103
  release(key: string | number = defaultKey): void {
104
- this.getSemaphoreInstance(key).release()
105
- this.tidy(key)
104
+ this.getSemaphoreInstance(key).release();
105
+ this.tidy(key);
106
106
  }
107
107
 
108
108
  /**
@@ -112,9 +112,9 @@ class Semaphore {
112
112
  */
113
113
  count(key: string | number = defaultKey): number {
114
114
  if (this.hasSemaphoreInstance(key)) {
115
- return this.getSemaphoreInstance(key).count
115
+ return this.getSemaphoreInstance(key).count;
116
116
  } else {
117
- return 0
117
+ return 0;
118
118
  }
119
119
  }
120
120
 
@@ -124,7 +124,7 @@ class Semaphore {
124
124
  * @returns {boolean} True if the semaphore and key has locks, false otherwise.
125
125
  */
126
126
  hasTasks(key: string | number = defaultKey): boolean {
127
- return this.count(key) > 0
127
+ return this.count(key) > 0;
128
128
  }
129
129
 
130
130
  /**
@@ -138,10 +138,10 @@ class Semaphore {
138
138
  key: string | number = defaultKey
139
139
  ): Promise<T> {
140
140
  try {
141
- await this.acquire(key)
142
- return await fn()
141
+ await this.acquire(key);
142
+ return await fn();
143
143
  } finally {
144
- this.release(key)
144
+ this.release(key);
145
145
  }
146
146
  }
147
147
 
@@ -158,11 +158,11 @@ class Semaphore {
158
158
  key: string | number = defaultKey
159
159
  ): Promise<T | null> {
160
160
  if (this.canAcquire(key)) {
161
- return this.request(fn, key)
161
+ return this.request(fn, key);
162
162
  } else {
163
- return null
163
+ return null;
164
164
  }
165
165
  }
166
166
  }
167
167
 
168
- export default Semaphore
168
+ export default Semaphore;
package/.prettierrc DELETED
@@ -1,4 +0,0 @@
1
- {
2
- "semi": false,
3
- "singleQuote": true
4
- }