neex 0.6.44 → 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,345 +1,368 @@
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.BuildManager = void 0;
30
- // src/build-manager.ts - Build manager with file watching and compilation
31
- const watcher_1 = require("./watcher");
32
- const runner_1 = require("./runner");
7
+ // src/build-manager.ts - Build manager for TypeScript projects using tsx
8
+ const child_process_1 = require("child_process");
9
+ const chokidar_1 = require("chokidar");
10
+ const logger_manager_js_1 = require("./logger-manager.js");
33
11
  const chalk_1 = __importDefault(require("chalk"));
34
12
  const figures_1 = __importDefault(require("figures"));
35
- const logger_1 = __importDefault(require("./logger"));
36
- const path = __importStar(require("path"));
37
- const fs = __importStar(require("fs/promises"));
13
+ const path_1 = __importDefault(require("path"));
14
+ const promises_1 = __importDefault(require("fs/promises"));
15
+ const fs_1 = require("fs");
38
16
  class BuildManager {
39
17
  constructor(options) {
18
+ this.watcher = null;
19
+ this.buildProcess = null;
40
20
  this.isBuilding = false;
41
21
  this.buildCount = 0;
42
- this.startTime = new Date();
43
- const defaultOptions = {
44
- parallel: false,
45
- printOutput: false,
46
- color: true,
47
- showTiming: false,
48
- prefix: false,
49
- stopOnError: true,
50
- minimalOutput: true,
51
- groupOutput: false,
52
- isServerMode: false,
53
- watch: false,
54
- ignore: [
55
- 'node_modules/**',
56
- '.git/**',
57
- '*.log',
58
- 'dist/**',
59
- 'build/**',
60
- 'coverage/**',
61
- '.nyc_output/**',
62
- '*.tmp',
63
- '*.temp'
64
- ],
65
- delay: 1000,
66
- verbose: false,
67
- showInfo: false,
68
- runnerName: 'neex build',
69
- clean: false,
70
- sourceMap: false,
71
- target: 'es2020',
72
- module: 'commonjs'
73
- };
74
- this.options = {
75
- ...defaultOptions,
76
- ...options
77
- };
22
+ this.debouncedBuild = this.debounce(this.runBuild.bind(this), 500);
23
+ this.options = options;
78
24
  }
79
- setupFileWatcher() {
80
- if (!this.options.watch) {
81
- return;
82
- }
83
- const inputDir = path.dirname(this.options.inputFile);
84
- const watchOptions = {
85
- watch: [inputDir],
86
- ignore: this.options.ignore,
87
- ext: this.options.buildType === 'typescript' ? ['ts', 'tsx'] : ['js', 'jsx', 'mjs', 'cjs'],
88
- delay: this.options.delay,
89
- verbose: this.options.verbose && this.options.showInfo
90
- };
91
- this.fileWatcher = new watcher_1.FileWatcher(watchOptions);
92
- this.fileWatcher.on('change', (event) => {
93
- if (this.options.watch && !this.isBuilding) {
94
- this.handleFileChange(event);
25
+ async cleanOutputDirectory() {
26
+ if (this.options.clean && (0, fs_1.existsSync)(this.options.output)) {
27
+ try {
28
+ await promises_1.default.rm(this.options.output, { recursive: true, force: true });
29
+ if (this.options.verbose) {
30
+ logger_manager_js_1.loggerManager.printLine(`Cleaned output directory: ${this.options.output}`, 'info');
31
+ }
32
+ }
33
+ catch (error) {
34
+ logger_manager_js_1.loggerManager.printLine(`Failed to clean output directory: ${error.message}`, 'warn');
95
35
  }
96
- });
97
- }
98
- async handleFileChange(event) {
99
- if (this.options.showInfo) {
100
- const prefix = chalk_1.default.cyan(`[${this.options.runnerName}]`);
101
- logger_1.default.printLine(`${prefix} File changed: ${chalk_1.default.yellow(event.relativePath)}`, 'info');
102
36
  }
103
- await this.rebuild();
104
37
  }
105
38
  async ensureOutputDirectory() {
106
39
  try {
107
- await fs.mkdir(this.options.outputDir, { recursive: true });
40
+ await promises_1.default.mkdir(this.options.output, { recursive: true });
108
41
  }
109
42
  catch (error) {
110
- if (this.options.showInfo) {
111
- logger_1.default.printLine(`Failed to create output directory: ${error.message}`, 'error');
112
- }
113
- throw error;
43
+ throw new Error(`Failed to create output directory: ${error.message}`);
114
44
  }
115
45
  }
116
- async cleanOutputDirectory() {
117
- if (!this.options.clean) {
118
- return;
46
+ async validateTsConfig() {
47
+ if (!(0, fs_1.existsSync)(this.options.tsconfig)) {
48
+ throw new Error(`TypeScript config file not found: ${this.options.tsconfig}`);
119
49
  }
120
- try {
121
- await fs.rm(this.options.outputDir, { recursive: true, force: true });
122
- if (this.options.showInfo) {
123
- const prefix = chalk_1.default.cyan(`[${this.options.runnerName}]`);
124
- logger_1.default.printLine(`${prefix} Cleaned output directory: ${chalk_1.default.yellow(this.options.outputDir)}`, 'info');
50
+ }
51
+ async copyPackageJson() {
52
+ var _a;
53
+ const packageJsonPath = path_1.default.join(process.cwd(), 'package.json');
54
+ const outputPackageJsonPath = path_1.default.join(this.options.output, 'package.json');
55
+ if ((0, fs_1.existsSync)(packageJsonPath)) {
56
+ try {
57
+ const packageJson = JSON.parse(await promises_1.default.readFile(packageJsonPath, 'utf8'));
58
+ // Create production package.json
59
+ const prodPackageJson = {
60
+ name: packageJson.name,
61
+ version: packageJson.version,
62
+ description: packageJson.description,
63
+ main: ((_a = packageJson.main) === null || _a === void 0 ? void 0 : _a.replace(/^src\//, '')) || 'index.js',
64
+ type: this.options.format === 'esm' ? 'module' : 'commonjs',
65
+ scripts: {
66
+ start: 'node index.js'
67
+ },
68
+ dependencies: packageJson.dependencies || {},
69
+ engines: packageJson.engines
70
+ };
71
+ await promises_1.default.writeFile(outputPackageJsonPath, JSON.stringify(prodPackageJson, null, 2));
72
+ if (this.options.verbose) {
73
+ logger_manager_js_1.loggerManager.printLine('Generated production package.json', 'info');
74
+ }
125
75
  }
126
- }
127
- catch (error) {
128
- if (this.options.showInfo) {
129
- logger_1.default.printLine(`Failed to clean output directory: ${error.message}`, 'error');
76
+ catch (error) {
77
+ logger_manager_js_1.loggerManager.printLine(`Failed to copy package.json: ${error.message}`, 'warn');
130
78
  }
131
- throw error;
132
79
  }
133
80
  }
134
- generateBuildCommand() {
135
- const { inputFile, outputDir, buildType, sourceMap, target, module } = this.options;
136
- switch (buildType) {
137
- case 'typescript':
138
- let tsCommand = `npx tsc ${inputFile} --outDir ${outputDir} --target ${target} --module ${module} --moduleResolution node --esModuleInterop --allowSyntheticDefaultImports --strict --skipLibCheck`;
139
- if (sourceMap) {
140
- tsCommand += ' --sourceMap';
141
- }
142
- return tsCommand;
143
- case 'javascript':
144
- case 'copy':
145
- return `cp ${inputFile} ${path.join(outputDir, path.basename(inputFile))}`;
146
- default:
147
- return `cp ${inputFile} ${path.join(outputDir, path.basename(inputFile))}`;
81
+ getBuildCommand() {
82
+ if (this.options.bundle) {
83
+ // Use tsx for bundling
84
+ const args = [
85
+ 'build',
86
+ this.options.source,
87
+ '--out-dir',
88
+ this.options.output,
89
+ '--target',
90
+ this.options.target
91
+ ];
92
+ if (this.options.minify) {
93
+ args.push('--minify');
94
+ }
95
+ if (this.options.sourcemap) {
96
+ args.push('--sourcemap');
97
+ }
98
+ if (this.options.format === 'esm') {
99
+ args.push('--format', 'esm');
100
+ }
101
+ if (this.options.external.length > 0) {
102
+ args.push('--external', this.options.external.join(','));
103
+ }
104
+ return { command: 'tsx', args };
105
+ }
106
+ else {
107
+ // Use TypeScript compiler directly
108
+ const args = [
109
+ '--project',
110
+ this.options.tsconfig,
111
+ '--outDir',
112
+ this.options.output,
113
+ '--target',
114
+ this.options.target
115
+ ];
116
+ if (this.options.sourcemap) {
117
+ args.push('--sourceMap');
118
+ }
119
+ if (this.options.format === 'esm') {
120
+ args.push('--module', 'es2020');
121
+ }
122
+ return { command: 'tsc', args };
148
123
  }
149
124
  }
150
125
  async runBuild() {
151
- var _a, _b, _c;
152
- const buildCommand = this.generateBuildCommand();
153
- // Create a runner with clean output settings
154
- const runnerOptions = {
155
- ...this.options,
156
- printOutput: (_a = this.options.showInfo) !== null && _a !== void 0 ? _a : false,
157
- showTiming: (_b = this.options.showInfo) !== null && _b !== void 0 ? _b : false,
158
- prefix: (_c = this.options.showInfo) !== null && _c !== void 0 ? _c : false,
159
- customPrefix: this.options.showInfo ? () => `build` : undefined
160
- };
161
- this.runner = new runner_1.Runner(runnerOptions);
126
+ if (this.isBuilding) {
127
+ return;
128
+ }
129
+ this.isBuilding = true;
130
+ this.buildCount++;
131
+ const startTime = Date.now();
132
+ if (!this.options.quiet) {
133
+ const buildNumber = this.options.watch ? ` #${this.buildCount}` : '';
134
+ logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.blue(figures_1.default.info)} Building${buildNumber}...`, 'info');
135
+ }
162
136
  try {
163
- this.isBuilding = true;
164
- this.buildCount++;
165
- this.lastBuildTime = new Date();
166
- // Ensure output directory exists
167
137
  await this.ensureOutputDirectory();
168
- // Clean if requested
169
- if (this.options.clean && this.buildCount === 1) {
170
- await this.cleanOutputDirectory();
171
- await this.ensureOutputDirectory();
138
+ const { command, args } = this.getBuildCommand();
139
+ if (this.options.verbose) {
140
+ logger_manager_js_1.loggerManager.printLine(`Executing: ${command} ${args.join(' ')}`, 'info');
172
141
  }
173
- const results = await this.runner.run([buildCommand]);
174
- // Handle build results
175
- const success = results.every(result => result.success);
176
- if (!success) {
177
- // Only show errors, let the caller handle success message
178
- const failedResults = results.filter(result => !result.success);
179
- for (const result of failedResults) {
180
- if (result.stderr) {
181
- console.error(chalk_1.default.red(result.stderr));
182
- }
183
- if (result.error) {
184
- console.error(chalk_1.default.red(result.error));
142
+ return new Promise((resolve, reject) => {
143
+ var _a, _b;
144
+ this.buildProcess = (0, child_process_1.spawn)(command, args, {
145
+ stdio: this.options.verbose ? ['ignore', 'pipe', 'pipe'] : ['ignore', 'ignore', 'pipe'],
146
+ shell: false,
147
+ env: {
148
+ ...process.env,
149
+ FORCE_COLOR: this.options.color ? '1' : '0'
185
150
  }
151
+ });
152
+ let stderr = '';
153
+ if (this.options.verbose) {
154
+ (_a = this.buildProcess.stdout) === null || _a === void 0 ? void 0 : _a.on('data', (data) => {
155
+ process.stdout.write(data);
156
+ });
186
157
  }
187
- throw new Error('Build failed');
188
- }
189
- return results;
158
+ (_b = this.buildProcess.stderr) === null || _b === void 0 ? void 0 : _b.on('data', (data) => {
159
+ stderr += data.toString();
160
+ if (this.options.verbose) {
161
+ process.stderr.write(data);
162
+ }
163
+ });
164
+ this.buildProcess.on('error', (error) => {
165
+ this.buildProcess = null;
166
+ this.isBuilding = false;
167
+ reject(new Error(`Build process error: ${error.message}`));
168
+ });
169
+ this.buildProcess.on('exit', async (code) => {
170
+ this.buildProcess = null;
171
+ this.isBuilding = false;
172
+ const duration = Date.now() - startTime;
173
+ if (code === 0) {
174
+ // Copy package.json after successful build
175
+ await this.copyPackageJson();
176
+ if (!this.options.quiet) {
177
+ logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.green(figures_1.default.tick)} Build completed in ${duration}ms`, 'info');
178
+ }
179
+ if (this.options.analyze) {
180
+ await this.analyzeBuild();
181
+ }
182
+ resolve();
183
+ }
184
+ else {
185
+ const error = new Error(`Build failed with code ${code}`);
186
+ if (stderr) {
187
+ logger_manager_js_1.loggerManager.printLine(`Build errors:\n${stderr}`, 'error');
188
+ }
189
+ reject(error);
190
+ }
191
+ });
192
+ });
190
193
  }
191
194
  catch (error) {
192
- throw error;
193
- }
194
- finally {
195
195
  this.isBuilding = false;
196
+ throw error;
196
197
  }
197
198
  }
198
- printBuildBanner() {
199
- var _a;
200
- if (!this.options.showInfo) {
201
- return;
202
- }
203
- const prefix = chalk_1.default.cyan(`[${this.options.runnerName}]`);
204
- const uptime = Math.floor((Date.now() - this.startTime.getTime()) / 1000);
205
- const uptimeStr = this.formatUptime(uptime);
206
- console.log('\n' + chalk_1.default.bgBlue.black(` ${(_a = this.options.runnerName) === null || _a === void 0 ? void 0 : _a.toUpperCase()} MODE `) + '\n');
207
- if (this.buildCount > 0) {
208
- console.log(`${prefix} ${chalk_1.default.green(`${figures_1.default.tick} Build #${this.buildCount}`)}`);
199
+ async analyzeBuild() {
200
+ try {
201
+ const stats = await promises_1.default.stat(this.options.output);
202
+ const files = await promises_1.default.readdir(this.options.output, { withFileTypes: true });
203
+ let totalSize = 0;
204
+ const fileStats = [];
205
+ for (const file of files) {
206
+ if (file.isFile()) {
207
+ const filePath = path_1.default.join(this.options.output, file.name);
208
+ const stat = await promises_1.default.stat(filePath);
209
+ totalSize += stat.size;
210
+ fileStats.push({ name: file.name, size: stat.size });
211
+ }
212
+ }
213
+ fileStats.sort((a, b) => b.size - a.size);
214
+ logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.blue(figures_1.default.info)} Bundle Analysis:`, 'info');
215
+ logger_manager_js_1.loggerManager.printLine(`Total size: ${chalk_1.default.cyan(this.formatBytes(totalSize))}`, 'info');
216
+ logger_manager_js_1.loggerManager.printLine(`Files: ${files.length}`, 'info');
217
+ if (this.options.verbose) {
218
+ fileStats.slice(0, 10).forEach(file => {
219
+ logger_manager_js_1.loggerManager.printLine(` ${file.name}: ${this.formatBytes(file.size)}`, 'info');
220
+ });
221
+ }
209
222
  }
210
- console.log(`${prefix} ${chalk_1.default.blue(`${figures_1.default.info} Uptime: ${uptimeStr}`)}`);
211
- console.log(`${prefix} ${chalk_1.default.blue(`${figures_1.default.info} Input: ${this.options.inputFile}`)}`);
212
- console.log(`${prefix} ${chalk_1.default.blue(`${figures_1.default.info} Output: ${this.options.outputDir}`)}`);
213
- console.log(`${prefix} ${chalk_1.default.blue(`${figures_1.default.info} Build type: ${this.options.buildType}`)}`);
214
- if (this.options.watch) {
215
- console.log(`${prefix} ${chalk_1.default.blue(`${figures_1.default.info} Watching for changes...`)}`);
223
+ catch (error) {
224
+ logger_manager_js_1.loggerManager.printLine(`Failed to analyze build: ${error.message}`, 'warn');
216
225
  }
217
- console.log('');
218
226
  }
219
- formatUptime(seconds) {
220
- if (seconds < 60) {
221
- return `${seconds}s`;
222
- }
223
- else if (seconds < 3600) {
224
- const minutes = Math.floor(seconds / 60);
225
- const remainingSeconds = seconds % 60;
226
- return `${minutes}m ${remainingSeconds}s`;
227
- }
228
- else {
229
- const hours = Math.floor(seconds / 3600);
230
- const minutes = Math.floor((seconds % 3600) / 60);
231
- return `${hours}h ${minutes}m`;
227
+ async stopProcess() {
228
+ if (!this.buildProcess) {
229
+ return;
232
230
  }
231
+ return new Promise((resolve) => {
232
+ if (!this.buildProcess) {
233
+ resolve();
234
+ return;
235
+ }
236
+ const proc = this.buildProcess;
237
+ this.buildProcess = null;
238
+ const cleanup = () => {
239
+ if (!this.options.quiet) {
240
+ logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.yellow(figures_1.default.square)} Stopped build process`, 'info');
241
+ }
242
+ resolve();
243
+ };
244
+ proc.on('exit', cleanup);
245
+ proc.on('error', cleanup);
246
+ try {
247
+ if (proc.pid) {
248
+ // Kill process group
249
+ process.kill(-proc.pid, 'SIGTERM');
250
+ // Fallback after timeout
251
+ setTimeout(() => {
252
+ if (proc.pid && !proc.killed) {
253
+ try {
254
+ process.kill(-proc.pid, 'SIGKILL');
255
+ }
256
+ catch (e) {
257
+ // Ignore
258
+ }
259
+ }
260
+ }, 5000);
261
+ }
262
+ }
263
+ catch (error) {
264
+ // Process might already be dead
265
+ cleanup();
266
+ }
267
+ });
233
268
  }
234
- async start() {
235
- this.startTime = new Date();
236
- // Setup file watcher if watch mode is enabled
237
- if (this.options.watch) {
238
- this.setupFileWatcher();
239
- }
240
- // Print build banner only if showInfo is true
241
- if (this.options.showInfo) {
242
- this.printBuildBanner();
243
- }
244
- // Start file watcher if enabled
245
- if (this.fileWatcher) {
246
- await this.fileWatcher.start();
247
- }
248
- // Run initial build
249
- await this.runBuild();
250
- // Set up graceful shutdown
251
- this.setupGracefulShutdown();
252
- if (this.options.watch) {
253
- if (this.options.showInfo) {
254
- const prefix = chalk_1.default.cyan(`[${this.options.runnerName}]`);
255
- logger_1.default.printLine(`${prefix} Build completed. Watching for changes...`, 'info');
256
- logger_1.default.printLine(`${prefix} Press ${chalk_1.default.cyan('Ctrl+C')} to stop`, 'info');
269
+ formatBytes(bytes) {
270
+ if (bytes === 0)
271
+ return '0 Bytes';
272
+ const k = 1024;
273
+ const sizes = ['Bytes', 'KB', 'MB', 'GB'];
274
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
275
+ return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
276
+ }
277
+ setupWatcher() {
278
+ const watchPatterns = [
279
+ `${this.options.source}/**/*.ts`,
280
+ `${this.options.source}/**/*.tsx`,
281
+ `${this.options.source}/**/*.js`,
282
+ `${this.options.source}/**/*.jsx`,
283
+ this.options.tsconfig
284
+ ];
285
+ this.watcher = (0, chokidar_1.watch)(watchPatterns, {
286
+ ignoreInitial: true,
287
+ followSymlinks: false,
288
+ usePolling: false,
289
+ atomic: 300,
290
+ ignored: [
291
+ '**/node_modules/**',
292
+ '**/.git/**',
293
+ `**/${this.options.output}/**`,
294
+ '**/*.log'
295
+ ]
296
+ });
297
+ this.watcher.on('change', (filePath) => {
298
+ if (this.options.verbose) {
299
+ logger_manager_js_1.loggerManager.printLine(`File changed: ${path_1.default.relative(process.cwd(), filePath)}`, 'info');
257
300
  }
301
+ this.debouncedBuild();
302
+ });
303
+ this.watcher.on('add', (filePath) => {
304
+ if (this.options.verbose) {
305
+ logger_manager_js_1.loggerManager.printLine(`File added: ${path_1.default.relative(process.cwd(), filePath)}`, 'info');
306
+ }
307
+ this.debouncedBuild();
308
+ });
309
+ this.watcher.on('unlink', (filePath) => {
310
+ if (this.options.verbose) {
311
+ logger_manager_js_1.loggerManager.printLine(`File removed: ${path_1.default.relative(process.cwd(), filePath)}`, 'info');
312
+ }
313
+ this.debouncedBuild();
314
+ });
315
+ this.watcher.on('error', (error) => {
316
+ logger_manager_js_1.loggerManager.printLine(`Watcher error: ${error.message}`, 'error');
317
+ });
318
+ if (this.options.verbose) {
319
+ logger_manager_js_1.loggerManager.printLine(`Watching: ${watchPatterns.join(', ')}`, 'info');
258
320
  }
259
321
  }
260
- async rebuild() {
261
- if (this.isBuilding) {
262
- return;
263
- }
264
- if (this.options.showInfo) {
265
- const prefix = chalk_1.default.cyan(`[${this.options.runnerName}]`);
266
- logger_1.default.printLine(`${prefix} Rebuilding due to file changes...`, 'info');
267
- }
268
- // Stop current processes
269
- if (this.runner) {
270
- this.runner.cleanup('SIGTERM');
271
- }
272
- // Wait a moment before rebuilding
273
- await new Promise(resolve => setTimeout(resolve, 500));
274
- // Print rebuild banner only if showInfo is true
275
- if (this.options.showInfo) {
276
- this.printBuildBanner();
322
+ debounce(func, wait) {
323
+ let timeout;
324
+ return function executedFunction(...args) {
325
+ const later = () => {
326
+ clearTimeout(timeout);
327
+ func(...args);
328
+ };
329
+ clearTimeout(timeout);
330
+ timeout = setTimeout(later, wait);
331
+ };
332
+ }
333
+ async build() {
334
+ // Check if source directory exists
335
+ if (!(0, fs_1.existsSync)(this.options.source)) {
336
+ throw new Error(`Source directory not found: ${this.options.source}`);
277
337
  }
278
- // Run build again
279
- await this.runBuild();
280
- if (this.options.showInfo) {
281
- const prefix = chalk_1.default.cyan(`[${this.options.runnerName}]`);
282
- logger_1.default.printLine(`${prefix} Rebuild completed. Watching for changes...`, 'info');
338
+ try {
339
+ await this.validateTsConfig();
340
+ await this.cleanOutputDirectory();
341
+ await this.runBuild();
342
+ if (this.options.watch) {
343
+ this.setupWatcher();
344
+ if (!this.options.quiet) {
345
+ logger_manager_js_1.loggerManager.printLine('Watching for file changes...', 'info');
346
+ }
347
+ }
283
348
  }
284
- else {
285
- // Show rebuild completion even without showInfo for watch mode
286
- console.log(chalk_1.default.green(`${figures_1.default.tick} Rebuild completed`));
349
+ catch (error) {
350
+ logger_manager_js_1.loggerManager.printLine(error.message, 'error');
351
+ if (!this.options.watch) {
352
+ process.exit(1);
353
+ }
287
354
  }
288
355
  }
289
356
  async stop() {
290
- if (!this.isBuilding && !this.options.watch) {
291
- return;
292
- }
293
- if (this.options.showInfo) {
294
- const prefix = chalk_1.default.cyan(`[${this.options.runnerName}]`);
295
- logger_1.default.printLine(`${prefix} Stopping build process...`, 'info');
296
- }
297
- // Stop file watcher
298
- if (this.fileWatcher) {
299
- this.fileWatcher.stop();
357
+ logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.yellow(figures_1.default.warning)} Stopping build process...`, 'info');
358
+ if (this.watcher) {
359
+ await this.watcher.close();
360
+ this.watcher = null;
300
361
  }
301
- // Stop current processes
302
- if (this.runner) {
303
- this.runner.cleanup('SIGTERM');
304
- }
305
- if (this.options.showInfo) {
306
- const prefix = chalk_1.default.cyan(`[${this.options.runnerName}]`);
307
- const uptime = Math.floor((Date.now() - this.startTime.getTime()) / 1000);
308
- const uptimeStr = this.formatUptime(uptime);
309
- logger_1.default.printLine(`${prefix} Build process stopped after ${uptimeStr}`, 'info');
310
- if (this.buildCount > 0) {
311
- logger_1.default.printLine(`${prefix} Total builds: ${this.buildCount}`, 'info');
312
- }
362
+ await this.stopProcess();
363
+ if (this.buildCount > 0) {
364
+ logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.blue(figures_1.default.info)} Build process stopped after ${this.buildCount} build(s)`, 'info');
313
365
  }
314
366
  }
315
- setupGracefulShutdown() {
316
- const handleSignal = (signal) => {
317
- if (this.options.showInfo) {
318
- console.log(`\n${chalk_1.default.yellow(`${figures_1.default.warning} Received ${signal}. Shutting down build process...`)}`);
319
- }
320
- this.stop().then(() => {
321
- process.exit(0);
322
- });
323
- };
324
- process.on('SIGINT', () => handleSignal('SIGINT'));
325
- process.on('SIGTERM', () => handleSignal('SIGTERM'));
326
- process.on('SIGQUIT', () => handleSignal('SIGQUIT'));
327
- }
328
- isActive() {
329
- return this.isBuilding || (this.options.watch || false);
330
- }
331
- getUptime() {
332
- return Math.floor((Date.now() - this.startTime.getTime()) / 1000);
333
- }
334
- getBuildCount() {
335
- return this.buildCount;
336
- }
337
- getLastBuildTime() {
338
- return this.lastBuildTime;
339
- }
340
- getWatchedFiles() {
341
- var _a;
342
- return ((_a = this.fileWatcher) === null || _a === void 0 ? void 0 : _a.getWatchedFiles()) || [];
343
- }
344
367
  }
345
368
  exports.BuildManager = BuildManager;