@chriscdn/promise-semaphore 2.0.11 → 2.0.12

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/lib/index.d.ts CHANGED
@@ -53,6 +53,13 @@ declare class Semaphore {
53
53
  * @returns {Promise<T>}
54
54
  */
55
55
  requestIfAvailable<T>(fn: Function, key?: string | number): Promise<T | null>;
56
+ /**
57
+ * Wait until the count on `key` is 0 and then resolve.
58
+ *
59
+ * @param key
60
+ * @returns
61
+ */
56
62
  wait(key?: string | number): Promise<void>;
57
63
  }
58
64
  export default Semaphore;
65
+ export { Semaphore };
@@ -1,2 +1,2 @@
1
- function e(e){var t=function(e){if("object"!=typeof e||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var n=t.call(e,"string");if("object"!=typeof n)return n;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e);return"symbol"==typeof t?t:t+""}var t=/*#__PURE__*/function(){function t(e){this.queue=void 0,this.waitQueue=void 0,this.maxConcurrent=void 0,this.count=void 0,this.queue=[],this.waitQueue=[],this.maxConcurrent=e,this.count=0}var n,r,i=t.prototype;return i.incrementCount=function(){this.count++},i.decrementCount=function(){this.count--,0===this.count&&(this.waitQueue.forEach(function(e){return e()}),this.waitQueue=[])},i.acquire=function(){var e=this;return this.canAcquire?(this.incrementCount(),Promise.resolve()):new Promise(function(t){return e.queue.push(t)})},i.release=function(){var e=this.queue.shift();e?setTimeout(e,0):this.decrementCount()},i.wait=function(){var e=this;return new Promise(function(t){return e.waitQueue.push(t)})},n=t,(r=[{key:"canAcquire",get:function(){return this.count<this.maxConcurrent}}])&&function(t,n){for(var r=0;r<n.length;r++){var i=n[r];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(t,e(i.key),i)}}(n.prototype,r),Object.defineProperty(n,"prototype",{writable:!1}),n}(),n="_default";module.exports=/*#__PURE__*/function(){function e(e){void 0===e&&(e=1),this.semaphoreInstances=void 0,this.maxConcurrent=void 0,this.semaphoreInstances={},this.maxConcurrent=e}var r=e.prototype;return r.hasSemaphoreInstance=function(e){return void 0===e&&(e=n),Boolean(this.semaphoreInstances[e])},r.getSemaphoreInstance=function(e){return void 0===e&&(e=n),this.hasSemaphoreInstance(e)||(this.semaphoreInstances[e]=new t(this.maxConcurrent)),this.semaphoreInstances[e]},r.tidy=function(e){void 0===e&&(e=n),this.hasSemaphoreInstance(e)&&0===this.getSemaphoreInstance(e).count&&delete this.semaphoreInstances[e]},r.canAcquire=function(e){return void 0===e&&(e=n),this.getSemaphoreInstance(e).canAcquire},r.acquire=function(e){return void 0===e&&(e=n),this.getSemaphoreInstance(e).acquire()},r.release=function(e){void 0===e&&(e=n),this.getSemaphoreInstance(e).release(),this.tidy(e)},r.count=function(e){return void 0===e&&(e=n),this.hasSemaphoreInstance(e)?this.getSemaphoreInstance(e).count:0},r.hasTasks=function(e){return void 0===e&&(e=n),this.count(e)>0},r.request=function(e,t){void 0===t&&(t=n);try{var r=this;return Promise.resolve(function(n,i){try{var o=Promise.resolve(r.acquire(t)).then(function(){return Promise.resolve(e())})}catch(e){return i(!0,e)}return o&&o.then?o.then(i.bind(null,!1),i.bind(null,!0)):i(!1,o)}(0,function(e,n){if(r.release(t),e)throw n;return n}))}catch(e){return Promise.reject(e)}},r.requestIfAvailable=function(e,t){void 0===t&&(t=n);try{return this.canAcquire(t)?Promise.resolve(this.request(e,t)):Promise.resolve(null)}catch(e){return Promise.reject(e)}},r.wait=function(e){void 0===e&&(e=n);try{return this.hasTasks(e)?Promise.resolve(this.getSemaphoreInstance(e).wait()):Promise.resolve()}catch(e){return Promise.reject(e)}},e}();
1
+ function e(e){var t=function(e){if("object"!=typeof e||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var n=t.call(e,"string");if("object"!=typeof n)return n;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e);return"symbol"==typeof t?t:t+""}var t=/*#__PURE__*/function(){function t(e){this.queue=void 0,this.waitQueue=void 0,this.maxConcurrent=void 0,this.count=void 0,this.queue=[],this.waitQueue=[],this.maxConcurrent=e,this.count=0}var n,r,i=t.prototype;return i.incrementCount=function(){this.count++},i.decrementCount=function(){this.count--,0===this.count&&(this.waitQueue.forEach(function(e){return e()}),this.waitQueue=[])},i.acquire=function(){var e=this;return this.canAcquire?(this.incrementCount(),Promise.resolve()):new Promise(function(t){return e.queue.push(t)})},i.release=function(){var e=this.queue.shift();e?setTimeout(e,0):this.decrementCount()},i.wait=function(){var e=this;return new Promise(function(t){return e.waitQueue.push(t)})},n=t,(r=[{key:"canAcquire",get:function(){return this.count<this.maxConcurrent}}])&&function(t,n){for(var r=0;r<n.length;r++){var i=n[r];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(t,e(i.key),i)}}(n.prototype,r),Object.defineProperty(n,"prototype",{writable:!1}),n}(),n="_default",r=/*#__PURE__*/function(){function e(e){void 0===e&&(e=1),this.semaphoreInstances=void 0,this.maxConcurrent=void 0,this.semaphoreInstances={},this.maxConcurrent=e}var r=e.prototype;return r.hasSemaphoreInstance=function(e){return void 0===e&&(e=n),Boolean(this.semaphoreInstances[e])},r.getSemaphoreInstance=function(e){return void 0===e&&(e=n),this.hasSemaphoreInstance(e)||(this.semaphoreInstances[e]=new t(this.maxConcurrent)),this.semaphoreInstances[e]},r.tidy=function(e){void 0===e&&(e=n),this.hasSemaphoreInstance(e)&&0===this.getSemaphoreInstance(e).count&&delete this.semaphoreInstances[e]},r.canAcquire=function(e){return void 0===e&&(e=n),this.getSemaphoreInstance(e).canAcquire},r.acquire=function(e){return void 0===e&&(e=n),this.getSemaphoreInstance(e).acquire()},r.release=function(e){void 0===e&&(e=n),this.getSemaphoreInstance(e).release(),this.tidy(e)},r.count=function(e){return void 0===e&&(e=n),this.hasSemaphoreInstance(e)?this.getSemaphoreInstance(e).count:0},r.hasTasks=function(e){return void 0===e&&(e=n),this.count(e)>0},r.request=function(e,t){void 0===t&&(t=n);try{var r=this;return Promise.resolve(function(n,i){try{var o=Promise.resolve(r.acquire(t)).then(function(){return Promise.resolve(e())})}catch(e){return i(!0,e)}return o&&o.then?o.then(i.bind(null,!1),i.bind(null,!0)):i(!1,o)}(0,function(e,n){if(r.release(t),e)throw n;return n}))}catch(e){return Promise.reject(e)}},r.requestIfAvailable=function(e,t){void 0===t&&(t=n);try{return this.canAcquire(t)?Promise.resolve(this.request(e,t)):Promise.resolve(null)}catch(e){return Promise.reject(e)}},r.wait=function(e){void 0===e&&(e=n);try{return this.hasTasks(e)?Promise.resolve(this.getSemaphoreInstance(e).wait()):Promise.resolve()}catch(e){return Promise.reject(e)}},e}();exports.Semaphore=r,exports.default=r;
2
2
  //# sourceMappingURL=promise-semaphore.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"promise-semaphore.cjs","sources":["../src/index.ts"],"sourcesContent":["class SemaphoreItem {\n private queue: Array<Function>;\n private waitQueue: Array<Function>;\n private maxConcurrent: number;\n\n /**\n * The number of locks.\n */\n public count: number;\n\n constructor(maxConcurrent: number) {\n this.queue = [];\n this.waitQueue = [];\n this.maxConcurrent = maxConcurrent;\n this.count = 0;\n }\n\n get canAcquire(): boolean {\n return this.count < this.maxConcurrent;\n }\n\n private incrementCount() {\n this.count++;\n }\n\n private decrementCount() {\n this.count--;\n\n if (this.count === 0) {\n this.waitQueue.forEach((resolve) => resolve());\n this.waitQueue = [];\n }\n }\n\n acquire(): Promise<void> {\n if (this.canAcquire) {\n this.incrementCount();\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 } else {\n this.decrementCount();\n }\n }\n\n wait(): Promise<void> {\n return new Promise((resolve) => this.waitQueue.push(resolve));\n }\n}\n\nconst defaultKey = \"_default\";\n\nclass Semaphore {\n private semaphoreInstances: Record<string | number, SemaphoreItem>;\n private maxConcurrent: number;\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 * @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 * @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 * @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 * @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 * @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 async wait(key: string | number = defaultKey) {\n if (this.hasTasks(key)) {\n return this.getSemaphoreInstance(key).wait();\n } else {\n return Promise.resolve();\n }\n }\n}\n\nexport default Semaphore;\n"],"names":["SemaphoreItem","maxConcurrent","queue","waitQueue","count","this","_proto","prototype","incrementCount","decrementCount","forEach","resolve","acquire","_this","canAcquire","Promise","push","release","resolveFunc","shift","setTimeout","wait","_this2","key","get","defaultKey","Semaphore","semaphoreInstances","_proto2","hasSemaphoreInstance","Boolean","getSemaphoreInstance","tidy","hasTasks","request","fn","_this3","then","_finallyRethrows","_wasThrown","_result","e","reject","requestIfAvailable"],"mappings":"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"}
1
+ {"version":3,"file":"promise-semaphore.cjs","sources":["../src/index.ts"],"sourcesContent":["class SemaphoreItem {\n private queue: Array<Function>;\n private waitQueue: Array<Function>;\n private maxConcurrent: number;\n\n /**\n * The number of locks.\n */\n public count: number;\n\n constructor(maxConcurrent: number) {\n this.queue = [];\n this.waitQueue = [];\n this.maxConcurrent = maxConcurrent;\n this.count = 0;\n }\n\n get canAcquire(): boolean {\n return this.count < this.maxConcurrent;\n }\n\n private incrementCount() {\n this.count++;\n }\n\n private decrementCount() {\n this.count--;\n\n if (this.count === 0) {\n this.waitQueue.forEach((resolve) => resolve());\n this.waitQueue = [];\n }\n }\n\n acquire(): Promise<void> {\n if (this.canAcquire) {\n this.incrementCount();\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 } else {\n this.decrementCount();\n }\n }\n\n wait(): Promise<void> {\n return new Promise((resolve) => this.waitQueue.push(resolve));\n }\n}\n\nconst defaultKey = \"_default\";\n\nclass Semaphore {\n private semaphoreInstances: Record<string | number, SemaphoreItem>;\n private maxConcurrent: number;\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 * @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 * @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 * @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 * @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 * @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 /**\n * Wait until the count on `key` is 0 and then resolve.\n *\n * @param key\n * @returns\n */\n async wait(key: string | number = defaultKey) {\n if (this.hasTasks(key)) {\n return this.getSemaphoreInstance(key).wait();\n } else {\n return Promise.resolve();\n }\n }\n\n // globalCount() {\n // return Object.values(this.semaphoreInstances).reduce(\n // (a, instance) => a + instance.count,\n // 0,\n // );\n // }\n}\n\nexport default Semaphore;\nexport { Semaphore };\n"],"names":["SemaphoreItem","maxConcurrent","queue","waitQueue","count","this","_proto","prototype","incrementCount","decrementCount","forEach","resolve","acquire","_this","canAcquire","Promise","push","release","resolveFunc","shift","setTimeout","wait","_this2","key","get","defaultKey","Semaphore","semaphoreInstances","_proto2","hasSemaphoreInstance","Boolean","getSemaphoreInstance","tidy","hasTasks","request","fn","_this3","then","_finallyRethrows","_wasThrown","_result","e","reject","requestIfAvailable"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- class e{constructor(e){this.queue=void 0,this.waitQueue=void 0,this.maxConcurrent=void 0,this.count=void 0,this.queue=[],this.waitQueue=[],this.maxConcurrent=e,this.count=0}get canAcquire(){return this.count<this.maxConcurrent}incrementCount(){this.count++}decrementCount(){this.count--,0===this.count&&(this.waitQueue.forEach(e=>e()),this.waitQueue=[])}acquire(){return this.canAcquire?(this.incrementCount(),Promise.resolve()):new Promise(e=>this.queue.push(e))}release(){const e=this.queue.shift();e?setTimeout(e,0):this.decrementCount()}wait(){return new Promise(e=>this.waitQueue.push(e))}}const t="_default";class s{constructor(e=1){this.semaphoreInstances=void 0,this.maxConcurrent=void 0,this.semaphoreInstances={},this.maxConcurrent=e}hasSemaphoreInstance(e=t){return Boolean(this.semaphoreInstances[e])}getSemaphoreInstance(s=t){return this.hasSemaphoreInstance(s)||(this.semaphoreInstances[s]=new e(this.maxConcurrent)),this.semaphoreInstances[s]}tidy(e=t){this.hasSemaphoreInstance(e)&&0===this.getSemaphoreInstance(e).count&&delete this.semaphoreInstances[e]}canAcquire(e=t){return this.getSemaphoreInstance(e).canAcquire}acquire(e=t){return this.getSemaphoreInstance(e).acquire()}release(e=t){this.getSemaphoreInstance(e).release(),this.tidy(e)}count(e=t){return this.hasSemaphoreInstance(e)?this.getSemaphoreInstance(e).count:0}hasTasks(e=t){return this.count(e)>0}async request(e,s=t){try{return await this.acquire(s),await e()}finally{this.release(s)}}async requestIfAvailable(e,s=t){return this.canAcquire(s)?this.request(e,s):null}async wait(e=t){return this.hasTasks(e)?this.getSemaphoreInstance(e).wait():Promise.resolve()}}export{s as default};
1
+ class e{constructor(e){this.queue=void 0,this.waitQueue=void 0,this.maxConcurrent=void 0,this.count=void 0,this.queue=[],this.waitQueue=[],this.maxConcurrent=e,this.count=0}get canAcquire(){return this.count<this.maxConcurrent}incrementCount(){this.count++}decrementCount(){this.count--,0===this.count&&(this.waitQueue.forEach(e=>e()),this.waitQueue=[])}acquire(){return this.canAcquire?(this.incrementCount(),Promise.resolve()):new Promise(e=>this.queue.push(e))}release(){const e=this.queue.shift();e?setTimeout(e,0):this.decrementCount()}wait(){return new Promise(e=>this.waitQueue.push(e))}}const t="_default";class s{constructor(e=1){this.semaphoreInstances=void 0,this.maxConcurrent=void 0,this.semaphoreInstances={},this.maxConcurrent=e}hasSemaphoreInstance(e=t){return Boolean(this.semaphoreInstances[e])}getSemaphoreInstance(s=t){return this.hasSemaphoreInstance(s)||(this.semaphoreInstances[s]=new e(this.maxConcurrent)),this.semaphoreInstances[s]}tidy(e=t){this.hasSemaphoreInstance(e)&&0===this.getSemaphoreInstance(e).count&&delete this.semaphoreInstances[e]}canAcquire(e=t){return this.getSemaphoreInstance(e).canAcquire}acquire(e=t){return this.getSemaphoreInstance(e).acquire()}release(e=t){this.getSemaphoreInstance(e).release(),this.tidy(e)}count(e=t){return this.hasSemaphoreInstance(e)?this.getSemaphoreInstance(e).count:0}hasTasks(e=t){return this.count(e)>0}async request(e,s=t){try{return await this.acquire(s),await e()}finally{this.release(s)}}async requestIfAvailable(e,s=t){return this.canAcquire(s)?this.request(e,s):null}async wait(e=t){return this.hasTasks(e)?this.getSemaphoreInstance(e).wait():Promise.resolve()}}export{s as Semaphore,s as default};
2
2
  //# sourceMappingURL=promise-semaphore.modern.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"promise-semaphore.modern.js","sources":["../src/index.ts"],"sourcesContent":["class SemaphoreItem {\n private queue: Array<Function>;\n private waitQueue: Array<Function>;\n private maxConcurrent: number;\n\n /**\n * The number of locks.\n */\n public count: number;\n\n constructor(maxConcurrent: number) {\n this.queue = [];\n this.waitQueue = [];\n this.maxConcurrent = maxConcurrent;\n this.count = 0;\n }\n\n get canAcquire(): boolean {\n return this.count < this.maxConcurrent;\n }\n\n private incrementCount() {\n this.count++;\n }\n\n private decrementCount() {\n this.count--;\n\n if (this.count === 0) {\n this.waitQueue.forEach((resolve) => resolve());\n this.waitQueue = [];\n }\n }\n\n acquire(): Promise<void> {\n if (this.canAcquire) {\n this.incrementCount();\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 } else {\n this.decrementCount();\n }\n }\n\n wait(): Promise<void> {\n return new Promise((resolve) => this.waitQueue.push(resolve));\n }\n}\n\nconst defaultKey = \"_default\";\n\nclass Semaphore {\n private semaphoreInstances: Record<string | number, SemaphoreItem>;\n private maxConcurrent: number;\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 * @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 * @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 * @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 * @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 * @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 async wait(key: string | number = defaultKey) {\n if (this.hasTasks(key)) {\n return this.getSemaphoreInstance(key).wait();\n } else {\n return Promise.resolve();\n }\n }\n}\n\nexport default Semaphore;\n"],"names":["SemaphoreItem","constructor","maxConcurrent","this","queue","waitQueue","count","canAcquire","incrementCount","decrementCount","forEach","resolve","acquire","Promise","push","release","resolveFunc","shift","setTimeout","wait","defaultKey","Semaphore","semaphoreInstances","hasSemaphoreInstance","key","Boolean","getSemaphoreInstance","tidy","hasTasks","request","fn","requestIfAvailable"],"mappings":"AAAA,MAAMA,EAUJC,WAAAA,CAAYC,GAAqBC,KATzBC,WAAK,EAAAD,KACLE,eAAS,EAAAF,KACTD,mBAKDI,EAAAA,KAAAA,WAGL,EAAAH,KAAKC,MAAQ,GACbD,KAAKE,UAAY,GACjBF,KAAKD,cAAgBA,EACrBC,KAAKG,MAAQ,CACf,CAEA,cAAIC,GACF,YAAYD,MAAQH,KAAKD,aAC3B,CAEQM,cAAAA,GACNL,KAAKG,OACP,CAEQG,cAAAA,GACNN,KAAKG,QAEc,IAAfH,KAAKG,QACPH,KAAKE,UAAUK,QAASC,GAAYA,KACpCR,KAAKE,UAAY,GAErB,CAEAO,OAAAA,GACE,OAAIT,KAAKI,YACPJ,KAAKK,iBACEK,QAAQF,WAEJ,IAAAE,QAASF,GAAYR,KAAKC,MAAMU,KAAKH,GAEpD,CAEAI,OAAAA,GACE,MAAMC,EAAcb,KAAKC,MAAMa,QAE3BD,EAEFE,WAAWF,EAAa,GAExBb,KAAKM,gBAET,CAEAU,IAAAA,GACE,OAAW,IAAAN,QAASF,GAAYR,KAAKE,UAAUS,KAAKH,GACtD,EAGF,MAAMS,EAAa,WAEnB,MAAMC,EAOJpB,WAAAA,CAAYC,EAAwB,GAN5BoB,KAAAA,wBACApB,EAAAA,KAAAA,qBAMNC,KAAKmB,mBAAqB,GAC1BnB,KAAKD,cAAgBA,CACvB,CAEQqB,oBAAAA,CAAqBC,EAAuBJ,GAClD,OAAOK,QAAQtB,KAAKmB,mBAAmBE,GACzC,CAEQE,oBAAAA,CAAqBF,EAAuBJ,GAIlD,OAHKjB,KAAKoB,qBAAqBC,KAC7BrB,KAAKmB,mBAAmBE,GAAO,IAAIxB,EAAcG,KAAKD,gBAE7CC,KAACmB,mBAAmBE,EACjC,CAKQG,IAAAA,CAAKH,EAAuBJ,GAEhCjB,KAAKoB,qBAAqBC,IACe,IAAzCrB,KAAKuB,qBAAqBF,GAAKlB,cAEpBH,KAACmB,mBAAmBE,EAEnC,CASAjB,UAAAA,CAAWiB,EAAuBJ,GAChC,OAAWjB,KAACuB,qBAAqBF,GAAKjB,UACxC,CAKAK,OAAAA,CAAQY,EAAuBJ,GAC7B,OAAWjB,KAACuB,qBAAqBF,GAAKZ,SACxC,CAKAG,OAAAA,CAAQS,EAAuBJ,GAC7BjB,KAAKuB,qBAAqBF,GAAKT,UAC/BZ,KAAKwB,KAAKH,EACZ,CAOAlB,KAAAA,CAAMkB,EAAuBJ,GAC3B,OAAIjB,KAAKoB,qBAAqBC,GACrBrB,KAAKuB,qBAAqBF,GAAKlB,MAGvC,CACH,CAMAsB,QAAAA,CAASJ,EAAuBJ,GAC9B,OAAOjB,KAAKG,MAAMkB,GAAO,CAC3B,CAOA,aAAMK,CACJC,EACAN,EAAuBJ,GAEvB,IAEE,aADMjB,KAAKS,QAAQY,SACNM,GACd,CAAA,QACC3B,KAAKY,QAAQS,EACd,CACH,CAUA,wBAAMO,CACJD,EACAN,EAAuBJ,GAEvB,OAAIjB,KAAKI,WAAWiB,GACPrB,KAAC0B,QAAQC,EAAIN,GAEjB,IAEX,CAEA,UAAML,CAAKK,EAAuBJ,GAChC,OAAIjB,KAAKyB,SAASJ,GACLrB,KAACuB,qBAAqBF,GAAKL,OAE/BN,QAAQF,SAEnB"}
1
+ {"version":3,"file":"promise-semaphore.modern.js","sources":["../src/index.ts"],"sourcesContent":["class SemaphoreItem {\n private queue: Array<Function>;\n private waitQueue: Array<Function>;\n private maxConcurrent: number;\n\n /**\n * The number of locks.\n */\n public count: number;\n\n constructor(maxConcurrent: number) {\n this.queue = [];\n this.waitQueue = [];\n this.maxConcurrent = maxConcurrent;\n this.count = 0;\n }\n\n get canAcquire(): boolean {\n return this.count < this.maxConcurrent;\n }\n\n private incrementCount() {\n this.count++;\n }\n\n private decrementCount() {\n this.count--;\n\n if (this.count === 0) {\n this.waitQueue.forEach((resolve) => resolve());\n this.waitQueue = [];\n }\n }\n\n acquire(): Promise<void> {\n if (this.canAcquire) {\n this.incrementCount();\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 } else {\n this.decrementCount();\n }\n }\n\n wait(): Promise<void> {\n return new Promise((resolve) => this.waitQueue.push(resolve));\n }\n}\n\nconst defaultKey = \"_default\";\n\nclass Semaphore {\n private semaphoreInstances: Record<string | number, SemaphoreItem>;\n private maxConcurrent: number;\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 * @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 * @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 * @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 * @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 * @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 /**\n * Wait until the count on `key` is 0 and then resolve.\n *\n * @param key\n * @returns\n */\n async wait(key: string | number = defaultKey) {\n if (this.hasTasks(key)) {\n return this.getSemaphoreInstance(key).wait();\n } else {\n return Promise.resolve();\n }\n }\n\n // globalCount() {\n // return Object.values(this.semaphoreInstances).reduce(\n // (a, instance) => a + instance.count,\n // 0,\n // );\n // }\n}\n\nexport default Semaphore;\nexport { Semaphore };\n"],"names":["SemaphoreItem","constructor","maxConcurrent","this","queue","waitQueue","count","canAcquire","incrementCount","decrementCount","forEach","resolve","acquire","Promise","push","release","resolveFunc","shift","setTimeout","wait","defaultKey","Semaphore","semaphoreInstances","hasSemaphoreInstance","key","Boolean","getSemaphoreInstance","tidy","hasTasks","request","fn","requestIfAvailable"],"mappings":"AAAA,MAAMA,EAUJC,WAAAA,CAAYC,GAAqBC,KATzBC,WAAK,EAAAD,KACLE,eAAS,EAAAF,KACTD,mBAKDI,EAAAA,KAAAA,WAGL,EAAAH,KAAKC,MAAQ,GACbD,KAAKE,UAAY,GACjBF,KAAKD,cAAgBA,EACrBC,KAAKG,MAAQ,CACf,CAEA,cAAIC,GACF,OAAOJ,KAAKG,MAAQH,KAAKD,aAC3B,CAEQM,cAAAA,GACNL,KAAKG,OACP,CAEQG,cAAAA,GACNN,KAAKG,QAEc,IAAfH,KAAKG,QACPH,KAAKE,UAAUK,QAASC,GAAYA,KACpCR,KAAKE,UAAY,GAErB,CAEAO,OAAAA,GACE,OAAIT,KAAKI,YACPJ,KAAKK,iBACEK,QAAQF,eAEJE,QAASF,GAAYR,KAAKC,MAAMU,KAAKH,GAEpD,CAEAI,OAAAA,GACE,MAAMC,EAAcb,KAAKC,MAAMa,QAE3BD,EAEFE,WAAWF,EAAa,GAExBb,KAAKM,gBAET,CAEAU,IAAAA,GACE,OAAW,IAAAN,QAASF,GAAYR,KAAKE,UAAUS,KAAKH,GACtD,EAGF,MAAMS,EAAa,WAEnB,MAAMC,EAOJpB,WAAAA,CAAYC,EAAwB,GAN5BoB,KAAAA,wBACApB,EAAAA,KAAAA,mBAMN,EAAAC,KAAKmB,mBAAqB,GAC1BnB,KAAKD,cAAgBA,CACvB,CAEQqB,oBAAAA,CAAqBC,EAAuBJ,GAClD,OAAOK,QAAQtB,KAAKmB,mBAAmBE,GACzC,CAEQE,oBAAAA,CAAqBF,EAAuBJ,GAIlD,OAHKjB,KAAKoB,qBAAqBC,KAC7BrB,KAAKmB,mBAAmBE,GAAO,IAAIxB,EAAcG,KAAKD,gBAE7CC,KAACmB,mBAAmBE,EACjC,CAKQG,IAAAA,CAAKH,EAAuBJ,GAEhCjB,KAAKoB,qBAAqBC,IACe,IAAzCrB,KAAKuB,qBAAqBF,GAAKlB,cAExBH,KAAKmB,mBAAmBE,EAEnC,CASAjB,UAAAA,CAAWiB,EAAuBJ,GAChC,YAAYM,qBAAqBF,GAAKjB,UACxC,CAKAK,OAAAA,CAAQY,EAAuBJ,GAC7B,OAAOjB,KAAKuB,qBAAqBF,GAAKZ,SACxC,CAKAG,OAAAA,CAAQS,EAAuBJ,GAC7BjB,KAAKuB,qBAAqBF,GAAKT,UAC/BZ,KAAKwB,KAAKH,EACZ,CAOAlB,KAAAA,CAAMkB,EAAuBJ,GAC3B,OAAIjB,KAAKoB,qBAAqBC,GACrBrB,KAAKuB,qBAAqBF,GAAKlB,MAE/B,CAEX,CAMAsB,QAAAA,CAASJ,EAAuBJ,GAC9B,OAAWjB,KAACG,MAAMkB,GAAO,CAC3B,CAOA,aAAMK,CACJC,EACAN,EAAuBJ,GAEvB,IAEE,aADUjB,KAACS,QAAQY,SACNM,GACd,CAAA,QACC3B,KAAKY,QAAQS,EACd,CACH,CAUA,wBAAMO,CACJD,EACAN,EAAuBJ,GAEvB,OAAIjB,KAAKI,WAAWiB,GACXrB,KAAK0B,QAAQC,EAAIN,GAGzB,IACH,CAQA,UAAML,CAAKK,EAAuBJ,GAChC,OAAIjB,KAAKyB,SAASJ,QACJE,qBAAqBF,GAAKL,OAE/BN,QAAQF,SAEnB"}
@@ -1,2 +1,2 @@
1
- function e(e){var t=function(e){if("object"!=typeof e||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var n=t.call(e,"string");if("object"!=typeof n)return n;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e);return"symbol"==typeof t?t:t+""}var t=/*#__PURE__*/function(){function t(e){this.queue=void 0,this.waitQueue=void 0,this.maxConcurrent=void 0,this.count=void 0,this.queue=[],this.waitQueue=[],this.maxConcurrent=e,this.count=0}var n,r,i=t.prototype;return i.incrementCount=function(){this.count++},i.decrementCount=function(){this.count--,0===this.count&&(this.waitQueue.forEach(function(e){return e()}),this.waitQueue=[])},i.acquire=function(){var e=this;return this.canAcquire?(this.incrementCount(),Promise.resolve()):new Promise(function(t){return e.queue.push(t)})},i.release=function(){var e=this.queue.shift();e?setTimeout(e,0):this.decrementCount()},i.wait=function(){var e=this;return new Promise(function(t){return e.waitQueue.push(t)})},n=t,(r=[{key:"canAcquire",get:function(){return this.count<this.maxConcurrent}}])&&function(t,n){for(var r=0;r<n.length;r++){var i=n[r];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(t,e(i.key),i)}}(n.prototype,r),Object.defineProperty(n,"prototype",{writable:!1}),n}(),n="_default",r=/*#__PURE__*/function(){function e(e){void 0===e&&(e=1),this.semaphoreInstances=void 0,this.maxConcurrent=void 0,this.semaphoreInstances={},this.maxConcurrent=e}var r=e.prototype;return r.hasSemaphoreInstance=function(e){return void 0===e&&(e=n),Boolean(this.semaphoreInstances[e])},r.getSemaphoreInstance=function(e){return void 0===e&&(e=n),this.hasSemaphoreInstance(e)||(this.semaphoreInstances[e]=new t(this.maxConcurrent)),this.semaphoreInstances[e]},r.tidy=function(e){void 0===e&&(e=n),this.hasSemaphoreInstance(e)&&0===this.getSemaphoreInstance(e).count&&delete this.semaphoreInstances[e]},r.canAcquire=function(e){return void 0===e&&(e=n),this.getSemaphoreInstance(e).canAcquire},r.acquire=function(e){return void 0===e&&(e=n),this.getSemaphoreInstance(e).acquire()},r.release=function(e){void 0===e&&(e=n),this.getSemaphoreInstance(e).release(),this.tidy(e)},r.count=function(e){return void 0===e&&(e=n),this.hasSemaphoreInstance(e)?this.getSemaphoreInstance(e).count:0},r.hasTasks=function(e){return void 0===e&&(e=n),this.count(e)>0},r.request=function(e,t){void 0===t&&(t=n);try{var r=this;return Promise.resolve(function(n,i){try{var o=Promise.resolve(r.acquire(t)).then(function(){return Promise.resolve(e())})}catch(e){return i(!0,e)}return o&&o.then?o.then(i.bind(null,!1),i.bind(null,!0)):i(!1,o)}(0,function(e,n){if(r.release(t),e)throw n;return n}))}catch(e){return Promise.reject(e)}},r.requestIfAvailable=function(e,t){void 0===t&&(t=n);try{return this.canAcquire(t)?Promise.resolve(this.request(e,t)):Promise.resolve(null)}catch(e){return Promise.reject(e)}},r.wait=function(e){void 0===e&&(e=n);try{return this.hasTasks(e)?Promise.resolve(this.getSemaphoreInstance(e).wait()):Promise.resolve()}catch(e){return Promise.reject(e)}},e}();export{r as default};
1
+ function e(e){var t=function(e){if("object"!=typeof e||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var n=t.call(e,"string");if("object"!=typeof n)return n;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e);return"symbol"==typeof t?t:t+""}var t=/*#__PURE__*/function(){function t(e){this.queue=void 0,this.waitQueue=void 0,this.maxConcurrent=void 0,this.count=void 0,this.queue=[],this.waitQueue=[],this.maxConcurrent=e,this.count=0}var n,r,i=t.prototype;return i.incrementCount=function(){this.count++},i.decrementCount=function(){this.count--,0===this.count&&(this.waitQueue.forEach(function(e){return e()}),this.waitQueue=[])},i.acquire=function(){var e=this;return this.canAcquire?(this.incrementCount(),Promise.resolve()):new Promise(function(t){return e.queue.push(t)})},i.release=function(){var e=this.queue.shift();e?setTimeout(e,0):this.decrementCount()},i.wait=function(){var e=this;return new Promise(function(t){return e.waitQueue.push(t)})},n=t,(r=[{key:"canAcquire",get:function(){return this.count<this.maxConcurrent}}])&&function(t,n){for(var r=0;r<n.length;r++){var i=n[r];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(t,e(i.key),i)}}(n.prototype,r),Object.defineProperty(n,"prototype",{writable:!1}),n}(),n="_default",r=/*#__PURE__*/function(){function e(e){void 0===e&&(e=1),this.semaphoreInstances=void 0,this.maxConcurrent=void 0,this.semaphoreInstances={},this.maxConcurrent=e}var r=e.prototype;return r.hasSemaphoreInstance=function(e){return void 0===e&&(e=n),Boolean(this.semaphoreInstances[e])},r.getSemaphoreInstance=function(e){return void 0===e&&(e=n),this.hasSemaphoreInstance(e)||(this.semaphoreInstances[e]=new t(this.maxConcurrent)),this.semaphoreInstances[e]},r.tidy=function(e){void 0===e&&(e=n),this.hasSemaphoreInstance(e)&&0===this.getSemaphoreInstance(e).count&&delete this.semaphoreInstances[e]},r.canAcquire=function(e){return void 0===e&&(e=n),this.getSemaphoreInstance(e).canAcquire},r.acquire=function(e){return void 0===e&&(e=n),this.getSemaphoreInstance(e).acquire()},r.release=function(e){void 0===e&&(e=n),this.getSemaphoreInstance(e).release(),this.tidy(e)},r.count=function(e){return void 0===e&&(e=n),this.hasSemaphoreInstance(e)?this.getSemaphoreInstance(e).count:0},r.hasTasks=function(e){return void 0===e&&(e=n),this.count(e)>0},r.request=function(e,t){void 0===t&&(t=n);try{var r=this;return Promise.resolve(function(n,i){try{var o=Promise.resolve(r.acquire(t)).then(function(){return Promise.resolve(e())})}catch(e){return i(!0,e)}return o&&o.then?o.then(i.bind(null,!1),i.bind(null,!0)):i(!1,o)}(0,function(e,n){if(r.release(t),e)throw n;return n}))}catch(e){return Promise.reject(e)}},r.requestIfAvailable=function(e,t){void 0===t&&(t=n);try{return this.canAcquire(t)?Promise.resolve(this.request(e,t)):Promise.resolve(null)}catch(e){return Promise.reject(e)}},r.wait=function(e){void 0===e&&(e=n);try{return this.hasTasks(e)?Promise.resolve(this.getSemaphoreInstance(e).wait()):Promise.resolve()}catch(e){return Promise.reject(e)}},e}();export{r as Semaphore,r as default};
2
2
  //# sourceMappingURL=promise-semaphore.module.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"promise-semaphore.module.js","sources":["../src/index.ts"],"sourcesContent":["class SemaphoreItem {\n private queue: Array<Function>;\n private waitQueue: Array<Function>;\n private maxConcurrent: number;\n\n /**\n * The number of locks.\n */\n public count: number;\n\n constructor(maxConcurrent: number) {\n this.queue = [];\n this.waitQueue = [];\n this.maxConcurrent = maxConcurrent;\n this.count = 0;\n }\n\n get canAcquire(): boolean {\n return this.count < this.maxConcurrent;\n }\n\n private incrementCount() {\n this.count++;\n }\n\n private decrementCount() {\n this.count--;\n\n if (this.count === 0) {\n this.waitQueue.forEach((resolve) => resolve());\n this.waitQueue = [];\n }\n }\n\n acquire(): Promise<void> {\n if (this.canAcquire) {\n this.incrementCount();\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 } else {\n this.decrementCount();\n }\n }\n\n wait(): Promise<void> {\n return new Promise((resolve) => this.waitQueue.push(resolve));\n }\n}\n\nconst defaultKey = \"_default\";\n\nclass Semaphore {\n private semaphoreInstances: Record<string | number, SemaphoreItem>;\n private maxConcurrent: number;\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 * @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 * @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 * @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 * @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 * @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 async wait(key: string | number = defaultKey) {\n if (this.hasTasks(key)) {\n return this.getSemaphoreInstance(key).wait();\n } else {\n return Promise.resolve();\n }\n }\n}\n\nexport default Semaphore;\n"],"names":["SemaphoreItem","maxConcurrent","queue","waitQueue","count","this","_proto","prototype","incrementCount","decrementCount","forEach","resolve","acquire","_this","canAcquire","Promise","push","release","resolveFunc","shift","setTimeout","wait","_this2","key","get","defaultKey","Semaphore","semaphoreInstances","_proto2","hasSemaphoreInstance","Boolean","getSemaphoreInstance","tidy","hasTasks","request","fn","_this3","then","_finallyRethrows","_wasThrown","_result","e","reject","requestIfAvailable"],"mappings":"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"}
1
+ {"version":3,"file":"promise-semaphore.module.js","sources":["../src/index.ts"],"sourcesContent":["class SemaphoreItem {\n private queue: Array<Function>;\n private waitQueue: Array<Function>;\n private maxConcurrent: number;\n\n /**\n * The number of locks.\n */\n public count: number;\n\n constructor(maxConcurrent: number) {\n this.queue = [];\n this.waitQueue = [];\n this.maxConcurrent = maxConcurrent;\n this.count = 0;\n }\n\n get canAcquire(): boolean {\n return this.count < this.maxConcurrent;\n }\n\n private incrementCount() {\n this.count++;\n }\n\n private decrementCount() {\n this.count--;\n\n if (this.count === 0) {\n this.waitQueue.forEach((resolve) => resolve());\n this.waitQueue = [];\n }\n }\n\n acquire(): Promise<void> {\n if (this.canAcquire) {\n this.incrementCount();\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 } else {\n this.decrementCount();\n }\n }\n\n wait(): Promise<void> {\n return new Promise((resolve) => this.waitQueue.push(resolve));\n }\n}\n\nconst defaultKey = \"_default\";\n\nclass Semaphore {\n private semaphoreInstances: Record<string | number, SemaphoreItem>;\n private maxConcurrent: number;\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 * @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 * @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 * @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 * @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 * @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 /**\n * Wait until the count on `key` is 0 and then resolve.\n *\n * @param key\n * @returns\n */\n async wait(key: string | number = defaultKey) {\n if (this.hasTasks(key)) {\n return this.getSemaphoreInstance(key).wait();\n } else {\n return Promise.resolve();\n }\n }\n\n // globalCount() {\n // return Object.values(this.semaphoreInstances).reduce(\n // (a, instance) => a + instance.count,\n // 0,\n // );\n // }\n}\n\nexport default Semaphore;\nexport { Semaphore };\n"],"names":["SemaphoreItem","maxConcurrent","queue","waitQueue","count","this","_proto","prototype","incrementCount","decrementCount","forEach","resolve","acquire","_this","canAcquire","Promise","push","release","resolveFunc","shift","setTimeout","wait","_this2","key","get","defaultKey","Semaphore","semaphoreInstances","_proto2","hasSemaphoreInstance","Boolean","getSemaphoreInstance","tidy","hasTasks","request","fn","_this3","then","_finallyRethrows","_wasThrown","_result","e","reject","requestIfAvailable"],"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.11",
3
+ "version": "2.0.12",
4
4
  "description": "Limit or throttle the simultaneous execution of asynchronous code in separate iterations of the event loop.",
5
5
  "repository": "https://github.com/chriscdn/promise-semaphore",
6
6
  "author": "Christopher Meyer <chris@schwiiz.org>",
package/src/index.ts CHANGED
@@ -177,6 +177,12 @@ class Semaphore {
177
177
  }
178
178
  }
179
179
 
180
+ /**
181
+ * Wait until the count on `key` is 0 and then resolve.
182
+ *
183
+ * @param key
184
+ * @returns
185
+ */
180
186
  async wait(key: string | number = defaultKey) {
181
187
  if (this.hasTasks(key)) {
182
188
  return this.getSemaphoreInstance(key).wait();
@@ -184,6 +190,14 @@ class Semaphore {
184
190
  return Promise.resolve();
185
191
  }
186
192
  }
193
+
194
+ // globalCount() {
195
+ // return Object.values(this.semaphoreInstances).reduce(
196
+ // (a, instance) => a + instance.count,
197
+ // 0,
198
+ // );
199
+ // }
187
200
  }
188
201
 
189
202
  export default Semaphore;
203
+ export { Semaphore };