/*
  @license
	Rollup.js v4.22.4
	Sat, 21 Sep 2024 06:10:53 GMT - commit 79c0aba353ca84c0e22c3cfe9eee433ba83f3670

	https://github.com/rollup/rollup

	Released under the MIT License.
*/
'use strict';

Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });

const index = require('./index.js');
const promises = require('node:fs/promises');
const process$2 = require('node:process');
const cli = require('../bin/rollup');
const rollup = require('./rollup.js');
const parseAst_js = require('./parseAst.js');
const loadConfigFile_js = require('./loadConfigFile.js');
const node_child_process = require('node:child_process');
const rollup_js = require('../rollup.js');
require('fs');
require('util');
require('stream');
require('path');
require('os');
require('./fsevents-importer.js');
require('events');
require('node:path');
require('tty');
require('../native.js');
require('node:perf_hooks');
require('node:url');
require('../getLogFilter.js');

function timeZone(date = new Date()) {
	const offset = date.getTimezoneOffset();
	const absOffset = Math.abs(offset);
	const hours = Math.floor(absOffset / 60);
	const minutes = absOffset % 60;
	const minutesOut = minutes > 0 ? ':' + ('0' + minutes).slice(-2) : '';
	return (offset < 0 ? '+' : '-') + hours + minutesOut;
}

function dateTime(options = {}) {
	let {
		date = new Date(),
		local = true,
		showTimeZone = false,
		showMilliseconds = false
	} = options;

	if (local) {
		// Offset the date so it will return the correct value when getting the ISO string.
		date = new Date(date.getTime() - (date.getTimezoneOffset() * 60000));
	}

	let end = '';

	if (showTimeZone) {
		end = ' UTC' + (local ? timeZone(date) : '');
	}

	if (showMilliseconds && date.getUTCMilliseconds() > 0) {
		end = ` ${date.getUTCMilliseconds()}ms${end}`;
	}

	return date
		.toISOString()
		.replace(/T/, ' ')
		.replace(/\..+/, end);
}

/**
 * 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'
    // should detect profiler and enable/disable accordingly.
    // see #21
    // 'SIGPROF'
    );
}
if (process.platform === 'linux') {
    signals.push('SIGIO', 'SIGPOLL', 'SIGPWR', 'SIGSTKFLT');
}

// Note: since nyc uses this module to output coverage, any lines
// that are in the direct sync flow of nyc's outputCoverage are
// ignored, since we can never get coverage for them.
// grab a reference to node's real process object right away
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);
// teeny special purpose ee
class Emitter {
    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;
    }
}
class SignalExitBase {
}
const signalExitWrap = (handler) => {
    return {
        onExit(cb, opts) {
            return handler.onExit(cb, opts);
        },
        load() {
            return handler.load();
        },
        unload() {
            return handler.unload();
        },
    };
};
class SignalExitFallback extends SignalExitBase {
    onExit() {
        return () => { };
    }
    load() { }
    unload() { }
}
class SignalExit extends SignalExitBase {
    // "SIGHUP" throws an `ENOSYS` error on Windows,
    // so use a supported signal instead
    /* 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;
        // { <signal>: <listener fn>, ... }
        this.#sigListeners = {};
        for (const sig of signals) {
            this.#sigListeners[sig] = () => {
                // If there are no other listeners, an exit is coming!
                // Simplest way: remove us and then re-send the signal.
                // We know that this will kill the process, so we can
                // safely emit now.
                const listeners = this.#process.listeners(sig);
                let { count } = this.#emitter;
                // This is a workaround for the fact that signal-exit v3 and signal
                // exit v4 are not aware of each other, and each will attempt to let
                // the other handle it, so neither of them do. To correct this, we
                // detect if we're the only handler *except* for previous versions
                // of signal-exit, and increment by the count of listeners it has
                // created.
                /* 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);
                    /* c8 ignore stop */
                }
            };
        }
        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 is the number of onSignalExit's that are in play.
        // It's important so that we can count the correct number of
        // listeners on signals, and don't wait for the other one to
        // handle it instead of us.
        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);
                /* c8 ignore start */
            }
            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 */
            }
            /* 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;
// wrap so that we call the method on the actual handler, without
// exporting it directly.
const { 
/**
 * Called when the process is exiting, whether via signal, explicit
 * exit, or running out of stuff to do.
 *
 * If the global process object is not suitable for instrumentation,
 * then this will be a no-op.
 *
 * Returns a function that may be used to unload signal-exit.
 */
onExit, 
/**
 * Load the listeners.  Likely you never need to call this, unless
 * doing a rather deep integration with signal-exit functionality.
 * Mostly exposed for the benefit of testing.
 *
 * @internal
 */
load, 
/**
 * Unload the listeners.  Likely you never need to call this, unless
 * doing a rather deep integration with signal-exit functionality.
 * Mostly exposed for the benefit of testing.
 *
 * @internal
 */
unload, } = signalExitWrap(processOk(process$1) ? new SignalExit(process$1) : new SignalExitFallback());

const CLEAR_SCREEN = '\u001Bc';
function getResetScreen(configs, allowClearScreen) {
    let clearScreen = allowClearScreen;
    for (const config of configs) {
        if (config.watch && config.watch.clearScreen === false) {
            clearScreen = false;
        }
    }
    if (clearScreen) {
        return (heading) => rollup.stderr(CLEAR_SCREEN + heading);
    }
    let firstRun = true;
    return (heading) => {
        if (firstRun) {
            rollup.stderr(heading);
            firstRun = false;
        }
    };
}

function extractWatchHooks(command) {
    if (!Array.isArray(command.watch))
        return {};
    return command.watch
        .filter(value => typeof value === 'object')
        .reduce((accumulator, keyValueOption) => ({ ...accumulator, ...keyValueOption }), {});
}
function createWatchHooks(command) {
    const watchHooks = extractWatchHooks(command);
    return function (hook) {
        if (watchHooks[hook]) {
            const cmd = watchHooks[hook];
            if (!command.silent) {
                rollup.stderr(rollup.cyan$1(`watch.${hook} ${rollup.bold(`$ ${cmd}`)}`));
            }
            try {
                // !! important - use stderr for all writes from execSync
                const stdio = [process.stdin, process.stderr, process.stderr];
                node_child_process.execSync(cmd, { stdio: command.silent ? 'ignore' : stdio });
            }
            catch (error) {
                rollup.stderr(error.message);
            }
        }
    };
}

async function watch(command) {
    process$2.env.ROLLUP_WATCH = 'true';
    const isTTY = process$2.stderr.isTTY;
    const silent = command.silent;
    let watcher;
    let configWatcher;
    let resetScreen;
    const configFile = command.config ? await cli.getConfigPath(command.config) : null;
    const runWatchHook = createWatchHooks(command);
    onExit(close);
    process$2.on('uncaughtException', closeWithError);
    if (!process$2.stdin.isTTY) {
        process$2.stdin.on('end', close);
        process$2.stdin.resume();
    }
    async function loadConfigFromFileAndTrack(configFile) {
        let configFileData = null;
        let configFileRevision = 0;
        configWatcher = index.chokidar.watch(configFile).on('change', reloadConfigFile);
        await reloadConfigFile();
        async function reloadConfigFile() {
            try {
                const newConfigFileData = await promises.readFile(configFile, 'utf8');
                if (newConfigFileData === configFileData) {
                    return;
                }
                configFileRevision++;
                const currentConfigFileRevision = configFileRevision;
                if (configFileData) {
                    rollup.stderr(`\nReloading updated config...`);
                }
                configFileData = newConfigFileData;
                const { options, warnings } = await loadConfigFile_js.loadConfigFile(configFile, command, true);
                if (currentConfigFileRevision !== configFileRevision) {
                    return;
                }
                if (watcher) {
                    await watcher.close();
                }
                start(options, warnings);
            }
            catch (error) {
                rollup.handleError(error, true);
            }
        }
    }
    if (configFile) {
        await loadConfigFromFileAndTrack(configFile);
    }
    else {
        const { options, warnings } = await cli.loadConfigFromCommand(command, true);
        await start(options, warnings);
    }
    async function start(configs, warnings) {
        watcher = rollup_js.watch(configs);
        watcher.on('event', event => {
            switch (event.code) {
                case 'ERROR': {
                    warnings.flush();
                    rollup.handleError(event.error, true);
                    runWatchHook('onError');
                    break;
                }
                case 'START': {
                    if (!silent) {
                        if (!resetScreen) {
                            resetScreen = getResetScreen(configs, isTTY);
                        }
                        resetScreen(rollup.underline(`rollup v${rollup.version}`));
                    }
                    runWatchHook('onStart');
                    break;
                }
                case 'BUNDLE_START': {
                    if (!silent) {
                        let input = event.input;
                        if (typeof input !== 'string') {
                            input = Array.isArray(input)
                                ? input.join(', ')
                                : Object.values(input).join(', ');
                        }
                        rollup.stderr(rollup.cyan$1(`bundles ${rollup.bold(input)} → ${rollup.bold(event.output.map(parseAst_js.relativeId).join(', '))}...`));
                    }
                    runWatchHook('onBundleStart');
                    break;
                }
                case 'BUNDLE_END': {
                    warnings.flush();
                    if (!silent)
                        rollup.stderr(rollup.green(`created ${rollup.bold(event.output.map(parseAst_js.relativeId).join(', '))} in ${rollup.bold(cli.prettyMilliseconds(event.duration))}`));
                    runWatchHook('onBundleEnd');
                    if (event.result && event.result.getTimings) {
                        cli.printTimings(event.result.getTimings());
                    }
                    break;
                }
                case 'END': {
                    runWatchHook('onEnd');
                    if (!silent && isTTY) {
                        rollup.stderr(`\n[${dateTime()}] waiting for changes...`);
                    }
                }
            }
            if ('result' in event && event.result) {
                event.result.close().catch(error => rollup.handleError(error, true));
            }
        });
    }
    function close(code) {
        process$2.removeListener('uncaughtException', closeWithError);
        // removing a non-existent listener is a no-op
        process$2.stdin.removeListener('end', close);
        if (configWatcher)
            configWatcher.close();
        Promise.resolve(watcher?.close()).finally(() => {
            process$2.exit(typeof code === 'number' ? code : 0);
        });
        // Tell signal-exit that we are handling this gracefully
        return true;
    }
    // return a promise that never resolves to keep the process running
    return new Promise(() => { });
}
function closeWithError(error) {
    error.name = `Uncaught ${error.name}`;
    rollup.handleError(error);
}

exports.watch = watch;
//# sourceMappingURL=watch-cli.js.map
