FIN INIT
This commit is contained in:
542
node_modules/rollup/dist/shared/watch-cli.js
generated
vendored
Normal file
542
node_modules/rollup/dist/shared/watch-cli.js
generated
vendored
Normal file
@ -0,0 +1,542 @@
|
||||
/*
|
||||
@license
|
||||
Rollup.js v4.41.1
|
||||
Sat, 24 May 2025 06:13:57 GMT - commit 7c469dc4eb8e1cb6def9fdc04581fdfce9975da3
|
||||
|
||||
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('util');
|
||||
require('fs');
|
||||
require('stream');
|
||||
require('os');
|
||||
require('./fsevents-importer.js');
|
||||
require('events');
|
||||
require('node:path');
|
||||
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} = 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(`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);
|
||||
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(`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) {
|
||||
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
|
Reference in New Issue
Block a user