neex 0.6.45 → 0.6.46

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.
@@ -1,256 +1,60 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
25
2
  var __importDefault = (this && this.__importDefault) || function (mod) {
26
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
27
4
  };
28
5
  Object.defineProperty(exports, "__esModule", { value: true });
29
6
  exports.addStartCommands = void 0;
30
7
  const start_manager_js_1 = require("../start-manager.js");
31
- const chalk_1 = __importDefault(require("chalk"));
32
- const figures_1 = __importDefault(require("figures"));
33
- const path = __importStar(require("path"));
34
- const fs = __importStar(require("fs/promises"));
35
- // Helper function to check if file exists
36
- async function fileExists(filePath) {
37
- try {
38
- await fs.access(filePath);
39
- return true;
40
- }
41
- catch (_a) {
42
- return false;
43
- }
44
- }
45
- // Helper function to determine the best command to start the application
46
- async function getStartCommand(filePath, showInfo) {
47
- const ext = path.extname(filePath).toLowerCase();
48
- const absolutePath = path.resolve(process.cwd(), filePath);
49
- const fileName = path.basename(filePath, ext);
50
- // Check if file exists
51
- if (!(await fileExists(absolutePath))) {
52
- throw new Error(`File not found: ${filePath}`);
53
- }
54
- if (showInfo) {
55
- console.log(chalk_1.default.blue(`${figures_1.default.info} neex start: Analyzing ${chalk_1.default.cyan(path.basename(filePath))}`));
56
- }
57
- switch (ext) {
58
- case '.js':
59
- case '.mjs':
60
- case '.cjs':
61
- if (showInfo) {
62
- console.log(chalk_1.default.green(`${figures_1.default.tick} neex start: JavaScript detected, using Node.js runtime`));
63
- }
64
- return {
65
- command: `node ${filePath}`,
66
- runtime: 'Node.js',
67
- processName: fileName
68
- };
69
- case '.ts':
70
- case '.mts':
71
- case '.cts':
72
- if (showInfo) {
73
- console.log(chalk_1.default.yellow(`${figures_1.default.warning} neex start: TypeScript detected, consider building first`));
74
- console.log(chalk_1.default.yellow(`${figures_1.default.pointer} Tip: Run 'neex build ${filePath}' first, then start the built .js file`));
75
- }
76
- return {
77
- command: `npx ts-node ${filePath}`,
78
- runtime: 'TypeScript (ts-node)',
79
- processName: fileName
80
- };
81
- default:
82
- if (showInfo) {
83
- console.log(chalk_1.default.yellow(`${figures_1.default.warning} neex start: Unknown file type, using Node.js`));
84
- }
85
- return {
86
- command: `node ${filePath}`,
87
- runtime: 'Node.js',
88
- processName: fileName
89
- };
90
- }
91
- }
8
+ const logger_manager_js_1 = require("../logger-manager.js");
9
+ const path_1 = __importDefault(require("path"));
10
+ const fs_1 = __importDefault(require("fs"));
92
11
  function addStartCommands(program) {
93
- let startManager = null;
94
- // Start command - run applications in production mode
95
- program
96
- .command('start <file>') // Made file mandatory
97
- .alias('s')
98
- .description('Start JavaScript/TypeScript applications in production mode')
99
- .option('-c, --no-color', 'Disable colored output')
100
- .option('-t, --no-timing', 'Hide timing information')
101
- .option('-p, --no-prefix', 'Hide command prefix')
102
- .option('-o, --no-output', 'Hide command output')
103
- .option('-m, --minimal', 'Use minimal output format')
104
- .option('-w, --watch', 'Watch for changes and restart (production hot-reload)')
105
- .option('-i, --ignore <patterns...>', 'Patterns to ignore when watching')
106
- .option('-e, --ext <extensions...>', 'File extensions to watch (default: js,mjs,json)')
107
- .option('-d, --delay <ms>', 'Delay before restart in milliseconds', parseInt)
108
- .option('--max-restarts <number>', 'Maximum number of restarts', parseInt)
109
- .option('--restart-delay <ms>', 'Delay between restarts in milliseconds', parseInt)
110
- .option('--verbose', 'Verbose output')
111
- .option('--info', 'Show detailed information during startup')
112
- .option('--signal <signal>', 'Signal to send to processes on restart', 'SIGTERM')
113
- .option('--env <env>', 'Environment mode', 'production')
114
- .option('--cluster', 'Enable cluster mode (spawn multiple processes)')
115
- .option('--cluster-instances <number>', 'Number of cluster instances', parseInt)
116
- .option('--memory-limit <mb>', 'Memory limit in MB', parseInt)
117
- .option('--cpu-limit <percent>', 'CPU limit percentage', parseInt)
118
- .action(async (file, options) => {
119
- try {
120
- const showInfo = options.info || false;
121
- if (showInfo) {
122
- console.log(chalk_1.default.blue(`${figures_1.default.info} neex start: Starting production application server...`));
123
- console.log(chalk_1.default.blue(`${figures_1.default.info} neex start: Target file: ${chalk_1.default.cyan(file)}`));
124
- }
125
- // Validate file parameter
126
- if (!file || file.trim() === '') {
127
- console.error(chalk_1.default.red(`${figures_1.default.cross} neex start: Error - No file specified!`));
128
- console.error(chalk_1.default.yellow(`${figures_1.default.pointer} Usage: neex start <file>`));
129
- console.error(chalk_1.default.yellow(`${figures_1.default.pointer} Example: neex start dist/server.js`));
130
- process.exit(1);
12
+ let manager = null;
13
+ const startCommand = program
14
+ .command('start [entry]')
15
+ .description('Start a production-ready application')
16
+ .option('-n, --name <name>', 'Application name')
17
+ .option('-w, --watch', 'Watch for file changes and restart the application', false)
18
+ .option('--quiet', 'Suppress all output', false)
19
+ .option('--color', 'Force color output', true)
20
+ .option('--verbose', 'Enable verbose logging', false)
21
+ .option('--node-args <args>', 'Arguments to pass to the node process', (value) => value.split(' '), [])
22
+ .action(async (entry, options) => {
23
+ let entryPoint = entry;
24
+ if (!entryPoint) {
25
+ const defaultPath = path_1.default.join(process.cwd(), 'dist', 'index.js');
26
+ if (fs_1.default.existsSync(defaultPath)) {
27
+ entryPoint = defaultPath;
131
28
  }
132
- // Get the start command configuration
133
- let startConfig;
134
- try {
135
- startConfig = await getStartCommand(file, showInfo);
136
- }
137
- catch (error) {
138
- console.error(chalk_1.default.red(`${figures_1.default.cross} neex start: ${error instanceof Error ? error.message : 'Unknown error occurred'}`));
29
+ else {
30
+ logger_manager_js_1.loggerManager.printLine('Entry file not found. Please specify an entry file or build the project first.', 'error');
139
31
  process.exit(1);
140
32
  }
141
- // Setup watch configuration if enabled
142
- const watchPaths = options.watch ? [path.dirname(file)] : [];
143
- const ignorePatterns = options.ignore || [
144
- 'node_modules/**',
145
- '.git/**',
146
- '*.log',
147
- 'src/**',
148
- 'test/**',
149
- 'tests/**',
150
- 'coverage/**',
151
- '.nyc_output/**',
152
- '*.tmp',
153
- '*.temp',
154
- '.DS_Store',
155
- 'Thumbs.db'
156
- ];
157
- const extensions = options.ext || ['js', 'mjs', 'json'];
158
- // Ensure environment is always set to production unless explicitly overridden
159
- const environment = options.env === 'development' ? options.env : 'production';
160
- // Log configuration only if --info flag is set
161
- if (showInfo) {
162
- console.log(chalk_1.default.blue(`${figures_1.default.info} neex start: Configuration:`));
163
- console.log(chalk_1.default.blue(` ${figures_1.default.arrowRight} Target: ${chalk_1.default.cyan(file)}`));
164
- console.log(chalk_1.default.blue(` ${figures_1.default.arrowRight} Runtime: ${chalk_1.default.cyan(startConfig.runtime)}`));
165
- console.log(chalk_1.default.blue(` ${figures_1.default.arrowRight} Process name: ${chalk_1.default.cyan(startConfig.processName)}`));
166
- console.log(chalk_1.default.blue(` ${figures_1.default.arrowRight} Environment: ${chalk_1.default.cyan(environment)}`));
167
- console.log(chalk_1.default.blue(` ${figures_1.default.arrowRight} Watch mode: ${chalk_1.default.cyan(options.watch ? 'Yes' : 'No')}`));
168
- console.log(chalk_1.default.blue(` ${figures_1.default.arrowRight} Cluster mode: ${chalk_1.default.cyan(options.cluster ? 'Yes' : 'No')}`));
169
- if (options.cluster) {
170
- console.log(chalk_1.default.blue(` ${figures_1.default.arrowRight} Cluster instances: ${chalk_1.default.cyan(options.clusterInstances || 'auto')}`));
171
- }
172
- if (options.watch) {
173
- console.log(chalk_1.default.blue(` ${figures_1.default.arrowRight} Watch paths: ${chalk_1.default.cyan(watchPaths.join(', '))}`));
174
- console.log(chalk_1.default.blue(` ${figures_1.default.arrowRight} Extensions: ${chalk_1.default.cyan(extensions.join(', '))}`));
175
- console.log(chalk_1.default.blue(` ${figures_1.default.arrowRight} Restart delay: ${chalk_1.default.cyan(options.delay || 1000)}ms`));
176
- }
177
- if (options.maxRestarts) {
178
- console.log(chalk_1.default.blue(` ${figures_1.default.arrowRight} Max restarts: ${chalk_1.default.cyan(options.maxRestarts)}`));
179
- }
180
- if (options.memoryLimit) {
181
- console.log(chalk_1.default.blue(` ${figures_1.default.arrowRight} Memory limit: ${chalk_1.default.cyan(options.memoryLimit)}MB`));
182
- }
183
- if (options.cpuLimit) {
184
- console.log(chalk_1.default.blue(` ${figures_1.default.arrowRight} CPU limit: ${chalk_1.default.cyan(options.cpuLimit)}%`));
185
- }
186
- if (options.verbose) {
187
- console.log(chalk_1.default.blue(`${figures_1.default.info} neex start: Verbose mode enabled - showing detailed logs`));
188
- }
189
- console.log(chalk_1.default.green(`${figures_1.default.tick} neex start: Starting production application server...`));
190
- console.log(chalk_1.default.green(`${figures_1.default.tick} neex start: Launching ${chalk_1.default.cyan(startConfig.processName)} in ${chalk_1.default.cyan(environment)} mode...`));
191
- console.log(chalk_1.default.blue(`${figures_1.default.info} neex start: Press Ctrl+C to stop the application server`));
192
- console.log(chalk_1.default.gray(`${'='.repeat(60)}`));
193
- }
194
- // Create StartManager instance
195
- startManager = new start_manager_js_1.StartManager({
196
- runnerName: 'neex start',
197
- targetFile: file,
198
- command: startConfig.command,
199
- processName: startConfig.processName,
200
- runtime: startConfig.runtime,
201
- environment: environment,
202
- parallel: false,
203
- color: options.color,
204
- showTiming: options.timing,
205
- prefix: options.prefix,
206
- printOutput: options.output,
207
- minimalOutput: options.minimal,
208
- watch: options.watch,
209
- watchPaths: watchPaths,
210
- ignore: ignorePatterns,
211
- ext: extensions,
212
- delay: options.delay || 1000,
213
- maxRestarts: options.maxRestarts,
214
- restartDelay: options.restartDelay || 3000,
215
- verbose: options.verbose,
216
- showInfo: showInfo,
217
- signal: options.signal,
218
- cluster: options.cluster,
219
- clusterInstances: options.clusterInstances,
220
- memoryLimit: options.memoryLimit,
221
- cpuLimit: options.cpuLimit,
222
- groupOutput: false,
223
- isServerMode: true,
224
- stopOnError: false
225
- });
226
- // Start the application server
227
- await startManager.start();
33
+ }
34
+ const startOptions = {
35
+ entry: entryPoint,
36
+ name: options.name,
37
+ watch: options.watch,
38
+ quiet: options.quiet,
39
+ color: options.color,
40
+ verbose: options.verbose,
41
+ nodeArgs: options.nodeArgs,
42
+ };
43
+ manager = new start_manager_js_1.StartManager(startOptions);
44
+ try {
45
+ await manager.start();
228
46
  }
229
47
  catch (error) {
230
- console.error(chalk_1.default.red(`${figures_1.default.cross} neex start: Fatal error occurred`));
231
- if (error instanceof Error) {
232
- console.error(chalk_1.default.red(`${figures_1.default.cross} Details: ${error.message}`));
233
- if (options.verbose && error.stack) {
234
- console.error(chalk_1.default.gray(`Stack trace:\n${error.stack}`));
235
- }
236
- }
237
- else {
238
- console.error(chalk_1.default.red(`${figures_1.default.cross} Unknown error occurred`));
239
- }
240
- console.error(chalk_1.default.yellow(`${figures_1.default.pointer} Try running with --verbose flag for more details`));
48
+ logger_manager_js_1.loggerManager.printLine(error.message, 'error');
241
49
  process.exit(1);
242
50
  }
243
51
  });
244
- // Return cleanup function for start manager
245
52
  return {
246
- getStartManager: () => startManager,
247
- cleanupStart: () => {
248
- if (startManager && startManager.isActive()) {
249
- console.log(chalk_1.default.blue(`${figures_1.default.info} neex start: Stopping application server...`));
250
- startManager.stop();
251
- console.log(chalk_1.default.green(`${figures_1.default.tick} neex start: Application server stopped successfully`));
53
+ cleanupStart: async () => {
54
+ if (manager) {
55
+ await manager.stop();
252
56
  }
253
- }
57
+ },
254
58
  };
255
59
  }
256
60
  exports.addStartCommands = addStartCommands;
@@ -0,0 +1,248 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.DevManager = void 0;
7
+ // src/dev-manager.ts - Development server manager with hot reloading
8
+ const child_process_1 = require("child_process");
9
+ const chokidar_1 = require("chokidar");
10
+ const logger_manager_js_1 = require("./logger-manager.js");
11
+ const chalk_1 = __importDefault(require("chalk"));
12
+ const figures_1 = __importDefault(require("figures"));
13
+ const path_1 = __importDefault(require("path"));
14
+ const fs_1 = __importDefault(require("fs"));
15
+ const lodash_1 = require("lodash");
16
+ class DevManager {
17
+ constructor(options) {
18
+ this.process = null;
19
+ this.watcher = null;
20
+ this.isRestarting = false;
21
+ this.restartCount = 0;
22
+ this.startTime = null;
23
+ this.options = options;
24
+ this.debouncedRestart = (0, lodash_1.debounce)(this.restart.bind(this), options.delay);
25
+ }
26
+ loadEnvFile() {
27
+ if (this.options.envFile && fs_1.default.existsSync(this.options.envFile)) {
28
+ try {
29
+ const envContent = fs_1.default.readFileSync(this.options.envFile, 'utf8');
30
+ const lines = envContent.split('\n');
31
+ for (const line of lines) {
32
+ const trimmed = line.trim();
33
+ if (trimmed && !trimmed.startsWith('#')) {
34
+ const [key, ...values] = trimmed.split('=');
35
+ if (key && values.length > 0) {
36
+ process.env[key.trim()] = values.join('=').trim();
37
+ }
38
+ }
39
+ }
40
+ if (this.options.verbose) {
41
+ logger_manager_js_1.loggerManager.printLine(`Loaded environment variables from ${this.options.envFile}`, 'info');
42
+ }
43
+ }
44
+ catch (error) {
45
+ logger_manager_js_1.loggerManager.printLine(`Failed to load environment file ${this.options.envFile}: ${error.message}`, 'warn');
46
+ }
47
+ }
48
+ }
49
+ getExecuteCommand() {
50
+ if (this.options.execCommand) {
51
+ const parts = this.options.execCommand.split(' ');
52
+ return { command: parts[0], args: [...parts.slice(1), this.options.file] };
53
+ }
54
+ // Default to tsx for TypeScript files
55
+ const args = [this.options.file];
56
+ if (this.options.inspect) {
57
+ args.unshift('--inspect');
58
+ }
59
+ if (this.options.inspectBrk) {
60
+ args.unshift('--inspect-brk');
61
+ }
62
+ return { command: 'tsx', args };
63
+ }
64
+ clearConsole() {
65
+ if (this.options.clearConsole && process.stdout.isTTY) {
66
+ process.stdout.write('\x1b[2J\x1b[0f');
67
+ }
68
+ }
69
+ async startProcess() {
70
+ var _a, _b;
71
+ if (this.process) {
72
+ return;
73
+ }
74
+ this.loadEnvFile();
75
+ const { command, args } = this.getExecuteCommand();
76
+ if (this.options.verbose) {
77
+ logger_manager_js_1.loggerManager.printLine(`Executing: ${command} ${args.join(' ')}`, 'info');
78
+ }
79
+ this.process = (0, child_process_1.spawn)(command, args, {
80
+ stdio: ['ignore', 'pipe', 'pipe'],
81
+ shell: false,
82
+ env: {
83
+ ...process.env,
84
+ NODE_ENV: process.env.NODE_ENV || 'development',
85
+ FORCE_COLOR: this.options.color ? '1' : '0'
86
+ },
87
+ detached: true
88
+ });
89
+ this.startTime = new Date();
90
+ this.restartCount++;
91
+ if (!this.options.quiet) {
92
+ const timestamp = new Date().toLocaleTimeString();
93
+ logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.green(figures_1.default.play)} Started ${chalk_1.default.cyan(this.options.file)} ${chalk_1.default.dim(`(${timestamp})`)}`, 'info');
94
+ }
95
+ (_a = this.process.stdout) === null || _a === void 0 ? void 0 : _a.on('data', (data) => {
96
+ if (!this.options.quiet) {
97
+ process.stdout.write(data);
98
+ }
99
+ });
100
+ (_b = this.process.stderr) === null || _b === void 0 ? void 0 : _b.on('data', (data) => {
101
+ if (!this.options.quiet) {
102
+ process.stderr.write(data);
103
+ }
104
+ });
105
+ this.process.on('error', (error) => {
106
+ logger_manager_js_1.loggerManager.printLine(`Process error: ${error.message}`, 'error');
107
+ });
108
+ this.process.on('exit', (code, signal) => {
109
+ if (this.process) {
110
+ this.process = null;
111
+ if (!this.isRestarting) {
112
+ if (code !== 0) {
113
+ const duration = this.startTime ? Date.now() - this.startTime.getTime() : 0;
114
+ logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.red(figures_1.default.cross)} Process exited with code ${code} after ${duration}ms`, 'error');
115
+ }
116
+ }
117
+ }
118
+ });
119
+ }
120
+ async stopProcess() {
121
+ if (!this.process) {
122
+ return;
123
+ }
124
+ return new Promise((resolve) => {
125
+ if (!this.process) {
126
+ resolve();
127
+ return;
128
+ }
129
+ const proc = this.process;
130
+ this.process = null;
131
+ const cleanup = () => {
132
+ if (!this.options.quiet) {
133
+ logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.yellow(figures_1.default.square)} Stopped process`, 'info');
134
+ }
135
+ resolve();
136
+ };
137
+ proc.on('exit', cleanup);
138
+ proc.on('error', cleanup);
139
+ try {
140
+ if (proc.pid) {
141
+ // Kill process group
142
+ process.kill(-proc.pid, 'SIGTERM');
143
+ // Fallback after timeout
144
+ setTimeout(() => {
145
+ if (proc.pid && !proc.killed) {
146
+ try {
147
+ process.kill(-proc.pid, 'SIGKILL');
148
+ }
149
+ catch (e) {
150
+ // Ignore
151
+ }
152
+ }
153
+ }, 5000);
154
+ }
155
+ }
156
+ catch (error) {
157
+ // Process might already be dead
158
+ cleanup();
159
+ }
160
+ });
161
+ }
162
+ async restart() {
163
+ if (this.isRestarting) {
164
+ return;
165
+ }
166
+ this.isRestarting = true;
167
+ if (this.options.clearConsole) {
168
+ this.clearConsole();
169
+ }
170
+ if (!this.options.quiet) {
171
+ logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.yellow(figures_1.default.arrowRight)} Restarting due to changes...`, 'info');
172
+ }
173
+ await this.stopProcess();
174
+ await this.startProcess();
175
+ this.isRestarting = false;
176
+ }
177
+ setupWatcher() {
178
+ const watchPatterns = this.options.watch;
179
+ const ignored = [
180
+ '**/node_modules/**',
181
+ '**/.git/**',
182
+ '**/dist/**',
183
+ '**/build/**',
184
+ '**/*.log',
185
+ ...this.options.ignore.map(pattern => `**/${pattern}/**`)
186
+ ];
187
+ this.watcher = (0, chokidar_1.watch)(watchPatterns, {
188
+ ignored,
189
+ ignoreInitial: true,
190
+ followSymlinks: false,
191
+ usePolling: false,
192
+ atomic: 300
193
+ });
194
+ this.watcher.on('change', (filePath) => {
195
+ if (this.options.verbose) {
196
+ logger_manager_js_1.loggerManager.printLine(`File changed: ${path_1.default.relative(process.cwd(), filePath)}`, 'info');
197
+ }
198
+ this.debouncedRestart();
199
+ });
200
+ this.watcher.on('add', (filePath) => {
201
+ if (this.options.verbose) {
202
+ logger_manager_js_1.loggerManager.printLine(`File added: ${path_1.default.relative(process.cwd(), filePath)}`, 'info');
203
+ }
204
+ this.debouncedRestart();
205
+ });
206
+ this.watcher.on('unlink', (filePath) => {
207
+ if (this.options.verbose) {
208
+ logger_manager_js_1.loggerManager.printLine(`File removed: ${path_1.default.relative(process.cwd(), filePath)}`, 'info');
209
+ }
210
+ this.debouncedRestart();
211
+ });
212
+ this.watcher.on('error', (error) => {
213
+ logger_manager_js_1.loggerManager.printLine(`Watcher error: ${error.message}`, 'error');
214
+ });
215
+ if (this.options.verbose) {
216
+ logger_manager_js_1.loggerManager.printLine(`Watching: ${watchPatterns.join(', ')}`, 'info');
217
+ logger_manager_js_1.loggerManager.printLine(`Ignoring: ${ignored.join(', ')}`, 'info');
218
+ }
219
+ }
220
+ async start() {
221
+ // Check if target file exists
222
+ if (!fs_1.default.existsSync(this.options.file)) {
223
+ throw new Error(`Target file not found: ${this.options.file}`);
224
+ }
225
+ logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.blue(figures_1.default.info)} Starting development server...`, 'info');
226
+ // Show configuration in verbose mode
227
+ if (this.options.verbose) {
228
+ logger_manager_js_1.loggerManager.printLine(`Target file: ${this.options.file}`, 'info');
229
+ logger_manager_js_1.loggerManager.printLine(`Watch patterns: ${this.options.watch.join(', ')}`, 'info');
230
+ logger_manager_js_1.loggerManager.printLine(`Restart delay: ${this.options.delay}ms`, 'info');
231
+ }
232
+ this.setupWatcher();
233
+ await this.startProcess();
234
+ logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.green(figures_1.default.tick)} Development server started. Watching for changes...`, 'info');
235
+ }
236
+ async stop() {
237
+ logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.yellow(figures_1.default.warning)} Stopping development server...`, 'info');
238
+ if (this.watcher) {
239
+ await this.watcher.close();
240
+ this.watcher = null;
241
+ }
242
+ await this.stopProcess();
243
+ if (this.restartCount > 0) {
244
+ logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.blue(figures_1.default.info)} Development server stopped after ${this.restartCount} restart(s)`, 'info');
245
+ }
246
+ }
247
+ }
248
+ exports.DevManager = DevManager;
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.loggerManager = void 0;
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ exports.loggerManager = {
9
+ printLine: (message, level = "info") => {
10
+ const prefix = {
11
+ info: chalk_1.default.blue("i"),
12
+ warn: chalk_1.default.yellow("!"),
13
+ error: chalk_1.default.red("x"),
14
+ }[level];
15
+ console.log(`${prefix} ${message}`);
16
+ },
17
+ };