mini-semaphore 1.3.4 → 1.3.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -1
- package/esm/class.js +1 -1
- package/esm/core.js +1 -1
- package/esm/deque.js +2 -1
- package/esm/extras.js +1 -1
- package/esm/flow-restrictor.js +1 -1
- package/esm/index.js +1 -1
- package/esm/object.js +1 -1
- package/package.json +2 -2
- package/umd/index.js.map +1 -1
- package/webpack/index.js.map +1 -1
package/README.md
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
[](https://circleci.com/gh/jeffy-g/mini-semaphore/tree/master)
|
|
2
|
+

|
|
2
3
|
|
|
3
4
|
# Mini Semaphore (mini-semaphore
|
|
4
5
|
|
package/esm/class.js
CHANGED
package/esm/core.js
CHANGED
package/esm/deque.js
CHANGED
|
@@ -15,6 +15,7 @@ const p2l = (n) => {
|
|
|
15
15
|
return n + 1;
|
|
16
16
|
};
|
|
17
17
|
const gc = (n) => {
|
|
18
|
+
// @ts-ignore typescript cannot allow (undefined | 0) expression
|
|
18
19
|
return p2l(Math.min(Math.max(16, n | 0), 1073741824));
|
|
19
20
|
};
|
|
20
21
|
export class Deque {
|
|
@@ -58,4 +59,4 @@ const rt = (dis, n) => {
|
|
|
58
59
|
const mc = (f + l) & (oc - 1);
|
|
59
60
|
am(dis._a, 0, dis._a, oc, mc);
|
|
60
61
|
}
|
|
61
|
-
};
|
|
62
|
+
};
|
package/esm/extras.js
CHANGED
package/esm/flow-restrictor.js
CHANGED
package/esm/index.js
CHANGED
package/esm/object.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mini-semaphore",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.7",
|
|
4
4
|
"description": "A lightweight version of Semaphore",
|
|
5
5
|
"private": false,
|
|
6
6
|
"main": "./cjs/index.js",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"url": "git+https://github.com/jeffy-g/mini-semaphore.git"
|
|
21
21
|
},
|
|
22
22
|
"engines": {
|
|
23
|
-
"node": ">=10",
|
|
23
|
+
"node": ">=v12.22.10",
|
|
24
24
|
"yarn": "^1.22.4"
|
|
25
25
|
},
|
|
26
26
|
"files": [
|
package/umd/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","mappings":"AAAA;AACA;AADA;AAUA;;ACTA;ACAA;AACA;AAEA;AAAA;;;ACJA;ACCA;AACA;AACA;AAEA;AAAA;;;;;;;;;;;;;;ACLA;AACA;ACAA;AACA;AAOA;AAEA;AAQA;AACA;AAMA;ACVA;AAFA;AAKA;AACA;AACA;;AAKA;AACA;AACA;AAGA;AACA;;AAGA;AACA;AACA;AAGA;AAKA;;AAEA;AACA;;;AAGA;AACA;AACA;AACA;AAEA;AACA;AAzDA;AACA;AAyDA;;ACxDA;AAEA;AACA;AACA;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AAEA;AACA;;;;ACzBA;AAIA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AAEA;AACA;;;;AC1BA;;AAEA;AAEA;AAqDA;AACA;AApDA;AACA;AAIA;AAKA;AA0CA;AAGA;;AA3CA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAGA;AAEA;AAKA;AACA;AAEA;;AAgBA;AAAA;AAQA;AAEA;;AAhEA;AVQA","sources":["webpack://MiniSema/webpack/universalModuleDefinition","webpack://MiniSema/webpack/bootstrap","webpack://MiniSema/webpack/runtime/define property getters","webpack://MiniSema/webpack/runtime/hasOwnProperty shorthand","webpack://MiniSema/webpack/runtime/make namespace object","webpack://MiniSema/./src/extras.ts","webpack://MiniSema/./src/core.ts","webpack://MiniSema/./src/deque.ts","webpack://MiniSema/./src/class.ts","webpack://MiniSema/./src/object.ts","webpack://MiniSema/./src/flow-restrictor.ts"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"MiniSema\"] = factory();\n\telse\n\t\troot[\"MiniSema\"] = factory();\n})(self, function() {\nreturn ","// The require scope\nvar __webpack_require__ = {};\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","export const THROW = () => {\r\n throw new Error(\"mini-semaphore: inconsistent occurred\");\r\n};\r\n","import { THROW } from \"./extras\";\r\nconst box = (z, r) => {\r\n if (z.capacity > 0) {\r\n z.capacity--, r();\r\n }\r\n else {\r\n z.q.push(r);\r\n }\r\n};\r\nexport const acquire = (dis, lazy = true) => {\r\n return new Promise(r => {\r\n if (!lazy) {\r\n box(dis, r);\r\n }\r\n else {\r\n setTimeout(() => box(dis, r), 4);\r\n }\r\n });\r\n};\r\nexport const release = (dis) => {\r\n dis.capacity++;\r\n if (dis.q.length) {\r\n dis.capacity -= 1, (dis.q.shift() || THROW)();\r\n }\r\n if (dis.capacity > dis.limit) {\r\n console.warn(\"inconsistent release!\");\r\n dis.capacity = dis.limit;\r\n }\r\n};\r\n","const am = (src, si, dst, di, len) => {\r\n for (let j = 0; j < len; ++j) {\r\n dst[j + di] = src[j + si];\r\n src[j + si] = void 0;\r\n }\r\n};\r\nconst p2l = (n) => {\r\n n = n >>> 0;\r\n n = n - 1;\r\n n = n | (n >> 1);\r\n n = n | (n >> 2);\r\n n = n | (n >> 4);\r\n n = n | (n >> 8);\r\n n = n | (n >> 16);\r\n return n + 1;\r\n};\r\nconst gc = (n) => {\r\n return p2l(Math.min(Math.max(16, n | 0), 1073741824));\r\n};\r\nexport class Deque {\r\n constructor(ic) {\r\n this._c = gc(ic);\r\n this._l = 0;\r\n this._f = 0;\r\n this._a = [];\r\n }\r\n push(s) {\r\n const l = this._l;\r\n if (this._c < l + 1) {\r\n rt(this, gc(this._c * 1.5 + 16));\r\n }\r\n const i = (this._f + l) & (this._c - 1);\r\n this._a[i] = s;\r\n this._l = l + 1;\r\n }\r\n shift() {\r\n const l = this._l;\r\n if (l === 0) {\r\n return void 0;\r\n }\r\n const f = this._f;\r\n const r = this._a[f];\r\n this._a[f] = void 0;\r\n this._f = (f + 1) & (this._c - 1);\r\n this._l = l - 1;\r\n return r;\r\n }\r\n get length() {\r\n return this._l;\r\n }\r\n}\r\nconst rt = (dis, n) => {\r\n const oc = dis._c;\r\n dis._c = n;\r\n const f = dis._f;\r\n const l = dis._l;\r\n if (f + l > oc) {\r\n const mc = (f + l) & (oc - 1);\r\n am(dis._a, 0, dis._a, oc, mc);\r\n }\r\n};\r\n","import * as core from \"./core\";\r\nimport { Deque } from \"./deque\";\r\nconst a = core.acquire;\r\nconst r = core.release;\r\nexport class MiniSemaphore {\r\n constructor(capacity) {\r\n this.limit = this.capacity = capacity;\r\n this.q = new Deque(capacity);\r\n }\r\n acquire(lazy) {\r\n return a(this, lazy);\r\n }\r\n release() {\r\n r(this);\r\n }\r\n setRestriction(restriction) {\r\n this.limit = this.capacity = restriction;\r\n }\r\n get pending() {\r\n return this.q.length;\r\n }\r\n async flow(process, lazy) {\r\n await a(this, lazy);\r\n try {\r\n return await process();\r\n }\r\n finally {\r\n r(this);\r\n }\r\n }\r\n}\r\n","import * as core from \"./core\";\r\nimport { Deque } from \"./deque\";\r\nconst a = core.acquire;\r\nconst r = core.release;\r\nexport const create = (capacity) => {\r\n return {\r\n capacity,\r\n limit: capacity,\r\n q: new Deque(capacity),\r\n acquire(lazy) {\r\n return a(this, lazy);\r\n },\r\n release() {\r\n r(this);\r\n },\r\n setRestriction(restriction) {\r\n this.limit = this.capacity = restriction;\r\n },\r\n get pending() {\r\n return this.q.length;\r\n },\r\n async flow(process, lazy) {\r\n await a(this, lazy);\r\n try {\r\n return await process();\r\n }\r\n finally {\r\n r(this);\r\n }\r\n }\r\n };\r\n};\r\n","import * as c from \"./class\";\r\nexport var restrictor;\r\n(function (restrictor) {\r\n const { MiniSemaphore: MS } = c;\r\n const internalLock = new MS(1);\r\n let locks = Object.create(null);\r\n const get = async (key, restriction) => {\r\n await internalLock.acquire(false);\r\n let lock = locks[key];\r\n if (!lock) {\r\n locks[key] = lock = new MS(restriction);\r\n }\r\n if (lock.limit !== restriction) {\r\n internalLock.release();\r\n throw new ReferenceError(`Cannot get object with different restriction: key: '${key}', lock.limit: ${lock.limit} <-> restriction: ${restriction},`);\r\n }\r\n internalLock.release();\r\n return lock;\r\n };\r\n restrictor.getLockByKey = async (key) => {\r\n await internalLock.acquire(false);\r\n const l = locks[key];\r\n internalLock.release();\r\n return l;\r\n };\r\n restrictor.cleanup = async (timeSpan, debug) => {\r\n await internalLock.acquire(false);\r\n const currentLocks = locks;\r\n const newLocks = Object.create(null);\r\n const keys = Object.keys(currentLocks);\r\n let eliminatedCount = 0;\r\n let eliminatedKeys;\r\n !timeSpan && (timeSpan = 1);\r\n timeSpan *= 1000;\r\n if (debug) {\r\n eliminatedKeys = [];\r\n }\r\n for (let i = 0, end = keys.length; i < end;) {\r\n const key = keys[i++];\r\n const s = currentLocks[key];\r\n if (s.last && Date.now() - s.last >= timeSpan) {\r\n eliminatedCount++;\r\n if (debug) {\r\n eliminatedKeys.push(key);\r\n }\r\n continue;\r\n }\r\n newLocks[key] = s;\r\n }\r\n locks = newLocks;\r\n internalLock.release();\r\n if (debug) {\r\n console.log(`eliminated: [\\n${eliminatedKeys.join(\",\\n\")}\\n]` +\r\n \"\\n\" +\r\n `lived: [\\n${Object.keys(newLocks).join(\",\\n\")}\\n]`);\r\n }\r\n return eliminatedCount;\r\n };\r\n async function multi(key, restriction, pb) {\r\n const s = await get(key, restriction);\r\n const result = s.flow(pb);\r\n s.last = Date.now();\r\n return result;\r\n }\r\n restrictor.multi = multi;\r\n async function one(key, pb) {\r\n return multi(key, 1, pb);\r\n }\r\n restrictor.one = one;\r\n})(restrictor || (restrictor = {}));\r\n"],"names":[],"sourceRoot":""}
|
|
1
|
+
{"version":3,"file":"index.js","mappings":"AAAA;AACA;AADA;AAUA;;ACTA;ACAA;AACA;AAEA;AAAA;;;ACJA;ACCA;AACA;AACA;AAEA;AAAA;;;;;;;;;;;;;;ACLA;AAEA;ACEA;AACA;AAOA;AAKA;AA4CA;AACA;AAOA;ACnCA;AANA;AAgBA;AAKA;AACA;;AAQA;AACA;AAIA;AAIA;AACA;;AAeA;AACA;AAEA;AAGA;AAKA;;AAeA;AACA;;;AAsBA;AAEA;AACA;AACA;AAEA;AAGA;AApIA;AAEA;AAoIA;;AClGA;AAkCA;AAMA;AACA;;AAQA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAMA;AAEA;AACA;AACA;AAEA;AACA;;;;AC/EA;AAiBA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AAEA;AACA;AACA;AAEA;AACA;;;;ACrCA;;AAEA;AAQA;AAyFA;AACA;AAjFA;AACA;AAIA;AAOA;AAqEA;AAGA;;AA9DA;AAEA;AACA;AAGA;AASA;AAEA;AACA;AAGA;AAEA;AAKA;AACA;AAEA;;AAkBA;AAAA;AAeA;AAWA;;AAnHA;AV/BA","sources":["webpack://MiniSema/webpack/universalModuleDefinition","webpack://MiniSema/webpack/bootstrap","webpack://MiniSema/webpack/runtime/define property getters","webpack://MiniSema/webpack/runtime/hasOwnProperty shorthand","webpack://MiniSema/webpack/runtime/make namespace object","webpack://MiniSema/./src/extras.ts","webpack://MiniSema/./src/core.ts","webpack://MiniSema/./src/deque.ts","webpack://MiniSema/./src/class.ts","webpack://MiniSema/./src/object.ts","webpack://MiniSema/./src/flow-restrictor.ts"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"MiniSema\"] = factory();\n\telse\n\t\troot[\"MiniSema\"] = factory();\n})(self, function() {\nreturn ","// The require scope\nvar __webpack_require__ = {};\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","export const THROW = () => {\r\n /* istanbul ignore next */\r\n throw new Error(\"mini-semaphore: inconsistent occurred\");\r\n};\r\n","import { THROW } from \"./extras\";\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n// class or namespace exports.\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\nconst box = (z, r) => {\r\n if (z.capacity > 0) {\r\n z.capacity--, r();\r\n }\r\n else {\r\n z.q.push(r);\r\n }\r\n};\r\nexport const acquire = (dis, lazy = true) => {\r\n // return !lazy? aqtight(dis): aqlazy(dis);\r\n return new Promise(r => {\r\n // DEVNOTE: Deque object resize event is less likely to occur if overdue by timeout\r\n // - however, this is not the case if the process takes hundreds of ms\r\n if (!lazy) {\r\n box(dis, r);\r\n }\r\n else {\r\n setTimeout(() => box(dis, r), 4);\r\n }\r\n });\r\n};\r\n// export const acquire = (dis: TFlowableLock, lazy = true) => {\r\n// // return !lazy? aqtight(dis): aqlazy(dis);\r\n// return new Promise<void>(resolve => {\r\n// // DEVNOTE: In the following code, you may not be able to get the effect of\r\n// // switching with the `lazy` flag (when tight processing is required\r\n// const box = () => {\r\n// if (dis.capacity > 0) {\r\n// dis.capacity--, resolve();\r\n// }\r\n// else {\r\n// dis.q.push(resolve);\r\n// }\r\n// };\r\n// // DEVNOTE: Deque object resize event is less likely to occur if overdue by timeout\r\n// // - however, this is not the case if the process takes hundreds of ms\r\n// if (!lazy) {\r\n// box();\r\n// } else {\r\n// setTimeout(box, 4);\r\n// }\r\n// // // setTimeout(() => {\r\n// // // if (dis.capacity > 0) {\r\n// // // dis.capacity--, resolve();\r\n// // // }\r\n// // // else {\r\n// // // dis.q.push(resolve);\r\n// // // }\r\n// // // }, 4);\r\n// // if (dis.capacity > 0) {\r\n// // dis.capacity--, resolve();\r\n// // }\r\n// // else {\r\n// // dis.q.push(resolve);\r\n// // }\r\n// });\r\n// };\r\nexport const release = (dis) => {\r\n dis.capacity++;\r\n if (dis.q.length) {\r\n // DEVNOTE: Will never reach `THROW`\r\n dis.capacity -= 1, (dis.q.shift() || THROW)();\r\n }\r\n if (dis.capacity > dis.limit) {\r\n console.warn(\"inconsistent release!\");\r\n dis.capacity = dis.limit;\r\n }\r\n};\r\n// export const flow = async <T>(dis: TFlowableLock, process: () => Promise<T>, lazy?: boolean) => {\r\n// await acquire(dis, lazy);\r\n// try {\r\n// return await process();\r\n// } finally {\r\n// release(dis);\r\n// }\r\n// };\r\n","/**\r\n * arrayMove\r\n *\r\n * @param src\r\n * @param si\r\n * @param dst\r\n * @param di\r\n * @param len\r\n */\r\nconst am = (src, si, dst, di, len) => {\r\n /* istanbul ignore next */\r\n for (let j = 0; j < len; ++j) {\r\n dst[j + di] = src[j + si];\r\n src[j + si] = void 0;\r\n }\r\n};\r\n/**\r\n * pow2AtLeast\r\n * @param n\r\n */\r\nconst p2l = (n) => {\r\n n = n >>> 0;\r\n n = n - 1;\r\n n = n | (n >> 1);\r\n n = n | (n >> 2);\r\n n = n | (n >> 4);\r\n n = n | (n >> 8);\r\n n = n | (n >> 16);\r\n return n + 1;\r\n};\r\n/**\r\n * getCapacity\r\n * @param n\r\n */\r\nconst gc = (n) => {\r\n // @ts-ignore typescript cannot allow (undefined | 0) expression\r\n return p2l(Math.min(Math.max(16, n | 0), 1073741824));\r\n};\r\n/**\r\n * ### Implementation restricted to FIFO\r\n *\r\n * this class is based on https://github.com/petkaantonov/deque/blob/master/js/deque.js\r\n * Released under the MIT License: https://github.com/petkaantonov/deque/blob/master/LICENSE\r\n */\r\nexport class Deque {\r\n /**\r\n * default capacity `16`\r\n * @param ic initial capacity\r\n */\r\n constructor(ic) {\r\n this._c = gc(ic);\r\n this._l = 0;\r\n this._f = 0;\r\n this._a = [];\r\n }\r\n /**\r\n * @param s subject\r\n */\r\n push(s) {\r\n const l = this._l;\r\n /* https://coderwall.com/p/zbc2zw/the-comment-toggle-trick\r\n cc(this, l + 1);\r\n /*/\r\n if (this._c < l + 1) {\r\n rt(this, gc(this._c * 1.5 + 16));\r\n }\r\n //*/\r\n const i = (this._f + l) & (this._c - 1);\r\n this._a[i] = s;\r\n this._l = l + 1;\r\n // return l + 1;\r\n }\r\n // pop() {\r\n // const length = this._length;\r\n // if (length === 0) {\r\n // return void 0;\r\n // }\r\n // const i = (this._front + length - 1) & (this._capacity - 1);\r\n // const ret = this.arr[i];\r\n // this.arr[i] = void 0;\r\n // this._length = length - 1;\r\n // return ret;\r\n // }\r\n shift() {\r\n const l = this._l;\r\n /* istanbul ignore if */\r\n if (l === 0) {\r\n return void 0;\r\n }\r\n const f = this._f;\r\n const r = this._a[f];\r\n this._a[f] = void 0;\r\n this._f = (f + 1) & (this._c - 1);\r\n this._l = l - 1;\r\n return r;\r\n }\r\n // // this._a.forEach(n => n && console.log(n));\r\n // /* istanbul ignore next */\r\n // clear() {\r\n // const l = this._l;\r\n // const f = this._f;\r\n // const c = this._c;\r\n // const a = this._a;\r\n // for (let j = 0; j < l; ++j) {\r\n // a[(f + j) & (c - 1)] = void 0 as unknown as T;\r\n // }\r\n // this._l = 0;\r\n // this._f = 0;\r\n // }\r\n get length() {\r\n return this._l;\r\n }\r\n}\r\n// export namespace Deque {\r\n// export const MAX_CAPACITY = (1 << 30) | 0;\r\n// export const MIN_CAPACITY = 16;\r\n// }\r\n// /**\r\n// * check capacity\r\n// * \r\n// * @param size \r\n// */\r\n// const cc = <T>(dis: Deque<T>, size: number) => {\r\n// if (dis._c < size) {\r\n// rt(dis, gc(dis._c * 1.5 + 16));\r\n// }\r\n// };\r\n/**\r\n * resize to\r\n *\r\n * @param n expected capacity\r\n */\r\nconst rt = (dis, n) => {\r\n // old capacity\r\n const oc = dis._c;\r\n dis._c = n;\r\n const f = dis._f;\r\n const l = dis._l;\r\n if (f + l > oc) {\r\n // move items count\r\n /* istanbul ignore next */\r\n const mc = (f + l) & (oc - 1);\r\n /* istanbul ignore next */\r\n am(dis._a, 0, dis._a, oc, mc);\r\n }\r\n};\r\n","/*\r\n! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n The MIT License (MIT)\r\n\r\n Copyright (C) 2020 jeffy-g hirotom1107@gmail.com\r\n\r\n Permission is hereby granted, free of charge, to any person obtaining a copy\r\n of this software and associated documentation files (the \"Software\"), to deal\r\n in the Software without restriction, including without limitation the rights\r\n to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\n copies of the Software, and to permit persons to whom the Software is\r\n furnished to do so, subject to the following conditions:\r\n\r\n The above copyright notice and this permission notice shall be included in\r\n all copies or substantial portions of the Software.\r\n\r\n THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\n THE SOFTWARE.\r\n - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n*/\r\n/**\r\n * @file minimal implementation of semaphore (class implementation\r\n * @author jeffy-g <hirotom1107@gmail.com>\r\n * @version 1.0\r\n */\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n// imports.\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\nimport * as core from \"./core\";\r\nimport { Deque } from \"./deque\";\r\n// DEVNOTE: export * as ns Syntax - since ts v3.8\r\n// import type {\r\n// TVoidFunction, TFlowableLock\r\n// } from \"./core\";\r\n// export type {\r\n// TVoidFunction, IFlowableLock, ISimplifiedLock,\r\n// } from \"./core\";\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n// constants, types\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\nconst a = core.acquire;\r\nconst r = core.release;\r\n// const f = core.flow;\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n// class or namespace exports.\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n/**\r\n * #### Mini Semaphore\r\n *\r\n * + minimal implementation of semaphore\r\n *\r\n * @example\r\n * import { MiniSemaphore } from \"mini-semaphore\";\r\n *\r\n * const s = new MiniSemaphore(10);\r\n * async function fetchTypeData(type_id) {\r\n * await s.acquire();\r\n * try {\r\n * return fetch(`https://esi.evetech.net/latest/universe/types/${type_id}/`);\r\n * } finally {\r\n * s.release();\r\n * }\r\n * }\r\n *\r\n * //\r\n * // or automatic acquire/release\r\n * //\r\n * async function fetchTypeData(type_id) {\r\n * return s.flow(async () => fetch(`https://esi.evetech.net/latest/universe/types/${type_id}/`));\r\n * }\r\n *\r\n * @date 2020/2/7\r\n * @version 1.0\r\n */\r\nexport class MiniSemaphore {\r\n /**\r\n * constructs a semaphore instance limited at `capacity`\r\n *\r\n * @param capacity limitation of concurrent async by `capacity`\r\n */\r\n constructor(capacity) {\r\n this.limit = this.capacity = capacity;\r\n this.q = new Deque(capacity);\r\n }\r\n /**\r\n * If there is enough capacity, execute the `resolve` immediately\r\n *\r\n * If not, put it in a queue and wait for the currently pending process to execute `release`\r\n */\r\n acquire(lazy) {\r\n return a(this, lazy);\r\n }\r\n release() {\r\n r(this);\r\n }\r\n setRestriction(restriction) {\r\n this.limit = this.capacity = restriction;\r\n }\r\n get pending() {\r\n return this.q.length;\r\n }\r\n /**\r\n * automatic acquire/release\r\n * @param process\r\n */\r\n async flow(process, lazy) {\r\n // return f(this, process, lazy);\r\n await a(this, lazy);\r\n try {\r\n return await process();\r\n }\r\n finally {\r\n r(this);\r\n }\r\n // return this.acquire().then(async () => {\r\n // return await process().then(result => result).finally(() => this.release());\r\n // });\r\n }\r\n}\r\n","/*\r\n! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n The MIT License (MIT)\r\n\r\n Copyright (C) 2020 jeffy-g hirotom1107@gmail.com\r\n\r\n Permission is hereby granted, free of charge, to any person obtaining a copy\r\n of this software and associated documentation files (the \"Software\"), to deal\r\n in the Software without restriction, including without limitation the rights\r\n to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\n copies of the Software, and to permit persons to whom the Software is\r\n furnished to do so, subject to the following conditions:\r\n\r\n The above copyright notice and this permission notice shall be included in\r\n all copies or substantial portions of the Software.\r\n\r\n THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\n THE SOFTWARE.\r\n - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n*/\r\n/**\r\n * @file minimal implementation of semaphore (object implementation\r\n * @author jeffy-g <hirotom1107@gmail.com>\r\n * @version 1.0\r\n */\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n// imports.\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\nimport * as core from \"./core\";\r\nimport { Deque } from \"./deque\";\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n// constants, types\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\nconst a = core.acquire;\r\nconst r = core.release;\r\n// const f = core.flow;\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n// class or namespace exports.\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n/**\r\n * object implementation of `IFlowableLock`\r\n *\r\n * + constructs a semaphore object limited at `capacity`\r\n *\r\n * @param capacity limitation of concurrent async by `capacity`\r\n * @date 2020/2/7\r\n * @version 1.0\r\n */\r\nexport const create = (capacity) => {\r\n return {\r\n capacity,\r\n limit: capacity,\r\n q: new Deque(capacity),\r\n acquire(lazy) {\r\n return a(this, lazy);\r\n },\r\n release() {\r\n r(this);\r\n },\r\n setRestriction(restriction) {\r\n this.limit = this.capacity = restriction;\r\n },\r\n get pending() {\r\n return this.q.length;\r\n },\r\n async flow(process, lazy) {\r\n // return f(this, process, lazy);\r\n await a(this, lazy);\r\n try {\r\n return await process();\r\n }\r\n finally {\r\n r(this);\r\n }\r\n // await this.acquire();\r\n // try {\r\n // // DEVNOTE: Since we use the `await` keyword here,\r\n // // - we simply return a Promise object in the process function on the user side\r\n // return await process();\r\n // } finally {\r\n // this.release();\r\n // }\r\n }\r\n };\r\n};\r\n","/*\r\n! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n The MIT License (MIT)\r\n\r\n Copyright (C) 2020 jeffy-g hirotom1107@gmail.com\r\n\r\n Permission is hereby granted, free of charge, to any person obtaining a copy\r\n of this software and associated documentation files (the \"Software\"), to deal\r\n in the Software without restriction, including without limitation the rights\r\n to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\n copies of the Software, and to permit persons to whom the Software is\r\n furnished to do so, subject to the following conditions:\r\n\r\n The above copyright notice and this permission notice shall be included in\r\n all copies or substantial portions of the Software.\r\n\r\n THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\n THE SOFTWARE.\r\n - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n*/\r\n/**\r\n * @file Utility module using `MiniSemaphore`\r\n * @author jeffy-g <hirotom1107@gmail.com>\r\n * @version 1.0\r\n */\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n// imports.\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\nimport * as c from \"./class\";\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n// class or namespace exports.\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n/**\r\n * Flow Restriction\r\n */\r\nexport var restrictor;\r\n(function (restrictor) {\r\n const { MiniSemaphore: MS } = c;\r\n /**\r\n * @internal\r\n */\r\n const internalLock = new MS(1);\r\n /**\r\n *\r\n */\r\n let locks = Object.create(null);\r\n /**\r\n *\r\n * @param key\r\n * @param restriction\r\n * @throws when different restriction\r\n */\r\n const get = async (key, restriction) => {\r\n // acquire internal lock\r\n await internalLock.acquire(false);\r\n let lock = locks[key];\r\n if (!lock) {\r\n locks[key] = lock = new MS(restriction);\r\n }\r\n if (lock.limit !== restriction) {\r\n // release internal lock\r\n internalLock.release();\r\n throw new ReferenceError(`Cannot get object with different restriction: key: '${key}', lock.limit: ${lock.limit} <-> restriction: ${restriction},`);\r\n }\r\n // release internal lock\r\n internalLock.release();\r\n return lock;\r\n };\r\n /**\r\n * get the semaphore associated with the value of `key`\r\n *\r\n * + ⚠️ The object to be retrieved with `key` must already be created with `multi` ore `one`\r\n *\r\n * @param key\r\n * @returns `IFlowableLock` instance or `undefined`\r\n */\r\n restrictor.getLockByKey = async (key) => {\r\n // acquire internal lock\r\n await internalLock.acquire(false);\r\n const l = locks[key];\r\n // release internal lock\r\n internalLock.release();\r\n return l;\r\n };\r\n /**\r\n * Eliminate unused instances for the `timeSpan` seconds\r\n *\r\n * @param timeSpan specify unit as seconds\r\n * @returns {Promise<number>} eliminated count\r\n * @date 2020/6/19\r\n */\r\n restrictor.cleanup = async (timeSpan, debug) => {\r\n // acquire internal lock\r\n await internalLock.acquire(false);\r\n const currentLocks = locks;\r\n const newLocks = Object.create(null);\r\n const keys = Object.keys(currentLocks);\r\n let eliminatedCount = 0;\r\n let eliminatedKeys;\r\n !timeSpan && (timeSpan = 1); // avoid implicit bug\r\n timeSpan *= 1000;\r\n if (debug) {\r\n eliminatedKeys = [];\r\n }\r\n for (let i = 0, end = keys.length; i < end;) {\r\n const key = keys[i++];\r\n const s = currentLocks[key];\r\n if (s.last && Date.now() - s.last >= timeSpan) {\r\n eliminatedCount++;\r\n if (debug) {\r\n eliminatedKeys.push(key);\r\n }\r\n continue;\r\n }\r\n newLocks[key] = s;\r\n }\r\n // update lock registry\r\n locks = newLocks;\r\n // release internal lock\r\n internalLock.release();\r\n if (debug) {\r\n console.log(`eliminated: [\\n${eliminatedKeys.join(\",\\n\")}\\n]` +\r\n \"\\n\" +\r\n `lived: [\\n${Object.keys(newLocks).join(\",\\n\")}\\n]`);\r\n }\r\n return eliminatedCount;\r\n };\r\n /**\r\n * Allocate a semaphore for each `key`, and limit the number of shares with the value of `restriction`\r\n *\r\n * @param key number or string as tag\r\n * @param restriction number of process restriction\r\n * @param pb the process body\r\n */\r\n async function multi(key, restriction, pb) {\r\n const s = await get(key, restriction);\r\n const result = s.flow(pb);\r\n s.last = Date.now();\r\n return result;\r\n }\r\n restrictor.multi = multi;\r\n /**\r\n * synonym of `multi(key, 1, pb)`\r\n *\r\n * + use case\r\n * * Avoid concurrent requests to the same url\r\n *\r\n * @param key number or string as tag\r\n * @param pb the process body\r\n */\r\n async function one(key, pb) {\r\n return multi(key, 1, pb);\r\n }\r\n restrictor.one = one;\r\n})(restrictor || (restrictor = {}));\r\n// export class FlowRestrictor {\r\n// /**\r\n// * \r\n// */\r\n// private locks: Record<string | number, IFlowableLock> = {};\r\n// // constructor() {}\r\n// /**\r\n// * \r\n// * @param key \r\n// * @param restriction \r\n// */\r\n// private get(key: string | number, restriction: number) {\r\n// let lock = this.locks[key];\r\n// if (!lock) {\r\n// this.locks[key] = lock = new MS(restriction);\r\n// }\r\n// return lock;\r\n// }\r\n// /**\r\n// * Allocate a semaphore for each `key`, and limit the number of shares with the value of` restriction`\r\n// * \r\n// * @param key number or string as tag\r\n// * @param restriction number of process restriction\r\n// * @param pb the process body\r\n// */\r\n// async multi<T>(key: string | number, restriction: number, pb: () => Promise<T>) {\r\n// return this.get(key, restriction).flow(pb);\r\n// }\r\n// /**\r\n// * synonym of `multi(key, 1, pb)`\r\n// * \r\n// * + use case\r\n// * * Avoid concurrent requests to the same url\r\n// * \r\n// * @param key number or string as tag\r\n// * @param pb the process body\r\n// */\r\n// async one<T>(key: string | number, pb: () => Promise<T>) {\r\n// return this.multi(key, 1, pb);\r\n// }\r\n// }\r\n"],"names":[],"sourceRoot":""}
|
package/webpack/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","mappings":";;AACA;ACAA;AACA;AAEA;AAAA;;;ACJA;ACCA;AACA;AACA;AAEA;AAAA;;;;;;;;;;;;;;ACLA;AACA;ACAA;AACA;AAOA;AAEA;AAQA;AACA;AAMA;ACVA;AAFA;AAKA;AACA;AACA;;AAKA;AACA;AACA;AAGA;AACA;;AAGA;AACA;AACA;AAGA;AAKA;;AAEA;AACA;;;AAGA;AACA;AACA;AACA;AAEA;AACA;AAzDA;AACA;AAyDA;;ACxDA;AAEA;AACA;AACA;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AAEA;AACA;;;;ACzBA;AAIA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AAEA;AACA;;;;AC1BA;AACA;AACA;AAEA;AAqDA;AACA;AApDA;AACA;AAIA;AAKA;AA0CA;AAGA;;AA3CA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAGA;AAEA;AAKA;AACA;AAEA;;AAgBA;AAAA;AAQA;AAEA;;AAhEA","sources":["webpack://mini-semaphore/webpack/bootstrap","webpack://mini-semaphore/webpack/runtime/define property getters","webpack://mini-semaphore/webpack/runtime/hasOwnProperty shorthand","webpack://mini-semaphore/webpack/runtime/make namespace object","webpack://mini-semaphore/./src/extras.ts","webpack://mini-semaphore/./src/core.ts","webpack://mini-semaphore/./src/deque.ts","webpack://mini-semaphore/./src/class.ts","webpack://mini-semaphore/./src/object.ts","webpack://mini-semaphore/./src/flow-restrictor.ts"],"sourcesContent":["// The require scope\nvar __webpack_require__ = {};\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","export const THROW = () => {\r\n throw new Error(\"mini-semaphore: inconsistent occurred\");\r\n};\r\n","import { THROW } from \"./extras\";\r\nconst box = (z, r) => {\r\n if (z.capacity > 0) {\r\n z.capacity--, r();\r\n }\r\n else {\r\n z.q.push(r);\r\n }\r\n};\r\nexport const acquire = (dis, lazy = true) => {\r\n return new Promise(r => {\r\n if (!lazy) {\r\n box(dis, r);\r\n }\r\n else {\r\n setTimeout(() => box(dis, r), 4);\r\n }\r\n });\r\n};\r\nexport const release = (dis) => {\r\n dis.capacity++;\r\n if (dis.q.length) {\r\n dis.capacity -= 1, (dis.q.shift() || THROW)();\r\n }\r\n if (dis.capacity > dis.limit) {\r\n console.warn(\"inconsistent release!\");\r\n dis.capacity = dis.limit;\r\n }\r\n};\r\n","const am = (src, si, dst, di, len) => {\r\n for (let j = 0; j < len; ++j) {\r\n dst[j + di] = src[j + si];\r\n src[j + si] = void 0;\r\n }\r\n};\r\nconst p2l = (n) => {\r\n n = n >>> 0;\r\n n = n - 1;\r\n n = n | (n >> 1);\r\n n = n | (n >> 2);\r\n n = n | (n >> 4);\r\n n = n | (n >> 8);\r\n n = n | (n >> 16);\r\n return n + 1;\r\n};\r\nconst gc = (n) => {\r\n return p2l(Math.min(Math.max(16, n | 0), 1073741824));\r\n};\r\nexport class Deque {\r\n constructor(ic) {\r\n this._c = gc(ic);\r\n this._l = 0;\r\n this._f = 0;\r\n this._a = [];\r\n }\r\n push(s) {\r\n const l = this._l;\r\n if (this._c < l + 1) {\r\n rt(this, gc(this._c * 1.5 + 16));\r\n }\r\n const i = (this._f + l) & (this._c - 1);\r\n this._a[i] = s;\r\n this._l = l + 1;\r\n }\r\n shift() {\r\n const l = this._l;\r\n if (l === 0) {\r\n return void 0;\r\n }\r\n const f = this._f;\r\n const r = this._a[f];\r\n this._a[f] = void 0;\r\n this._f = (f + 1) & (this._c - 1);\r\n this._l = l - 1;\r\n return r;\r\n }\r\n get length() {\r\n return this._l;\r\n }\r\n}\r\nconst rt = (dis, n) => {\r\n const oc = dis._c;\r\n dis._c = n;\r\n const f = dis._f;\r\n const l = dis._l;\r\n if (f + l > oc) {\r\n const mc = (f + l) & (oc - 1);\r\n am(dis._a, 0, dis._a, oc, mc);\r\n }\r\n};\r\n","import * as core from \"./core\";\r\nimport { Deque } from \"./deque\";\r\nconst a = core.acquire;\r\nconst r = core.release;\r\nexport class MiniSemaphore {\r\n constructor(capacity) {\r\n this.limit = this.capacity = capacity;\r\n this.q = new Deque(capacity);\r\n }\r\n acquire(lazy) {\r\n return a(this, lazy);\r\n }\r\n release() {\r\n r(this);\r\n }\r\n setRestriction(restriction) {\r\n this.limit = this.capacity = restriction;\r\n }\r\n get pending() {\r\n return this.q.length;\r\n }\r\n async flow(process, lazy) {\r\n await a(this, lazy);\r\n try {\r\n return await process();\r\n }\r\n finally {\r\n r(this);\r\n }\r\n }\r\n}\r\n","import * as core from \"./core\";\r\nimport { Deque } from \"./deque\";\r\nconst a = core.acquire;\r\nconst r = core.release;\r\nexport const create = (capacity) => {\r\n return {\r\n capacity,\r\n limit: capacity,\r\n q: new Deque(capacity),\r\n acquire(lazy) {\r\n return a(this, lazy);\r\n },\r\n release() {\r\n r(this);\r\n },\r\n setRestriction(restriction) {\r\n this.limit = this.capacity = restriction;\r\n },\r\n get pending() {\r\n return this.q.length;\r\n },\r\n async flow(process, lazy) {\r\n await a(this, lazy);\r\n try {\r\n return await process();\r\n }\r\n finally {\r\n r(this);\r\n }\r\n }\r\n };\r\n};\r\n","import * as c from \"./class\";\r\nexport var restrictor;\r\n(function (restrictor) {\r\n const { MiniSemaphore: MS } = c;\r\n const internalLock = new MS(1);\r\n let locks = Object.create(null);\r\n const get = async (key, restriction) => {\r\n await internalLock.acquire(false);\r\n let lock = locks[key];\r\n if (!lock) {\r\n locks[key] = lock = new MS(restriction);\r\n }\r\n if (lock.limit !== restriction) {\r\n internalLock.release();\r\n throw new ReferenceError(`Cannot get object with different restriction: key: '${key}', lock.limit: ${lock.limit} <-> restriction: ${restriction},`);\r\n }\r\n internalLock.release();\r\n return lock;\r\n };\r\n restrictor.getLockByKey = async (key) => {\r\n await internalLock.acquire(false);\r\n const l = locks[key];\r\n internalLock.release();\r\n return l;\r\n };\r\n restrictor.cleanup = async (timeSpan, debug) => {\r\n await internalLock.acquire(false);\r\n const currentLocks = locks;\r\n const newLocks = Object.create(null);\r\n const keys = Object.keys(currentLocks);\r\n let eliminatedCount = 0;\r\n let eliminatedKeys;\r\n !timeSpan && (timeSpan = 1);\r\n timeSpan *= 1000;\r\n if (debug) {\r\n eliminatedKeys = [];\r\n }\r\n for (let i = 0, end = keys.length; i < end;) {\r\n const key = keys[i++];\r\n const s = currentLocks[key];\r\n if (s.last && Date.now() - s.last >= timeSpan) {\r\n eliminatedCount++;\r\n if (debug) {\r\n eliminatedKeys.push(key);\r\n }\r\n continue;\r\n }\r\n newLocks[key] = s;\r\n }\r\n locks = newLocks;\r\n internalLock.release();\r\n if (debug) {\r\n console.log(`eliminated: [\\n${eliminatedKeys.join(\",\\n\")}\\n]` +\r\n \"\\n\" +\r\n `lived: [\\n${Object.keys(newLocks).join(\",\\n\")}\\n]`);\r\n }\r\n return eliminatedCount;\r\n };\r\n async function multi(key, restriction, pb) {\r\n const s = await get(key, restriction);\r\n const result = s.flow(pb);\r\n s.last = Date.now();\r\n return result;\r\n }\r\n restrictor.multi = multi;\r\n async function one(key, pb) {\r\n return multi(key, 1, pb);\r\n }\r\n restrictor.one = one;\r\n})(restrictor || (restrictor = {}));\r\n"],"names":[],"sourceRoot":""}
|
|
1
|
+
{"version":3,"file":"index.js","mappings":";;AACA;ACAA;AACA;AAEA;AAAA;;;ACJA;ACCA;AACA;AACA;AAEA;AAAA;;;;;;;;;;;;;;ACLA;AAEA;ACEA;AACA;AAOA;AAKA;AA4CA;AACA;AAOA;ACnCA;AANA;AAgBA;AAKA;AACA;;AAQA;AACA;AAIA;AAIA;AACA;;AAeA;AACA;AAEA;AAGA;AAKA;;AAeA;AACA;;;AAsBA;AAEA;AACA;AACA;AAEA;AAGA;AApIA;AAEA;AAoIA;;AClGA;AAkCA;AAMA;AACA;;AAQA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAMA;AAEA;AACA;AACA;AAEA;AACA;;;;AC/EA;AAiBA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AAEA;AACA;AACA;AAEA;AACA;;;;ACrCA;AACA;AACA;AAQA;AAyFA;AACA;AAjFA;AACA;AAIA;AAOA;AAqEA;AAGA;;AA9DA;AAEA;AACA;AAGA;AASA;AAEA;AACA;AAGA;AAEA;AAKA;AACA;AAEA;;AAkBA;AAAA;AAeA;AAWA;;AAnHA","sources":["webpack://mini-semaphore/webpack/bootstrap","webpack://mini-semaphore/webpack/runtime/define property getters","webpack://mini-semaphore/webpack/runtime/hasOwnProperty shorthand","webpack://mini-semaphore/webpack/runtime/make namespace object","webpack://mini-semaphore/./src/extras.ts","webpack://mini-semaphore/./src/core.ts","webpack://mini-semaphore/./src/deque.ts","webpack://mini-semaphore/./src/class.ts","webpack://mini-semaphore/./src/object.ts","webpack://mini-semaphore/./src/flow-restrictor.ts"],"sourcesContent":["// The require scope\nvar __webpack_require__ = {};\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","export const THROW = () => {\r\n /* istanbul ignore next */\r\n throw new Error(\"mini-semaphore: inconsistent occurred\");\r\n};\r\n","import { THROW } from \"./extras\";\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n// class or namespace exports.\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\nconst box = (z, r) => {\r\n if (z.capacity > 0) {\r\n z.capacity--, r();\r\n }\r\n else {\r\n z.q.push(r);\r\n }\r\n};\r\nexport const acquire = (dis, lazy = true) => {\r\n // return !lazy? aqtight(dis): aqlazy(dis);\r\n return new Promise(r => {\r\n // DEVNOTE: Deque object resize event is less likely to occur if overdue by timeout\r\n // - however, this is not the case if the process takes hundreds of ms\r\n if (!lazy) {\r\n box(dis, r);\r\n }\r\n else {\r\n setTimeout(() => box(dis, r), 4);\r\n }\r\n });\r\n};\r\n// export const acquire = (dis: TFlowableLock, lazy = true) => {\r\n// // return !lazy? aqtight(dis): aqlazy(dis);\r\n// return new Promise<void>(resolve => {\r\n// // DEVNOTE: In the following code, you may not be able to get the effect of\r\n// // switching with the `lazy` flag (when tight processing is required\r\n// const box = () => {\r\n// if (dis.capacity > 0) {\r\n// dis.capacity--, resolve();\r\n// }\r\n// else {\r\n// dis.q.push(resolve);\r\n// }\r\n// };\r\n// // DEVNOTE: Deque object resize event is less likely to occur if overdue by timeout\r\n// // - however, this is not the case if the process takes hundreds of ms\r\n// if (!lazy) {\r\n// box();\r\n// } else {\r\n// setTimeout(box, 4);\r\n// }\r\n// // // setTimeout(() => {\r\n// // // if (dis.capacity > 0) {\r\n// // // dis.capacity--, resolve();\r\n// // // }\r\n// // // else {\r\n// // // dis.q.push(resolve);\r\n// // // }\r\n// // // }, 4);\r\n// // if (dis.capacity > 0) {\r\n// // dis.capacity--, resolve();\r\n// // }\r\n// // else {\r\n// // dis.q.push(resolve);\r\n// // }\r\n// });\r\n// };\r\nexport const release = (dis) => {\r\n dis.capacity++;\r\n if (dis.q.length) {\r\n // DEVNOTE: Will never reach `THROW`\r\n dis.capacity -= 1, (dis.q.shift() || THROW)();\r\n }\r\n if (dis.capacity > dis.limit) {\r\n console.warn(\"inconsistent release!\");\r\n dis.capacity = dis.limit;\r\n }\r\n};\r\n// export const flow = async <T>(dis: TFlowableLock, process: () => Promise<T>, lazy?: boolean) => {\r\n// await acquire(dis, lazy);\r\n// try {\r\n// return await process();\r\n// } finally {\r\n// release(dis);\r\n// }\r\n// };\r\n","/**\r\n * arrayMove\r\n *\r\n * @param src\r\n * @param si\r\n * @param dst\r\n * @param di\r\n * @param len\r\n */\r\nconst am = (src, si, dst, di, len) => {\r\n /* istanbul ignore next */\r\n for (let j = 0; j < len; ++j) {\r\n dst[j + di] = src[j + si];\r\n src[j + si] = void 0;\r\n }\r\n};\r\n/**\r\n * pow2AtLeast\r\n * @param n\r\n */\r\nconst p2l = (n) => {\r\n n = n >>> 0;\r\n n = n - 1;\r\n n = n | (n >> 1);\r\n n = n | (n >> 2);\r\n n = n | (n >> 4);\r\n n = n | (n >> 8);\r\n n = n | (n >> 16);\r\n return n + 1;\r\n};\r\n/**\r\n * getCapacity\r\n * @param n\r\n */\r\nconst gc = (n) => {\r\n // @ts-ignore typescript cannot allow (undefined | 0) expression\r\n return p2l(Math.min(Math.max(16, n | 0), 1073741824));\r\n};\r\n/**\r\n * ### Implementation restricted to FIFO\r\n *\r\n * this class is based on https://github.com/petkaantonov/deque/blob/master/js/deque.js\r\n * Released under the MIT License: https://github.com/petkaantonov/deque/blob/master/LICENSE\r\n */\r\nexport class Deque {\r\n /**\r\n * default capacity `16`\r\n * @param ic initial capacity\r\n */\r\n constructor(ic) {\r\n this._c = gc(ic);\r\n this._l = 0;\r\n this._f = 0;\r\n this._a = [];\r\n }\r\n /**\r\n * @param s subject\r\n */\r\n push(s) {\r\n const l = this._l;\r\n /* https://coderwall.com/p/zbc2zw/the-comment-toggle-trick\r\n cc(this, l + 1);\r\n /*/\r\n if (this._c < l + 1) {\r\n rt(this, gc(this._c * 1.5 + 16));\r\n }\r\n //*/\r\n const i = (this._f + l) & (this._c - 1);\r\n this._a[i] = s;\r\n this._l = l + 1;\r\n // return l + 1;\r\n }\r\n // pop() {\r\n // const length = this._length;\r\n // if (length === 0) {\r\n // return void 0;\r\n // }\r\n // const i = (this._front + length - 1) & (this._capacity - 1);\r\n // const ret = this.arr[i];\r\n // this.arr[i] = void 0;\r\n // this._length = length - 1;\r\n // return ret;\r\n // }\r\n shift() {\r\n const l = this._l;\r\n /* istanbul ignore if */\r\n if (l === 0) {\r\n return void 0;\r\n }\r\n const f = this._f;\r\n const r = this._a[f];\r\n this._a[f] = void 0;\r\n this._f = (f + 1) & (this._c - 1);\r\n this._l = l - 1;\r\n return r;\r\n }\r\n // // this._a.forEach(n => n && console.log(n));\r\n // /* istanbul ignore next */\r\n // clear() {\r\n // const l = this._l;\r\n // const f = this._f;\r\n // const c = this._c;\r\n // const a = this._a;\r\n // for (let j = 0; j < l; ++j) {\r\n // a[(f + j) & (c - 1)] = void 0 as unknown as T;\r\n // }\r\n // this._l = 0;\r\n // this._f = 0;\r\n // }\r\n get length() {\r\n return this._l;\r\n }\r\n}\r\n// export namespace Deque {\r\n// export const MAX_CAPACITY = (1 << 30) | 0;\r\n// export const MIN_CAPACITY = 16;\r\n// }\r\n// /**\r\n// * check capacity\r\n// * \r\n// * @param size \r\n// */\r\n// const cc = <T>(dis: Deque<T>, size: number) => {\r\n// if (dis._c < size) {\r\n// rt(dis, gc(dis._c * 1.5 + 16));\r\n// }\r\n// };\r\n/**\r\n * resize to\r\n *\r\n * @param n expected capacity\r\n */\r\nconst rt = (dis, n) => {\r\n // old capacity\r\n const oc = dis._c;\r\n dis._c = n;\r\n const f = dis._f;\r\n const l = dis._l;\r\n if (f + l > oc) {\r\n // move items count\r\n /* istanbul ignore next */\r\n const mc = (f + l) & (oc - 1);\r\n /* istanbul ignore next */\r\n am(dis._a, 0, dis._a, oc, mc);\r\n }\r\n};\r\n","/*\r\n! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n The MIT License (MIT)\r\n\r\n Copyright (C) 2020 jeffy-g hirotom1107@gmail.com\r\n\r\n Permission is hereby granted, free of charge, to any person obtaining a copy\r\n of this software and associated documentation files (the \"Software\"), to deal\r\n in the Software without restriction, including without limitation the rights\r\n to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\n copies of the Software, and to permit persons to whom the Software is\r\n furnished to do so, subject to the following conditions:\r\n\r\n The above copyright notice and this permission notice shall be included in\r\n all copies or substantial portions of the Software.\r\n\r\n THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\n THE SOFTWARE.\r\n - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n*/\r\n/**\r\n * @file minimal implementation of semaphore (class implementation\r\n * @author jeffy-g <hirotom1107@gmail.com>\r\n * @version 1.0\r\n */\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n// imports.\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\nimport * as core from \"./core\";\r\nimport { Deque } from \"./deque\";\r\n// DEVNOTE: export * as ns Syntax - since ts v3.8\r\n// import type {\r\n// TVoidFunction, TFlowableLock\r\n// } from \"./core\";\r\n// export type {\r\n// TVoidFunction, IFlowableLock, ISimplifiedLock,\r\n// } from \"./core\";\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n// constants, types\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\nconst a = core.acquire;\r\nconst r = core.release;\r\n// const f = core.flow;\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n// class or namespace exports.\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n/**\r\n * #### Mini Semaphore\r\n *\r\n * + minimal implementation of semaphore\r\n *\r\n * @example\r\n * import { MiniSemaphore } from \"mini-semaphore\";\r\n *\r\n * const s = new MiniSemaphore(10);\r\n * async function fetchTypeData(type_id) {\r\n * await s.acquire();\r\n * try {\r\n * return fetch(`https://esi.evetech.net/latest/universe/types/${type_id}/`);\r\n * } finally {\r\n * s.release();\r\n * }\r\n * }\r\n *\r\n * //\r\n * // or automatic acquire/release\r\n * //\r\n * async function fetchTypeData(type_id) {\r\n * return s.flow(async () => fetch(`https://esi.evetech.net/latest/universe/types/${type_id}/`));\r\n * }\r\n *\r\n * @date 2020/2/7\r\n * @version 1.0\r\n */\r\nexport class MiniSemaphore {\r\n /**\r\n * constructs a semaphore instance limited at `capacity`\r\n *\r\n * @param capacity limitation of concurrent async by `capacity`\r\n */\r\n constructor(capacity) {\r\n this.limit = this.capacity = capacity;\r\n this.q = new Deque(capacity);\r\n }\r\n /**\r\n * If there is enough capacity, execute the `resolve` immediately\r\n *\r\n * If not, put it in a queue and wait for the currently pending process to execute `release`\r\n */\r\n acquire(lazy) {\r\n return a(this, lazy);\r\n }\r\n release() {\r\n r(this);\r\n }\r\n setRestriction(restriction) {\r\n this.limit = this.capacity = restriction;\r\n }\r\n get pending() {\r\n return this.q.length;\r\n }\r\n /**\r\n * automatic acquire/release\r\n * @param process\r\n */\r\n async flow(process, lazy) {\r\n // return f(this, process, lazy);\r\n await a(this, lazy);\r\n try {\r\n return await process();\r\n }\r\n finally {\r\n r(this);\r\n }\r\n // return this.acquire().then(async () => {\r\n // return await process().then(result => result).finally(() => this.release());\r\n // });\r\n }\r\n}\r\n","/*\r\n! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n The MIT License (MIT)\r\n\r\n Copyright (C) 2020 jeffy-g hirotom1107@gmail.com\r\n\r\n Permission is hereby granted, free of charge, to any person obtaining a copy\r\n of this software and associated documentation files (the \"Software\"), to deal\r\n in the Software without restriction, including without limitation the rights\r\n to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\n copies of the Software, and to permit persons to whom the Software is\r\n furnished to do so, subject to the following conditions:\r\n\r\n The above copyright notice and this permission notice shall be included in\r\n all copies or substantial portions of the Software.\r\n\r\n THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\n THE SOFTWARE.\r\n - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n*/\r\n/**\r\n * @file minimal implementation of semaphore (object implementation\r\n * @author jeffy-g <hirotom1107@gmail.com>\r\n * @version 1.0\r\n */\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n// imports.\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\nimport * as core from \"./core\";\r\nimport { Deque } from \"./deque\";\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n// constants, types\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\nconst a = core.acquire;\r\nconst r = core.release;\r\n// const f = core.flow;\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n// class or namespace exports.\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n/**\r\n * object implementation of `IFlowableLock`\r\n *\r\n * + constructs a semaphore object limited at `capacity`\r\n *\r\n * @param capacity limitation of concurrent async by `capacity`\r\n * @date 2020/2/7\r\n * @version 1.0\r\n */\r\nexport const create = (capacity) => {\r\n return {\r\n capacity,\r\n limit: capacity,\r\n q: new Deque(capacity),\r\n acquire(lazy) {\r\n return a(this, lazy);\r\n },\r\n release() {\r\n r(this);\r\n },\r\n setRestriction(restriction) {\r\n this.limit = this.capacity = restriction;\r\n },\r\n get pending() {\r\n return this.q.length;\r\n },\r\n async flow(process, lazy) {\r\n // return f(this, process, lazy);\r\n await a(this, lazy);\r\n try {\r\n return await process();\r\n }\r\n finally {\r\n r(this);\r\n }\r\n // await this.acquire();\r\n // try {\r\n // // DEVNOTE: Since we use the `await` keyword here,\r\n // // - we simply return a Promise object in the process function on the user side\r\n // return await process();\r\n // } finally {\r\n // this.release();\r\n // }\r\n }\r\n };\r\n};\r\n","/*\r\n! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n The MIT License (MIT)\r\n\r\n Copyright (C) 2020 jeffy-g hirotom1107@gmail.com\r\n\r\n Permission is hereby granted, free of charge, to any person obtaining a copy\r\n of this software and associated documentation files (the \"Software\"), to deal\r\n in the Software without restriction, including without limitation the rights\r\n to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\n copies of the Software, and to permit persons to whom the Software is\r\n furnished to do so, subject to the following conditions:\r\n\r\n The above copyright notice and this permission notice shall be included in\r\n all copies or substantial portions of the Software.\r\n\r\n THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\n THE SOFTWARE.\r\n - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n*/\r\n/**\r\n * @file Utility module using `MiniSemaphore`\r\n * @author jeffy-g <hirotom1107@gmail.com>\r\n * @version 1.0\r\n */\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n// imports.\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\nimport * as c from \"./class\";\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n// class or namespace exports.\r\n// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n/**\r\n * Flow Restriction\r\n */\r\nexport var restrictor;\r\n(function (restrictor) {\r\n const { MiniSemaphore: MS } = c;\r\n /**\r\n * @internal\r\n */\r\n const internalLock = new MS(1);\r\n /**\r\n *\r\n */\r\n let locks = Object.create(null);\r\n /**\r\n *\r\n * @param key\r\n * @param restriction\r\n * @throws when different restriction\r\n */\r\n const get = async (key, restriction) => {\r\n // acquire internal lock\r\n await internalLock.acquire(false);\r\n let lock = locks[key];\r\n if (!lock) {\r\n locks[key] = lock = new MS(restriction);\r\n }\r\n if (lock.limit !== restriction) {\r\n // release internal lock\r\n internalLock.release();\r\n throw new ReferenceError(`Cannot get object with different restriction: key: '${key}', lock.limit: ${lock.limit} <-> restriction: ${restriction},`);\r\n }\r\n // release internal lock\r\n internalLock.release();\r\n return lock;\r\n };\r\n /**\r\n * get the semaphore associated with the value of `key`\r\n *\r\n * + ⚠️ The object to be retrieved with `key` must already be created with `multi` ore `one`\r\n *\r\n * @param key\r\n * @returns `IFlowableLock` instance or `undefined`\r\n */\r\n restrictor.getLockByKey = async (key) => {\r\n // acquire internal lock\r\n await internalLock.acquire(false);\r\n const l = locks[key];\r\n // release internal lock\r\n internalLock.release();\r\n return l;\r\n };\r\n /**\r\n * Eliminate unused instances for the `timeSpan` seconds\r\n *\r\n * @param timeSpan specify unit as seconds\r\n * @returns {Promise<number>} eliminated count\r\n * @date 2020/6/19\r\n */\r\n restrictor.cleanup = async (timeSpan, debug) => {\r\n // acquire internal lock\r\n await internalLock.acquire(false);\r\n const currentLocks = locks;\r\n const newLocks = Object.create(null);\r\n const keys = Object.keys(currentLocks);\r\n let eliminatedCount = 0;\r\n let eliminatedKeys;\r\n !timeSpan && (timeSpan = 1); // avoid implicit bug\r\n timeSpan *= 1000;\r\n if (debug) {\r\n eliminatedKeys = [];\r\n }\r\n for (let i = 0, end = keys.length; i < end;) {\r\n const key = keys[i++];\r\n const s = currentLocks[key];\r\n if (s.last && Date.now() - s.last >= timeSpan) {\r\n eliminatedCount++;\r\n if (debug) {\r\n eliminatedKeys.push(key);\r\n }\r\n continue;\r\n }\r\n newLocks[key] = s;\r\n }\r\n // update lock registry\r\n locks = newLocks;\r\n // release internal lock\r\n internalLock.release();\r\n if (debug) {\r\n console.log(`eliminated: [\\n${eliminatedKeys.join(\",\\n\")}\\n]` +\r\n \"\\n\" +\r\n `lived: [\\n${Object.keys(newLocks).join(\",\\n\")}\\n]`);\r\n }\r\n return eliminatedCount;\r\n };\r\n /**\r\n * Allocate a semaphore for each `key`, and limit the number of shares with the value of `restriction`\r\n *\r\n * @param key number or string as tag\r\n * @param restriction number of process restriction\r\n * @param pb the process body\r\n */\r\n async function multi(key, restriction, pb) {\r\n const s = await get(key, restriction);\r\n const result = s.flow(pb);\r\n s.last = Date.now();\r\n return result;\r\n }\r\n restrictor.multi = multi;\r\n /**\r\n * synonym of `multi(key, 1, pb)`\r\n *\r\n * + use case\r\n * * Avoid concurrent requests to the same url\r\n *\r\n * @param key number or string as tag\r\n * @param pb the process body\r\n */\r\n async function one(key, pb) {\r\n return multi(key, 1, pb);\r\n }\r\n restrictor.one = one;\r\n})(restrictor || (restrictor = {}));\r\n// export class FlowRestrictor {\r\n// /**\r\n// * \r\n// */\r\n// private locks: Record<string | number, IFlowableLock> = {};\r\n// // constructor() {}\r\n// /**\r\n// * \r\n// * @param key \r\n// * @param restriction \r\n// */\r\n// private get(key: string | number, restriction: number) {\r\n// let lock = this.locks[key];\r\n// if (!lock) {\r\n// this.locks[key] = lock = new MS(restriction);\r\n// }\r\n// return lock;\r\n// }\r\n// /**\r\n// * Allocate a semaphore for each `key`, and limit the number of shares with the value of` restriction`\r\n// * \r\n// * @param key number or string as tag\r\n// * @param restriction number of process restriction\r\n// * @param pb the process body\r\n// */\r\n// async multi<T>(key: string | number, restriction: number, pb: () => Promise<T>) {\r\n// return this.get(key, restriction).flow(pb);\r\n// }\r\n// /**\r\n// * synonym of `multi(key, 1, pb)`\r\n// * \r\n// * + use case\r\n// * * Avoid concurrent requests to the same url\r\n// * \r\n// * @param key number or string as tag\r\n// * @param pb the process body\r\n// */\r\n// async one<T>(key: string | number, pb: () => Promise<T>) {\r\n// return this.multi(key, 1, pb);\r\n// }\r\n// }\r\n"],"names":[],"sourceRoot":""}
|