nx 22.3.3 → 22.4.0-beta.0

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.
Files changed (39) hide show
  1. package/package.json +11 -11
  2. package/src/command-line/graph/graph.d.ts.map +1 -1
  3. package/src/command-line/graph/graph.js +90 -57
  4. package/src/command-line/watch/watch.d.ts.map +1 -1
  5. package/src/command-line/watch/watch.js +22 -6
  6. package/src/config/nx-json.d.ts +5 -0
  7. package/src/config/nx-json.d.ts.map +1 -1
  8. package/src/daemon/cache.d.ts.map +1 -1
  9. package/src/daemon/cache.js +9 -3
  10. package/src/daemon/client/client.d.ts +20 -3
  11. package/src/daemon/client/client.d.ts.map +1 -1
  12. package/src/daemon/client/client.js +410 -81
  13. package/src/daemon/client/daemon-socket-messenger.d.ts +5 -2
  14. package/src/daemon/client/daemon-socket-messenger.d.ts.map +1 -1
  15. package/src/daemon/client/daemon-socket-messenger.js +28 -6
  16. package/src/daemon/logger.d.ts +26 -0
  17. package/src/daemon/logger.d.ts.map +1 -0
  18. package/src/daemon/logger.js +65 -0
  19. package/src/daemon/server/file-watching/file-change-events.js +1 -1
  20. package/src/daemon/server/handle-process-in-background.js +1 -1
  21. package/src/daemon/server/handle-request-project-graph.js +1 -1
  22. package/src/daemon/server/nx-console-operations.js +1 -1
  23. package/src/daemon/server/project-graph-incremental-recomputation.d.ts +1 -1
  24. package/src/daemon/server/project-graph-incremental-recomputation.d.ts.map +1 -1
  25. package/src/daemon/server/project-graph-incremental-recomputation.js +7 -7
  26. package/src/daemon/server/project-graph-listener-sockets.d.ts +1 -1
  27. package/src/daemon/server/project-graph-listener-sockets.d.ts.map +1 -1
  28. package/src/daemon/server/project-graph-listener-sockets.js +2 -2
  29. package/src/daemon/server/server.d.ts.map +1 -1
  30. package/src/daemon/server/server.js +34 -18
  31. package/src/daemon/server/shutdown-utils.d.ts +1 -0
  32. package/src/daemon/server/shutdown-utils.d.ts.map +1 -1
  33. package/src/daemon/server/shutdown-utils.js +52 -1
  34. package/src/daemon/server/sync-generators.js +1 -1
  35. package/src/native/nx.wasm32-wasi.wasm +0 -0
  36. package/src/project-graph/nx-deps-cache.js +1 -1
  37. package/src/daemon/server/logger.d.ts +0 -19
  38. package/src/daemon/server/logger.d.ts.map +0 -1
  39. package/src/daemon/server/logger.js +0 -38
@@ -1,14 +1,27 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.DaemonSocketMessenger = void 0;
3
+ exports.DaemonSocketMessenger = exports.VersionMismatchError = void 0;
4
4
  const perf_hooks_1 = require("perf_hooks");
5
5
  const consume_messages_from_socket_1 = require("../../utils/consume-messages-from-socket");
6
6
  const socket_utils_1 = require("../socket-utils");
7
+ const logger_1 = require("../logger");
8
+ class VersionMismatchError extends Error {
9
+ constructor() {
10
+ super('Version mismatch with daemon server');
11
+ this.name = 'VersionMismatchError';
12
+ Object.setPrototypeOf(this, VersionMismatchError.prototype);
13
+ }
14
+ }
15
+ exports.VersionMismatchError = VersionMismatchError;
7
16
  class DaemonSocketMessenger {
8
17
  constructor(socket) {
9
18
  this.socket = socket;
10
19
  }
11
- async sendMessage(messageToDaemon, force) {
20
+ sendMessage(messageToDaemon, force) {
21
+ if (!this.socket) {
22
+ throw new Error('Socket not initialized.');
23
+ }
24
+ logger_1.clientLogger.log('[Messenger] Sending message type:', messageToDaemon.type);
12
25
  perf_hooks_1.performance.mark('daemon-message-serialization-start-' + messageToDaemon.type);
13
26
  const serialized = (0, socket_utils_1.serialize)(messageToDaemon, force);
14
27
  perf_hooks_1.performance.mark('daemon-message-serialization-end-' + messageToDaemon.type);
@@ -16,17 +29,26 @@ class DaemonSocketMessenger {
16
29
  this.socket.write(serialized);
17
30
  // send EOT to indicate that the message has been fully written
18
31
  this.socket.write(consume_messages_from_socket_1.MESSAGE_END_SEQ);
32
+ logger_1.clientLogger.log('[Messenger] Message sent');
19
33
  }
20
- listen(onData, onClose = () => { }, onError = (err) => { }) {
34
+ listen(onData, onClose = () => { }, onError = () => { }) {
35
+ logger_1.clientLogger.log('[Messenger] Setting up socket listeners');
36
+ this.socket.on('close', onClose);
37
+ this.socket.on('error', (err) => {
38
+ logger_1.clientLogger.log('[Messenger] Socket error:', err.message);
39
+ onError(err);
40
+ });
21
41
  this.socket.on('data', (0, consume_messages_from_socket_1.consumeMessagesFromSocket)(async (message) => {
42
+ logger_1.clientLogger.log('[Messenger] Received message, length:', message.length);
22
43
  onData(message);
23
44
  }));
24
- this.socket.on('close', onClose);
25
- this.socket.on('error', onError);
45
+ logger_1.clientLogger.log('[Messenger] listen() complete');
26
46
  return this;
27
47
  }
28
48
  close() {
29
- this.socket.destroy();
49
+ if (this.socket) {
50
+ this.socket.destroy();
51
+ }
30
52
  }
31
53
  }
32
54
  exports.DaemonSocketMessenger = DaemonSocketMessenger;
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Unified logger for daemon server and client.
3
+ *
4
+ * To improve the overall readability of the logs, we categorize things by "trigger":
5
+ *
6
+ * - [REQUEST] meaning that the current set of actions were triggered by a client request to the server
7
+ * - [WATCHER] meaning the current set of actions were triggered by handling changes to the workspace files
8
+ *
9
+ * We keep those two "triggers" left aligned at the top level and then indent subsequent logs so that there is a
10
+ * logical hierarchy/grouping.
11
+ */
12
+ type LogSource = 'Server' | 'Client';
13
+ declare class DaemonLogger {
14
+ private source;
15
+ constructor(source: LogSource);
16
+ log(...s: unknown[]): void;
17
+ requestLog(...s: unknown[]): void;
18
+ watcherLog(...s: unknown[]): void;
19
+ private writeToFile;
20
+ private formatLogMessage;
21
+ private getNow;
22
+ }
23
+ export declare const serverLogger: DaemonLogger;
24
+ export declare const clientLogger: DaemonLogger;
25
+ export {};
26
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../../../../packages/nx/src/daemon/logger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AASH,KAAK,SAAS,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAErC,cAAM,YAAY;IACJ,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,SAAS;IAErC,GAAG,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE;IAqBnB,UAAU,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE;IAI1B,UAAU,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE;IAI1B,OAAO,CAAC,WAAW;IAWnB,OAAO,CAAC,gBAAgB;IAMxB,OAAO,CAAC,MAAM;CAGf;AAED,eAAO,MAAM,YAAY,cAA6B,CAAC;AACvD,eAAO,MAAM,YAAY,cAA6B,CAAC"}
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ /**
3
+ * Unified logger for daemon server and client.
4
+ *
5
+ * To improve the overall readability of the logs, we categorize things by "trigger":
6
+ *
7
+ * - [REQUEST] meaning that the current set of actions were triggered by a client request to the server
8
+ * - [WATCHER] meaning the current set of actions were triggered by handling changes to the workspace files
9
+ *
10
+ * We keep those two "triggers" left aligned at the top level and then indent subsequent logs so that there is a
11
+ * logical hierarchy/grouping.
12
+ */
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ exports.clientLogger = exports.serverLogger = void 0;
15
+ const fs_1 = require("fs");
16
+ const tmp_dir_1 = require("./tmp-dir");
17
+ const versions_1 = require("../utils/versions");
18
+ class DaemonLogger {
19
+ constructor(source) {
20
+ this.source = source;
21
+ }
22
+ log(...s) {
23
+ const message = this.formatLogMessage(s
24
+ .map((val) => {
25
+ if (typeof val === 'string') {
26
+ return val;
27
+ }
28
+ return JSON.stringify(val);
29
+ })
30
+ .join(' '));
31
+ if (this.source === 'Server') {
32
+ // Server's stdout is redirected to daemon.log
33
+ console.log(message);
34
+ }
35
+ else {
36
+ // Client writes directly to the log file
37
+ this.writeToFile(message);
38
+ }
39
+ }
40
+ requestLog(...s) {
41
+ this.log(`[REQUEST]: ${s.join(' ')}`);
42
+ }
43
+ watcherLog(...s) {
44
+ this.log(`[WATCHER]: ${s.join(' ')}`);
45
+ }
46
+ writeToFile(message) {
47
+ try {
48
+ if (!(0, fs_1.existsSync)(tmp_dir_1.DAEMON_DIR_FOR_CURRENT_WORKSPACE)) {
49
+ (0, fs_1.mkdirSync)(tmp_dir_1.DAEMON_DIR_FOR_CURRENT_WORKSPACE, { recursive: true });
50
+ }
51
+ (0, fs_1.appendFileSync)(tmp_dir_1.DAEMON_OUTPUT_LOG_FILE, message + '\n');
52
+ }
53
+ catch {
54
+ // Ignore write errors
55
+ }
56
+ }
57
+ formatLogMessage(message) {
58
+ return `[NX v${versions_1.nxVersion} Daemon ${this.source}] - ${this.getNow()} - ${message}`;
59
+ }
60
+ getNow() {
61
+ return new Date(Date.now()).toISOString();
62
+ }
63
+ }
64
+ exports.serverLogger = new DaemonLogger('Server');
65
+ exports.clientLogger = new DaemonLogger('Client');
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.registerFileChangeListener = registerFileChangeListener;
4
4
  exports.notifyFileChangeListeners = notifyFileChangeListeners;
5
- const logger_1 = require("../logger");
5
+ const logger_1 = require("../../logger");
6
6
  const fileChangeListeners = new Set();
7
7
  function registerFileChangeListener(listener) {
8
8
  fileChangeListeners.add(listener);
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.handleProcessInBackground = handleProcessInBackground;
4
- const logger_1 = require("./logger");
4
+ const logger_1 = require("../logger");
5
5
  const installation_directory_1 = require("../../utils/installation-directory");
6
6
  async function handleProcessInBackground(payload) {
7
7
  let fn;
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.handleRequestProjectGraph = handleRequestProjectGraph;
4
4
  const perf_hooks_1 = require("perf_hooks");
5
5
  const socket_utils_1 = require("../socket-utils");
6
- const logger_1 = require("./logger");
6
+ const logger_1 = require("../logger");
7
7
  const project_graph_incremental_recomputation_1 = require("./project-graph-incremental-recomputation");
8
8
  async function handleRequestProjectGraph() {
9
9
  try {
@@ -8,7 +8,7 @@ exports.handleNxConsolePreferenceAndInstallImpl = handleNxConsolePreferenceAndIn
8
8
  const devkit_internals_1 = require("../../devkit-internals");
9
9
  const os_1 = require("os");
10
10
  const native_1 = require("../../native");
11
- const logger_1 = require("./logger");
11
+ const logger_1 = require("../logger");
12
12
  // Module-level state - persists across invocations within daemon lifecycle
13
13
  let latestNxTmpPath = null;
14
14
  let cleanupFn = null;
@@ -22,6 +22,6 @@ export declare let currentProjectFileMapCache: FileMapCache | undefined;
22
22
  export declare let currentProjectGraph: ProjectGraph | undefined;
23
23
  export declare function getCachedSerializedProjectGraphPromise(): Promise<SerializedProjectGraph>;
24
24
  export declare function addUpdatedAndDeletedFiles(createdFiles: string[], updatedFiles: string[], deletedFiles: string[]): void;
25
- export declare function registerProjectGraphRecomputationListener(listener: (projectGraph: ProjectGraph, sourceMaps: ConfigurationSourceMaps) => void): void;
25
+ export declare function registerProjectGraphRecomputationListener(listener: (projectGraph: ProjectGraph, sourceMaps: ConfigurationSourceMaps, error: Error | null) => void): void;
26
26
  export {};
27
27
  //# sourceMappingURL=project-graph-incremental-recomputation.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"project-graph-incremental-recomputation.d.ts","sourceRoot":"","sources":["../../../../../../packages/nx/src/daemon/server/project-graph-incremental-recomputation.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,QAAQ,EACR,OAAO,EACP,YAAY,EAEb,MAAM,4BAA4B,CAAC;AAKpC,OAAO,EACL,YAAY,EAIb,MAAM,mCAAmC,CAAC;AAe3C,OAAO,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC;AACzD,OAAO,EAEL,uBAAuB,EACxB,MAAM,uDAAuD,CAAC;AAS/D,UAAU,sBAAsB;IAC9B,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,YAAY,EAAE,YAAY,GAAG,IAAI,CAAC;IAClC,mBAAmB,EAAE,YAAY,GAAG,IAAI,CAAC;IACzC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IACxB,iBAAiB,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC;IACrC,sBAAsB,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,UAAU,EAAE,uBAAuB,GAAG,IAAI,CAAC;IAC3C,cAAc,EAAE,yBAAyB,GAAG,IAAI,CAAC;CAClD;AAGD,eAAO,IAAI,gBAAgB,EACvB;IACE,OAAO,EAAE,OAAO,CAAC;IACjB,iBAAiB,EAAE,QAAQ,EAAE,CAAC;IAC9B,cAAc,EAAE,yBAAyB,CAAC;CAC3C,GACD,SAAS,CAAC;AACd,eAAO,IAAI,0BAA0B,EAAE,YAAY,GAAG,SAAS,CAAC;AAChE,eAAO,IAAI,mBAAmB,EAAE,YAAY,GAAG,SAAS,CAAC;AAYzD,wBAAsB,sCAAsC,IAAI,OAAO,CAAC,sBAAsB,CAAC,CA+E9F;AAED,wBAAgB,yBAAyB,CACvC,YAAY,EAAE,MAAM,EAAE,EACtB,YAAY,EAAE,MAAM,EAAE,EACtB,YAAY,EAAE,MAAM,EAAE,QAgDvB;AAED,wBAAgB,yCAAyC,CACvD,QAAQ,EAAE,CACR,YAAY,EAAE,YAAY,EAC1B,UAAU,EAAE,uBAAuB,KAChC,IAAI,QAGV"}
1
+ {"version":3,"file":"project-graph-incremental-recomputation.d.ts","sourceRoot":"","sources":["../../../../../../packages/nx/src/daemon/server/project-graph-incremental-recomputation.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,QAAQ,EACR,OAAO,EACP,YAAY,EAEb,MAAM,4BAA4B,CAAC;AAKpC,OAAO,EACL,YAAY,EAIb,MAAM,mCAAmC,CAAC;AAe3C,OAAO,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC;AACzD,OAAO,EAEL,uBAAuB,EACxB,MAAM,uDAAuD,CAAC;AAS/D,UAAU,sBAAsB;IAC9B,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,YAAY,EAAE,YAAY,GAAG,IAAI,CAAC;IAClC,mBAAmB,EAAE,YAAY,GAAG,IAAI,CAAC;IACzC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IACxB,iBAAiB,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC;IACrC,sBAAsB,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,UAAU,EAAE,uBAAuB,GAAG,IAAI,CAAC;IAC3C,cAAc,EAAE,yBAAyB,GAAG,IAAI,CAAC;CAClD;AAGD,eAAO,IAAI,gBAAgB,EACvB;IACE,OAAO,EAAE,OAAO,CAAC;IACjB,iBAAiB,EAAE,QAAQ,EAAE,CAAC;IAC9B,cAAc,EAAE,yBAAyB,CAAC;CAC3C,GACD,SAAS,CAAC;AACd,eAAO,IAAI,0BAA0B,EAAE,YAAY,GAAG,SAAS,CAAC;AAChE,eAAO,IAAI,mBAAmB,EAAE,YAAY,GAAG,SAAS,CAAC;AAgBzD,wBAAsB,sCAAsC,IAAI,OAAO,CAAC,sBAAsB,CAAC,CAgF9F;AAED,wBAAgB,yBAAyB,CACvC,YAAY,EAAE,MAAM,EAAE,EACtB,YAAY,EAAE,MAAM,EAAE,EACtB,YAAY,EAAE,MAAM,EAAE,QAgDvB;AAED,wBAAgB,yCAAyC,CACvD,QAAQ,EAAE,CACR,YAAY,EAAE,YAAY,EAC1B,UAAU,EAAE,uBAAuB,EACnC,KAAK,EAAE,KAAK,GAAG,IAAI,KAChB,IAAI,QAGV"}
@@ -17,7 +17,7 @@ const workspace_root_1 = require("../../utils/workspace-root");
17
17
  const file_watcher_sockets_1 = require("./file-watching/file-watcher-sockets");
18
18
  const file_change_events_1 = require("./file-watching/file-change-events");
19
19
  const project_graph_listener_sockets_1 = require("./project-graph-listener-sockets");
20
- const logger_1 = require("./logger");
20
+ const logger_1 = require("../logger");
21
21
  const error_types_1 = require("../../project-graph/error-types");
22
22
  const get_plugins_1 = require("../../project-graph/plugins/get-plugins");
23
23
  let cachedSerializedProjectGraphPromise;
@@ -58,7 +58,7 @@ async function getCachedSerializedProjectGraphPromise() {
58
58
  }
59
59
  const result = await cachedSerializedProjectGraphPromise;
60
60
  if (wasScheduled) {
61
- notifyProjectGraphRecomputationListeners(result.projectGraph, result.sourceMaps);
61
+ notifyProjectGraphRecomputationListeners(result.projectGraph, result.sourceMaps, result.error);
62
62
  }
63
63
  const errors = result.error
64
64
  ? result.error instanceof error_types_1.DaemonProjectGraphError
@@ -119,11 +119,11 @@ function addUpdatedAndDeletedFiles(createdFiles, updatedFiles, deletedFiles) {
119
119
  }
120
120
  cachedSerializedProjectGraphPromise =
121
121
  processFilesAndCreateAndSerializeProjectGraph(await (0, get_plugins_1.getPlugins)());
122
- const { projectGraph, sourceMaps } = await cachedSerializedProjectGraphPromise;
122
+ const { projectGraph, sourceMaps, error } = await cachedSerializedProjectGraphPromise;
123
123
  if (createdFiles.length > 0) {
124
124
  (0, file_watcher_sockets_1.notifyFileWatcherSockets)(createdFiles, null, null);
125
125
  }
126
- notifyProjectGraphRecomputationListeners(projectGraph, sourceMaps);
126
+ notifyProjectGraphRecomputationListeners(projectGraph, sourceMaps, error);
127
127
  }, waitPeriod);
128
128
  }
129
129
  }
@@ -325,9 +325,9 @@ async function resetInternalStateIfNxDepsMissing() {
325
325
  await resetInternalState();
326
326
  }
327
327
  }
328
- function notifyProjectGraphRecomputationListeners(projectGraph, sourceMaps) {
328
+ function notifyProjectGraphRecomputationListeners(projectGraph, sourceMaps, error) {
329
329
  for (const listener of projectGraphRecomputationListeners) {
330
- listener(projectGraph, sourceMaps);
330
+ listener(projectGraph, sourceMaps, error);
331
331
  }
332
- (0, project_graph_listener_sockets_1.notifyProjectGraphListenerSockets)(projectGraph, sourceMaps);
332
+ (0, project_graph_listener_sockets_1.notifyProjectGraphListenerSockets)(projectGraph, sourceMaps, error);
333
333
  }
@@ -4,5 +4,5 @@ import { ConfigurationSourceMaps } from '../../project-graph/utils/project-confi
4
4
  export declare let registeredProjectGraphListenerSockets: Socket[];
5
5
  export declare function removeRegisteredProjectGraphListenerSocket(socket: Socket): void;
6
6
  export declare function hasRegisteredProjectGraphListenerSockets(): boolean;
7
- export declare function notifyProjectGraphListenerSockets(projectGraph: ProjectGraph, sourceMaps: ConfigurationSourceMaps): Promise<void>;
7
+ export declare function notifyProjectGraphListenerSockets(projectGraph: ProjectGraph, sourceMaps: ConfigurationSourceMaps, error: Error | null): Promise<void>;
8
8
  //# sourceMappingURL=project-graph-listener-sockets.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"project-graph-listener-sockets.d.ts","sourceRoot":"","sources":["../../../../../../packages/nx/src/daemon/server/project-graph-listener-sockets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,KAAK,CAAC;AAC7B,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,uBAAuB,EAAE,MAAM,uDAAuD,CAAC;AAIhG,eAAO,IAAI,qCAAqC,EAAE,MAAM,EAAO,CAAC;AAEhE,wBAAgB,0CAA0C,CAAC,MAAM,EAAE,MAAM,QAGxE;AAED,wBAAgB,wCAAwC,YAEvD;AAED,wBAAsB,iCAAiC,CACrD,YAAY,EAAE,YAAY,EAC1B,UAAU,EAAE,uBAAuB,iBAoBpC"}
1
+ {"version":3,"file":"project-graph-listener-sockets.d.ts","sourceRoot":"","sources":["../../../../../../packages/nx/src/daemon/server/project-graph-listener-sockets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,KAAK,CAAC;AAC7B,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,uBAAuB,EAAE,MAAM,uDAAuD,CAAC;AAIhG,eAAO,IAAI,qCAAqC,EAAE,MAAM,EAAO,CAAC;AAEhE,wBAAgB,0CAA0C,CAAC,MAAM,EAAE,MAAM,QAGxE;AAED,wBAAgB,wCAAwC,YAEvD;AAED,wBAAsB,iCAAiC,CACrD,YAAY,EAAE,YAAY,EAC1B,UAAU,EAAE,uBAAuB,EACnC,KAAK,EAAE,KAAK,GAAG,IAAI,iBAoBpB"}
@@ -14,12 +14,12 @@ function removeRegisteredProjectGraphListenerSocket(socket) {
14
14
  function hasRegisteredProjectGraphListenerSockets() {
15
15
  return exports.registeredProjectGraphListenerSockets.length > 0;
16
16
  }
17
- async function notifyProjectGraphListenerSockets(projectGraph, sourceMaps) {
17
+ async function notifyProjectGraphListenerSockets(projectGraph, sourceMaps, error) {
18
18
  if (!hasRegisteredProjectGraphListenerSockets()) {
19
19
  return;
20
20
  }
21
21
  await Promise.all(exports.registeredProjectGraphListenerSockets.map((socket) => (0, server_1.handleResult)(socket, 'PROJECT_GRAPH_UPDATED', () => Promise.resolve({
22
22
  description: 'Project graph updated',
23
- response: { projectGraph, sourceMaps },
23
+ response: { projectGraph, sourceMaps, error },
24
24
  }), (0, is_v8_serializer_enabled_1.isV8SerializerEnabled)() ? 'v8' : 'json')));
25
25
  }
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../../../../packages/nx/src/daemon/server/server.ts"],"names":[],"mappings":"AACA,OAAO,EAAgB,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,CAAC;AAmKnD,MAAM,MAAM,aAAa,GAAG;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,GAAG,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;CACtC,CAAC;AAGF,eAAO,MAAM,WAAW,EAAE,GAAG,CAAC,MAAM,CAAa,CAAC;AA8RlD,wBAAsB,YAAY,CAChC,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,OAAO,CAAC,aAAa,CAAC,EAClC,IAAI,EAAE,MAAM,GAAG,IAAI,iBA6BpB;AAoLD,wBAAsB,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC,CA2EnD"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../../../../packages/nx/src/daemon/server/server.ts"],"names":[],"mappings":"AACA,OAAO,EAAgB,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,CAAC;AAwKnD,MAAM,MAAM,aAAa,GAAG;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,GAAG,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;CACtC,CAAC;AAGF,eAAO,MAAM,WAAW,EAAE,GAAG,CAAC,MAAM,CAAa,CAAC;AAsRlD,wBAAsB,YAAY,CAChC,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,OAAO,CAAC,aAAa,CAAC,EAClC,IAAI,EAAE,MAAM,GAAG,IAAI,iBA6BpB;AA+KD,wBAAsB,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC,CA2GnD"}
@@ -23,7 +23,7 @@ const handle_outputs_tracking_1 = require("./handle-outputs-tracking");
23
23
  const handle_process_in_background_1 = require("./handle-process-in-background");
24
24
  const handle_request_project_graph_1 = require("./handle-request-project-graph");
25
25
  const handle_request_shutdown_1 = require("./handle-request-shutdown");
26
- const logger_1 = require("./logger");
26
+ const logger_1 = require("../logger");
27
27
  const outputs_tracking_1 = require("./outputs-tracking");
28
28
  const project_graph_incremental_recomputation_1 = require("./project-graph-incremental-recomputation");
29
29
  const shutdown_utils_1 = require("./shutdown-utils");
@@ -96,10 +96,6 @@ async function handleMessage(socket, data) {
96
96
  if (workspaceWatcherError) {
97
97
  await (0, shutdown_utils_1.respondWithErrorAndExit)(socket, `File watcher error in the workspace '${workspace_root_1.workspaceRoot}'.`, workspaceWatcherError);
98
98
  }
99
- const outdated = daemonIsOutdated();
100
- if (outdated) {
101
- await (0, shutdown_utils_1.respondWithErrorAndExit)(socket, `Daemon outdated`, new Error(outdated));
102
- }
103
99
  (0, shutdown_utils_1.resetInactivityTimeout)(handleInactivityTimeout);
104
100
  const unparsedPayload = data;
105
101
  let payload;
@@ -275,17 +271,18 @@ function daemonIsOutdated() {
275
271
  return null;
276
272
  }
277
273
  function lockFileHashChanged() {
278
- const lockHashes = [
274
+ const lockFiles = [
279
275
  (0, path_1.join)(workspace_root_1.workspaceRoot, 'package-lock.json'),
280
276
  (0, path_1.join)(workspace_root_1.workspaceRoot, 'yarn.lock'),
281
277
  (0, path_1.join)(workspace_root_1.workspaceRoot, 'pnpm-lock.yaml'),
282
278
  (0, path_1.join)(workspace_root_1.workspaceRoot, 'bun.lockb'),
283
279
  (0, path_1.join)(workspace_root_1.workspaceRoot, 'bun.lock'),
284
- ]
285
- .filter((file) => (0, fs_1.existsSync)(file))
286
- .map((file) => (0, native_1.hashFile)(file));
280
+ ];
281
+ const existingFiles = lockFiles.filter((file) => (0, fs_1.existsSync)(file));
282
+ const lockHashes = existingFiles.map((file) => (0, native_1.hashFile)(file));
287
283
  const newHash = (0, file_hasher_1.hashArray)(lockHashes);
288
284
  if (existingLockHash && newHash != existingLockHash) {
285
+ logger_1.serverLogger.log(`[Server] lock file hash changed! old=${existingLockHash}, new=${newHash}`);
289
286
  existingLockHash = newHash;
290
287
  return true;
291
288
  }
@@ -306,15 +303,6 @@ const handleWorkspaceChanges = async (err, changeEvents) => {
306
303
  }
307
304
  try {
308
305
  (0, shutdown_utils_1.resetInactivityTimeout)(handleInactivityTimeout);
309
- const outdatedReason = daemonIsOutdated();
310
- if (outdatedReason) {
311
- await (0, shutdown_utils_1.handleServerProcessTermination)({
312
- server,
313
- reason: outdatedReason,
314
- sockets: exports.openSockets,
315
- });
316
- return;
317
- }
318
306
  if (err) {
319
307
  let error = typeof err === 'string' ? new Error(err) : err;
320
308
  logger_1.serverLogger.watcherLog('Unexpected workspace watcher error', error.message);
@@ -381,6 +369,11 @@ const handleOutputsChanges = async (err, changeEvents) => {
381
369
  async function startServer() {
382
370
  (0, workspace_context_1.setupWorkspaceContext)(workspace_root_1.workspaceRoot);
383
371
  const socketPath = (0, socket_utils_1.getFullOsSocketPath)();
372
+ // Log daemon startup information for debugging
373
+ logger_1.serverLogger.log(`New daemon starting from: ${__filename}`);
374
+ logger_1.serverLogger.log(`New daemon __dirname: ${__dirname}`);
375
+ logger_1.serverLogger.log(`New daemon nxVersion: ${versions_1.nxVersion}`);
376
+ logger_1.serverLogger.log(`New daemon getInstalledNxVersion(): ${(0, is_nx_version_mismatch_1.getInstalledNxVersion)()}`);
384
377
  // Persist metadata about the background process so that it can be cleaned up later if needed
385
378
  await (0, cache_1.writeDaemonJsonProcessCache)({
386
379
  processId: process.pid,
@@ -391,6 +384,7 @@ async function startServer() {
391
384
  if (!socket_utils_1.isWindows) {
392
385
  (0, socket_utils_1.killSocketOrPath)();
393
386
  }
387
+ logger_1.serverLogger.log(`[Server] Starting outdated check interval (20ms)`);
394
388
  setInterval(() => {
395
389
  if ((0, cache_1.getDaemonProcessIdSync)() !== process.pid) {
396
390
  return (0, shutdown_utils_1.handleServerProcessTermination)({
@@ -399,6 +393,28 @@ async function startServer() {
399
393
  sockets: exports.openSockets,
400
394
  });
401
395
  }
396
+ const outdated = daemonIsOutdated();
397
+ if (outdated) {
398
+ logger_1.serverLogger.log(`[Server] Daemon outdated: ${outdated}`);
399
+ if (outdated === 'LOCK_FILES_CHANGED') {
400
+ // Lock file changes - restart daemon, clients will reconnect
401
+ logger_1.serverLogger.log('[Server] Restarting daemon...');
402
+ (0, shutdown_utils_1.handleServerProcessTerminationWithRestart)({
403
+ server,
404
+ reason: outdated,
405
+ sockets: exports.openSockets,
406
+ });
407
+ }
408
+ else {
409
+ // Version changes or other reasons - just shut down, don't restart
410
+ logger_1.serverLogger.log('[Server] Shutting down daemon (no restart)...');
411
+ (0, shutdown_utils_1.handleServerProcessTermination)({
412
+ server,
413
+ reason: outdated,
414
+ sockets: exports.openSockets,
415
+ });
416
+ }
417
+ }
402
418
  }, 20).unref();
403
419
  return new Promise(async (resolve, reject) => {
404
420
  try {
@@ -11,6 +11,7 @@ interface HandleServerProcessTerminationParams {
11
11
  sockets: Iterable<Socket>;
12
12
  }
13
13
  export declare function handleServerProcessTermination({ server, reason, sockets, }: HandleServerProcessTerminationParams): Promise<void>;
14
+ export declare function handleServerProcessTerminationWithRestart({ server, reason, sockets, }: HandleServerProcessTerminationParams): Promise<void>;
14
15
  export declare function resetInactivityTimeout(cb: () => void): void;
15
16
  export declare function respondToClient(socket: Socket, response: string, description: string): Promise<unknown>;
16
17
  export declare function respondWithErrorAndExit(socket: Socket, description: string, error: Error): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"shutdown-utils.d.ts","sourceRoot":"","sources":["../../../../../../packages/nx/src/daemon/server/shutdown-utils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,CAAC;AAI1C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAU5C,eAAO,MAAM,4BAA4B,EAAG,QAAiB,CAAC;AAI9D,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,OAAO,QAErD;AAED,wBAAgB,kBAAkB,YAEjC;AAID,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,OAAO,QAE3D;AAED,wBAAgB,wBAAwB,YAEvC;AAED,UAAU,oCAAoC;IAC5C,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;CAC3B;AAED,wBAAsB,8BAA8B,CAAC,EACnD,MAAM,EACN,MAAM,EACN,OAAO,GACR,EAAE,oCAAoC,iBAsCtC;AAID,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,MAAM,IAAI,GAAG,IAAI,CAK3D;AAED,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,oBAcpB;AAED,wBAAsB,uBAAuB,CAC3C,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,KAAK,iBAsBb"}
1
+ {"version":3,"file":"shutdown-utils.d.ts","sourceRoot":"","sources":["../../../../../../packages/nx/src/daemon/server/shutdown-utils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,CAAC;AAI1C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAkB5C,eAAO,MAAM,4BAA4B,EAAG,QAAiB,CAAC;AA6C9D,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,OAAO,QAErD;AAED,wBAAgB,kBAAkB,YAEjC;AAID,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,OAAO,QAE3D;AAED,wBAAgB,wBAAwB,YAEvC;AAED,UAAU,oCAAoC;IAC5C,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;CAC3B;AAED,wBAAsB,8BAA8B,CAAC,EACnD,MAAM,EACN,MAAM,EACN,OAAO,GACR,EAAE,oCAAoC,iBAEtC;AAED,wBAAsB,yCAAyC,CAAC,EAC9D,MAAM,EACN,MAAM,EACN,OAAO,GACR,EAAE,oCAAoC,iBAMtC;AAgDD,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,MAAM,IAAI,GAAG,IAAI,CAK3D;AAED,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,oBAcpB;AAED,wBAAsB,uBAAuB,CAC3C,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,KAAK,iBAsBb"}
@@ -6,11 +6,12 @@ exports.getWatcherInstance = getWatcherInstance;
6
6
  exports.storeOutputWatcherInstance = storeOutputWatcherInstance;
7
7
  exports.getOutputWatcherInstance = getOutputWatcherInstance;
8
8
  exports.handleServerProcessTermination = handleServerProcessTermination;
9
+ exports.handleServerProcessTerminationWithRestart = handleServerProcessTerminationWithRestart;
9
10
  exports.resetInactivityTimeout = resetInactivityTimeout;
10
11
  exports.respondToClient = respondToClient;
11
12
  exports.respondWithErrorAndExit = respondWithErrorAndExit;
12
13
  const workspace_root_1 = require("../../utils/workspace-root");
13
- const logger_1 = require("./logger");
14
+ const logger_1 = require("../logger");
14
15
  const socket_utils_1 = require("../socket-utils");
15
16
  const cache_1 = require("../cache");
16
17
  const error_types_1 = require("../../project-graph/error-types");
@@ -18,7 +19,47 @@ const db_connection_1 = require("../../utils/db-connection");
18
19
  const get_plugins_1 = require("../../project-graph/plugins/get-plugins");
19
20
  const consume_messages_from_socket_1 = require("../../utils/consume-messages-from-socket");
20
21
  const nx_console_operations_1 = require("./nx-console-operations");
22
+ const child_process_1 = require("child_process");
23
+ const path_1 = require("path");
24
+ const node_fs_1 = require("node:fs");
25
+ const promises_1 = require("fs/promises");
26
+ const tmp_dir_1 = require("../tmp-dir");
21
27
  exports.SERVER_INACTIVITY_TIMEOUT_MS = 10800000; // 10800000 ms = 3 hours
28
+ async function startNewDaemonInBackground() {
29
+ (0, node_fs_1.mkdirSync)(tmp_dir_1.DAEMON_DIR_FOR_CURRENT_WORKSPACE, { recursive: true });
30
+ if (!(0, node_fs_1.existsSync)(tmp_dir_1.DAEMON_OUTPUT_LOG_FILE)) {
31
+ (0, node_fs_1.writeFileSync)(tmp_dir_1.DAEMON_OUTPUT_LOG_FILE, '');
32
+ }
33
+ const out = await (0, promises_1.open)(tmp_dir_1.DAEMON_OUTPUT_LOG_FILE, 'a');
34
+ const err = await (0, promises_1.open)(tmp_dir_1.DAEMON_OUTPUT_LOG_FILE, 'a');
35
+ // Use require.resolve to find the currently installed version's start.js
36
+ // instead of using __dirname which points to the old running daemon's path
37
+ // Resolve from workspace root to pick up the correct symlink target
38
+ let startScriptPath;
39
+ try {
40
+ startScriptPath = require.resolve('nx/src/daemon/server/start.js', {
41
+ paths: [workspace_root_1.workspaceRoot],
42
+ });
43
+ }
44
+ catch (e) {
45
+ // Fall back to using __dirname if resolution fails
46
+ logger_1.serverLogger.log(`Failed to resolve nx package, falling back to __dirname: ${e.message}`);
47
+ startScriptPath = (0, path_1.join)(__dirname, '../server/start.js');
48
+ }
49
+ logger_1.serverLogger.log(`Restarting daemon with script: ${startScriptPath}`);
50
+ logger_1.serverLogger.log(`Old daemon __dirname: ${__dirname}`);
51
+ logger_1.serverLogger.log(`Current process.execPath: ${process.execPath}`);
52
+ const backgroundProcess = (0, child_process_1.spawn)(process.execPath, [startScriptPath], {
53
+ cwd: workspace_root_1.workspaceRoot,
54
+ stdio: ['ignore', out.fd, err.fd],
55
+ detached: true,
56
+ windowsHide: false,
57
+ shell: false,
58
+ env: process.env,
59
+ });
60
+ backgroundProcess.unref();
61
+ logger_1.serverLogger.log('Started new daemon process in background');
62
+ }
22
63
  let watcherInstance;
23
64
  function storeWatcherInstance(instance) {
24
65
  watcherInstance = instance;
@@ -34,6 +75,16 @@ function getOutputWatcherInstance() {
34
75
  return outputWatcherInstance;
35
76
  }
36
77
  async function handleServerProcessTermination({ server, reason, sockets, }) {
78
+ await performShutdown(server, reason, sockets);
79
+ }
80
+ async function handleServerProcessTerminationWithRestart({ server, reason, sockets, }) {
81
+ // Clean up old daemon cache before starting new instance
82
+ (0, cache_1.deleteDaemonJsonProcessCache)();
83
+ // Start new daemon before shutting down
84
+ await startNewDaemonInBackground();
85
+ await performShutdown(server, reason, sockets);
86
+ }
87
+ async function performShutdown(server, reason, sockets) {
37
88
  try {
38
89
  await new Promise((res) => {
39
90
  server.close(() => {
@@ -12,7 +12,7 @@ const file_hasher_1 = require("../../hasher/file-hasher");
12
12
  const project_graph_1 = require("../../project-graph/project-graph");
13
13
  const sync_generators_1 = require("../../utils/sync-generators");
14
14
  const workspace_root_1 = require("../../utils/workspace-root");
15
- const logger_1 = require("./logger");
15
+ const logger_1 = require("../logger");
16
16
  const project_graph_incremental_recomputation_1 = require("./project-graph-incremental-recomputation");
17
17
  const syncGeneratorsCacheResultPromises = new Map();
18
18
  let registeredTaskSyncGenerators = new Set();
Binary file
@@ -17,7 +17,7 @@ const fileutils_1 = require("../utils/fileutils");
17
17
  const versions_1 = require("../utils/versions");
18
18
  const error_types_1 = require("./error-types");
19
19
  const is_on_daemon_1 = require("../daemon/is-on-daemon");
20
- const logger_1 = require("../daemon/server/logger");
20
+ const logger_1 = require("../daemon/logger");
21
21
  exports.nxProjectGraph = (0, path_1.join)(cache_directory_1.workspaceDataDirectory, 'project-graph.json');
22
22
  exports.nxFileMap = (0, path_1.join)(cache_directory_1.workspaceDataDirectory, 'file-map.json');
23
23
  exports.nxSourceMaps = (0, path_1.join)(cache_directory_1.workspaceDataDirectory, 'source-maps.json');
@@ -1,19 +0,0 @@
1
- /**
2
- * To improve the overall readibility of the logs, we categorize things by "trigger":
3
- *
4
- * - [REQUEST] meaning that the current set of actions were triggered by a client request to the server
5
- * - [WATCHER] meaning the the current set of actions were triggered by handling changes to the workspace files
6
- *
7
- * We keep those two "triggers" left aligned at the top level and then indent subsequent logs so that there is a
8
- * logical hierarchy/grouping.
9
- */
10
- declare class ServerLogger {
11
- log(...s: unknown[]): void;
12
- requestLog(...s: unknown[]): void;
13
- watcherLog(...s: unknown[]): void;
14
- private formatLogMessage;
15
- private getNow;
16
- }
17
- export declare const serverLogger: ServerLogger;
18
- export {};
19
- //# sourceMappingURL=logger.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../../../../../packages/nx/src/daemon/server/logger.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,cAAM,YAAY;IAChB,GAAG,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE;IAenB,UAAU,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE;IAI1B,UAAU,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE;IAI1B,OAAO,CAAC,gBAAgB;IAIxB,OAAO,CAAC,MAAM;CAGf;AAED,eAAO,MAAM,YAAY,cAAqB,CAAC"}
@@ -1,38 +0,0 @@
1
- "use strict";
2
- /**
3
- * To improve the overall readibility of the logs, we categorize things by "trigger":
4
- *
5
- * - [REQUEST] meaning that the current set of actions were triggered by a client request to the server
6
- * - [WATCHER] meaning the the current set of actions were triggered by handling changes to the workspace files
7
- *
8
- * We keep those two "triggers" left aligned at the top level and then indent subsequent logs so that there is a
9
- * logical hierarchy/grouping.
10
- */
11
- Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.serverLogger = void 0;
13
- const versions_1 = require("../../utils/versions");
14
- class ServerLogger {
15
- log(...s) {
16
- console.log(this.formatLogMessage(`${s
17
- .map((val) => {
18
- if (typeof val === 'string') {
19
- return val;
20
- }
21
- return JSON.stringify(val);
22
- })
23
- .join(' ')}`));
24
- }
25
- requestLog(...s) {
26
- this.log(`[REQUEST]: ${s.join(' ')}`);
27
- }
28
- watcherLog(...s) {
29
- this.log(`[WATCHER]: ${s.join(' ')}`);
30
- }
31
- formatLogMessage(message) {
32
- return `[NX v${versions_1.nxVersion} Daemon Server] - ${this.getNow()} - ${message}`;
33
- }
34
- getNow() {
35
- return new Date(Date.now()).toISOString();
36
- }
37
- }
38
- exports.serverLogger = new ServerLogger();