Skip to content

Commit b7f733a

Browse files
CMCDragonkaitegefaulkes
authored andcommittedFeb 26, 2025
feat: migrate to ESM
1 parent aae39d9 commit b7f733a

15 files changed

+171
-89
lines changed
 

Diff for: ‎.eslintrc

+8-9
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,18 @@
77
"jest": true
88
},
99
"parser": "@typescript-eslint/parser",
10-
"extends": [
11-
"eslint:recommended",
12-
"plugin:@typescript-eslint/recommended",
13-
"plugin:prettier/recommended",
14-
"prettier"
15-
],
16-
"plugins": [
17-
"import"
18-
],
1910
"parserOptions": {
2011
"project": "tsconfig.json",
2112
"sourceType": "module"
2213
},
14+
"plugins": [
15+
"import"
16+
],
17+
"extends": [
18+
"eslint:recommended",
19+
"plugin:@typescript-eslint/recommended",
20+
"plugin:prettier/recommended"
21+
],
2322
"rules": {
2423
"linebreak-style": ["error", "unix"],
2524
"no-empty": 1,

Diff for: ‎README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ npm install
5555
# build the dist
5656
npm run build
5757
# run the repl (this allows you to import from ./src)
58-
npm run ts-node
58+
npm run tsx
5959
# run the tests
6060
npm run test
6161
# lint the source code

Diff for: ‎benches/index.ts

+20-9
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,29 @@
11
#!/usr/bin/env ts-node
22

3-
import fs from 'fs';
4-
import path from 'path';
3+
import fs from 'node:fs';
4+
import path from 'node:path';
5+
import url from 'node:url';
56
import si from 'systeminformation';
6-
import workerManager from './worker_manager';
7+
import { benchesPath } from './utils/utils.js';
8+
import workerManager from './worker_manager.js';
79

810
async function main(): Promise<void> {
9-
await fs.promises.mkdir(path.join(__dirname, 'results'), { recursive: true });
11+
await fs.promises.mkdir(path.join(benchesPath, 'results'), {
12+
recursive: true,
13+
});
1014
await workerManager();
1115
const resultFilenames = await fs.promises.readdir(
12-
path.join(__dirname, 'results'),
16+
path.join(benchesPath, 'results'),
1317
);
1418
const metricsFile = await fs.promises.open(
15-
path.join(__dirname, 'results', 'metrics.txt'),
19+
path.join(benchesPath, 'results', 'metrics.txt'),
1620
'w',
1721
);
1822
let concatenating = false;
1923
for (const resultFilename of resultFilenames) {
2024
if (/.+_metrics\.txt$/.test(resultFilename)) {
2125
const metricsData = await fs.promises.readFile(
22-
path.join(__dirname, 'results', resultFilename),
26+
path.join(benchesPath, 'results', resultFilename),
2327
);
2428
if (concatenating) {
2529
await metricsFile.write('\n');
@@ -35,9 +39,16 @@ async function main(): Promise<void> {
3539
system: 'model, manufacturer',
3640
});
3741
await fs.promises.writeFile(
38-
path.join(__dirname, 'results', 'system.json'),
42+
path.join(benchesPath, 'results', 'system.json'),
3943
JSON.stringify(systemData, null, 2),
4044
);
4145
}
4246

43-
void main();
47+
if (import.meta.url.startsWith('file:')) {
48+
const modulePath = url.fileURLToPath(import.meta.url);
49+
if (process.argv[1] === modulePath) {
50+
void main();
51+
}
52+
}
53+
54+
export default main;

Diff for: ‎benches/utils/index.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
export * from './utils';
1+
export * from './utils.js';

Diff for: ‎benches/utils/utils.ts

+13-8
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,33 @@
1-
import fs from 'fs';
2-
import path from 'path';
1+
import fs from 'node:fs';
2+
import path from 'node:path';
3+
import url from 'node:url';
34
import b from 'benny';
45
import { codeBlock } from 'common-tags';
5-
import packageJson from '../../package.json';
6+
import packageJson from '../../package.json' assert { type: 'json' };
7+
8+
const benchesPath = path.dirname(
9+
path.dirname(url.fileURLToPath(import.meta.url)),
10+
);
611

712
const suiteCommon = [
813
b.cycle(),
914
b.complete(),
1015
b.save({
1116
file: (summary) => summary.name,
12-
folder: path.join(__dirname, '../results'),
17+
folder: path.join(benchesPath, 'results'),
1318
version: packageJson.version,
1419
details: true,
1520
}),
1621
b.save({
1722
file: (summary) => summary.name,
18-
folder: path.join(__dirname, '../results'),
23+
folder: path.join(benchesPath, 'results'),
1924
version: packageJson.version,
2025
format: 'chart.html',
2126
}),
2227
b.complete((summary) => {
2328
const filePath = path.join(
24-
__dirname,
25-
'../results',
29+
benchesPath,
30+
'results',
2631
summary.name + '_metrics.txt',
2732
);
2833
fs.writeFileSync(
@@ -58,4 +63,4 @@ const suiteCommon = [
5863
}),
5964
];
6065

61-
export { suiteCommon };
66+
export { benchesPath, suiteCommon };

Diff for: ‎benches/worker_manager.ts

+14-8
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
1-
import type { WorkerModule } from '@/worker';
2-
import path from 'path';
3-
import crypto from 'crypto';
1+
import type { WorkerModule } from '#worker.js';
2+
import path from 'node:path';
3+
import url from 'node:url';
4+
import crypto from 'node:crypto';
45
import b from 'benny';
56
import { spawn, Worker, Transfer } from 'threads';
67
import Logger, { LogLevel, StreamHandler } from '@matrixai/logger';
7-
import WorkerManager from '@/WorkerManager';
8-
import { suiteCommon } from './utils';
8+
import { suiteCommon } from './utils/index.js';
9+
import WorkerManager from '#WorkerManager.js';
10+
11+
const filePath = url.fileURLToPath(import.meta.url);
912

1013
const logger = new Logger('WorkerManager Bench', LogLevel.WARN, [
1114
new StreamHandler(),
@@ -22,7 +25,7 @@ async function main() {
2225
// 1 KiB of data is still too small
2326
const bytes = crypto.randomBytes(1024 * 1024);
2427
const summary = await b.suite(
25-
path.basename(__filename, path.extname(__filename)),
28+
path.basename(filePath, path.extname(filePath)),
2629
b.add('call overhead', async () => {
2730
// This calls a noop, this will show the overhead costs
2831
// All parallelised operation can never be faster than this
@@ -104,8 +107,11 @@ async function main() {
104107
return summary;
105108
}
106109

107-
if (require.main === module) {
108-
void main();
110+
if (import.meta.url.startsWith('file:')) {
111+
const modulePath = url.fileURLToPath(import.meta.url);
112+
if (process.argv[1] === modulePath) {
113+
void main();
114+
}
109115
}
110116

111117
export default main;

Diff for: ‎jest.config.js renamed to ‎jest.config.mjs

+15-12
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,16 @@
1-
const path = require('path');
2-
const { pathsToModuleNameMapper } = require('ts-jest');
3-
const { compilerOptions } = require('./tsconfig');
1+
import path from 'node:path';
2+
import url from 'node:url';
3+
import tsconfigJSON from './tsconfig.json' assert { type: "json" };
44

5-
const moduleNameMapper = pathsToModuleNameMapper(compilerOptions.paths, {
6-
prefix: '<rootDir>/src/',
7-
});
5+
const projectPath = path.dirname(url.fileURLToPath(import.meta.url));
86

97
// Global variables that are shared across the jest worker pool
108
// These variables must be static and serializable
119
const globals = {
1210
// Absolute directory to the project root
13-
projectDir: __dirname,
11+
projectDir: projectPath,
1412
// Absolute directory to the test root
15-
testDir: path.join(__dirname, 'tests'),
13+
testDir: path.join(projectPath, 'tests'),
1614
// Default asynchronous test timeout
1715
defaultTimeout: 20000,
1816
// Timeouts rely on setTimeout which takes 32 bit numbers
@@ -24,7 +22,7 @@ const globals = {
2422
// They can however receive the process environment
2523
// Use `process.env` to set variables
2624

27-
module.exports = {
25+
const config = {
2826
testEnvironment: 'node',
2927
verbose: true,
3028
collectCoverage: false,
@@ -40,10 +38,10 @@ module.exports = {
4038
parser: {
4139
syntax: "typescript",
4240
tsx: true,
43-
decorators: compilerOptions.experimentalDecorators,
41+
decorators: tsconfigJSON.compilerOptions.experimentalDecorators,
4442
dynamicImport: true,
4543
},
46-
target: compilerOptions.target.toLowerCase(),
44+
target: tsconfigJSON.compilerOptions.target.toLowerCase(),
4745
keepClassNames: true,
4846
},
4947
}
@@ -77,5 +75,10 @@ module.exports = {
7775
'jest-extended/all',
7876
'<rootDir>/tests/setupAfterEnv.ts'
7977
],
80-
moduleNameMapper: moduleNameMapper,
78+
moduleNameMapper: {
79+
"^(\\.{1,2}/.*)\\.js$": "$1",
80+
},
81+
extensionsToTreatAsEsm: ['.ts', '.tsx', '.mts'],
8182
};
83+
84+
export default config;

Diff for: ‎package.json

+28-16
Original file line numberDiff line numberDiff line change
@@ -8,31 +8,45 @@
88
"type": "git",
99
"url": "https://github.com/MatrixAI/js-workers.git"
1010
},
11-
"main": "dist/index.js",
12-
"types": "dist/index.d.ts",
11+
"type": "module",
12+
"exports": {
13+
"./package.json": "./package.json",
14+
".": {
15+
"types": "./dist/index.d.ts",
16+
"import": "./dist/index.js"
17+
},
18+
"./*.js": {
19+
"types": "./dist/*.d.ts",
20+
"import": "./dist/*.js"
21+
},
22+
"./*": "./dist/*"
23+
},
24+
"imports": {
25+
"#*": "./dist/*"
26+
},
1327
"scripts": {
1428
"prepare": "tsc -p ./tsconfig.build.json",
1529
"build": "shx rm -rf ./dist && tsc -p ./tsconfig.build.json",
1630
"postversion": "npm install --package-lock-only --ignore-scripts --silent",
17-
"ts-node": "ts-node",
18-
"test": "jest",
19-
"lint": "eslint '{src,tests,scripts,benches}/**/*.{js,ts}'",
20-
"lintfix": "eslint '{src,tests,scripts,benches}/**/*.{js,ts}' --fix",
31+
"tsx": "tsx",
32+
"test": "node ./scripts/test.mjs",
33+
"lint": "eslint '{src,tests,scripts,benches}/**/*.{js,mjs,ts,mts,jsx,tsx}'",
34+
"lintfix": "eslint '{src,tests,scripts,benches}/**/*.{js,mjs,ts,mts,jsx,tsx}' --fix",
2135
"lint-shell": "find ./src ./tests ./scripts -type f -regextype posix-extended -regex '.*\\.(sh)' -exec shellcheck {} +",
2236
"docs": "shx rm -rf ./docs && typedoc --gitRevision master --tsconfig ./tsconfig.build.json --out ./docs src",
23-
"bench": "shx rm -rf ./benches/results && ts-node ./benches"
37+
"bench": "tsc -p ./tsconfig.build.json && shx rm -rf ./benches/results && tsx ./benches/index.ts"
2438
},
2539
"dependencies": {
26-
"@matrixai/async-init": "^1.9.1",
27-
"@matrixai/errors": "^1.2.0",
28-
"@matrixai/logger": "^3.1.0",
29-
"threads": "^1.6.5"
40+
"@matrixai/async-init": "^2.0.0",
41+
"@matrixai/errors": "^2.0.1",
42+
"@matrixai/logger": "^4.0.1",
43+
"threads": "^1.7.0"
3044
},
3145
"devDependencies": {
32-
"@swc/core": "1.3.82",
46+
"@swc/core": "^1.3.76",
3347
"@swc/jest": "^0.2.29",
3448
"@types/jest": "^29.5.2",
35-
"@types/node": "^20.5.7",
49+
"@types/node": "^18.15.0",
3650
"@typescript-eslint/eslint-plugin": "^5.61.0",
3751
"@typescript-eslint/parser": "^5.61.0",
3852
"benny": "^3.7.1",
@@ -47,9 +61,7 @@
4761
"prettier": "^3.0.0",
4862
"shx": "^0.3.4",
4963
"systeminformation": "^5.18.5",
50-
"ts-jest": "^29.1.1",
51-
"ts-node": "^10.9.1",
52-
"tsconfig-paths": "^3.9.0",
64+
"tsx": "^3.12.7",
5365
"typedoc": "^0.24.8",
5466
"typescript": "^5.1.6"
5567
}

Diff for: ‎scripts/test.mjs

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#!/usr/bin/env node
2+
3+
import os from 'node:os';
4+
import path from 'node:path';
5+
import url from 'node:url';
6+
import process from 'node:process';
7+
import childProcess from 'node:child_process';
8+
9+
const projectPath = path.dirname(
10+
path.dirname(url.fileURLToPath(import.meta.url)),
11+
);
12+
13+
const platform = os.platform();
14+
15+
/* eslint-disable no-console */
16+
async function main() {
17+
const tscArgs = [`-p`, path.join(projectPath, 'tsconfig.build.json')];
18+
console.error('Running tsc:');
19+
console.error(['tsc', ...tscArgs].join(' '));
20+
childProcess.execFileSync('tsc', tscArgs, {
21+
stdio: ['inherit', 'inherit', 'inherit'],
22+
windowsHide: true,
23+
encoding: 'utf-8',
24+
shell: platform === 'win32' ? true : false,
25+
});
26+
const jestArgs = [];
27+
console.error('Running jest:');
28+
console.error(['jest', ...jestArgs].join(' '));
29+
childProcess.execFileSync('jest', jestArgs, {
30+
env: {
31+
...process.env,
32+
NODE_OPTIONS: '--experimental-vm-modules',
33+
},
34+
stdio: ['inherit', 'inherit', 'inherit'],
35+
windowsHide: true,
36+
encoding: 'utf-8',
37+
shell: platform === 'win32' ? true : false,
38+
});
39+
}
40+
/* eslint-enable no-console */
41+
42+
if (import.meta.url.startsWith('file:')) {
43+
const modulePath = url.fileURLToPath(import.meta.url);
44+
if (process.argv[1] === modulePath) {
45+
void main();
46+
}
47+
}

Diff for: ‎src/WorkerManager.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import type { ModuleThread } from 'threads';
22
import type { ModuleMethods } from 'threads/dist/types/master';
3+
import type WorkerManagerInterface from './WorkerManagerInterface.js';
34
import type { QueuedTask } from 'threads/dist/master/pool-types';
4-
import type WorkerManagerInterface from './WorkerManagerInterface';
55
import { Pool } from 'threads';
66
import Logger from '@matrixai/logger';
7-
import { CreateDestroy, ready } from '@matrixai/async-init/dist/CreateDestroy';
8-
import * as errors from './errors';
7+
import { CreateDestroy, ready } from '@matrixai/async-init/CreateDestroy.js';
8+
import * as errors from './errors.js';
99

1010
@CreateDestroy()
1111
class WorkerManager<W extends ModuleMethods>

Diff for: ‎src/index.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
export { default as WorkerManager } from './WorkerManager';
2-
export { default as workerModule } from './workerModule';
3-
export * as errors from './errors';
1+
export { default as WorkerManager } from './WorkerManager.js';
2+
export { default as workerModule } from './workerModule.js';
3+
export * as errors from './errors.js';
44

5-
export type { default as WorkerManagerInterface } from './WorkerManagerInterface';
6-
export type { WorkerModule } from './workerModule';
5+
export type { default as WorkerManagerInterface } from './WorkerManagerInterface.js';
6+
export type { WorkerModule } from './workerModule.js';

0 commit comments

Comments
 (0)