| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374 |
- import { n as __toESM, t as require_binding } from "./binding-s-V_wTpj.mjs";
- import { o as logMultipleWatcherOption } from "./logs-D80CXhvg.mjs";
- import { v as LOG_LEVEL_WARN } from "./bindingify-input-options-DYpBf1OG.mjs";
- import { t as arraify } from "./misc-DJYbNKZX.mjs";
- import { n as createBundlerOptions, u as PluginDriver } from "./rolldown-build-DtGk-m96.mjs";
- import { t as aggregateBindingErrorsIntoJsError } from "./error-w0u7biK-.mjs";
- //#region ../../node_modules/.pnpm/signal-exit@4.1.0/node_modules/signal-exit/dist/mjs/signals.js
- /**
- * This is not the set of all possible signals.
- *
- * It IS, however, the set of all signals that trigger
- * an exit on either Linux or BSD systems. Linux is a
- * superset of the signal names supported on BSD, and
- * the unknown signals just fail to register, so we can
- * catch that easily enough.
- *
- * Windows signals are a different set, since there are
- * signals that terminate Windows processes, but don't
- * terminate (or don't even exist) on Posix systems.
- *
- * Don't bother with SIGKILL. It's uncatchable, which
- * means that we can't fire any callbacks anyway.
- *
- * If a user does happen to register a handler on a non-
- * fatal signal like SIGWINCH or something, and then
- * exit, it'll end up firing `process.emit('exit')`, so
- * the handler will be fired anyway.
- *
- * SIGBUS, SIGFPE, SIGSEGV and SIGILL, when not raised
- * artificially, inherently leave the process in a
- * state from which it is not safe to try and enter JS
- * listeners.
- */
- const signals = [];
- signals.push("SIGHUP", "SIGINT", "SIGTERM");
- if (process.platform !== "win32") signals.push("SIGALRM", "SIGABRT", "SIGVTALRM", "SIGXCPU", "SIGXFSZ", "SIGUSR2", "SIGTRAP", "SIGSYS", "SIGQUIT", "SIGIOT");
- if (process.platform === "linux") signals.push("SIGIO", "SIGPOLL", "SIGPWR", "SIGSTKFLT");
- //#endregion
- //#region ../../node_modules/.pnpm/signal-exit@4.1.0/node_modules/signal-exit/dist/mjs/index.js
- const processOk = (process) => !!process && typeof process === "object" && typeof process.removeListener === "function" && typeof process.emit === "function" && typeof process.reallyExit === "function" && typeof process.listeners === "function" && typeof process.kill === "function" && typeof process.pid === "number" && typeof process.on === "function";
- const kExitEmitter = Symbol.for("signal-exit emitter");
- const global = globalThis;
- const ObjectDefineProperty = Object.defineProperty.bind(Object);
- var Emitter = class {
- emitted = {
- afterExit: false,
- exit: false
- };
- listeners = {
- afterExit: [],
- exit: []
- };
- count = 0;
- id = Math.random();
- constructor() {
- if (global[kExitEmitter]) return global[kExitEmitter];
- ObjectDefineProperty(global, kExitEmitter, {
- value: this,
- writable: false,
- enumerable: false,
- configurable: false
- });
- }
- on(ev, fn) {
- this.listeners[ev].push(fn);
- }
- removeListener(ev, fn) {
- const list = this.listeners[ev];
- const i = list.indexOf(fn);
- /* c8 ignore start */
- if (i === -1) return;
- /* c8 ignore stop */
- if (i === 0 && list.length === 1) list.length = 0;
- else list.splice(i, 1);
- }
- emit(ev, code, signal) {
- if (this.emitted[ev]) return false;
- this.emitted[ev] = true;
- let ret = false;
- for (const fn of this.listeners[ev]) ret = fn(code, signal) === true || ret;
- if (ev === "exit") ret = this.emit("afterExit", code, signal) || ret;
- return ret;
- }
- };
- var SignalExitBase = class {};
- const signalExitWrap = (handler) => {
- return {
- onExit(cb, opts) {
- return handler.onExit(cb, opts);
- },
- load() {
- return handler.load();
- },
- unload() {
- return handler.unload();
- }
- };
- };
- var SignalExitFallback = class extends SignalExitBase {
- onExit() {
- return () => {};
- }
- load() {}
- unload() {}
- };
- var SignalExit = class extends SignalExitBase {
- /* c8 ignore start */
- #hupSig = process$1.platform === "win32" ? "SIGINT" : "SIGHUP";
- /* c8 ignore stop */
- #emitter = new Emitter();
- #process;
- #originalProcessEmit;
- #originalProcessReallyExit;
- #sigListeners = {};
- #loaded = false;
- constructor(process) {
- super();
- this.#process = process;
- this.#sigListeners = {};
- for (const sig of signals) this.#sigListeners[sig] = () => {
- const listeners = this.#process.listeners(sig);
- let { count } = this.#emitter;
- /* c8 ignore start */
- const p = process;
- if (typeof p.__signal_exit_emitter__ === "object" && typeof p.__signal_exit_emitter__.count === "number") count += p.__signal_exit_emitter__.count;
- /* c8 ignore stop */
- if (listeners.length === count) {
- this.unload();
- const ret = this.#emitter.emit("exit", null, sig);
- /* c8 ignore start */
- const s = sig === "SIGHUP" ? this.#hupSig : sig;
- if (!ret) process.kill(process.pid, s);
- }
- };
- this.#originalProcessReallyExit = process.reallyExit;
- this.#originalProcessEmit = process.emit;
- }
- onExit(cb, opts) {
- /* c8 ignore start */
- if (!processOk(this.#process)) return () => {};
- /* c8 ignore stop */
- if (this.#loaded === false) this.load();
- const ev = opts?.alwaysLast ? "afterExit" : "exit";
- this.#emitter.on(ev, cb);
- return () => {
- this.#emitter.removeListener(ev, cb);
- if (this.#emitter.listeners["exit"].length === 0 && this.#emitter.listeners["afterExit"].length === 0) this.unload();
- };
- }
- load() {
- if (this.#loaded) return;
- this.#loaded = true;
- this.#emitter.count += 1;
- for (const sig of signals) try {
- const fn = this.#sigListeners[sig];
- if (fn) this.#process.on(sig, fn);
- } catch (_) {}
- this.#process.emit = (ev, ...a) => {
- return this.#processEmit(ev, ...a);
- };
- this.#process.reallyExit = (code) => {
- return this.#processReallyExit(code);
- };
- }
- unload() {
- if (!this.#loaded) return;
- this.#loaded = false;
- signals.forEach((sig) => {
- const listener = this.#sigListeners[sig];
- /* c8 ignore start */
- if (!listener) throw new Error("Listener not defined for signal: " + sig);
- /* c8 ignore stop */
- try {
- this.#process.removeListener(sig, listener);
- } catch (_) {}
- /* c8 ignore stop */
- });
- this.#process.emit = this.#originalProcessEmit;
- this.#process.reallyExit = this.#originalProcessReallyExit;
- this.#emitter.count -= 1;
- }
- #processReallyExit(code) {
- /* c8 ignore start */
- if (!processOk(this.#process)) return 0;
- this.#process.exitCode = code || 0;
- /* c8 ignore stop */
- this.#emitter.emit("exit", this.#process.exitCode, null);
- return this.#originalProcessReallyExit.call(this.#process, this.#process.exitCode);
- }
- #processEmit(ev, ...args) {
- const og = this.#originalProcessEmit;
- if (ev === "exit" && processOk(this.#process)) {
- if (typeof args[0] === "number") this.#process.exitCode = args[0];
- /* c8 ignore start */
- const ret = og.call(this.#process, ev, ...args);
- /* c8 ignore start */
- this.#emitter.emit("exit", this.#process.exitCode, null);
- /* c8 ignore stop */
- return ret;
- } else return og.call(this.#process, ev, ...args);
- }
- };
- const process$1 = globalThis.process;
- const { onExit: onExit$1, load, unload } = signalExitWrap(processOk(process$1) ? new SignalExit(process$1) : new SignalExitFallback());
- //#endregion
- //#region src/utils/signal-exit.ts
- function onExit(...args) {
- if (typeof process === "object" && process.versions.webcontainer) {
- process.on("exit", (code) => {
- args[0](code, null);
- });
- return;
- }
- onExit$1(...args);
- }
- //#endregion
- //#region src/api/watch/watch-emitter.ts
- var WatcherEmitter = class {
- listeners = /* @__PURE__ */ new Map();
- on(event, listener) {
- const listeners = this.listeners.get(event);
- if (listeners) listeners.push(listener);
- else this.listeners.set(event, [listener]);
- return this;
- }
- off(event, listener) {
- const listeners = this.listeners.get(event);
- if (listeners) {
- const index = listeners.indexOf(listener);
- if (index !== -1) listeners.splice(index, 1);
- }
- return this;
- }
- clear(event) {
- this.listeners.delete(event);
- }
- /** Async emit — sequential dispatch so side effects from earlier handlers
- * (e.g. `event.result.close()` triggering `closeBundle`) are visible to later handlers. */
- async emit(event, ...args) {
- const handlers = this.listeners.get(event);
- if (handlers?.length) for (const h of handlers) await h(...args);
- }
- async close() {}
- };
- //#endregion
- //#region src/api/watch/watcher.ts
- var import_binding = /* @__PURE__ */ __toESM(require_binding(), 1);
- function createEventCallback(emitter) {
- return async (event) => {
- switch (event.eventKind()) {
- case "event": {
- const code = event.bundleEventKind();
- if (code === "BUNDLE_END") {
- const { duration, output, result } = event.bundleEndData();
- await emitter.emit("event", {
- code: "BUNDLE_END",
- duration,
- output: [output],
- result
- });
- } else if (code === "ERROR") {
- const data = event.bundleErrorData();
- await emitter.emit("event", {
- code: "ERROR",
- error: aggregateBindingErrorsIntoJsError(data.error),
- result: data.result
- });
- } else await emitter.emit("event", { code });
- break;
- }
- case "change": {
- const { path, kind } = event.watchChangeData();
- await emitter.emit("change", path, { event: kind });
- break;
- }
- case "restart":
- await emitter.emit("restart");
- break;
- case "close":
- await emitter.emit("close");
- break;
- }
- };
- }
- var Watcher = class {
- closed;
- inner;
- emitter;
- stopWorkers;
- constructor(emitter, inner, stopWorkers) {
- this.closed = false;
- this.inner = inner;
- this.emitter = emitter;
- const originClose = emitter.close.bind(emitter);
- emitter.close = async () => {
- await this.close();
- originClose();
- };
- this.stopWorkers = stopWorkers;
- process.nextTick(() => this.run());
- }
- async close() {
- if (this.closed) return;
- this.closed = true;
- for (const stop of this.stopWorkers) await stop?.();
- await this.inner.close();
- (0, import_binding.shutdownAsyncRuntime)();
- }
- async run() {
- await this.inner.run();
- this.inner.waitForClose();
- }
- };
- async function createWatcher(emitter, input) {
- const options = arraify(input);
- const bundlerOptions = await Promise.all(options.map((option) => arraify(option.output || {}).map(async (output) => {
- return createBundlerOptions(await PluginDriver.callOptionsHook(option, true), output, true);
- })).flat());
- warnMultiplePollingOptions(bundlerOptions);
- const callback = createEventCallback(emitter);
- new Watcher(emitter, new import_binding.BindingWatcher(bundlerOptions.map((option) => option.bundlerOptions), callback), bundlerOptions.map((option) => option.stopWorkers));
- }
- function warnMultiplePollingOptions(bundlerOptions) {
- let found = false;
- for (const option of bundlerOptions) {
- const watch = option.inputOptions.watch;
- const watcher = watch && typeof watch === "object" ? watch.watcher ?? watch.notify : void 0;
- if (watcher && (watcher.usePolling != null || watcher.pollInterval != null)) {
- if (found) {
- option.onLog(LOG_LEVEL_WARN, logMultipleWatcherOption());
- return;
- }
- found = true;
- }
- }
- }
- //#endregion
- //#region src/api/watch/index.ts
- /**
- * The API compatible with Rollup's `watch` function.
- *
- * This function will rebuild the bundle when it detects that the individual modules have changed on disk.
- *
- * Note that when using this function, it is your responsibility to call `event.result.close()` in response to the `BUNDLE_END` event to avoid resource leaks.
- *
- * @param input The watch options object or the list of them.
- * @returns A watcher object.
- *
- * @example
- * ```js
- * import { watch } from 'rolldown';
- *
- * const watcher = watch({ /* ... *\/ });
- * watcher.on('event', (event) => {
- * if (event.code === 'BUNDLE_END') {
- * console.log(event.duration);
- * event.result.close();
- * }
- * });
- *
- * // Stop watching
- * watcher.close();
- * ```
- *
- * @experimental
- * @category Programmatic APIs
- */
- function watch(input) {
- const emitter = new WatcherEmitter();
- createWatcher(emitter, input);
- return emitter;
- }
- //#endregion
- export { onExit as n, watch as t };
|