UNPKG

@babel/register

Version:
152 lines (146 loc) 3.84 kB
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