neex 0.6.88 → 0.6.89

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,56 +7,43 @@ 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 path_1 = __importDefault(require("path"));
11
- const fs_1 = __importDefault(require("fs"));
12
- const figures_1 = __importDefault(require("figures"));
13
10
  function addDevCommands(program) {
14
11
  let devManager = null;
15
- let isShuttingDown = false;
16
- // Ultra-fast Express dev command optimized for speed
12
+ // Ultra-fast dev command optimized for speed
17
13
  program
18
14
  .command('dev [file]')
19
- .description('Start TypeScript development server with hot reloading (default: src/index.ts)')
20
- .option('-w, --watch <patterns>', 'Watch additional patterns (comma-separated)', 'src/**/*')
21
- .option('-i, --ignore <patterns>', 'Ignore patterns (comma-separated)', 'node_modules,dist,build,.git,coverage')
22
- .option('-e, --ext <extensions>', 'File extensions to watch (comma-separated)', 'ts,tsx,js,jsx,json')
23
- .option('-d, --delay <ms>', 'Delay before restart (ms)', parseInt, 800)
24
- .option('-c, --no-color', 'Disable colored output')
25
- .option('-q, --quiet', 'Reduce output verbosity')
26
- .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)')
27
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')
28
25
  .option('--inspect', 'Enable Node.js inspector')
29
- .option('--inspect-brk', 'Enable Node.js inspector with break')
30
- .option('--env <file>', 'Load environment variables from file', '.env')
31
- .option('--exec <command>', 'Command to execute instead of built-in TypeScript compilation')
32
- .option('--tsconfig <path>', 'Path to TypeScript configuration file')
33
- .option('--no-source-maps', 'Disable source maps')
34
- .option('--transpile-only', 'Skip type checking for faster compilation')
35
- .option('--node-args <args>', 'Additional Node.js arguments (comma-separated)', '')
36
- .option('--port <port>', 'Port to use if available', parseInt)
37
- .option('--host <host>', 'Host to bind to')
38
- .option('--hot-reload', 'Enable hot reloading for supported frameworks (e.g., Express)')
39
- .option('--middleware', 'Inject middleware for features like hot reloading')
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)', '')
40
33
  .action(async (file, options) => {
41
34
  try {
42
35
  const targetFile = file || 'src/index.ts';
36
+ const delay = options.fast ? 50 : options.delay;
43
37
  if (!options.quiet) {
44
- 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');
45
- if (options.verbose) {
46
- logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.dim('Features:')}`, 'info');
47
- logger_manager_js_1.loggerManager.printLine(` ${chalk_1.default.green('✓')} Built-in TypeScript compilation`, 'info');
48
- logger_manager_js_1.loggerManager.printLine(` ${chalk_1.default.green('✓')} Hot reloading with intelligent caching`, 'info');
49
- logger_manager_js_1.loggerManager.printLine(` ${chalk_1.default.green('✓')} Source map support`, 'info');
50
- logger_manager_js_1.loggerManager.printLine(` ${chalk_1.default.green('✓')} Fast transpilation mode`, 'info');
51
- logger_manager_js_1.loggerManager.printLine(` ${chalk_1.default.green('✓')} Dependency tracking`, 'info');
52
- }
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');
53
40
  }
54
41
  devManager = new dev_manager_js_1.DevManager({
55
42
  file: targetFile,
56
43
  watch: options.watch.split(',').map((p) => p.trim()),
57
44
  ignore: options.ignore.split(',').map((p) => p.trim()),
58
45
  extensions: options.ext.split(',').map((e) => e.trim()),
59
- delay: options.delay,
46
+ delay: delay,
60
47
  color: options.color,
61
48
  quiet: options.quiet,
62
49
  verbose: options.verbose,
@@ -68,64 +55,125 @@ function addDevCommands(program) {
68
55
  tsConfig: options.tsconfig,
69
56
  sourceMaps: options.sourceMaps,
70
57
  transpileOnly: options.transpileOnly,
71
- nodeArgs: options.nodeArgs ? options.nodeArgs.split(',').map((arg) => arg.trim()) : [],
72
- port: options.port,
73
- host: options.host,
74
- hotReload: options.hotReload,
75
- middleware: options.middleware
58
+ nodeArgs: options.nodeArgs ? options.nodeArgs.split(',').map((arg) => arg.trim()) : []
76
59
  });
77
60
  await devManager.start();
78
61
  }
79
62
  catch (error) {
80
63
  if (error instanceof Error) {
81
- 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');
82
65
  }
83
66
  else {
84
- 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');
85
68
  }
86
69
  process.exit(1);
87
70
  }
88
71
  });
89
- // Additional helper commands
72
+ // Clean cache command
90
73
  program
91
74
  .command('dev:clean')
92
- .description('Clean development server cache and temporary files')
75
+ .description('Clean development cache and temp files')
93
76
  .action(() => {
94
- const tempDir = path_1.default.join(process.cwd(), '.neex');
95
- if (fs_1.default.existsSync(tempDir)) {
96
- fs_1.default.rmSync(tempDir, { recursive: true, force: true });
97
- logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.green(figures_1.default.tick)} Cleaned development cache`, 'info');
77
+ const path = require('path');
78
+ const fs = require('fs');
79
+ const tempDir = path.join(process.cwd(), '.neex-temp');
80
+ const nodeModulesCache = path.join(process.cwd(), 'node_modules/.cache');
81
+ let cleaned = false;
82
+ if (fs.existsSync(tempDir)) {
83
+ fs.rmSync(tempDir, { recursive: true, force: true });
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');
98
97
  }
99
98
  else {
100
- 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');
101
100
  }
102
101
  });
102
+ // TypeScript config check
103
103
  program
104
104
  .command('dev:check')
105
- .description('Check TypeScript configuration and dependencies')
106
- .option('--tsconfig <path>', 'Path to TypeScript configuration file')
105
+ .description('Check TypeScript configuration')
106
+ .option('--tsconfig <path>', 'TypeScript config file path')
107
107
  .action((options) => {
108
+ const path = require('path');
109
+ const fs = require('fs');
108
110
  const configPath = options.tsconfig || 'tsconfig.json';
109
- if (!fs_1.default.existsSync(configPath)) {
110
- logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.red(figures_1.default.cross)} TypeScript config not found: ${configPath}`, 'error');
111
+ if (!fs.existsSync(configPath)) {
112
+ logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.red('✖')} TypeScript config not found: ${configPath}`, 'error');
111
113
  process.exit(1);
112
114
  }
113
115
  try {
114
- const config = JSON.parse(fs_1.default.readFileSync(configPath, 'utf8'));
115
- logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.green(figures_1.default.tick)} TypeScript config is valid`, 'info');
116
- if (config.compilerOptions) {
117
- logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.dim('Compiler Options:')}`, 'info');
118
- logger_manager_js_1.loggerManager.printLine(` Target: ${config.compilerOptions.target || 'default'}`, 'info');
119
- logger_manager_js_1.loggerManager.printLine(` Module: ${config.compilerOptions.module || 'default'}`, 'info');
120
- logger_manager_js_1.loggerManager.printLine(` Strict: ${config.compilerOptions.strict || 'false'}`, 'info');
121
- logger_manager_js_1.loggerManager.printLine(` Source Maps: ${config.compilerOptions.sourceMap || 'false'}`, 'info');
116
+ const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
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');
122
126
  }
123
127
  }
124
128
  catch (error) {
125
- 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');
126
130
  process.exit(1);
127
131
  }
128
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
+ });
129
177
  // Cleanup function
130
178
  const cleanupDev = () => {
131
179
  if (devManager) {
@@ -133,20 +181,27 @@ function addDevCommands(program) {
133
181
  devManager = null;
134
182
  }
135
183
  };
136
- // Handle process termination
137
- process.on('SIGINT', () => {
184
+ // Enhanced signal handling
185
+ const handleSignal = (signal) => {
138
186
  if (devManager) {
139
- 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');
140
189
  cleanupDev();
141
190
  process.exit(0);
142
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);
143
200
  });
144
- process.on('SIGTERM', () => {
145
- if (devManager) {
146
- logger_manager_js_1.loggerManager.printLine(`\n${chalk_1.default.yellow(figures_1.default.warning)} Received SIGTERM, shutting down gracefully...`, 'info');
147
- cleanupDev();
148
- process.exit(0);
149
- }
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);
150
205
  });
151
206
  return { cleanupDev };
152
207
  }
@@ -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 process manager for Node.js applications
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");
@@ -37,7 +37,6 @@ const fs_1 = __importDefault(require("fs"));
37
37
  const lodash_1 = require("lodash");
38
38
  const ts = __importStar(require("typescript"));
39
39
  const crypto_1 = __importDefault(require("crypto"));
40
- const net_1 = __importDefault(require("net"));
41
40
  class DevManager {
42
41
  constructor(options) {
43
42
  this.process = null;
@@ -47,23 +46,11 @@ class DevManager {
47
46
  this.startTime = null;
48
47
  this.moduleCache = new Map();
49
48
  this.currentTempFile = null;
50
- this.serverInfo = null;
51
- this.hotReloadClient = null;
52
- this.isExpressApp = false;
53
- this.lastCompileTime = 0;
54
- this.performanceMetrics = {
55
- averageRestartTime: 0,
56
- totalRestarts: 0,
57
- cacheHits: 0,
58
- cacheMisses: 0
59
- };
60
49
  this.options = options;
61
- this.tempDir = path_1.default.join(process.cwd(), '.neex');
50
+ this.tempDir = path_1.default.join(process.cwd(), '.neex-temp');
62
51
  this.debouncedRestart = (0, lodash_1.debounce)(this.restart.bind(this), Math.max(options.delay, 100));
63
52
  this.tsCompilerOptions = this.loadTsConfig();
64
53
  this.setupTempDir();
65
- this.detectExpressApp();
66
- this.setupHotReloadClient();
67
54
  }
68
55
  setupTempDir() {
69
56
  if (fs_1.default.existsSync(this.tempDir)) {
@@ -75,64 +62,6 @@ class DevManager {
75
62
  }
76
63
  }
77
64
  fs_1.default.mkdirSync(this.tempDir, { recursive: true });
78
- // Create cache directory
79
- const cacheDir = path_1.default.join(this.tempDir, 'cache');
80
- fs_1.default.mkdirSync(cacheDir, { recursive: true });
81
- }
82
- detectExpressApp() {
83
- try {
84
- const fileContent = fs_1.default.readFileSync(this.options.file, 'utf8');
85
- this.isExpressApp = /import.*express|require.*express|app\.listen|server\.listen/.test(fileContent);
86
- if (this.options.verbose) {
87
- logger_manager_js_1.loggerManager.printLine(`Detected ${this.isExpressApp ? 'Express' : 'Node.js'} application`, 'info');
88
- }
89
- }
90
- catch (error) {
91
- this.isExpressApp = false;
92
- }
93
- }
94
- setupHotReloadClient() {
95
- if (!this.options.hotReload || !this.isExpressApp)
96
- return;
97
- this.hotReloadClient = `
98
- // Hot reload client for Express development
99
- (function() {
100
- if (typeof window === 'undefined') return;
101
-
102
- const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
103
- const wsUrl = protocol + '//' + window.location.host + '/__neex_hot_reload';
104
-
105
- function connect() {
106
- const ws = new WebSocket(wsUrl);
107
-
108
- ws.onopen = function() {
109
- console.log('🔥 Hot reload connected');
110
- };
111
-
112
- ws.onmessage = function(event) {
113
- const data = JSON.parse(event.data);
114
-
115
- if (data.type === 'reload') {
116
- console.log('🔄 Reloading page...');
117
- window.location.reload();
118
- } else if (data.type === 'error') {
119
- console.error('🚨 Build error:', data.message);
120
- }
121
- };
122
-
123
- ws.onclose = function() {
124
- console.log('🔌 Hot reload disconnected, retrying...');
125
- setTimeout(connect, 1000);
126
- };
127
-
128
- ws.onerror = function(error) {
129
- console.error('❌ Hot reload error:', error);
130
- };
131
- }
132
-
133
- connect();
134
- })();
135
- `;
136
65
  }
137
66
  loadTsConfig() {
138
67
  const configPath = this.options.tsConfig || 'tsconfig.json';
@@ -152,9 +81,7 @@ class DevManager {
152
81
  inlineSources: false,
153
82
  removeComments: false,
154
83
  preserveConstEnums: false,
155
- isolatedModules: true,
156
- incremental: true,
157
- tsBuildInfoFile: path_1.default.join(this.tempDir, 'tsconfig.tsbuildinfo'),
84
+ isolatedModules: true, // For faster compilation
158
85
  };
159
86
  if (fs_1.default.existsSync(configPath)) {
160
87
  try {
@@ -173,44 +100,29 @@ class DevManager {
173
100
  return defaultOptions;
174
101
  }
175
102
  loadEnvFile() {
176
- const envFiles = [
177
- this.options.envFile,
178
- '.env.development',
179
- '.env.local',
180
- '.env'
181
- ].filter(Boolean);
182
- for (const envFile of envFiles) {
183
- if (fs_1.default.existsSync(envFile)) {
184
- try {
185
- const envContent = fs_1.default.readFileSync(envFile, 'utf8');
186
- const lines = envContent.split('\n');
187
- for (const line of lines) {
188
- const trimmed = line.trim();
189
- if (trimmed && !trimmed.startsWith('#')) {
190
- const [key, ...values] = trimmed.split('=');
191
- if (key && values.length > 0) {
192
- const value = values.join('=').trim().replace(/^["']|["']$/g, '');
193
- if (!process.env[key.trim()]) {
194
- process.env[key.trim()] = value;
195
- }
196
- }
103
+ if (this.options.envFile && fs_1.default.existsSync(this.options.envFile)) {
104
+ try {
105
+ const envContent = fs_1.default.readFileSync(this.options.envFile, 'utf8');
106
+ const lines = envContent.split('\n');
107
+ for (const line of lines) {
108
+ const trimmed = line.trim();
109
+ if (trimmed && !trimmed.startsWith('#')) {
110
+ const [key, ...values] = trimmed.split('=');
111
+ if (key && values.length > 0) {
112
+ process.env[key.trim()] = values.join('=').trim().replace(/^["']|["']$/g, '');
197
113
  }
198
114
  }
199
- if (this.options.verbose) {
200
- logger_manager_js_1.loggerManager.printLine(`Loaded environment from ${envFile}`, 'info');
201
- }
202
- break;
203
115
  }
204
- catch (error) {
205
- if (this.options.verbose) {
206
- logger_manager_js_1.loggerManager.printLine(`Failed to load ${envFile}: ${error.message}`, 'warn');
207
- }
116
+ }
117
+ catch (error) {
118
+ if (this.options.verbose) {
119
+ logger_manager_js_1.loggerManager.printLine(`Failed to load ${this.options.envFile}: ${error.message}`, 'warn');
208
120
  }
209
121
  }
210
122
  }
211
123
  }
212
124
  createHash(content) {
213
- return crypto_1.default.createHash('sha256').update(content).digest('hex').substring(0, 16);
125
+ return crypto_1.default.createHash('md5').update(content).digest('hex');
214
126
  }
215
127
  extractDependencies(sourceCode, filePath) {
216
128
  const dependencies = [];
@@ -222,7 +134,7 @@ class DevManager {
222
134
  let resolvedPath = path_1.default.resolve(path_1.default.dirname(filePath), importPath);
223
135
  // Try to resolve with extensions
224
136
  if (!fs_1.default.existsSync(resolvedPath)) {
225
- for (const ext of this.options.extensions.map(e => `.${e}`)) {
137
+ for (const ext of ['.ts', '.tsx', '.js', '.jsx']) {
226
138
  const withExt = resolvedPath + ext;
227
139
  if (fs_1.default.existsSync(withExt)) {
228
140
  resolvedPath = withExt;
@@ -232,7 +144,7 @@ class DevManager {
232
144
  }
233
145
  // Try index files
234
146
  if (!fs_1.default.existsSync(resolvedPath)) {
235
- for (const ext of this.options.extensions.map(e => `.${e}`)) {
147
+ for (const ext of ['.ts', '.tsx', '.js', '.jsx']) {
236
148
  const indexPath = path_1.default.join(resolvedPath, 'index' + ext);
237
149
  if (fs_1.default.existsSync(indexPath)) {
238
150
  resolvedPath = indexPath;
@@ -247,125 +159,67 @@ class DevManager {
247
159
  }
248
160
  return dependencies;
249
161
  }
250
- extractExports(sourceCode) {
251
- const exports = [];
252
- const exportRegex = /export\s+(?:default\s+)?(?:class|function|const|let|var|interface|type|enum)\s+([a-zA-Z_$][a-zA-Z0-9_$]*)/g;
253
- let match;
254
- while ((match = exportRegex.exec(sourceCode)) !== null) {
255
- exports.push(match[1]);
256
- }
257
- return exports;
258
- }
259
162
  compileModule(filePath, forceRecompile = false) {
260
163
  const absolutePath = path_1.default.resolve(filePath);
261
- const compileStart = Date.now();
262
164
  try {
263
165
  const sourceCode = fs_1.default.readFileSync(absolutePath, 'utf8');
264
166
  const hash = this.createHash(sourceCode);
265
167
  const cached = this.moduleCache.get(absolutePath);
266
168
  // Check if we can use cached version
267
169
  if (!forceRecompile && cached && cached.hash === hash) {
268
- this.performanceMetrics.cacheHits++;
269
170
  return cached;
270
171
  }
271
- this.performanceMetrics.cacheMisses++;
272
172
  const dependencies = this.extractDependencies(sourceCode, absolutePath);
273
- const exports = this.extractExports(sourceCode);
274
173
  // Fast transpile without type checking for development
275
174
  const result = ts.transpileModule(sourceCode, {
276
175
  compilerOptions: this.tsCompilerOptions,
277
176
  fileName: absolutePath,
278
- reportDiagnostics: this.options.verbose
177
+ reportDiagnostics: false // Skip diagnostics for speed
279
178
  });
280
179
  const moduleInfo = {
281
180
  code: result.outputText,
282
181
  map: result.sourceMapText,
283
182
  hash,
284
183
  timestamp: Date.now(),
285
- dependencies,
286
- exports
184
+ dependencies
287
185
  };
288
186
  this.moduleCache.set(absolutePath, moduleInfo);
289
187
  if (this.options.verbose) {
290
- const compileTime = Date.now() - compileStart;
291
- logger_manager_js_1.loggerManager.printLine(`Compiled ${path_1.default.relative(process.cwd(), filePath)} (${compileTime}ms)`, 'info');
188
+ logger_manager_js_1.loggerManager.printLine(`Compiled ${path_1.default.relative(process.cwd(), filePath)}`, 'info');
292
189
  }
293
190
  return moduleInfo;
294
191
  }
295
192
  catch (error) {
296
- logger_manager_js_1.loggerManager.printLine(`Compilation error in ${filePath}: ${error.message}`, 'error');
193
+ logger_manager_js_1.loggerManager.printLine(`Compilation error: ${error.message}`, 'error');
297
194
  throw error;
298
195
  }
299
196
  }
300
197
  invalidateModuleCache(filePath) {
301
198
  const absolutePath = path_1.default.resolve(filePath);
302
- const toRemove = new Set();
303
199
  // Remove the file itself
304
- toRemove.add(absolutePath);
305
- // Remove any modules that depend on this file (recursive)
306
- const findDependents = (targetPath) => {
307
- for (const [cachedPath, info] of this.moduleCache.entries()) {
308
- if (info.dependencies.includes(targetPath) && !toRemove.has(cachedPath)) {
309
- toRemove.add(cachedPath);
310
- findDependents(cachedPath);
311
- }
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);
312
206
  }
313
- };
314
- findDependents(absolutePath);
315
- // Remove all affected modules
207
+ }
316
208
  for (const pathToRemove of toRemove) {
317
209
  this.moduleCache.delete(pathToRemove);
318
210
  }
319
- if (this.options.verbose && toRemove.size > 1) {
320
- logger_manager_js_1.loggerManager.printLine(`Invalidated ${toRemove.size} modules`, 'info');
211
+ if (this.options.verbose && toRemove.length > 0) {
212
+ logger_manager_js_1.loggerManager.printLine(`Invalidated ${toRemove.length + 1} modules`, 'info');
321
213
  }
322
214
  }
323
- async findFreePort(startPort = 3000) {
324
- return new Promise((resolve, reject) => {
325
- const server = net_1.default.createServer();
326
- server.listen(startPort, () => {
327
- const port = server.address().port;
328
- server.close(() => resolve(port));
329
- });
330
- server.on('error', () => {
331
- this.findFreePort(startPort + 1).then(resolve).catch(reject);
332
- });
333
- });
334
- }
335
215
  createExecutableFile() {
336
- const startCompile = Date.now();
337
216
  // Always force recompile the main file
338
217
  const mainModule = this.compileModule(this.options.file, true);
339
218
  // Create a unique temp file
340
219
  const timestamp = Date.now();
341
220
  const random = Math.random().toString(36).substr(2, 9);
342
- const tempFile = path_1.default.join(this.tempDir, `server-${timestamp}-${random}.js`);
221
+ const tempFile = path_1.default.join(this.tempDir, `main-${timestamp}-${random}.js`);
343
222
  let code = mainModule.code;
344
- // Add hot reload middleware for Express apps
345
- if (this.isExpressApp && this.options.hotReload) {
346
- const hotReloadMiddleware = `
347
- // Hot reload middleware injected by neex
348
- const originalListen = require('http').Server.prototype.listen;
349
- require('http').Server.prototype.listen = function(...args) {
350
- const server = originalListen.apply(this, args);
351
-
352
- // Setup WebSocket for hot reload
353
- const WebSocket = require('ws');
354
- const wss = new WebSocket.Server({ server, path: '/__neex_hot_reload' });
355
-
356
- global.__neex_hot_reload = (type, data) => {
357
- wss.clients.forEach(client => {
358
- if (client.readyState === WebSocket.OPEN) {
359
- client.send(JSON.stringify({ type, ...data }));
360
- }
361
- });
362
- };
363
-
364
- return server;
365
- };
366
- `;
367
- code = hotReloadMiddleware + '\n' + code;
368
- }
369
223
  // Add source map support
370
224
  if (mainModule.map && this.options.sourceMaps) {
371
225
  const mapFile = tempFile + '.map';
@@ -387,7 +241,6 @@ require('http').Server.prototype.listen = function(...args) {
387
241
  }
388
242
  }
389
243
  this.currentTempFile = tempFile;
390
- this.lastCompileTime = Date.now() - startCompile;
391
244
  return tempFile;
392
245
  }
393
246
  async getExecuteCommand() {
@@ -404,93 +257,50 @@ require('http').Server.prototype.listen = function(...args) {
404
257
  args.unshift('--inspect-brk');
405
258
  if (this.options.sourceMaps)
406
259
  args.unshift('--enable-source-maps');
407
- // Memory optimization
408
- args.unshift('--max-old-space-size=4096');
409
- args.unshift('--optimize-for-size');
410
260
  return { command: 'node', args };
411
261
  }
412
262
  clearConsole() {
413
263
  if (this.options.clearConsole && process.stdout.isTTY) {
414
- process.stdout.write('\x1Bc');
264
+ process.stdout.write('\x1Bc'); // Clear screen and scrollback
415
265
  }
416
266
  }
417
267
  async startProcess() {
418
268
  var _a, _b;
419
269
  if (this.process)
420
270
  return;
421
- const restartStart = Date.now();
422
271
  this.loadEnvFile();
423
272
  try {
424
273
  const { command, args } = await this.getExecuteCommand();
425
- // Find free port for Express apps
426
- if (this.isExpressApp && !process.env.PORT) {
427
- const port = await this.findFreePort(this.options.port || 3000);
428
- process.env.PORT = port.toString();
429
- }
430
274
  this.process = (0, child_process_1.spawn)(command, args, {
431
275
  stdio: ['ignore', 'pipe', 'pipe'],
432
276
  env: {
433
277
  ...process.env,
434
278
  NODE_ENV: process.env.NODE_ENV || 'development',
435
279
  FORCE_COLOR: this.options.color ? '1' : '0',
436
- NEEX_DEV_MODE: '1',
437
- NEEX_HOT_RELOAD: this.options.hotReload ? '1' : '0',
280
+ NODE_OPTIONS: '--max-old-space-size=4096', // Prevent memory issues
438
281
  },
439
- detached: false
282
+ detached: false // Keep attached for better cleanup
440
283
  });
441
284
  this.startTime = new Date();
442
285
  this.restartCount++;
443
- // Update performance metrics
444
- if (this.restartCount > 1) {
445
- const restartTime = Date.now() - restartStart;
446
- this.performanceMetrics.averageRestartTime =
447
- (this.performanceMetrics.averageRestartTime * (this.restartCount - 2) + restartTime) / (this.restartCount - 1);
448
- this.performanceMetrics.totalRestarts++;
449
- }
450
286
  if (!this.options.quiet) {
451
287
  const timestamp = new Date().toLocaleTimeString();
452
288
  const fileRelative = path_1.default.relative(process.cwd(), this.options.file);
453
- const port = process.env.PORT ? `:${process.env.PORT}` : '';
454
- const url = this.isExpressApp ? `http://localhost${port}` : '';
455
289
  logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.green('▶')} ${chalk_1.default.cyan(fileRelative)} ${chalk_1.default.dim(`#${this.restartCount} ${timestamp}`)}`, 'info');
456
- if (url) {
457
- logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.blue('🌐')} ${chalk_1.default.underline(url)}`, 'info');
458
- }
459
- if (this.options.verbose) {
460
- logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.dim('Compile time:')} ${this.lastCompileTime}ms`, 'info');
461
- logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.dim('Cache hits:')} ${this.performanceMetrics.cacheHits}`, 'info');
462
- }
463
290
  }
464
- this.serverInfo = {
465
- port: parseInt(process.env.PORT || '3000'),
466
- host: this.options.host || 'localhost',
467
- pid: this.process.pid,
468
- startTime: Date.now(),
469
- restarts: this.restartCount
470
- };
471
- // Handle stdout/stderr with better formatting
291
+ // Handle stdout/stderr
472
292
  (_a = this.process.stdout) === null || _a === void 0 ? void 0 : _a.on('data', (data) => {
473
- const output = data.toString();
474
- if (!this.options.quiet) {
475
- process.stdout.write(output);
476
- }
293
+ process.stdout.write(data);
477
294
  });
478
295
  (_b = this.process.stderr) === null || _b === void 0 ? void 0 : _b.on('data', (data) => {
479
- const output = data.toString();
480
- if (!this.options.quiet) {
481
- process.stderr.write(output);
482
- }
296
+ process.stderr.write(data);
483
297
  });
484
298
  this.process.on('error', (error) => {
485
299
  logger_manager_js_1.loggerManager.printLine(`Process error: ${error.message}`, 'error');
486
- if (this.options.hotReload && global.__neex_hot_reload) {
487
- global.__neex_hot_reload('error', { message: error.message });
488
- }
489
300
  });
490
301
  this.process.on('exit', (code, signal) => {
491
302
  if (this.process) {
492
303
  this.process = null;
493
- this.serverInfo = null;
494
304
  if (!this.isRestarting && code !== 0) {
495
305
  const duration = this.startTime ? Date.now() - this.startTime.getTime() : 0;
496
306
  logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.red('✖')} Process exited with code ${code} (${duration}ms)`, 'error');
@@ -509,7 +319,6 @@ require('http').Server.prototype.listen = function(...args) {
509
319
  return new Promise((resolve) => {
510
320
  const proc = this.process;
511
321
  this.process = null;
512
- this.serverInfo = null;
513
322
  const cleanup = () => {
514
323
  resolve();
515
324
  };
@@ -522,8 +331,7 @@ require('http').Server.prototype.listen = function(...args) {
522
331
  if (!proc.killed) {
523
332
  proc.kill('SIGKILL');
524
333
  }
525
- cleanup();
526
- }, 2000);
334
+ }, 1000);
527
335
  }
528
336
  catch (error) {
529
337
  cleanup();
@@ -534,14 +342,10 @@ require('http').Server.prototype.listen = function(...args) {
534
342
  if (this.isRestarting)
535
343
  return;
536
344
  this.isRestarting = true;
537
- // Clear console for better UX
345
+ // Clear console immediately for better UX
538
346
  this.clearConsole();
539
347
  if (!this.options.quiet) {
540
- logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.yellow('⟳')} Restarting server...`, 'info');
541
- }
542
- // Notify hot reload clients
543
- if (this.options.hotReload && global.__neex_hot_reload) {
544
- global.__neex_hot_reload('reload', {});
348
+ logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.yellow('⟳')} Restarting...`, 'info');
545
349
  }
546
350
  // Stop current process
547
351
  await this.stopProcess();
@@ -551,21 +355,17 @@ require('http').Server.prototype.listen = function(...args) {
551
355
  }
552
356
  setupWatcher() {
553
357
  const watchPatterns = this.options.watch;
554
- // Optimized ignore patterns for Express projects
358
+ // Optimized ignore patterns
555
359
  const ignored = [
556
360
  'node_modules/**',
557
361
  '.git/**',
558
362
  'dist/**',
559
363
  'build/**',
560
- '.neex/**',
561
- 'coverage/**',
562
- 'logs/**',
364
+ '.neex-temp/**',
563
365
  '**/*.log',
564
366
  '**/*.d.ts',
565
367
  '**/*.map',
566
368
  '**/*.tsbuildinfo',
567
- '**/package-lock.json',
568
- '**/yarn.lock',
569
369
  ...this.options.ignore
570
370
  ];
571
371
  this.watcher = (0, chokidar_1.watch)(watchPatterns, {
@@ -573,10 +373,10 @@ require('http').Server.prototype.listen = function(...args) {
573
373
  ignoreInitial: true,
574
374
  followSymlinks: false,
575
375
  usePolling: false,
576
- atomic: 100,
376
+ atomic: 50,
577
377
  awaitWriteFinish: {
578
- stabilityThreshold: 150,
579
- pollInterval: 100
378
+ stabilityThreshold: 100,
379
+ pollInterval: 50
580
380
  }
581
381
  });
582
382
  this.watcher.on('change', (filePath) => {
@@ -608,28 +408,24 @@ require('http').Server.prototype.listen = function(...args) {
608
408
  throw new Error(`Target file not found: ${this.options.file}`);
609
409
  }
610
410
  const ext = path_1.default.extname(this.options.file);
611
- if (!this.options.extensions.map(e => `.${e}`).includes(ext)) {
411
+ if (!['.ts', '.tsx', '.js', '.jsx'].includes(ext)) {
612
412
  throw new Error(`Unsupported file extension: ${ext}`);
613
413
  }
614
414
  // Clear any existing cache
615
415
  this.moduleCache.clear();
616
416
  this.setupTempDir();
617
417
  if (!this.options.quiet) {
618
- const appType = this.isExpressApp ? 'Express' : 'Node.js';
619
- logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.blue('⚡')} Starting ${appType} development server...`, 'info');
418
+ logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.blue('')} Starting dev server...`, 'info');
620
419
  }
621
420
  this.setupWatcher();
622
421
  await this.startProcess();
623
422
  if (!this.options.quiet) {
624
423
  logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.green('✓')} Watching for changes...`, 'info');
625
- if (this.options.hotReload) {
626
- logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.blue('🔥')} Hot reload enabled`, 'info');
627
- }
628
424
  }
629
425
  }
630
426
  async stop() {
631
427
  if (!this.options.quiet) {
632
- logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.yellow('⏹')} Stopping development server...`, 'info');
428
+ logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.yellow('⏹')} Stopping dev server...`, 'info');
633
429
  }
634
430
  if (this.watcher) {
635
431
  await this.watcher.close();
@@ -646,23 +442,6 @@ require('http').Server.prototype.listen = function(...args) {
646
442
  }
647
443
  }
648
444
  this.moduleCache.clear();
649
- if (this.options.verbose) {
650
- logger_manager_js_1.loggerManager.printLine('Development server stopped', 'info');
651
- }
652
- }
653
- getServerInfo() {
654
- return this.serverInfo;
655
- }
656
- getPerformanceMetrics() {
657
- return {
658
- ...this.performanceMetrics,
659
- modulesCached: this.moduleCache.size,
660
- lastCompileTime: this.lastCompileTime
661
- };
662
- }
663
- async forceRestart() {
664
- this.moduleCache.clear();
665
- await this.restart();
666
445
  }
667
446
  }
668
447
  exports.DevManager = DevManager;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "neex",
3
- "version": "0.6.88",
3
+ "version": "0.6.89",
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",