nx 22.4.0-canary.20260109-0fe39b2 → 22.4.0-canary.20260112-6cca28c
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nx",
|
|
3
|
-
"version": "22.4.0-canary.
|
|
3
|
+
"version": "22.4.0-canary.20260112-6cca28c",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "The core Nx plugin contains the core functionality of Nx like the project graph, nx commands and task orchestration.",
|
|
6
6
|
"repository": {
|
|
@@ -83,16 +83,16 @@
|
|
|
83
83
|
}
|
|
84
84
|
},
|
|
85
85
|
"optionalDependencies": {
|
|
86
|
-
"@nx/nx-darwin-arm64": "22.4.0-canary.
|
|
87
|
-
"@nx/nx-darwin-x64": "22.4.0-canary.
|
|
88
|
-
"@nx/nx-freebsd-x64": "22.4.0-canary.
|
|
89
|
-
"@nx/nx-linux-arm-gnueabihf": "22.4.0-canary.
|
|
90
|
-
"@nx/nx-linux-arm64-gnu": "22.4.0-canary.
|
|
91
|
-
"@nx/nx-linux-arm64-musl": "22.4.0-canary.
|
|
92
|
-
"@nx/nx-linux-x64-gnu": "22.4.0-canary.
|
|
93
|
-
"@nx/nx-linux-x64-musl": "22.4.0-canary.
|
|
94
|
-
"@nx/nx-win32-arm64-msvc": "22.4.0-canary.
|
|
95
|
-
"@nx/nx-win32-x64-msvc": "22.4.0-canary.
|
|
86
|
+
"@nx/nx-darwin-arm64": "22.4.0-canary.20260112-6cca28c",
|
|
87
|
+
"@nx/nx-darwin-x64": "22.4.0-canary.20260112-6cca28c",
|
|
88
|
+
"@nx/nx-freebsd-x64": "22.4.0-canary.20260112-6cca28c",
|
|
89
|
+
"@nx/nx-linux-arm-gnueabihf": "22.4.0-canary.20260112-6cca28c",
|
|
90
|
+
"@nx/nx-linux-arm64-gnu": "22.4.0-canary.20260112-6cca28c",
|
|
91
|
+
"@nx/nx-linux-arm64-musl": "22.4.0-canary.20260112-6cca28c",
|
|
92
|
+
"@nx/nx-linux-x64-gnu": "22.4.0-canary.20260112-6cca28c",
|
|
93
|
+
"@nx/nx-linux-x64-musl": "22.4.0-canary.20260112-6cca28c",
|
|
94
|
+
"@nx/nx-win32-arm64-msvc": "22.4.0-canary.20260112-6cca28c",
|
|
95
|
+
"@nx/nx-win32-x64-msvc": "22.4.0-canary.20260112-6cca28c"
|
|
96
96
|
},
|
|
97
97
|
"nx-migrations": {
|
|
98
98
|
"migrations": "./migrations.json",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin-pool.d.ts","sourceRoot":"","sources":["../../../../../../../packages/nx/src/project-graph/plugins/isolation/plugin-pool.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"plugin-pool.d.ts","sourceRoot":"","sources":["../../../../../../../packages/nx/src/project-graph/plugins/isolation/plugin-pool.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAO9D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AA4C1D,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,mBAAmB,EAC3B,IAAI,EAAE,MAAM,EACZ,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC,CAAC,CAmGhD"}
|
|
@@ -2,13 +2,15 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.loadRemoteNxPlugin = loadRemoteNxPlugin;
|
|
4
4
|
const child_process_1 = require("child_process");
|
|
5
|
-
const path = require("path");
|
|
6
5
|
const net_1 = require("net");
|
|
6
|
+
const path = require("path");
|
|
7
|
+
// TODO (@AgentEnder): After scoped verbose logging is implemented, re-add verbose logs here.
|
|
8
|
+
// import { logger } from '../../utils/logger';
|
|
7
9
|
const socket_utils_1 = require("../../../daemon/socket-utils");
|
|
8
10
|
const consume_messages_from_socket_1 = require("../../../utils/consume-messages-from-socket");
|
|
9
|
-
const messaging_1 = require("./messaging");
|
|
10
11
|
const installation_directory_1 = require("../../../utils/installation-directory");
|
|
11
12
|
const resolve_plugin_1 = require("../resolve-plugin");
|
|
13
|
+
const messaging_1 = require("./messaging");
|
|
12
14
|
const cleanupFunctions = new Set();
|
|
13
15
|
const pluginNames = new Map();
|
|
14
16
|
const PLUGIN_TIMEOUT_HINT_TEXT = 'As a last resort, you can set NX_PLUGIN_NO_TIMEOUTS=true to bypass this timeout.';
|
|
@@ -60,6 +62,15 @@ async function loadRemoteNxPlugin(plugin, root, index) {
|
|
|
60
62
|
const exitHandler = createWorkerExitHandler(worker, pendingPromises);
|
|
61
63
|
const cleanupFunction = () => {
|
|
62
64
|
worker.off('exit', exitHandler);
|
|
65
|
+
// Unpipe streams to prevent hanging processes and release references
|
|
66
|
+
if (worker.stdout) {
|
|
67
|
+
worker.stdout.unpipe(process.stdout);
|
|
68
|
+
worker.stdout.destroy();
|
|
69
|
+
}
|
|
70
|
+
if (worker.stderr) {
|
|
71
|
+
worker.stderr.unpipe(process.stderr);
|
|
72
|
+
worker.stderr.destroy();
|
|
73
|
+
}
|
|
63
74
|
socket.destroy();
|
|
64
75
|
nxPluginWorkerCache.delete(cacheKey);
|
|
65
76
|
};
|
|
@@ -238,6 +249,13 @@ function createWorkerHandler(worker, pending, onload, onloadError, socket) {
|
|
|
238
249
|
}
|
|
239
250
|
function createWorkerExitHandler(worker, pendingPromises) {
|
|
240
251
|
return () => {
|
|
252
|
+
// Clean up piped streams when worker exits to prevent hanging
|
|
253
|
+
if (worker.stdout) {
|
|
254
|
+
worker.stdout.unpipe(process.stdout);
|
|
255
|
+
}
|
|
256
|
+
if (worker.stderr) {
|
|
257
|
+
worker.stderr.unpipe(process.stderr);
|
|
258
|
+
}
|
|
241
259
|
for (const [_, pendingPromise] of pendingPromises) {
|
|
242
260
|
pendingPromise.rejector(new Error(`Plugin worker ${pluginNames.get(worker) ?? worker.pid} exited unexpectedly with code ${worker.exitCode}`));
|
|
243
261
|
}
|
|
@@ -301,13 +319,56 @@ async function startPluginWorker(name) {
|
|
|
301
319
|
ipcPath,
|
|
302
320
|
name,
|
|
303
321
|
], {
|
|
304
|
-
stdio: '
|
|
322
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
305
323
|
env,
|
|
306
324
|
detached: true,
|
|
307
325
|
shell: false,
|
|
308
326
|
windowsHide: true,
|
|
309
327
|
});
|
|
328
|
+
// To make debugging easier and allow plugins to communicate things
|
|
329
|
+
// like performance metrics, we pipe the stdout/stderr of the worker
|
|
330
|
+
// to the main process.
|
|
331
|
+
// This adds one listener per plugin to a few events on process.stdout/stderr,
|
|
332
|
+
// so we need to increase the max listener count to avoid warnings.
|
|
333
|
+
//
|
|
334
|
+
// We originally used `inherit` for stdio, but that caused issues with
|
|
335
|
+
// some environments where the terminal was left in an inconsistent state
|
|
336
|
+
// that prevented `↑`/`↓` arrow keys from working correctly after Nx finished execution.
|
|
337
|
+
// Instead, they would print things like `^[[A`/`^[[B` to the terminal.
|
|
338
|
+
const stdoutMaxListeners = process.stdout.getMaxListeners();
|
|
339
|
+
const stderrMaxListeners = process.stderr.getMaxListeners();
|
|
340
|
+
if (stdoutMaxListeners !== 0) {
|
|
341
|
+
process.stdout.setMaxListeners(stdoutMaxListeners + 1);
|
|
342
|
+
}
|
|
343
|
+
if (stderrMaxListeners !== 0) {
|
|
344
|
+
process.stderr.setMaxListeners(stderrMaxListeners + 1);
|
|
345
|
+
}
|
|
346
|
+
worker.stdout.pipe(process.stdout);
|
|
347
|
+
worker.stderr.pipe(process.stderr);
|
|
348
|
+
// Unref the worker process so it doesn't prevent the parent from exiting.
|
|
349
|
+
// IMPORTANT: We must also unref the stdout/stderr streams. When streams are
|
|
350
|
+
// piped, they maintain internal references in Node's event loop. Without
|
|
351
|
+
// unreferencing them, the parent process will wait for the worker to exit
|
|
352
|
+
// even after worker.unref() is called. This causes e2e tests to hang on CI
|
|
353
|
+
// where test frameworks wait for all handles to be released.
|
|
354
|
+
//
|
|
355
|
+
// Although TypeScript types these as Readable/Writable, they are actually
|
|
356
|
+
// net.Socket instances at runtime. Node.js internally creates sockets for
|
|
357
|
+
// stdio pipes (see lib/internal/child_process.js createSocket function).
|
|
358
|
+
// Socket.unref() allows the event loop to exit if these are the only handles.
|
|
310
359
|
worker.unref();
|
|
360
|
+
if (worker.stdout instanceof net_1.Socket) {
|
|
361
|
+
worker.stdout.unref();
|
|
362
|
+
}
|
|
363
|
+
else {
|
|
364
|
+
throw new Error(`Expected worker.stdout to be an instance of Socket, but got ${getTypeName(worker.stdout)}`);
|
|
365
|
+
}
|
|
366
|
+
if (worker.stderr instanceof net_1.Socket) {
|
|
367
|
+
worker.stderr.unref();
|
|
368
|
+
}
|
|
369
|
+
else {
|
|
370
|
+
throw new Error(`Expected worker.stderr to be an instance of Socket, but got ${getTypeName(worker.stderr)}`);
|
|
371
|
+
}
|
|
311
372
|
let attempts = 0;
|
|
312
373
|
return new Promise((resolve, reject) => {
|
|
313
374
|
const id = setInterval(async () => {
|
|
@@ -346,3 +407,16 @@ function isServerAvailable(ipcPath) {
|
|
|
346
407
|
}
|
|
347
408
|
});
|
|
348
409
|
}
|
|
410
|
+
function getTypeName(u) {
|
|
411
|
+
if (u === null)
|
|
412
|
+
return 'null';
|
|
413
|
+
if (u === undefined)
|
|
414
|
+
return 'undefined';
|
|
415
|
+
if (typeof u !== 'object')
|
|
416
|
+
return typeof u;
|
|
417
|
+
if (Array.isArray(u)) {
|
|
418
|
+
const innerTypes = u.map((el) => getTypeName(el));
|
|
419
|
+
return `Array<${Array.from(new Set(innerTypes)).join('|')}>`;
|
|
420
|
+
}
|
|
421
|
+
return u.constructor?.name ?? 'unknown object';
|
|
422
|
+
}
|