nx 23.2.0-beta.1 → 23.2.0-beta.2

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 (37) hide show
  1. package/dist/src/analytics/analytics.d.ts +6 -0
  2. package/dist/src/analytics/analytics.js +7 -1
  3. package/dist/src/analytics/index.d.ts +1 -1
  4. package/dist/src/analytics/index.js +2 -1
  5. package/dist/src/command-line/init/implementation/angular/integrated-workspace.js +2 -5
  6. package/dist/src/command-line/init/implementation/angular/legacy-angular-versions.js +3 -0
  7. package/dist/src/command-line/init/implementation/dot-nx/add-nx-scripts.js +4 -1
  8. package/dist/src/command-line/migrate/migrate.js +4 -0
  9. package/dist/src/command-line/nx-cloud/connect/view-logs.js +2 -0
  10. package/dist/src/command-line/show/show-target/inputs.js +50 -153
  11. package/dist/src/command-line/show/show-target/outputs.js +48 -173
  12. package/dist/src/command-line/show/show-target/utils.d.ts +28 -0
  13. package/dist/src/command-line/show/show-target/utils.js +83 -3
  14. package/dist/src/command-line/yargs-utils/shared-options.d.ts +1 -1
  15. package/dist/src/core/graph/main.js +1 -1
  16. package/dist/src/daemon/server/handle-tasks-execution-hooks.d.ts +1 -1
  17. package/dist/src/daemon/server/server.js +7 -4
  18. package/dist/src/devkit-internals.d.ts +1 -0
  19. package/dist/src/devkit-internals.js +5 -2
  20. package/dist/src/hasher/check-task-files.d.ts +86 -0
  21. package/dist/src/hasher/check-task-files.js +378 -0
  22. package/dist/src/native/index.d.ts +25 -2
  23. package/dist/src/native/native-bindings.js +2 -0
  24. package/dist/src/native/nx.wasm32-wasi.debug.wasm +0 -0
  25. package/dist/src/native/nx.wasm32-wasi.wasm +0 -0
  26. package/dist/src/plugins/js/lock-file/utils/pnpm-normalizer.js +3 -0
  27. package/dist/src/project-graph/build-project-graph.js +7 -1
  28. package/dist/src/project-graph/plugins/loaded-nx-plugin.js +1 -0
  29. package/dist/src/project-graph/project-graph.js +3 -0
  30. package/dist/src/tasks-runner/life-cycle.d.ts +2 -2
  31. package/dist/src/tasks-runner/life-cycle.js +2 -2
  32. package/dist/src/tasks-runner/pseudo-terminal.d.ts +1 -1
  33. package/dist/src/tasks-runner/pseudo-terminal.js +2 -2
  34. package/dist/src/tasks-runner/task-orchestrator.d.ts +4 -1
  35. package/dist/src/tasks-runner/task-orchestrator.js +23 -6
  36. package/dist/src/utils/acknowledge-build-scripts.js +7 -5
  37. package/package.json +11 -11
@@ -244,6 +244,7 @@ async function createProjectGraphAndSourceMapsAsync(opts = {
244
244
  track: true,
245
245
  ...(analytics_1.customDimensions && {
246
246
  [analytics_1.customDimensions.projectCount]: Object.keys(currentProjectGraph.nodes).length,
247
+ [analytics_1.customDimensions.sampleRate]: analytics_1.PERF_SPAN_SAMPLE_RATE,
247
248
  }),
248
249
  },
249
250
  });
@@ -310,6 +311,7 @@ async function createProjectGraphAndSourceMapsAsync(opts = {
310
311
  ...(analytics_1.customDimensions && {
311
312
  [analytics_1.customDimensions.projectCount]: Object.keys(res.projectGraph.nodes)
312
313
  .length,
314
+ [analytics_1.customDimensions.sampleRate]: analytics_1.PERF_SPAN_SAMPLE_RATE,
313
315
  }),
314
316
  },
315
317
  });
@@ -333,6 +335,7 @@ async function createProjectGraphAndSourceMapsAsync(opts = {
333
335
  track: true,
334
336
  ...(analytics_1.customDimensions && {
335
337
  [analytics_1.customDimensions.projectCount]: Object.keys(projectGraphAndSourceMaps.projectGraph.nodes).length,
338
+ [analytics_1.customDimensions.sampleRate]: analytics_1.PERF_SPAN_SAMPLE_RATE,
336
339
  }),
337
340
  },
338
341
  });
@@ -44,7 +44,7 @@ export interface LifeCycle {
44
44
  startTasks?(task: Task[], metadata: TaskMetadata): void | Promise<void>;
45
45
  endTasks?(taskResults: TaskResult[], metadata: TaskMetadata): void | Promise<void>;
46
46
  printTaskTerminalOutput?(task: Task, status: TaskStatus, output: string): void;
47
- registerRunningTask?(taskId: string, parserAndWriter: ExternalObject<[any, any]>): void;
47
+ registerRunningTask?(taskId: string, ptyHandles: ExternalObject<[any, any, any]>): void;
48
48
  registerRunningTaskWithEmptyParser?(taskId: string): void;
49
49
  appendTaskOutput?(taskId: string, output: string, isPtyTask: boolean): void;
50
50
  setTaskStatus?(taskId: string, status: NativeTaskStatus): void;
@@ -72,7 +72,7 @@ export declare class CompositeLifeCycle implements LifeCycle {
72
72
  startTasks(tasks: Task[], metadata: TaskMetadata): Promise<void>;
73
73
  endTasks(taskResults: TaskResult[], metadata: TaskMetadata): Promise<void>;
74
74
  printTaskTerminalOutput(task: Task, status: TaskStatus, output: string): void;
75
- registerRunningTask(taskId: string, parserAndWriter: ExternalObject<[any, any]>): void;
75
+ registerRunningTask(taskId: string, ptyHandles: ExternalObject<[any, any, any]>): void;
76
76
  registerRunningTaskWithEmptyParser(taskId: string): void;
77
77
  appendTaskOutput(taskId: string, output: string, isPtyTask: boolean): void;
78
78
  setTaskStatus(taskId: string, status: NativeTaskStatus): void;
@@ -67,10 +67,10 @@ class CompositeLifeCycle {
67
67
  }
68
68
  }
69
69
  }
70
- registerRunningTask(taskId, parserAndWriter) {
70
+ registerRunningTask(taskId, ptyHandles) {
71
71
  for (let l of this.lifeCycles) {
72
72
  if (l.registerRunningTask) {
73
- l.registerRunningTask(taskId, parserAndWriter);
73
+ l.registerRunningTask(taskId, ptyHandles);
74
74
  }
75
75
  }
76
76
  }
@@ -47,7 +47,7 @@ export declare class PseudoTtyProcess implements RunningTask {
47
47
  onOutput(callback: (message: string) => void): void;
48
48
  getPid(): number | undefined;
49
49
  kill(s?: NodeJS.Signals): Promise<void>;
50
- getParserAndWriter(): import("../native").ExternalObject<[import("../native").ParserArc, import("../native").WriterArc]>;
50
+ getPtyHandles(): import("../native").ExternalObject<[import("../native").ParserArc, import("../native").WriterArc, import("../native").MasterArc]>;
51
51
  }
52
52
  export declare class PseudoTtyProcessWithSend extends PseudoTtyProcess {
53
53
  rustPseudoTerminal: RustPseudoTerminal;
@@ -150,8 +150,8 @@ class PseudoTtyProcess {
150
150
  }
151
151
  }
152
152
  }
153
- getParserAndWriter() {
154
- return this.childProcess.getParserAndWriter();
153
+ getPtyHandles() {
154
+ return this.childProcess.getPtyHandles();
155
155
  }
156
156
  }
157
157
  exports.PseudoTtyProcess = PseudoTtyProcess;
@@ -35,6 +35,7 @@ export declare class TaskOrchestrator {
35
35
  private reverseTaskDeps;
36
36
  private initializingTaskIds;
37
37
  private processedTasks;
38
+ private cacheMissedHashes;
38
39
  private completedTasks;
39
40
  private waitingForTasks;
40
41
  private pendingDiscreteWorkers;
@@ -100,7 +101,9 @@ export declare class TaskOrchestrator {
100
101
  * The coordinator relies on this running unconditionally (when cache
101
102
  * is enabled): tasks dispatched in step 5 via runTaskDirectly skip
102
103
  * their own cache lookup on the assumption that this has already
103
- * confirmed them as misses. Don't add length-based bails.
104
+ * confirmed them as misses. Excluding cacheMissedHashes preserves that
105
+ * invariant — every dispatched hash was queried exactly once — but
106
+ * don't add other length-based bails.
104
107
  */
105
108
  private resolveCachedTasksBulk;
106
109
  /**
@@ -79,6 +79,12 @@ class TaskOrchestrator {
79
79
  // underlying real tasks become the anchors.
80
80
  this.initializingTaskIds = (0, utils_1.expandInitiatingTasksThroughNoop)(this.initiatingTasks, this.taskGraph, this.projectGraph);
81
81
  this.processedTasks = new Map();
82
+ // Hashes confirmed absent from the cache this run. A confirmed miss can
83
+ // only become a hit when the task itself runs — and then it leaves the
84
+ // schedule — so a missed hash never needs re-querying. Without this, a
85
+ // miss waiting for a worker slot is re-queried (including the remote
86
+ // retrieval) on every coordinator cycle.
87
+ this.cacheMissedHashes = new Set();
82
88
  this.completedTasks = new Map();
83
89
  this.waitingForTasks = [];
84
90
  this.pendingDiscreteWorkers = new Set();
@@ -324,9 +330,12 @@ class TaskOrchestrator {
324
330
  * inside DbCache.getBatch.
325
331
  */
326
332
  async fetchCacheHits(tasks) {
327
- const batchResults = await this.cache.getBatch(tasks);
333
+ const tasksToQuery = tasks.filter((t) => t.hash && !this.cacheMissedHashes.has(t.hash));
334
+ if (tasksToQuery.length === 0)
335
+ return [];
336
+ const batchResults = await this.cache.getBatch(tasksToQuery);
328
337
  const cacheHits = [];
329
- for (const task of tasks) {
338
+ for (const task of tasksToQuery) {
330
339
  const cachedResult = batchResults.get(task.hash);
331
340
  // Replay a cached result only under the same condition it was cached
332
341
  // under (shouldCacheTaskResult): successes always, failures only when
@@ -335,6 +344,9 @@ class TaskOrchestrator {
335
344
  if (cachedResult && this.shouldCacheTaskResult(task, cachedResult.code)) {
336
345
  cacheHits.push({ task, cachedResult });
337
346
  }
347
+ else {
348
+ this.cacheMissedHashes.add(task.hash);
349
+ }
338
350
  }
339
351
  return cacheHits;
340
352
  }
@@ -396,14 +408,19 @@ class TaskOrchestrator {
396
408
  * The coordinator relies on this running unconditionally (when cache
397
409
  * is enabled): tasks dispatched in step 5 via runTaskDirectly skip
398
410
  * their own cache lookup on the assumption that this has already
399
- * confirmed them as misses. Don't add length-based bails.
411
+ * confirmed them as misses. Excluding cacheMissedHashes preserves that
412
+ * invariant — every dispatched hash was queried exactly once — but
413
+ * don't add other length-based bails.
400
414
  */
401
415
  async resolveCachedTasksBulk() {
402
416
  const { scheduledTasks } = this.tasksSchedule.getAllScheduledTasks();
403
417
  const candidates = [];
404
418
  for (const id of scheduledTasks) {
405
419
  const task = this.taskGraph.tasks[id];
406
- if (task.hash && !task.continuous && task.cache) {
420
+ if (task.hash &&
421
+ !this.cacheMissedHashes.has(task.hash) &&
422
+ !task.continuous &&
423
+ task.cache) {
407
424
  candidates.push(task);
408
425
  }
409
426
  }
@@ -790,7 +807,7 @@ class TaskOrchestrator {
790
807
  else if (this.tuiEnabled) {
791
808
  if (runningTask instanceof pseudo_terminal_1.PseudoTtyProcess) {
792
809
  // This is an external of a the pseudo terminal where a task is running and can be passed to the TUI
793
- this.options.lifeCycle.registerRunningTask(task.id, runningTask.getParserAndWriter());
810
+ this.options.lifeCycle.registerRunningTask(task.id, runningTask.getPtyHandles());
794
811
  runningTask.onOutput((output) => {
795
812
  this.options.lifeCycle.appendTaskOutput(task.id, output, true);
796
813
  });
@@ -839,7 +856,7 @@ class TaskOrchestrator {
839
856
  if (this.tuiEnabled) {
840
857
  if (runningTask instanceof pseudo_terminal_1.PseudoTtyProcess) {
841
858
  // This is an external of a the pseudo terminal where a task is running and can be passed to the TUI
842
- this.options.lifeCycle.registerRunningTask(task.id, runningTask.getParserAndWriter());
859
+ this.options.lifeCycle.registerRunningTask(task.id, runningTask.getPtyHandles());
843
860
  runningTask.onOutput((output) => {
844
861
  this.options.lifeCycle.appendTaskOutput(task.id, output, true);
845
862
  });
@@ -7,6 +7,7 @@ const yaml_1 = require("yaml");
7
7
  const semver_1 = require("semver");
8
8
  const package_manager_1 = require("./package-manager");
9
9
  const fileutils_1 = require("./fileutils");
10
+ const json_1 = require("./json");
10
11
  const PNPM_WORKSPACE_FILE = 'pnpm-workspace.yaml';
11
12
  /**
12
13
  * Records build-script decisions for dependencies that are about to be
@@ -42,23 +43,24 @@ function acknowledgePnpmBuildScripts(treeOrRoot, entries) {
42
43
  // A file that doesn't parse cleanly or whose root isn't a mapping is
43
44
  // malformed for pnpm; leave it alone rather than crashing or replacing the
44
45
  // user's content. pnpm's own error on the file is the actionable signal.
46
+ // Empty and comment-only files have no contents at all; setIn creates the
47
+ // mapping for them while keeping whatever comments they carry.
45
48
  if (parsed.errors.length > 0 ||
46
49
  (parsed.contents != null && !(parsed.contents instanceof yaml_1.YAMLMap))) {
47
50
  return;
48
51
  }
49
- const doc = parsed.contents instanceof yaml_1.YAMLMap ? parsed : new yaml_1.Document({});
50
52
  let changed = false;
51
53
  for (const [pkg, allowed] of Object.entries(entries)) {
52
54
  // Only a real boolean is a user decision. pnpm's non-strict installs stub
53
55
  // undecided packages with a placeholder string ("set this to true or
54
56
  // false"), which would fail the next strict install if left in place.
55
- if (typeof doc.getIn(['allowBuilds', pkg]) !== 'boolean') {
56
- doc.setIn(['allowBuilds', pkg], allowed);
57
+ if (typeof parsed.getIn(['allowBuilds', pkg]) !== 'boolean') {
58
+ parsed.setIn(['allowBuilds', pkg], allowed);
57
59
  changed = true;
58
60
  }
59
61
  }
60
62
  if (changed) {
61
- host.write(PNPM_WORKSPACE_FILE, doc.toString());
63
+ host.write(PNPM_WORKSPACE_FILE, parsed.toString());
62
64
  }
63
65
  }
64
66
  function createHost(treeOrRoot) {
@@ -76,7 +78,7 @@ function createHost(treeOrRoot) {
76
78
  exists: (p) => treeOrRoot.exists(p),
77
79
  read: (p) => treeOrRoot.read(p, 'utf-8'),
78
80
  write: (p, c) => treeOrRoot.write(p, c),
79
- readJson: (p) => JSON.parse(treeOrRoot.read(p, 'utf-8')),
81
+ readJson: (p) => (0, json_1.parseJson)(treeOrRoot.read(p, 'utf-8')),
80
82
  };
81
83
  }
82
84
  function getPnpmVersion(host) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nx",
3
- "version": "23.2.0-beta.1",
3
+ "version": "23.2.0-beta.2",
4
4
  "private": false,
5
5
  "type": "commonjs",
6
6
  "description": "The core Nx plugin contains the core functionality of Nx like the project graph, nx commands and task orchestration.",
@@ -176,16 +176,16 @@
176
176
  }
177
177
  },
178
178
  "optionalDependencies": {
179
- "@nx/nx-darwin-arm64": "23.2.0-beta.1",
180
- "@nx/nx-darwin-x64": "23.2.0-beta.1",
181
- "@nx/nx-freebsd-x64": "23.2.0-beta.1",
182
- "@nx/nx-linux-arm-gnueabihf": "23.2.0-beta.1",
183
- "@nx/nx-linux-arm64-gnu": "23.2.0-beta.1",
184
- "@nx/nx-linux-arm64-musl": "23.2.0-beta.1",
185
- "@nx/nx-linux-x64-gnu": "23.2.0-beta.1",
186
- "@nx/nx-linux-x64-musl": "23.2.0-beta.1",
187
- "@nx/nx-win32-arm64-msvc": "23.2.0-beta.1",
188
- "@nx/nx-win32-x64-msvc": "23.2.0-beta.1"
179
+ "@nx/nx-darwin-arm64": "23.2.0-beta.2",
180
+ "@nx/nx-darwin-x64": "23.2.0-beta.2",
181
+ "@nx/nx-freebsd-x64": "23.2.0-beta.2",
182
+ "@nx/nx-linux-arm-gnueabihf": "23.2.0-beta.2",
183
+ "@nx/nx-linux-arm64-gnu": "23.2.0-beta.2",
184
+ "@nx/nx-linux-arm64-musl": "23.2.0-beta.2",
185
+ "@nx/nx-linux-x64-gnu": "23.2.0-beta.2",
186
+ "@nx/nx-linux-x64-musl": "23.2.0-beta.2",
187
+ "@nx/nx-win32-arm64-msvc": "23.2.0-beta.2",
188
+ "@nx/nx-win32-x64-msvc": "23.2.0-beta.2"
189
189
  },
190
190
  "nx-migrations": {
191
191
  "migrations": "./migrations.json",