@babel/register
Version:
babel require hook
152 lines (146 loc) • 3.84 kB
JavaScript
import pirates from 'pirates';
import sourceMapSupport from '@cspotcode/source-map-support';
import { ACTIONS } from './types-shared.js';
import worker_threads from 'node:worker_threads';
let piratesRevert;
const maps = Object.create(null);
let sourceMapSupportInstalled = false;
function installSourceMapSupport() {
if (sourceMapSupportInstalled) return;
sourceMapSupport.install({
handleUncaughtExceptions: false,
environment: "node",
retrieveSourceMap(filename) {
const map = maps?.[filename];
if (map) {
return {
url: null,
map: map
};
} else {
return null;
}
}
});
sourceMapSupportInstalled = true;
}
function compile(client, inputCode, filename) {
const result = client.transform(inputCode, filename);
if (result == null) return inputCode;
const {
code,
map
} = result;
if (map) {
maps[filename] = map;
installSourceMapSupport();
}
return code;
}
function register$1(client, opts = {}) {
if (piratesRevert) piratesRevert();
piratesRevert = pirates.addHook(compile.bind(null, client), {
exts: opts.extensions ?? client.getDefaultExtensions(),
ignoreNodeModules: false,
matcher(filename) {
return !client.isFileIgnored(filename);
}
});
client.setOptions(opts);
}
function revert$1() {
if (piratesRevert) piratesRevert();
if (sourceMapSupportInstalled) {
sourceMapSupport.uninstall();
sourceMapSupportInstalled = false;
}
}
const envVarName = "___INTERNAL___IS_INSIDE_BABEL_REGISTER_WORKER___";
const envVarValue = "yes_I_am";
const markInRegisterWorker = env => ({
...env,
[envVarName]: envVarValue
});
const isInRegisterWorker = process.env[envVarName] === envVarValue;
class Client {
#send;
constructor(send) {
this.#send = send;
}
#eCache;
getDefaultExtensions() {
return this.#eCache ??= this.#send(ACTIONS.GET_DEFAULT_EXTENSIONS, undefined);
}
setOptions(options) {
return this.#send(ACTIONS.SET_OPTIONS, options);
}
transform(code, filename) {
return this.#send(ACTIONS.TRANSFORM, {
code,
filename
});
}
isFileIgnored(filename) {
return this.#send(ACTIONS.IS_FILE_IGNORED, filename);
}
close() {
this.#send(ACTIONS.CLOSE, undefined);
}
}
class WorkerClient extends Client {
#worker = new worker_threads.Worker(new URL("./worker/index.js", import.meta.url), {
env: markInRegisterWorker(process.env)
});
constructor() {
super((action, payload) => {
const signal = new Int32Array(new SharedArrayBuffer(4));
const subChannel = new worker_threads.MessageChannel();
this.#worker.postMessage({
signal,
port: subChannel.port1,
action,
payload
}, [subChannel.port1]);
Atomics.wait(signal, 0, 0);
const {
message
} = worker_threads.receiveMessageOnPort(subChannel.port2);
if (message.error) throw Object.assign(message.error, message.errorData);else return message.result;
});
this.#worker.unref();
}
}
let client;
let listener;
function register(opts) {
if (!client) {
let hasClosed = false;
listener = function (signalOrCode) {
if (hasClosed) return;
hasClosed = true;
client.close();
if (typeof signalOrCode !== "number") {
process.exit(0);
}
};
process.on("exit", listener);
process.on("SIGINT", listener);
process.on("SIGTERM", listener);
}
client ||= new WorkerClient();
register$1(client, opts);
}
function revert() {
revert$1();
if (listener) {
process.off("exit", listener);
process.off("SIGINT", listener);
process.off("SIGTERM", listener);
listener = undefined;
}
}
if (!isInRegisterWorker) {
register();
}
export { register as default, revert };
//# sourceMappingURL=index.js.map