@laphilosophia/steady-watch 2.0.1 → 2.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/steady-watch +3 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +5 -3
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +5 -3
- package/dist/index.mjs.map +1 -1
- package/package.json +6 -5
- package/steady-watch.config.json +4 -0
package/bin/steady-watch
CHANGED
package/dist/index.d.mts
CHANGED
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -412,8 +412,9 @@ function loadConfig(configPath) {
|
|
|
412
412
|
".steady-watchrc",
|
|
413
413
|
".steady-watchrc.json",
|
|
414
414
|
"steady-watch.config.json"
|
|
415
|
-
]
|
|
415
|
+
];
|
|
416
416
|
for (const cfgPath of searchPaths) {
|
|
417
|
+
if (!cfgPath) continue;
|
|
417
418
|
try {
|
|
418
419
|
const fullPath = import_path2.default.resolve(cfgPath);
|
|
419
420
|
if (import_fs2.default.existsSync(fullPath)) {
|
|
@@ -465,7 +466,7 @@ function mergeOptions(cliArgs, cliOpts, config) {
|
|
|
465
466
|
};
|
|
466
467
|
}
|
|
467
468
|
function parseCliArgs() {
|
|
468
|
-
import_commander.program.name("steady-watch").description("Intelligent file watcher with debouncing and content hashing.").argument("
|
|
469
|
+
import_commander.program.name("steady-watch").description("Intelligent file watcher with debouncing and content hashing.").argument("[files]", 'Glob pattern to watch (e.g., "src/**/*.ts")').option("-c, --cmd <command>", "Command(s) to execute on change (supports quotes)").option("-d, --delay <ms>", "Debounce delay in milliseconds", "300").option("-v, --verbose", "Show hash calculations", false).option("-q, --quiet", "Minimize output", false).option("--ignore <patterns>", "Additional ignore patterns (comma-separated)").option("--ext <extensions>", "Filter by file extensions (e.g., .ts,.tsx)").option("--config <path>", "Path to config file").option("--kill-timeout <ms>", "Force kill process after timeout", "0").option("--retry <count>", "Retry failed command (0 = disabled)", "0").option("--hash <algorithm>", "Hash algorithm (md5, sha1, sha256)", "md5").option("--no-hash", "Use mtime only instead of content hash (fastest)").option("--clear", "Clear screen on each trigger").option("--json", "Output in JSON format").option("--theme <theme>", "Color theme (default, minimal, none)", "default").version("2.0.0").parse();
|
|
469
470
|
const cliOpts = import_commander.program.opts();
|
|
470
471
|
const cliArgs = { pattern: import_commander.program.args[0] || "" };
|
|
471
472
|
return { args: cliArgs, opts: cliOpts };
|
|
@@ -505,7 +506,8 @@ Received ${signal}, shutting down...`);
|
|
|
505
506
|
process.exit(1);
|
|
506
507
|
});
|
|
507
508
|
}
|
|
508
|
-
|
|
509
|
+
var isMain = require.main === module || process.argv[1]?.includes("index.js") || process.argv[1]?.includes("steady-watch");
|
|
510
|
+
if (isMain) {
|
|
509
511
|
runCli();
|
|
510
512
|
}
|
|
511
513
|
// Annotate the CommonJS export names for ESM import in node:
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/theme.ts","../src/watcher.ts","../src/cli.ts"],"sourcesContent":["export * from './types.js';\nexport * from './theme.js';\nexport { SteadyWatcher, steadyWatch } from './watcher.js';\n\nimport { SteadyWatcher, steadyWatch } from './watcher.js';\nimport { parseCliArgs, loadConfig, mergeOptions } from './cli.js';\n\nexport function runCli(): void {\n const { args, opts } = parseCliArgs();\n const config = loadConfig(opts.config);\n \n if (opts.config && config.cmd) {\n opts.cmd = config.cmd as string;\n }\n\n const options = mergeOptions(args, opts, config);\n \n if (!options.cmd) {\n console.error('Error: Command is required. Use -c option or config file.');\n process.exit(1);\n }\n\n const watcher = new SteadyWatcher(options);\n\n watcher.on('error', (err) => {\n console.error(`Error: ${err.message}`);\n process.exit(1);\n });\n\n watcher.start().catch((err) => {\n console.error(`Failed to start: ${err.message}`);\n process.exit(1);\n });\n\n const shutdown = async (signal: string) => {\n console.log(`\\nReceived ${signal}, shutting down...`);\n await watcher.close();\n process.exit(0);\n };\n\n process.on('SIGINT', () => shutdown('SIGINT'));\n process.on('SIGTERM', () => shutdown('SIGTERM'));\n process.on('uncaughtException', (err) => {\n console.error('Uncaught exception:', err);\n process.exit(1);\n });\n}\n\nif (require.main === module) {\n runCli();\n}\n","import chalk from 'chalk';\nimport { ThemeName } from './types.js';\n\nexport type ChalkStyle = (s: string) => string;\n\nexport interface Theme {\n blue: ChalkStyle;\n green: ChalkStyle;\n yellow: ChalkStyle;\n red: ChalkStyle;\n cyan: ChalkStyle;\n gray: ChalkStyle;\n dim: ChalkStyle;\n bold: ChalkStyle;\n}\n\nexport const themes: Record<ThemeName, Theme> = {\n default: {\n blue: chalk.blue,\n green: chalk.green,\n yellow: chalk.yellow,\n red: chalk.red,\n cyan: chalk.cyan,\n gray: chalk.gray,\n dim: chalk.dim,\n bold: chalk.bold\n },\n minimal: {\n blue: (s: string) => s,\n green: (s: string) => s,\n yellow: (s: string) => s,\n red: (s: string) => s,\n cyan: (s: string) => s,\n gray: (s: string) => s,\n dim: (s: string) => s,\n bold: (s: string) => s\n },\n none: {\n blue: () => '',\n green: () => '',\n yellow: () => '',\n red: () => '',\n cyan: () => '',\n gray: () => '',\n dim: () => '',\n bold: (s: string) => s\n }\n};\n\nexport function getTheme(name: ThemeName): Theme {\n return themes[name] || themes.default;\n}\n","import { ChildProcess, spawn } from 'child_process';\nimport chokidar, { FSWatcher } from 'chokidar';\nimport crypto from 'crypto';\nimport fs from 'fs';\nimport path from 'path';\nimport { EventEmitter } from 'events';\nimport { \n SteadyWatchOptions, \n NormalizedOptions, \n ValidationResult,\n HashAlgorithm,\n ThemeName,\n SteadyWatchEvents\n} from './types.js';\nimport { getTheme, Theme } from './theme.js';\n\nexport class SteadyWatcher extends EventEmitter {\n private options: NormalizedOptions;\n private watcher: FSWatcher | null = null;\n private fileHashes = new Map<string, string>();\n private timeout: NodeJS.Timeout | null = null;\n private isRunning = false;\n private activeProcess: ChildProcess | null = null;\n private killTimer: NodeJS.Timeout | null = null;\n private retryCount = 0;\n private disposed = false;\n private t: Theme;\n\n private static readonly DEFAULT_IGNORE = [/node_modules/, /\\.git/, /dist/, /build/];\n private static readonly VALID_HASH_ALGORITHMS: HashAlgorithm[] = ['md5', 'sha1', 'sha256'];\n private static readonly VALID_THEMES: ThemeName[] = ['default', 'minimal', 'none'];\n\n constructor(options: SteadyWatchOptions) {\n super();\n this.options = this.normalizeOptions(options);\n this.t = getTheme(this.options.theme);\n }\n\n private normalizeOptions(options: SteadyWatchOptions): NormalizedOptions {\n const hash = SteadyWatcher.VALID_HASH_ALGORITHMS.includes(options.hash as HashAlgorithm)\n ? options.hash as HashAlgorithm\n : 'md5';\n \n const theme = SteadyWatcher.VALID_THEMES.includes(options.theme as ThemeName)\n ? options.theme as ThemeName\n : 'default';\n\n const mergedIgnore = [\n ...SteadyWatcher.DEFAULT_IGNORE,\n ...this.normalizeIgnorePatterns(options.ignore || [])\n ];\n\n return {\n pattern: options.pattern,\n cmd: options.cmd,\n delay: Math.max(0, options.delay ?? 300),\n verbose: options.verbose ?? false,\n quiet: options.quiet ?? false,\n ignore: mergedIgnore,\n ext: options.ext || [],\n killTimeout: Math.max(0, options.killTimeout ?? 0),\n retry: Math.max(0, options.retry ?? 0),\n hash,\n mtimeOnly: options.mtimeOnly ?? false,\n clearScreen: options.clearScreen ?? false,\n json: options.json ?? false,\n theme\n };\n }\n\n private normalizeIgnorePatterns(patterns: (string | RegExp)[]): RegExp[] {\n return patterns.map(p => {\n if (p instanceof RegExp) return p;\n try {\n return new RegExp(p);\n } catch {\n return new RegExp(`^${p.replace(/\\*/g, '.*')}$`);\n }\n });\n }\n\n public validate(): ValidationResult {\n const errors: string[] = [];\n\n if (!this.options.pattern) {\n errors.push('Pattern is required');\n }\n\n if (!this.options.cmd) {\n errors.push('Command is required');\n }\n\n if (this.options.delay < 0) {\n errors.push('Delay must be a non-negative number');\n }\n\n if (this.options.killTimeout < 0) {\n errors.push('Kill timeout must be a non-negative number');\n }\n\n if (this.options.retry < 0) {\n errors.push('Retry must be a non-negative number');\n }\n\n return { valid: errors.length === 0, errors };\n }\n\n private getEffectivePattern(): string {\n if (this.options.ext.length === 0) {\n return this.options.pattern;\n }\n\n const extGlob = this.options.ext\n .map(e => e.startsWith('.') ? `*${e}` : `*.${e}`)\n .join(',');\n \n const pattern = this.options.pattern;\n return pattern.includes('{')\n ? pattern.replace(/\\}$/, `,${extGlob}}`)\n : `${pattern.replace(/\\/$/, '')}/{${extGlob}}`;\n }\n\n private getHash(filePath: string): string | null {\n try {\n if (!fs.existsSync(filePath)) return null;\n \n if (this.options.mtimeOnly) {\n const stats = fs.statSync(filePath);\n return `mtime:${stats.mtimeMs}`;\n }\n \n const content = fs.readFileSync(filePath);\n return crypto.createHash(this.options.hash).update(content).digest('hex');\n } catch {\n return null;\n }\n }\n\n private log(...args: unknown[]): void {\n if (!this.options.quiet && !this.disposed) console.log(...args);\n }\n\n private logVerbose(...args: unknown[]): void {\n if (this.options.verbose && !this.options.quiet && !this.disposed) {\n console.log(...args);\n }\n }\n\n private logJson(type: string, data: Record<string, unknown>): void {\n if (this.options.json && !this.disposed) {\n console.log(JSON.stringify({ timestamp: new Date().toISOString(), type, ...data }));\n }\n }\n\n private timestamp(): string {\n return this.t.gray(`[${new Date().toLocaleTimeString()}]`);\n }\n\n private parseCommand(cmdString: string): { cmd: string; args: string[] } {\n const tokens: string[] = [];\n let current = '';\n let inQuote = false;\n let quoteChar = '';\n let escaped = false;\n\n for (let i = 0; i < cmdString.length; i++) {\n const char = cmdString[i];\n const prevChar = i > 0 ? cmdString[i - 1] : '';\n\n if (escaped) {\n current += char;\n escaped = false;\n continue;\n }\n\n if (char === '\\\\' && !inQuote) {\n escaped = true;\n continue;\n }\n\n if ((char === '\"' || char === \"'\") && !inQuote) {\n inQuote = true;\n quoteChar = char;\n } else if (char === quoteChar && inQuote) {\n inQuote = false;\n quoteChar = '';\n } else if (char === ' ' && !inQuote) {\n if (current) {\n tokens.push(current);\n current = '';\n }\n } else {\n current += char;\n }\n }\n\n if (current) {\n tokens.push(current);\n }\n\n return { cmd: tokens[0] || '', args: tokens.slice(1) };\n }\n\n private runCommand(): void {\n if (this.disposed) return;\n\n if (this.isRunning) {\n this.logVerbose(this.t.yellow('⚠️ Previous command still running, skipping...'));\n this.emit('skip', 'previous command still running');\n return;\n }\n\n if (this.options.clearScreen) {\n console.clear();\n }\n\n this.isRunning = true;\n const retryInfo = this.retryCount > 0 ? ` (Retry ${this.retryCount}/${this.options.retry})` : '';\n this.log(`${this.timestamp()} ${this.t.cyan('🚀 Triggering:')} ${this.t.bold(this.options.cmd)}${retryInfo}`);\n this.logJson('trigger', { command: this.options.cmd, retry: this.retryCount });\n this.emit('trigger', this.options.cmd);\n\n const { cmd, args } = this.parseCommand(this.options.cmd);\n const startTime = Date.now();\n\n this.activeProcess = spawn(cmd, args, {\n stdio: 'inherit',\n shell: true,\n env: { ...process.env }\n });\n\n if (this.options.killTimeout > 0) {\n this.killTimer = setTimeout(() => {\n if (this.activeProcess && !this.disposed) {\n this.log(this.t.yellow(`⚠️ Process timeout (${this.options.killTimeout}ms), force killing...`));\n this.activeProcess.kill('SIGKILL');\n }\n }, this.options.killTimeout);\n }\n\n this.activeProcess.on('error', (err) => {\n this.log(this.t.red(`Process error: ${err.message}`));\n this.emit('error', err);\n });\n\n this.activeProcess.on('close', (code, signal) => {\n if (this.disposed) return;\n\n this.isRunning = false;\n if (this.killTimer) {\n clearTimeout(this.killTimer);\n this.killTimer = null;\n }\n this.activeProcess = null;\n const duration = ((Date.now() - startTime) / 1000).toFixed(2);\n\n if (code === 0) {\n this.log(`${this.timestamp()} ${this.t.green('✔ Done')} in ${duration}s`);\n this.logJson('done', { duration: parseFloat(duration) });\n this.emit('done', parseFloat(duration));\n this.retryCount = 0;\n } else {\n const exitMessage = signal ? ` (Signal: ${signal})` : ` (Exit code: ${code})`;\n this.log(`${this.timestamp()} ${this.t.red('✘ Failed')}${exitMessage}`);\n this.logJson('failed', { exitCode: code, signal });\n this.emit('fail', code, signal ?? undefined);\n \n if (this.options.retry > 0 && this.retryCount < this.options.retry) {\n this.retryCount++;\n this.log(this.t.yellow(`🔄 Retrying in 1s... (${this.retryCount}/${this.options.retry})`));\n setTimeout(() => this.runCommand(), 1000);\n return;\n }\n this.retryCount = 0;\n }\n this.log(this.t.dim('─'.repeat(40)));\n });\n }\n\n private handleFileChange(filePath: string): void {\n if (this.disposed) return;\n\n const currentHash = this.getHash(filePath);\n const lastHash = this.fileHashes.get(filePath);\n\n if (currentHash === lastHash) {\n this.logVerbose(this.t.gray(`Skipping ghost change: ${path.basename(filePath)}`));\n this.emit('skip', 'content unchanged', filePath);\n return;\n }\n\n if (currentHash) {\n this.fileHashes.set(filePath, currentHash);\n }\n\n this.emit('change', filePath);\n\n if (this.timeout) clearTimeout(this.timeout);\n this.timeout = setTimeout(() => {\n if (!this.disposed) {\n this.log(`${this.timestamp()} ${this.t.yellow('⚡ Change detected:')} ${path.basename(filePath)}`);\n this.logJson('change', { file: path.basename(filePath) });\n this.runCommand();\n }\n }, this.options.delay);\n }\n\n public async start(): Promise<void> {\n const validation = this.validate();\n if (!validation.valid) {\n const errorMsg = validation.errors.join(', ');\n this.log(this.t.red(`Validation error: ${errorMsg}`));\n this.emit('error', new Error(errorMsg));\n throw new Error(errorMsg);\n }\n\n const effectivePattern = this.getEffectivePattern();\n\n this.log(this.t.bold(`\\n🔭 Steady Watch Initialized`));\n this.log(` ${this.t.dim('Pattern:')} ${effectivePattern}`);\n this.log(` ${this.t.dim('Command:')} ${this.options.cmd}`);\n this.log(` ${this.t.dim('Delay:')} ${this.options.delay}ms`);\n if (this.options.quiet) this.log(` ${this.t.dim('Mode:')} quiet`);\n if (this.options.killTimeout > 0) this.log(` ${this.t.dim('Kill:')} ${this.options.killTimeout}ms`);\n if (this.options.retry > 0) this.log(` ${this.t.dim('Retry:')} ${this.options.retry}x`);\n if (this.options.mtimeOnly) this.log(` ${this.t.dim('Hash:')} mtime-only (fastest)`);\n else this.log(` ${this.t.dim('Hash:')} ${this.options.hash}`);\n this.log('');\n\n this.watcher = chokidar.watch(effectivePattern, {\n ignored: this.options.ignore,\n ignoreInitial: false,\n awaitWriteFinish: {\n stabilityThreshold: 100,\n pollInterval: 100\n }\n });\n\n this.watcher.on('ready', () => {\n this.log(this.t.green('👁️ Watcher ready. Monitoring for changes...'));\n this.logVerbose(this.t.dim(` Tracking ${this.fileHashes.size} file(s)`));\n this.emit('ready');\n });\n\n this.watcher.on('error', (error) => {\n this.log(this.t.red(`Watcher error: ${error.message}`));\n this.emit('error', error);\n });\n\n this.watcher.on('add', (filePath) => {\n if (this.disposed) return;\n const hash = this.getHash(filePath);\n if (hash) this.fileHashes.set(filePath, hash);\n this.logVerbose(this.t.dim(`Indexed: ${path.basename(filePath)}`));\n });\n\n this.watcher.on('change', (filePath) => this.handleFileChange(filePath));\n\n this.watcher.on('unlink', (filePath) => {\n if (this.disposed) return;\n this.fileHashes.delete(filePath);\n this.logVerbose(this.t.dim(`Removed: ${path.basename(filePath)}`));\n });\n }\n\n public async close(): Promise<void> {\n if (this.disposed) return;\n this.disposed = true;\n\n this.log(this.t.yellow('\\n🛑 Shutting down...'));\n this.logJson('shutdown', {});\n\n if (this.timeout) {\n clearTimeout(this.timeout);\n this.timeout = null;\n }\n\n if (this.killTimer) {\n clearTimeout(this.killTimer);\n this.killTimer = null;\n }\n\n if (this.activeProcess) {\n this.activeProcess.kill('SIGTERM');\n this.activeProcess = null;\n }\n\n if (this.watcher) {\n await this.watcher.close();\n this.watcher = null;\n }\n\n this.removeAllListeners();\n }\n\n public getTrackedFiles(): string[] {\n return Array.from(this.fileHashes.keys());\n }\n\n public isCurrentlyRunning(): boolean {\n return this.isRunning;\n }\n\n public isDisposed(): boolean {\n return this.disposed;\n }\n}\n\nexport function steadyWatch(options: SteadyWatchOptions): SteadyWatcher {\n return new SteadyWatcher(options);\n}\n","import fs from 'fs';\nimport path from 'path';\nimport { program } from 'commander';\nimport { CliOptions, CliArgs, SteadyWatchOptions, HashAlgorithm, ThemeName } from './types.js';\n\nexport function loadConfig(configPath?: string): Record<string, unknown> {\n const searchPaths = [\n configPath,\n '.steady-watchrc',\n '.steady-watchrc.json',\n 'steady-watch.config.json'\n ].filter(Boolean) as string[];\n\n for (const cfgPath of searchPaths) {\n try {\n const fullPath = path.resolve(cfgPath);\n if (fs.existsSync(fullPath)) {\n return JSON.parse(fs.readFileSync(fullPath, 'utf-8'));\n }\n } catch {\n continue;\n }\n }\n\n return {};\n}\n\nexport function parseIgnorePatterns(patternString?: string): (string | RegExp)[] {\n if (!patternString) return [];\n return patternString.split(',').map(p => p.trim()).filter(Boolean);\n}\n\nexport function parseExtFilter(extString?: string): string[] {\n if (!extString) return [];\n return extString.split(',').map(e => e.trim()).filter(Boolean);\n}\n\nexport function parseBoolean(value: unknown): boolean {\n if (typeof value === 'boolean') return value;\n if (typeof value === 'string') return value.toLowerCase() === 'true';\n return false;\n}\n\nexport function parseNumber(value: unknown, defaultValue: number): number {\n if (typeof value === 'number') return value;\n if (typeof value === 'string') {\n const parsed = parseInt(value, 10);\n return isNaN(parsed) ? defaultValue : parsed;\n }\n return defaultValue;\n}\n\nexport function mergeOptions(\n cliArgs: CliArgs,\n cliOpts: CliOptions,\n config: Record<string, unknown>\n): SteadyWatchOptions {\n return {\n pattern: cliArgs.pattern || (config.pattern as string) || '',\n cmd: cliOpts.cmd || (config.cmd as string) || '', \n delay: parseNumber(cliOpts.delay ?? config.delay, 300),\n verbose: parseBoolean(cliOpts.verbose ?? config.verbose),\n quiet: parseBoolean(cliOpts.quiet ?? config.quiet),\n ignore: [...parseIgnorePatterns(cliOpts.ignore), ...(config.ignore as string[] || [])],\n ext: cliOpts.ext ? parseExtFilter(cliOpts.ext) : (config.ext as string[] || []),\n killTimeout: parseNumber(cliOpts.killTimeout ?? config.killTimeout, 0),\n retry: parseNumber(cliOpts.retry ?? config.retry, 0),\n hash: (cliOpts.hash as HashAlgorithm) || (config.hash as HashAlgorithm) || 'md5',\n mtimeOnly: cliOpts.noHash ?? (config.mtimeOnly as boolean) ?? false,\n clearScreen: parseBoolean(cliOpts.clear ?? config.clearScreen),\n json: parseBoolean(cliOpts.json ?? config.json),\n theme: (cliOpts.theme as ThemeName) || (config.theme as ThemeName) || 'default'\n };\n}\n\nexport function parseCliArgs(): { args: CliArgs; opts: CliOptions } {\n program\n .name('steady-watch')\n .description('Intelligent file watcher with debouncing and content hashing.')\n .argument('<files>', 'Glob pattern to watch (e.g., \"src/**/*.ts\")')\n .requiredOption('-c, --cmd <command>', 'Command(s) to execute on change (supports quotes)')\n .option('-d, --delay <ms>', 'Debounce delay in milliseconds', '300')\n .option('-v, --verbose', 'Show hash calculations', false)\n .option('-q, --quiet', 'Minimize output', false)\n .option('--ignore <patterns>', 'Additional ignore patterns (comma-separated)')\n .option('--ext <extensions>', 'Filter by file extensions (e.g., .ts,.tsx)')\n .option('--config <path>', 'Path to config file')\n .option('--kill-timeout <ms>', 'Force kill process after timeout', '0')\n .option('--retry <count>', 'Retry failed command (0 = disabled)', '0')\n .option('--hash <algorithm>', 'Hash algorithm (md5, sha1, sha256)', 'md5')\n .option('--no-hash', 'Use mtime only instead of content hash (fastest)')\n .option('--clear', 'Clear screen on each trigger')\n .option('--json', 'Output in JSON format')\n .option('--theme <theme>', 'Color theme (default, minimal, none)', 'default')\n .version('2.0.0')\n .parse();\n\n const cliOpts = program.opts() as CliOptions;\n const cliArgs: CliArgs = { pattern: program.args[0] || '' };\n\n return { args: cliArgs, opts: cliOpts };\n}\n"],"mappings":"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","names":["chalk","fs","crypto","path","chokidar","import_fs","import_path","path","fs"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/theme.ts","../src/watcher.ts","../src/cli.ts"],"sourcesContent":["export * from './types.js';\nexport * from './theme.js';\nexport { SteadyWatcher, steadyWatch } from './watcher.js';\n\nimport { SteadyWatcher, steadyWatch } from './watcher.js';\nimport { parseCliArgs, loadConfig, mergeOptions } from './cli.js';\n\nexport function runCli(): void {\n const { args, opts } = parseCliArgs();\n const config = loadConfig(opts.config);\n \n if (opts.config && config.cmd) {\n opts.cmd = config.cmd as string;\n }\n\n const options = mergeOptions(args, opts, config);\n \n if (!options.cmd) {\n console.error('Error: Command is required. Use -c option or config file.');\n process.exit(1);\n }\n\n const watcher = new SteadyWatcher(options);\n\n watcher.on('error', (err) => {\n console.error(`Error: ${err.message}`);\n process.exit(1);\n });\n\n watcher.start().catch((err) => {\n console.error(`Failed to start: ${err.message}`);\n process.exit(1);\n });\n\n const shutdown = async (signal: string) => {\n console.log(`\\nReceived ${signal}, shutting down...`);\n await watcher.close();\n process.exit(0);\n };\n\n process.on('SIGINT', () => shutdown('SIGINT'));\n process.on('SIGTERM', () => shutdown('SIGTERM'));\n process.on('uncaughtException', (err) => {\n console.error('Uncaught exception:', err);\n process.exit(1);\n });\n}\n\nconst isMain = require.main === module || process.argv[1]?.includes('index.js') || process.argv[1]?.includes('steady-watch');\n\nif (isMain) {\n runCli();\n}\n","import chalk from 'chalk';\nimport { ThemeName } from './types.js';\n\nexport type ChalkStyle = (s: string) => string;\n\nexport interface Theme {\n blue: ChalkStyle;\n green: ChalkStyle;\n yellow: ChalkStyle;\n red: ChalkStyle;\n cyan: ChalkStyle;\n gray: ChalkStyle;\n dim: ChalkStyle;\n bold: ChalkStyle;\n}\n\nexport const themes: Record<ThemeName, Theme> = {\n default: {\n blue: chalk.blue,\n green: chalk.green,\n yellow: chalk.yellow,\n red: chalk.red,\n cyan: chalk.cyan,\n gray: chalk.gray,\n dim: chalk.dim,\n bold: chalk.bold\n },\n minimal: {\n blue: (s: string) => s,\n green: (s: string) => s,\n yellow: (s: string) => s,\n red: (s: string) => s,\n cyan: (s: string) => s,\n gray: (s: string) => s,\n dim: (s: string) => s,\n bold: (s: string) => s\n },\n none: {\n blue: () => '',\n green: () => '',\n yellow: () => '',\n red: () => '',\n cyan: () => '',\n gray: () => '',\n dim: () => '',\n bold: (s: string) => s\n }\n};\n\nexport function getTheme(name: ThemeName): Theme {\n return themes[name] || themes.default;\n}\n","import { ChildProcess, spawn } from 'child_process';\nimport chokidar, { FSWatcher } from 'chokidar';\nimport crypto from 'crypto';\nimport fs from 'fs';\nimport path from 'path';\nimport { EventEmitter } from 'events';\nimport { \n SteadyWatchOptions, \n NormalizedOptions, \n ValidationResult,\n HashAlgorithm,\n ThemeName,\n SteadyWatchEvents\n} from './types.js';\nimport { getTheme, Theme } from './theme.js';\n\nexport class SteadyWatcher extends EventEmitter {\n private options: NormalizedOptions;\n private watcher: FSWatcher | null = null;\n private fileHashes = new Map<string, string>();\n private timeout: NodeJS.Timeout | null = null;\n private isRunning = false;\n private activeProcess: ChildProcess | null = null;\n private killTimer: NodeJS.Timeout | null = null;\n private retryCount = 0;\n private disposed = false;\n private t: Theme;\n\n private static readonly DEFAULT_IGNORE = [/node_modules/, /\\.git/, /dist/, /build/];\n private static readonly VALID_HASH_ALGORITHMS: HashAlgorithm[] = ['md5', 'sha1', 'sha256'];\n private static readonly VALID_THEMES: ThemeName[] = ['default', 'minimal', 'none'];\n\n constructor(options: SteadyWatchOptions) {\n super();\n this.options = this.normalizeOptions(options);\n this.t = getTheme(this.options.theme);\n }\n\n private normalizeOptions(options: SteadyWatchOptions): NormalizedOptions {\n const hash = SteadyWatcher.VALID_HASH_ALGORITHMS.includes(options.hash as HashAlgorithm)\n ? options.hash as HashAlgorithm\n : 'md5';\n \n const theme = SteadyWatcher.VALID_THEMES.includes(options.theme as ThemeName)\n ? options.theme as ThemeName\n : 'default';\n\n const mergedIgnore = [\n ...SteadyWatcher.DEFAULT_IGNORE,\n ...this.normalizeIgnorePatterns(options.ignore || [])\n ];\n\n return {\n pattern: options.pattern,\n cmd: options.cmd,\n delay: Math.max(0, options.delay ?? 300),\n verbose: options.verbose ?? false,\n quiet: options.quiet ?? false,\n ignore: mergedIgnore,\n ext: options.ext || [],\n killTimeout: Math.max(0, options.killTimeout ?? 0),\n retry: Math.max(0, options.retry ?? 0),\n hash,\n mtimeOnly: options.mtimeOnly ?? false,\n clearScreen: options.clearScreen ?? false,\n json: options.json ?? false,\n theme\n };\n }\n\n private normalizeIgnorePatterns(patterns: (string | RegExp)[]): RegExp[] {\n return patterns.map(p => {\n if (p instanceof RegExp) return p;\n try {\n return new RegExp(p);\n } catch {\n return new RegExp(`^${p.replace(/\\*/g, '.*')}$`);\n }\n });\n }\n\n public validate(): ValidationResult {\n const errors: string[] = [];\n\n if (!this.options.pattern) {\n errors.push('Pattern is required');\n }\n\n if (!this.options.cmd) {\n errors.push('Command is required');\n }\n\n if (this.options.delay < 0) {\n errors.push('Delay must be a non-negative number');\n }\n\n if (this.options.killTimeout < 0) {\n errors.push('Kill timeout must be a non-negative number');\n }\n\n if (this.options.retry < 0) {\n errors.push('Retry must be a non-negative number');\n }\n\n return { valid: errors.length === 0, errors };\n }\n\n private getEffectivePattern(): string {\n if (this.options.ext.length === 0) {\n return this.options.pattern;\n }\n\n const extGlob = this.options.ext\n .map(e => e.startsWith('.') ? `*${e}` : `*.${e}`)\n .join(',');\n \n const pattern = this.options.pattern;\n return pattern.includes('{')\n ? pattern.replace(/\\}$/, `,${extGlob}}`)\n : `${pattern.replace(/\\/$/, '')}/{${extGlob}}`;\n }\n\n private getHash(filePath: string): string | null {\n try {\n if (!fs.existsSync(filePath)) return null;\n \n if (this.options.mtimeOnly) {\n const stats = fs.statSync(filePath);\n return `mtime:${stats.mtimeMs}`;\n }\n \n const content = fs.readFileSync(filePath);\n return crypto.createHash(this.options.hash).update(content).digest('hex');\n } catch {\n return null;\n }\n }\n\n private log(...args: unknown[]): void {\n if (!this.options.quiet && !this.disposed) console.log(...args);\n }\n\n private logVerbose(...args: unknown[]): void {\n if (this.options.verbose && !this.options.quiet && !this.disposed) {\n console.log(...args);\n }\n }\n\n private logJson(type: string, data: Record<string, unknown>): void {\n if (this.options.json && !this.disposed) {\n console.log(JSON.stringify({ timestamp: new Date().toISOString(), type, ...data }));\n }\n }\n\n private timestamp(): string {\n return this.t.gray(`[${new Date().toLocaleTimeString()}]`);\n }\n\n private parseCommand(cmdString: string): { cmd: string; args: string[] } {\n const tokens: string[] = [];\n let current = '';\n let inQuote = false;\n let quoteChar = '';\n let escaped = false;\n\n for (let i = 0; i < cmdString.length; i++) {\n const char = cmdString[i];\n const prevChar = i > 0 ? cmdString[i - 1] : '';\n\n if (escaped) {\n current += char;\n escaped = false;\n continue;\n }\n\n if (char === '\\\\' && !inQuote) {\n escaped = true;\n continue;\n }\n\n if ((char === '\"' || char === \"'\") && !inQuote) {\n inQuote = true;\n quoteChar = char;\n } else if (char === quoteChar && inQuote) {\n inQuote = false;\n quoteChar = '';\n } else if (char === ' ' && !inQuote) {\n if (current) {\n tokens.push(current);\n current = '';\n }\n } else {\n current += char;\n }\n }\n\n if (current) {\n tokens.push(current);\n }\n\n return { cmd: tokens[0] || '', args: tokens.slice(1) };\n }\n\n private runCommand(): void {\n if (this.disposed) return;\n\n if (this.isRunning) {\n this.logVerbose(this.t.yellow('⚠️ Previous command still running, skipping...'));\n this.emit('skip', 'previous command still running');\n return;\n }\n\n if (this.options.clearScreen) {\n console.clear();\n }\n\n this.isRunning = true;\n const retryInfo = this.retryCount > 0 ? ` (Retry ${this.retryCount}/${this.options.retry})` : '';\n this.log(`${this.timestamp()} ${this.t.cyan('🚀 Triggering:')} ${this.t.bold(this.options.cmd)}${retryInfo}`);\n this.logJson('trigger', { command: this.options.cmd, retry: this.retryCount });\n this.emit('trigger', this.options.cmd);\n\n const { cmd, args } = this.parseCommand(this.options.cmd);\n const startTime = Date.now();\n\n this.activeProcess = spawn(cmd, args, {\n stdio: 'inherit',\n shell: true,\n env: { ...process.env }\n });\n\n if (this.options.killTimeout > 0) {\n this.killTimer = setTimeout(() => {\n if (this.activeProcess && !this.disposed) {\n this.log(this.t.yellow(`⚠️ Process timeout (${this.options.killTimeout}ms), force killing...`));\n this.activeProcess.kill('SIGKILL');\n }\n }, this.options.killTimeout);\n }\n\n this.activeProcess.on('error', (err) => {\n this.log(this.t.red(`Process error: ${err.message}`));\n this.emit('error', err);\n });\n\n this.activeProcess.on('close', (code, signal) => {\n if (this.disposed) return;\n\n this.isRunning = false;\n if (this.killTimer) {\n clearTimeout(this.killTimer);\n this.killTimer = null;\n }\n this.activeProcess = null;\n const duration = ((Date.now() - startTime) / 1000).toFixed(2);\n\n if (code === 0) {\n this.log(`${this.timestamp()} ${this.t.green('✔ Done')} in ${duration}s`);\n this.logJson('done', { duration: parseFloat(duration) });\n this.emit('done', parseFloat(duration));\n this.retryCount = 0;\n } else {\n const exitMessage = signal ? ` (Signal: ${signal})` : ` (Exit code: ${code})`;\n this.log(`${this.timestamp()} ${this.t.red('✘ Failed')}${exitMessage}`);\n this.logJson('failed', { exitCode: code, signal });\n this.emit('fail', code, signal ?? undefined);\n \n if (this.options.retry > 0 && this.retryCount < this.options.retry) {\n this.retryCount++;\n this.log(this.t.yellow(`🔄 Retrying in 1s... (${this.retryCount}/${this.options.retry})`));\n setTimeout(() => this.runCommand(), 1000);\n return;\n }\n this.retryCount = 0;\n }\n this.log(this.t.dim('─'.repeat(40)));\n });\n }\n\n private handleFileChange(filePath: string): void {\n if (this.disposed) return;\n\n const currentHash = this.getHash(filePath);\n const lastHash = this.fileHashes.get(filePath);\n\n if (currentHash === lastHash) {\n this.logVerbose(this.t.gray(`Skipping ghost change: ${path.basename(filePath)}`));\n this.emit('skip', 'content unchanged', filePath);\n return;\n }\n\n if (currentHash) {\n this.fileHashes.set(filePath, currentHash);\n }\n\n this.emit('change', filePath);\n\n if (this.timeout) clearTimeout(this.timeout);\n this.timeout = setTimeout(() => {\n if (!this.disposed) {\n this.log(`${this.timestamp()} ${this.t.yellow('⚡ Change detected:')} ${path.basename(filePath)}`);\n this.logJson('change', { file: path.basename(filePath) });\n this.runCommand();\n }\n }, this.options.delay);\n }\n\n public async start(): Promise<void> {\n const validation = this.validate();\n if (!validation.valid) {\n const errorMsg = validation.errors.join(', ');\n this.log(this.t.red(`Validation error: ${errorMsg}`));\n this.emit('error', new Error(errorMsg));\n throw new Error(errorMsg);\n }\n\n const effectivePattern = this.getEffectivePattern();\n\n this.log(this.t.bold(`\\n🔭 Steady Watch Initialized`));\n this.log(` ${this.t.dim('Pattern:')} ${effectivePattern}`);\n this.log(` ${this.t.dim('Command:')} ${this.options.cmd}`);\n this.log(` ${this.t.dim('Delay:')} ${this.options.delay}ms`);\n if (this.options.quiet) this.log(` ${this.t.dim('Mode:')} quiet`);\n if (this.options.killTimeout > 0) this.log(` ${this.t.dim('Kill:')} ${this.options.killTimeout}ms`);\n if (this.options.retry > 0) this.log(` ${this.t.dim('Retry:')} ${this.options.retry}x`);\n if (this.options.mtimeOnly) this.log(` ${this.t.dim('Hash:')} mtime-only (fastest)`);\n else this.log(` ${this.t.dim('Hash:')} ${this.options.hash}`);\n this.log('');\n\n this.watcher = chokidar.watch(effectivePattern, {\n ignored: this.options.ignore,\n ignoreInitial: false,\n awaitWriteFinish: {\n stabilityThreshold: 100,\n pollInterval: 100\n }\n });\n\n this.watcher.on('ready', () => {\n this.log(this.t.green('👁️ Watcher ready. Monitoring for changes...'));\n this.logVerbose(this.t.dim(` Tracking ${this.fileHashes.size} file(s)`));\n this.emit('ready');\n });\n\n this.watcher.on('error', (error) => {\n this.log(this.t.red(`Watcher error: ${error.message}`));\n this.emit('error', error);\n });\n\n this.watcher.on('add', (filePath) => {\n if (this.disposed) return;\n const hash = this.getHash(filePath);\n if (hash) this.fileHashes.set(filePath, hash);\n this.logVerbose(this.t.dim(`Indexed: ${path.basename(filePath)}`));\n });\n\n this.watcher.on('change', (filePath) => this.handleFileChange(filePath));\n\n this.watcher.on('unlink', (filePath) => {\n if (this.disposed) return;\n this.fileHashes.delete(filePath);\n this.logVerbose(this.t.dim(`Removed: ${path.basename(filePath)}`));\n });\n }\n\n public async close(): Promise<void> {\n if (this.disposed) return;\n this.disposed = true;\n\n this.log(this.t.yellow('\\n🛑 Shutting down...'));\n this.logJson('shutdown', {});\n\n if (this.timeout) {\n clearTimeout(this.timeout);\n this.timeout = null;\n }\n\n if (this.killTimer) {\n clearTimeout(this.killTimer);\n this.killTimer = null;\n }\n\n if (this.activeProcess) {\n this.activeProcess.kill('SIGTERM');\n this.activeProcess = null;\n }\n\n if (this.watcher) {\n await this.watcher.close();\n this.watcher = null;\n }\n\n this.removeAllListeners();\n }\n\n public getTrackedFiles(): string[] {\n return Array.from(this.fileHashes.keys());\n }\n\n public isCurrentlyRunning(): boolean {\n return this.isRunning;\n }\n\n public isDisposed(): boolean {\n return this.disposed;\n }\n}\n\nexport function steadyWatch(options: SteadyWatchOptions): SteadyWatcher {\n return new SteadyWatcher(options);\n}\n","import fs from 'fs';\nimport path from 'path';\nimport { program } from 'commander';\nimport { CliOptions, CliArgs, SteadyWatchOptions, HashAlgorithm, ThemeName } from './types.js';\n\nexport function loadConfig(configPath?: string): Record<string, unknown> {\n const searchPaths = [\n configPath,\n '.steady-watchrc',\n '.steady-watchrc.json',\n 'steady-watch.config.json'\n ];\n\n for (const cfgPath of searchPaths) {\n if (!cfgPath) continue;\n try {\n const fullPath = path.resolve(cfgPath);\n if (fs.existsSync(fullPath)) {\n return JSON.parse(fs.readFileSync(fullPath, 'utf-8'));\n }\n } catch {\n continue;\n }\n }\n\n return {};\n}\n\nexport function parseIgnorePatterns(patternString?: string): (string | RegExp)[] {\n if (!patternString) return [];\n return patternString.split(',').map(p => p.trim()).filter(Boolean);\n}\n\nexport function parseExtFilter(extString?: string): string[] {\n if (!extString) return [];\n return extString.split(',').map(e => e.trim()).filter(Boolean);\n}\n\nexport function parseBoolean(value: unknown): boolean {\n if (typeof value === 'boolean') return value;\n if (typeof value === 'string') return value.toLowerCase() === 'true';\n return false;\n}\n\nexport function parseNumber(value: unknown, defaultValue: number): number {\n if (typeof value === 'number') return value;\n if (typeof value === 'string') {\n const parsed = parseInt(value, 10);\n return isNaN(parsed) ? defaultValue : parsed;\n }\n return defaultValue;\n}\n\nexport function mergeOptions(\n cliArgs: CliArgs,\n cliOpts: CliOptions,\n config: Record<string, unknown>\n): SteadyWatchOptions {\n return {\n pattern: cliArgs.pattern || (config.pattern as string) || '',\n cmd: cliOpts.cmd || (config.cmd as string) || '', \n delay: parseNumber(cliOpts.delay ?? config.delay, 300),\n verbose: parseBoolean(cliOpts.verbose ?? config.verbose),\n quiet: parseBoolean(cliOpts.quiet ?? config.quiet),\n ignore: [...parseIgnorePatterns(cliOpts.ignore), ...(config.ignore as string[] || [])],\n ext: cliOpts.ext ? parseExtFilter(cliOpts.ext) : (config.ext as string[] || []),\n killTimeout: parseNumber(cliOpts.killTimeout ?? config.killTimeout, 0),\n retry: parseNumber(cliOpts.retry ?? config.retry, 0),\n hash: (cliOpts.hash as HashAlgorithm) || (config.hash as HashAlgorithm) || 'md5',\n mtimeOnly: cliOpts.noHash ?? (config.mtimeOnly as boolean) ?? false,\n clearScreen: parseBoolean(cliOpts.clear ?? config.clearScreen),\n json: parseBoolean(cliOpts.json ?? config.json),\n theme: (cliOpts.theme as ThemeName) || (config.theme as ThemeName) || 'default'\n };\n}\n\nexport function parseCliArgs(): { args: CliArgs; opts: CliOptions } {\n program\n .name('steady-watch')\n .description('Intelligent file watcher with debouncing and content hashing.')\n .argument('[files]', 'Glob pattern to watch (e.g., \"src/**/*.ts\")')\n .option('-c, --cmd <command>', 'Command(s) to execute on change (supports quotes)')\n .option('-d, --delay <ms>', 'Debounce delay in milliseconds', '300')\n .option('-v, --verbose', 'Show hash calculations', false)\n .option('-q, --quiet', 'Minimize output', false)\n .option('--ignore <patterns>', 'Additional ignore patterns (comma-separated)')\n .option('--ext <extensions>', 'Filter by file extensions (e.g., .ts,.tsx)')\n .option('--config <path>', 'Path to config file')\n .option('--kill-timeout <ms>', 'Force kill process after timeout', '0')\n .option('--retry <count>', 'Retry failed command (0 = disabled)', '0')\n .option('--hash <algorithm>', 'Hash algorithm (md5, sha1, sha256)', 'md5')\n .option('--no-hash', 'Use mtime only instead of content hash (fastest)')\n .option('--clear', 'Clear screen on each trigger')\n .option('--json', 'Output in JSON format')\n .option('--theme <theme>', 'Color theme (default, minimal, none)', 'default')\n .version('2.0.0')\n .parse();\n\n const cliOpts = program.opts() as CliOptions;\n const cliArgs: CliArgs = { pattern: program.args[0] || '' };\n\n return { args: cliArgs, opts: cliOpts };\n}\n"],"mappings":"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","names":["chalk","fs","crypto","path","chokidar","import_fs","import_path","path","fs"]}
|
package/dist/index.mjs
CHANGED
|
@@ -379,8 +379,9 @@ function loadConfig(configPath) {
|
|
|
379
379
|
".steady-watchrc",
|
|
380
380
|
".steady-watchrc.json",
|
|
381
381
|
"steady-watch.config.json"
|
|
382
|
-
]
|
|
382
|
+
];
|
|
383
383
|
for (const cfgPath of searchPaths) {
|
|
384
|
+
if (!cfgPath) continue;
|
|
384
385
|
try {
|
|
385
386
|
const fullPath = path2.resolve(cfgPath);
|
|
386
387
|
if (fs2.existsSync(fullPath)) {
|
|
@@ -432,7 +433,7 @@ function mergeOptions(cliArgs, cliOpts, config) {
|
|
|
432
433
|
};
|
|
433
434
|
}
|
|
434
435
|
function parseCliArgs() {
|
|
435
|
-
program.name("steady-watch").description("Intelligent file watcher with debouncing and content hashing.").argument("
|
|
436
|
+
program.name("steady-watch").description("Intelligent file watcher with debouncing and content hashing.").argument("[files]", 'Glob pattern to watch (e.g., "src/**/*.ts")').option("-c, --cmd <command>", "Command(s) to execute on change (supports quotes)").option("-d, --delay <ms>", "Debounce delay in milliseconds", "300").option("-v, --verbose", "Show hash calculations", false).option("-q, --quiet", "Minimize output", false).option("--ignore <patterns>", "Additional ignore patterns (comma-separated)").option("--ext <extensions>", "Filter by file extensions (e.g., .ts,.tsx)").option("--config <path>", "Path to config file").option("--kill-timeout <ms>", "Force kill process after timeout", "0").option("--retry <count>", "Retry failed command (0 = disabled)", "0").option("--hash <algorithm>", "Hash algorithm (md5, sha1, sha256)", "md5").option("--no-hash", "Use mtime only instead of content hash (fastest)").option("--clear", "Clear screen on each trigger").option("--json", "Output in JSON format").option("--theme <theme>", "Color theme (default, minimal, none)", "default").version("2.0.0").parse();
|
|
436
437
|
const cliOpts = program.opts();
|
|
437
438
|
const cliArgs = { pattern: program.args[0] || "" };
|
|
438
439
|
return { args: cliArgs, opts: cliOpts };
|
|
@@ -472,7 +473,8 @@ Received ${signal}, shutting down...`);
|
|
|
472
473
|
process.exit(1);
|
|
473
474
|
});
|
|
474
475
|
}
|
|
475
|
-
|
|
476
|
+
var isMain = __require.main === module || process.argv[1]?.includes("index.js") || process.argv[1]?.includes("steady-watch");
|
|
477
|
+
if (isMain) {
|
|
476
478
|
runCli();
|
|
477
479
|
}
|
|
478
480
|
export {
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/theme.ts","../src/watcher.ts","../src/cli.ts","../src/index.ts"],"sourcesContent":["import chalk from 'chalk';\nimport { ThemeName } from './types.js';\n\nexport type ChalkStyle = (s: string) => string;\n\nexport interface Theme {\n blue: ChalkStyle;\n green: ChalkStyle;\n yellow: ChalkStyle;\n red: ChalkStyle;\n cyan: ChalkStyle;\n gray: ChalkStyle;\n dim: ChalkStyle;\n bold: ChalkStyle;\n}\n\nexport const themes: Record<ThemeName, Theme> = {\n default: {\n blue: chalk.blue,\n green: chalk.green,\n yellow: chalk.yellow,\n red: chalk.red,\n cyan: chalk.cyan,\n gray: chalk.gray,\n dim: chalk.dim,\n bold: chalk.bold\n },\n minimal: {\n blue: (s: string) => s,\n green: (s: string) => s,\n yellow: (s: string) => s,\n red: (s: string) => s,\n cyan: (s: string) => s,\n gray: (s: string) => s,\n dim: (s: string) => s,\n bold: (s: string) => s\n },\n none: {\n blue: () => '',\n green: () => '',\n yellow: () => '',\n red: () => '',\n cyan: () => '',\n gray: () => '',\n dim: () => '',\n bold: (s: string) => s\n }\n};\n\nexport function getTheme(name: ThemeName): Theme {\n return themes[name] || themes.default;\n}\n","import { ChildProcess, spawn } from 'child_process';\nimport chokidar, { FSWatcher } from 'chokidar';\nimport crypto from 'crypto';\nimport fs from 'fs';\nimport path from 'path';\nimport { EventEmitter } from 'events';\nimport { \n SteadyWatchOptions, \n NormalizedOptions, \n ValidationResult,\n HashAlgorithm,\n ThemeName,\n SteadyWatchEvents\n} from './types.js';\nimport { getTheme, Theme } from './theme.js';\n\nexport class SteadyWatcher extends EventEmitter {\n private options: NormalizedOptions;\n private watcher: FSWatcher | null = null;\n private fileHashes = new Map<string, string>();\n private timeout: NodeJS.Timeout | null = null;\n private isRunning = false;\n private activeProcess: ChildProcess | null = null;\n private killTimer: NodeJS.Timeout | null = null;\n private retryCount = 0;\n private disposed = false;\n private t: Theme;\n\n private static readonly DEFAULT_IGNORE = [/node_modules/, /\\.git/, /dist/, /build/];\n private static readonly VALID_HASH_ALGORITHMS: HashAlgorithm[] = ['md5', 'sha1', 'sha256'];\n private static readonly VALID_THEMES: ThemeName[] = ['default', 'minimal', 'none'];\n\n constructor(options: SteadyWatchOptions) {\n super();\n this.options = this.normalizeOptions(options);\n this.t = getTheme(this.options.theme);\n }\n\n private normalizeOptions(options: SteadyWatchOptions): NormalizedOptions {\n const hash = SteadyWatcher.VALID_HASH_ALGORITHMS.includes(options.hash as HashAlgorithm)\n ? options.hash as HashAlgorithm\n : 'md5';\n \n const theme = SteadyWatcher.VALID_THEMES.includes(options.theme as ThemeName)\n ? options.theme as ThemeName\n : 'default';\n\n const mergedIgnore = [\n ...SteadyWatcher.DEFAULT_IGNORE,\n ...this.normalizeIgnorePatterns(options.ignore || [])\n ];\n\n return {\n pattern: options.pattern,\n cmd: options.cmd,\n delay: Math.max(0, options.delay ?? 300),\n verbose: options.verbose ?? false,\n quiet: options.quiet ?? false,\n ignore: mergedIgnore,\n ext: options.ext || [],\n killTimeout: Math.max(0, options.killTimeout ?? 0),\n retry: Math.max(0, options.retry ?? 0),\n hash,\n mtimeOnly: options.mtimeOnly ?? false,\n clearScreen: options.clearScreen ?? false,\n json: options.json ?? false,\n theme\n };\n }\n\n private normalizeIgnorePatterns(patterns: (string | RegExp)[]): RegExp[] {\n return patterns.map(p => {\n if (p instanceof RegExp) return p;\n try {\n return new RegExp(p);\n } catch {\n return new RegExp(`^${p.replace(/\\*/g, '.*')}$`);\n }\n });\n }\n\n public validate(): ValidationResult {\n const errors: string[] = [];\n\n if (!this.options.pattern) {\n errors.push('Pattern is required');\n }\n\n if (!this.options.cmd) {\n errors.push('Command is required');\n }\n\n if (this.options.delay < 0) {\n errors.push('Delay must be a non-negative number');\n }\n\n if (this.options.killTimeout < 0) {\n errors.push('Kill timeout must be a non-negative number');\n }\n\n if (this.options.retry < 0) {\n errors.push('Retry must be a non-negative number');\n }\n\n return { valid: errors.length === 0, errors };\n }\n\n private getEffectivePattern(): string {\n if (this.options.ext.length === 0) {\n return this.options.pattern;\n }\n\n const extGlob = this.options.ext\n .map(e => e.startsWith('.') ? `*${e}` : `*.${e}`)\n .join(',');\n \n const pattern = this.options.pattern;\n return pattern.includes('{')\n ? pattern.replace(/\\}$/, `,${extGlob}}`)\n : `${pattern.replace(/\\/$/, '')}/{${extGlob}}`;\n }\n\n private getHash(filePath: string): string | null {\n try {\n if (!fs.existsSync(filePath)) return null;\n \n if (this.options.mtimeOnly) {\n const stats = fs.statSync(filePath);\n return `mtime:${stats.mtimeMs}`;\n }\n \n const content = fs.readFileSync(filePath);\n return crypto.createHash(this.options.hash).update(content).digest('hex');\n } catch {\n return null;\n }\n }\n\n private log(...args: unknown[]): void {\n if (!this.options.quiet && !this.disposed) console.log(...args);\n }\n\n private logVerbose(...args: unknown[]): void {\n if (this.options.verbose && !this.options.quiet && !this.disposed) {\n console.log(...args);\n }\n }\n\n private logJson(type: string, data: Record<string, unknown>): void {\n if (this.options.json && !this.disposed) {\n console.log(JSON.stringify({ timestamp: new Date().toISOString(), type, ...data }));\n }\n }\n\n private timestamp(): string {\n return this.t.gray(`[${new Date().toLocaleTimeString()}]`);\n }\n\n private parseCommand(cmdString: string): { cmd: string; args: string[] } {\n const tokens: string[] = [];\n let current = '';\n let inQuote = false;\n let quoteChar = '';\n let escaped = false;\n\n for (let i = 0; i < cmdString.length; i++) {\n const char = cmdString[i];\n const prevChar = i > 0 ? cmdString[i - 1] : '';\n\n if (escaped) {\n current += char;\n escaped = false;\n continue;\n }\n\n if (char === '\\\\' && !inQuote) {\n escaped = true;\n continue;\n }\n\n if ((char === '\"' || char === \"'\") && !inQuote) {\n inQuote = true;\n quoteChar = char;\n } else if (char === quoteChar && inQuote) {\n inQuote = false;\n quoteChar = '';\n } else if (char === ' ' && !inQuote) {\n if (current) {\n tokens.push(current);\n current = '';\n }\n } else {\n current += char;\n }\n }\n\n if (current) {\n tokens.push(current);\n }\n\n return { cmd: tokens[0] || '', args: tokens.slice(1) };\n }\n\n private runCommand(): void {\n if (this.disposed) return;\n\n if (this.isRunning) {\n this.logVerbose(this.t.yellow('⚠️ Previous command still running, skipping...'));\n this.emit('skip', 'previous command still running');\n return;\n }\n\n if (this.options.clearScreen) {\n console.clear();\n }\n\n this.isRunning = true;\n const retryInfo = this.retryCount > 0 ? ` (Retry ${this.retryCount}/${this.options.retry})` : '';\n this.log(`${this.timestamp()} ${this.t.cyan('🚀 Triggering:')} ${this.t.bold(this.options.cmd)}${retryInfo}`);\n this.logJson('trigger', { command: this.options.cmd, retry: this.retryCount });\n this.emit('trigger', this.options.cmd);\n\n const { cmd, args } = this.parseCommand(this.options.cmd);\n const startTime = Date.now();\n\n this.activeProcess = spawn(cmd, args, {\n stdio: 'inherit',\n shell: true,\n env: { ...process.env }\n });\n\n if (this.options.killTimeout > 0) {\n this.killTimer = setTimeout(() => {\n if (this.activeProcess && !this.disposed) {\n this.log(this.t.yellow(`⚠️ Process timeout (${this.options.killTimeout}ms), force killing...`));\n this.activeProcess.kill('SIGKILL');\n }\n }, this.options.killTimeout);\n }\n\n this.activeProcess.on('error', (err) => {\n this.log(this.t.red(`Process error: ${err.message}`));\n this.emit('error', err);\n });\n\n this.activeProcess.on('close', (code, signal) => {\n if (this.disposed) return;\n\n this.isRunning = false;\n if (this.killTimer) {\n clearTimeout(this.killTimer);\n this.killTimer = null;\n }\n this.activeProcess = null;\n const duration = ((Date.now() - startTime) / 1000).toFixed(2);\n\n if (code === 0) {\n this.log(`${this.timestamp()} ${this.t.green('✔ Done')} in ${duration}s`);\n this.logJson('done', { duration: parseFloat(duration) });\n this.emit('done', parseFloat(duration));\n this.retryCount = 0;\n } else {\n const exitMessage = signal ? ` (Signal: ${signal})` : ` (Exit code: ${code})`;\n this.log(`${this.timestamp()} ${this.t.red('✘ Failed')}${exitMessage}`);\n this.logJson('failed', { exitCode: code, signal });\n this.emit('fail', code, signal ?? undefined);\n \n if (this.options.retry > 0 && this.retryCount < this.options.retry) {\n this.retryCount++;\n this.log(this.t.yellow(`🔄 Retrying in 1s... (${this.retryCount}/${this.options.retry})`));\n setTimeout(() => this.runCommand(), 1000);\n return;\n }\n this.retryCount = 0;\n }\n this.log(this.t.dim('─'.repeat(40)));\n });\n }\n\n private handleFileChange(filePath: string): void {\n if (this.disposed) return;\n\n const currentHash = this.getHash(filePath);\n const lastHash = this.fileHashes.get(filePath);\n\n if (currentHash === lastHash) {\n this.logVerbose(this.t.gray(`Skipping ghost change: ${path.basename(filePath)}`));\n this.emit('skip', 'content unchanged', filePath);\n return;\n }\n\n if (currentHash) {\n this.fileHashes.set(filePath, currentHash);\n }\n\n this.emit('change', filePath);\n\n if (this.timeout) clearTimeout(this.timeout);\n this.timeout = setTimeout(() => {\n if (!this.disposed) {\n this.log(`${this.timestamp()} ${this.t.yellow('⚡ Change detected:')} ${path.basename(filePath)}`);\n this.logJson('change', { file: path.basename(filePath) });\n this.runCommand();\n }\n }, this.options.delay);\n }\n\n public async start(): Promise<void> {\n const validation = this.validate();\n if (!validation.valid) {\n const errorMsg = validation.errors.join(', ');\n this.log(this.t.red(`Validation error: ${errorMsg}`));\n this.emit('error', new Error(errorMsg));\n throw new Error(errorMsg);\n }\n\n const effectivePattern = this.getEffectivePattern();\n\n this.log(this.t.bold(`\\n🔭 Steady Watch Initialized`));\n this.log(` ${this.t.dim('Pattern:')} ${effectivePattern}`);\n this.log(` ${this.t.dim('Command:')} ${this.options.cmd}`);\n this.log(` ${this.t.dim('Delay:')} ${this.options.delay}ms`);\n if (this.options.quiet) this.log(` ${this.t.dim('Mode:')} quiet`);\n if (this.options.killTimeout > 0) this.log(` ${this.t.dim('Kill:')} ${this.options.killTimeout}ms`);\n if (this.options.retry > 0) this.log(` ${this.t.dim('Retry:')} ${this.options.retry}x`);\n if (this.options.mtimeOnly) this.log(` ${this.t.dim('Hash:')} mtime-only (fastest)`);\n else this.log(` ${this.t.dim('Hash:')} ${this.options.hash}`);\n this.log('');\n\n this.watcher = chokidar.watch(effectivePattern, {\n ignored: this.options.ignore,\n ignoreInitial: false,\n awaitWriteFinish: {\n stabilityThreshold: 100,\n pollInterval: 100\n }\n });\n\n this.watcher.on('ready', () => {\n this.log(this.t.green('👁️ Watcher ready. Monitoring for changes...'));\n this.logVerbose(this.t.dim(` Tracking ${this.fileHashes.size} file(s)`));\n this.emit('ready');\n });\n\n this.watcher.on('error', (error) => {\n this.log(this.t.red(`Watcher error: ${error.message}`));\n this.emit('error', error);\n });\n\n this.watcher.on('add', (filePath) => {\n if (this.disposed) return;\n const hash = this.getHash(filePath);\n if (hash) this.fileHashes.set(filePath, hash);\n this.logVerbose(this.t.dim(`Indexed: ${path.basename(filePath)}`));\n });\n\n this.watcher.on('change', (filePath) => this.handleFileChange(filePath));\n\n this.watcher.on('unlink', (filePath) => {\n if (this.disposed) return;\n this.fileHashes.delete(filePath);\n this.logVerbose(this.t.dim(`Removed: ${path.basename(filePath)}`));\n });\n }\n\n public async close(): Promise<void> {\n if (this.disposed) return;\n this.disposed = true;\n\n this.log(this.t.yellow('\\n🛑 Shutting down...'));\n this.logJson('shutdown', {});\n\n if (this.timeout) {\n clearTimeout(this.timeout);\n this.timeout = null;\n }\n\n if (this.killTimer) {\n clearTimeout(this.killTimer);\n this.killTimer = null;\n }\n\n if (this.activeProcess) {\n this.activeProcess.kill('SIGTERM');\n this.activeProcess = null;\n }\n\n if (this.watcher) {\n await this.watcher.close();\n this.watcher = null;\n }\n\n this.removeAllListeners();\n }\n\n public getTrackedFiles(): string[] {\n return Array.from(this.fileHashes.keys());\n }\n\n public isCurrentlyRunning(): boolean {\n return this.isRunning;\n }\n\n public isDisposed(): boolean {\n return this.disposed;\n }\n}\n\nexport function steadyWatch(options: SteadyWatchOptions): SteadyWatcher {\n return new SteadyWatcher(options);\n}\n","import fs from 'fs';\nimport path from 'path';\nimport { program } from 'commander';\nimport { CliOptions, CliArgs, SteadyWatchOptions, HashAlgorithm, ThemeName } from './types.js';\n\nexport function loadConfig(configPath?: string): Record<string, unknown> {\n const searchPaths = [\n configPath,\n '.steady-watchrc',\n '.steady-watchrc.json',\n 'steady-watch.config.json'\n ].filter(Boolean) as string[];\n\n for (const cfgPath of searchPaths) {\n try {\n const fullPath = path.resolve(cfgPath);\n if (fs.existsSync(fullPath)) {\n return JSON.parse(fs.readFileSync(fullPath, 'utf-8'));\n }\n } catch {\n continue;\n }\n }\n\n return {};\n}\n\nexport function parseIgnorePatterns(patternString?: string): (string | RegExp)[] {\n if (!patternString) return [];\n return patternString.split(',').map(p => p.trim()).filter(Boolean);\n}\n\nexport function parseExtFilter(extString?: string): string[] {\n if (!extString) return [];\n return extString.split(',').map(e => e.trim()).filter(Boolean);\n}\n\nexport function parseBoolean(value: unknown): boolean {\n if (typeof value === 'boolean') return value;\n if (typeof value === 'string') return value.toLowerCase() === 'true';\n return false;\n}\n\nexport function parseNumber(value: unknown, defaultValue: number): number {\n if (typeof value === 'number') return value;\n if (typeof value === 'string') {\n const parsed = parseInt(value, 10);\n return isNaN(parsed) ? defaultValue : parsed;\n }\n return defaultValue;\n}\n\nexport function mergeOptions(\n cliArgs: CliArgs,\n cliOpts: CliOptions,\n config: Record<string, unknown>\n): SteadyWatchOptions {\n return {\n pattern: cliArgs.pattern || (config.pattern as string) || '',\n cmd: cliOpts.cmd || (config.cmd as string) || '', \n delay: parseNumber(cliOpts.delay ?? config.delay, 300),\n verbose: parseBoolean(cliOpts.verbose ?? config.verbose),\n quiet: parseBoolean(cliOpts.quiet ?? config.quiet),\n ignore: [...parseIgnorePatterns(cliOpts.ignore), ...(config.ignore as string[] || [])],\n ext: cliOpts.ext ? parseExtFilter(cliOpts.ext) : (config.ext as string[] || []),\n killTimeout: parseNumber(cliOpts.killTimeout ?? config.killTimeout, 0),\n retry: parseNumber(cliOpts.retry ?? config.retry, 0),\n hash: (cliOpts.hash as HashAlgorithm) || (config.hash as HashAlgorithm) || 'md5',\n mtimeOnly: cliOpts.noHash ?? (config.mtimeOnly as boolean) ?? false,\n clearScreen: parseBoolean(cliOpts.clear ?? config.clearScreen),\n json: parseBoolean(cliOpts.json ?? config.json),\n theme: (cliOpts.theme as ThemeName) || (config.theme as ThemeName) || 'default'\n };\n}\n\nexport function parseCliArgs(): { args: CliArgs; opts: CliOptions } {\n program\n .name('steady-watch')\n .description('Intelligent file watcher with debouncing and content hashing.')\n .argument('<files>', 'Glob pattern to watch (e.g., \"src/**/*.ts\")')\n .requiredOption('-c, --cmd <command>', 'Command(s) to execute on change (supports quotes)')\n .option('-d, --delay <ms>', 'Debounce delay in milliseconds', '300')\n .option('-v, --verbose', 'Show hash calculations', false)\n .option('-q, --quiet', 'Minimize output', false)\n .option('--ignore <patterns>', 'Additional ignore patterns (comma-separated)')\n .option('--ext <extensions>', 'Filter by file extensions (e.g., .ts,.tsx)')\n .option('--config <path>', 'Path to config file')\n .option('--kill-timeout <ms>', 'Force kill process after timeout', '0')\n .option('--retry <count>', 'Retry failed command (0 = disabled)', '0')\n .option('--hash <algorithm>', 'Hash algorithm (md5, sha1, sha256)', 'md5')\n .option('--no-hash', 'Use mtime only instead of content hash (fastest)')\n .option('--clear', 'Clear screen on each trigger')\n .option('--json', 'Output in JSON format')\n .option('--theme <theme>', 'Color theme (default, minimal, none)', 'default')\n .version('2.0.0')\n .parse();\n\n const cliOpts = program.opts() as CliOptions;\n const cliArgs: CliArgs = { pattern: program.args[0] || '' };\n\n return { args: cliArgs, opts: cliOpts };\n}\n","export * from './types.js';\nexport * from './theme.js';\nexport { SteadyWatcher, steadyWatch } from './watcher.js';\n\nimport { SteadyWatcher, steadyWatch } from './watcher.js';\nimport { parseCliArgs, loadConfig, mergeOptions } from './cli.js';\n\nexport function runCli(): void {\n const { args, opts } = parseCliArgs();\n const config = loadConfig(opts.config);\n \n if (opts.config && config.cmd) {\n opts.cmd = config.cmd as string;\n }\n\n const options = mergeOptions(args, opts, config);\n \n if (!options.cmd) {\n console.error('Error: Command is required. Use -c option or config file.');\n process.exit(1);\n }\n\n const watcher = new SteadyWatcher(options);\n\n watcher.on('error', (err) => {\n console.error(`Error: ${err.message}`);\n process.exit(1);\n });\n\n watcher.start().catch((err) => {\n console.error(`Failed to start: ${err.message}`);\n process.exit(1);\n });\n\n const shutdown = async (signal: string) => {\n console.log(`\\nReceived ${signal}, shutting down...`);\n await watcher.close();\n process.exit(0);\n };\n\n process.on('SIGINT', () => shutdown('SIGINT'));\n process.on('SIGTERM', () => shutdown('SIGTERM'));\n process.on('uncaughtException', (err) => {\n console.error('Uncaught exception:', err);\n process.exit(1);\n });\n}\n\nif (require.main === module) {\n runCli();\n}\n"],"mappings":"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","names":["fs","path"]}
|
|
1
|
+
{"version":3,"sources":["../src/theme.ts","../src/watcher.ts","../src/cli.ts","../src/index.ts"],"sourcesContent":["import chalk from 'chalk';\nimport { ThemeName } from './types.js';\n\nexport type ChalkStyle = (s: string) => string;\n\nexport interface Theme {\n blue: ChalkStyle;\n green: ChalkStyle;\n yellow: ChalkStyle;\n red: ChalkStyle;\n cyan: ChalkStyle;\n gray: ChalkStyle;\n dim: ChalkStyle;\n bold: ChalkStyle;\n}\n\nexport const themes: Record<ThemeName, Theme> = {\n default: {\n blue: chalk.blue,\n green: chalk.green,\n yellow: chalk.yellow,\n red: chalk.red,\n cyan: chalk.cyan,\n gray: chalk.gray,\n dim: chalk.dim,\n bold: chalk.bold\n },\n minimal: {\n blue: (s: string) => s,\n green: (s: string) => s,\n yellow: (s: string) => s,\n red: (s: string) => s,\n cyan: (s: string) => s,\n gray: (s: string) => s,\n dim: (s: string) => s,\n bold: (s: string) => s\n },\n none: {\n blue: () => '',\n green: () => '',\n yellow: () => '',\n red: () => '',\n cyan: () => '',\n gray: () => '',\n dim: () => '',\n bold: (s: string) => s\n }\n};\n\nexport function getTheme(name: ThemeName): Theme {\n return themes[name] || themes.default;\n}\n","import { ChildProcess, spawn } from 'child_process';\nimport chokidar, { FSWatcher } from 'chokidar';\nimport crypto from 'crypto';\nimport fs from 'fs';\nimport path from 'path';\nimport { EventEmitter } from 'events';\nimport { \n SteadyWatchOptions, \n NormalizedOptions, \n ValidationResult,\n HashAlgorithm,\n ThemeName,\n SteadyWatchEvents\n} from './types.js';\nimport { getTheme, Theme } from './theme.js';\n\nexport class SteadyWatcher extends EventEmitter {\n private options: NormalizedOptions;\n private watcher: FSWatcher | null = null;\n private fileHashes = new Map<string, string>();\n private timeout: NodeJS.Timeout | null = null;\n private isRunning = false;\n private activeProcess: ChildProcess | null = null;\n private killTimer: NodeJS.Timeout | null = null;\n private retryCount = 0;\n private disposed = false;\n private t: Theme;\n\n private static readonly DEFAULT_IGNORE = [/node_modules/, /\\.git/, /dist/, /build/];\n private static readonly VALID_HASH_ALGORITHMS: HashAlgorithm[] = ['md5', 'sha1', 'sha256'];\n private static readonly VALID_THEMES: ThemeName[] = ['default', 'minimal', 'none'];\n\n constructor(options: SteadyWatchOptions) {\n super();\n this.options = this.normalizeOptions(options);\n this.t = getTheme(this.options.theme);\n }\n\n private normalizeOptions(options: SteadyWatchOptions): NormalizedOptions {\n const hash = SteadyWatcher.VALID_HASH_ALGORITHMS.includes(options.hash as HashAlgorithm)\n ? options.hash as HashAlgorithm\n : 'md5';\n \n const theme = SteadyWatcher.VALID_THEMES.includes(options.theme as ThemeName)\n ? options.theme as ThemeName\n : 'default';\n\n const mergedIgnore = [\n ...SteadyWatcher.DEFAULT_IGNORE,\n ...this.normalizeIgnorePatterns(options.ignore || [])\n ];\n\n return {\n pattern: options.pattern,\n cmd: options.cmd,\n delay: Math.max(0, options.delay ?? 300),\n verbose: options.verbose ?? false,\n quiet: options.quiet ?? false,\n ignore: mergedIgnore,\n ext: options.ext || [],\n killTimeout: Math.max(0, options.killTimeout ?? 0),\n retry: Math.max(0, options.retry ?? 0),\n hash,\n mtimeOnly: options.mtimeOnly ?? false,\n clearScreen: options.clearScreen ?? false,\n json: options.json ?? false,\n theme\n };\n }\n\n private normalizeIgnorePatterns(patterns: (string | RegExp)[]): RegExp[] {\n return patterns.map(p => {\n if (p instanceof RegExp) return p;\n try {\n return new RegExp(p);\n } catch {\n return new RegExp(`^${p.replace(/\\*/g, '.*')}$`);\n }\n });\n }\n\n public validate(): ValidationResult {\n const errors: string[] = [];\n\n if (!this.options.pattern) {\n errors.push('Pattern is required');\n }\n\n if (!this.options.cmd) {\n errors.push('Command is required');\n }\n\n if (this.options.delay < 0) {\n errors.push('Delay must be a non-negative number');\n }\n\n if (this.options.killTimeout < 0) {\n errors.push('Kill timeout must be a non-negative number');\n }\n\n if (this.options.retry < 0) {\n errors.push('Retry must be a non-negative number');\n }\n\n return { valid: errors.length === 0, errors };\n }\n\n private getEffectivePattern(): string {\n if (this.options.ext.length === 0) {\n return this.options.pattern;\n }\n\n const extGlob = this.options.ext\n .map(e => e.startsWith('.') ? `*${e}` : `*.${e}`)\n .join(',');\n \n const pattern = this.options.pattern;\n return pattern.includes('{')\n ? pattern.replace(/\\}$/, `,${extGlob}}`)\n : `${pattern.replace(/\\/$/, '')}/{${extGlob}}`;\n }\n\n private getHash(filePath: string): string | null {\n try {\n if (!fs.existsSync(filePath)) return null;\n \n if (this.options.mtimeOnly) {\n const stats = fs.statSync(filePath);\n return `mtime:${stats.mtimeMs}`;\n }\n \n const content = fs.readFileSync(filePath);\n return crypto.createHash(this.options.hash).update(content).digest('hex');\n } catch {\n return null;\n }\n }\n\n private log(...args: unknown[]): void {\n if (!this.options.quiet && !this.disposed) console.log(...args);\n }\n\n private logVerbose(...args: unknown[]): void {\n if (this.options.verbose && !this.options.quiet && !this.disposed) {\n console.log(...args);\n }\n }\n\n private logJson(type: string, data: Record<string, unknown>): void {\n if (this.options.json && !this.disposed) {\n console.log(JSON.stringify({ timestamp: new Date().toISOString(), type, ...data }));\n }\n }\n\n private timestamp(): string {\n return this.t.gray(`[${new Date().toLocaleTimeString()}]`);\n }\n\n private parseCommand(cmdString: string): { cmd: string; args: string[] } {\n const tokens: string[] = [];\n let current = '';\n let inQuote = false;\n let quoteChar = '';\n let escaped = false;\n\n for (let i = 0; i < cmdString.length; i++) {\n const char = cmdString[i];\n const prevChar = i > 0 ? cmdString[i - 1] : '';\n\n if (escaped) {\n current += char;\n escaped = false;\n continue;\n }\n\n if (char === '\\\\' && !inQuote) {\n escaped = true;\n continue;\n }\n\n if ((char === '\"' || char === \"'\") && !inQuote) {\n inQuote = true;\n quoteChar = char;\n } else if (char === quoteChar && inQuote) {\n inQuote = false;\n quoteChar = '';\n } else if (char === ' ' && !inQuote) {\n if (current) {\n tokens.push(current);\n current = '';\n }\n } else {\n current += char;\n }\n }\n\n if (current) {\n tokens.push(current);\n }\n\n return { cmd: tokens[0] || '', args: tokens.slice(1) };\n }\n\n private runCommand(): void {\n if (this.disposed) return;\n\n if (this.isRunning) {\n this.logVerbose(this.t.yellow('⚠️ Previous command still running, skipping...'));\n this.emit('skip', 'previous command still running');\n return;\n }\n\n if (this.options.clearScreen) {\n console.clear();\n }\n\n this.isRunning = true;\n const retryInfo = this.retryCount > 0 ? ` (Retry ${this.retryCount}/${this.options.retry})` : '';\n this.log(`${this.timestamp()} ${this.t.cyan('🚀 Triggering:')} ${this.t.bold(this.options.cmd)}${retryInfo}`);\n this.logJson('trigger', { command: this.options.cmd, retry: this.retryCount });\n this.emit('trigger', this.options.cmd);\n\n const { cmd, args } = this.parseCommand(this.options.cmd);\n const startTime = Date.now();\n\n this.activeProcess = spawn(cmd, args, {\n stdio: 'inherit',\n shell: true,\n env: { ...process.env }\n });\n\n if (this.options.killTimeout > 0) {\n this.killTimer = setTimeout(() => {\n if (this.activeProcess && !this.disposed) {\n this.log(this.t.yellow(`⚠️ Process timeout (${this.options.killTimeout}ms), force killing...`));\n this.activeProcess.kill('SIGKILL');\n }\n }, this.options.killTimeout);\n }\n\n this.activeProcess.on('error', (err) => {\n this.log(this.t.red(`Process error: ${err.message}`));\n this.emit('error', err);\n });\n\n this.activeProcess.on('close', (code, signal) => {\n if (this.disposed) return;\n\n this.isRunning = false;\n if (this.killTimer) {\n clearTimeout(this.killTimer);\n this.killTimer = null;\n }\n this.activeProcess = null;\n const duration = ((Date.now() - startTime) / 1000).toFixed(2);\n\n if (code === 0) {\n this.log(`${this.timestamp()} ${this.t.green('✔ Done')} in ${duration}s`);\n this.logJson('done', { duration: parseFloat(duration) });\n this.emit('done', parseFloat(duration));\n this.retryCount = 0;\n } else {\n const exitMessage = signal ? ` (Signal: ${signal})` : ` (Exit code: ${code})`;\n this.log(`${this.timestamp()} ${this.t.red('✘ Failed')}${exitMessage}`);\n this.logJson('failed', { exitCode: code, signal });\n this.emit('fail', code, signal ?? undefined);\n \n if (this.options.retry > 0 && this.retryCount < this.options.retry) {\n this.retryCount++;\n this.log(this.t.yellow(`🔄 Retrying in 1s... (${this.retryCount}/${this.options.retry})`));\n setTimeout(() => this.runCommand(), 1000);\n return;\n }\n this.retryCount = 0;\n }\n this.log(this.t.dim('─'.repeat(40)));\n });\n }\n\n private handleFileChange(filePath: string): void {\n if (this.disposed) return;\n\n const currentHash = this.getHash(filePath);\n const lastHash = this.fileHashes.get(filePath);\n\n if (currentHash === lastHash) {\n this.logVerbose(this.t.gray(`Skipping ghost change: ${path.basename(filePath)}`));\n this.emit('skip', 'content unchanged', filePath);\n return;\n }\n\n if (currentHash) {\n this.fileHashes.set(filePath, currentHash);\n }\n\n this.emit('change', filePath);\n\n if (this.timeout) clearTimeout(this.timeout);\n this.timeout = setTimeout(() => {\n if (!this.disposed) {\n this.log(`${this.timestamp()} ${this.t.yellow('⚡ Change detected:')} ${path.basename(filePath)}`);\n this.logJson('change', { file: path.basename(filePath) });\n this.runCommand();\n }\n }, this.options.delay);\n }\n\n public async start(): Promise<void> {\n const validation = this.validate();\n if (!validation.valid) {\n const errorMsg = validation.errors.join(', ');\n this.log(this.t.red(`Validation error: ${errorMsg}`));\n this.emit('error', new Error(errorMsg));\n throw new Error(errorMsg);\n }\n\n const effectivePattern = this.getEffectivePattern();\n\n this.log(this.t.bold(`\\n🔭 Steady Watch Initialized`));\n this.log(` ${this.t.dim('Pattern:')} ${effectivePattern}`);\n this.log(` ${this.t.dim('Command:')} ${this.options.cmd}`);\n this.log(` ${this.t.dim('Delay:')} ${this.options.delay}ms`);\n if (this.options.quiet) this.log(` ${this.t.dim('Mode:')} quiet`);\n if (this.options.killTimeout > 0) this.log(` ${this.t.dim('Kill:')} ${this.options.killTimeout}ms`);\n if (this.options.retry > 0) this.log(` ${this.t.dim('Retry:')} ${this.options.retry}x`);\n if (this.options.mtimeOnly) this.log(` ${this.t.dim('Hash:')} mtime-only (fastest)`);\n else this.log(` ${this.t.dim('Hash:')} ${this.options.hash}`);\n this.log('');\n\n this.watcher = chokidar.watch(effectivePattern, {\n ignored: this.options.ignore,\n ignoreInitial: false,\n awaitWriteFinish: {\n stabilityThreshold: 100,\n pollInterval: 100\n }\n });\n\n this.watcher.on('ready', () => {\n this.log(this.t.green('👁️ Watcher ready. Monitoring for changes...'));\n this.logVerbose(this.t.dim(` Tracking ${this.fileHashes.size} file(s)`));\n this.emit('ready');\n });\n\n this.watcher.on('error', (error) => {\n this.log(this.t.red(`Watcher error: ${error.message}`));\n this.emit('error', error);\n });\n\n this.watcher.on('add', (filePath) => {\n if (this.disposed) return;\n const hash = this.getHash(filePath);\n if (hash) this.fileHashes.set(filePath, hash);\n this.logVerbose(this.t.dim(`Indexed: ${path.basename(filePath)}`));\n });\n\n this.watcher.on('change', (filePath) => this.handleFileChange(filePath));\n\n this.watcher.on('unlink', (filePath) => {\n if (this.disposed) return;\n this.fileHashes.delete(filePath);\n this.logVerbose(this.t.dim(`Removed: ${path.basename(filePath)}`));\n });\n }\n\n public async close(): Promise<void> {\n if (this.disposed) return;\n this.disposed = true;\n\n this.log(this.t.yellow('\\n🛑 Shutting down...'));\n this.logJson('shutdown', {});\n\n if (this.timeout) {\n clearTimeout(this.timeout);\n this.timeout = null;\n }\n\n if (this.killTimer) {\n clearTimeout(this.killTimer);\n this.killTimer = null;\n }\n\n if (this.activeProcess) {\n this.activeProcess.kill('SIGTERM');\n this.activeProcess = null;\n }\n\n if (this.watcher) {\n await this.watcher.close();\n this.watcher = null;\n }\n\n this.removeAllListeners();\n }\n\n public getTrackedFiles(): string[] {\n return Array.from(this.fileHashes.keys());\n }\n\n public isCurrentlyRunning(): boolean {\n return this.isRunning;\n }\n\n public isDisposed(): boolean {\n return this.disposed;\n }\n}\n\nexport function steadyWatch(options: SteadyWatchOptions): SteadyWatcher {\n return new SteadyWatcher(options);\n}\n","import fs from 'fs';\nimport path from 'path';\nimport { program } from 'commander';\nimport { CliOptions, CliArgs, SteadyWatchOptions, HashAlgorithm, ThemeName } from './types.js';\n\nexport function loadConfig(configPath?: string): Record<string, unknown> {\n const searchPaths = [\n configPath,\n '.steady-watchrc',\n '.steady-watchrc.json',\n 'steady-watch.config.json'\n ];\n\n for (const cfgPath of searchPaths) {\n if (!cfgPath) continue;\n try {\n const fullPath = path.resolve(cfgPath);\n if (fs.existsSync(fullPath)) {\n return JSON.parse(fs.readFileSync(fullPath, 'utf-8'));\n }\n } catch {\n continue;\n }\n }\n\n return {};\n}\n\nexport function parseIgnorePatterns(patternString?: string): (string | RegExp)[] {\n if (!patternString) return [];\n return patternString.split(',').map(p => p.trim()).filter(Boolean);\n}\n\nexport function parseExtFilter(extString?: string): string[] {\n if (!extString) return [];\n return extString.split(',').map(e => e.trim()).filter(Boolean);\n}\n\nexport function parseBoolean(value: unknown): boolean {\n if (typeof value === 'boolean') return value;\n if (typeof value === 'string') return value.toLowerCase() === 'true';\n return false;\n}\n\nexport function parseNumber(value: unknown, defaultValue: number): number {\n if (typeof value === 'number') return value;\n if (typeof value === 'string') {\n const parsed = parseInt(value, 10);\n return isNaN(parsed) ? defaultValue : parsed;\n }\n return defaultValue;\n}\n\nexport function mergeOptions(\n cliArgs: CliArgs,\n cliOpts: CliOptions,\n config: Record<string, unknown>\n): SteadyWatchOptions {\n return {\n pattern: cliArgs.pattern || (config.pattern as string) || '',\n cmd: cliOpts.cmd || (config.cmd as string) || '', \n delay: parseNumber(cliOpts.delay ?? config.delay, 300),\n verbose: parseBoolean(cliOpts.verbose ?? config.verbose),\n quiet: parseBoolean(cliOpts.quiet ?? config.quiet),\n ignore: [...parseIgnorePatterns(cliOpts.ignore), ...(config.ignore as string[] || [])],\n ext: cliOpts.ext ? parseExtFilter(cliOpts.ext) : (config.ext as string[] || []),\n killTimeout: parseNumber(cliOpts.killTimeout ?? config.killTimeout, 0),\n retry: parseNumber(cliOpts.retry ?? config.retry, 0),\n hash: (cliOpts.hash as HashAlgorithm) || (config.hash as HashAlgorithm) || 'md5',\n mtimeOnly: cliOpts.noHash ?? (config.mtimeOnly as boolean) ?? false,\n clearScreen: parseBoolean(cliOpts.clear ?? config.clearScreen),\n json: parseBoolean(cliOpts.json ?? config.json),\n theme: (cliOpts.theme as ThemeName) || (config.theme as ThemeName) || 'default'\n };\n}\n\nexport function parseCliArgs(): { args: CliArgs; opts: CliOptions } {\n program\n .name('steady-watch')\n .description('Intelligent file watcher with debouncing and content hashing.')\n .argument('[files]', 'Glob pattern to watch (e.g., \"src/**/*.ts\")')\n .option('-c, --cmd <command>', 'Command(s) to execute on change (supports quotes)')\n .option('-d, --delay <ms>', 'Debounce delay in milliseconds', '300')\n .option('-v, --verbose', 'Show hash calculations', false)\n .option('-q, --quiet', 'Minimize output', false)\n .option('--ignore <patterns>', 'Additional ignore patterns (comma-separated)')\n .option('--ext <extensions>', 'Filter by file extensions (e.g., .ts,.tsx)')\n .option('--config <path>', 'Path to config file')\n .option('--kill-timeout <ms>', 'Force kill process after timeout', '0')\n .option('--retry <count>', 'Retry failed command (0 = disabled)', '0')\n .option('--hash <algorithm>', 'Hash algorithm (md5, sha1, sha256)', 'md5')\n .option('--no-hash', 'Use mtime only instead of content hash (fastest)')\n .option('--clear', 'Clear screen on each trigger')\n .option('--json', 'Output in JSON format')\n .option('--theme <theme>', 'Color theme (default, minimal, none)', 'default')\n .version('2.0.0')\n .parse();\n\n const cliOpts = program.opts() as CliOptions;\n const cliArgs: CliArgs = { pattern: program.args[0] || '' };\n\n return { args: cliArgs, opts: cliOpts };\n}\n","export * from './types.js';\nexport * from './theme.js';\nexport { SteadyWatcher, steadyWatch } from './watcher.js';\n\nimport { SteadyWatcher, steadyWatch } from './watcher.js';\nimport { parseCliArgs, loadConfig, mergeOptions } from './cli.js';\n\nexport function runCli(): void {\n const { args, opts } = parseCliArgs();\n const config = loadConfig(opts.config);\n \n if (opts.config && config.cmd) {\n opts.cmd = config.cmd as string;\n }\n\n const options = mergeOptions(args, opts, config);\n \n if (!options.cmd) {\n console.error('Error: Command is required. Use -c option or config file.');\n process.exit(1);\n }\n\n const watcher = new SteadyWatcher(options);\n\n watcher.on('error', (err) => {\n console.error(`Error: ${err.message}`);\n process.exit(1);\n });\n\n watcher.start().catch((err) => {\n console.error(`Failed to start: ${err.message}`);\n process.exit(1);\n });\n\n const shutdown = async (signal: string) => {\n console.log(`\\nReceived ${signal}, shutting down...`);\n await watcher.close();\n process.exit(0);\n };\n\n process.on('SIGINT', () => shutdown('SIGINT'));\n process.on('SIGTERM', () => shutdown('SIGTERM'));\n process.on('uncaughtException', (err) => {\n console.error('Uncaught exception:', err);\n process.exit(1);\n });\n}\n\nconst isMain = require.main === module || process.argv[1]?.includes('index.js') || process.argv[1]?.includes('steady-watch');\n\nif (isMain) {\n runCli();\n}\n"],"mappings":"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","names":["fs","path"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@laphilosophia/steady-watch",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.3",
|
|
4
4
|
"description": "Intelligent file watcher with content hashing and debouncing. No more ghost rebuilds.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -20,10 +20,11 @@
|
|
|
20
20
|
"steady-watch": "./bin/steady-watch",
|
|
21
21
|
"sw": "./bin/steady-watch"
|
|
22
22
|
},
|
|
23
|
-
"files": [
|
|
24
|
-
"dist",
|
|
25
|
-
"bin"
|
|
26
|
-
|
|
23
|
+
"files": [
|
|
24
|
+
"dist",
|
|
25
|
+
"bin",
|
|
26
|
+
"steady-watch.config.json"
|
|
27
|
+
],
|
|
27
28
|
"keywords": [
|
|
28
29
|
"watch",
|
|
29
30
|
"watcher",
|