@chriscdn/promise-semaphore 2.0.2 → 2.0.3

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
@@ -1,64 +1,63 @@
1
- declare class Semaphore {
2
- private semaphoreInstances;
3
- private maxConcurrent;
4
- /**
5
- *
6
- * @param {number} [maxConcurrent] The maximum number of concurrent locks.
7
- */
8
- constructor(maxConcurrent?: number);
9
- private hasSemaphoreInstance;
10
- private getSemaphoreInstance;
11
- /**
12
- *
13
- * @param {string | number} [key]- Optional, the semaphore key.
14
- */
15
- private tidy;
16
- /**
17
- * A synchronous function to determine whether a lock can be acquired.
18
- *
19
- * @param {string | number} [key]- Optional, the semaphore key.
20
- * @returns {boolean} Returns true if the lock on `key` can be acquired, false
21
- * otherwise.
22
- */
23
- canAcquire(key?: string | number): boolean;
24
- /**
25
- *
26
- * @param {string | number} [key]- Optional, the semaphore key.
27
- */
28
- acquire(key?: string | number): Promise<void>;
29
- /**
30
- *
31
- * @param {string | number} [key]- Optional, the semaphore key.
32
- */
33
- release(key?: string | number): void;
34
- /**
35
- * The number of active locks. Will always be less or equal to `max`.
36
- *
37
- * @param {string | number} [key]- Optional, the semaphore key.
38
- */
39
- count(key?: string | number): number;
40
- /**
41
- *
42
- * @param {string | number} [key]- Optional, the semaphore key.
43
- * @returns {boolean} True if the semaphore and key has locks, false otherwise.
44
- */
45
- hasTasks(key?: string | number): boolean;
46
- /**
47
- *
48
- * @param {Function<T>} fn The function to execute.
49
- * @param {string | number} [key]- Optional, the semaphore key.
50
- * @returns {Promise<T>}
51
- */
52
- request<T>(fn: Function, key?: string | number): Promise<T>;
53
- /**
54
- * Asynchronously executes `fn` if a lock can be immediately acquired.
55
- * Otherwise, returns null.
56
- *
57
- * @param {Function<T>} fn The function to execute.
58
- * @param {string | number} [key]- Optional, the semaphore key.
59
- * @returns {Promise<T>}
60
- */
61
- requestIfAvailable<T>(fn: Function, key?: string | number): Promise<T | null>;
62
- }
63
-
64
- export { Semaphore as default };
1
+ declare class Semaphore {
2
+ private semaphoreInstances;
3
+ private maxConcurrent;
4
+ /**
5
+ *
6
+ * @param {number} [maxConcurrent] The maximum number of concurrent locks.
7
+ */
8
+ constructor(maxConcurrent?: number);
9
+ private hasSemaphoreInstance;
10
+ private getSemaphoreInstance;
11
+ /**
12
+ *
13
+ * @param {string | number} [key]- Optional, the semaphore key.
14
+ */
15
+ private tidy;
16
+ /**
17
+ * A synchronous function to determine whether a lock can be acquired.
18
+ *
19
+ * @param {string | number} [key]- Optional, the semaphore key.
20
+ * @returns {boolean} Returns true if the lock on `key` can be acquired, false
21
+ * otherwise.
22
+ */
23
+ canAcquire(key?: string | number): boolean;
24
+ /**
25
+ *
26
+ * @param {string | number} [key]- Optional, the semaphore key.
27
+ */
28
+ acquire(key?: string | number): Promise<void>;
29
+ /**
30
+ *
31
+ * @param {string | number} [key]- Optional, the semaphore key.
32
+ */
33
+ release(key?: string | number): void;
34
+ /**
35
+ * The number of active locks. Will always be less or equal to `max`.
36
+ *
37
+ * @param {string | number} [key]- Optional, the semaphore key.
38
+ */
39
+ count(key?: string | number): number;
40
+ /**
41
+ *
42
+ * @param {string | number} [key]- Optional, the semaphore key.
43
+ * @returns {boolean} True if the semaphore and key has locks, false otherwise.
44
+ */
45
+ hasTasks(key?: string | number): boolean;
46
+ /**
47
+ *
48
+ * @param {Function<T>} fn The function to execute.
49
+ * @param {string | number} [key]- Optional, the semaphore key.
50
+ * @returns {Promise<T>}
51
+ */
52
+ request<T>(fn: Function, key?: string | number): Promise<T>;
53
+ /**
54
+ * Asynchronously executes `fn` if a lock can be immediately acquired.
55
+ * Otherwise, returns null.
56
+ *
57
+ * @param {Function<T>} fn The function to execute.
58
+ * @param {string | number} [key]- Optional, the semaphore key.
59
+ * @returns {Promise<T>}
60
+ */
61
+ requestIfAvailable<T>(fn: Function, key?: string | number): Promise<T | null>;
62
+ }
63
+ export default Semaphore;
@@ -0,0 +1,2 @@
1
+ var e=/*#__PURE__*/function(){function e(e){this.queue=void 0,this.maxConcurrent=void 0,this.count=void 0,this.queue=[],this.maxConcurrent=e,this.count=0}var t,n,r=e.prototype;return r.acquire=function(){var e=this;return this.canAcquire?(this.count++,Promise.resolve()):new Promise(function(t){return e.queue.push(t)})},r.release=function(){var e=this.queue.shift();e?setTimeout(e,0):this.count--},t=e,(n=[{key:"canAcquire",get:function(){return this.count<this.maxConcurrent}}])&&function(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,"symbol"==typeof(i=function(e,t){if("object"!=typeof e||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,"string");if("object"!=typeof r)return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(r.key))?i:String(i),r)}var i}(t.prototype,n),Object.defineProperty(t,"prototype",{writable:!1}),e}(),t="_default";module.exports=/*#__PURE__*/function(){function n(e){void 0===e&&(e=1),this.semaphoreInstances=void 0,this.maxConcurrent=void 0,this.semaphoreInstances={},this.maxConcurrent=e}var r=n.prototype;return r.hasSemaphoreInstance=function(e){return void 0===e&&(e=t),Boolean(this.semaphoreInstances[e])},r.getSemaphoreInstance=function(n){return void 0===n&&(n=t),this.hasSemaphoreInstance(n)||(this.semaphoreInstances[n]=new e(this.maxConcurrent)),this.semaphoreInstances[n]},r.tidy=function(e){void 0===e&&(e=t),this.hasSemaphoreInstance(e)&&0==this.getSemaphoreInstance(e).count&&delete this.semaphoreInstances[e]},r.canAcquire=function(e){return void 0===e&&(e=t),this.getSemaphoreInstance(e).canAcquire},r.acquire=function(e){return void 0===e&&(e=t),this.getSemaphoreInstance(e).acquire()},r.release=function(e){void 0===e&&(e=t),this.getSemaphoreInstance(e).release(),this.tidy(e)},r.count=function(e){return void 0===e&&(e=t),this.hasSemaphoreInstance(e)?this.getSemaphoreInstance(e).count:0},r.hasTasks=function(e){return void 0===e&&(e=t),this.count(e)>0},r.request=function(e,n){void 0===n&&(n=t);try{var r=this;return Promise.resolve(function(t,i){try{var o=Promise.resolve(r.acquire(n)).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,t){if(r.release(n),e)throw t;return t}))}catch(e){return Promise.reject(e)}},r.requestIfAvailable=function(e,n){void 0===n&&(n=t);try{return this.canAcquire(n)?Promise.resolve(this.request(e,n)):Promise.resolve(null)}catch(e){return Promise.reject(e)}},n}();
2
+ //# sourceMappingURL=promise-semaphore.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promise-semaphore.cjs","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":["SemaphoreItem","maxConcurrent","this","queue","count","_proto","prototype","acquire","_this","canAcquire","Promise","resolve","push","release","resolveFunc","shift","setTimeout","key","get","defaultKey","Semaphore","semaphoreInstances","_proto2","hasSemaphoreInstance","Boolean","getSemaphoreInstance","tidy","hasTasks","request","fn","_this2","then","_finallyRethrows","_wasThrown","_result","e","reject","requestIfAvailable"],"mappings":"IAAMA,0BAQJ,SAAAA,EAAYC,GAAqBC,KAPzBC,WACAF,EAAAA,KAAAA,mBAIDG,EAAAA,KAAAA,aAGLF,KAAKC,MAAQ,GACbD,KAAKD,cAAgBA,EACrBC,KAAKE,MAAQ,CACf,CAAC,QAAAC,EAAAL,EAAAM,UAIAN,OAJAK,EAMDE,QAAA,eAAOC,EAAAN,KACL,OAAIA,KAAKO,YACPP,KAAKE,QACEM,QAAQC,eAEJD,QAAQ,SAACC,GAAY,OAAAH,EAAKL,MAAMS,KAAKD,EAAQ,EAE5D,EAACN,EAEDQ,QAAA,WACE,IAAMC,EAAcZ,KAAKC,MAAMY,QAE3BD,EAEFE,WAAWF,EAAa,GAGxBZ,KAAKE,OAET,IAACJ,OAAAiB,IAAA,aAAAC,IAvBD,WACE,OAAOhB,KAAKE,MAAQF,KAAKD,aAC3B,mgBAACD,CAAA,IAwBGmB,EAAa,uCAEJ,WAQb,SAAAC,EAAYnB,QAAAA,IAAAA,IAAAA,EAAwB,GAACC,KAP7BmB,wBAAkB,EAAAnB,KAClBD,mBAON,EAAAC,KAAKmB,mBAAqB,CAAE,EAC5BnB,KAAKD,cAAgBA,CACvB,CAAC,IAAAqB,EAAAF,EAAAd,UA+GA,OA/GAgB,EAEOC,qBAAA,SAAqBN,GAC3B,gBAD2BA,IAAAA,EAAuBE,GAC3CK,QAAQtB,KAAKmB,mBAAmBJ,GACzC,EAACK,EAEOG,qBAAA,SAAqBR,GAI3B,gBAJ2BA,IAAAA,EAAuBE,GAC7CjB,KAAKqB,qBAAqBN,KAC7Bf,KAAKmB,mBAAmBJ,GAAO,IAAIjB,EAAcE,KAAKD,gBAE7CC,KAACmB,mBAAmBJ,EACjC,EAACK,EAMOI,KAAA,SAAKT,QAAAA,IAAAA,IAAAA,EAAuBE,GAEhCjB,KAAKqB,qBAAqBN,IACc,GAAxCf,KAAKuB,qBAAqBR,GAAKb,cAExBF,KAAKmB,mBAAmBJ,EAEnC,EAACK,EASDb,WAAA,SAAWQ,GACT,gBADSA,IAAAA,EAAuBE,GACzBjB,KAAKuB,qBAAqBR,GAAKR,UACxC,EAACa,EAMDf,QAAA,SAAQU,GACN,gBADMA,IAAAA,EAAuBE,GAClBjB,KAACuB,qBAAqBR,GAAKV,SACxC,EAACe,EAMDT,QAAA,SAAQI,QAAAA,IAAAA,IAAAA,EAAuBE,GAC7BjB,KAAKuB,qBAAqBR,GAAKJ,UAC/BX,KAAKwB,KAAKT,EACZ,EAACK,EAODlB,MAAA,SAAMa,GACJ,gBADIA,IAAAA,EAAuBE,GACvBjB,KAAKqB,qBAAqBN,QAChBQ,qBAAqBR,GAAKb,MAGvC,CACH,EAACkB,EAODK,SAAA,SAASV,GACP,gBADOA,IAAAA,EAAuBE,GACvBjB,KAAKE,MAAMa,GAAO,CAC3B,EAACK,EAQKM,QAAOA,SACXC,EACAZ,YAAAA,IAAAA,EAAuBE,GAAU,IAAA,IAAAW,EAGzB5B,KAAIQ,OAAAA,QAAAC,gCADRD,QAAAC,QACImB,EAAKvB,QAAQU,IAAIc,KAAA,WAAA,OAAArB,QAAAC,QACVkB,IACd,4FAFWG,CADR,EAGHC,SAAAA,EAAAC,GACmB,GAAlBJ,EAAKjB,QAAQI,GAAKgB,EAAAC,MAAAA,SAAAA,CAAA,GAEtB,CAAC,MAAAC,GAAAzB,OAAAA,QAAA0B,OAAAD,EAAAb,CAAAA,EAAAA,EAUKe,mBAAkB,SACtBR,EACAZ,QAAAA,IAAAA,IAAAA,EAAuBE,GAAU,IAEjC,OAAIjB,KAAKO,WAAWQ,GAClBP,QAAAC,QADET,KACU0B,QAAQC,EAAIZ,IAExBP,QAAAC,QAAO,KAEX,CAAC,MAAAwB,GAAAzB,OAAAA,QAAA0B,OAAAD,EAAA,CAAA,EAAAf,CAAA,CA1HY"}
@@ -0,0 +1,2 @@
1
+ class e{constructor(e){this.queue=void 0,this.maxConcurrent=void 0,this.count=void 0,this.queue=[],this.maxConcurrent=e,this.count=0}get canAcquire(){return this.count<this.maxConcurrent}acquire(){return this.canAcquire?(this.count++,Promise.resolve()):new Promise(e=>this.queue.push(e))}release(){const e=this.queue.shift();e?setTimeout(e,0):this.count--}}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}}export{s as default};
2
+ //# sourceMappingURL=promise-semaphore.modern.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promise-semaphore.modern.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":["SemaphoreItem","constructor","maxConcurrent","queue","count","this","canAcquire","acquire","Promise","resolve","push","release","resolveFunc","shift","setTimeout","defaultKey","Semaphore","semaphoreInstances","hasSemaphoreInstance","key","Boolean","getSemaphoreInstance","tidy","hasTasks","request","fn","requestIfAvailable"],"mappings":"AAAA,MAAMA,EAQJC,WAAAA,CAAYC,GAPJC,KAAAA,WACAD,EAAAA,KAAAA,0BAIDE,WAAK,EAGVC,KAAKF,MAAQ,GACbE,KAAKH,cAAgBA,EACrBG,KAAKD,MAAQ,CACf,CAEA,cAAIE,GACF,YAAYF,MAAQC,KAAKH,aAC3B,CAEAK,OAAAA,GACE,OAAIF,KAAKC,YACPD,KAAKD,QACEI,QAAQC,WAER,IAAID,QAASC,GAAYJ,KAAKF,MAAMO,KAAKD,GAEpD,CAEAE,OAAAA,GACE,MAAMC,EAAcP,KAAKF,MAAMU,QAE3BD,EAEFE,WAAWF,EAAa,GAGxBP,KAAKD,OAET,EAGF,MAAMW,EAAa,WAEnB,MAAMC,EAQJf,WAAAA,CAAYC,EAAwB,GAP5Be,KAAAA,+BACAf,mBAAa,EAOnBG,KAAKY,mBAAqB,CAAA,EAC1BZ,KAAKH,cAAgBA,CACvB,CAEQgB,oBAAAA,CAAqBC,EAAuBJ,GAClD,OAAOK,QAAQf,KAAKY,mBAAmBE,GACzC,CAEQE,oBAAAA,CAAqBF,EAAuBJ,GAIlD,OAHKV,KAAKa,qBAAqBC,KAC7Bd,KAAKY,mBAAmBE,GAAO,IAAInB,EAAcK,KAAKH,gBAEjDG,KAAKY,mBAAmBE,EACjC,CAMQG,IAAAA,CAAKH,EAAuBJ,GAEhCV,KAAKa,qBAAqBC,IACc,GAAxCd,KAAKgB,qBAAqBF,GAAKf,cAExBC,KAAKY,mBAAmBE,EAEnC,CASAb,UAAAA,CAAWa,EAAuBJ,GAChC,OAAWV,KAACgB,qBAAqBF,GAAKb,UACxC,CAMAC,OAAAA,CAAQY,EAAuBJ,GAC7B,OAAOV,KAAKgB,qBAAqBF,GAAKZ,SACxC,CAMAI,OAAAA,CAAQQ,EAAuBJ,GAC7BV,KAAKgB,qBAAqBF,GAAKR,UAC/BN,KAAKiB,KAAKH,EACZ,CAOAf,KAAAA,CAAMe,EAAuBJ,GAC3B,OAAIV,KAAKa,qBAAqBC,GACjBd,KAACgB,qBAAqBF,GAAKf,MAE/B,CAEX,CAOAmB,QAAAA,CAASJ,EAAuBJ,GAC9B,OAAWV,KAACD,MAAMe,GAAO,CAC3B,CAQA,aAAMK,CACJC,EACAN,EAAuBJ,GAEvB,IAEE,aADUV,KAACE,QAAQY,SACNM,GACd,CAAA,QACCpB,KAAKM,QAAQQ,EACd,CACH,CAUA,wBAAMO,CACJD,EACAN,EAAuBJ,GAEvB,OAAIV,KAAKC,WAAWa,GACPd,KAACmB,QAAQC,EAAIN,GAEjB,IAEX"}
@@ -0,0 +1,2 @@
1
+ var e=/*#__PURE__*/function(){function e(e){this.queue=void 0,this.maxConcurrent=void 0,this.count=void 0,this.queue=[],this.maxConcurrent=e,this.count=0}var t,n,r=e.prototype;return r.acquire=function(){var e=this;return this.canAcquire?(this.count++,Promise.resolve()):new Promise(function(t){return e.queue.push(t)})},r.release=function(){var e=this.queue.shift();e?setTimeout(e,0):this.count--},t=e,(n=[{key:"canAcquire",get:function(){return this.count<this.maxConcurrent}}])&&function(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,"symbol"==typeof(i=function(e,t){if("object"!=typeof e||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,"string");if("object"!=typeof r)return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(r.key))?i:String(i),r)}var i}(t.prototype,n),Object.defineProperty(t,"prototype",{writable:!1}),e}(),t="_default",n=/*#__PURE__*/function(){function n(e){void 0===e&&(e=1),this.semaphoreInstances=void 0,this.maxConcurrent=void 0,this.semaphoreInstances={},this.maxConcurrent=e}var r=n.prototype;return r.hasSemaphoreInstance=function(e){return void 0===e&&(e=t),Boolean(this.semaphoreInstances[e])},r.getSemaphoreInstance=function(n){return void 0===n&&(n=t),this.hasSemaphoreInstance(n)||(this.semaphoreInstances[n]=new e(this.maxConcurrent)),this.semaphoreInstances[n]},r.tidy=function(e){void 0===e&&(e=t),this.hasSemaphoreInstance(e)&&0==this.getSemaphoreInstance(e).count&&delete this.semaphoreInstances[e]},r.canAcquire=function(e){return void 0===e&&(e=t),this.getSemaphoreInstance(e).canAcquire},r.acquire=function(e){return void 0===e&&(e=t),this.getSemaphoreInstance(e).acquire()},r.release=function(e){void 0===e&&(e=t),this.getSemaphoreInstance(e).release(),this.tidy(e)},r.count=function(e){return void 0===e&&(e=t),this.hasSemaphoreInstance(e)?this.getSemaphoreInstance(e).count:0},r.hasTasks=function(e){return void 0===e&&(e=t),this.count(e)>0},r.request=function(e,n){void 0===n&&(n=t);try{var r=this;return Promise.resolve(function(t,i){try{var o=Promise.resolve(r.acquire(n)).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,t){if(r.release(n),e)throw t;return t}))}catch(e){return Promise.reject(e)}},r.requestIfAvailable=function(e,n){void 0===n&&(n=t);try{return this.canAcquire(n)?Promise.resolve(this.request(e,n)):Promise.resolve(null)}catch(e){return Promise.reject(e)}},n}();export{n as default};
2
+ //# sourceMappingURL=promise-semaphore.module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promise-semaphore.module.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":["SemaphoreItem","maxConcurrent","this","queue","count","_proto","prototype","acquire","_this","canAcquire","Promise","resolve","push","release","resolveFunc","shift","setTimeout","key","get","defaultKey","Semaphore","semaphoreInstances","_proto2","hasSemaphoreInstance","Boolean","getSemaphoreInstance","tidy","hasTasks","request","fn","_this2","then","_finallyRethrows","_wasThrown","_result","e","reject","requestIfAvailable"],"mappings":"IAAMA,0BAQJ,SAAAA,EAAYC,GAAqBC,KAPzBC,WACAF,EAAAA,KAAAA,mBAIDG,EAAAA,KAAAA,aAGLF,KAAKC,MAAQ,GACbD,KAAKD,cAAgBA,EACrBC,KAAKE,MAAQ,CACf,CAAC,QAAAC,EAAAL,EAAAM,UAIAN,OAJAK,EAMDE,QAAA,eAAOC,EAAAN,KACL,OAAIA,KAAKO,YACPP,KAAKE,QACEM,QAAQC,eAEJD,QAAQ,SAACC,GAAY,OAAAH,EAAKL,MAAMS,KAAKD,EAAQ,EAE5D,EAACN,EAEDQ,QAAA,WACE,IAAMC,EAAcZ,KAAKC,MAAMY,QAE3BD,EAEFE,WAAWF,EAAa,GAGxBZ,KAAKE,OAET,IAACJ,OAAAiB,IAAA,aAAAC,IAvBD,WACE,OAAOhB,KAAKE,MAAQF,KAAKD,aAC3B,mgBAACD,CAAA,IAwBGmB,EAAa,WAEbC,eAAS,WAQb,SAAAA,EAAYnB,QAAAA,IAAAA,IAAAA,EAAwB,GAACC,KAP7BmB,wBAAkB,EAAAnB,KAClBD,mBAON,EAAAC,KAAKmB,mBAAqB,CAAE,EAC5BnB,KAAKD,cAAgBA,CACvB,CAAC,IAAAqB,EAAAF,EAAAd,UA+GA,OA/GAgB,EAEOC,qBAAA,SAAqBN,GAC3B,gBAD2BA,IAAAA,EAAuBE,GAC3CK,QAAQtB,KAAKmB,mBAAmBJ,GACzC,EAACK,EAEOG,qBAAA,SAAqBR,GAI3B,gBAJ2BA,IAAAA,EAAuBE,GAC7CjB,KAAKqB,qBAAqBN,KAC7Bf,KAAKmB,mBAAmBJ,GAAO,IAAIjB,EAAcE,KAAKD,gBAE7CC,KAACmB,mBAAmBJ,EACjC,EAACK,EAMOI,KAAA,SAAKT,QAAAA,IAAAA,IAAAA,EAAuBE,GAEhCjB,KAAKqB,qBAAqBN,IACc,GAAxCf,KAAKuB,qBAAqBR,GAAKb,cAExBF,KAAKmB,mBAAmBJ,EAEnC,EAACK,EASDb,WAAA,SAAWQ,GACT,gBADSA,IAAAA,EAAuBE,GACzBjB,KAAKuB,qBAAqBR,GAAKR,UACxC,EAACa,EAMDf,QAAA,SAAQU,GACN,gBADMA,IAAAA,EAAuBE,GAClBjB,KAACuB,qBAAqBR,GAAKV,SACxC,EAACe,EAMDT,QAAA,SAAQI,QAAAA,IAAAA,IAAAA,EAAuBE,GAC7BjB,KAAKuB,qBAAqBR,GAAKJ,UAC/BX,KAAKwB,KAAKT,EACZ,EAACK,EAODlB,MAAA,SAAMa,GACJ,gBADIA,IAAAA,EAAuBE,GACvBjB,KAAKqB,qBAAqBN,QAChBQ,qBAAqBR,GAAKb,MAGvC,CACH,EAACkB,EAODK,SAAA,SAASV,GACP,gBADOA,IAAAA,EAAuBE,GACvBjB,KAAKE,MAAMa,GAAO,CAC3B,EAACK,EAQKM,QAAOA,SACXC,EACAZ,YAAAA,IAAAA,EAAuBE,GAAU,IAAA,IAAAW,EAGzB5B,KAAIQ,OAAAA,QAAAC,gCADRD,QAAAC,QACImB,EAAKvB,QAAQU,IAAIc,KAAA,WAAA,OAAArB,QAAAC,QACVkB,IACd,4FAFWG,CADR,EAGHC,SAAAA,EAAAC,GACmB,GAAlBJ,EAAKjB,QAAQI,GAAKgB,EAAAC,MAAAA,SAAAA,CAAA,GAEtB,CAAC,MAAAC,GAAAzB,OAAAA,QAAA0B,OAAAD,EAAAb,CAAAA,EAAAA,EAUKe,mBAAkB,SACtBR,EACAZ,QAAAA,IAAAA,IAAAA,EAAuBE,GAAU,IAEjC,OAAIjB,KAAKO,WAAWQ,GAClBP,QAAAC,QADET,KACU0B,QAAQC,EAAIZ,IAExBP,QAAAC,QAAO,KAEX,CAAC,MAAAwB,GAAAzB,OAAAA,QAAA0B,OAAAD,EAAA,CAAA,EAAAf,CAAA,CA1HY"}
@@ -0,0 +1,3 @@
1
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e||self).promiseSemaphore=t()}(this,function(){var e=/*#__PURE__*/function(){function e(e){this.queue=void 0,this.maxConcurrent=void 0,this.count=void 0,this.queue=[],this.maxConcurrent=e,this.count=0}var t,n,r=e.prototype;return r.acquire=function(){var e=this;return this.canAcquire?(this.count++,Promise.resolve()):new Promise(function(t){return e.queue.push(t)})},r.release=function(){var e=this.queue.shift();e?setTimeout(e,0):this.count--},t=e,(n=[{key:"canAcquire",get:function(){return this.count<this.maxConcurrent}}])&&function(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,"symbol"==typeof(i=function(e,t){if("object"!=typeof e||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,"string");if("object"!=typeof r)return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(r.key))?i:String(i),r)}var i}(t.prototype,n),Object.defineProperty(t,"prototype",{writable:!1}),e}(),t="_default";/*#__PURE__*/
2
+ return function(){function n(e){void 0===e&&(e=1),this.semaphoreInstances=void 0,this.maxConcurrent=void 0,this.semaphoreInstances={},this.maxConcurrent=e}var r=n.prototype;return r.hasSemaphoreInstance=function(e){return void 0===e&&(e=t),Boolean(this.semaphoreInstances[e])},r.getSemaphoreInstance=function(n){return void 0===n&&(n=t),this.hasSemaphoreInstance(n)||(this.semaphoreInstances[n]=new e(this.maxConcurrent)),this.semaphoreInstances[n]},r.tidy=function(e){void 0===e&&(e=t),this.hasSemaphoreInstance(e)&&0==this.getSemaphoreInstance(e).count&&delete this.semaphoreInstances[e]},r.canAcquire=function(e){return void 0===e&&(e=t),this.getSemaphoreInstance(e).canAcquire},r.acquire=function(e){return void 0===e&&(e=t),this.getSemaphoreInstance(e).acquire()},r.release=function(e){void 0===e&&(e=t),this.getSemaphoreInstance(e).release(),this.tidy(e)},r.count=function(e){return void 0===e&&(e=t),this.hasSemaphoreInstance(e)?this.getSemaphoreInstance(e).count:0},r.hasTasks=function(e){return void 0===e&&(e=t),this.count(e)>0},r.request=function(e,n){void 0===n&&(n=t);try{var r=this;return Promise.resolve(function(t,i){try{var o=Promise.resolve(r.acquire(n)).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,t){if(r.release(n),e)throw t;return t}))}catch(e){return Promise.reject(e)}},r.requestIfAvailable=function(e,n){void 0===n&&(n=t);try{return this.canAcquire(n)?Promise.resolve(this.request(e,n)):Promise.resolve(null)}catch(e){return Promise.reject(e)}},n}()});
3
+ //# sourceMappingURL=promise-semaphore.umd.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promise-semaphore.umd.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":["SemaphoreItem","maxConcurrent","this","queue","count","_proto","prototype","acquire","_this","canAcquire","Promise","resolve","push","release","resolveFunc","shift","setTimeout","key","get","defaultKey","Semaphore","semaphoreInstances","_proto2","hasSemaphoreInstance","Boolean","getSemaphoreInstance","tidy","hasTasks","request","fn","_this2","then","_finallyRethrows","_wasThrown","_result","e","reject","requestIfAvailable"],"mappings":"uOAAMA,0BAQJ,SAAAA,EAAYC,GAAqBC,KAPzBC,WACAF,EAAAA,KAAAA,mBAIDG,EAAAA,KAAAA,aAGLF,KAAKC,MAAQ,GACbD,KAAKD,cAAgBA,EACrBC,KAAKE,MAAQ,CACf,CAAC,QAAAC,EAAAL,EAAAM,UAIAN,OAJAK,EAMDE,QAAA,eAAOC,EAAAN,KACL,OAAIA,KAAKO,YACPP,KAAKE,QACEM,QAAQC,eAEJD,QAAQ,SAACC,GAAY,OAAAH,EAAKL,MAAMS,KAAKD,EAAQ,EAE5D,EAACN,EAEDQ,QAAA,WACE,IAAMC,EAAcZ,KAAKC,MAAMY,QAE3BD,EAEFE,WAAWF,EAAa,GAGxBZ,KAAKE,OAET,IAACJ,OAAAiB,IAAA,aAAAC,IAvBD,WACE,OAAOhB,KAAKE,MAAQF,KAAKD,aAC3B,mgBAACD,CAAA,IAwBGmB,EAAa;OAEJ,WAQb,SAAAC,EAAYnB,QAAAA,IAAAA,IAAAA,EAAwB,GAACC,KAP7BmB,wBAAkB,EAAAnB,KAClBD,mBAON,EAAAC,KAAKmB,mBAAqB,CAAE,EAC5BnB,KAAKD,cAAgBA,CACvB,CAAC,IAAAqB,EAAAF,EAAAd,UA+GA,OA/GAgB,EAEOC,qBAAA,SAAqBN,GAC3B,gBAD2BA,IAAAA,EAAuBE,GAC3CK,QAAQtB,KAAKmB,mBAAmBJ,GACzC,EAACK,EAEOG,qBAAA,SAAqBR,GAI3B,gBAJ2BA,IAAAA,EAAuBE,GAC7CjB,KAAKqB,qBAAqBN,KAC7Bf,KAAKmB,mBAAmBJ,GAAO,IAAIjB,EAAcE,KAAKD,gBAE7CC,KAACmB,mBAAmBJ,EACjC,EAACK,EAMOI,KAAA,SAAKT,QAAAA,IAAAA,IAAAA,EAAuBE,GAEhCjB,KAAKqB,qBAAqBN,IACc,GAAxCf,KAAKuB,qBAAqBR,GAAKb,cAExBF,KAAKmB,mBAAmBJ,EAEnC,EAACK,EASDb,WAAA,SAAWQ,GACT,gBADSA,IAAAA,EAAuBE,GACzBjB,KAAKuB,qBAAqBR,GAAKR,UACxC,EAACa,EAMDf,QAAA,SAAQU,GACN,gBADMA,IAAAA,EAAuBE,GAClBjB,KAACuB,qBAAqBR,GAAKV,SACxC,EAACe,EAMDT,QAAA,SAAQI,QAAAA,IAAAA,IAAAA,EAAuBE,GAC7BjB,KAAKuB,qBAAqBR,GAAKJ,UAC/BX,KAAKwB,KAAKT,EACZ,EAACK,EAODlB,MAAA,SAAMa,GACJ,gBADIA,IAAAA,EAAuBE,GACvBjB,KAAKqB,qBAAqBN,QAChBQ,qBAAqBR,GAAKb,MAGvC,CACH,EAACkB,EAODK,SAAA,SAASV,GACP,gBADOA,IAAAA,EAAuBE,GACvBjB,KAAKE,MAAMa,GAAO,CAC3B,EAACK,EAQKM,QAAOA,SACXC,EACAZ,YAAAA,IAAAA,EAAuBE,GAAU,IAAA,IAAAW,EAGzB5B,KAAIQ,OAAAA,QAAAC,gCADRD,QAAAC,QACImB,EAAKvB,QAAQU,IAAIc,KAAA,WAAA,OAAArB,QAAAC,QACVkB,IACd,4FAFWG,CADR,EAGHC,SAAAA,EAAAC,GACmB,GAAlBJ,EAAKjB,QAAQI,GAAKgB,EAAAC,MAAAA,SAAAA,CAAA,GAEtB,CAAC,MAAAC,GAAAzB,OAAAA,QAAA0B,OAAAD,EAAAb,CAAAA,EAAAA,EAUKe,mBAAkB,SACtBR,EACAZ,QAAAA,IAAAA,IAAAA,EAAuBE,GAAU,IAEjC,OAAIjB,KAAKO,WAAWQ,GAClBP,QAAAC,QADET,KACU0B,QAAQC,EAAIZ,IAExBP,QAAAC,QAAO,KAEX,CAAC,MAAAwB,GAAAzB,OAAAA,QAAA0B,OAAAD,EAAA,CAAA,EAAAf,CAAA,CA1HY"}
package/package.json CHANGED
@@ -1,27 +1,26 @@
1
1
  {
2
2
  "name": "@chriscdn/promise-semaphore",
3
- "version": "2.0.2",
3
+ "version": "2.0.3",
4
4
  "description": "Limit or throttle the simultaneous execution of asynchronous code in separate iterations of the event loop.",
5
- "main": "lib/index.cjs.js",
6
- "module": "lib/index.es.js",
7
- "types": "lib/index.d.ts",
8
5
  "repository": "https://github.com/chriscdn/promise-semaphore",
9
6
  "author": "Christopher Meyer <chris@schwiiz.org>",
10
7
  "license": "MIT",
8
+ "type": "module",
9
+ "source": "./src/index.ts",
10
+ "main": "./lib/promise-semaphore.cjs",
11
+ "module": "./lib/promise-semaphore.module.js",
12
+ "unpkg": "./lib/promise-semaphore.umd.js",
13
+ "exports": {
14
+ "require": "./lib/promise-semaphore.cjs",
15
+ "default": "./lib/promise-semaphore.modern.js"
16
+ },
17
+ "types": "./lib/index.d.ts",
11
18
  "scripts": {
12
- "build": "rollup -c",
13
- "watch": "rollup -c --watch",
14
- "test": "jest"
19
+ "build": "rm -rf ./lib/ && microbundle",
20
+ "dev": "microbundle watch"
15
21
  },
16
22
  "devDependencies": {
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
- "rollup-plugin-esbuild": "^5.0.0",
23
- "ts-jest": "^29.1.1",
24
- "typescript": "^5.2.2"
23
+ "microbundle": "^0.15.1"
25
24
  },
26
25
  "keywords": [
27
26
  "promise",
package/lib/index.cjs.js DELETED
@@ -1,142 +0,0 @@
1
- 'use strict';
2
-
3
- class SemaphoreItem {
4
- queue;
5
- maxConcurrent;
6
- /**
7
- * The number of locks.
8
- */
9
- count;
10
- constructor(maxConcurrent) {
11
- this.queue = [];
12
- this.maxConcurrent = maxConcurrent;
13
- this.count = 0;
14
- }
15
- get canAcquire() {
16
- return this.count < this.maxConcurrent;
17
- }
18
- acquire() {
19
- if (this.canAcquire) {
20
- this.count++;
21
- return Promise.resolve();
22
- } else {
23
- return new Promise((resolve) => this.queue.push(resolve));
24
- }
25
- }
26
- release() {
27
- const resolveFunc = this.queue.shift();
28
- if (resolveFunc) {
29
- setTimeout(resolveFunc, 0);
30
- } else {
31
- this.count--;
32
- }
33
- }
34
- }
35
- const defaultKey = "_default";
36
- class Semaphore {
37
- semaphoreInstances;
38
- maxConcurrent;
39
- /**
40
- *
41
- * @param {number} [maxConcurrent] The maximum number of concurrent locks.
42
- */
43
- constructor(maxConcurrent = 1) {
44
- this.semaphoreInstances = {};
45
- this.maxConcurrent = maxConcurrent;
46
- }
47
- hasSemaphoreInstance(key = defaultKey) {
48
- return Boolean(this.semaphoreInstances[key]);
49
- }
50
- getSemaphoreInstance(key = defaultKey) {
51
- if (!this.hasSemaphoreInstance(key)) {
52
- this.semaphoreInstances[key] = new SemaphoreItem(this.maxConcurrent);
53
- }
54
- return this.semaphoreInstances[key];
55
- }
56
- /**
57
- *
58
- * @param {string | number} [key]- Optional, the semaphore key.
59
- */
60
- tidy(key = defaultKey) {
61
- if (this.hasSemaphoreInstance(key) && this.getSemaphoreInstance(key).count == 0) {
62
- delete this.semaphoreInstances[key];
63
- }
64
- }
65
- /**
66
- * A synchronous function to determine whether a lock can be acquired.
67
- *
68
- * @param {string | number} [key]- Optional, the semaphore key.
69
- * @returns {boolean} Returns true if the lock on `key` can be acquired, false
70
- * otherwise.
71
- */
72
- canAcquire(key = defaultKey) {
73
- return this.getSemaphoreInstance(key).canAcquire;
74
- }
75
- /**
76
- *
77
- * @param {string | number} [key]- Optional, the semaphore key.
78
- */
79
- acquire(key = defaultKey) {
80
- return this.getSemaphoreInstance(key).acquire();
81
- }
82
- /**
83
- *
84
- * @param {string | number} [key]- Optional, the semaphore key.
85
- */
86
- release(key = defaultKey) {
87
- this.getSemaphoreInstance(key).release();
88
- this.tidy(key);
89
- }
90
- /**
91
- * The number of active locks. Will always be less or equal to `max`.
92
- *
93
- * @param {string | number} [key]- Optional, the semaphore key.
94
- */
95
- count(key = defaultKey) {
96
- if (this.hasSemaphoreInstance(key)) {
97
- return this.getSemaphoreInstance(key).count;
98
- } else {
99
- return 0;
100
- }
101
- }
102
- /**
103
- *
104
- * @param {string | number} [key]- Optional, the semaphore key.
105
- * @returns {boolean} True if the semaphore and key has locks, false otherwise.
106
- */
107
- hasTasks(key = defaultKey) {
108
- return this.count(key) > 0;
109
- }
110
- /**
111
- *
112
- * @param {Function<T>} fn The function to execute.
113
- * @param {string | number} [key]- Optional, the semaphore key.
114
- * @returns {Promise<T>}
115
- */
116
- async request(fn, key = defaultKey) {
117
- try {
118
- await this.acquire(key);
119
- return await fn();
120
- } finally {
121
- this.release(key);
122
- }
123
- }
124
- /**
125
- * Asynchronously executes `fn` if a lock can be immediately acquired.
126
- * Otherwise, returns null.
127
- *
128
- * @param {Function<T>} fn The function to execute.
129
- * @param {string | number} [key]- Optional, the semaphore key.
130
- * @returns {Promise<T>}
131
- */
132
- async requestIfAvailable(fn, key = defaultKey) {
133
- if (this.canAcquire(key)) {
134
- return this.request(fn, key);
135
- } else {
136
- return null;
137
- }
138
- }
139
- }
140
-
141
- module.exports = Semaphore;
142
- //# sourceMappingURL=index.cjs.js.map
@@ -1 +0,0 @@
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 DELETED
@@ -1,140 +0,0 @@
1
- class SemaphoreItem {
2
- queue;
3
- maxConcurrent;
4
- /**
5
- * The number of locks.
6
- */
7
- count;
8
- constructor(maxConcurrent) {
9
- this.queue = [];
10
- this.maxConcurrent = maxConcurrent;
11
- this.count = 0;
12
- }
13
- get canAcquire() {
14
- return this.count < this.maxConcurrent;
15
- }
16
- acquire() {
17
- if (this.canAcquire) {
18
- this.count++;
19
- return Promise.resolve();
20
- } else {
21
- return new Promise((resolve) => this.queue.push(resolve));
22
- }
23
- }
24
- release() {
25
- const resolveFunc = this.queue.shift();
26
- if (resolveFunc) {
27
- setTimeout(resolveFunc, 0);
28
- } else {
29
- this.count--;
30
- }
31
- }
32
- }
33
- const defaultKey = "_default";
34
- class Semaphore {
35
- semaphoreInstances;
36
- maxConcurrent;
37
- /**
38
- *
39
- * @param {number} [maxConcurrent] The maximum number of concurrent locks.
40
- */
41
- constructor(maxConcurrent = 1) {
42
- this.semaphoreInstances = {};
43
- this.maxConcurrent = maxConcurrent;
44
- }
45
- hasSemaphoreInstance(key = defaultKey) {
46
- return Boolean(this.semaphoreInstances[key]);
47
- }
48
- getSemaphoreInstance(key = defaultKey) {
49
- if (!this.hasSemaphoreInstance(key)) {
50
- this.semaphoreInstances[key] = new SemaphoreItem(this.maxConcurrent);
51
- }
52
- return this.semaphoreInstances[key];
53
- }
54
- /**
55
- *
56
- * @param {string | number} [key]- Optional, the semaphore key.
57
- */
58
- tidy(key = defaultKey) {
59
- if (this.hasSemaphoreInstance(key) && this.getSemaphoreInstance(key).count == 0) {
60
- delete this.semaphoreInstances[key];
61
- }
62
- }
63
- /**
64
- * A synchronous function to determine whether a lock can be acquired.
65
- *
66
- * @param {string | number} [key]- Optional, the semaphore key.
67
- * @returns {boolean} Returns true if the lock on `key` can be acquired, false
68
- * otherwise.
69
- */
70
- canAcquire(key = defaultKey) {
71
- return this.getSemaphoreInstance(key).canAcquire;
72
- }
73
- /**
74
- *
75
- * @param {string | number} [key]- Optional, the semaphore key.
76
- */
77
- acquire(key = defaultKey) {
78
- return this.getSemaphoreInstance(key).acquire();
79
- }
80
- /**
81
- *
82
- * @param {string | number} [key]- Optional, the semaphore key.
83
- */
84
- release(key = defaultKey) {
85
- this.getSemaphoreInstance(key).release();
86
- this.tidy(key);
87
- }
88
- /**
89
- * The number of active locks. Will always be less or equal to `max`.
90
- *
91
- * @param {string | number} [key]- Optional, the semaphore key.
92
- */
93
- count(key = defaultKey) {
94
- if (this.hasSemaphoreInstance(key)) {
95
- return this.getSemaphoreInstance(key).count;
96
- } else {
97
- return 0;
98
- }
99
- }
100
- /**
101
- *
102
- * @param {string | number} [key]- Optional, the semaphore key.
103
- * @returns {boolean} True if the semaphore and key has locks, false otherwise.
104
- */
105
- hasTasks(key = defaultKey) {
106
- return this.count(key) > 0;
107
- }
108
- /**
109
- *
110
- * @param {Function<T>} fn The function to execute.
111
- * @param {string | number} [key]- Optional, the semaphore key.
112
- * @returns {Promise<T>}
113
- */
114
- async request(fn, key = defaultKey) {
115
- try {
116
- await this.acquire(key);
117
- return await fn();
118
- } finally {
119
- this.release(key);
120
- }
121
- }
122
- /**
123
- * Asynchronously executes `fn` if a lock can be immediately acquired.
124
- * Otherwise, returns null.
125
- *
126
- * @param {Function<T>} fn The function to execute.
127
- * @param {string | number} [key]- Optional, the semaphore key.
128
- * @returns {Promise<T>}
129
- */
130
- async requestIfAvailable(fn, key = defaultKey) {
131
- if (this.canAcquire(key)) {
132
- return this.request(fn, key);
133
- } else {
134
- return null;
135
- }
136
- }
137
- }
138
-
139
- export { Semaphore as default };
140
- //# sourceMappingURL=index.es.js.map
@@ -1 +0,0 @@
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/rollup.config.mjs DELETED
@@ -1,37 +0,0 @@
1
- import pkg from './package.json' assert { type: 'json' }
2
- import dts from 'rollup-plugin-dts'
3
- import esbuild from 'rollup-plugin-esbuild'
4
-
5
- const input = 'src/index.ts'
6
-
7
- export default [
8
- {
9
- input,
10
- plugins: [esbuild()],
11
- output: [
12
- {
13
- file: pkg.main,
14
- format: 'cjs',
15
- sourcemap: true,
16
- },
17
- ],
18
- },
19
- {
20
- input,
21
- plugins: [esbuild()],
22
- output: [
23
- {
24
- file: pkg.module,
25
- format: 'es',
26
- sourcemap: true,
27
- },
28
- ],
29
- },
30
- {
31
- input,
32
- plugins: [dts()],
33
- output: {
34
- file: pkg.types,
35
- },
36
- },
37
- ]
package/tsconfig.json DELETED
@@ -1,6 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "esnext",
4
- "esModuleInterop": true
5
- }
6
- }