fix: prepare code to fix pool internal IPC for cluster worker
authorJérôme Benoit <jerome.benoit@sap.com>
Mon, 26 Jun 2023 19:08:32 +0000 (21:08 +0200)
committerJérôme Benoit <jerome.benoit@sap.com>
Mon, 26 Jun 2023 19:08:32 +0000 (21:08 +0200)
Signed-off-by: Jérôme Benoit <jerome.benoit@sap.com>
38 files changed:
.eslintrc.js
benchmarks/README.md
benchmarks/internal/cluster-worker.mjs
benchmarks/internal/thread-worker.mjs
benchmarks/versus-external-pools/fixed-microjob.mjs [deleted file]
benchmarks/versus-external-pools/fixed-threadwork.mjs [deleted file]
benchmarks/versus-external-pools/hyperfine_benchmarks.sh
benchmarks/versus-external-pools/package.json
benchmarks/versus-external-pools/pnpm-lock.yaml
benchmarks/versus-external-pools/pool-threadwork.mjs [deleted file]
benchmarks/versus-external-pools/threadjs.mjs [deleted file]
benchmarks/versus-external-pools/workers/threadjs/function-to-bench-worker.mjs [deleted file]
package.json
pnpm-lock.yaml
src/index.ts
src/pools/abstract-pool.ts
src/pools/cluster/dynamic.ts
src/pools/cluster/fixed.ts
src/pools/pool.ts
src/pools/selection-strategies/abstract-worker-choice-strategy.ts
src/pools/selection-strategies/fair-share-worker-choice-strategy.ts
src/pools/selection-strategies/interleaved-weighted-round-robin-worker-choice-strategy.ts
src/pools/selection-strategies/least-busy-worker-choice-strategy.ts
src/pools/selection-strategies/least-elu-worker-choice-strategy.ts
src/pools/selection-strategies/least-used-worker-choice-strategy.ts
src/pools/selection-strategies/round-robin-worker-choice-strategy.ts
src/pools/selection-strategies/weighted-round-robin-worker-choice-strategy.ts
src/pools/selection-strategies/worker-choice-strategy-context.ts
src/pools/thread/dynamic.ts
src/pools/thread/fixed.ts
src/pools/worker.ts
src/queue.ts
src/utility-types.ts
src/worker/abstract-worker.ts
src/worker/cluster-worker.ts
src/worker/thread-worker.ts
src/worker/worker-functions.ts
tests/worker/abstract-worker.test.js

index 5d9c45bfded4540646464d5bef191deb85360260..e160b189d2394e46a51c9572026d1fd0aa14a1ef 100644 (file)
@@ -43,6 +43,7 @@ module.exports = defineConfig({
           'builtins',
           'christopher',
           'cjs',
+          'cloneable',
           'comparator',
           'cpu',
           'cpus',
index 3b7f0702557e379169ee8b16586bec6ba6ebefa5..400bb152802bbfb6598afdb786df7bc9614d39b3 100644 (file)
@@ -18,9 +18,6 @@ External pools with which we compared the poolifier results:
 - [workerpool](https://github.com/josdejong/workerpool)
 - [worker-nodes](https://github.com/allegro/node-worker-nodes)
 - [node-worker-threads-pool](https://github.com/SUCHMOKUO/node-worker-threads-pool)
-- [threads.js](https://github.com/andywer/threads.js/)
-- [threadwork](https://github.com/kevlened/threadwork)
-- [microjob](https://github.com/wilk/microjob)
 
 Those are our results:
 
@@ -33,6 +30,9 @@ External pools with which we used to compare the poolifier results:
 <!-- - [node-worker-threads-pool](https://github.com/SUCHMOKUO/node-worker-threads-pool): removed because it does not support dynamic modules import or import outside the worker function. The worker function is expected to be self-contained, which makes it difficult to use in real world application without ugly hacks. -->
 
 - [worker-threads-pool](https://github.com/watson/worker-threads-pool): removed because unmaintained since more than 4 years.
+- [threadwork](https://github.com/kevlened/threadwork): removed because unmaintained since more than 3 years.
+- [microjob](https://github.com/wilk/microjob): removed because unmaintained since more than 5 years.
+- [threads.js](https://github.com/andywer/threads.js/): removed because not a threads pool.
 
 ### Internal
 
index 50e4a324a98a580206db83a3dc3dc40bf80efc32..e8d16d217313457bffccb269642644207d1292f0 100644 (file)
@@ -5,7 +5,7 @@ import { WorkerFunctions } from '../benchmarks-types.mjs'
 
 const debug = false
 
-function yourFunction (data) {
+function workerFunction (data) {
   data = data || {}
   data.function = data.function || WorkerFunctions.jsonIntegerSerialization
   executeWorkerFunction(data)
@@ -13,4 +13,4 @@ function yourFunction (data) {
   return { ok: 1 }
 }
 
-export default new ClusterWorker(yourFunction)
+export default new ClusterWorker(workerFunction)
index 4e3c10500e0edc8fde098d49fc633d585336fc0a..c1cd01414830aa9eaaa88bd2d7a0a3d0a4854ab4 100644 (file)
@@ -5,7 +5,7 @@ import { WorkerFunctions } from '../benchmarks-types.mjs'
 
 const debug = false
 
-function yourFunction (data) {
+function workerFunction (data) {
   data = data || {}
   data.function = data.function || WorkerFunctions.jsonIntegerSerialization
   executeWorkerFunction(data)
@@ -13,4 +13,4 @@ function yourFunction (data) {
   return { ok: 1 }
 }
 
-export default new ThreadWorker(yourFunction)
+export default new ThreadWorker(workerFunction)
diff --git a/benchmarks/versus-external-pools/fixed-microjob.mjs b/benchmarks/versus-external-pools/fixed-microjob.mjs
deleted file mode 100644 (file)
index 8507586..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-// IMPORT LIBRARIES
-import { job, start } from 'microjob'
-// FINISH IMPORT LIBRARIES
-// IMPORT FUNCTION TO BENCH
-import functionToBench from './functions/function-to-bench.js'
-// FINISH IMPORT FUNCTION TO BENCH
-const size = parseInt(process.env.POOL_SIZE)
-const iterations = parseInt(process.env.NUM_ITERATIONS)
-const data = {
-  test: 'MYBENCH',
-  taskType: process.env.TASK_TYPE,
-  taskSize: parseInt(process.env.TASK_SIZE)
-}
-
-async function run () {
-  await start({ maxWorkers: size })
-  const promises = []
-  for (let i = 0; i < iterations; i++) {
-    promises.push(
-      job(
-        data => {
-          functionToBench(data)
-        },
-        { data, ctx: { functionToBench } }
-      )
-    )
-  }
-  await Promise.all(promises)
-  // eslint-disable-next-line n/no-process-exit
-  process.exit()
-}
-
-await run()
diff --git a/benchmarks/versus-external-pools/fixed-threadwork.mjs b/benchmarks/versus-external-pools/fixed-threadwork.mjs
deleted file mode 100644 (file)
index 190abc1..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-// IMPORT LIBRARIES
-import threadPool from './pool-threadwork'
-// FINISH IMPORT LIBRARIES
-const iterations = parseInt(process.env.NUM_ITERATIONS)
-const data = {
-  test: 'MYBENCH',
-  taskType: process.env.TASK_TYPE,
-  taskSize: parseInt(process.env.TASK_SIZE)
-}
-
-async function run () {
-  const promises = []
-  for (let i = 0; i < iterations; i++) {
-    promises.push(threadPool.run(data))
-  }
-  await Promise.all(promises)
-  // eslint-disable-next-line n/no-process-exit
-  process.exit()
-}
-
-await run()
index b6534d825e6bc9a1f2f3d66e3675776c3e61a3ef..011e986b325e606b8d5c2f19949a937c411bac70 100755 (executable)
@@ -13,6 +13,3 @@ hyperfine --export-markdown BENCH-100000.md --min-runs 20 --prepare 'sleep 2' --
   'node fixed-worker-nodes.js' \
   'node dynamic-node-worker-threads-pool.mjs' \
   'node static-node-worker-threads-pool.mjs' \
-  'node threadjs.mjs' \
-  'node fixed-threadwork.mjs' \
-  'node fixed-microjob.mjs'
index 5d0691b5bf0905a1cf1dc1f2674ca9e2f57c6425..8478510e642b28fdc65e25ccd1a3a502ce71dadb 100644 (file)
@@ -1,6 +1,6 @@
 {
   "name": "poolifier-benchmarks",
-  "version": "1.0.0-internal",
+  "version": "1.0.0",
   "description": "This project contains benchmarks for the most used and popular Node.js thread/cluster pools implementations",
   "private": true,
   "main": "index.js",
   },
   "volta": {
     "node": "18.16.1",
-    "pnpm": "8.6.3"
+    "pnpm": "8.6.5"
   },
   "scripts": {
     "test": "echo \"Error: no test specified\" && exit 1"
   },
   "dependencies": {
-    "microjob": "0.7.0",
     "node-worker-threads-pool": "1.5.1",
     "piscina": "4.0.0",
     "poolifier": "2.6.3",
-    "threads": "1.7.0",
-    "threadwork": "0.6.0",
     "tinypool": "0.5.0",
     "worker-nodes": "2.6.0",
     "workerpool": "6.4.0"
index fe22ee3439dba91291f6aad3330112548b7c0c87..69c4154da163b7e0c25755530e4b632734e65d37 100644 (file)
@@ -5,9 +5,6 @@ settings:
   excludeLinksFromLockfile: false
 
 dependencies:
-  microjob:
-    specifier: 0.7.0
-    version: 0.7.0
   node-worker-threads-pool:
     specifier: 1.5.1
     version: 1.5.1
@@ -17,12 +14,6 @@ dependencies:
   poolifier:
     specifier: 2.6.3
     version: 2.6.3
-  threads:
-    specifier: 1.7.0
-    version: 1.7.0
-  threadwork:
-    specifier: 0.6.0
-    version: 0.6.0
   tinypool:
     specifier: 0.5.0
     version: 0.5.0
@@ -43,29 +34,6 @@ packages:
     resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
     dev: false
 
-  /callsites@3.1.0:
-    resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
-    engines: {node: '>=6'}
-    dev: false
-
-  /debug@4.3.4:
-    resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
-    engines: {node: '>=6.0'}
-    peerDependencies:
-      supports-color: '*'
-    peerDependenciesMeta:
-      supports-color:
-        optional: true
-    dependencies:
-      ms: 2.1.2
-    dev: false
-
-  /esm@3.2.25:
-    resolution: {integrity: sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==}
-    engines: {node: '>=6'}
-    dev: false
-    optional: true
-
   /event-lite@0.1.3:
     resolution: {integrity: sha512-8qz9nOz5VeD2z96elrEKD2U433+L3DWdUdDkOINLGOJvx1GsMBbMn0aCeu28y8/e85A6mCigBiFlYMnTBEGlSw==}
     dev: false
@@ -74,14 +42,6 @@ packages:
     resolution: {integrity: sha512-39F7TBIV0G7gTelxwbEqnwhp90eqCPON1k0NwNfwhgKn4Co4ybUbj2pECcXT0B3ztRKZ7Pw1JujUUgmQJHcVAQ==}
     dev: false
 
-  /find-up@5.0.0:
-    resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==}
-    engines: {node: '>=10'}
-    dependencies:
-      locate-path: 6.0.0
-      path-exists: 4.0.0
-    dev: false
-
   /hdr-histogram-js@2.0.3:
     resolution: {integrity: sha512-Hkn78wwzWHNCp2uarhzQ2SGFLU3JY8SBDDd3TAABK4fc30wm+MuPOrg5QVFVfkKOQd6Bfz3ukJEI+q9sXEkK1g==}
     dependencies:
@@ -102,31 +62,10 @@ packages:
     resolution: {integrity: sha512-v7cSY1J8ydZ0GyjUHqF+1bshJ6cnEVLo9EnjB8p+4HDRPZc9N5jjmvUV7NvEsqQOKyH0pmIBFWXVQbiS0+OBbA==}
     dev: false
 
-  /is-observable@2.1.0:
-    resolution: {integrity: sha512-DailKdLb0WU+xX8K5w7VsJhapwHLZ9jjmazqCJq4X12CTgqq73TKnbRcnSLuXYPOoLQgV5IrD7ePiX/h1vnkBw==}
-    engines: {node: '>=8'}
-    dev: false
-
   /isarray@1.0.0:
     resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==}
     dev: false
 
-  /locate-path@6.0.0:
-    resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
-    engines: {node: '>=10'}
-    dependencies:
-      p-locate: 5.0.0
-    dev: false
-
-  /microjob@0.7.0:
-    resolution: {integrity: sha512-ofDpqaVEv67ymCYdCE8eIVMCJY0H/hAtGxYmi1pXjtNkLOM0UUuUDshA1YLdVFwPwwt5+SW9EbBtSfsNokf+PA==}
-    engines: {node: '>=10.5.0', npm: '>= 6.0.0'}
-    dev: false
-
-  /ms@2.1.2:
-    resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==}
-    dev: false
-
   /msgpack-lite@0.1.26:
     resolution: {integrity: sha512-SZ2IxeqZ1oRFGo0xFGbvBJWMp3yLIY9rlIJyxy8CGrwZn1f0ZK4r6jV/AM1r0FZMDUkWkglOk/eeKIL9g77Nxw==}
     hasBin: true
@@ -162,33 +101,10 @@ packages:
     resolution: {integrity: sha512-7TXAhpMm+jO4MfESxYLtMGSnJWv+itdNHMdaFmeZuPXxwFGU90mtEB42BciUULXOUAxYBfXILAuvrSG3rQZ7mw==}
     dev: false
 
-  /observable-fns@0.6.1:
-    resolution: {integrity: sha512-9gRK4+sRWzeN6AOewNBTLXir7Zl/i3GB6Yl26gK4flxz8BXVpD3kt8amREmWNb0mxYOGDotvE5a4N+PtGGKdkg==}
-    dev: false
-
-  /p-limit@3.1.0:
-    resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
-    engines: {node: '>=10'}
-    dependencies:
-      yocto-queue: 0.1.0
-    dev: false
-
-  /p-locate@5.0.0:
-    resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
-    engines: {node: '>=10'}
-    dependencies:
-      p-limit: 3.1.0
-    dev: false
-
   /pako@1.0.11:
     resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==}
     dev: false
 
-  /path-exists@4.0.0:
-    resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
-    engines: {node: '>=8'}
-    dev: false
-
   /piscina@4.0.0:
     resolution: {integrity: sha512-641nAmJS4k4iqpNUqfggqUBUMmlw0ZoM5VZKdQkV2e970Inn3Tk9kroCc1wpsYLD07vCwpys5iY0d3xI/9WkTg==}
     dependencies:
@@ -199,48 +115,12 @@ packages:
       nice-napi: 1.0.2
     dev: false
 
-  /pkg-dir@5.0.0:
-    resolution: {integrity: sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==}
-    engines: {node: '>=10'}
-    dependencies:
-      find-up: 5.0.0
-    dev: false
-
   /poolifier@2.6.3:
     resolution: {integrity: sha512-5kQjBXqeW8dbzlmDxKRvlC6Vi2zBrpiviVb53rupdQWIsivB6waApeJT4ayhVVLqKGrvLVr9HAeBMHBJaNUDVA==}
     engines: {node: '>=16.14.0', pnpm: '>=8.6.0'}
     requiresBuild: true
     dev: false
 
-  /threads@1.7.0:
-    resolution: {integrity: sha512-Mx5NBSHX3sQYR6iI9VYbgHKBLisyB+xROCBGjjWm1O9wb9vfLxdaGtmT/KCjUqMsSNW6nERzCW3T6H43LqjDZQ==}
-    dependencies:
-      callsites: 3.1.0
-      debug: 4.3.4
-      is-observable: 2.1.0
-      observable-fns: 0.6.1
-    optionalDependencies:
-      tiny-worker: 2.3.0
-    transitivePeerDependencies:
-      - supports-color
-    dev: false
-
-  /threadwork@0.6.0:
-    resolution: {integrity: sha512-NzKDArTtcSAq0jlMdiC04+fuls5nWn1ziptmMTBwPyjKxZk+aQvw/LVVf3IW3tUKz4vLGJ2XE+PXDMoJuoNEfQ==}
-    engines: {node: '>=12'}
-    dependencies:
-      callsites: 3.1.0
-      pkg-dir: 5.0.0
-    dev: false
-
-  /tiny-worker@2.3.0:
-    resolution: {integrity: sha512-pJ70wq5EAqTAEl9IkGzA+fN0836rycEuz2Cn6yeZ6FRzlVS5IDOkFHpIoEsksPRQV34GDqXm65+OlnZqUSyK2g==}
-    requiresBuild: true
-    dependencies:
-      esm: 3.2.25
-    dev: false
-    optional: true
-
   /tinypool@0.5.0:
     resolution: {integrity: sha512-paHQtnrlS1QZYKF/GnLoOM/DN9fqaGOFbCbxzAhwniySnzl9Ebk8w73/dd34DAhe/obUbPAOldTyYXQZxnPBPQ==}
     engines: {node: '>=14.0.0'}
@@ -256,8 +136,3 @@ packages:
   /workerpool@6.4.0:
     resolution: {integrity: sha512-i3KR1mQMNwY2wx20ozq2EjISGtQWDIfV56We+yGJ5yDs8jTwQiLLaqHlkBHITlCuJnYlVRmXegxFxZg7gqI++A==}
     dev: false
-
-  /yocto-queue@0.1.0:
-    resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
-    engines: {node: '>=10'}
-    dev: false
diff --git a/benchmarks/versus-external-pools/pool-threadwork.mjs b/benchmarks/versus-external-pools/pool-threadwork.mjs
deleted file mode 100644 (file)
index 545c013..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-// IMPORT LIBRARIES
-import { ThreadPool } from 'threadwork'
-// FINISH IMPORT LIBRARIES
-// IMPORT FUNCTION TO BENCH
-import functionToBench from './functions/function-to-bench.js'
-// FINISH IMPORT FUNCTION TO BENCH
-const size = parseInt(process.env.POOL_SIZE)
-
-export default new ThreadPool({ task: functionToBench, size })
diff --git a/benchmarks/versus-external-pools/threadjs.mjs b/benchmarks/versus-external-pools/threadjs.mjs
deleted file mode 100644 (file)
index f6c06ee..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-// IMPORT LIBRARIES
-import { Worker, spawn } from 'threads'
-// FINISH IMPORT LIBRARIES
-const size = parseInt(process.env.POOL_SIZE)
-const iterations = parseInt(process.env.NUM_ITERATIONS)
-const data = {
-  test: 'MYBENCH',
-  taskType: process.env.TASK_TYPE,
-  taskSize: parseInt(process.env.TASK_SIZE)
-}
-
-// Threads.js is not really a pool so we need to write few additional code
-const workers = []
-async function poolify () {
-  for (let i = 0; i < size; i++) {
-    const worker = await spawn(
-      new Worker('./workers/threadjs/function-to-bench-worker.mjs')
-    )
-    workers.push(worker)
-  }
-}
-
-async function run () {
-  await poolify()
-  const promises = []
-  for (let i = 0; i < iterations; i++) {
-    const worker = workers[i % size]
-    promises.push(worker.exposedFunction(data))
-  }
-  await Promise.all(promises)
-  // eslint-disable-next-line n/no-process-exit
-  process.exit()
-}
-
-await run()
diff --git a/benchmarks/versus-external-pools/workers/threadjs/function-to-bench-worker.mjs b/benchmarks/versus-external-pools/workers/threadjs/function-to-bench-worker.mjs
deleted file mode 100644 (file)
index 8217e22..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-import { expose } from 'threads/worker'
-import functionToBench from '../../functions/function-to-bench.js'
-
-expose({
-  exposedFunction (data) {
-    return functionToBench(data)
-  }
-})
index da45fca73a451fe486dca762d17efa4a696f2958..63ae7d5a7410ccb6668f277f79801dc65d4f2d6a 100644 (file)
@@ -48,7 +48,7 @@
   },
   "volta": {
     "node": "20.3.1",
-    "pnpm": "8.6.3"
+    "pnpm": "8.6.5"
   },
   "repository": {
     "type": "git",
     "@rollup/plugin-terser": "^0.4.3",
     "@rollup/plugin-typescript": "^11.1.1",
     "@types/node": "^20.3.1",
-    "@typescript-eslint/eslint-plugin": "^5.60.0",
-    "@typescript-eslint/parser": "^5.60.0",
+    "@typescript-eslint/eslint-plugin": "^5.60.1",
+    "@typescript-eslint/parser": "^5.60.1",
     "benny": "^3.7.1",
     "c8": "^8.0.0",
     "eslint": "^8.43.0",
     "eslint-define-config": "^1.21.0",
     "eslint-import-resolver-typescript": "^3.5.5",
     "eslint-plugin-import": "^2.27.5",
-    "eslint-plugin-jsdoc": "^46.2.6",
+    "eslint-plugin-jsdoc": "^46.3.0",
     "eslint-plugin-n": "^16.0.1",
     "eslint-plugin-promise": "^6.1.1",
     "eslint-plugin-spellcheck": "^0.0.20",
index a4d3ae6456b97fd3c9dafe4d6144e3c94b3a4091..d98662de1bcaec746335bc53e1d7523da0f82e6b 100644 (file)
@@ -27,11 +27,11 @@ devDependencies:
     specifier: ^20.3.1
     version: 20.3.1
   '@typescript-eslint/eslint-plugin':
-    specifier: ^5.60.0
-    version: 5.60.0(@typescript-eslint/parser@5.60.0)(eslint@8.43.0)(typescript@5.1.3)
+    specifier: ^5.60.1
+    version: 5.60.1(@typescript-eslint/parser@5.60.1)(eslint@8.43.0)(typescript@5.1.3)
   '@typescript-eslint/parser':
-    specifier: ^5.60.0
-    version: 5.60.0(eslint@8.43.0)(typescript@5.1.3)
+    specifier: ^5.60.1
+    version: 5.60.1(eslint@8.43.0)(typescript@5.1.3)
   benny:
     specifier: ^3.7.1
     version: 3.7.1
@@ -46,19 +46,19 @@ devDependencies:
     version: 17.1.0(eslint-plugin-import@2.27.5)(eslint-plugin-n@16.0.1)(eslint-plugin-promise@6.1.1)(eslint@8.43.0)
   eslint-config-standard-with-typescript:
     specifier: ^35.0.0
-    version: 35.0.0(@typescript-eslint/eslint-plugin@5.60.0)(eslint-plugin-import@2.27.5)(eslint-plugin-n@16.0.1)(eslint-plugin-promise@6.1.1)(eslint@8.43.0)(typescript@5.1.3)
+    version: 35.0.0(@typescript-eslint/eslint-plugin@5.60.1)(eslint-plugin-import@2.27.5)(eslint-plugin-n@16.0.1)(eslint-plugin-promise@6.1.1)(eslint@8.43.0)(typescript@5.1.3)
   eslint-define-config:
     specifier: ^1.21.0
     version: 1.21.0
   eslint-import-resolver-typescript:
     specifier: ^3.5.5
-    version: 3.5.5(@typescript-eslint/parser@5.60.0)(eslint-plugin-import@2.27.5)(eslint@8.43.0)
+    version: 3.5.5(@typescript-eslint/parser@5.60.1)(eslint-plugin-import@2.27.5)(eslint@8.43.0)
   eslint-plugin-import:
     specifier: ^2.27.5
-    version: 2.27.5(@typescript-eslint/parser@5.60.0)(eslint-import-resolver-typescript@3.5.5)(eslint@8.43.0)
+    version: 2.27.5(@typescript-eslint/parser@5.60.1)(eslint-import-resolver-typescript@3.5.5)(eslint@8.43.0)
   eslint-plugin-jsdoc:
-    specifier: ^46.2.6
-    version: 46.2.6(eslint@8.43.0)
+    specifier: ^46.3.0
+    version: 46.3.0(eslint@8.43.0)
   eslint-plugin-n:
     specifier: ^16.0.1
     version: 16.0.1(eslint@8.43.0)
@@ -912,8 +912,8 @@ packages:
       '@types/yargs-parser': 21.0.0
     dev: true
 
-  /@typescript-eslint/eslint-plugin@5.60.0(@typescript-eslint/parser@5.60.0)(eslint@8.43.0)(typescript@5.1.3):
-    resolution: {integrity: sha512-78B+anHLF1TI8Jn/cD0Q00TBYdMgjdOn980JfAVa9yw5sop8nyTfVOQAv6LWywkOGLclDBtv5z3oxN4w7jxyNg==}
+  /@typescript-eslint/eslint-plugin@5.60.1(@typescript-eslint/parser@5.60.1)(eslint@8.43.0)(typescript@5.1.3):
+    resolution: {integrity: sha512-KSWsVvsJsLJv3c4e73y/Bzt7OpqMCADUO846bHcuWYSYM19bldbAeDv7dYyV0jwkbMfJ2XdlzwjhXtuD7OY6bw==}
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
     peerDependencies:
       '@typescript-eslint/parser': ^5.0.0
@@ -924,10 +924,10 @@ packages:
         optional: true
     dependencies:
       '@eslint-community/regexpp': 4.5.1
-      '@typescript-eslint/parser': 5.60.0(eslint@8.43.0)(typescript@5.1.3)
-      '@typescript-eslint/scope-manager': 5.60.0
-      '@typescript-eslint/type-utils': 5.60.0(eslint@8.43.0)(typescript@5.1.3)
-      '@typescript-eslint/utils': 5.60.0(eslint@8.43.0)(typescript@5.1.3)
+      '@typescript-eslint/parser': 5.60.1(eslint@8.43.0)(typescript@5.1.3)
+      '@typescript-eslint/scope-manager': 5.60.1
+      '@typescript-eslint/type-utils': 5.60.1(eslint@8.43.0)(typescript@5.1.3)
+      '@typescript-eslint/utils': 5.60.1(eslint@8.43.0)(typescript@5.1.3)
       debug: 4.3.4(supports-color@8.1.1)
       eslint: 8.43.0
       grapheme-splitter: 1.0.4
@@ -940,8 +940,8 @@ packages:
       - supports-color
     dev: true
 
-  /@typescript-eslint/parser@5.60.0(eslint@8.43.0)(typescript@5.1.3):
-    resolution: {integrity: sha512-jBONcBsDJ9UoTWrARkRRCgDz6wUggmH5RpQVlt7BimSwaTkTjwypGzKORXbR4/2Hqjk9hgwlon2rVQAjWNpkyQ==}
+  /@typescript-eslint/parser@5.60.1(eslint@8.43.0)(typescript@5.1.3):
+    resolution: {integrity: sha512-pHWlc3alg2oSMGwsU/Is8hbm3XFbcrb6P5wIxcQW9NsYBfnrubl/GhVVD/Jm/t8HXhA2WncoIRfBtnCgRGV96Q==}
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
     peerDependencies:
       eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
@@ -950,9 +950,9 @@ packages:
       typescript:
         optional: true
     dependencies:
-      '@typescript-eslint/scope-manager': 5.60.0
-      '@typescript-eslint/types': 5.60.0
-      '@typescript-eslint/typescript-estree': 5.60.0(typescript@5.1.3)
+      '@typescript-eslint/scope-manager': 5.60.1
+      '@typescript-eslint/types': 5.60.1
+      '@typescript-eslint/typescript-estree': 5.60.1(typescript@5.1.3)
       debug: 4.3.4(supports-color@8.1.1)
       eslint: 8.43.0
       typescript: 5.1.3
@@ -960,16 +960,16 @@ packages:
       - supports-color
     dev: true
 
-  /@typescript-eslint/scope-manager@5.60.0:
-    resolution: {integrity: sha512-hakuzcxPwXi2ihf9WQu1BbRj1e/Pd8ZZwVTG9kfbxAMZstKz8/9OoexIwnmLzShtsdap5U/CoQGRCWlSuPbYxQ==}
+  /@typescript-eslint/scope-manager@5.60.1:
+    resolution: {integrity: sha512-Dn/LnN7fEoRD+KspEOV0xDMynEmR3iSHdgNsarlXNLGGtcUok8L4N71dxUgt3YvlO8si7E+BJ5Fe3wb5yUw7DQ==}
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
     dependencies:
-      '@typescript-eslint/types': 5.60.0
-      '@typescript-eslint/visitor-keys': 5.60.0
+      '@typescript-eslint/types': 5.60.1
+      '@typescript-eslint/visitor-keys': 5.60.1
     dev: true
 
-  /@typescript-eslint/type-utils@5.60.0(eslint@8.43.0)(typescript@5.1.3):
-    resolution: {integrity: sha512-X7NsRQddORMYRFH7FWo6sA9Y/zbJ8s1x1RIAtnlj6YprbToTiQnM6vxcMu7iYhdunmoC0rUWlca13D5DVHkK2g==}
+  /@typescript-eslint/type-utils@5.60.1(eslint@8.43.0)(typescript@5.1.3):
+    resolution: {integrity: sha512-vN6UztYqIu05nu7JqwQGzQKUJctzs3/Hg7E2Yx8rz9J+4LgtIDFWjjl1gm3pycH0P3mHAcEUBd23LVgfrsTR8A==}
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
     peerDependencies:
       eslint: '*'
@@ -978,8 +978,8 @@ packages:
       typescript:
         optional: true
     dependencies:
-      '@typescript-eslint/typescript-estree': 5.60.0(typescript@5.1.3)
-      '@typescript-eslint/utils': 5.60.0(eslint@8.43.0)(typescript@5.1.3)
+      '@typescript-eslint/typescript-estree': 5.60.1(typescript@5.1.3)
+      '@typescript-eslint/utils': 5.60.1(eslint@8.43.0)(typescript@5.1.3)
       debug: 4.3.4(supports-color@8.1.1)
       eslint: 8.43.0
       tsutils: 3.21.0(typescript@5.1.3)
@@ -988,13 +988,13 @@ packages:
       - supports-color
     dev: true
 
-  /@typescript-eslint/types@5.60.0:
-    resolution: {integrity: sha512-ascOuoCpNZBccFVNJRSC6rPq4EmJ2NkuoKnd6LDNyAQmdDnziAtxbCGWCbefG1CNzmDvd05zO36AmB7H8RzKPA==}
+  /@typescript-eslint/types@5.60.1:
+    resolution: {integrity: sha512-zDcDx5fccU8BA0IDZc71bAtYIcG9PowaOwaD8rjYbqwK7dpe/UMQl3inJ4UtUK42nOCT41jTSCwg76E62JpMcg==}
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
     dev: true
 
-  /@typescript-eslint/typescript-estree@5.60.0(typescript@5.1.3):
-    resolution: {integrity: sha512-R43thAuwarC99SnvrBmh26tc7F6sPa2B3evkXp/8q954kYL6Ro56AwASYWtEEi+4j09GbiNAHqYwNNZuNlARGQ==}
+  /@typescript-eslint/typescript-estree@5.60.1(typescript@5.1.3):
+    resolution: {integrity: sha512-hkX70J9+2M2ZT6fhti5Q2FoU9zb+GeZK2SLP1WZlvUDqdMbEKhexZODD1WodNRyO8eS+4nScvT0dts8IdaBzfw==}
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
     peerDependencies:
       typescript: '*'
@@ -1002,8 +1002,8 @@ packages:
       typescript:
         optional: true
     dependencies:
-      '@typescript-eslint/types': 5.60.0
-      '@typescript-eslint/visitor-keys': 5.60.0
+      '@typescript-eslint/types': 5.60.1
+      '@typescript-eslint/visitor-keys': 5.60.1
       debug: 4.3.4(supports-color@8.1.1)
       globby: 11.1.0
       is-glob: 4.0.3
@@ -1014,8 +1014,8 @@ packages:
       - supports-color
     dev: true
 
-  /@typescript-eslint/utils@5.60.0(eslint@8.43.0)(typescript@5.1.3):
-    resolution: {integrity: sha512-ba51uMqDtfLQ5+xHtwlO84vkdjrqNzOnqrnwbMHMRY8Tqeme8C2Q8Fc7LajfGR+e3/4LoYiWXUM6BpIIbHJ4hQ==}
+  /@typescript-eslint/utils@5.60.1(eslint@8.43.0)(typescript@5.1.3):
+    resolution: {integrity: sha512-tiJ7FFdFQOWssFa3gqb94Ilexyw0JVxj6vBzaSpfN/8IhoKkDuSAenUKvsSHw2A/TMpJb26izIszTXaqygkvpQ==}
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
     peerDependencies:
       eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
@@ -1023,9 +1023,9 @@ packages:
       '@eslint-community/eslint-utils': 4.4.0(eslint@8.43.0)
       '@types/json-schema': 7.0.12
       '@types/semver': 7.5.0
-      '@typescript-eslint/scope-manager': 5.60.0
-      '@typescript-eslint/types': 5.60.0
-      '@typescript-eslint/typescript-estree': 5.60.0(typescript@5.1.3)
+      '@typescript-eslint/scope-manager': 5.60.1
+      '@typescript-eslint/types': 5.60.1
+      '@typescript-eslint/typescript-estree': 5.60.1(typescript@5.1.3)
       eslint: 8.43.0
       eslint-scope: 5.1.1
       semver: 7.5.3
@@ -1034,11 +1034,11 @@ packages:
       - typescript
     dev: true
 
-  /@typescript-eslint/visitor-keys@5.60.0:
-    resolution: {integrity: sha512-wm9Uz71SbCyhUKgcaPRauBdTegUyY/ZWl8gLwD/i/ybJqscrrdVSFImpvUz16BLPChIeKBK5Fa9s6KDQjsjyWw==}
+  /@typescript-eslint/visitor-keys@5.60.1:
+    resolution: {integrity: sha512-xEYIxKcultP6E/RMKqube11pGjXH1DCo60mQoWhVYyKfLkwbIVVjYxmOenNMxILx0TjCujPTjjnTIVzm09TXIw==}
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
     dependencies:
-      '@typescript-eslint/types': 5.60.0
+      '@typescript-eslint/types': 5.60.1
       eslint-visitor-keys: 3.4.1
     dev: true
 
@@ -2158,7 +2158,7 @@ packages:
       eslint-plugin-react: 7.32.2(eslint@8.43.0)
     dev: true
 
-  /eslint-config-standard-with-typescript@23.0.0(@typescript-eslint/eslint-plugin@5.60.0)(eslint-plugin-import@2.27.5)(eslint-plugin-n@15.7.0)(eslint-plugin-promise@6.1.1)(eslint@8.43.0)(typescript@5.1.3):
+  /eslint-config-standard-with-typescript@23.0.0(@typescript-eslint/eslint-plugin@5.60.1)(eslint-plugin-import@2.27.5)(eslint-plugin-n@15.7.0)(eslint-plugin-promise@6.1.1)(eslint@8.43.0)(typescript@5.1.3):
     resolution: {integrity: sha512-iaaWifImn37Z1OXbNW1es7KI+S7D408F9ys0bpaQf2temeBWlvb0Nc5qHkOgYaRb5QxTZT32GGeN1gtswASOXA==}
     peerDependencies:
       '@typescript-eslint/eslint-plugin': ^5.0.0
@@ -2168,11 +2168,11 @@ packages:
       eslint-plugin-promise: ^6.0.0
       typescript: '*'
     dependencies:
-      '@typescript-eslint/eslint-plugin': 5.60.0(@typescript-eslint/parser@5.60.0)(eslint@8.43.0)(typescript@5.1.3)
-      '@typescript-eslint/parser': 5.60.0(eslint@8.43.0)(typescript@5.1.3)
+      '@typescript-eslint/eslint-plugin': 5.60.1(@typescript-eslint/parser@5.60.1)(eslint@8.43.0)(typescript@5.1.3)
+      '@typescript-eslint/parser': 5.60.1(eslint@8.43.0)(typescript@5.1.3)
       eslint: 8.43.0
       eslint-config-standard: 17.0.0(eslint-plugin-import@2.27.5)(eslint-plugin-n@15.7.0)(eslint-plugin-promise@6.1.1)(eslint@8.43.0)
-      eslint-plugin-import: 2.27.5(@typescript-eslint/parser@5.60.0)(eslint-import-resolver-typescript@3.5.5)(eslint@8.43.0)
+      eslint-plugin-import: 2.27.5(@typescript-eslint/parser@5.60.1)(eslint-import-resolver-typescript@3.5.5)(eslint@8.43.0)
       eslint-plugin-n: 15.7.0(eslint@8.43.0)
       eslint-plugin-promise: 6.1.1(eslint@8.43.0)
       typescript: 5.1.3
@@ -2180,7 +2180,7 @@ packages:
       - supports-color
     dev: true
 
-  /eslint-config-standard-with-typescript@35.0.0(@typescript-eslint/eslint-plugin@5.60.0)(eslint-plugin-import@2.27.5)(eslint-plugin-n@16.0.1)(eslint-plugin-promise@6.1.1)(eslint@8.43.0)(typescript@5.1.3):
+  /eslint-config-standard-with-typescript@35.0.0(@typescript-eslint/eslint-plugin@5.60.1)(eslint-plugin-import@2.27.5)(eslint-plugin-n@16.0.1)(eslint-plugin-promise@6.1.1)(eslint@8.43.0)(typescript@5.1.3):
     resolution: {integrity: sha512-Xa7DY9GgduZyp0qmXxBF0/dB+Vm4/DgWu1lGpNLJV2d46aCaUxTKDEnkzjUWX/1O9S0a+Dhnw7A4oI0JpYzwtw==}
     peerDependencies:
       '@typescript-eslint/eslint-plugin': ^5.50.0
@@ -2190,11 +2190,11 @@ packages:
       eslint-plugin-promise: ^6.0.0
       typescript: '*'
     dependencies:
-      '@typescript-eslint/eslint-plugin': 5.60.0(@typescript-eslint/parser@5.60.0)(eslint@8.43.0)(typescript@5.1.3)
-      '@typescript-eslint/parser': 5.60.0(eslint@8.43.0)(typescript@5.1.3)
+      '@typescript-eslint/eslint-plugin': 5.60.1(@typescript-eslint/parser@5.60.1)(eslint@8.43.0)(typescript@5.1.3)
+      '@typescript-eslint/parser': 5.60.1(eslint@8.43.0)(typescript@5.1.3)
       eslint: 8.43.0
       eslint-config-standard: 17.0.0(eslint-plugin-import@2.27.5)(eslint-plugin-n@16.0.1)(eslint-plugin-promise@6.1.1)(eslint@8.43.0)
-      eslint-plugin-import: 2.27.5(@typescript-eslint/parser@5.60.0)(eslint-import-resolver-typescript@3.5.5)(eslint@8.43.0)
+      eslint-plugin-import: 2.27.5(@typescript-eslint/parser@5.60.1)(eslint-import-resolver-typescript@3.5.5)(eslint@8.43.0)
       eslint-plugin-n: 16.0.1(eslint@8.43.0)
       eslint-plugin-promise: 6.1.1(eslint@8.43.0)
       typescript: 5.1.3
@@ -2211,7 +2211,7 @@ packages:
       eslint-plugin-promise: ^6.0.0
     dependencies:
       eslint: 8.43.0
-      eslint-plugin-import: 2.27.5(@typescript-eslint/parser@5.60.0)(eslint-import-resolver-typescript@3.5.5)(eslint@8.43.0)
+      eslint-plugin-import: 2.27.5(@typescript-eslint/parser@5.60.1)(eslint-import-resolver-typescript@3.5.5)(eslint@8.43.0)
       eslint-plugin-n: 15.7.0(eslint@8.43.0)
       eslint-plugin-promise: 6.1.1(eslint@8.43.0)
     dev: true
@@ -2225,7 +2225,7 @@ packages:
       eslint-plugin-promise: ^6.0.0
     dependencies:
       eslint: 8.43.0
-      eslint-plugin-import: 2.27.5(@typescript-eslint/parser@5.60.0)(eslint-import-resolver-typescript@3.5.5)(eslint@8.43.0)
+      eslint-plugin-import: 2.27.5(@typescript-eslint/parser@5.60.1)(eslint-import-resolver-typescript@3.5.5)(eslint@8.43.0)
       eslint-plugin-n: 16.0.1(eslint@8.43.0)
       eslint-plugin-promise: 6.1.1(eslint@8.43.0)
     dev: true
@@ -2240,7 +2240,7 @@ packages:
       eslint-plugin-promise: ^6.0.0
     dependencies:
       eslint: 8.43.0
-      eslint-plugin-import: 2.27.5(@typescript-eslint/parser@5.60.0)(eslint-import-resolver-typescript@3.5.5)(eslint@8.43.0)
+      eslint-plugin-import: 2.27.5(@typescript-eslint/parser@5.60.1)(eslint-import-resolver-typescript@3.5.5)(eslint@8.43.0)
       eslint-plugin-n: 16.0.1(eslint@8.43.0)
       eslint-plugin-promise: 6.1.1(eslint@8.43.0)
     dev: true
@@ -2260,7 +2260,7 @@ packages:
       - supports-color
     dev: true
 
-  /eslint-import-resolver-typescript@3.5.5(@typescript-eslint/parser@5.60.0)(eslint-plugin-import@2.27.5)(eslint@8.43.0):
+  /eslint-import-resolver-typescript@3.5.5(@typescript-eslint/parser@5.60.1)(eslint-plugin-import@2.27.5)(eslint@8.43.0):
     resolution: {integrity: sha512-TdJqPHs2lW5J9Zpe17DZNQuDnox4xo2o+0tE7Pggain9Rbc19ik8kFtXdxZ250FVx2kF4vlt2RSf4qlUpG7bhw==}
     engines: {node: ^14.18.0 || >=16.0.0}
     peerDependencies:
@@ -2270,8 +2270,8 @@ packages:
       debug: 4.3.4(supports-color@8.1.1)
       enhanced-resolve: 5.15.0
       eslint: 8.43.0
-      eslint-module-utils: 2.8.0(@typescript-eslint/parser@5.60.0)(eslint-import-resolver-node@0.3.7)(eslint-import-resolver-typescript@3.5.5)(eslint@8.43.0)
-      eslint-plugin-import: 2.27.5(@typescript-eslint/parser@5.60.0)(eslint-import-resolver-typescript@3.5.5)(eslint@8.43.0)
+      eslint-module-utils: 2.8.0(@typescript-eslint/parser@5.60.1)(eslint-import-resolver-node@0.3.7)(eslint-import-resolver-typescript@3.5.5)(eslint@8.43.0)
+      eslint-plugin-import: 2.27.5(@typescript-eslint/parser@5.60.1)(eslint-import-resolver-typescript@3.5.5)(eslint@8.43.0)
       get-tsconfig: 4.6.0
       globby: 13.2.0
       is-core-module: 2.12.1
@@ -2284,7 +2284,7 @@ packages:
       - supports-color
     dev: true
 
-  /eslint-module-utils@2.8.0(@typescript-eslint/parser@5.60.0)(eslint-import-resolver-node@0.3.7)(eslint-import-resolver-typescript@3.5.5)(eslint@8.43.0):
+  /eslint-module-utils@2.8.0(@typescript-eslint/parser@5.60.1)(eslint-import-resolver-node@0.3.7)(eslint-import-resolver-typescript@3.5.5)(eslint@8.43.0):
     resolution: {integrity: sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==}
     engines: {node: '>=4'}
     peerDependencies:
@@ -2305,11 +2305,11 @@ packages:
       eslint-import-resolver-webpack:
         optional: true
     dependencies:
-      '@typescript-eslint/parser': 5.60.0(eslint@8.43.0)(typescript@5.1.3)
+      '@typescript-eslint/parser': 5.60.1(eslint@8.43.0)(typescript@5.1.3)
       debug: 3.2.7
       eslint: 8.43.0
       eslint-import-resolver-node: 0.3.7
-      eslint-import-resolver-typescript: 3.5.5(@typescript-eslint/parser@5.60.0)(eslint-plugin-import@2.27.5)(eslint@8.43.0)
+      eslint-import-resolver-typescript: 3.5.5(@typescript-eslint/parser@5.60.1)(eslint-plugin-import@2.27.5)(eslint@8.43.0)
     transitivePeerDependencies:
       - supports-color
     dev: true
@@ -2336,7 +2336,7 @@ packages:
       regexpp: 3.2.0
     dev: true
 
-  /eslint-plugin-import@2.27.5(@typescript-eslint/parser@5.60.0)(eslint-import-resolver-typescript@3.5.5)(eslint@8.43.0):
+  /eslint-plugin-import@2.27.5(@typescript-eslint/parser@5.60.1)(eslint-import-resolver-typescript@3.5.5)(eslint@8.43.0):
     resolution: {integrity: sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow==}
     engines: {node: '>=4'}
     peerDependencies:
@@ -2346,7 +2346,7 @@ packages:
       '@typescript-eslint/parser':
         optional: true
     dependencies:
-      '@typescript-eslint/parser': 5.60.0(eslint@8.43.0)(typescript@5.1.3)
+      '@typescript-eslint/parser': 5.60.1(eslint@8.43.0)(typescript@5.1.3)
       array-includes: 3.1.6
       array.prototype.flat: 1.3.1
       array.prototype.flatmap: 1.3.1
@@ -2354,7 +2354,7 @@ packages:
       doctrine: 2.1.0
       eslint: 8.43.0
       eslint-import-resolver-node: 0.3.7
-      eslint-module-utils: 2.8.0(@typescript-eslint/parser@5.60.0)(eslint-import-resolver-node@0.3.7)(eslint-import-resolver-typescript@3.5.5)(eslint@8.43.0)
+      eslint-module-utils: 2.8.0(@typescript-eslint/parser@5.60.1)(eslint-import-resolver-node@0.3.7)(eslint-import-resolver-typescript@3.5.5)(eslint@8.43.0)
       has: 1.0.3
       is-core-module: 2.12.1
       is-glob: 4.0.3
@@ -2369,8 +2369,8 @@ packages:
       - supports-color
     dev: true
 
-  /eslint-plugin-jsdoc@46.2.6(eslint@8.43.0):
-    resolution: {integrity: sha512-zIaK3zbSrKuH12bP+SPybPgcHSM6MFzh3HFeaODzmsF1N8C1l8dzJ22cW1aq4g0+nayU1VMjmNf7hg0dpShLrA==}
+  /eslint-plugin-jsdoc@46.3.0(eslint@8.43.0):
+    resolution: {integrity: sha512-nfSvsR8YJRZyKrWwcXPSQyQC8jllfdEjcRhTXFr7RxfB5Wyl7AxrfjCUz72WwalkXMF4u+R6F/oDoW46ah69HQ==}
     engines: {node: '>=16'}
     peerDependencies:
       eslint: ^7.0.0 || ^8.0.0
@@ -5736,12 +5736,12 @@ packages:
     peerDependencies:
       typescript: '*'
     dependencies:
-      '@typescript-eslint/eslint-plugin': 5.60.0(@typescript-eslint/parser@5.60.0)(eslint@8.43.0)(typescript@5.1.3)
-      '@typescript-eslint/parser': 5.60.0(eslint@8.43.0)(typescript@5.1.3)
+      '@typescript-eslint/eslint-plugin': 5.60.1(@typescript-eslint/parser@5.60.1)(eslint@8.43.0)(typescript@5.1.3)
+      '@typescript-eslint/parser': 5.60.1(eslint@8.43.0)(typescript@5.1.3)
       eslint: 8.43.0
       eslint-config-standard-jsx: 11.0.0(eslint-plugin-react@7.32.2)(eslint@8.43.0)
-      eslint-config-standard-with-typescript: 23.0.0(@typescript-eslint/eslint-plugin@5.60.0)(eslint-plugin-import@2.27.5)(eslint-plugin-n@15.7.0)(eslint-plugin-promise@6.1.1)(eslint@8.43.0)(typescript@5.1.3)
-      eslint-plugin-import: 2.27.5(@typescript-eslint/parser@5.60.0)(eslint-import-resolver-typescript@3.5.5)(eslint@8.43.0)
+      eslint-config-standard-with-typescript: 23.0.0(@typescript-eslint/eslint-plugin@5.60.1)(eslint-plugin-import@2.27.5)(eslint-plugin-n@15.7.0)(eslint-plugin-promise@6.1.1)(eslint@8.43.0)(typescript@5.1.3)
+      eslint-plugin-import: 2.27.5(@typescript-eslint/parser@5.60.1)(eslint-import-resolver-typescript@3.5.5)(eslint@8.43.0)
       eslint-plugin-n: 15.7.0(eslint@8.43.0)
       eslint-plugin-promise: 6.1.1(eslint@8.43.0)
       eslint-plugin-react: 7.32.2(eslint@8.43.0)
index 4730ad6557a5a922beb5db4aabb9eb0379832e06..367c205c977582f14ea68b4f8d8776eff373581f 100644 (file)
@@ -44,11 +44,7 @@ export type {
 } from './pools/selection-strategies/selection-strategies-types'
 export type { WorkerChoiceStrategyContext } from './pools/selection-strategies/worker-choice-strategy-context'
 export { DynamicThreadPool } from './pools/thread/dynamic'
-export {
-  FixedThreadPool,
-  type ThreadPoolOptions,
-  type ThreadWorkerWithMessageChannel
-} from './pools/thread/fixed'
+export { FixedThreadPool, type ThreadPoolOptions } from './pools/thread/fixed'
 export type { AbstractWorker } from './worker/abstract-worker'
 export { ClusterWorker } from './worker/cluster-worker'
 export { ThreadWorker } from './worker/thread-worker'
@@ -61,7 +57,6 @@ export type {
   WorkerSyncFunction
 } from './worker/worker-functions'
 export type {
-  Draft,
   MessageValue,
   PromiseResponseWrapper,
   TaskError,
index 6ebb30595d822c525ef98e226bf3239a1d4c475f..da8a5eb69c9f69b7744dfe23525877e88680290a 100644 (file)
@@ -21,7 +21,13 @@ import {
   type TasksQueueOptions,
   type WorkerType
 } from './pool'
-import type { IWorker, Task, WorkerNode, WorkerUsage } from './worker'
+import type {
+  IWorker,
+  MessageHandler,
+  Task,
+  WorkerNode,
+  WorkerUsage
+} from './worker'
 import {
   Measurements,
   WorkerChoiceStrategies,
@@ -34,8 +40,8 @@ import { WorkerChoiceStrategyContext } from './selection-strategies/worker-choic
  * Base class that implements some shared logic for all poolifier pools.
  *
  * @typeParam Worker - Type of worker which manages this pool.
- * @typeParam Data - Type of data sent to the worker. This can only be serializable data.
- * @typeParam Response - Type of execution response. This can only be serializable data.
+ * @typeParam Data - Type of data sent to the worker. This can only be structured-cloneable data.
+ * @typeParam Response - Type of execution response. This can only be structured-cloneable data.
  */
 export abstract class AbstractPool<
   Worker extends IWorker,
@@ -670,9 +676,12 @@ export abstract class AbstractPool<
    * @param worker - The worker which should register a listener.
    * @param listener - The message listener callback.
    */
-  protected abstract registerWorkerMessageListener<
-    Message extends Data | Response
-  >(worker: Worker, listener: (message: MessageValue<Message>) => void): void
+  private registerWorkerMessageListener<Message extends Data | Response>(
+    worker: Worker,
+    listener: (message: MessageValue<Message>) => void
+  ): void {
+    worker.on('message', listener as MessageHandler<Worker>)
+  }
 
   /**
    * Creates a new worker.
@@ -684,11 +693,12 @@ export abstract class AbstractPool<
   /**
    * Function that can be hooked up when a worker has been newly created and moved to the pool worker nodes.
    *
-   * Can be used to update the `maxListeners` or binding the `main-worker`\<-\>`worker` connection if not bind by default.
-   *
    * @param worker - The newly created worker.
    */
-  protected abstract afterWorkerSetup (worker: Worker): void
+  private afterWorkerSetup (worker: Worker): void {
+    // Listen to worker messages.
+    this.registerWorkerMessageListener(worker, this.workerListener())
+  }
 
   /**
    * Creates a new worker and sets it up completely in the pool worker nodes.
index b75b3f800d8dc771176b7f11fa437b3fedab867e..a9ccd6977255bcadc43bee150d8684a3ee3ad75e 100644 (file)
@@ -7,8 +7,8 @@ import { type ClusterPoolOptions, FixedClusterPool } from './fixed'
  * This cluster pool creates new workers when the others are busy, up to the maximum number of workers.
  * When the maximum number of workers is reached and workers are busy, an event is emitted. If you want to listen to this event, use the pool's `emitter`.
  *
- * @typeParam Data - Type of data sent to the worker. This can only be serializable data.
- * @typeParam Response - Type of execution response. This can only be serializable data.
+ * @typeParam Data - Type of data sent to the worker. This can only be structured-cloneable data.
+ * @typeParam Response - Type of execution response. This can only be structured-cloneable data.
  * @author [Christopher Quadflieg](https://github.com/Shinigami92)
  * @since 2.0.0
  */
index 3f56c858b0ed5b363fc19da06eb1b9a295a66dd5..7a3b630b8dd8bf261dac5a207542100f423f0c42 100644 (file)
@@ -32,8 +32,8 @@ export interface ClusterPoolOptions extends PoolOptions<Worker> {
  *
  * It is possible to perform tasks in sync or asynchronous mode as you prefer.
  *
- * @typeParam Data - Type of data sent to the worker. This can only be serializable data.
- * @typeParam Response - Type of execution response. This can only be serializable data.
+ * @typeParam Data - Type of data sent to the worker. This can only be structured-cloneable data.
+ * @typeParam Response - Type of execution response. This can only be structured-cloneable data.
  * @author [Christopher Quadflieg](https://github.com/Shinigami92)
  * @since 2.0.0
  */
@@ -80,25 +80,11 @@ export class FixedClusterPool<
     worker.send(message)
   }
 
-  /** @inheritDoc */
-  protected registerWorkerMessageListener<Message extends Data | Response>(
-    worker: Worker,
-    listener: (message: MessageValue<Message>) => void
-  ): void {
-    worker.on('message', listener)
-  }
-
   /** @inheritDoc */
   protected createWorker (): Worker {
     return cluster.fork(this.opts.env)
   }
 
-  /** @inheritDoc */
-  protected afterWorkerSetup (worker: Worker): void {
-    // Listen to worker messages.
-    this.registerWorkerMessageListener(worker, super.workerListener())
-  }
-
   /** @inheritDoc */
   protected get type (): PoolType {
     return PoolTypes.fixed
index 257b0d64b0844d664ba00763b1dcde79c4711ee7..ef93982fbf19ab4c3350af3150116e7cb27dfd40 100644 (file)
@@ -152,8 +152,8 @@ export interface PoolOptions<Worker extends IWorker> {
  * Contract definition for a poolifier pool.
  *
  * @typeParam Worker - Type of worker which manages this pool.
- * @typeParam Data - Type of data sent to the worker. This can only be serializable data.
- * @typeParam Response - Type of execution response. This can only be serializable data.
+ * @typeParam Data - Type of data sent to the worker. This can only be structured-cloneable data.
+ * @typeParam Response - Type of execution response. This can only be structured-cloneable data.
  */
 export interface IPool<
   Worker extends IWorker,
@@ -182,7 +182,7 @@ export interface IPool<
   /**
    * Executes the specified function in the worker constructor with the task data input parameter.
    *
-   * @param data - The task input data for the specified worker function. This can only be serializable data.
+   * @param data - The task input data for the specified worker function. This can only be structured-cloneable data.
    * @param name - The name of the worker function to execute. If not specified, the default worker function will be executed.
    * @returns Promise that will be fulfilled when the task is completed.
    */
index 121647b697139e9c068170d266d96f2c0837edad..5172a181a507fad13940216c933646c616ddb3fa 100644 (file)
@@ -13,8 +13,8 @@ import type {
  * Worker choice strategy abstract base class.
  *
  * @typeParam Worker - Type of worker which manages the strategy.
- * @typeParam Data - Type of data sent to the worker. This can only be serializable data.
- * @typeParam Response - Type of execution response. This can only be serializable data.
+ * @typeParam Data - Type of data sent to the worker. This can only be structured-cloneable data.
+ * @typeParam Response - Type of execution response. This can only be structured-cloneable data.
  */
 export abstract class AbstractWorkerChoiceStrategy<
   Worker extends IWorker,
index 7b3ad3f7516f2b9522aca6acf3ec6b0356aabac3..9ccec752a3f2c68777f2e6473720b3276185a644 100644 (file)
@@ -14,8 +14,8 @@ import {
  * Loosely modeled after the fair queueing algorithm: https://en.wikipedia.org/wiki/Fair_queuing.
  *
  * @typeParam Worker - Type of worker which manages the strategy.
- * @typeParam Data - Type of data sent to the worker. This can only be serializable data.
- * @typeParam Response - Type of execution response. This can only be serializable data.
+ * @typeParam Data - Type of data sent to the worker. This can only be structured-cloneable data.
+ * @typeParam Response - Type of execution response. This can only be structured-cloneable data.
  */
 export class FairShareWorkerChoiceStrategy<
     Worker extends IWorker,
index 85f3148374e5b0c5cf932425772779839f217ca0..40522c72741e67fd6303874f80467e14748d718f 100644 (file)
@@ -12,8 +12,8 @@ import type {
  * Selects the next worker with an interleaved weighted round robin scheduling algorithm.
  *
  * @typeParam Worker - Type of worker which manages the strategy.
- * @typeParam Data - Type of data sent to the worker. This can only be serializable data.
- * @typeParam Response - Type of execution response. This can only be serializable data.
+ * @typeParam Data - Type of data sent to the worker. This can only be structured-cloneable data.
+ * @typeParam Response - Type of execution response. This can only be structured-cloneable data.
  */
 export class InterleavedWeightedRoundRobinWorkerChoiceStrategy<
     Worker extends IWorker,
index 84476eedaf0c434f5bcce23aa7ca694f1bf9d267..31fa281aa75dd0dcbf63fffe1d2508f0277d3f6a 100644 (file)
@@ -12,8 +12,8 @@ import type {
  * Selects the least busy worker.
  *
  * @typeParam Worker - Type of worker which manages the strategy.
- * @typeParam Data - Type of data sent to the worker. This can only be serializable data.
- * @typeParam Response - Type of execution response. This can only be serializable data.
+ * @typeParam Data - Type of data sent to the worker. This can only be structured-cloneable data.
+ * @typeParam Response - Type of execution response. This can only be structured-cloneable data.
  */
 export class LeastBusyWorkerChoiceStrategy<
     Worker extends IWorker,
index 30491dce6fd6962c11547a7fd2494e9a733775da..8394ae7c303144a93855425fe360902774f71bf3 100644 (file)
@@ -12,8 +12,8 @@ import type {
  * Selects the worker with the least ELU.
  *
  * @typeParam Worker - Type of worker which manages the strategy.
- * @typeParam Data - Type of data sent to the worker. This can only be serializable data.
- * @typeParam Response - Type of execution response. This can only be serializable data.
+ * @typeParam Data - Type of data sent to the worker. This can only be structured-cloneable data.
+ * @typeParam Response - Type of execution response. This can only be structured-cloneable data.
  */
 export class LeastEluWorkerChoiceStrategy<
     Worker extends IWorker,
index aaa6c21dc0f3dc7654a4b4d7986d44f809ef96b0..5c266f282d229fd5c5647e3305237ac1ee33c865 100644 (file)
@@ -11,8 +11,8 @@ import type {
  * Selects the least used worker.
  *
  * @typeParam Worker - Type of worker which manages the strategy.
- * @typeParam Data - Type of data sent to the worker. This can only be serializable data.
- * @typeParam Response - Type of execution response. This can only be serializable data.
+ * @typeParam Data - Type of data sent to the worker. This can only be structured-cloneable data.
+ * @typeParam Response - Type of execution response. This can only be structured-cloneable data.
  */
 export class LeastUsedWorkerChoiceStrategy<
     Worker extends IWorker,
index 0995b3506b102931ab59956a927a51f0aa5fbbbc..835860930b0d76f54c37d547b73274d9bf7fb175 100644 (file)
@@ -12,8 +12,8 @@ import type {
  * Selects the next worker in a round robin fashion.
  *
  * @typeParam Worker - Type of worker which manages the strategy.
- * @typeParam Data - Type of data sent to the worker. This can only be serializable data.
- * @typeParam Response - Type of execution response. This can only be serializable data.
+ * @typeParam Data - Type of data sent to the worker. This can only be structured-cloneable data.
+ * @typeParam Response - Type of execution response. This can only be structured-cloneable data.
  */
 export class RoundRobinWorkerChoiceStrategy<
     Worker extends IWorker,
index fc6f48cf2632a89e0fa1de1afe198ff37eb2cdb7..926900800272fef430ddf68273dcb2992954a85a 100644 (file)
@@ -14,8 +14,8 @@ import type {
  * Loosely modeled after the weighted round robin queueing algorithm: https://en.wikipedia.org/wiki/Weighted_round_robin.
  *
  * @typeParam Worker - Type of worker which manages the strategy.
- * @typeParam Data - Type of data sent to the worker. This can only be serializable data.
- * @typeParam Response - Type of execution response. This can only be serializable data.
+ * @typeParam Data - Type of data sent to the worker. This can only be structured-cloneable data.
+ * @typeParam Response - Type of execution response. This can only be structured-cloneable data.
  */
 export class WeightedRoundRobinWorkerChoiceStrategy<
     Worker extends IWorker,
index e1332b85f150d30395cff0938371290765032f1f..2bc99a7b47f14b86b0f43104723b1735f2eed0a1 100644 (file)
@@ -21,8 +21,8 @@ import { WeightedRoundRobinWorkerChoiceStrategy } from './weighted-round-robin-w
  * The worker choice strategy context.
  *
  * @typeParam Worker - Type of worker.
- * @typeParam Data - Type of data sent to the worker. This can only be serializable data.
- * @typeParam Response - Type of execution response. This can only be serializable data.
+ * @typeParam Data - Type of data sent to the worker. This can only be structured-cloneable data.
+ * @typeParam Response - Type of execution response. This can only be structured-cloneable data.
  */
 export class WorkerChoiceStrategyContext<
   Worker extends IWorker,
index b6d41e9ef9f7ff92cecf89e068c6493bafe696e3..b03ca47e27ab272233338e8e4fb751bb8de0d0e4 100644 (file)
@@ -7,8 +7,8 @@ import { FixedThreadPool, type ThreadPoolOptions } from './fixed'
  * This thread pool creates new threads when the others are busy, up to the maximum number of threads.
  * When the maximum number of threads is reached and workers are busy, an event is emitted. If you want to listen to this event, use the pool's `emitter`.
  *
- * @typeParam Data - Type of data sent to the worker. This can only be serializable data.
- * @typeParam Response - Type of execution response. This can only be serializable data.
+ * @typeParam Data - Type of data sent to the worker. This can only be structured-cloneable data.
+ * @typeParam Response - Type of execution response. This can only be structured-cloneable data.
  * @author [Alessandro Pio Ardizio](https://github.com/pioardi)
  * @since 0.0.1
  */
index d843144c633fd99d5becf18ad1d5918ab570eaf6..881e37f636eb3a5ba4770c0c7b90cbb994ab029e 100644 (file)
@@ -1,11 +1,10 @@
 import {
-  MessageChannel,
   SHARE_ENV,
   Worker,
   type WorkerOptions,
   isMainThread
 } from 'node:worker_threads'
-import type { Draft, MessageValue } from '../../utility-types'
+import type { MessageValue } from '../../utility-types'
 import { AbstractPool } from '../abstract-pool'
 import {
   type PoolOptions,
@@ -27,25 +26,20 @@ export interface ThreadPoolOptions extends PoolOptions<Worker> {
   workerOptions?: WorkerOptions
 }
 
-/**
- * A thread worker with message channels for communication between main thread and thread worker.
- */
-export type ThreadWorkerWithMessageChannel = Worker & Draft<MessageChannel>
-
 /**
  * A thread pool with a fixed number of threads.
  *
  * It is possible to perform tasks in sync or asynchronous mode as you prefer.
  *
- * @typeParam Data - Type of data sent to the worker. This can only be serializable data.
- * @typeParam Response - Type of execution response. This can only be serializable data.
+ * @typeParam Data - Type of data sent to the worker. This can only be structured-cloneable data.
+ * @typeParam Response - Type of execution response. This can only be structured-cloneable data.
  * @author [Alessandro Pio Ardizio](https://github.com/pioardi)
  * @since 0.0.1
  */
 export class FixedThreadPool<
   Data = unknown,
   Response = unknown
-> extends AbstractPool<ThreadWorkerWithMessageChannel, Data, Response> {
+> extends AbstractPool<Worker, Data, Response> {
   /**
    * Constructs a new poolifier fixed thread pool.
    *
@@ -67,47 +61,24 @@ export class FixedThreadPool<
   }
 
   /** @inheritDoc */
-  protected async destroyWorker (
-    worker: ThreadWorkerWithMessageChannel
-  ): Promise<void> {
+  protected async destroyWorker (worker: Worker): Promise<void> {
     this.sendToWorker(worker, { kill: 1 })
     await worker.terminate()
   }
 
   /** @inheritDoc */
-  protected sendToWorker (
-    worker: ThreadWorkerWithMessageChannel,
-    message: MessageValue<Data>
-  ): void {
+  protected sendToWorker (worker: Worker, message: MessageValue<Data>): void {
     worker.postMessage(message)
   }
 
   /** @inheritDoc */
-  protected registerWorkerMessageListener<Message extends Data | Response>(
-    worker: ThreadWorkerWithMessageChannel,
-    listener: (message: MessageValue<Message>) => void
-  ): void {
-    worker.port2?.on('message', listener)
-  }
-
-  /** @inheritDoc */
-  protected createWorker (): ThreadWorkerWithMessageChannel {
+  protected createWorker (): Worker {
     return new Worker(this.filePath, {
       env: SHARE_ENV,
       ...this.opts.workerOptions
     })
   }
 
-  /** @inheritDoc */
-  protected afterWorkerSetup (worker: ThreadWorkerWithMessageChannel): void {
-    const { port1, port2 } = new MessageChannel()
-    worker.postMessage({ parent: port1 }, [port1])
-    worker.port1 = port1
-    worker.port2 = port2
-    // Listen to worker messages.
-    this.registerWorkerMessageListener(worker, super.workerListener())
-  }
-
   /** @inheritDoc */
   protected get type (): PoolType {
     return PoolTypes.fixed
index 4e6aea4eef596df89bf828cd24a9d00f335ed7f8..07eabdfe4b43d28a7ecc1238b6f422be04d83ef1 100644 (file)
@@ -6,7 +6,7 @@ import type { Queue } from '../queue'
  */
 export type MessageHandler<Worker extends IWorker> = (
   this: Worker,
-  m: unknown
+  message: unknown
 ) => void
 
 /**
@@ -14,7 +14,7 @@ export type MessageHandler<Worker extends IWorker> = (
  */
 export type ErrorHandler<Worker extends IWorker> = (
   this: Worker,
-  e: Error
+  error: Error
 ) => void
 
 /**
@@ -27,13 +27,13 @@ export type OnlineHandler<Worker extends IWorker> = (this: Worker) => void
  */
 export type ExitHandler<Worker extends IWorker> = (
   this: Worker,
-  code: number
+  exitCode: number
 ) => void
 
 /**
  * Message object that is passed as a task between main worker and worker.
  *
- * @typeParam Data - Type of data sent to the worker. This can only be serializable data.
+ * @typeParam Data - Type of data sent to the worker. This can only be structured-cloneable data.
  * @internal
  */
 export interface Task<Data = unknown> {
@@ -169,7 +169,7 @@ export interface IWorker {
  * Worker node interface.
  *
  * @typeParam Worker - Type of worker.
- * @typeParam Data - Type of data sent to the worker. This can only be serializable data.
+ * @typeParam Data - Type of data sent to the worker. This can only be structured-cloneable data.
  * @internal
  */
 export interface WorkerNode<Worker extends IWorker, Data = unknown> {
index baecaa35b248d98a6cd4d378b444cfe2a4d316f2..e7c9dd11fc0332ccbba845e9bd663d4bc682c523 100644 (file)
@@ -6,18 +6,15 @@
  * @typeParam T - Type of queue items.
  */
 export class Queue<T> {
-  private items: T[]
-  private offset: number
-  public size: number
-  public maxSize: number
+  private items!: T[]
+  private offset!: number
+  /** The size of the queue. */
+  public size!: number
+  /** The maximum size of the queue. */
+  public maxSize!: number
 
   public constructor () {
-    this.items = []
-    this.offset = 0
-    /** The size of the queue. */
-    this.size = 0
-    /** The maximum size of the queue. */
-    this.maxSize = 0
+    this.clear()
   }
 
   /**
index bfbc2a84e376ac1db341614f6427943d5405285f..da2fa22300c58c99998a637c31f531dba8c982c0 100644 (file)
@@ -1,20 +1,11 @@
-import type { Worker as ClusterWorker } from 'node:cluster'
-import type { MessagePort } from 'node:worker_threads'
 import type { EventLoopUtilization } from 'node:perf_hooks'
 import type { KillBehavior } from './worker/worker-options'
 import type { IWorker, Task } from './pools/worker'
 
-/**
- * Make all properties in T non-readonly.
- *
- * @typeParam T - Type in which properties will be non-readonly.
- */
-export type Draft<T> = { -readonly [P in keyof T]?: T[P] }
-
 /**
  * Task error.
  *
- * @typeParam Data - Type of data sent to the worker. This can only be serializable data.
+ * @typeParam Data - Type of data sent to the worker triggering an error. This can only be structured-cloneable data.
  */
 export interface TaskError<Data = unknown> {
   /**
@@ -56,16 +47,16 @@ export interface WorkerStatistics {
 /**
  * Message object that is passed between main worker and worker.
  *
- * @typeParam MessageData - Type of data sent to and/or from the worker. This can only be serializable data.
- * @typeParam Data - Type of data sent to the worker. This can only be serializable data.
+ * @typeParam Data - Type of data sent to the worker or execution response. This can only be structured-cloneable data.
+ * @typeParam ErrorData - Type of data sent to the worker triggering an error. This can only be structured-cloneable data.
  * @typeParam MainWorker - Type of main worker.
  * @internal
  */
 export interface MessageValue<
-  MessageData = unknown,
   Data = unknown,
-  MainWorker extends ClusterWorker | MessagePort = ClusterWorker | MessagePort
-> extends Task<MessageData> {
+  ErrorData = unknown,
+  MainWorker = NodeJS.Process | MessagePort
+> extends Task<Data> {
   /**
    * Kill code.
    */
@@ -73,7 +64,7 @@ export interface MessageValue<
   /**
    * Task error.
    */
-  readonly taskError?: TaskError<Data>
+  readonly taskError?: TaskError<ErrorData>
   /**
    * Task performance.
    */
@@ -92,7 +83,7 @@ export interface MessageValue<
  * An object holding the execution response promise resolve/reject callbacks.
  *
  * @typeParam Worker - Type of worker.
- * @typeParam Response - Type of execution response. This can only be serializable data.
+ * @typeParam Response - Type of execution response. This can only be structured-cloneable data.
  * @internal
  */
 export interface PromiseResponseWrapper<
index 1e1d3088fb7cce28ad22f1961899786e6edd5fdd..8df09ee02f1ed5078f10393d48c4c84d3428683a 100644 (file)
@@ -1,5 +1,4 @@
 import { AsyncResource } from 'node:async_hooks'
-import type { Worker } from 'node:cluster'
 import type { MessagePort } from 'node:worker_threads'
 import { performance } from 'node:perf_hooks'
 import type {
@@ -28,11 +27,11 @@ const DEFAULT_KILL_BEHAVIOR: KillBehavior = KillBehaviors.SOFT
  * Base class that implements some shared logic for all poolifier workers.
  *
  * @typeParam MainWorker - Type of main worker.
- * @typeParam Data - Type of data this worker receives from pool's execution. This can only be serializable data.
- * @typeParam Response - Type of response the worker sends back to the main worker. This can only be serializable data.
+ * @typeParam Data - Type of data this worker receives from pool's execution. This can only be structured-cloneable data.
+ * @typeParam Response - Type of response the worker sends back to the main worker. This can only be structured-cloneable data.
  */
 export abstract class AbstractWorker<
-  MainWorker extends Worker | MessagePort,
+  MainWorker extends NodeJS.Process | MessagePort,
   Data = unknown,
   Response = unknown
 > extends AsyncResource {
@@ -67,7 +66,7 @@ export abstract class AbstractWorker<
     taskFunctions:
     | WorkerFunction<Data, Response>
     | TaskFunctions<Data, Response>,
-    protected mainWorker: MainWorker | undefined | null,
+    protected mainWorker: MainWorker,
     protected readonly opts: WorkerOptions = {
       /**
        * The kill behavior option on this worker or its default value.
@@ -177,7 +176,7 @@ export abstract class AbstractWorker<
    */
   protected getMainWorker (): MainWorker {
     if (this.mainWorker == null) {
-      throw new Error('Main worker was not set')
+      throw new Error('Main worker not set')
     }
     return this.mainWorker
   }
index 2a3961b37f02836d52c7972f98ee150c02904281..efc17acf0b9205f05ff621e399b448af2cfbbb47 100644 (file)
@@ -1,4 +1,4 @@
-import cluster, { type Worker } from 'node:cluster'
+import cluster from 'node:cluster'
 import type { MessageValue } from '../utility-types'
 import { AbstractWorker } from './abstract-worker'
 import type { WorkerOptions } from './worker-options'
@@ -13,15 +13,15 @@ import type { TaskFunctions, WorkerFunction } from './worker-functions'
  * If you use a `DynamicClusterPool` the extra workers that were created will be terminated,
  * but the minimum number of workers will be guaranteed.
  *
- * @typeParam Data - Type of data this worker receives from pool's execution. This can only be serializable data.
- * @typeParam Response - Type of response the worker sends back to the main worker. This can only be serializable data.
+ * @typeParam Data - Type of data this worker receives from pool's execution. This can only be structured-cloneable data.
+ * @typeParam Response - Type of response the worker sends back to the main worker. This can only be structured-cloneable data.
  * @author [Christopher Quadflieg](https://github.com/Shinigami92)
  * @since 2.0.0
  */
 export class ClusterWorker<
   Data = unknown,
   Response = unknown
-> extends AbstractWorker<Worker, Data, Response> {
+> extends AbstractWorker<NodeJS.Process, Data, Response> {
   /**
    * Constructs a new poolifier cluster worker.
    *
@@ -38,14 +38,18 @@ export class ClusterWorker<
       'worker-cluster-pool:poolifier',
       cluster.isPrimary,
       taskFunctions,
-      cluster.worker,
+      process,
       opts
     )
   }
 
   /** @inheritDoc */
   protected sendToMainWorker (message: MessageValue<Response>): void {
-    this.getMainWorker().send(message)
+    const mainWorker = this.getMainWorker()
+    if (mainWorker.send == null) {
+      throw new Error('Main worker does not support IPC communication')
+    }
+    mainWorker.send(message)
   }
 
   /** @inheritDoc */
index 81d98aa5c2fed44c67f84f1ea8145d24e4e3b676..b6573a974cc653656fb6a968b0437e57eeed7dd6 100644 (file)
@@ -13,8 +13,8 @@ import type { TaskFunctions, WorkerFunction } from './worker-functions'
  * If you use a `DynamicThreadPool` the extra workers that were created will be terminated,
  * but the minimum number of workers will be guaranteed.
  *
- * @typeParam Data - Type of data this worker receives from pool's execution. This can only be serializable data.
- * @typeParam Response - Type of response the worker sends back to the main thread. This can only be serializable data.
+ * @typeParam Data - Type of data this worker receives from pool's execution. This can only be structured-cloneable data.
+ * @typeParam Response - Type of response the worker sends back to the main thread. This can only be structured-cloneable data.
  * @author [Alessandro Pio Ardizio](https://github.com/pioardi)
  * @since 0.0.1
  */
@@ -38,7 +38,7 @@ export class ThreadWorker<
       'worker-thread-pool:poolifier',
       isMainThread,
       taskFunctions,
-      parentPort,
+      parentPort as MessagePort,
       opts
     )
   }
index 28b9ed5446b5525c6904c1ed7a3a9916064f9545..9232e58f9e9b4b9000124621e16f083af07c154d 100644 (file)
@@ -1,8 +1,8 @@
 /**
  * Worker synchronous function that can be executed.
  *
- * @typeParam Data - Type of data sent to the worker. This can only be serializable data.
- * @typeParam Response - Type of execution response. This can only be serializable data.
+ * @typeParam Data - Type of data sent to the worker. This can only be structured-cloneable data.
+ * @typeParam Response - Type of execution response. This can only be structured-cloneable data.
  */
 export type WorkerSyncFunction<Data = unknown, Response = unknown> = (
   data?: Data
@@ -12,8 +12,8 @@ export type WorkerSyncFunction<Data = unknown, Response = unknown> = (
  * Worker asynchronous function that can be executed.
  * This function must return a promise.
  *
- * @typeParam Data - Type of data sent to the worker. This can only be serializable data.
- * @typeParam Response - Type of execution response. This can only be serializable data.
+ * @typeParam Data - Type of data sent to the worker. This can only be structured-cloneable data.
+ * @typeParam Response - Type of execution response. This can only be structured-cloneable data.
  */
 export type WorkerAsyncFunction<Data = unknown, Response = unknown> = (
   data?: Data
@@ -23,8 +23,8 @@ export type WorkerAsyncFunction<Data = unknown, Response = unknown> = (
  * Worker function that can be executed.
  * This function can be synchronous or asynchronous.
  *
- * @typeParam Data - Type of data sent to the worker. This can only be serializable data.
- * @typeParam Response - Type of execution response. This can only be serializable data.
+ * @typeParam Data - Type of data sent to the worker. This can only be structured-cloneable data.
+ * @typeParam Response - Type of execution response. This can only be structured-cloneable data.
  */
 export type WorkerFunction<Data = unknown, Response = unknown> =
   | WorkerSyncFunction<Data, Response>
@@ -36,8 +36,8 @@ export type WorkerFunction<Data = unknown, Response = unknown> =
  * The key is the name of the function.
  * The value is the function itself.
  *
- * @typeParam Data - Type of data sent to the worker. This can only be serializable data.
- * @typeParam Response - Type of execution response. This can only be serializable data.
+ * @typeParam Data - Type of data sent to the worker. This can only be structured-cloneable data.
+ * @typeParam Response - Type of execution response. This can only be structured-cloneable data.
  */
 export type TaskFunctions<Data = unknown, Response = unknown> = Record<
 string,
index 458cec807bbb7a22b4c4dce5023e0186821de0ee..e5bf4c81005f94a33cee53bc2f04a10b48549847 100644 (file)
@@ -114,6 +114,6 @@ describe('Abstract worker test suite', () => {
   it('Verify that getMainWorker() throw error if main worker is not set', () => {
     expect(() =>
       new StubWorkerWithMainWorker(() => {}).getMainWorker()
-    ).toThrowError('Main worker was not set')
+    ).toThrowError('Main worker not set')
   })
 })