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