neex 0.6.54 → 0.6.60

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.
@@ -13,10 +13,10 @@ const fs_1 = __importDefault(require("fs"));
13
13
  const os_1 = __importDefault(require("os"));
14
14
  function addStartCommands(program) {
15
15
  let startManager = null;
16
- // Single optimized start command for production
16
+ // Production start command
17
17
  program
18
18
  .command('start [file]')
19
- .description('Start production application with automatic optimization')
19
+ .description('Start production application')
20
20
  .option('-d, --dir <directory>', 'Working directory', process.cwd())
21
21
  .option('-e, --env <file>', 'Environment file to load', '.env')
22
22
  .option('-p, --port <port>', 'Port number', parseInt)
@@ -32,7 +32,7 @@ function addStartCommands(program) {
32
32
  .option('--node-args <args>', 'Additional Node.js arguments')
33
33
  .action(async (file, options) => {
34
34
  try {
35
- const targetFile = file || 'dist/index.js';
35
+ const targetFile = file || 'dist/server.js';
36
36
  let resolvedFile = path_1.default.resolve(options.dir, targetFile);
37
37
  // Auto-detect main file if not found
38
38
  if (!fs_1.default.existsSync(resolvedFile)) {
@@ -53,12 +53,13 @@ function addStartCommands(program) {
53
53
  const commonLocations = [
54
54
  'dist/server.js',
55
55
  'dist/app.js',
56
- 'build/index.js',
56
+ 'dist/index.js',
57
57
  'build/server.js',
58
- 'src/index.js',
59
- 'src/server.js',
60
- 'index.js',
61
- 'server.js'
58
+ 'build/app.js',
59
+ 'build/index.js',
60
+ 'server.js',
61
+ 'app.js',
62
+ 'index.js'
62
63
  ];
63
64
  let found = false;
64
65
  for (const location of commonLocations) {
@@ -85,25 +86,37 @@ function addStartCommands(program) {
85
86
  throw new Error(`Application file not found: ${resolvedFile}`);
86
87
  }
87
88
  }
88
- // Detect environment and set optimal configuration
89
+ // Environment detection
89
90
  const isDevelopment = options.watch || process.env.NODE_ENV === 'development';
90
91
  const isProduction = !isDevelopment;
91
92
  const cpuCount = os_1.default.cpus().length;
92
- // Smart worker allocation
93
+ // Smart worker allocation - more conservative approach
93
94
  let workers = options.workers;
94
95
  if (!workers) {
95
96
  if (isDevelopment) {
96
- workers = 1; // Single worker for development
97
+ workers = 1; // Always single worker in development
97
98
  }
98
99
  else {
99
- // For production, use CPU count but cap at 8 for most applications
100
- workers = Math.min(cpuCount, 8);
100
+ // For production, be more conservative
101
+ if (cpuCount <= 2) {
102
+ workers = 1; // Single worker for small systems
103
+ }
104
+ else if (cpuCount <= 4) {
105
+ workers = 2; // Two workers for medium systems
106
+ }
107
+ else {
108
+ workers = Math.min(Math.floor(cpuCount / 2), 4); // Max 4 workers
109
+ }
101
110
  }
102
111
  }
103
- const healthCheck = options.health !== false && isProduction;
112
+ // Force single worker for development or debugging
113
+ if (isDevelopment || options.inspect || options.inspectBrk) {
114
+ workers = 1;
115
+ }
116
+ const healthCheck = options.health !== false;
104
117
  const defaultPort = parseInt(process.env.PORT || '8000');
105
118
  const port = options.port || defaultPort;
106
- // Environment setup
119
+ // Set NODE_ENV if not already set
107
120
  if (!process.env.NODE_ENV) {
108
121
  process.env.NODE_ENV = isProduction ? 'production' : 'development';
109
122
  }
@@ -117,24 +130,28 @@ function addStartCommands(program) {
117
130
  logger_manager_js_1.loggerManager.printLine(`Environment: ${process.env.NODE_ENV}`);
118
131
  logger_manager_js_1.loggerManager.printLine(`Port: ${port}`);
119
132
  logger_manager_js_1.loggerManager.printLine(`Workers: ${workers}`);
133
+ logger_manager_js_1.loggerManager.printLine(`CPU Cores: ${cpuCount}`);
120
134
  if (healthCheck) {
121
135
  logger_manager_js_1.loggerManager.printLine(`Health Check: http://localhost:${options.healthPort}/health`);
122
136
  }
123
137
  }
138
+ // Optimize memory settings based on workers
139
+ const memoryPerWorker = workers > 1 ? Math.floor(512 / workers) : 512;
140
+ const maxMemoryPerWorker = workers > 1 ? Math.floor(1024 / workers) : 1024;
124
141
  startManager = new start_manager_js_1.StartManager({
125
142
  file: resolvedFile,
126
143
  workingDir: options.dir,
127
144
  envFile: options.env,
128
145
  port,
129
146
  workers,
130
- memoryLimit: isProduction ? '512M' : undefined,
147
+ memoryLimit: isProduction ? `${memoryPerWorker}M` : undefined,
131
148
  logLevel: options.verbose ? 'debug' : 'info',
132
149
  color: process.stdout.isTTY,
133
150
  verbose: options.verbose,
134
151
  watch: options.watch,
135
- maxMemory: options.maxMemory || (isProduction ? '1G' : undefined),
152
+ maxMemory: options.maxMemory || (isProduction ? `${maxMemoryPerWorker}M` : undefined),
136
153
  maxCrashes: isProduction ? 3 : 10,
137
- restartDelay: isProduction ? 2000 : 1000,
154
+ restartDelay: isProduction ? 1000 : 500,
138
155
  healthCheck,
139
156
  healthPort: options.healthPort,
140
157
  gracefulTimeout: options.gracefulTimeout,
@@ -162,14 +179,13 @@ function addStartCommands(program) {
162
179
  startManager = null;
163
180
  }
164
181
  catch (error) {
165
- // Ignore cleanup errors but log in verbose mode
166
182
  if (process.env.VERBOSE) {
167
183
  console.error('Cleanup error:', error);
168
184
  }
169
185
  }
170
186
  }
171
187
  };
172
- // Enhanced signal handling
188
+ // Signal handling
173
189
  const handleExit = (signal) => {
174
190
  if (startManager) {
175
191
  console.log(`\n${chalk_1.default.yellow(figures_1.default.warning)} Received ${signal}, shutting down gracefully...`);
@@ -183,11 +199,9 @@ function addStartCommands(program) {
183
199
  process.exit(0);
184
200
  }
185
201
  };
186
- // Register signal handlers
187
202
  process.on('SIGINT', () => handleExit('SIGINT'));
188
203
  process.on('SIGTERM', () => handleExit('SIGTERM'));
189
204
  process.on('SIGUSR2', () => handleExit('SIGUSR2'));
190
- // Handle uncaught exceptions
191
205
  process.on('uncaughtException', (error) => {
192
206
  console.error(`${chalk_1.default.red(figures_1.default.cross)} Uncaught Exception:`, error);
193
207
  cleanupStart().then(() => {
@@ -4,7 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.StartManager = void 0;
7
- // src/start-manager.ts - Fixed and optimized production start manager
7
+ // src/start-manager.ts - Fixed production start manager
8
8
  const child_process_1 = require("child_process");
9
9
  const chokidar_1 = require("chokidar");
10
10
  const logger_manager_js_1 = require("./logger-manager.js");
@@ -23,6 +23,8 @@ class StartManager {
23
23
  this.isShuttingDown = false;
24
24
  this.totalRestarts = 0;
25
25
  this.envLoaded = false;
26
+ this.masterProcess = null;
27
+ this.readyWorkers = 0;
26
28
  this.options = options;
27
29
  this.startTime = new Date();
28
30
  this.debouncedRestart = (0, lodash_1.debounce)(this.restartAll.bind(this), options.restartDelay);
@@ -85,10 +87,10 @@ class StartManager {
85
87
  args.push(`--max-old-space-size=${memoryMB}`);
86
88
  }
87
89
  }
88
- if (this.options.inspect) {
90
+ if (this.options.inspect && this.options.workers === 1) {
89
91
  args.push('--inspect');
90
92
  }
91
- if (this.options.inspectBrk) {
93
+ if (this.options.inspectBrk && this.options.workers === 1) {
92
94
  args.push('--inspect-brk');
93
95
  }
94
96
  if (this.options.nodeArgs) {
@@ -96,58 +98,147 @@ class StartManager {
96
98
  }
97
99
  return args;
98
100
  }
101
+ async startSingleProcess() {
102
+ var _a, _b;
103
+ const nodeArgs = this.getNodeArgs();
104
+ const port = this.options.port || 8000;
105
+ const env = {
106
+ ...process.env,
107
+ NODE_ENV: process.env.NODE_ENV || 'production',
108
+ PORT: port.toString(),
109
+ FORCE_COLOR: this.options.color ? '1' : '0',
110
+ NODE_OPTIONS: '--no-deprecation',
111
+ CLUSTER_WORKER: 'false',
112
+ MASTER_PROCESS: 'true'
113
+ };
114
+ if (this.options.verbose) {
115
+ this.log(`Starting single process on port ${port}`);
116
+ }
117
+ this.masterProcess = (0, child_process_1.fork)(this.options.file, [], {
118
+ cwd: this.options.workingDir,
119
+ env,
120
+ execArgv: nodeArgs,
121
+ silent: true
122
+ });
123
+ // Handle process output with filtering
124
+ (_a = this.masterProcess.stdout) === null || _a === void 0 ? void 0 : _a.on('data', (data) => {
125
+ const message = data.toString().trim();
126
+ if (message && !this.shouldFilterMessage(message)) {
127
+ console.log(message);
128
+ }
129
+ });
130
+ (_b = this.masterProcess.stderr) === null || _b === void 0 ? void 0 : _b.on('data', (data) => {
131
+ const message = data.toString().trim();
132
+ if (message && !this.shouldFilterMessage(message)) {
133
+ console.error(chalk_1.default.red(message));
134
+ }
135
+ });
136
+ this.masterProcess.on('error', (error) => {
137
+ this.log(`Process error: ${error.message}`, 'error');
138
+ });
139
+ this.masterProcess.on('exit', (code, signal) => {
140
+ if (!this.isShuttingDown && code !== 0 && signal !== 'SIGTERM') {
141
+ this.log(`Process crashed (code: ${code}, signal: ${signal})`, 'error');
142
+ this.totalRestarts++;
143
+ if (this.totalRestarts < this.options.maxCrashes) {
144
+ setTimeout(() => {
145
+ this.startSingleProcess();
146
+ }, this.options.restartDelay);
147
+ }
148
+ else {
149
+ this.log(`Max crashes reached (${this.options.maxCrashes}), not restarting`, 'error');
150
+ }
151
+ }
152
+ });
153
+ // Wait for process to be ready
154
+ await new Promise((resolve, reject) => {
155
+ const timeout = setTimeout(() => {
156
+ resolve(); // Don't reject, assume it's ready
157
+ }, 5000);
158
+ this.masterProcess.on('message', (message) => {
159
+ if (message && message.type === 'ready') {
160
+ clearTimeout(timeout);
161
+ resolve();
162
+ }
163
+ });
164
+ this.masterProcess.on('error', (error) => {
165
+ clearTimeout(timeout);
166
+ reject(error);
167
+ });
168
+ this.masterProcess.on('exit', (code) => {
169
+ clearTimeout(timeout);
170
+ if (code !== 0) {
171
+ reject(new Error(`Process exited with code ${code}`));
172
+ }
173
+ else {
174
+ resolve();
175
+ }
176
+ });
177
+ });
178
+ if (this.options.verbose) {
179
+ this.log(`Process started (PID: ${this.masterProcess.pid})`);
180
+ }
181
+ }
182
+ shouldFilterMessage(message) {
183
+ const filters = [
184
+ '[dotenv@',
185
+ 'injecting env',
186
+ 'Express (',
187
+ 'Local: http://localhost:',
188
+ 'Health Check: http://localhost:',
189
+ 'Environment: production',
190
+ 'Environment: development'
191
+ ];
192
+ return filters.some(filter => message.includes(filter));
193
+ }
99
194
  async startWorker(workerId) {
100
195
  var _a, _b;
101
196
  const nodeArgs = this.getNodeArgs();
102
- const basePort = this.options.port || 8000;
103
- const workerPort = this.options.workers > 1 ? basePort + workerId - 1 : basePort;
197
+ const port = this.options.port || 8000;
104
198
  const env = {
105
199
  ...process.env,
106
200
  NODE_ENV: process.env.NODE_ENV || 'production',
107
201
  WORKER_ID: workerId.toString(),
108
- PORT: workerPort.toString(),
202
+ PORT: port.toString(),
109
203
  CLUSTER_WORKER: 'true',
204
+ MASTER_PROCESS: 'false',
110
205
  FORCE_COLOR: this.options.color ? '1' : '0',
111
- // Prevent dotenv from loading again in worker processes
112
- DOTENV_CONFIG_PATH: '',
113
- NODE_OPTIONS: '--no-deprecation'
206
+ NODE_OPTIONS: '--no-deprecation',
207
+ SUPPRESS_STARTUP_LOGS: 'true' // Signal to suppress duplicate logs
114
208
  };
209
+ if (this.options.verbose) {
210
+ this.log(`Starting worker ${workerId}`);
211
+ }
115
212
  const workerProcess = (0, child_process_1.fork)(this.options.file, [], {
116
213
  cwd: this.options.workingDir,
117
214
  env,
118
215
  execArgv: nodeArgs,
119
- silent: true // Capture output to avoid duplication
216
+ silent: true
120
217
  });
121
218
  const workerInfo = {
122
219
  process: workerProcess,
123
220
  pid: workerProcess.pid,
124
221
  restarts: 0,
125
222
  startTime: new Date(),
126
- id: workerId
223
+ id: workerId,
224
+ port: port,
225
+ ready: false
127
226
  };
128
227
  this.workers.set(workerId, workerInfo);
129
- // Handle worker output with proper prefixing
228
+ // Handle worker output with filtering
130
229
  (_a = workerProcess.stdout) === null || _a === void 0 ? void 0 : _a.on('data', (data) => {
131
230
  const message = data.toString().trim();
132
- if (message) {
133
- // Filter out repetitive dotenv messages
134
- if (message.includes('[dotenv@') || message.includes('injecting env')) {
135
- return;
136
- }
231
+ if (message && !this.shouldFilterMessage(message)) {
137
232
  const prefix = this.options.verbose ?
138
- chalk_1.default.dim(`[Worker ${workerId}:${workerPort}] `) : '';
233
+ chalk_1.default.dim(`[Worker ${workerId}] `) : '';
139
234
  console.log(prefix + message);
140
235
  }
141
236
  });
142
237
  (_b = workerProcess.stderr) === null || _b === void 0 ? void 0 : _b.on('data', (data) => {
143
238
  const message = data.toString().trim();
144
- if (message) {
145
- // Filter out non-critical warnings
146
- if (message.includes('[dotenv@') || message.includes('injecting env')) {
147
- return;
148
- }
239
+ if (message && !this.shouldFilterMessage(message)) {
149
240
  const prefix = this.options.verbose ?
150
- chalk_1.default.dim(`[Worker ${workerId}:${workerPort}] `) : '';
241
+ chalk_1.default.dim(`[Worker ${workerId}] `) : '';
151
242
  console.error(prefix + chalk_1.default.red(message));
152
243
  }
153
244
  });
@@ -156,21 +247,23 @@ class StartManager {
156
247
  });
157
248
  workerProcess.on('exit', (code, signal) => {
158
249
  this.workers.delete(workerId);
159
- if (!this.isShuttingDown) {
160
- if (code !== 0 && signal !== 'SIGTERM') {
161
- this.log(`Worker ${workerId} crashed (code: ${code}, signal: ${signal})`, 'error');
162
- this.restartWorker(workerId);
163
- }
250
+ if (!this.isShuttingDown && code !== 0 && signal !== 'SIGTERM') {
251
+ this.log(`Worker ${workerId} crashed (code: ${code}, signal: ${signal})`, 'error');
252
+ this.restartWorker(workerId);
164
253
  }
165
254
  });
166
255
  // Wait for worker to be ready
167
256
  await new Promise((resolve, reject) => {
168
257
  const timeout = setTimeout(() => {
169
- reject(new Error(`Worker ${workerId} failed to start within timeout`));
170
- }, 10000);
258
+ workerInfo.ready = true;
259
+ this.readyWorkers++;
260
+ resolve(); // Don't reject, assume it's ready
261
+ }, 5000);
171
262
  workerProcess.on('message', (message) => {
172
263
  if (message && message.type === 'ready') {
173
264
  clearTimeout(timeout);
265
+ workerInfo.ready = true;
266
+ this.readyWorkers++;
174
267
  resolve();
175
268
  }
176
269
  });
@@ -179,19 +272,17 @@ class StartManager {
179
272
  reject(error);
180
273
  });
181
274
  workerProcess.on('exit', (code) => {
275
+ clearTimeout(timeout);
182
276
  if (code !== 0) {
183
- clearTimeout(timeout);
184
277
  reject(new Error(`Worker ${workerId} exited with code ${code}`));
185
278
  }
279
+ else {
280
+ resolve();
281
+ }
186
282
  });
187
- // Fallback - assume ready after 2 seconds if no message
188
- setTimeout(() => {
189
- clearTimeout(timeout);
190
- resolve();
191
- }, 2000);
192
283
  });
193
284
  if (this.options.verbose) {
194
- this.log(`Worker ${workerId} started (PID: ${workerProcess.pid}, Port: ${workerPort})`);
285
+ this.log(`Worker ${workerId} started (PID: ${workerProcess.pid})`);
195
286
  }
196
287
  return workerInfo;
197
288
  }
@@ -235,6 +326,12 @@ class StartManager {
235
326
  });
236
327
  }
237
328
  async startCluster() {
329
+ if (this.options.workers === 1) {
330
+ await this.startSingleProcess();
331
+ return;
332
+ }
333
+ // Multi-worker mode
334
+ this.readyWorkers = 0;
238
335
  const startPromises = [];
239
336
  for (let i = 0; i < this.options.workers; i++) {
240
337
  startPromises.push(this.startWorker(i + 1));
@@ -260,19 +357,27 @@ class StartManager {
260
357
  return;
261
358
  }
262
359
  if (req.url === '/health') {
360
+ const activeWorkers = this.options.workers === 1 ?
361
+ (this.masterProcess ? 1 : 0) :
362
+ this.workers.size;
263
363
  const stats = {
264
364
  status: 'ok',
265
365
  uptime: Date.now() - this.startTime.getTime(),
266
- workers: this.workers.size,
267
- activeWorkers: Array.from(this.workers.values()).map(w => ({
268
- id: w.id,
269
- pid: w.pid,
270
- restarts: w.restarts,
271
- uptime: Date.now() - w.startTime.getTime()
272
- })),
366
+ workers: activeWorkers,
367
+ expectedWorkers: this.options.workers,
368
+ activeWorkers: this.options.workers === 1 ?
369
+ (this.masterProcess ? [{ id: 1, pid: this.masterProcess.pid, uptime: Date.now() - this.startTime.getTime() }] : []) :
370
+ Array.from(this.workers.values()).map(w => ({
371
+ id: w.id,
372
+ pid: w.pid,
373
+ restarts: w.restarts,
374
+ uptime: Date.now() - w.startTime.getTime(),
375
+ ready: w.ready
376
+ })),
273
377
  totalRestarts: this.totalRestarts,
274
378
  memory: process.memoryUsage(),
275
- cpu: os_1.default.loadavg()
379
+ cpu: os_1.default.loadavg(),
380
+ port: this.options.port || 8000
276
381
  };
277
382
  res.writeHead(200, { 'Content-Type': 'application/json' });
278
383
  res.end(JSON.stringify(stats, null, 2));
@@ -321,67 +426,53 @@ class StartManager {
321
426
  async restartAll() {
322
427
  if (this.isShuttingDown)
323
428
  return;
324
- this.log('Restarting all workers due to file changes...');
325
- const restartPromises = [];
326
- for (const [workerId, workerInfo] of this.workers.entries()) {
327
- restartPromises.push((async () => {
328
- try {
329
- workerInfo.process.kill('SIGTERM');
330
- await this.waitForProcessExit(workerInfo.process, 5000);
331
- }
332
- catch (error) {
333
- workerInfo.process.kill('SIGKILL');
334
- }
335
- })());
336
- }
337
- await Promise.allSettled(restartPromises);
338
- // Wait a bit before restarting
339
- setTimeout(() => {
340
- this.startCluster();
341
- }, this.options.restartDelay);
342
- }
343
- setupMemoryMonitoring() {
344
- if (!this.options.maxMemory)
345
- return;
346
- const maxMemory = this.parseMemoryLimit(this.options.maxMemory);
347
- if (!maxMemory)
348
- return;
349
- const checkInterval = setInterval(() => {
350
- if (this.isShuttingDown) {
351
- clearInterval(checkInterval);
352
- return;
429
+ this.log('Restarting due to file changes...');
430
+ if (this.options.workers === 1 && this.masterProcess) {
431
+ try {
432
+ this.masterProcess.kill('SIGTERM');
433
+ await this.waitForProcessExit(this.masterProcess, 5000);
353
434
  }
354
- this.workers.forEach((workerInfo, workerId) => {
355
- try {
356
- // This is a simplified check - in practice, you'd need to get actual worker memory usage
357
- const usage = process.memoryUsage();
358
- if (usage.heapUsed > maxMemory) {
359
- this.log(`Worker ${workerId} may have exceeded memory limit, restarting`, 'warn');
360
- this.restartWorker(workerId);
435
+ catch (error) {
436
+ this.masterProcess.kill('SIGKILL');
437
+ }
438
+ setTimeout(() => {
439
+ this.startSingleProcess();
440
+ }, this.options.restartDelay);
441
+ }
442
+ else {
443
+ const restartPromises = [];
444
+ for (const [workerId, workerInfo] of this.workers.entries()) {
445
+ restartPromises.push((async () => {
446
+ try {
447
+ workerInfo.process.kill('SIGTERM');
448
+ await this.waitForProcessExit(workerInfo.process, 5000);
361
449
  }
362
- }
363
- catch (error) {
364
- // Ignore monitoring errors
365
- }
366
- });
367
- }, 30000); // Check every 30 seconds
450
+ catch (error) {
451
+ workerInfo.process.kill('SIGKILL');
452
+ }
453
+ })());
454
+ }
455
+ await Promise.allSettled(restartPromises);
456
+ setTimeout(() => {
457
+ this.startCluster();
458
+ }, this.options.restartDelay);
459
+ }
368
460
  }
369
461
  async start() {
370
462
  try {
371
- // Load environment variables only once in the main process
463
+ // Load environment variables
372
464
  this.loadEnvFile();
373
465
  // Set up monitoring and health checks
374
466
  this.setupHealthCheck();
375
467
  this.setupWatcher();
376
- this.setupMemoryMonitoring();
377
- // Start worker cluster
468
+ // Start the application
378
469
  await this.startCluster();
379
470
  // Success message
380
- const basePort = this.options.port || 8000;
381
- const portInfo = this.options.workers > 1 ?
382
- ` on ports ${basePort}-${basePort + this.options.workers - 1}` :
383
- ` on port ${basePort}`;
384
- logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.green(figures_1.default.tick)} Server ready${portInfo} (${this.workers.size} workers)`, 'info');
471
+ const port = this.options.port || 8000;
472
+ const actualWorkers = this.options.workers === 1 ? 1 : this.workers.size;
473
+ const workerInfo = this.options.workers === 1 ?
474
+ '' : ` (${actualWorkers} workers)`;
475
+ logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.green(figures_1.default.tick)} Server ready on port ${port}${workerInfo}`, 'info');
385
476
  }
386
477
  catch (error) {
387
478
  this.log(`Failed to start server: ${error.message}`, 'error');
@@ -399,6 +490,17 @@ class StartManager {
399
490
  if (this.healthServer) {
400
491
  this.healthServer.close();
401
492
  }
493
+ // Stop single process
494
+ if (this.masterProcess) {
495
+ try {
496
+ this.masterProcess.kill('SIGTERM');
497
+ await this.waitForProcessExit(this.masterProcess, this.options.gracefulTimeout);
498
+ }
499
+ catch (error) {
500
+ this.masterProcess.kill('SIGKILL');
501
+ }
502
+ }
503
+ // Stop workers
402
504
  const shutdownPromises = [];
403
505
  for (const [workerId, workerInfo] of this.workers.entries()) {
404
506
  shutdownPromises.push((async () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "neex",
3
- "version": "0.6.54",
3
+ "version": "0.6.60",
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",