neex 0.6.75 → 0.6.80

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,8 +44,55 @@ 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)) {
@@ -69,7 +104,7 @@ class DevManager {
69
104
  if (trimmed && !trimmed.startsWith('#')) {
70
105
  const [key, ...values] = trimmed.split('=');
71
106
  if (key && values.length > 0) {
72
- process.env[key.trim()] = values.join('=').trim();
107
+ process.env[key.trim()] = values.join('=').trim().replace(/^["']|["']$/g, '');
73
108
  }
74
109
  }
75
110
  }
@@ -82,24 +117,123 @@ class DevManager {
82
117
  }
83
118
  }
84
119
  }
120
+ compileTypeScript(filePath) {
121
+ const absolutePath = path_1.default.resolve(filePath);
122
+ // Check cache first
123
+ const cached = this.moduleCache.get(absolutePath);
124
+ if (cached && !this.options.transpileOnly) {
125
+ return cached;
126
+ }
127
+ try {
128
+ const sourceCode = fs_1.default.readFileSync(absolutePath, 'utf8');
129
+ const dependencies = new Set();
130
+ // Extract import/require dependencies
131
+ const importRegex = /(?:import|require)\s*(?:\(.*?\)|.*?from\s+)['"`]([^'"`]+)['"`]/g;
132
+ let match;
133
+ while ((match = importRegex.exec(sourceCode)) !== null) {
134
+ if (!match[1].startsWith('.'))
135
+ continue;
136
+ const depPath = path_1.default.resolve(path_1.default.dirname(absolutePath), match[1]);
137
+ dependencies.add(depPath);
138
+ }
139
+ let result;
140
+ if (this.options.transpileOnly) {
141
+ // Fast transpile without type checking
142
+ result = ts.transpileModule(sourceCode, {
143
+ compilerOptions: this.tsCompilerOptions,
144
+ fileName: absolutePath,
145
+ reportDiagnostics: false
146
+ });
147
+ }
148
+ else {
149
+ // Full compilation with type checking
150
+ const program = ts.createProgram([absolutePath], this.tsCompilerOptions);
151
+ const sourceFile = program.getSourceFile(absolutePath);
152
+ if (!sourceFile) {
153
+ throw new Error(`Could not load source file: ${absolutePath}`);
154
+ }
155
+ // Check for errors
156
+ const diagnostics = ts.getPreEmitDiagnostics(program, sourceFile);
157
+ if (diagnostics.length > 0) {
158
+ const errors = diagnostics.map(diagnostic => {
159
+ const message = ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n');
160
+ if (diagnostic.file && diagnostic.start !== undefined) {
161
+ const { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start);
162
+ return `${path_1.default.relative(process.cwd(), diagnostic.file.fileName)}:${line + 1}:${character + 1} - ${message}`;
163
+ }
164
+ return message;
165
+ });
166
+ logger_manager_js_1.loggerManager.printLine(`TypeScript compilation errors:\n${errors.join('\n')}`, 'error');
167
+ if (!this.options.quiet) {
168
+ process.exit(1);
169
+ }
170
+ }
171
+ result = ts.transpileModule(sourceCode, {
172
+ compilerOptions: this.tsCompilerOptions,
173
+ fileName: absolutePath,
174
+ reportDiagnostics: true
175
+ });
176
+ }
177
+ const compiled = {
178
+ code: result.outputText,
179
+ map: result.sourceMapText,
180
+ dependencies
181
+ };
182
+ this.moduleCache.set(absolutePath, compiled);
183
+ return compiled;
184
+ }
185
+ catch (error) {
186
+ logger_manager_js_1.loggerManager.printLine(`Compilation error in ${filePath}: ${error.message}`, 'error');
187
+ throw error;
188
+ }
189
+ }
190
+ createTempFile(compiled, originalPath) {
191
+ const tempDir = path_1.default.join(process.cwd(), '.neex-temp');
192
+ if (!fs_1.default.existsSync(tempDir)) {
193
+ fs_1.default.mkdirSync(tempDir, { recursive: true });
194
+ }
195
+ const tempFile = path_1.default.join(tempDir, `${path_1.default.basename(originalPath, path_1.default.extname(originalPath))}-${Date.now()}.js`);
196
+ let code = compiled.code;
197
+ // Handle source maps
198
+ if (compiled.map && this.options.sourceMaps) {
199
+ const mapFile = tempFile + '.map';
200
+ fs_1.default.writeFileSync(mapFile, compiled.map);
201
+ code += `\n//# sourceMappingURL=${path_1.default.basename(mapFile)}`;
202
+ }
203
+ fs_1.default.writeFileSync(tempFile, code);
204
+ return tempFile;
205
+ }
206
+ cleanupTempFiles() {
207
+ const tempDir = path_1.default.join(process.cwd(), '.neex-temp');
208
+ if (fs_1.default.existsSync(tempDir)) {
209
+ try {
210
+ fs_1.default.rmSync(tempDir, { recursive: true, force: true });
211
+ }
212
+ catch (error) {
213
+ // Ignore cleanup errors
214
+ }
215
+ }
216
+ }
85
217
  async getExecuteCommand() {
86
218
  if (this.options.execCommand) {
87
219
  const parts = this.options.execCommand.split(' ');
88
- return { command: parts[0], args: [...parts.slice(1), this.options.file] };
220
+ return { command: parts[0], args: [...parts.slice(1)] };
89
221
  }
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`');
94
- }
95
- const args = [this.options.file];
222
+ // Compile TypeScript file
223
+ const compiled = this.compileTypeScript(this.options.file);
224
+ const tempFile = this.createTempFile(compiled, this.options.file);
225
+ const args = [...this.options.nodeArgs, tempFile];
96
226
  if (this.options.inspect) {
97
227
  args.unshift('--inspect');
98
228
  }
99
229
  if (this.options.inspectBrk) {
100
230
  args.unshift('--inspect-brk');
101
231
  }
102
- return { command: 'tsx', args };
232
+ // Enable source map support
233
+ if (this.options.sourceMaps) {
234
+ args.unshift('--enable-source-maps');
235
+ }
236
+ return { command: 'node', args };
103
237
  }
104
238
  clearConsole() {
105
239
  if (this.options.clearConsole && process.stdout.isTTY) {
@@ -112,50 +246,58 @@ class DevManager {
112
246
  return;
113
247
  }
114
248
  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);
249
+ try {
250
+ const { command, args } = await this.getExecuteCommand();
251
+ if (this.options.verbose) {
252
+ logger_manager_js_1.loggerManager.printLine(`Executing: ${command} ${args.join(' ')}`, 'info');
138
253
  }
139
- });
140
- (_b = this.process.stderr) === null || _b === void 0 ? void 0 : _b.on('data', (data) => {
254
+ this.process = (0, child_process_1.spawn)(command, args, {
255
+ stdio: ['ignore', 'pipe', 'pipe'],
256
+ shell: false,
257
+ env: {
258
+ ...process.env,
259
+ NODE_ENV: process.env.NODE_ENV || 'development',
260
+ FORCE_COLOR: this.options.color ? '1' : '0',
261
+ TS_NODE_DEV: '1',
262
+ NEEX_DEV: '1'
263
+ },
264
+ detached: true
265
+ });
266
+ this.startTime = new Date();
267
+ this.restartCount++;
141
268
  if (!this.options.quiet) {
142
- process.stderr.write(data);
269
+ const timestamp = new Date().toLocaleTimeString();
270
+ 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
271
  }
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');
272
+ (_a = this.process.stdout) === null || _a === void 0 ? void 0 : _a.on('data', (data) => {
273
+ if (!this.options.quiet) {
274
+ process.stdout.write(data);
275
+ }
276
+ });
277
+ (_b = this.process.stderr) === null || _b === void 0 ? void 0 : _b.on('data', (data) => {
278
+ if (!this.options.quiet) {
279
+ process.stderr.write(data);
280
+ }
281
+ });
282
+ this.process.on('error', (error) => {
283
+ logger_manager_js_1.loggerManager.printLine(`Process error: ${error.message}`, 'error');
284
+ });
285
+ this.process.on('exit', (code, signal) => {
286
+ if (this.process) {
287
+ this.process = null;
288
+ if (!this.isRestarting) {
289
+ if (code !== 0) {
290
+ const duration = this.startTime ? Date.now() - this.startTime.getTime() : 0;
291
+ logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.red(figures_1.default.cross)} Process exited with code ${code} after ${duration}ms`, 'error');
292
+ }
155
293
  }
156
294
  }
157
- }
158
- });
295
+ });
296
+ }
297
+ catch (error) {
298
+ logger_manager_js_1.loggerManager.printLine(`Failed to start process: ${error.message}`, 'error');
299
+ throw error;
300
+ }
159
301
  }
160
302
  async stopProcess() {
161
303
  if (!this.process) {
@@ -172,6 +314,7 @@ class DevManager {
172
314
  if (!this.options.quiet) {
173
315
  logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.yellow(figures_1.default.square)} Stopped process`, 'info');
174
316
  }
317
+ this.cleanupTempFiles();
175
318
  resolve();
176
319
  };
177
320
  proc.on('exit', cleanup);
@@ -190,7 +333,7 @@ class DevManager {
190
333
  // Ignore
191
334
  }
192
335
  }
193
- }, 5000);
336
+ }, 3000);
194
337
  }
195
338
  }
196
339
  catch (error) {
@@ -199,6 +342,17 @@ class DevManager {
199
342
  }
200
343
  });
201
344
  }
345
+ invalidateCache(filePath) {
346
+ const absolutePath = path_1.default.resolve(filePath);
347
+ // Remove from cache
348
+ this.moduleCache.delete(absolutePath);
349
+ // Remove dependent modules from cache
350
+ for (const [cachedPath, module] of this.moduleCache.entries()) {
351
+ if (module.dependencies.has(absolutePath)) {
352
+ this.moduleCache.delete(cachedPath);
353
+ }
354
+ }
355
+ }
202
356
  async restart() {
203
357
  if (this.isRestarting) {
204
358
  return;
@@ -210,7 +364,11 @@ class DevManager {
210
364
  if (!this.options.quiet) {
211
365
  logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.yellow(figures_1.default.arrowRight)} Restarting due to changes...`, 'info');
212
366
  }
367
+ // Clear module cache
368
+ this.moduleCache.clear();
213
369
  await this.stopProcess();
370
+ // Small delay to ensure cleanup
371
+ await new Promise(resolve => setTimeout(resolve, 100));
214
372
  await this.startProcess();
215
373
  this.isRestarting = false;
216
374
  }
@@ -221,7 +379,9 @@ class DevManager {
221
379
  '**/.git/**',
222
380
  '**/dist/**',
223
381
  '**/build/**',
382
+ '**/.neex-temp/**',
224
383
  '**/*.log',
384
+ '**/*.d.ts',
225
385
  ...this.options.ignore.map(pattern => `**/${pattern}/**`)
226
386
  ];
227
387
  this.watcher = (0, chokidar_1.watch)(watchPatterns, {
@@ -232,6 +392,7 @@ class DevManager {
232
392
  atomic: 300
233
393
  });
234
394
  this.watcher.on('change', (filePath) => {
395
+ this.invalidateCache(filePath);
235
396
  if (this.options.verbose) {
236
397
  logger_manager_js_1.loggerManager.printLine(`File changed: ${path_1.default.relative(process.cwd(), filePath)}`, 'info');
237
398
  }
@@ -244,6 +405,7 @@ class DevManager {
244
405
  this.debouncedRestart();
245
406
  });
246
407
  this.watcher.on('unlink', (filePath) => {
408
+ this.invalidateCache(filePath);
247
409
  if (this.options.verbose) {
248
410
  logger_manager_js_1.loggerManager.printLine(`File removed: ${path_1.default.relative(process.cwd(), filePath)}`, 'info');
249
411
  }
@@ -262,16 +424,23 @@ class DevManager {
262
424
  if (!fs_1.default.existsSync(this.options.file)) {
263
425
  throw new Error(`Target file not found: ${this.options.file}`);
264
426
  }
265
- logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.blue(figures_1.default.info)} Starting development server...`, 'info');
427
+ // Validate TypeScript file
428
+ const ext = path_1.default.extname(this.options.file);
429
+ if (!['.ts', '.tsx', '.js', '.jsx'].includes(ext)) {
430
+ throw new Error(`Unsupported file extension: ${ext}`);
431
+ }
432
+ logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.blue(figures_1.default.info)} Starting TypeScript development server...`, 'info');
266
433
  // Show configuration in verbose mode
267
434
  if (this.options.verbose) {
268
435
  logger_manager_js_1.loggerManager.printLine(`Target file: ${this.options.file}`, 'info');
269
436
  logger_manager_js_1.loggerManager.printLine(`Watch patterns: ${this.options.watch.join(', ')}`, 'info');
270
437
  logger_manager_js_1.loggerManager.printLine(`Restart delay: ${this.options.delay}ms`, 'info');
438
+ logger_manager_js_1.loggerManager.printLine(`Transpile only: ${this.options.transpileOnly}`, 'info');
439
+ logger_manager_js_1.loggerManager.printLine(`Source maps: ${this.options.sourceMaps}`, 'info');
271
440
  }
272
441
  this.setupWatcher();
273
442
  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');
443
+ logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.green(figures_1.default.tick)} TypeScript development server started. Watching for changes...`, 'info');
275
444
  }
276
445
  async stop() {
277
446
  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.80",
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",