-
Notifications
You must be signed in to change notification settings - Fork 225
Expand file tree
/
Copy pathworkerize.ts
More file actions
95 lines (85 loc) · 2.38 KB
/
workerize.ts
File metadata and controls
95 lines (85 loc) · 2.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
import {
Worker,
isMainThread,
parentPort,
workerData,
} from 'node:worker_threads';
import codegen from '../targets/codegen';
import commonjs from '../targets/commonjs';
import custom from '../targets/custom';
import module from '../targets/module';
import typescript from '../targets/typescript';
import type { Report } from '../types';
import type { Target } from '../schema';
type WorkerData<T extends Target> = {
target: T;
data: Omit<Parameters<(typeof targets)[T]>[0], 'report'>;
};
const targets = {
commonjs,
module,
typescript,
codegen,
custom,
} as const;
export const run = async <T extends Target>(
target: T,
{ report, ...data }: Parameters<(typeof targets)[T]>[0]
) => {
if (!isMainThread) {
throw new Error('Worker can only be run from the main thread');
}
return new Promise<void>((resolve, reject) => {
const worker = new Worker(__filename, {
workerData: {
target,
data,
} satisfies WorkerData<T>,
env: {
...process.env,
FORCE_COLOR: process.stdout.isTTY ? '1' : '0',
},
});
worker.on('message', (message) => {
switch (message.type) {
case 'info':
report.info(message.message);
break;
case 'warn':
report.warn(message.message);
break;
case 'error':
report.error(message.message);
break;
case 'success':
report.success(message.message);
break;
}
});
worker.on('error', (error) => {
reject(error);
});
worker.on('exit', (code) => {
if (code !== 0) {
reject(new Error(`Worker exited with code ${code}`));
} else {
resolve();
}
});
});
};
if (!isMainThread) {
const { target, data } = workerData as WorkerData<Target>;
const report: Report = {
info: (message) => parentPort?.postMessage({ type: 'info', message }),
warn: (message) => parentPort?.postMessage({ type: 'warn', message }),
error: (message) => parentPort?.postMessage({ type: 'error', message }),
success: (message) => parentPort?.postMessage({ type: 'success', message }),
};
if (target in targets) {
// @ts-expect-error - typescript doesn't support correlated union types https://github.com/microsoft/TypeScript/issues/30581
targets[target]({ ...data, report });
} else {
throw new Error(`Unknown target: ${target}`);
}
}