123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563 |
- /*
- @license
- Rollup.js v4.24.2
- Sun, 27 Oct 2024 15:39:37 GMT - commit 32d0e7dae85121ac0850ec28576a10a6302f84a9
- 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('path');
- require('fs');
- require('util');
- require('stream');
- 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
|