diff --git a/package.json b/package.json index 798803a..12dcc00 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "async-sema", - "version": "3.1.1", + "version": "3.1.2", "description": "Semaphore using `async` and `await`", "repository": { "type": "git", @@ -29,13 +29,13 @@ "test": "jest" }, "devDependencies": { - "@types/jest": "27.0.1", + "@types/jest": "29.2.3", "@types/node": "16.6.1", - "jest": "27.0.6", + "jest": "29.3.1", "lint-staged": "11.1.2", "pre-commit": "1.2.2", "prettier": "2.3.2", - "ts-jest": "27.0.4", + "ts-jest": "29.0.3", "typescript": "4.3.5" }, "pre-commit": "lint:staged", diff --git a/src/index.ts b/src/index.ts index d584c64..cc54bac 100644 --- a/src/index.ts +++ b/src/index.ts @@ -30,11 +30,11 @@ function getCapacity(capacity: number) { // Deque is based on https://github.com/petkaantonov/deque/blob/master/js/deque.js // Released under the MIT License: https://github.com/petkaantonov/deque/blob/6ef4b6400ad3ba82853fdcc6531a38eb4f78c18c/LICENSE -class Deque { +class Deque { private _capacity: number; private _length: number; private _front: number; - private arr: Array; + private arr: Array; constructor(capacity: number) { this._capacity = getCapacity(capacity); @@ -43,7 +43,7 @@ class Deque { this.arr = []; } - push(item: any): number { + push(item: T): number { const length = this._length; this.checkCapacity(length + 1); @@ -54,7 +54,7 @@ class Deque { return length + 1; } - pop() { + pop(): T | void { const length = this._length; if (length === 0) { return void 0; @@ -109,14 +109,17 @@ function isFn(x: any) { return typeof x === 'function'; } -function defaultInit() { - return '1'; +function defaultInit(): T { + return '1' as any; } -export class Sema { +export class Sema { private nrTokens: number; - private free: Deque; - private waiting: Deque; + private free: Deque; + private waiting: Deque<{ + resolve: (value: T | PromiseLike) => void; + reject: (reason?: any) => void; + }>; private releaseEmitter: EventEmitter; private noTokens: boolean; private pauseFn?: () => void; @@ -152,7 +155,7 @@ export class Sema { this.resumeFn = resumeFn; this.paused = false; - this.releaseEmitter.on('release', (token) => { + this.releaseEmitter.on('release', (token: T) => { const p = this.waiting.shift(); if (p) { p.resolve(token); @@ -171,18 +174,18 @@ export class Sema { } } - tryAcquire(): any | undefined { + tryAcquire(): T | void { return this.free.pop(); } - async acquire(): Promise { + async acquire(): Promise { let token = this.tryAcquire(); if (token !== void 0) { return token; } - return new Promise((resolve, reject) => { + return new Promise((resolve, reject) => { if (this.pauseFn && !this.paused) { this.paused = true; this.pauseFn(); @@ -192,11 +195,11 @@ export class Sema { }); } - release(token?: any): void { + release(token?: T): void { this.releaseEmitter.emit('release', this.noTokens ? '1' : token); } - drain(): Promise { + drain(): Promise { const a = new Array(this.nrTokens); for (let i = 0; i < this.nrTokens; i++) { a[i] = this.acquire();