]> Piment Noir Git Repositories - poolifier.git/commitdiff
fix!: require Node.js versions with ESM cluster support (#3348)
authorJérôme Benoit <jerome.benoit@piment-noir.org>
Fri, 16 Oct 2026 22:42:38 +0000 (00:42 +0200)
committerGitHub <noreply@github.com>
Fri, 16 Oct 2026 22:42:38 +0000 (00:42 +0200)
* fix!: require Node.js versions with ESM cluster support

Migrate cluster fixtures and benchmarks to ESM, retain explicit CommonJS coverage, and test the exact minimum Node.js releases in CI.

BREAKING CHANGE: Node.js ^22.18.0 || >=24.3.0 is required. Upgrade older Node.js installations before updating Poolifier.

Fixes #782

* fix(examples): remove CommonJS cluster build workarounds

Build and start all six cluster and hybrid server examples as ESM. Remove redundant start:esm scripts and extension-dependent worker paths; retain public CommonJS library support.

* fix(examples): declare Node.js requirements for ESM cluster workers

Align the six standalone cluster and hybrid examples with the supported Node.js range. This declares compatibility and enables package-manager engine checks without adding a runtime guard or changing dependencies.

* docs: remove unnecessary ESM background from README

* docs: remove unnecessary cluster startup explanations

47 files changed:
.github/workflows/ci.yml
README.md
benchmarks/benchmarks-utils.mjs
benchmarks/internal/cluster-worker.mjs [moved from benchmarks/internal/cluster-worker.cjs with 55% similarity]
eslint.config.js
examples/typescript/http-server-pool/express-cluster/package.json
examples/typescript/http-server-pool/express-cluster/rollup.config.ts
examples/typescript/http-server-pool/express-cluster/src/main.ts
examples/typescript/http-server-pool/express-hybrid/package.json
examples/typescript/http-server-pool/express-hybrid/rollup.config.ts
examples/typescript/http-server-pool/express-hybrid/src/main.ts
examples/typescript/http-server-pool/fastify-cluster/package.json
examples/typescript/http-server-pool/fastify-cluster/rollup.config.ts
examples/typescript/http-server-pool/fastify-cluster/src/main.ts
examples/typescript/http-server-pool/fastify-hybrid/package.json
examples/typescript/http-server-pool/fastify-hybrid/rollup.config.ts
examples/typescript/http-server-pool/fastify-hybrid/src/main.ts
examples/typescript/websocket-server-pool/ws-cluster/package.json
examples/typescript/websocket-server-pool/ws-cluster/rollup.config.ts
examples/typescript/websocket-server-pool/ws-cluster/src/main.ts
examples/typescript/websocket-server-pool/ws-hybrid/package.json
examples/typescript/websocket-server-pool/ws-hybrid/rollup.config.ts
examples/typescript/websocket-server-pool/ws-hybrid/src/main.ts
package.json
tests/pools/abstract-pool.test.mjs
tests/pools/cluster/dynamic.test.mjs
tests/pools/cluster/fixed.test.mjs
tests/pools/cluster/module-formats.test.mjs [new file with mode: 0644]
tests/pools/prototype-pollution.test.mjs
tests/pools/selection-strategies/selection-strategies-utils.test.mjs
tests/pools/selection-strategies/selection-strategies.test.mjs
tests/pools/utils.test.mjs
tests/pools/worker-exit.test.mjs
tests/pools/worker-node.test.mjs
tests/worker-files/cluster/asyncErrorWorker.mjs [moved from tests/worker-files/cluster/asyncErrorWorker.cjs with 66% similarity]
tests/worker-files/cluster/asyncWorker.mjs [moved from tests/worker-files/cluster/asyncWorker.cjs with 58% similarity]
tests/worker-files/cluster/crashWorker.mjs [moved from tests/worker-files/cluster/crashWorker.cjs with 85% similarity]
tests/worker-files/cluster/echoWorker.mjs [new file with mode: 0644]
tests/worker-files/cluster/emptyWorker.cjs [deleted file]
tests/worker-files/cluster/emptyWorker.mjs [new file with mode: 0644]
tests/worker-files/cluster/errorWorker.mjs [moved from tests/worker-files/cluster/errorWorker.cjs with 53% similarity]
tests/worker-files/cluster/longRunningWorkerHardBehavior.mjs [moved from tests/worker-files/cluster/longRunningWorkerHardBehavior.cjs with 59% similarity]
tests/worker-files/cluster/longRunningWorkerSoftBehavior.mjs [moved from tests/worker-files/cluster/longRunningWorkerSoftBehavior.cjs with 60% similarity]
tests/worker-files/cluster/prototypePollutionWorker.mjs [moved from tests/worker-files/cluster/prototypePollutionWorker.cjs with 75% similarity]
tests/worker-files/cluster/testMultipleTaskFunctionsWorker.mjs [moved from tests/worker-files/cluster/testMultipleTaskFunctionsWorker.cjs with 72% similarity]
tests/worker-files/cluster/testTaskFunctionObjectsWorker.mjs [moved from tests/worker-files/cluster/testTaskFunctionObjectsWorker.cjs with 68% similarity]
tests/worker-files/cluster/testWorker.mjs [moved from tests/worker-files/cluster/testWorker.cjs with 62% similarity]

index 1d9ef6423d8f8295b66f3c59615742a21c3cb883..d4727cd993787928d0354d8657a04abfc00e0025 100644 (file)
@@ -32,6 +32,11 @@ jobs:
       matrix:
         os: [windows-latest, macos-latest, ubuntu-latest]
         node: ['22.x', '24.x', 'latest']
+        include:
+          - os: ubuntu-latest
+            node: '22.18.0'
+          - os: ubuntu-latest
+            node: '24.3.0'
 
     name: Node.js ${{ matrix.node }} on ${{ matrix.os }}
 
index b6c2d34f6932c97a3a8f94c3ea2076938919ba03..97c1014b61f714056286535badb6f968227f3490 100644 (file)
--- a/README.md
+++ b/README.md
@@ -174,7 +174,7 @@ Remember that workers can only send and receive structured-cloneable data.
 
 ## Node.js versions
 
-Node.js versions >= 22.x.x are supported.
+Supported Node.js versions are **22.18.0 or later in the 22.x line**, or **24.3.0 and later**.
 
 ## [API](./docs/api.md)
 
index 53755f8befc120d73e1891f575de48f6b8d2ad25..5a42d462c04148afc58a9c390f479ae06c17c22e 100644 (file)
@@ -21,7 +21,7 @@ const buildPoolifierPool = (workerType, poolType, poolSize, poolOptions) => {
           return new DynamicClusterPool(
             Math.floor(poolSize / 2),
             poolSize,
-            './benchmarks/internal/cluster-worker.cjs',
+            './benchmarks/internal/cluster-worker.mjs',
             poolOptions
           )
         case WorkerTypes.thread:
@@ -38,7 +38,7 @@ const buildPoolifierPool = (workerType, poolType, poolSize, poolOptions) => {
         case WorkerTypes.cluster:
           return new FixedClusterPool(
             poolSize,
-            './benchmarks/internal/cluster-worker.cjs',
+            './benchmarks/internal/cluster-worker.mjs',
             poolOptions
           )
         case WorkerTypes.thread:
similarity index 55%
rename from benchmarks/internal/cluster-worker.cjs
rename to benchmarks/internal/cluster-worker.mjs
index 757c6961ec09f701c4db37de3cbd8a78c43f8cab..bb29274677003304e199d681346b1764a3a81380 100644 (file)
@@ -1,8 +1,8 @@
-const { isPrimary } = require('node:cluster')
+import { isPrimary } from 'node:cluster'
 
-const { ClusterWorker } = require('../../lib/index.cjs')
-const { TaskFunctions } = require('../benchmarks-types.cjs')
-const { executeTaskFunction } = require('../benchmarks-utils.cjs')
+import { ClusterWorker } from '../../lib/index.mjs'
+import { TaskFunctions } from '../benchmarks-types.cjs'
+import { executeTaskFunction } from '../benchmarks-utils.mjs'
 
 const taskFunction = data => {
   data = data || {}
@@ -14,4 +14,4 @@ const taskFunction = data => {
   return res
 }
 
-module.exports = new ClusterWorker(taskFunction)
+export default new ClusterWorker(taskFunction)
index 9c358f51949cc9e767581e4e5b15a79998806bb7..c1b230d3d1f4b9c0fbc0942db6870414c80578f1 100644 (file)
@@ -57,7 +57,6 @@ export default defineConfig([
       languageOptions: {
         parserOptions: {
           projectService: true,
-          // eslint-disable-next-line n/no-unsupported-features/node-builtins
           tsconfigRootDir: import.meta.dirname,
         },
       },
index f6b17f046b1c1e0ff90db7e84587ead44b3b57cf..dc0a11d44f84ce83d7d94cda4d2497be18fa9e0f 100644 (file)
@@ -5,11 +5,13 @@
   "description": "Express cluster pool",
   "main": "dist/main.js",
   "type": "module",
+  "engines": {
+    "node": "^22.18.0 || >=24.3.0"
+  },
   "packageManager": "pnpm@12.11.2",
   "scripts": {
     "build": "rollup --config --configPlugin typescript",
-    "start": "node --enable-source-maps dist/main.cjs",
-    "start:esm": "node --enable-source-maps dist/main.js",
+    "start": "node --enable-source-maps dist/main.js",
     "test": "echo \"Error: no test specified\" && exit 1",
     "benchmark:echo": "autocannon -c 100 -d 30 -p 10 -m POST -H Content-Type=application/json -b '{\"key1\":\"value1\", \"key2\":\"value2\"}' http://localhost:8080/api/echo",
     "benchmark:factorial": "autocannon -c 100 -d 30 -p 10 http://localhost:8080/api/factorial/50000"
index 1ed40f58ce478a677635bde37f52d8f2693379a6..f7497196017c3f9be6e517ed8dd7ac42f1b0ac06 100644 (file)
@@ -5,20 +5,11 @@ import del from 'rollup-plugin-delete'
 export default defineConfig({
   external: ['express', /^node:*/, 'poolifier'],
   input: ['./src/main.ts', './src/worker.ts'],
-  output: [
-    {
-      chunkFileNames: '[name]-[hash].cjs',
-      dir: './dist',
-      entryFileNames: '[name].cjs',
-      format: 'cjs',
-      sourcemap: true,
-    },
-    {
-      dir: './dist',
-      format: 'esm',
-      sourcemap: true,
-    },
-  ],
+  output: {
+    dir: './dist',
+    format: 'esm',
+    sourcemap: true,
+  },
   plugins: [
     typescript({
       compilerOptions: {
index 355c5a6b5df08312564d5822004c2e77149acfe9..fbbf341f79ac74f66622179210093ac90ef8e35e 100644 (file)
@@ -1,13 +1,10 @@
-import { dirname, extname, join } from 'node:path'
+import { dirname, join } from 'node:path'
 import { fileURLToPath } from 'node:url'
 import { availableParallelism, FixedClusterPool } from 'poolifier'
 
 import type { WorkerData, WorkerResponse } from './types.js'
 
-const workerFile = join(
-  dirname(fileURLToPath(import.meta.url)),
-  `worker${extname(fileURLToPath(import.meta.url))}`
-)
+const workerFile = join(dirname(fileURLToPath(import.meta.url)), 'worker.js')
 
 const pool = new FixedClusterPool<WorkerData, WorkerResponse>(
   availableParallelism(),
index 1c6ecde3b176e985ce29f724a3f9a8c181b2928e..f21774b235024fcbcedc70527de32f4812003f14 100644 (file)
@@ -5,11 +5,13 @@
   "description": "Express hybrid pool",
   "main": "dist/main.js",
   "type": "module",
+  "engines": {
+    "node": "^22.18.0 || >=24.3.0"
+  },
   "packageManager": "pnpm@12.11.2",
   "scripts": {
     "build": "rollup --config --configPlugin typescript",
-    "start": "node --enable-source-maps dist/main.cjs",
-    "start:esm": "node --enable-source-maps dist/main.js",
+    "start": "node --enable-source-maps dist/main.js",
     "test": "echo \"Error: no test specified\" && exit 1",
     "benchmark:echo": "autocannon -c 100 -d 30 -p 10 -m POST -H Content-Type=application/json -b '{\"key1\":\"value1\", \"key2\":\"value2\"}' http://localhost:8080/api/echo",
     "benchmark:factorial": "autocannon -c 100 -d 30 -p 10 http://localhost:8080/api/factorial/50000"
index e80bc482f472169e67a149bf34f48b65588b61c3..4e492c380ea1e9dd3c8c74cfab50f13bf4d79679 100644 (file)
@@ -9,20 +9,11 @@ export default defineConfig({
     './src/express-worker.ts',
     './src/request-handler-worker.ts',
   ],
-  output: [
-    {
-      chunkFileNames: '[name]-[hash].cjs',
-      dir: './dist',
-      entryFileNames: '[name].cjs',
-      format: 'cjs',
-      sourcemap: true,
-    },
-    {
-      dir: './dist',
-      format: 'esm',
-      sourcemap: true,
-    },
-  ],
+  output: {
+    dir: './dist',
+    format: 'esm',
+    sourcemap: true,
+  },
   plugins: [
     typescript({
       compilerOptions: {
index 60c724889173bf588f8cf15d72a8ad158fdee579..17155bdf3fcdb6d333f61b5963899640a0f81be0 100644 (file)
@@ -1,4 +1,4 @@
-import { dirname, extname, join } from 'node:path'
+import { dirname, join } from 'node:path'
 import { fileURLToPath } from 'node:url'
 import { availableParallelism, FixedClusterPool } from 'poolifier'
 
@@ -6,12 +6,12 @@ import type { ClusterWorkerData, ClusterWorkerResponse } from './types.js'
 
 const expressWorkerFile = join(
   dirname(fileURLToPath(import.meta.url)),
-  `express-worker${extname(fileURLToPath(import.meta.url))}`
+  'express-worker.js'
 )
 
 const requestHandlerWorkerFile = join(
   dirname(fileURLToPath(import.meta.url)),
-  `request-handler-worker${extname(fileURLToPath(import.meta.url))}`
+  'request-handler-worker.js'
 )
 
 const pool = new FixedClusterPool<ClusterWorkerData, ClusterWorkerResponse>(
index c07ebe02415adf73a2e0fb88ab741eebdd444046..bd0d69e52633ecdc21328353896d7c71c9b94a70 100644 (file)
@@ -5,11 +5,13 @@
   "description": "Fastify cluster pool",
   "main": "dist/main.js",
   "type": "module",
+  "engines": {
+    "node": "^22.18.0 || >=24.3.0"
+  },
   "packageManager": "pnpm@12.11.2",
   "scripts": {
     "build": "rollup --config --configPlugin typescript",
-    "start": "node --enable-source-maps dist/main.cjs",
-    "start:esm": "node --enable-source-maps dist/main.js",
+    "start": "node --enable-source-maps dist/main.js",
     "test": "echo \"Error: no test specified\" && exit 1",
     "benchmark:echo": "autocannon -c 100 -d 30 -p 10 -m POST -H Content-Type=application/json -b '{\"key1\":\"value1\", \"key2\":\"value2\"}' http://localhost:8080/api/echo",
     "benchmark:factorial": "autocannon -c 100 -d 30 -p 10 http://localhost:8080/api/factorial/50000"
index 836f417adfc23198591a6f39cc00e260e11a8ec3..0cf7523fd813d790278beeb4c74a5985874dd247 100644 (file)
@@ -5,20 +5,11 @@ import del from 'rollup-plugin-delete'
 export default defineConfig({
   external: ['fastify', /^node:*/, 'poolifier'],
   input: ['./src/main.ts', './src/worker.ts'],
-  output: [
-    {
-      chunkFileNames: '[name]-[hash].cjs',
-      dir: './dist',
-      entryFileNames: '[name].cjs',
-      format: 'cjs',
-      sourcemap: true,
-    },
-    {
-      dir: './dist',
-      format: 'esm',
-      sourcemap: true,
-    },
-  ],
+  output: {
+    dir: './dist',
+    format: 'esm',
+    sourcemap: true,
+  },
   plugins: [
     typescript({
       compilerOptions: {
index d85b736929adfdb0734c5b78fadf5d0946737588..4b07e8063a27c4a2d31d56f4b67e7e198728ab7b 100644 (file)
@@ -1,13 +1,10 @@
-import { dirname, extname, join } from 'node:path'
+import { dirname, join } from 'node:path'
 import { fileURLToPath } from 'node:url'
 import { availableParallelism, FixedClusterPool } from 'poolifier'
 
 import type { WorkerData, WorkerResponse } from './types.js'
 
-const workerFile = join(
-  dirname(fileURLToPath(import.meta.url)),
-  `worker${extname(fileURLToPath(import.meta.url))}`
-)
+const workerFile = join(dirname(fileURLToPath(import.meta.url)), 'worker.js')
 
 const pool = new FixedClusterPool<WorkerData, WorkerResponse>(
   availableParallelism(),
index ffb6cad3847237f8c280303ffcc0ff0418ca79f4..cf309abadd14e9c0b634f5104f89cbb80305b114 100644 (file)
@@ -5,11 +5,13 @@
   "description": "Fastify hybrid pool",
   "main": "dist/main.js",
   "type": "module",
+  "engines": {
+    "node": "^22.18.0 || >=24.3.0"
+  },
   "packageManager": "pnpm@12.11.2",
   "scripts": {
     "build": "rollup --config --configPlugin typescript",
-    "start": "node --enable-source-maps dist/main.cjs",
-    "start:esm": "node --enable-source-maps dist/main.js",
+    "start": "node --enable-source-maps dist/main.js",
     "test": "echo \"Error: no test specified\" && exit 1",
     "benchmark:echo": "autocannon -c 100 -d 30 -p 10 -m POST -H Content-Type=application/json -b '{\"key1\":\"value1\", \"key2\":\"value2\"}' http://localhost:8080/api/echo",
     "benchmark:factorial": "autocannon -c 100 -d 30 -p 10 http://localhost:8080/api/factorial/50000"
index c978be2443b2be47cf2677e3cb0ffc42b557eb15..1caa123c3e92d3473074fa7da9807583765120ad 100644 (file)
@@ -9,20 +9,11 @@ export default defineConfig({
     './src/fastify-worker.ts',
     './src/request-handler-worker.ts',
   ],
-  output: [
-    {
-      chunkFileNames: '[name]-[hash].cjs',
-      dir: './dist',
-      entryFileNames: '[name].cjs',
-      format: 'cjs',
-      sourcemap: true,
-    },
-    {
-      dir: './dist',
-      format: 'esm',
-      sourcemap: true,
-    },
-  ],
+  output: {
+    dir: './dist',
+    format: 'esm',
+    sourcemap: true,
+  },
   plugins: [
     typescript({
       compilerOptions: {
index 60e8655ed7fc30717e50c48dc6121eeeab1e4df8..e9662dae58669ee3e39ba271cc433018a4c952ec 100644 (file)
@@ -1,4 +1,4 @@
-import { dirname, extname, join } from 'node:path'
+import { dirname, join } from 'node:path'
 import { fileURLToPath } from 'node:url'
 import { availableParallelism, FixedClusterPool } from 'poolifier'
 
@@ -6,12 +6,12 @@ import type { ClusterWorkerData, ClusterWorkerResponse } from './types.js'
 
 const fastifyWorkerFile = join(
   dirname(fileURLToPath(import.meta.url)),
-  `fastify-worker${extname(fileURLToPath(import.meta.url))}`
+  'fastify-worker.js'
 )
 
 const requestHandlerWorkerFile = join(
   dirname(fileURLToPath(import.meta.url)),
-  `request-handler-worker${extname(fileURLToPath(import.meta.url))}`
+  'request-handler-worker.js'
 )
 
 const pool = new FixedClusterPool<ClusterWorkerData, ClusterWorkerResponse>(
index 95cc778fe79298722da0a2279be330d159484716..ea280aec471057ac704bc660abc6ae05555b700e 100644 (file)
@@ -5,11 +5,13 @@
   "description": "ws cluster pool",
   "main": "dist/main.js",
   "type": "module",
+  "engines": {
+    "node": "^22.18.0 || >=24.3.0"
+  },
   "packageManager": "pnpm@12.11.2",
   "scripts": {
     "build": "rollup --config --configPlugin typescript",
-    "start": "node --enable-source-maps dist/main.cjs",
-    "start:esm": "node --enable-source-maps dist/main.js",
+    "start": "node --enable-source-maps dist/main.js",
     "test": "echo \"Error: no test specified\" && exit 1",
     "test:requests": "node requests.js"
   },
index 023ccbe4f402423d25eeff30174f18e55ebdee2c..4333dde312f24ae1f2cd115fda592470fb2ee1ee 100644 (file)
@@ -5,20 +5,11 @@ import del from 'rollup-plugin-delete'
 export default defineConfig({
   external: [/^node:*/, 'poolifier', 'ws'],
   input: ['./src/main.ts', './src/worker.ts'],
-  output: [
-    {
-      chunkFileNames: '[name]-[hash].cjs',
-      dir: './dist',
-      entryFileNames: '[name].cjs',
-      format: 'cjs',
-      sourcemap: true,
-    },
-    {
-      dir: './dist',
-      format: 'esm',
-      sourcemap: true,
-    },
-  ],
+  output: {
+    dir: './dist',
+    format: 'esm',
+    sourcemap: true,
+  },
   plugins: [
     typescript({
       compilerOptions: {
index 654be2ba894ef345bbc1430f2c4f257dcaeccfa4..93b931cb1d7325e2628269e8118682e0eec2d14e 100644 (file)
@@ -1,13 +1,10 @@
-import { dirname, extname, join } from 'node:path'
+import { dirname, join } from 'node:path'
 import { fileURLToPath } from 'node:url'
 import { availableParallelism, FixedClusterPool } from 'poolifier'
 
 import type { WorkerData, WorkerResponse } from './types.js'
 
-const workerFile = join(
-  dirname(fileURLToPath(import.meta.url)),
-  `worker${extname(fileURLToPath(import.meta.url))}`
-)
+const workerFile = join(dirname(fileURLToPath(import.meta.url)), 'worker.js')
 
 const pool = new FixedClusterPool<WorkerData, WorkerResponse>(
   availableParallelism(),
index c131a2b654652c7e37bb35d030ea8aaa40f6340f..58745a7f8e3d530f8fe9743d75d78f3d3cd65b30 100644 (file)
@@ -5,11 +5,13 @@
   "description": "ws hybrid pool",
   "main": "dist/main.js",
   "type": "module",
+  "engines": {
+    "node": "^22.18.0 || >=24.3.0"
+  },
   "packageManager": "pnpm@12.11.2",
   "scripts": {
     "build": "rollup --config --configPlugin typescript",
-    "start": "node --enable-source-maps dist/main.cjs",
-    "start:esm": "node --enable-source-maps dist/main.js",
+    "start": "node --enable-source-maps dist/main.js",
     "test": "echo \"Error: no test specified\" && exit 1",
     "test:requests": "node requests.js"
   },
index d504c5dd98ea961604bb8b9e10c6cc29f72b8422..6575b4ecddc9bf3c29c44bbf0dd9e244f179793a 100644 (file)
@@ -9,20 +9,11 @@ export default defineConfig({
     './src/websocket-server-worker.ts',
     './src/request-handler-worker.ts',
   ],
-  output: [
-    {
-      chunkFileNames: '[name]-[hash].cjs',
-      dir: './dist',
-      entryFileNames: '[name].cjs',
-      format: 'cjs',
-      sourcemap: true,
-    },
-    {
-      dir: './dist',
-      format: 'esm',
-      sourcemap: true,
-    },
-  ],
+  output: {
+    dir: './dist',
+    format: 'esm',
+    sourcemap: true,
+  },
   plugins: [
     typescript({
       compilerOptions: {
index 13f78249fefa83c59f722591aca25ad06257d91c..c24b130b13e6794a0f9cdcd6df6e233fdbf90346 100644 (file)
@@ -1,4 +1,4 @@
-import { dirname, extname, join } from 'node:path'
+import { dirname, join } from 'node:path'
 import { fileURLToPath } from 'node:url'
 import { availableParallelism, FixedClusterPool } from 'poolifier'
 
@@ -6,12 +6,12 @@ import type { ClusterWorkerData, ClusterWorkerResponse } from './types.js'
 
 const webSocketServerWorkerFile = join(
   dirname(fileURLToPath(import.meta.url)),
-  `websocket-server-worker${extname(fileURLToPath(import.meta.url))}`
+  'websocket-server-worker.js'
 )
 
 const requestHandlerWorkerFile = join(
   dirname(fileURLToPath(import.meta.url)),
-  `request-handler-worker${extname(fileURLToPath(import.meta.url))}`
+  'request-handler-worker.js'
 )
 
 const pool = new FixedClusterPool<ClusterWorkerData, ClusterWorkerResponse>(
index 8a520bb2b8435f24f96bcea3824a13b1877c19c0..61d88dfcbfe68d58423ef5a677e7240c9b03fb79 100644 (file)
@@ -39,7 +39,7 @@
     "postpublish": "rm -rf ./package"
   },
   "engines": {
-    "node": ">=22.13.0",
+    "node": "^22.18.0 || >=24.3.0",
     "pnpm": ">=9.0.0"
   },
   "devEngines": {
index 8056b143f5d375d75b906bd059cdf8e80337d9f1..16a107e5fbc2f4df5d10f5ac889785b823be89fc 100644 (file)
@@ -106,7 +106,7 @@ describe('Abstract pool test suite', () => {
   it('Verify that a negative number of workers is checked', () => {
     expect(
       () =>
-        new FixedClusterPool(-1, './tests/worker-files/cluster/testWorker.cjs')
+        new FixedClusterPool(-1, './tests/worker-files/cluster/testWorker.mjs')
     ).toThrow(
       new RangeError(
         'Cannot instantiate a pool with a negative number of workers'
@@ -147,7 +147,7 @@ describe('Abstract pool test suite', () => {
         new DynamicClusterPool(
           1,
           undefined,
-          './tests/worker-files/cluster/testWorker.cjs'
+          './tests/worker-files/cluster/testWorker.mjs'
         )
     ).toThrow(
       new TypeError(
@@ -171,7 +171,7 @@ describe('Abstract pool test suite', () => {
         new DynamicClusterPool(
           0,
           0.5,
-          './tests/worker-files/cluster/testWorker.cjs'
+          './tests/worker-files/cluster/testWorker.mjs'
         )
     ).toThrow(
       new TypeError(
@@ -207,7 +207,7 @@ describe('Abstract pool test suite', () => {
         new DynamicClusterPool(
           1,
           1,
-          './tests/worker-files/cluster/testWorker.cjs'
+          './tests/worker-files/cluster/testWorker.mjs'
         )
     ).toThrow(
       new RangeError(
@@ -882,7 +882,7 @@ describe('Abstract pool test suite', () => {
     pool = new DynamicClusterPool(
       Math.floor(numberOfWorkers / 2),
       numberOfWorkers,
-      './tests/worker-files/cluster/testWorker.cjs'
+      './tests/worker-files/cluster/testWorker.mjs'
     )
     expect(pool.info).toStrictEqual({
       busyWorkerNodes: 0,
@@ -908,7 +908,7 @@ describe('Abstract pool test suite', () => {
   it('Verify that pool worker tasks usage are initialized', async () => {
     const pool = new FixedClusterPool(
       numberOfWorkers,
-      './tests/worker-files/cluster/testWorker.cjs'
+      './tests/worker-files/cluster/testWorker.mjs'
     )
     for (const workerNode of pool.workerNodes) {
       expect(workerNode).toBeInstanceOf(WorkerNode)
@@ -944,7 +944,7 @@ describe('Abstract pool test suite', () => {
   it('Verify that pool worker tasks queue are initialized', async () => {
     let pool = new FixedClusterPool(
       numberOfWorkers,
-      './tests/worker-files/cluster/testWorker.cjs'
+      './tests/worker-files/cluster/testWorker.mjs'
     )
     for (const workerNode of pool.workerNodes) {
       expect(workerNode).toBeInstanceOf(WorkerNode)
@@ -974,7 +974,7 @@ describe('Abstract pool test suite', () => {
   it('Verify that pool worker info are initialized', async () => {
     let pool = new FixedClusterPool(
       numberOfWorkers,
-      './tests/worker-files/cluster/testWorker.cjs'
+      './tests/worker-files/cluster/testWorker.mjs'
     )
     for (const workerNode of pool.workerNodes) {
       expect(workerNode).toBeInstanceOf(WorkerNode)
@@ -1036,7 +1036,7 @@ describe('Abstract pool test suite', () => {
   it('Verify that pool can be started after initialization', async () => {
     const pool = new FixedClusterPool(
       numberOfWorkers,
-      './tests/worker-files/cluster/testWorker.cjs',
+      './tests/worker-files/cluster/testWorker.mjs',
       {
         startWorkers: false,
       }
@@ -1064,7 +1064,7 @@ describe('Abstract pool test suite', () => {
   it('Verify that pool execute() arguments are checked', async () => {
     const pool = new FixedClusterPool(
       numberOfWorkers,
-      './tests/worker-files/cluster/testWorker.cjs'
+      './tests/worker-files/cluster/testWorker.mjs'
     )
     await expect(pool.execute(undefined, 0)).rejects.toThrow(
       new TypeError('name argument must be a string')
@@ -1090,7 +1090,7 @@ describe('Abstract pool test suite', () => {
   it('Verify that pool worker tasks usage are computed', async () => {
     const pool = new FixedClusterPool(
       numberOfWorkers,
-      './tests/worker-files/cluster/testWorker.cjs'
+      './tests/worker-files/cluster/testWorker.mjs'
     )
     const promises = new Set()
     const maxMultiplier = 2
@@ -1237,7 +1237,7 @@ describe('Abstract pool test suite', () => {
     const pool = new DynamicClusterPool(
       Math.floor(numberOfWorkers / 2),
       numberOfWorkers,
-      './tests/worker-files/cluster/testWorker.cjs'
+      './tests/worker-files/cluster/testWorker.mjs'
     )
     expect(pool.emitter.eventNames()).toStrictEqual([])
     let poolInfo
@@ -1341,7 +1341,7 @@ describe('Abstract pool test suite', () => {
     const pool = new DynamicClusterPool(
       Math.floor(numberOfWorkers / 2),
       numberOfWorkers,
-      './tests/worker-files/cluster/testWorker.cjs'
+      './tests/worker-files/cluster/testWorker.mjs'
     )
     expect(pool.emitter.eventNames()).toStrictEqual([])
     const promises = new Set()
@@ -1495,7 +1495,7 @@ describe('Abstract pool test suite', () => {
     const pool = new DynamicClusterPool(
       0,
       numberOfWorkers,
-      './tests/worker-files/cluster/testWorker.cjs'
+      './tests/worker-files/cluster/testWorker.mjs'
     )
     expect(pool.emitter.eventNames()).toStrictEqual([])
     const promises = new Set()
@@ -1568,7 +1568,7 @@ describe('Abstract pool test suite', () => {
   for (const { PoolClass, workerFilePath, workerType } of [
     {
       PoolClass: FixedClusterPool,
-      workerFilePath: './tests/worker-files/cluster/asyncWorker.cjs',
+      workerFilePath: './tests/worker-files/cluster/asyncWorker.mjs',
       workerType: WorkerTypes.cluster,
     },
     {
@@ -1659,7 +1659,7 @@ describe('Abstract pool test suite', () => {
     await dynamicThreadPool.destroy()
     const fixedClusterPool = new FixedClusterPool(
       numberOfWorkers,
-      './tests/worker-files/cluster/testMultipleTaskFunctionsWorker.cjs'
+      './tests/worker-files/cluster/testMultipleTaskFunctionsWorker.mjs'
     )
     await waitPoolEvents(fixedClusterPool, PoolEvents.ready, 1)
     expect(fixedClusterPool.hasTaskFunction(DEFAULT_TASK_NAME)).toBe(true)
@@ -2081,7 +2081,7 @@ describe('Abstract pool test suite', () => {
     await dynamicThreadPool.destroy()
     const fixedClusterPool = new FixedClusterPool(
       numberOfWorkers,
-      './tests/worker-files/cluster/testMultipleTaskFunctionsWorker.cjs'
+      './tests/worker-files/cluster/testMultipleTaskFunctionsWorker.mjs'
     )
     await waitPoolEvents(fixedClusterPool, PoolEvents.ready, 1)
     expect(fixedClusterPool.listTaskFunctionsProperties()).toStrictEqual([
@@ -2151,7 +2151,7 @@ describe('Abstract pool test suite', () => {
     const pool = new DynamicClusterPool(
       Math.floor(numberOfWorkers / 2),
       numberOfWorkers,
-      './tests/worker-files/cluster/testMultipleTaskFunctionsWorker.cjs'
+      './tests/worker-files/cluster/testMultipleTaskFunctionsWorker.mjs'
     )
     const data = { n: 10 }
     const result0 = await pool.execute(data)
@@ -2381,7 +2381,7 @@ describe('Abstract pool test suite', () => {
     const pool = new DynamicClusterPool(
       Math.floor(numberOfWorkers / 2),
       numberOfWorkers,
-      './tests/worker-files/cluster/testWorker.cjs'
+      './tests/worker-files/cluster/testWorker.mjs'
     )
     const workerNodeKey = 0
     await expect(
@@ -2394,7 +2394,7 @@ describe('Abstract pool test suite', () => {
     const pool = new DynamicClusterPool(
       Math.floor(numberOfWorkers / 2),
       numberOfWorkers,
-      './tests/worker-files/cluster/testWorker.cjs'
+      './tests/worker-files/cluster/testWorker.mjs'
     )
     const workerNodeKey = 0
     await expect(
@@ -2418,7 +2418,7 @@ describe('Abstract pool test suite', () => {
     const pool = new DynamicClusterPool(
       Math.floor(numberOfWorkers / 2),
       numberOfWorkers,
-      './tests/worker-files/cluster/testWorker.cjs'
+      './tests/worker-files/cluster/testWorker.mjs'
     )
     await expect(
       pool.sendTaskFunctionOperationToWorkers({
index 45f2be5172e459b8fbc64b4b77e5ca35a43ace57..d057dfd6da29d73cdf1299522bfe0a6445152b9a 100644 (file)
@@ -17,7 +17,7 @@ describe('Dynamic cluster pool test suite', () => {
     pool = new DynamicClusterPool(
       min,
       max,
-      './tests/worker-files/cluster/testWorker.cjs',
+      './tests/worker-files/cluster/testWorker.mjs',
       {
         errorHandler: e => console.error(e),
       }
@@ -123,7 +123,7 @@ describe('Dynamic cluster pool test suite', () => {
     const longRunningPool = new DynamicClusterPool(
       min,
       max,
-      './tests/worker-files/cluster/longRunningWorkerHardBehavior.cjs',
+      './tests/worker-files/cluster/longRunningWorkerHardBehavior.mjs',
       {
         errorHandler: e => console.error(e),
         exitHandler: () => console.info('long executing worker exited'),
@@ -150,7 +150,7 @@ describe('Dynamic cluster pool test suite', () => {
     const longRunningPool = new DynamicClusterPool(
       min,
       max,
-      './tests/worker-files/cluster/longRunningWorkerSoftBehavior.cjs',
+      './tests/worker-files/cluster/longRunningWorkerSoftBehavior.mjs',
       {
         errorHandler: e => console.error(e),
         exitHandler: () => console.info('long executing worker exited'),
@@ -173,7 +173,7 @@ describe('Dynamic cluster pool test suite', () => {
     const pool = new DynamicClusterPool(
       0,
       max,
-      './tests/worker-files/cluster/testWorker.cjs'
+      './tests/worker-files/cluster/testWorker.mjs'
     )
     expect(pool).toBeInstanceOf(DynamicClusterPool)
     // We need to clean up the resources after our test
@@ -185,7 +185,7 @@ describe('Dynamic cluster pool test suite', () => {
       const pool = new DynamicClusterPool(
         0,
         max,
-        './tests/worker-files/cluster/testWorker.cjs',
+        './tests/worker-files/cluster/testWorker.mjs',
         {
           startWorkers: false,
           workerChoiceStrategy,
index 9c40ab1bb71f55419859bc2dd98549df86c7f9d7..481a6de8ee02f29e4583bbc6034b689ccb8119a4 100644 (file)
@@ -14,14 +14,14 @@ describe('Fixed cluster pool test suite', () => {
   beforeAll(() => {
     pool = new FixedClusterPool(
       numberOfWorkers,
-      './tests/worker-files/cluster/testWorker.cjs',
+      './tests/worker-files/cluster/testWorker.mjs',
       {
         errorHandler: e => console.error(e),
       }
     )
     queuePool = new FixedClusterPool(
       numberOfWorkers,
-      './tests/worker-files/cluster/testWorker.cjs',
+      './tests/worker-files/cluster/testWorker.mjs',
       {
         enableTasksQueue: true,
         errorHandler: e => console.error(e),
@@ -32,30 +32,30 @@ describe('Fixed cluster pool test suite', () => {
     )
     emptyPool = new FixedClusterPool(
       numberOfWorkers,
-      './tests/worker-files/cluster/emptyWorker.cjs',
+      './tests/worker-files/cluster/emptyWorker.mjs',
       { exitHandler: () => console.info('empty pool worker exited') }
     )
     echoPool = new FixedClusterPool(
       numberOfWorkers,
-      './tests/worker-files/cluster/echoWorker.cjs'
+      './tests/worker-files/cluster/echoWorker.mjs'
     )
     errorPool = new FixedClusterPool(
       numberOfWorkers,
-      './tests/worker-files/cluster/errorWorker.cjs',
+      './tests/worker-files/cluster/errorWorker.mjs',
       {
         errorHandler: e => console.error(e),
       }
     )
     asyncErrorPool = new FixedClusterPool(
       numberOfWorkers,
-      './tests/worker-files/cluster/asyncErrorWorker.cjs',
+      './tests/worker-files/cluster/asyncErrorWorker.mjs',
       {
         errorHandler: e => console.error(e),
       }
     )
     asyncPool = new FixedClusterPool(
       numberOfWorkers,
-      './tests/worker-files/cluster/asyncWorker.cjs'
+      './tests/worker-files/cluster/asyncWorker.mjs'
     )
   })
 
@@ -294,7 +294,7 @@ describe('Fixed cluster pool test suite', () => {
   })
 
   it('Verify that cluster pool options are checked', async () => {
-    const workerFilePath = './tests/worker-files/cluster/testWorker.cjs'
+    const workerFilePath = './tests/worker-files/cluster/testWorker.mjs'
     let pool = new FixedClusterPool(numberOfWorkers, workerFilePath)
     expect(pool.opts.env).toBeUndefined()
     expect(pool.opts.settings).toBeUndefined()
@@ -321,7 +321,7 @@ describe('Fixed cluster pool test suite', () => {
   })
 
   it('Verify destroyWorkerNode()', async () => {
-    const workerFilePath = './tests/worker-files/cluster/testWorker.cjs'
+    const workerFilePath = './tests/worker-files/cluster/testWorker.mjs'
     const pool = new FixedClusterPool(numberOfWorkers, workerFilePath)
     const workerNodeKey = 0
     let disconnectEvent = 0
@@ -344,7 +344,7 @@ describe('Fixed cluster pool test suite', () => {
   it('Verify that a pool with zero worker fails', () => {
     expect(
       () =>
-        new FixedClusterPool(0, './tests/worker-files/cluster/testWorker.cjs')
+        new FixedClusterPool(0, './tests/worker-files/cluster/testWorker.mjs')
     ).toThrow('Cannot instantiate a fixed pool with zero worker')
   })
 })
diff --git a/tests/pools/cluster/module-formats.test.mjs b/tests/pools/cluster/module-formats.test.mjs
new file mode 100644 (file)
index 0000000..617ec16
--- /dev/null
@@ -0,0 +1,70 @@
+import { describe, expect, it } from 'vitest'
+
+import { DynamicClusterPool, FixedClusterPool } from '../../../lib/index.mjs'
+
+const bounded = async promise => {
+  let timeout
+  try {
+    return await Promise.race([
+      promise,
+      new Promise((resolve, reject) => {
+        timeout = setTimeout(
+          () => reject(new Error('Cluster worker operation remained pending')),
+          5000
+        )
+      }),
+    ])
+  } finally {
+    clearTimeout(timeout)
+  }
+}
+
+// Start destruction before force-killing on failure, so fixed workers cannot restart.
+const destroyPool = async pool => {
+  const workers = pool.workerNodes.map(workerNode => workerNode.worker)
+  const exits = workers.map(worker => {
+    return worker.isDead()
+      ? Promise.resolve()
+      : new Promise(resolve => worker.once('exit', resolve))
+  })
+  try {
+    await bounded(pool.destroy())
+    expect(workers.every(worker => worker.isDead())).toBe(true)
+  } finally {
+    for (const worker of workers) {
+      if (!worker.isDead()) worker.process.kill('SIGKILL')
+    }
+    await bounded(Promise.all(exits))
+  }
+  expect(workers).toHaveLength(1)
+  expect(pool.info.started).toBe(false)
+}
+
+for (const [poolType, PoolClass, sizes] of [
+  ['fixed', FixedClusterPool, [1]],
+  ['dynamic', DynamicClusterPool, [0, 1]],
+]) {
+  describe(`${poolType} cluster worker module formats`, { retry: 0 }, () => {
+    for (const [format, workerFile] of [
+      ['ESM', './tests/worker-files/cluster/echoWorker.mjs'],
+      ['CommonJS', './tests/worker-files/cluster/echoWorker.cjs'],
+    ]) {
+      it(`executes an immediate task with ${format} and destroys the worker`, async () => {
+        const pool = new PoolClass(...sizes, workerFile, {
+          restartWorkerOnError: false,
+        })
+        const data = {
+          format,
+          nested: { enabled: true, values: [1, 'two', null] },
+          poolType,
+        }
+        try {
+          // Do not wait for online or ready: the first startup message must survive ESM loading.
+          expect(await bounded(pool.execute(data))).toStrictEqual(data)
+        } finally {
+          await destroyPool(pool)
+        }
+      }, 20000)
+    }
+  })
+}
index e1200ea8fcbdce8c7bef59f77633d8df6425c118..bec32b0ff110e8cfad618606d50f95d140d997d0 100644 (file)
@@ -13,9 +13,9 @@ import {
   FixedThreadPool,
 } from '../../lib/index.mjs'
 
-const clusterWorker = './tests/worker-files/cluster/testWorker.cjs'
+const clusterWorker = './tests/worker-files/cluster/testWorker.mjs'
 const clusterIntrospectionWorker = resolve(
-  './tests/worker-files/cluster/prototypePollutionWorker.cjs'
+  './tests/worker-files/cluster/prototypePollutionWorker.mjs'
 )
 const environmentPollutionKey = 'POOLIFIER_ARBITRARY_ENV_POLLUTION'
 const pollutedProperties = [
index 33a3425d1168f1b9e8afab95d717dc0f9dd93209..840b31808feb2677fda1af9ffd931ea9887659fa 100644 (file)
@@ -14,7 +14,7 @@ describe('Selection strategies utils test suite', () => {
   beforeAll(() => {
     clusterFixedPool = new FixedClusterPool(
       numberOfWorkers,
-      './tests/worker-files/cluster/testWorker.cjs'
+      './tests/worker-files/cluster/testWorker.mjs'
     )
     threadFixedPool = new FixedThreadPool(
       numberOfThreads,
index df69f2f66e96d8edb6b722f7a41331b9dcd344d3..56dd2dd9a8110d45af8a0cb74267cc3f7b7a4e2e 100644 (file)
@@ -77,7 +77,7 @@ describe('Selection strategies test suite', () => {
       const pool = new DynamicClusterPool(
         min,
         max,
-        './tests/worker-files/cluster/testWorker.cjs'
+        './tests/worker-files/cluster/testWorker.mjs'
       )
       pool.setWorkerChoiceStrategy(workerChoiceStrategy)
       expect(pool.opts.workerChoiceStrategy).toBe(workerChoiceStrategy)
@@ -360,7 +360,7 @@ describe('Selection strategies test suite', () => {
     const workerChoiceStrategy = WorkerChoiceStrategies.ROUND_ROBIN
     let pool = new FixedClusterPool(
       max,
-      './tests/worker-files/cluster/testWorker.cjs',
+      './tests/worker-files/cluster/testWorker.mjs',
       { workerChoiceStrategy }
     )
     let results = new Set()
index 0c5a56e01eb38807446ec975d2e91aa49fe44e67..35250b0fe1b8142f810e6496151fc401c574f513 100644 (file)
@@ -678,7 +678,7 @@ parentPort.postMessage({
     expect(
       createWorker(
         WorkerTypes.cluster,
-        './tests/worker-files/cluster/testWorker.cjs',
+        './tests/worker-files/cluster/testWorker.mjs',
         {}
       )
     ).toBeInstanceOf(ClusterWorker)
@@ -705,7 +705,7 @@ parentPort.postMessage({
     })
     const clusterWorker = createWorker(
       WorkerTypes.cluster,
-      './tests/worker-files/cluster/testWorker.cjs',
+      './tests/worker-files/cluster/testWorker.mjs',
       {}
     )
     const clusterWorkerInfo = initWorkerInfo(clusterWorker)
index b521d1610fe3eb7741a85a6cc6a2594af28e5321..07bbbe48c200036ba4a88eb00c4a5e9be6275549 100644 (file)
@@ -49,7 +49,7 @@ const cleanupRegressionPool = async (pool, capturedNodes) => {
 
 for (const [workerType, PoolClass, workerFile] of [
   ['thread', FixedThreadPool, './tests/worker-files/thread/crashWorker.mjs'],
-  ['cluster', FixedClusterPool, './tests/worker-files/cluster/crashWorker.cjs'],
+  ['cluster', FixedClusterPool, './tests/worker-files/cluster/crashWorker.mjs'],
 ]) {
   describe(`${workerType} worker exit`, { retry: 0 }, () => {
     const createPool = async (size = 1, options = {}) => {
index 1e9443da93ecfcf6e9161e66a29cbf2226e046de..4e0a8f16cb9babdddca850339b785a89d90d707c 100644 (file)
@@ -26,7 +26,7 @@ describe('Worker node test suite', () => {
     )
     clusterWorkerNode = new WorkerNode(
       WorkerTypes.cluster,
-      './tests/worker-files/cluster/testWorker.cjs',
+      './tests/worker-files/cluster/testWorker.mjs',
       {
         tasksQueueBackPressureSize: 12,
         tasksQueueBucketSize: 6,
@@ -83,13 +83,13 @@ describe('Worker node test suite', () => {
   it('terminates an already disconnected cluster worker node and can terminate it again after exit', async () => {
     const clusterSettings = { ...cluster.settings }
     cluster.setupPrimary({
-      exec: './tests/worker-files/cluster/crashWorker.cjs',
+      exec: './tests/worker-files/cluster/crashWorker.mjs',
     })
     let workerNode
     try {
       workerNode = new WorkerNode(
         WorkerTypes.cluster,
-        './tests/worker-files/cluster/crashWorker.cjs',
+        './tests/worker-files/cluster/crashWorker.mjs',
         {
           tasksQueueBackPressureSize: 12,
           tasksQueueBucketSize: 6,
similarity index 66%
rename from tests/worker-files/cluster/asyncErrorWorker.cjs
rename to tests/worker-files/cluster/asyncErrorWorker.mjs
index ffab9c176c8e6f856043dbcde0271c502fb54884..d9bae1e57349caf40b8acf164362eb352479fd08 100644 (file)
@@ -1,6 +1,5 @@
-'use strict'
-const { ClusterWorker, KillBehaviors } = require('../../../lib/index.cjs')
-const { sleepTaskFunction } = require('../../test-utils.cjs')
+import { ClusterWorker, KillBehaviors } from '../../../lib/index.mjs'
+import { sleepTaskFunction } from '../../test-utils.cjs'
 
 /**
  * Test worker function that throws an error after sleeping.
@@ -16,7 +15,7 @@ async function error (data) {
   )
 }
 
-module.exports = new ClusterWorker(error, {
+export default new ClusterWorker(error, {
   killBehavior: KillBehaviors.HARD,
   maxInactiveTime: 500,
 })
similarity index 58%
rename from tests/worker-files/cluster/asyncWorker.cjs
rename to tests/worker-files/cluster/asyncWorker.mjs
index 1ebe9a5e3e74b72d18953f7aaae03be50eb470bc..f642bd7e76235ed0ee81d49202ed7aae6a62fc64 100644 (file)
@@ -1,6 +1,5 @@
-'use strict'
-const { ClusterWorker, KillBehaviors } = require('../../../lib/index.cjs')
-const { sleepTaskFunction } = require('../../test-utils.cjs')
+import { ClusterWorker, KillBehaviors } from '../../../lib/index.mjs'
+import { sleepTaskFunction } from '../../test-utils.cjs'
 
 /**
  * Test worker function that sleeps for a specified duration.
@@ -11,7 +10,7 @@ async function sleep (data) {
   return sleepTaskFunction(data, 2000)
 }
 
-module.exports = new ClusterWorker(sleep, {
+export default new ClusterWorker(sleep, {
   killBehavior: KillBehaviors.HARD,
   maxInactiveTime: 500,
 })
similarity index 85%
rename from tests/worker-files/cluster/crashWorker.cjs
rename to tests/worker-files/cluster/crashWorker.mjs
index 56e6e4bf81d5bda4bd4d6ae1db7e5a092fff5cb3..634a5faba6eeb163cc90e080289ef906447094ef 100644 (file)
@@ -1,7 +1,6 @@
-'use strict'
-const cluster = require('node:cluster')
+import cluster from 'node:cluster'
 
-const { ClusterWorker } = require('../../../lib/index.cjs')
+import { ClusterWorker } from '../../../lib/index.mjs'
 
 const pendingTasks = new Map()
 
@@ -24,7 +23,7 @@ process.on('message', message => {
   }
 })
 
-module.exports = new ClusterWorker(async data => {
+export default new ClusterWorker(async data => {
   if (data.exitCode != null) {
     // Exit without an error event to exercise lost task responses.
     // eslint-disable-next-line n/no-process-exit
diff --git a/tests/worker-files/cluster/echoWorker.mjs b/tests/worker-files/cluster/echoWorker.mjs
new file mode 100644 (file)
index 0000000..4906c7e
--- /dev/null
@@ -0,0 +1,14 @@
+import { ClusterWorker, KillBehaviors } from '../../../lib/index.mjs'
+
+/**
+ * Test worker function that echoes the input data.
+ * @param data - The task data to echo.
+ * @returns The same data that was passed in.
+ */
+function echo (data) {
+  return data
+}
+
+export default new ClusterWorker(echo, {
+  killBehavior: KillBehaviors.HARD,
+})
diff --git a/tests/worker-files/cluster/emptyWorker.cjs b/tests/worker-files/cluster/emptyWorker.cjs
deleted file mode 100644 (file)
index 78f534a..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-'use strict'
-const { ClusterWorker, KillBehaviors } = require('../../../lib/index.cjs')
-
-/**
- *
- */
-function test () {}
-
-module.exports = new ClusterWorker(test, {
-  killBehavior: KillBehaviors.HARD,
-  maxInactiveTime: 500,
-})
diff --git a/tests/worker-files/cluster/emptyWorker.mjs b/tests/worker-files/cluster/emptyWorker.mjs
new file mode 100644 (file)
index 0000000..eb05acf
--- /dev/null
@@ -0,0 +1,11 @@
+import { ClusterWorker, KillBehaviors } from '../../../lib/index.mjs'
+
+/**
+ *
+ */
+function test () {}
+
+export default new ClusterWorker(test, {
+  killBehavior: KillBehaviors.HARD,
+  maxInactiveTime: 500,
+})
similarity index 53%
rename from tests/worker-files/cluster/errorWorker.cjs
rename to tests/worker-files/cluster/errorWorker.mjs
index 9a2695b258515ca364867f0a169f877108b0e905..0828169b501356d12f69ea4c23c06f9ef23dd7e5 100644 (file)
@@ -1,5 +1,4 @@
-'use strict'
-const { ClusterWorker, KillBehaviors } = require('../../../lib/index.cjs')
+import { ClusterWorker, KillBehaviors } from '../../../lib/index.mjs'
 
 /**
  *
@@ -8,7 +7,7 @@ function error () {
   throw new Error('Error Message from ClusterWorker')
 }
 
-module.exports = new ClusterWorker(error, {
+export default new ClusterWorker(error, {
   killBehavior: KillBehaviors.HARD,
   maxInactiveTime: 500,
 })
similarity index 59%
rename from tests/worker-files/cluster/longRunningWorkerHardBehavior.cjs
rename to tests/worker-files/cluster/longRunningWorkerHardBehavior.mjs
index eb31dfa3d320ad3760523591e4a7a4153a7368a4..83d4ac67a62852a5057ca714ffce52e432b506aa 100644 (file)
@@ -1,6 +1,5 @@
-'use strict'
-const { ClusterWorker, KillBehaviors } = require('../../../lib/index.cjs')
-const { sleepTaskFunction } = require('../../test-utils.cjs')
+import { ClusterWorker, KillBehaviors } from '../../../lib/index.mjs'
+import { sleepTaskFunction } from '../../test-utils.cjs'
 
 /**
  * Test worker function for long-running tasks with hard kill behavior.
@@ -11,7 +10,7 @@ async function sleep (data) {
   return sleepTaskFunction(data, 50000)
 }
 
-module.exports = new ClusterWorker(sleep, {
+export default new ClusterWorker(sleep, {
   killBehavior: KillBehaviors.HARD,
   maxInactiveTime: 500,
 })
similarity index 60%
rename from tests/worker-files/cluster/longRunningWorkerSoftBehavior.cjs
rename to tests/worker-files/cluster/longRunningWorkerSoftBehavior.mjs
index 94ad584f2bfa494e283a14e2dca46708614bb522..4052bfe4804a636e09b658d5b67b364f218e7027 100644 (file)
@@ -1,6 +1,5 @@
-'use strict'
-const { ClusterWorker } = require('../../../lib/index.cjs')
-const { sleepTaskFunction } = require('../../test-utils.cjs')
+import { ClusterWorker } from '../../../lib/index.mjs'
+import { sleepTaskFunction } from '../../test-utils.cjs'
 
 /**
  * Test worker function that performs a long-running sleep operation with soft behavior.
@@ -11,6 +10,6 @@ async function sleep (data) {
   return sleepTaskFunction(data, 50000)
 }
 
-module.exports = new ClusterWorker(sleep, {
+export default new ClusterWorker(sleep, {
   maxInactiveTime: 500,
 })
similarity index 75%
rename from tests/worker-files/cluster/prototypePollutionWorker.cjs
rename to tests/worker-files/cluster/prototypePollutionWorker.mjs
index 08bef924ec6b71ee2c3ab421268f1d3722f645a7..e9fee840f8043808f44887770c5828f714523044 100644 (file)
@@ -1,5 +1,4 @@
-'use strict'
-const { ClusterWorker, KillBehaviors } = require('../../../lib/index.cjs')
+import { ClusterWorker, KillBehaviors } from '../../../lib/index.mjs'
 
 /**
  * Returns the cluster worker launch context needed by security regressions.
@@ -15,7 +14,7 @@ function inspectLaunchContext (data = {}) {
   }
 }
 
-module.exports = new ClusterWorker(inspectLaunchContext, {
+export default new ClusterWorker(inspectLaunchContext, {
   killBehavior: KillBehaviors.HARD,
   maxInactiveTime: 500,
 })
similarity index 72%
rename from tests/worker-files/cluster/testMultipleTaskFunctionsWorker.cjs
rename to tests/worker-files/cluster/testMultipleTaskFunctionsWorker.mjs
index 3ce4f7c53e2f6c8f9a2e2a75747d3d2eda03499d..0085d50c590a514b0248cdd880d520b16fc0baf1 100644 (file)
@@ -1,12 +1,11 @@
-'use strict'
-const { ClusterWorker, KillBehaviors } = require('../../../lib/index.cjs')
-const {
+import { ClusterWorker, KillBehaviors } from '../../../lib/index.mjs'
+import {
   factorial,
   fibonacci,
   jsonIntegerSerialization,
-} = require('../../test-utils.cjs')
+} from '../../test-utils.cjs'
 
-module.exports = new ClusterWorker(
+export default new ClusterWorker(
   {
     factorial: {
       priority: 1,
similarity index 68%
rename from tests/worker-files/cluster/testTaskFunctionObjectsWorker.cjs
rename to tests/worker-files/cluster/testTaskFunctionObjectsWorker.mjs
index 265ea136c689820bb80c29f25f2981c725b03d2b..961c3b7cd2ec48767a9976bcff400d4f2444fafe 100644 (file)
@@ -1,12 +1,11 @@
-'use strict'
-const { ClusterWorker, KillBehaviors } = require('../../../lib/index.cjs')
-const {
+import { ClusterWorker, KillBehaviors } from '../../../lib/index.mjs'
+import {
   factorial,
   fibonacci,
   jsonIntegerSerialization,
-} = require('../../test-utils.cjs')
+} from '../../test-utils.cjs'
 
-module.exports = new ClusterWorker(
+export default new ClusterWorker(
   {
     factorial: { taskFunction: data => factorial(data.n) },
     fibonacci: { priority: -5, taskFunction: data => fibonacci(data.n) },
similarity index 62%
rename from tests/worker-files/cluster/testWorker.cjs
rename to tests/worker-files/cluster/testWorker.mjs
index 871f74d090c71cb33b13506b81220083f131fbf0..0bc4a09def5999294b52e2f2a416878b0a460d20 100644 (file)
@@ -1,7 +1,6 @@
-'use strict'
-const { ClusterWorker, KillBehaviors } = require('../../../lib/index.cjs')
-const { TaskFunctions } = require('../../test-types.cjs')
-const { executeTaskFunction } = require('../../test-utils.cjs')
+import { ClusterWorker, KillBehaviors } from '../../../lib/index.mjs'
+import { TaskFunctions } from '../../test-types.cjs'
+import { executeTaskFunction } from '../../test-utils.cjs'
 
 /**
  * Test worker function that executes configurable task functions for testing.
@@ -14,7 +13,7 @@ function test (data) {
   return executeTaskFunction(data)
 }
 
-module.exports = new ClusterWorker(test, {
+export default new ClusterWorker(test, {
   killBehavior: KillBehaviors.HARD,
   maxInactiveTime: 500,
 })