neex 0.6.85 → 0.6.87

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.
@@ -7,45 +7,36 @@ exports.addDevCommands = void 0;
7
7
  const dev_manager_js_1 = require("../dev-manager.js");
8
8
  const logger_manager_js_1 = require("../logger-manager.js");
9
9
  const chalk_1 = __importDefault(require("chalk"));
10
- const figures_1 = __importDefault(require("figures"));
11
10
  function addDevCommands(program) {
12
11
  let devManager = null;
13
- // Enhanced dev command with built-in TypeScript compilation
12
+ // Ultra-fast dev command optimized for speed
14
13
  program
15
14
  .command('dev [file]')
16
- .description('Start TypeScript development server with hot reloading (default: src/index.ts)')
17
- .option('-w, --watch <patterns>', 'Watch additional patterns (comma-separated)', 'src/**/*')
18
- .option('-i, --ignore <patterns>', 'Ignore patterns (comma-separated)', 'node_modules,dist,build,.git,coverage')
19
- .option('-e, --ext <extensions>', 'File extensions to watch (comma-separated)', 'ts,tsx,js,jsx,json')
20
- .option('-d, --delay <ms>', 'Delay before restart (ms)', parseInt, 500)
21
- .option('--fast', 'Enable fast hot reload (shorter delays)')
22
- .option('-c, --no-color', 'Disable colored output')
23
- .option('-q, --quiet', 'Reduce output verbosity')
24
- .option('-v, --verbose', 'Verbose output')
15
+ .description('Start ultra-fast TypeScript development server (like tsx)')
16
+ .option('-w, --watch <patterns>', 'Watch patterns (comma-separated)', 'src/**/*')
17
+ .option('-i, --ignore <patterns>', 'Ignore patterns (comma-separated)', 'node_modules,dist,build,.git')
18
+ .option('-e, --ext <extensions>', 'File extensions to watch', 'ts,tsx,js,jsx')
19
+ .option('-d, --delay <ms>', 'Restart delay in milliseconds', parseInt, 100)
20
+ .option('--fast', 'Ultra-fast mode (50ms delay)')
25
21
  .option('--no-clear', 'Don\'t clear console on restart')
22
+ .option('--no-color', 'Disable colored output')
23
+ .option('-q, --quiet', 'Minimal output')
24
+ .option('-v, --verbose', 'Verbose logging')
26
25
  .option('--inspect', 'Enable Node.js inspector')
27
- .option('--inspect-brk', 'Enable Node.js inspector with break')
28
- .option('--env <file>', 'Load environment variables from file', '.env')
29
- .option('--exec <command>', 'Command to execute instead of built-in TypeScript compilation')
30
- .option('--tsconfig <path>', 'Path to TypeScript configuration file')
31
- .option('--no-source-maps', 'Disable source maps')
32
- .option('--transpile-only', 'Skip type checking for faster compilation')
33
- .option('--node-args <args>', 'Additional Node.js arguments (comma-separated)', '')
26
+ .option('--inspect-brk', 'Enable Node.js inspector with breakpoint')
27
+ .option('--env <file>', 'Environment file to load', '.env')
28
+ .option('--exec <command>', 'Custom command to execute')
29
+ .option('--tsconfig <path>', 'TypeScript config file path')
30
+ .option('--no-source-maps', 'Disable source map generation')
31
+ .option('--transpile-only', 'Skip type checking (faster)')
32
+ .option('--node-args <args>', 'Node.js arguments (comma-separated)', '')
34
33
  .action(async (file, options) => {
35
34
  try {
36
35
  const targetFile = file || 'src/index.ts';
37
- // تنظیمات fast mode
38
- const delay = options.fast ? 200 : options.delay;
36
+ const delay = options.fast ? 50 : options.delay;
39
37
  if (!options.quiet) {
40
- logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.blue(figures_1.default.info)} Starting ${chalk_1.default.cyan('neex dev')} for ${chalk_1.default.cyan(targetFile)}`, 'info');
41
- if (options.verbose) {
42
- logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.dim('Features:')}`, 'info');
43
- logger_manager_js_1.loggerManager.printLine(` ${chalk_1.default.green('✓')} Built-in TypeScript compilation`, 'info');
44
- logger_manager_js_1.loggerManager.printLine(` ${chalk_1.default.green('✓')} Hot reloading with intelligent caching`, 'info');
45
- logger_manager_js_1.loggerManager.printLine(` ${chalk_1.default.green('✓')} Source map support`, 'info');
46
- logger_manager_js_1.loggerManager.printLine(` ${chalk_1.default.green('✓')} Fast transpilation mode`, 'info');
47
- logger_manager_js_1.loggerManager.printLine(` ${chalk_1.default.green('✓')} Dependency tracking`, 'info');
48
- }
38
+ console.log(''); // Empty line for better visual separation
39
+ logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.blue('⚡')} ${chalk_1.default.bold('neex dev')} ${chalk_1.default.dim('v1.0.0')} - ${chalk_1.default.cyan(targetFile)}`, 'info');
49
40
  }
50
41
  devManager = new dev_manager_js_1.DevManager({
51
42
  file: targetFile,
@@ -70,58 +61,119 @@ function addDevCommands(program) {
70
61
  }
71
62
  catch (error) {
72
63
  if (error instanceof Error) {
73
- logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.red(figures_1.default.cross)} Development server error: ${error.message}`, 'error');
64
+ logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.red('✖')} ${error.message}`, 'error');
74
65
  }
75
66
  else {
76
- logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.red(figures_1.default.cross)} An unknown development server error occurred`, 'error');
67
+ logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.red('✖')} Unknown error occurred`, 'error');
77
68
  }
78
69
  process.exit(1);
79
70
  }
80
71
  });
81
- // Additional helper commands
72
+ // Clean cache command
82
73
  program
83
74
  .command('dev:clean')
84
- .description('Clean development server cache and temporary files')
75
+ .description('Clean development cache and temp files')
85
76
  .action(() => {
86
77
  const path = require('path');
87
78
  const fs = require('fs');
88
79
  const tempDir = path.join(process.cwd(), '.neex-temp');
80
+ const nodeModulesCache = path.join(process.cwd(), 'node_modules/.cache');
81
+ let cleaned = false;
89
82
  if (fs.existsSync(tempDir)) {
90
83
  fs.rmSync(tempDir, { recursive: true, force: true });
91
- logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.green(figures_1.default.tick)} Cleaned development cache`, 'info');
84
+ cleaned = true;
85
+ }
86
+ if (fs.existsSync(nodeModulesCache)) {
87
+ try {
88
+ fs.rmSync(nodeModulesCache, { recursive: true, force: true });
89
+ cleaned = true;
90
+ }
91
+ catch (error) {
92
+ // Ignore cache cleanup errors
93
+ }
94
+ }
95
+ if (cleaned) {
96
+ logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.green('✓')} Cache cleaned successfully`, 'info');
92
97
  }
93
98
  else {
94
- logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.yellow(figures_1.default.info)} No cache to clean`, 'info');
99
+ logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.blue('ℹ')} No cache to clean`, 'info');
95
100
  }
96
101
  });
102
+ // TypeScript config check
97
103
  program
98
104
  .command('dev:check')
99
- .description('Check TypeScript configuration and dependencies')
100
- .option('--tsconfig <path>', 'Path to TypeScript configuration file')
105
+ .description('Check TypeScript configuration')
106
+ .option('--tsconfig <path>', 'TypeScript config file path')
101
107
  .action((options) => {
102
108
  const path = require('path');
103
109
  const fs = require('fs');
104
110
  const configPath = options.tsconfig || 'tsconfig.json';
105
111
  if (!fs.existsSync(configPath)) {
106
- logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.red(figures_1.default.cross)} TypeScript config not found: ${configPath}`, 'error');
112
+ logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.red('✖')} TypeScript config not found: ${configPath}`, 'error');
107
113
  process.exit(1);
108
114
  }
109
115
  try {
110
116
  const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
111
- logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.green(figures_1.default.tick)} TypeScript config is valid`, 'info');
112
- if (config.compilerOptions) {
113
- logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.dim('Compiler Options:')}`, 'info');
114
- logger_manager_js_1.loggerManager.printLine(` Target: ${config.compilerOptions.target || 'default'}`, 'info');
115
- logger_manager_js_1.loggerManager.printLine(` Module: ${config.compilerOptions.module || 'default'}`, 'info');
116
- logger_manager_js_1.loggerManager.printLine(` Strict: ${config.compilerOptions.strict || 'false'}`, 'info');
117
- logger_manager_js_1.loggerManager.printLine(` Source Maps: ${config.compilerOptions.sourceMap || 'false'}`, 'info');
117
+ logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.green('✓')} TypeScript config is valid`, 'info');
118
+ if (config.compilerOptions && !options.quiet) {
119
+ const opts = config.compilerOptions;
120
+ logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.dim('Configuration:')}`, 'info');
121
+ logger_manager_js_1.loggerManager.printLine(` Target: ${opts.target || 'ES5'}`, 'info');
122
+ logger_manager_js_1.loggerManager.printLine(` Module: ${opts.module || 'CommonJS'}`, 'info');
123
+ logger_manager_js_1.loggerManager.printLine(` Strict: ${opts.strict || false}`, 'info');
124
+ logger_manager_js_1.loggerManager.printLine(` Source Maps: ${opts.sourceMap || false}`, 'info');
125
+ logger_manager_js_1.loggerManager.printLine(` Skip Lib Check: ${opts.skipLibCheck || false}`, 'info');
118
126
  }
119
127
  }
120
128
  catch (error) {
121
- logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.red(figures_1.default.cross)} Invalid TypeScript config: ${error.message}`, 'error');
129
+ logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.red('✖')} Invalid TypeScript config: ${error.message}`, 'error');
122
130
  process.exit(1);
123
131
  }
124
132
  });
133
+ // Performance info command
134
+ program
135
+ .command('dev:info')
136
+ .description('Show development server information')
137
+ .action(() => {
138
+ const path = require('path');
139
+ const fs = require('fs');
140
+ const os = require('os');
141
+ console.log('');
142
+ logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.blue('⚡')} ${chalk_1.default.bold('neex dev')} - Development Server Info`, 'info');
143
+ console.log('');
144
+ logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.dim('System:')}`, 'info');
145
+ logger_manager_js_1.loggerManager.printLine(` Platform: ${os.platform()} ${os.arch()}`, 'info');
146
+ logger_manager_js_1.loggerManager.printLine(` Node.js: ${process.version}`, 'info');
147
+ logger_manager_js_1.loggerManager.printLine(` Memory: ${Math.round(process.memoryUsage().heapUsed / 1024 / 1024)}MB used`, 'info');
148
+ console.log('');
149
+ logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.dim('Features:')}`, 'info');
150
+ logger_manager_js_1.loggerManager.printLine(` ${chalk_1.default.green('✓')} Ultra-fast TypeScript compilation`, 'info');
151
+ logger_manager_js_1.loggerManager.printLine(` ${chalk_1.default.green('✓')} Intelligent module caching`, 'info');
152
+ logger_manager_js_1.loggerManager.printLine(` ${chalk_1.default.green('✓')} Hot reload with dependency tracking`, 'info');
153
+ logger_manager_js_1.loggerManager.printLine(` ${chalk_1.default.green('✓')} Source map support`, 'info');
154
+ logger_manager_js_1.loggerManager.printLine(` ${chalk_1.default.green('✓')} Memory-optimized processing`, 'info');
155
+ const tsConfigExists = fs.existsSync('tsconfig.json');
156
+ const packageJsonExists = fs.existsSync('package.json');
157
+ console.log('');
158
+ logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.dim('Project:')}`, 'info');
159
+ logger_manager_js_1.loggerManager.printLine(` TypeScript Config: ${tsConfigExists ? chalk_1.default.green('✓') : chalk_1.default.red('✖')}`, 'info');
160
+ logger_manager_js_1.loggerManager.printLine(` Package.json: ${packageJsonExists ? chalk_1.default.green('✓') : chalk_1.default.red('✖')}`, 'info');
161
+ if (packageJsonExists) {
162
+ try {
163
+ const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8'));
164
+ if (pkg.name) {
165
+ logger_manager_js_1.loggerManager.printLine(` Name: ${pkg.name}`, 'info');
166
+ }
167
+ if (pkg.version) {
168
+ logger_manager_js_1.loggerManager.printLine(` Version: ${pkg.version}`, 'info');
169
+ }
170
+ }
171
+ catch (error) {
172
+ // Ignore package.json parsing errors
173
+ }
174
+ }
175
+ console.log('');
176
+ });
125
177
  // Cleanup function
126
178
  const cleanupDev = () => {
127
179
  if (devManager) {
@@ -129,20 +181,27 @@ function addDevCommands(program) {
129
181
  devManager = null;
130
182
  }
131
183
  };
132
- // Handle process termination
133
- process.on('SIGINT', () => {
184
+ // Enhanced signal handling
185
+ const handleSignal = (signal) => {
134
186
  if (devManager) {
135
- logger_manager_js_1.loggerManager.printLine(`\n${chalk_1.default.yellow(figures_1.default.warning)} Received SIGINT, shutting down gracefully...`, 'info');
187
+ console.log(''); // New line for better formatting
188
+ logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.yellow('⏹')} Received ${signal}, shutting down...`, 'info');
136
189
  cleanupDev();
137
190
  process.exit(0);
138
191
  }
192
+ };
193
+ process.on('SIGINT', () => handleSignal('SIGINT'));
194
+ process.on('SIGTERM', () => handleSignal('SIGTERM'));
195
+ // Handle uncaught exceptions
196
+ process.on('uncaughtException', (error) => {
197
+ console.error(chalk_1.default.red('Uncaught Exception:'), error);
198
+ cleanupDev();
199
+ process.exit(1);
139
200
  });
140
- process.on('SIGTERM', () => {
141
- if (devManager) {
142
- logger_manager_js_1.loggerManager.printLine(`\n${chalk_1.default.yellow(figures_1.default.warning)} Received SIGTERM, shutting down gracefully...`, 'info');
143
- cleanupDev();
144
- process.exit(0);
145
- }
201
+ process.on('unhandledRejection', (reason, promise) => {
202
+ console.error(chalk_1.default.red('Unhandled Rejection at:'), promise, 'reason:', reason);
203
+ cleanupDev();
204
+ process.exit(1);
146
205
  });
147
206
  return { cleanupDev };
148
207
  }
@@ -27,16 +27,16 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
27
27
  };
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
29
  exports.DevManager = void 0;
30
- // src/dev-manager.ts - Enhanced TypeScript development server with improved caching
30
+ // src/dev-manager.ts - Ultra-fast TypeScript development server like tsx
31
31
  const child_process_1 = require("child_process");
32
32
  const chokidar_1 = require("chokidar");
33
33
  const logger_manager_js_1 = require("./logger-manager.js");
34
34
  const chalk_1 = __importDefault(require("chalk"));
35
- const figures_1 = __importDefault(require("figures"));
36
35
  const path_1 = __importDefault(require("path"));
37
36
  const fs_1 = __importDefault(require("fs"));
38
37
  const lodash_1 = require("lodash");
39
38
  const ts = __importStar(require("typescript"));
39
+ const crypto_1 = __importDefault(require("crypto"));
40
40
  class DevManager {
41
41
  constructor(options) {
42
42
  this.process = null;
@@ -45,10 +45,23 @@ class DevManager {
45
45
  this.restartCount = 0;
46
46
  this.startTime = null;
47
47
  this.moduleCache = new Map();
48
- this.fileWatcher = new Map();
48
+ this.currentTempFile = null;
49
49
  this.options = options;
50
- this.debouncedRestart = (0, lodash_1.debounce)(this.restart.bind(this), options.delay);
50
+ this.tempDir = path_1.default.join(process.cwd(), '.neex-temp');
51
+ this.debouncedRestart = (0, lodash_1.debounce)(this.restart.bind(this), Math.max(options.delay, 100));
51
52
  this.tsCompilerOptions = this.loadTsConfig();
53
+ this.setupTempDir();
54
+ }
55
+ setupTempDir() {
56
+ if (fs_1.default.existsSync(this.tempDir)) {
57
+ try {
58
+ fs_1.default.rmSync(this.tempDir, { recursive: true, force: true });
59
+ }
60
+ catch (error) {
61
+ // Ignore cleanup errors
62
+ }
63
+ }
64
+ fs_1.default.mkdirSync(this.tempDir, { recursive: true });
52
65
  }
53
66
  loadTsConfig() {
54
67
  const configPath = this.options.tsConfig || 'tsconfig.json';
@@ -57,8 +70,6 @@ class DevManager {
57
70
  module: ts.ModuleKind.CommonJS,
58
71
  moduleResolution: ts.ModuleResolutionKind.NodeJs,
59
72
  allowJs: true,
60
- outDir: undefined,
61
- rootDir: undefined,
62
73
  strict: false,
63
74
  esModuleInterop: true,
64
75
  skipLibCheck: true,
@@ -68,27 +79,22 @@ class DevManager {
68
79
  sourceMap: this.options.sourceMaps,
69
80
  inlineSourceMap: false,
70
81
  inlineSources: false,
82
+ removeComments: false,
83
+ preserveConstEnums: false,
84
+ isolatedModules: true, // For faster compilation
71
85
  };
72
86
  if (fs_1.default.existsSync(configPath)) {
73
87
  try {
74
88
  const configFile = ts.readConfigFile(configPath, ts.sys.readFile);
75
- if (configFile.error) {
76
- logger_manager_js_1.loggerManager.printLine(`Error reading tsconfig.json: ${configFile.error.messageText}`, 'warn');
77
- return defaultOptions;
78
- }
79
- const parsedConfig = ts.parseJsonConfigFileContent(configFile.config, ts.sys, path_1.default.dirname(configPath));
80
- if (parsedConfig.errors.length > 0) {
81
- logger_manager_js_1.loggerManager.printLine(`Error parsing tsconfig.json: ${parsedConfig.errors[0].messageText}`, 'warn');
82
- return defaultOptions;
83
- }
84
- const options = { ...parsedConfig.options, ...defaultOptions };
85
- if (this.options.verbose) {
86
- logger_manager_js_1.loggerManager.printLine(`Loaded TypeScript config from ${configPath}`, 'info');
89
+ if (!configFile.error) {
90
+ const parsedConfig = ts.parseJsonConfigFileContent(configFile.config, ts.sys, path_1.default.dirname(configPath));
91
+ if (parsedConfig.errors.length === 0) {
92
+ return { ...defaultOptions, ...parsedConfig.options };
93
+ }
87
94
  }
88
- return options;
89
95
  }
90
96
  catch (error) {
91
- logger_manager_js_1.loggerManager.printLine(`Failed to load tsconfig.json: ${error.message}`, 'warn');
97
+ // Fall back to defaults
92
98
  }
93
99
  }
94
100
  return defaultOptions;
@@ -98,455 +104,344 @@ class DevManager {
98
104
  try {
99
105
  const envContent = fs_1.default.readFileSync(this.options.envFile, 'utf8');
100
106
  const lines = envContent.split('\n');
101
- let loadedCount = 0;
102
107
  for (const line of lines) {
103
108
  const trimmed = line.trim();
104
109
  if (trimmed && !trimmed.startsWith('#')) {
105
110
  const [key, ...values] = trimmed.split('=');
106
111
  if (key && values.length > 0) {
107
112
  process.env[key.trim()] = values.join('=').trim().replace(/^["']|["']$/g, '');
108
- loadedCount++;
109
113
  }
110
114
  }
111
115
  }
112
- if (!this.options.quiet && loadedCount > 0) {
113
- logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.dim(figures_1.default.info)} Loaded ${loadedCount} env variable${loadedCount > 1 ? 's' : ''} from ${path_1.default.basename(this.options.envFile)}`, 'info');
114
- }
115
- else if (this.options.verbose) {
116
- logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.dim(figures_1.default.info)} No env variables found in ${this.options.envFile}`, 'info');
117
- }
118
116
  }
119
117
  catch (error) {
120
- logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.yellow(figures_1.default.warning)} Failed to load ${this.options.envFile}: ${error.message}`, 'warn');
118
+ if (this.options.verbose) {
119
+ logger_manager_js_1.loggerManager.printLine(`Failed to load ${this.options.envFile}: ${error.message}`, 'warn');
120
+ }
121
121
  }
122
122
  }
123
123
  }
124
- generateFileHash(content) {
125
- // Simple hash function for content
126
- let hash = 0;
127
- for (let i = 0; i < content.length; i++) {
128
- const char = content.charCodeAt(i);
129
- hash = ((hash << 5) - hash) + char;
130
- hash = hash & hash; // Convert to 32bit integer
131
- }
132
- return hash.toString(16);
133
- }
134
- shouldRecompile(filePath, sourceCode) {
135
- const absolutePath = path_1.default.resolve(filePath);
136
- const cached = this.moduleCache.get(absolutePath);
137
- if (!cached) {
138
- return true;
139
- }
140
- // Check if file was modified
141
- const stat = fs_1.default.statSync(absolutePath);
142
- if (stat.mtimeMs > cached.lastModified) {
143
- return true;
144
- }
145
- // Check if content hash changed
146
- const currentHash = this.generateFileHash(sourceCode);
147
- if (currentHash !== cached.hash) {
148
- return true;
149
- }
150
- return false;
124
+ createHash(content) {
125
+ return crypto_1.default.createHash('md5').update(content).digest('hex');
151
126
  }
152
- compileTypeScript(filePath) {
153
- const absolutePath = path_1.default.resolve(filePath);
154
- try {
155
- const sourceCode = fs_1.default.readFileSync(absolutePath, 'utf8');
156
- const currentHash = this.generateFileHash(sourceCode);
157
- // Check if we need to recompile
158
- if (!this.shouldRecompile(absolutePath, sourceCode)) {
159
- const cached = this.moduleCache.get(absolutePath);
160
- if (this.options.verbose) {
161
- logger_manager_js_1.loggerManager.printLine(`Using cached compilation for ${path_1.default.relative(process.cwd(), filePath)}`, 'info');
162
- }
163
- return cached;
164
- }
165
- if (this.options.verbose) {
166
- logger_manager_js_1.loggerManager.printLine(`Compiling ${path_1.default.relative(process.cwd(), filePath)}`, 'info');
167
- }
168
- const dependencies = new Set();
169
- // Extract import/require dependencies with better regex
170
- const importRegex = /(?:import|require)\s*(?:\([^)]*\)|[^;]+from\s+)['"`]([^'"`]+)['"`]/g;
171
- let match;
172
- while ((match = importRegex.exec(sourceCode)) !== null) {
173
- if (match[1].startsWith('.')) {
174
- let depPath = path_1.default.resolve(path_1.default.dirname(absolutePath), match[1]);
175
- // Handle file extensions
176
- if (!path_1.default.extname(depPath)) {
177
- // Try common extensions
178
- for (const ext of ['.ts', '.tsx', '.js', '.jsx']) {
179
- if (fs_1.default.existsSync(depPath + ext)) {
180
- depPath = depPath + ext;
181
- break;
182
- }
127
+ extractDependencies(sourceCode, filePath) {
128
+ const dependencies = [];
129
+ const importRegex = /(?:import|require)\s*(?:\([^)]*\)|[^;]+?from\s+)?['"`]([^'"`]+)['"`]/g;
130
+ let match;
131
+ while ((match = importRegex.exec(sourceCode)) !== null) {
132
+ const importPath = match[1];
133
+ if (importPath.startsWith('.')) {
134
+ let resolvedPath = path_1.default.resolve(path_1.default.dirname(filePath), importPath);
135
+ // Try to resolve with extensions
136
+ if (!fs_1.default.existsSync(resolvedPath)) {
137
+ for (const ext of ['.ts', '.tsx', '.js', '.jsx']) {
138
+ const withExt = resolvedPath + ext;
139
+ if (fs_1.default.existsSync(withExt)) {
140
+ resolvedPath = withExt;
141
+ break;
183
142
  }
184
- // Try index files
185
- if (!fs_1.default.existsSync(depPath)) {
186
- for (const ext of ['.ts', '.tsx', '.js', '.jsx']) {
187
- const indexPath = path_1.default.join(depPath, 'index' + ext);
188
- if (fs_1.default.existsSync(indexPath)) {
189
- depPath = indexPath;
190
- break;
191
- }
192
- }
193
- }
194
- }
195
- if (fs_1.default.existsSync(depPath)) {
196
- dependencies.add(depPath);
197
143
  }
198
144
  }
199
- }
200
- let result;
201
- if (this.options.transpileOnly) {
202
- result = ts.transpileModule(sourceCode, {
203
- compilerOptions: this.tsCompilerOptions,
204
- fileName: absolutePath,
205
- reportDiagnostics: false
206
- });
207
- }
208
- else {
209
- // Create a program for better error reporting
210
- const program = ts.createProgram([absolutePath], this.tsCompilerOptions);
211
- const sourceFile = program.getSourceFile(absolutePath);
212
- if (!sourceFile) {
213
- throw new Error(`Could not load source file: ${absolutePath}`);
214
- }
215
- // Check for compilation errors
216
- const diagnostics = ts.getPreEmitDiagnostics(program, sourceFile);
217
- if (diagnostics.length > 0) {
218
- const errors = diagnostics.map(diagnostic => {
219
- const message = ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n');
220
- if (diagnostic.file && diagnostic.start !== undefined) {
221
- const { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start);
222
- return `${path_1.default.relative(process.cwd(), diagnostic.file.fileName)}:${line + 1}:${character + 1} - ${message}`;
145
+ // Try index files
146
+ if (!fs_1.default.existsSync(resolvedPath)) {
147
+ for (const ext of ['.ts', '.tsx', '.js', '.jsx']) {
148
+ const indexPath = path_1.default.join(resolvedPath, 'index' + ext);
149
+ if (fs_1.default.existsSync(indexPath)) {
150
+ resolvedPath = indexPath;
151
+ break;
223
152
  }
224
- return message;
225
- });
226
- logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.red(figures_1.default.cross)} TypeScript compilation errors:\n${errors.join('\n')}`, 'error');
227
- // Don't exit in dev mode, just show errors
228
- if (!this.options.quiet) {
229
- logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.yellow(figures_1.default.warning)} Continuing with compilation errors...`, 'warn');
230
153
  }
231
154
  }
232
- result = ts.transpileModule(sourceCode, {
233
- compilerOptions: this.tsCompilerOptions,
234
- fileName: absolutePath,
235
- reportDiagnostics: false
236
- });
155
+ if (fs_1.default.existsSync(resolvedPath)) {
156
+ dependencies.push(resolvedPath);
157
+ }
237
158
  }
238
- const stat = fs_1.default.statSync(absolutePath);
239
- const compiled = {
159
+ }
160
+ return dependencies;
161
+ }
162
+ compileModule(filePath, forceRecompile = false) {
163
+ const absolutePath = path_1.default.resolve(filePath);
164
+ try {
165
+ const sourceCode = fs_1.default.readFileSync(absolutePath, 'utf8');
166
+ const hash = this.createHash(sourceCode);
167
+ const cached = this.moduleCache.get(absolutePath);
168
+ // Check if we can use cached version
169
+ if (!forceRecompile && cached && cached.hash === hash) {
170
+ return cached;
171
+ }
172
+ const dependencies = this.extractDependencies(sourceCode, absolutePath);
173
+ // Fast transpile without type checking for development
174
+ const result = ts.transpileModule(sourceCode, {
175
+ compilerOptions: this.tsCompilerOptions,
176
+ fileName: absolutePath,
177
+ reportDiagnostics: false // Skip diagnostics for speed
178
+ });
179
+ const moduleInfo = {
240
180
  code: result.outputText,
241
181
  map: result.sourceMapText,
242
- dependencies,
243
- lastModified: stat.mtimeMs,
244
- hash: currentHash
182
+ hash,
183
+ timestamp: Date.now(),
184
+ dependencies
245
185
  };
246
- this.moduleCache.set(absolutePath, compiled);
186
+ this.moduleCache.set(absolutePath, moduleInfo);
247
187
  if (this.options.verbose) {
248
- logger_manager_js_1.loggerManager.printLine(`Compiled ${path_1.default.relative(process.cwd(), filePath)} (${dependencies.size} dependencies)`, 'info');
188
+ logger_manager_js_1.loggerManager.printLine(`Compiled ${path_1.default.relative(process.cwd(), filePath)}`, 'info');
249
189
  }
250
- return compiled;
190
+ return moduleInfo;
251
191
  }
252
192
  catch (error) {
253
- logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.red(figures_1.default.cross)} Compilation error in ${path_1.default.relative(process.cwd(), filePath)}: ${error.message}`, 'error');
193
+ logger_manager_js_1.loggerManager.printLine(`Compilation error: ${error.message}`, 'error');
254
194
  throw error;
255
195
  }
256
196
  }
257
- createTempFile(compiled, originalPath) {
258
- const tempDir = path_1.default.join(process.cwd(), '.neex-temp');
259
- if (!fs_1.default.existsSync(tempDir)) {
260
- fs_1.default.mkdirSync(tempDir, { recursive: true });
197
+ invalidateModuleCache(filePath) {
198
+ const absolutePath = path_1.default.resolve(filePath);
199
+ // Remove the file itself
200
+ this.moduleCache.delete(absolutePath);
201
+ // Remove any modules that depend on this file
202
+ const toRemove = [];
203
+ for (const [cachedPath, info] of this.moduleCache.entries()) {
204
+ if (info.dependencies.includes(absolutePath)) {
205
+ toRemove.push(cachedPath);
206
+ }
207
+ }
208
+ for (const pathToRemove of toRemove) {
209
+ this.moduleCache.delete(pathToRemove);
261
210
  }
262
- const baseName = path_1.default.basename(originalPath, path_1.default.extname(originalPath));
263
- const tempFile = path_1.default.join(tempDir, `${baseName}-${Date.now()}-${Math.random().toString(36).substr(2, 9)}.js`);
264
- let code = compiled.code;
265
- // Handle source maps
266
- if (compiled.map && this.options.sourceMaps) {
211
+ if (this.options.verbose && toRemove.length > 0) {
212
+ logger_manager_js_1.loggerManager.printLine(`Invalidated ${toRemove.length + 1} modules`, 'info');
213
+ }
214
+ }
215
+ createExecutableFile() {
216
+ // Always force recompile the main file
217
+ const mainModule = this.compileModule(this.options.file, true);
218
+ // Create a unique temp file
219
+ const timestamp = Date.now();
220
+ const random = Math.random().toString(36).substr(2, 9);
221
+ const tempFile = path_1.default.join(this.tempDir, `main-${timestamp}-${random}.js`);
222
+ let code = mainModule.code;
223
+ // Add source map support
224
+ if (mainModule.map && this.options.sourceMaps) {
267
225
  const mapFile = tempFile + '.map';
268
- fs_1.default.writeFileSync(mapFile, compiled.map);
226
+ fs_1.default.writeFileSync(mapFile, mainModule.map);
269
227
  code += `\n//# sourceMappingURL=${path_1.default.basename(mapFile)}`;
270
228
  }
271
229
  fs_1.default.writeFileSync(tempFile, code);
272
- return tempFile;
273
- }
274
- cleanupTempFiles() {
275
- const tempDir = path_1.default.join(process.cwd(), '.neex-temp');
276
- if (fs_1.default.existsSync(tempDir)) {
230
+ // Clean up old temp file
231
+ if (this.currentTempFile && fs_1.default.existsSync(this.currentTempFile)) {
277
232
  try {
278
- const files = fs_1.default.readdirSync(tempDir);
279
- for (const file of files) {
280
- const filePath = path_1.default.join(tempDir, file);
281
- try {
282
- fs_1.default.unlinkSync(filePath);
283
- }
284
- catch (error) {
285
- // Ignore individual file errors
286
- }
233
+ fs_1.default.unlinkSync(this.currentTempFile);
234
+ const mapFile = this.currentTempFile + '.map';
235
+ if (fs_1.default.existsSync(mapFile)) {
236
+ fs_1.default.unlinkSync(mapFile);
287
237
  }
288
- fs_1.default.rmdirSync(tempDir);
289
238
  }
290
239
  catch (error) {
291
240
  // Ignore cleanup errors
292
241
  }
293
242
  }
294
- }
295
- invalidateCache(filePath) {
296
- const absolutePath = path_1.default.resolve(filePath);
297
- // Remove from cache
298
- const removed = this.moduleCache.delete(absolutePath);
299
- if (this.options.verbose && removed) {
300
- logger_manager_js_1.loggerManager.printLine(`Invalidated cache for ${path_1.default.relative(process.cwd(), filePath)}`, 'info');
301
- }
302
- // Remove dependent modules from cache
303
- const dependents = [];
304
- for (const [cachedPath, module] of this.moduleCache.entries()) {
305
- if (module.dependencies.has(absolutePath)) {
306
- this.moduleCache.delete(cachedPath);
307
- dependents.push(cachedPath);
308
- }
309
- }
310
- if (this.options.verbose && dependents.length > 0) {
311
- logger_manager_js_1.loggerManager.printLine(`Invalidated ${dependents.length} dependent modules`, 'info');
312
- }
243
+ this.currentTempFile = tempFile;
244
+ return tempFile;
313
245
  }
314
246
  async getExecuteCommand() {
315
247
  if (this.options.execCommand) {
316
248
  const parts = this.options.execCommand.split(' ');
317
- return { command: parts[0], args: [...parts.slice(1)] };
249
+ return { command: parts[0], args: parts.slice(1) };
318
250
  }
319
- // Always recompile the main file to ensure fresh execution
320
- this.invalidateCache(this.options.file);
321
- // Compile TypeScript file
322
- const compiled = this.compileTypeScript(this.options.file);
323
- const tempFile = this.createTempFile(compiled, this.options.file);
324
- const args = [...this.options.nodeArgs, tempFile];
325
- if (this.options.inspect) {
251
+ const executableFile = this.createExecutableFile();
252
+ const args = [...this.options.nodeArgs, executableFile];
253
+ // Add Node.js flags
254
+ if (this.options.inspect)
326
255
  args.unshift('--inspect');
327
- }
328
- if (this.options.inspectBrk) {
256
+ if (this.options.inspectBrk)
329
257
  args.unshift('--inspect-brk');
330
- }
331
- // Enable source map support
332
- if (this.options.sourceMaps) {
258
+ if (this.options.sourceMaps)
333
259
  args.unshift('--enable-source-maps');
334
- }
335
260
  return { command: 'node', args };
336
261
  }
337
262
  clearConsole() {
338
263
  if (this.options.clearConsole && process.stdout.isTTY) {
339
- process.stdout.write('\x1b[2J\x1b[0f');
264
+ process.stdout.write('\x1Bc'); // Clear screen and scrollback
340
265
  }
341
266
  }
342
267
  async startProcess() {
343
268
  var _a, _b;
344
- if (this.process) {
269
+ if (this.process)
345
270
  return;
346
- }
347
271
  this.loadEnvFile();
348
272
  try {
349
273
  const { command, args } = await this.getExecuteCommand();
350
- if (this.options.verbose) {
351
- logger_manager_js_1.loggerManager.printLine(`Executing: ${command} ${args.join(' ')}`, 'info');
352
- }
353
274
  this.process = (0, child_process_1.spawn)(command, args, {
354
275
  stdio: ['ignore', 'pipe', 'pipe'],
355
- shell: false,
356
276
  env: {
357
277
  ...process.env,
358
278
  NODE_ENV: process.env.NODE_ENV || 'development',
359
279
  FORCE_COLOR: this.options.color ? '1' : '0',
360
- TS_NODE_DEV: '1',
361
- NEEX_DEV: '1'
280
+ NODE_OPTIONS: '--max-old-space-size=4096', // Prevent memory issues
362
281
  },
363
- detached: true
282
+ detached: false // Keep attached for better cleanup
364
283
  });
365
284
  this.startTime = new Date();
366
285
  this.restartCount++;
367
286
  if (!this.options.quiet) {
368
287
  const timestamp = new Date().toLocaleTimeString();
369
- logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.green(figures_1.default.play)} Started ${chalk_1.default.cyan(path_1.default.relative(process.cwd(), this.options.file))} ${chalk_1.default.dim(`(#${this.restartCount} - ${timestamp})`)}`, 'info');
288
+ const fileRelative = path_1.default.relative(process.cwd(), this.options.file);
289
+ logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.green('▶')} ${chalk_1.default.cyan(fileRelative)} ${chalk_1.default.dim(`#${this.restartCount} ${timestamp}`)}`, 'info');
370
290
  }
291
+ // Handle stdout/stderr
371
292
  (_a = this.process.stdout) === null || _a === void 0 ? void 0 : _a.on('data', (data) => {
372
- if (!this.options.quiet) {
373
- process.stdout.write(data);
374
- }
293
+ process.stdout.write(data);
375
294
  });
376
295
  (_b = this.process.stderr) === null || _b === void 0 ? void 0 : _b.on('data', (data) => {
377
- if (!this.options.quiet) {
378
- process.stderr.write(data);
379
- }
296
+ process.stderr.write(data);
380
297
  });
381
298
  this.process.on('error', (error) => {
382
- logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.red(figures_1.default.cross)} Process error: ${error.message}`, 'error');
299
+ logger_manager_js_1.loggerManager.printLine(`Process error: ${error.message}`, 'error');
383
300
  });
384
301
  this.process.on('exit', (code, signal) => {
385
302
  if (this.process) {
386
303
  this.process = null;
387
- if (!this.isRestarting) {
388
- if (code !== 0) {
389
- const duration = this.startTime ? Date.now() - this.startTime.getTime() : 0;
390
- logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.red(figures_1.default.cross)} Process exited with code ${code} after ${duration}ms`, 'error');
391
- }
304
+ if (!this.isRestarting && code !== 0) {
305
+ const duration = this.startTime ? Date.now() - this.startTime.getTime() : 0;
306
+ logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.red('✖')} Process exited with code ${code} (${duration}ms)`, 'error');
392
307
  }
393
308
  }
394
309
  });
395
310
  }
396
311
  catch (error) {
397
- logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.red(figures_1.default.cross)} Failed to start process: ${error.message}`, 'error');
312
+ logger_manager_js_1.loggerManager.printLine(`Failed to start: ${error.message}`, 'error');
398
313
  throw error;
399
314
  }
400
315
  }
401
316
  async stopProcess() {
402
- if (!this.process) {
317
+ if (!this.process)
403
318
  return;
404
- }
405
319
  return new Promise((resolve) => {
406
- if (!this.process) {
407
- resolve();
408
- return;
409
- }
410
320
  const proc = this.process;
411
321
  this.process = null;
412
322
  const cleanup = () => {
413
- if (!this.options.quiet) {
414
- logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.yellow(figures_1.default.square)} Process stopped`, 'info');
415
- }
416
- this.cleanupTempFiles();
417
323
  resolve();
418
324
  };
419
325
  proc.on('exit', cleanup);
420
326
  proc.on('error', cleanup);
421
327
  try {
422
- if (proc.pid) {
423
- // Kill process group
424
- process.kill(-proc.pid, 'SIGTERM');
425
- // Fallback after timeout
426
- setTimeout(() => {
427
- if (proc.pid && !proc.killed) {
428
- try {
429
- process.kill(-proc.pid, 'SIGKILL');
430
- }
431
- catch (e) {
432
- // Ignore
433
- }
434
- }
435
- }, 2000);
436
- }
328
+ proc.kill('SIGTERM');
329
+ // Force kill after timeout
330
+ setTimeout(() => {
331
+ if (!proc.killed) {
332
+ proc.kill('SIGKILL');
333
+ }
334
+ }, 1000);
437
335
  }
438
336
  catch (error) {
439
- // Process might already be dead
440
337
  cleanup();
441
338
  }
442
339
  });
443
340
  }
444
341
  async restart() {
445
- if (this.isRestarting) {
342
+ if (this.isRestarting)
446
343
  return;
447
- }
448
344
  this.isRestarting = true;
449
- if (this.options.clearConsole) {
450
- this.clearConsole();
451
- }
345
+ // Clear console immediately for better UX
346
+ this.clearConsole();
452
347
  if (!this.options.quiet) {
453
- logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.yellow(figures_1.default.arrowRight)} Restarting due to changes...`, 'info');
348
+ logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.yellow('⟳')} Restarting...`, 'info');
454
349
  }
350
+ // Stop current process
455
351
  await this.stopProcess();
456
- // Small delay to ensure cleanup
457
- await new Promise(resolve => setTimeout(resolve, 50));
352
+ // Start new process
458
353
  await this.startProcess();
459
354
  this.isRestarting = false;
460
355
  }
461
356
  setupWatcher() {
462
357
  const watchPatterns = this.options.watch;
358
+ // Optimized ignore patterns
463
359
  const ignored = [
464
- '**/node_modules/**',
465
- '**/.git/**',
466
- '**/dist/**',
467
- '**/build/**',
468
- '**/.neex-temp/**',
360
+ 'node_modules/**',
361
+ '.git/**',
362
+ 'dist/**',
363
+ 'build/**',
364
+ '.neex-temp/**',
469
365
  '**/*.log',
470
366
  '**/*.d.ts',
471
367
  '**/*.map',
472
- ...this.options.ignore.map(pattern => `**/${pattern}/**`)
368
+ '**/*.tsbuildinfo',
369
+ ...this.options.ignore
473
370
  ];
474
371
  this.watcher = (0, chokidar_1.watch)(watchPatterns, {
475
372
  ignored,
476
373
  ignoreInitial: true,
477
374
  followSymlinks: false,
478
375
  usePolling: false,
479
- atomic: 100,
376
+ atomic: 50,
480
377
  awaitWriteFinish: {
481
- stabilityThreshold: 50,
482
- pollInterval: 25
378
+ stabilityThreshold: 100,
379
+ pollInterval: 50
483
380
  }
484
381
  });
485
382
  this.watcher.on('change', (filePath) => {
486
- this.invalidateCache(filePath);
383
+ this.invalidateModuleCache(filePath);
487
384
  if (this.options.verbose) {
488
- logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.blue(figures_1.default.info)} File changed: ${path_1.default.relative(process.cwd(), filePath)}`, 'info');
385
+ logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.blue('●')} ${path_1.default.relative(process.cwd(), filePath)}`, 'info');
489
386
  }
490
387
  this.debouncedRestart();
491
388
  });
492
389
  this.watcher.on('add', (filePath) => {
493
390
  if (this.options.verbose) {
494
- logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.green('+')} File added: ${path_1.default.relative(process.cwd(), filePath)}`, 'info');
391
+ logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.green('+')} ${path_1.default.relative(process.cwd(), filePath)}`, 'info');
495
392
  }
496
393
  this.debouncedRestart();
497
394
  });
498
395
  this.watcher.on('unlink', (filePath) => {
499
- this.invalidateCache(filePath);
396
+ this.invalidateModuleCache(filePath);
500
397
  if (this.options.verbose) {
501
- logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.red('-')} File removed: ${path_1.default.relative(process.cwd(), filePath)}`, 'info');
398
+ logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.red('-')} ${path_1.default.relative(process.cwd(), filePath)}`, 'info');
502
399
  }
503
400
  this.debouncedRestart();
504
401
  });
505
402
  this.watcher.on('error', (error) => {
506
- logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.red(figures_1.default.cross)} Watcher error: ${error.message}`, 'error');
403
+ logger_manager_js_1.loggerManager.printLine(`Watcher error: ${error.message}`, 'error');
507
404
  });
508
- if (this.options.verbose) {
509
- logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.dim(figures_1.default.info)} Watching: ${watchPatterns.join(', ')}`, 'info');
510
- logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.dim(figures_1.default.info)} Ignoring: ${ignored.join(', ')}`, 'info');
511
- }
512
405
  }
513
406
  async start() {
514
- // Check if target file exists
515
407
  if (!fs_1.default.existsSync(this.options.file)) {
516
408
  throw new Error(`Target file not found: ${this.options.file}`);
517
409
  }
518
- // Validate TypeScript file
519
410
  const ext = path_1.default.extname(this.options.file);
520
411
  if (!['.ts', '.tsx', '.js', '.jsx'].includes(ext)) {
521
412
  throw new Error(`Unsupported file extension: ${ext}`);
522
413
  }
523
- logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.blue(figures_1.default.info)} Starting TypeScript development server...`, 'info');
524
- // Show configuration in verbose mode
525
- if (this.options.verbose) {
526
- logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.dim('Target file:')} ${this.options.file}`, 'info');
527
- logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.dim('Watch patterns:')} ${this.options.watch.join(', ')}`, 'info');
528
- logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.dim('Restart delay:')} ${this.options.delay}ms`, 'info');
529
- logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.dim('Transpile only:')} ${this.options.transpileOnly}`, 'info');
530
- logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.dim('Source maps:')} ${this.options.sourceMaps}`, 'info');
531
- }
532
414
  // Clear any existing cache
533
415
  this.moduleCache.clear();
416
+ this.setupTempDir();
417
+ if (!this.options.quiet) {
418
+ logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.blue('⚡')} Starting dev server...`, 'info');
419
+ }
534
420
  this.setupWatcher();
535
421
  await this.startProcess();
536
- logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.green(figures_1.default.tick)} TypeScript development server started. Watching for changes...`, 'info');
422
+ if (!this.options.quiet) {
423
+ logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.green('✓')} Watching for changes...`, 'info');
424
+ }
537
425
  }
538
426
  async stop() {
539
- logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.yellow(figures_1.default.warning)} Stopping development server...`, 'info');
427
+ if (!this.options.quiet) {
428
+ logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.yellow('⏹')} Stopping dev server...`, 'info');
429
+ }
540
430
  if (this.watcher) {
541
431
  await this.watcher.close();
542
432
  this.watcher = null;
543
433
  }
544
434
  await this.stopProcess();
545
- // Clear cache on stop
546
- this.moduleCache.clear();
547
- if (this.restartCount > 0) {
548
- logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.blue(figures_1.default.info)} Development server stopped after ${this.restartCount} restart(s)`, 'info');
435
+ // Cleanup temp files
436
+ if (fs_1.default.existsSync(this.tempDir)) {
437
+ try {
438
+ fs_1.default.rmSync(this.tempDir, { recursive: true, force: true });
439
+ }
440
+ catch (error) {
441
+ // Ignore cleanup errors
442
+ }
549
443
  }
444
+ this.moduleCache.clear();
550
445
  }
551
446
  }
552
447
  exports.DevManager = DevManager;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "neex",
3
- "version": "0.6.85",
3
+ "version": "0.6.87",
4
4
  "description": "The Modern Build System for Polyrepo-in-Monorepo Architecture",
5
5
  "main": "dist/src/index.js",
6
6
  "types": "dist/src/index.d.ts",