neex 0.6.75 → 0.6.81

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,16 +7,17 @@ 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"));
10
11
  function addDevCommands(program) {
11
12
  let devManager = null;
12
- // Dev command for hot reloading development
13
+ // Enhanced dev command with built-in TypeScript compilation
13
14
  program
14
15
  .command('dev [file]')
15
- .description('Start development server with hot reloading (default: src/index.ts)')
16
+ .description('Start TypeScript development server with hot reloading (default: src/index.ts)')
16
17
  .option('-w, --watch <patterns>', 'Watch additional 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 (comma-separated)', 'ts,js,json')
19
- .option('-d, --delay <ms>', 'Delay before restart (ms)', parseInt, 1000)
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, 800)
20
21
  .option('-c, --no-color', 'Disable colored output')
21
22
  .option('-q, --quiet', 'Reduce output verbosity')
22
23
  .option('-v, --verbose', 'Verbose output')
@@ -24,11 +25,25 @@ function addDevCommands(program) {
24
25
  .option('--inspect', 'Enable Node.js inspector')
25
26
  .option('--inspect-brk', 'Enable Node.js inspector with break')
26
27
  .option('--env <file>', 'Load environment variables from file', '.env')
27
- .option('--exec <command>', 'Command to execute instead of tsx')
28
+ .option('--exec <command>', 'Command to execute instead of built-in TypeScript compilation')
29
+ .option('--tsconfig <path>', 'Path to TypeScript configuration file')
30
+ .option('--no-source-maps', 'Disable source maps')
31
+ .option('--transpile-only', 'Skip type checking for faster compilation')
32
+ .option('--node-args <args>', 'Additional Node.js arguments (comma-separated)', '')
28
33
  .action(async (file, options) => {
29
34
  try {
30
35
  const targetFile = file || 'src/index.ts';
31
- logger_manager_js_1.loggerManager.printLine(`Starting development server for ${chalk_1.default.cyan(targetFile)}`, 'info');
36
+ if (!options.quiet) {
37
+ 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');
38
+ if (options.verbose) {
39
+ logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.dim('Features:')}`, 'info');
40
+ logger_manager_js_1.loggerManager.printLine(` ${chalk_1.default.green('✓')} Built-in TypeScript compilation`, 'info');
41
+ logger_manager_js_1.loggerManager.printLine(` ${chalk_1.default.green('✓')} Hot reloading with intelligent caching`, 'info');
42
+ logger_manager_js_1.loggerManager.printLine(` ${chalk_1.default.green('✓')} Source map support`, 'info');
43
+ logger_manager_js_1.loggerManager.printLine(` ${chalk_1.default.green('✓')} Fast transpilation mode`, 'info');
44
+ logger_manager_js_1.loggerManager.printLine(` ${chalk_1.default.green('✓')} Dependency tracking`, 'info');
45
+ }
46
+ }
32
47
  devManager = new dev_manager_js_1.DevManager({
33
48
  file: targetFile,
34
49
  watch: options.watch.split(',').map((p) => p.trim()),
@@ -42,20 +57,68 @@ function addDevCommands(program) {
42
57
  inspect: options.inspect,
43
58
  inspectBrk: options.inspectBrk,
44
59
  envFile: options.env,
45
- execCommand: options.exec
60
+ execCommand: options.exec,
61
+ tsConfig: options.tsconfig,
62
+ sourceMaps: options.sourceMaps,
63
+ transpileOnly: options.transpileOnly,
64
+ nodeArgs: options.nodeArgs ? options.nodeArgs.split(',').map((arg) => arg.trim()) : []
46
65
  });
47
66
  await devManager.start();
48
67
  }
49
68
  catch (error) {
50
69
  if (error instanceof Error) {
51
- logger_manager_js_1.loggerManager.printLine(`Development server error: ${error.message}`, 'error');
70
+ logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.red(figures_1.default.cross)} Development server error: ${error.message}`, 'error');
52
71
  }
53
72
  else {
54
- logger_manager_js_1.loggerManager.printLine('An unknown development server error occurred', 'error');
73
+ logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.red(figures_1.default.cross)} An unknown development server error occurred`, 'error');
55
74
  }
56
75
  process.exit(1);
57
76
  }
58
77
  });
78
+ // Additional helper commands
79
+ program
80
+ .command('dev:clean')
81
+ .description('Clean development server cache and temporary files')
82
+ .action(() => {
83
+ const path = require('path');
84
+ const fs = require('fs');
85
+ const tempDir = path.join(process.cwd(), '.neex-temp');
86
+ if (fs.existsSync(tempDir)) {
87
+ fs.rmSync(tempDir, { recursive: true, force: true });
88
+ logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.green(figures_1.default.tick)} Cleaned development cache`, 'info');
89
+ }
90
+ else {
91
+ logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.yellow(figures_1.default.info)} No cache to clean`, 'info');
92
+ }
93
+ });
94
+ program
95
+ .command('dev:check')
96
+ .description('Check TypeScript configuration and dependencies')
97
+ .option('--tsconfig <path>', 'Path to TypeScript configuration file')
98
+ .action((options) => {
99
+ const path = require('path');
100
+ const fs = require('fs');
101
+ const configPath = options.tsconfig || 'tsconfig.json';
102
+ if (!fs.existsSync(configPath)) {
103
+ logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.red(figures_1.default.cross)} TypeScript config not found: ${configPath}`, 'error');
104
+ process.exit(1);
105
+ }
106
+ try {
107
+ const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
108
+ logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.green(figures_1.default.tick)} TypeScript config is valid`, 'info');
109
+ if (config.compilerOptions) {
110
+ logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.dim('Compiler Options:')}`, 'info');
111
+ logger_manager_js_1.loggerManager.printLine(` Target: ${config.compilerOptions.target || 'default'}`, 'info');
112
+ logger_manager_js_1.loggerManager.printLine(` Module: ${config.compilerOptions.module || 'default'}`, 'info');
113
+ logger_manager_js_1.loggerManager.printLine(` Strict: ${config.compilerOptions.strict || 'false'}`, 'info');
114
+ logger_manager_js_1.loggerManager.printLine(` Source Maps: ${config.compilerOptions.sourceMap || 'false'}`, 'info');
115
+ }
116
+ }
117
+ catch (error) {
118
+ logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.red(figures_1.default.cross)} Invalid TypeScript config: ${error.message}`, 'error');
119
+ process.exit(1);
120
+ }
121
+ });
59
122
  // Cleanup function
60
123
  const cleanupDev = () => {
61
124
  if (devManager) {
@@ -63,6 +126,21 @@ function addDevCommands(program) {
63
126
  devManager = null;
64
127
  }
65
128
  };
129
+ // Handle process termination
130
+ process.on('SIGINT', () => {
131
+ if (devManager) {
132
+ logger_manager_js_1.loggerManager.printLine(`\n${chalk_1.default.yellow(figures_1.default.warning)} Received SIGINT, shutting down gracefully...`, 'info');
133
+ cleanupDev();
134
+ process.exit(0);
135
+ }
136
+ });
137
+ process.on('SIGTERM', () => {
138
+ if (devManager) {
139
+ logger_manager_js_1.loggerManager.printLine(`\n${chalk_1.default.yellow(figures_1.default.warning)} Received SIGTERM, shutting down gracefully...`, 'info');
140
+ cleanupDev();
141
+ process.exit(0);
142
+ }
143
+ });
66
144
  return { cleanupDev };
67
145
  }
68
146
  exports.addDevCommands = addDevCommands;
@@ -27,7 +27,7 @@ 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 - Development server manager with hot reloading
30
+ // src/dev-manager.ts - Enhanced TypeScript development server with built-in compilation
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");
@@ -36,19 +36,7 @@ const figures_1 = __importDefault(require("figures"));
36
36
  const path_1 = __importDefault(require("path"));
37
37
  const fs_1 = __importDefault(require("fs"));
38
38
  const lodash_1 = require("lodash");
39
- async function isCommandAvailable(command) {
40
- try {
41
- const { exec } = await Promise.resolve().then(() => __importStar(require('child_process')));
42
- return new Promise((resolve) => {
43
- exec(`command -v ${command}`, (error) => {
44
- resolve(!error);
45
- });
46
- });
47
- }
48
- catch (e) {
49
- return false;
50
- }
51
- }
39
+ const ts = __importStar(require("typescript"));
52
40
  class DevManager {
53
41
  constructor(options) {
54
42
  this.process = null;
@@ -56,50 +44,201 @@ class DevManager {
56
44
  this.isRestarting = false;
57
45
  this.restartCount = 0;
58
46
  this.startTime = null;
47
+ this.moduleCache = new Map();
48
+ this.fileWatcher = new Map();
59
49
  this.options = options;
60
50
  this.debouncedRestart = (0, lodash_1.debounce)(this.restart.bind(this), options.delay);
51
+ this.tsCompilerOptions = this.loadTsConfig();
52
+ }
53
+ loadTsConfig() {
54
+ const configPath = this.options.tsConfig || 'tsconfig.json';
55
+ const defaultOptions = {
56
+ target: ts.ScriptTarget.ES2022,
57
+ module: ts.ModuleKind.CommonJS,
58
+ moduleResolution: ts.ModuleResolutionKind.NodeJs,
59
+ allowJs: true,
60
+ outDir: undefined,
61
+ rootDir: undefined,
62
+ strict: false,
63
+ esModuleInterop: true,
64
+ skipLibCheck: true,
65
+ forceConsistentCasingInFileNames: true,
66
+ resolveJsonModule: true,
67
+ declaration: false,
68
+ sourceMap: this.options.sourceMaps,
69
+ inlineSourceMap: false,
70
+ inlineSources: false,
71
+ };
72
+ if (fs_1.default.existsSync(configPath)) {
73
+ try {
74
+ 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
+ // Override some options for development
85
+ const options = { ...parsedConfig.options, ...defaultOptions };
86
+ if (this.options.verbose) {
87
+ logger_manager_js_1.loggerManager.printLine(`Loaded TypeScript config from ${configPath}`, 'info');
88
+ }
89
+ return options;
90
+ }
91
+ catch (error) {
92
+ logger_manager_js_1.loggerManager.printLine(`Failed to load tsconfig.json: ${error.message}`, 'warn');
93
+ }
94
+ }
95
+ return defaultOptions;
61
96
  }
62
97
  loadEnvFile() {
63
98
  if (this.options.envFile && fs_1.default.existsSync(this.options.envFile)) {
64
99
  try {
65
100
  const envContent = fs_1.default.readFileSync(this.options.envFile, 'utf8');
66
101
  const lines = envContent.split('\n');
102
+ let loadedCount = 0;
67
103
  for (const line of lines) {
68
104
  const trimmed = line.trim();
69
105
  if (trimmed && !trimmed.startsWith('#')) {
70
106
  const [key, ...values] = trimmed.split('=');
71
107
  if (key && values.length > 0) {
72
- process.env[key.trim()] = values.join('=').trim();
108
+ process.env[key.trim()] = values.join('=').trim().replace(/^["']|["']$/g, '');
109
+ loadedCount++;
73
110
  }
74
111
  }
75
112
  }
76
- if (this.options.verbose) {
77
- logger_manager_js_1.loggerManager.printLine(`Loaded environment variables from ${this.options.envFile}`, 'info');
113
+ if (!this.options.quiet && loadedCount > 0) {
114
+ 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');
115
+ }
116
+ else if (this.options.verbose) {
117
+ logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.dim(figures_1.default.info)} No env variables found in ${this.options.envFile}`, 'info');
78
118
  }
79
119
  }
80
120
  catch (error) {
81
- logger_manager_js_1.loggerManager.printLine(`Failed to load environment file ${this.options.envFile}: ${error.message}`, 'warn');
121
+ logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.yellow(figures_1.default.warning)} Failed to load ${this.options.envFile}: ${error.message}`, 'warn');
122
+ }
123
+ }
124
+ }
125
+ compileTypeScript(filePath) {
126
+ const absolutePath = path_1.default.resolve(filePath);
127
+ // Check cache first
128
+ const cached = this.moduleCache.get(absolutePath);
129
+ if (cached && !this.options.transpileOnly) {
130
+ return cached;
131
+ }
132
+ try {
133
+ const sourceCode = fs_1.default.readFileSync(absolutePath, 'utf8');
134
+ const dependencies = new Set();
135
+ // Extract import/require dependencies
136
+ const importRegex = /(?:import|require)\s*(?:\(.*?\)|.*?from\s+)['"`]([^'"`]+)['"`]/g;
137
+ let match;
138
+ while ((match = importRegex.exec(sourceCode)) !== null) {
139
+ if (!match[1].startsWith('.'))
140
+ continue;
141
+ const depPath = path_1.default.resolve(path_1.default.dirname(absolutePath), match[1]);
142
+ dependencies.add(depPath);
143
+ }
144
+ let result;
145
+ if (this.options.transpileOnly) {
146
+ // Fast transpile without type checking
147
+ result = ts.transpileModule(sourceCode, {
148
+ compilerOptions: this.tsCompilerOptions,
149
+ fileName: absolutePath,
150
+ reportDiagnostics: false
151
+ });
152
+ }
153
+ else {
154
+ // Full compilation with type checking
155
+ const program = ts.createProgram([absolutePath], this.tsCompilerOptions);
156
+ const sourceFile = program.getSourceFile(absolutePath);
157
+ if (!sourceFile) {
158
+ throw new Error(`Could not load source file: ${absolutePath}`);
159
+ }
160
+ // Check for errors
161
+ const diagnostics = ts.getPreEmitDiagnostics(program, sourceFile);
162
+ if (diagnostics.length > 0) {
163
+ const errors = diagnostics.map(diagnostic => {
164
+ const message = ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n');
165
+ if (diagnostic.file && diagnostic.start !== undefined) {
166
+ const { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start);
167
+ return `${path_1.default.relative(process.cwd(), diagnostic.file.fileName)}:${line + 1}:${character + 1} - ${message}`;
168
+ }
169
+ return message;
170
+ });
171
+ logger_manager_js_1.loggerManager.printLine(`TypeScript compilation errors:\n${errors.join('\n')}`, 'error');
172
+ if (!this.options.quiet) {
173
+ process.exit(1);
174
+ }
175
+ }
176
+ result = ts.transpileModule(sourceCode, {
177
+ compilerOptions: this.tsCompilerOptions,
178
+ fileName: absolutePath,
179
+ reportDiagnostics: true
180
+ });
181
+ }
182
+ const compiled = {
183
+ code: result.outputText,
184
+ map: result.sourceMapText,
185
+ dependencies
186
+ };
187
+ this.moduleCache.set(absolutePath, compiled);
188
+ return compiled;
189
+ }
190
+ catch (error) {
191
+ logger_manager_js_1.loggerManager.printLine(`Compilation error in ${filePath}: ${error.message}`, 'error');
192
+ throw error;
193
+ }
194
+ }
195
+ createTempFile(compiled, originalPath) {
196
+ const tempDir = path_1.default.join(process.cwd(), '.neex-temp');
197
+ if (!fs_1.default.existsSync(tempDir)) {
198
+ fs_1.default.mkdirSync(tempDir, { recursive: true });
199
+ }
200
+ const tempFile = path_1.default.join(tempDir, `${path_1.default.basename(originalPath, path_1.default.extname(originalPath))}-${Date.now()}.js`);
201
+ let code = compiled.code;
202
+ // Handle source maps
203
+ if (compiled.map && this.options.sourceMaps) {
204
+ const mapFile = tempFile + '.map';
205
+ fs_1.default.writeFileSync(mapFile, compiled.map);
206
+ code += `\n//# sourceMappingURL=${path_1.default.basename(mapFile)}`;
207
+ }
208
+ fs_1.default.writeFileSync(tempFile, code);
209
+ return tempFile;
210
+ }
211
+ cleanupTempFiles() {
212
+ const tempDir = path_1.default.join(process.cwd(), '.neex-temp');
213
+ if (fs_1.default.existsSync(tempDir)) {
214
+ try {
215
+ fs_1.default.rmSync(tempDir, { recursive: true, force: true });
216
+ }
217
+ catch (error) {
218
+ // Ignore cleanup errors
82
219
  }
83
220
  }
84
221
  }
85
222
  async getExecuteCommand() {
86
223
  if (this.options.execCommand) {
87
224
  const parts = this.options.execCommand.split(' ');
88
- return { command: parts[0], args: [...parts.slice(1), this.options.file] };
89
- }
90
- // Default to tsx for TypeScript files
91
- const tsxExists = await isCommandAvailable('tsx');
92
- if (!tsxExists) {
93
- throw new Error('`tsx` command not found. Please install `tsx`');
225
+ return { command: parts[0], args: [...parts.slice(1)] };
94
226
  }
95
- const args = [this.options.file];
227
+ // Compile TypeScript file
228
+ const compiled = this.compileTypeScript(this.options.file);
229
+ const tempFile = this.createTempFile(compiled, this.options.file);
230
+ const args = [...this.options.nodeArgs, tempFile];
96
231
  if (this.options.inspect) {
97
232
  args.unshift('--inspect');
98
233
  }
99
234
  if (this.options.inspectBrk) {
100
235
  args.unshift('--inspect-brk');
101
236
  }
102
- return { command: 'tsx', args };
237
+ // Enable source map support
238
+ if (this.options.sourceMaps) {
239
+ args.unshift('--enable-source-maps');
240
+ }
241
+ return { command: 'node', args };
103
242
  }
104
243
  clearConsole() {
105
244
  if (this.options.clearConsole && process.stdout.isTTY) {
@@ -112,50 +251,58 @@ class DevManager {
112
251
  return;
113
252
  }
114
253
  this.loadEnvFile();
115
- const { command, args } = await this.getExecuteCommand();
116
- if (this.options.verbose) {
117
- logger_manager_js_1.loggerManager.printLine(`Executing: ${command} ${args.join(' ')}`, 'info');
118
- }
119
- this.process = (0, child_process_1.spawn)(command, args, {
120
- stdio: ['ignore', 'pipe', 'pipe'],
121
- shell: false,
122
- env: {
123
- ...process.env,
124
- NODE_ENV: process.env.NODE_ENV || 'development',
125
- FORCE_COLOR: this.options.color ? '1' : '0'
126
- },
127
- detached: true
128
- });
129
- this.startTime = new Date();
130
- this.restartCount++;
131
- if (!this.options.quiet) {
132
- const timestamp = new Date().toLocaleTimeString();
133
- 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');
134
- }
135
- (_a = this.process.stdout) === null || _a === void 0 ? void 0 : _a.on('data', (data) => {
136
- if (!this.options.quiet) {
137
- process.stdout.write(data);
254
+ try {
255
+ const { command, args } = await this.getExecuteCommand();
256
+ if (this.options.verbose) {
257
+ logger_manager_js_1.loggerManager.printLine(`Executing: ${command} ${args.join(' ')}`, 'info');
138
258
  }
139
- });
140
- (_b = this.process.stderr) === null || _b === void 0 ? void 0 : _b.on('data', (data) => {
259
+ this.process = (0, child_process_1.spawn)(command, args, {
260
+ stdio: ['ignore', 'pipe', 'pipe'],
261
+ shell: false,
262
+ env: {
263
+ ...process.env,
264
+ NODE_ENV: process.env.NODE_ENV || 'development',
265
+ FORCE_COLOR: this.options.color ? '1' : '0',
266
+ TS_NODE_DEV: '1',
267
+ NEEX_DEV: '1'
268
+ },
269
+ detached: true
270
+ });
271
+ this.startTime = new Date();
272
+ this.restartCount++;
141
273
  if (!this.options.quiet) {
142
- process.stderr.write(data);
274
+ const timestamp = new Date().toLocaleTimeString();
275
+ 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(`(${timestamp})`)}`, 'info');
143
276
  }
144
- });
145
- this.process.on('error', (error) => {
146
- logger_manager_js_1.loggerManager.printLine(`Process error: ${error.message}`, 'error');
147
- });
148
- this.process.on('exit', (code, signal) => {
149
- if (this.process) {
150
- this.process = null;
151
- if (!this.isRestarting) {
152
- if (code !== 0) {
153
- const duration = this.startTime ? Date.now() - this.startTime.getTime() : 0;
154
- logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.red(figures_1.default.cross)} Process exited with code ${code} after ${duration}ms`, 'error');
277
+ (_a = this.process.stdout) === null || _a === void 0 ? void 0 : _a.on('data', (data) => {
278
+ if (!this.options.quiet) {
279
+ process.stdout.write(data);
280
+ }
281
+ });
282
+ (_b = this.process.stderr) === null || _b === void 0 ? void 0 : _b.on('data', (data) => {
283
+ if (!this.options.quiet) {
284
+ process.stderr.write(data);
285
+ }
286
+ });
287
+ this.process.on('error', (error) => {
288
+ logger_manager_js_1.loggerManager.printLine(`Process error: ${error.message}`, 'error');
289
+ });
290
+ this.process.on('exit', (code, signal) => {
291
+ if (this.process) {
292
+ this.process = null;
293
+ if (!this.isRestarting) {
294
+ if (code !== 0) {
295
+ const duration = this.startTime ? Date.now() - this.startTime.getTime() : 0;
296
+ logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.red(figures_1.default.cross)} Process exited with code ${code} after ${duration}ms`, 'error');
297
+ }
155
298
  }
156
299
  }
157
- }
158
- });
300
+ });
301
+ }
302
+ catch (error) {
303
+ logger_manager_js_1.loggerManager.printLine(`Failed to start process: ${error.message}`, 'error');
304
+ throw error;
305
+ }
159
306
  }
160
307
  async stopProcess() {
161
308
  if (!this.process) {
@@ -172,6 +319,7 @@ class DevManager {
172
319
  if (!this.options.quiet) {
173
320
  logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.yellow(figures_1.default.square)} Stopped process`, 'info');
174
321
  }
322
+ this.cleanupTempFiles();
175
323
  resolve();
176
324
  };
177
325
  proc.on('exit', cleanup);
@@ -190,7 +338,7 @@ class DevManager {
190
338
  // Ignore
191
339
  }
192
340
  }
193
- }, 5000);
341
+ }, 3000);
194
342
  }
195
343
  }
196
344
  catch (error) {
@@ -199,6 +347,17 @@ class DevManager {
199
347
  }
200
348
  });
201
349
  }
350
+ invalidateCache(filePath) {
351
+ const absolutePath = path_1.default.resolve(filePath);
352
+ // Remove from cache
353
+ this.moduleCache.delete(absolutePath);
354
+ // Remove dependent modules from cache
355
+ for (const [cachedPath, module] of this.moduleCache.entries()) {
356
+ if (module.dependencies.has(absolutePath)) {
357
+ this.moduleCache.delete(cachedPath);
358
+ }
359
+ }
360
+ }
202
361
  async restart() {
203
362
  if (this.isRestarting) {
204
363
  return;
@@ -210,7 +369,11 @@ class DevManager {
210
369
  if (!this.options.quiet) {
211
370
  logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.yellow(figures_1.default.arrowRight)} Restarting due to changes...`, 'info');
212
371
  }
372
+ // Clear module cache
373
+ this.moduleCache.clear();
213
374
  await this.stopProcess();
375
+ // Small delay to ensure cleanup
376
+ await new Promise(resolve => setTimeout(resolve, 100));
214
377
  await this.startProcess();
215
378
  this.isRestarting = false;
216
379
  }
@@ -221,7 +384,9 @@ class DevManager {
221
384
  '**/.git/**',
222
385
  '**/dist/**',
223
386
  '**/build/**',
387
+ '**/.neex-temp/**',
224
388
  '**/*.log',
389
+ '**/*.d.ts',
225
390
  ...this.options.ignore.map(pattern => `**/${pattern}/**`)
226
391
  ];
227
392
  this.watcher = (0, chokidar_1.watch)(watchPatterns, {
@@ -232,6 +397,7 @@ class DevManager {
232
397
  atomic: 300
233
398
  });
234
399
  this.watcher.on('change', (filePath) => {
400
+ this.invalidateCache(filePath);
235
401
  if (this.options.verbose) {
236
402
  logger_manager_js_1.loggerManager.printLine(`File changed: ${path_1.default.relative(process.cwd(), filePath)}`, 'info');
237
403
  }
@@ -244,6 +410,7 @@ class DevManager {
244
410
  this.debouncedRestart();
245
411
  });
246
412
  this.watcher.on('unlink', (filePath) => {
413
+ this.invalidateCache(filePath);
247
414
  if (this.options.verbose) {
248
415
  logger_manager_js_1.loggerManager.printLine(`File removed: ${path_1.default.relative(process.cwd(), filePath)}`, 'info');
249
416
  }
@@ -262,16 +429,23 @@ class DevManager {
262
429
  if (!fs_1.default.existsSync(this.options.file)) {
263
430
  throw new Error(`Target file not found: ${this.options.file}`);
264
431
  }
265
- logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.blue(figures_1.default.info)} Starting development server...`, 'info');
432
+ // Validate TypeScript file
433
+ const ext = path_1.default.extname(this.options.file);
434
+ if (!['.ts', '.tsx', '.js', '.jsx'].includes(ext)) {
435
+ throw new Error(`Unsupported file extension: ${ext}`);
436
+ }
437
+ logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.blue(figures_1.default.info)} Starting TypeScript development server...`, 'info');
266
438
  // Show configuration in verbose mode
267
439
  if (this.options.verbose) {
268
440
  logger_manager_js_1.loggerManager.printLine(`Target file: ${this.options.file}`, 'info');
269
441
  logger_manager_js_1.loggerManager.printLine(`Watch patterns: ${this.options.watch.join(', ')}`, 'info');
270
442
  logger_manager_js_1.loggerManager.printLine(`Restart delay: ${this.options.delay}ms`, 'info');
443
+ logger_manager_js_1.loggerManager.printLine(`Transpile only: ${this.options.transpileOnly}`, 'info');
444
+ logger_manager_js_1.loggerManager.printLine(`Source maps: ${this.options.sourceMaps}`, 'info');
271
445
  }
272
446
  this.setupWatcher();
273
447
  await this.startProcess();
274
- logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.green(figures_1.default.tick)} Development server started. Watching for changes...`, 'info');
448
+ logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.green(figures_1.default.tick)} TypeScript development server started. Watching for changes...`, 'info');
275
449
  }
276
450
  async stop() {
277
451
  logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.yellow(figures_1.default.warning)} Stopping development server...`, 'info');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "neex",
3
- "version": "0.6.75",
3
+ "version": "0.6.81",
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",