nx 23.3.0-beta.5 → 23.3.0-beta.7

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 (112) hide show
  1. package/dist/nx-cloud-internals.d.ts +1 -0
  2. package/dist/nx-cloud-internals.js +9 -0
  3. package/dist/src/command-line/affected/affected.js +51 -9
  4. package/dist/src/command-line/graph/graph.d.ts +31 -0
  5. package/dist/src/command-line/graph/graph.js +71 -17
  6. package/dist/src/command-line/release/publish.js +7 -11
  7. package/dist/src/command-line/release/utils/get-touched-projects-for-group.js +3 -3
  8. package/dist/src/command-line/run/run-one.js +5 -1
  9. package/dist/src/command-line/run-many/run-many.js +6 -12
  10. package/dist/src/command-line/show/projects.js +30 -1
  11. package/dist/src/config/task-graph.d.ts +1 -1
  12. package/dist/src/config/workspace-json-project-json.d.ts +21 -1
  13. package/dist/src/core/graph/main.js +1 -1
  14. package/dist/src/core/graph/runtime.js +1 -1
  15. package/dist/src/core/graph/styles.js +1 -1
  16. package/dist/src/daemon/client/client.d.ts +7 -2
  17. package/dist/src/daemon/client/client.js +15 -2
  18. package/dist/src/daemon/message-types/io-snapshot-version.d.ts +5 -0
  19. package/dist/src/daemon/message-types/io-snapshot-version.js +2 -0
  20. package/dist/src/daemon/message-types/select-affected-tasks.d.ts +18 -0
  21. package/dist/src/daemon/message-types/select-affected-tasks.js +11 -0
  22. package/dist/src/daemon/server/handle-hash-tasks.d.ts +2 -0
  23. package/dist/src/daemon/server/handle-hash-tasks.js +5 -3
  24. package/dist/src/daemon/server/handle-select-affected-tasks.d.ts +3 -0
  25. package/dist/src/daemon/server/handle-select-affected-tasks.js +23 -0
  26. package/dist/src/daemon/server/io-snapshots-state.d.ts +7 -0
  27. package/dist/src/daemon/server/io-snapshots-state.js +35 -0
  28. package/dist/src/daemon/server/planning-context.d.ts +8 -0
  29. package/dist/src/daemon/server/planning-context.js +18 -0
  30. package/dist/src/daemon/server/server.d.ts +1 -0
  31. package/dist/src/daemon/server/server.js +6 -0
  32. package/dist/src/executors/run-commands/run-commands.impl.d.ts +2 -1
  33. package/dist/src/executors/run-commands/run-commands.impl.js +19 -5
  34. package/dist/src/executors/run-commands/running-tasks.d.ts +5 -4
  35. package/dist/src/executors/run-commands/running-tasks.js +13 -13
  36. package/dist/src/hasher/create-task-hasher.d.ts +8 -1
  37. package/dist/src/hasher/create-task-hasher.js +13 -3
  38. package/dist/src/hasher/hash-plan-inspector.js +2 -2
  39. package/dist/src/hasher/hash-task.d.ts +2 -2
  40. package/dist/src/hasher/hash-task.js +7 -1
  41. package/dist/src/hasher/native-task-hasher-impl.d.ts +13 -5
  42. package/dist/src/hasher/native-task-hasher-impl.js +38 -15
  43. package/dist/src/hasher/task-hasher.d.ts +17 -9
  44. package/dist/src/hasher/task-hasher.js +16 -11
  45. package/dist/src/hasher/task-planning-context.d.ts +13 -0
  46. package/dist/src/hasher/task-planning-context.js +12 -0
  47. package/dist/src/io-snapshots/config.d.ts +23 -0
  48. package/dist/src/io-snapshots/config.js +32 -0
  49. package/dist/src/io-snapshots/fetch.d.ts +21 -0
  50. package/dist/src/io-snapshots/fetch.js +43 -0
  51. package/dist/src/io-snapshots/outputs.d.ts +12 -0
  52. package/dist/src/io-snapshots/outputs.js +33 -0
  53. package/dist/src/io-snapshots/overrides.d.ts +17 -0
  54. package/dist/src/io-snapshots/overrides.js +60 -0
  55. package/dist/src/io-snapshots/report.d.ts +13 -0
  56. package/dist/src/io-snapshots/report.js +68 -0
  57. package/dist/src/io-snapshots/store.d.ts +37 -0
  58. package/dist/src/io-snapshots/store.js +162 -0
  59. package/dist/src/native/index.d.ts +264 -2
  60. package/dist/src/native/native-bindings.js +10 -0
  61. package/dist/src/native/nx.wasm32-wasi.debug.wasm +0 -0
  62. package/dist/src/native/nx.wasm32-wasi.wasm +0 -0
  63. package/dist/src/native/transform-objects.d.ts +11 -2
  64. package/dist/src/native/transform-objects.js +46 -0
  65. package/dist/src/nx-cloud/update-manager.d.ts +3 -0
  66. package/dist/src/plugins/js/index.js +45 -64
  67. package/dist/src/plugins/js/lock-file/lock-file.d.ts +4 -4
  68. package/dist/src/plugins/js/lock-file/lock-file.js +6 -7
  69. package/dist/src/plugins/js/project-graph/affected/lock-file-changes.d.ts +10 -2
  70. package/dist/src/plugins/js/project-graph/affected/lock-file-changes.js +51 -29
  71. package/dist/src/plugins/js/project-graph/affected/npm-packages.d.ts +10 -2
  72. package/dist/src/plugins/js/project-graph/affected/npm-packages.js +32 -11
  73. package/dist/src/project-graph/affected/affected-project-graph-models.d.ts +14 -0
  74. package/dist/src/project-graph/affected/affected-project-graph.js +5 -18
  75. package/dist/src/project-graph/affected/affected-projects.d.ts +7 -0
  76. package/dist/src/project-graph/affected/affected-projects.js +42 -0
  77. package/dist/src/project-graph/affected/affected-tasks.d.ts +90 -0
  78. package/dist/src/project-graph/affected/affected-tasks.js +214 -0
  79. package/dist/src/project-graph/file-utils.js +6 -2
  80. package/dist/src/project-graph/utils/project-configuration/target-merging.js +67 -0
  81. package/dist/src/project-graph/utils/project-configuration/target-normalization.js +83 -0
  82. package/dist/src/project-graph/utils/project-configuration/utils.d.ts +1 -0
  83. package/dist/src/project-graph/utils/project-configuration/utils.js +1 -0
  84. package/dist/src/tasks-runner/create-task-graph.d.ts +24 -1
  85. package/dist/src/tasks-runner/create-task-graph.js +56 -2
  86. package/dist/src/tasks-runner/forked-process-task-runner.js +3 -3
  87. package/dist/src/tasks-runner/init-tasks-runner.d.ts +7 -2
  88. package/dist/src/tasks-runner/init-tasks-runner.js +17 -6
  89. package/dist/src/tasks-runner/run-command.d.ts +41 -5
  90. package/dist/src/tasks-runner/run-command.js +84 -18
  91. package/dist/src/tasks-runner/task-io-service.d.ts +11 -3
  92. package/dist/src/tasks-runner/task-io-service.js +14 -5
  93. package/dist/src/tasks-runner/task-orchestrator.js +1 -1
  94. package/dist/src/tasks-runner/utils.d.ts +5 -0
  95. package/dist/src/tasks-runner/utils.js +9 -0
  96. package/dist/src/utils/db-connection.d.ts +1 -0
  97. package/dist/src/utils/db-connection.js +1 -0
  98. package/dist/src/utils/json-diff.d.ts +4 -2
  99. package/dist/src/utils/json-diff.js +6 -94
  100. package/dist/src/utils/nx-cloud-utils.d.ts +2 -0
  101. package/dist/src/utils/nx-cloud-utils.js +6 -1
  102. package/dist/src/utils/project-graph-utils.d.ts +2 -0
  103. package/dist/src/utils/project-graph-utils.js +12 -0
  104. package/package.json +22 -13
  105. package/schemas/nx-schema.json +34 -0
  106. package/schemas/project-schema.json +31 -0
  107. package/dist/src/project-graph/affected/locators/project-glob-changes.d.ts +0 -2
  108. package/dist/src/project-graph/affected/locators/project-glob-changes.js +0 -40
  109. package/dist/src/project-graph/affected/locators/workspace-json-changes.d.ts +0 -4
  110. package/dist/src/project-graph/affected/locators/workspace-json-changes.js +0 -47
  111. package/dist/src/project-graph/affected/locators/workspace-projects.d.ts +0 -3
  112. package/dist/src/project-graph/affected/locators/workspace-projects.js +0 -74
@@ -2,6 +2,8 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ProcessTasks = void 0;
4
4
  exports.createTaskGraph = createTaskGraph;
5
+ exports.createTaskGraphWithDependencyOverrides = createTaskGraphWithDependencyOverrides;
6
+ exports.filterTaskGraphToSelection = filterTaskGraphToSelection;
5
7
  exports.filterDummyTasks = filterDummyTasks;
6
8
  exports.getNonDummyDeps = getNonDummyDeps;
7
9
  const utils_1 = require("./utils");
@@ -10,13 +12,15 @@ const output_1 = require("../utils/output");
10
12
  const task_graph_utils_1 = require("./task-graph-utils");
11
13
  const DUMMY_TASK_TARGET = '__nx_dummy_task__';
12
14
  class ProcessTasks {
13
- constructor(extraTargetDependencies, projectGraph) {
15
+ constructor(extraTargetDependencies, projectGraph, recordDependencyOverrides = false) {
14
16
  this.extraTargetDependencies = extraTargetDependencies;
15
17
  this.projectGraph = projectGraph;
18
+ this.recordDependencyOverrides = recordDependencyOverrides;
16
19
  this.seen = new Set();
17
20
  this.tasks = {};
18
21
  this.dependencies = {};
19
22
  this.continuousDependencies = {};
23
+ this.dependencyOverrides = {};
20
24
  const allTargetNames = new Set();
21
25
  for (const projectName in projectGraph.nodes) {
22
26
  const project = projectGraph.nodes[projectName];
@@ -126,6 +130,7 @@ class ProcessTasks {
126
130
  this.processTask(newTask, newTask.target.project, configuration, overrides);
127
131
  }
128
132
  if (task.id !== selfTaskId) {
133
+ this.recordEdge(task, selfTaskId, taskOverrides);
129
134
  if (this.tasks[selfTaskId].continuous) {
130
135
  this.continuousDependencies[task.id].push(selfTaskId);
131
136
  }
@@ -149,6 +154,7 @@ class ProcessTasks {
149
154
  const depTargetId = (0, utils_1.createTaskId)(depProject.name, dependencyConfig.target, resolvedConfiguration);
150
155
  const depTargetConfiguration = this.projectGraph.nodes[depProject.name].data.targets[dependencyConfig.target];
151
156
  if (task.id !== depTargetId) {
157
+ this.recordEdge(task, depTargetId, taskOverrides);
152
158
  if (depTargetConfiguration.continuous) {
153
159
  this.continuousDependencies[task.id].push(depTargetId);
154
160
  }
@@ -180,6 +186,14 @@ class ProcessTasks {
180
186
  }
181
187
  }
182
188
  }
189
+ recordEdge(task, dependencyId, overrides) {
190
+ if (!this.recordDependencyOverrides) {
191
+ return;
192
+ }
193
+ // A dummy task keeps its creator's target, so `from` is the real task the edge started from.
194
+ const from = (0, utils_1.createTaskId)(task.target.project, task.target.target, task.target.configuration);
195
+ (this.dependencyOverrides[dependencyId] ??= []).push({ from, overrides });
196
+ }
183
197
  createDummyTask(id, task) {
184
198
  return {
185
199
  ...task,
@@ -208,6 +222,7 @@ class ProcessTasks {
208
222
  cache: project.data.targets[target].cache ?? false,
209
223
  parallelism: project.data.targets[target].parallelism ?? true,
210
224
  continuous: project.data.targets[target].continuous ?? false,
225
+ ultracache: project.data.targets[target].ultracache,
211
226
  };
212
227
  }
213
228
  resolveConfiguration(project, target, configuration) {
@@ -220,7 +235,46 @@ class ProcessTasks {
220
235
  }
221
236
  exports.ProcessTasks = ProcessTasks;
222
237
  function createTaskGraph(projectGraph, extraTargetDependencies, projectNames, targets, configuration, overrides, excludeTaskDependencies = false) {
223
- const p = new ProcessTasks(extraTargetDependencies, projectGraph);
238
+ return buildTaskGraph(new ProcessTasks(extraTargetDependencies, projectGraph), projectNames, targets, configuration, overrides, excludeTaskDependencies);
239
+ }
240
+ /** `createTaskGraph`, plus the overrides each dependency edge would give. */
241
+ function createTaskGraphWithDependencyOverrides(projectGraph, extraTargetDependencies, projectNames, targets, configuration, overrides, excludeTaskDependencies = false) {
242
+ const p = new ProcessTasks(extraTargetDependencies, projectGraph, true);
243
+ const taskGraph = buildTaskGraph(p, projectNames, targets, configuration, overrides, excludeTaskDependencies);
244
+ return { taskGraph, dependencyOverrides: p.dependencyOverrides };
245
+ }
246
+ /**
247
+ * `taskGraph` pruned to `keep`, as if built from `initial` alone: a kept dependency
248
+ * takes the overrides its edges give it. Undefined when those edges disagree or are missing.
249
+ */
250
+ function filterTaskGraphToSelection(projectGraph, taskGraph, dependencyOverrides, initial, keep) {
251
+ const tasks = {};
252
+ for (const id of keep) {
253
+ const task = taskGraph.tasks[id];
254
+ if (initial.has(id)) {
255
+ tasks[id] = { ...task };
256
+ continue;
257
+ }
258
+ const edges = dependencyOverrides[id] ?? [];
259
+ if (!edges.length) {
260
+ return undefined;
261
+ }
262
+ const first = JSON.stringify(edges[0].overrides);
263
+ if (edges.some((e) => JSON.stringify(e.overrides) !== first)) {
264
+ return undefined;
265
+ }
266
+ const project = projectGraph.nodes[task.target.project];
267
+ const overrides = interpolateOverrides(edges[0].overrides, project.name, project.data);
268
+ tasks[id] = {
269
+ ...task,
270
+ overrides,
271
+ outputs: (0, utils_1.getOutputs)(projectGraph.nodes, task.target, overrides),
272
+ };
273
+ }
274
+ const pruned = (0, utils_1.removeTasksFromTaskGraph)(taskGraph, Object.keys(taskGraph.tasks).filter((id) => !keep.has(id)));
275
+ return { ...pruned, tasks };
276
+ }
277
+ function buildTaskGraph(p, projectNames, targets, configuration, overrides, excludeTaskDependencies) {
224
278
  const roots = p.processTasks(projectNames, targets, configuration, overrides, excludeTaskDependencies);
225
279
  return {
226
280
  roots,
@@ -144,7 +144,7 @@ class ForkedProcessTaskRunner {
144
144
  // Register forked process for metrics collection
145
145
  const pid = p.getPid();
146
146
  if (pid) {
147
- (0, task_io_service_1.registerTaskProcessStart)(task.id, pid);
147
+ (0, task_io_service_1.registerTaskProcessStart)(task, pid);
148
148
  }
149
149
  p.send({
150
150
  targetDescription: task.target,
@@ -181,7 +181,7 @@ class ForkedProcessTaskRunner {
181
181
  });
182
182
  // Register forked process for metrics collection
183
183
  if (p.pid) {
184
- (0, task_io_service_1.registerTaskProcessStart)(task.id, p.pid);
184
+ (0, task_io_service_1.registerTaskProcessStart)(task, p.pid);
185
185
  }
186
186
  // Send message to run the executor
187
187
  p.send({
@@ -224,7 +224,7 @@ class ForkedProcessTaskRunner {
224
224
  });
225
225
  // Register forked process for metrics collection
226
226
  if (p.pid) {
227
- (0, task_io_service_1.registerTaskProcessStart)(task.id, p.pid);
227
+ (0, task_io_service_1.registerTaskProcessStart)(task, p.pid);
228
228
  }
229
229
  const cp = new node_child_process_1.NodeChildProcessWithDirectOutput(p, temporaryOutputPath);
230
230
  this.processes.add(cp);
@@ -1,7 +1,12 @@
1
1
  import type { NxJsonConfiguration } from '../config/nx-json';
2
2
  import { Task, TaskGraph } from '../config/task-graph';
3
3
  import { LifeCycle, TaskResult } from './life-cycle';
4
+ import type { IoSnapshots } from '../native';
4
5
  import type { ProjectGraph } from '../config/project-graph';
5
6
  import { RunningTask } from './running-tasks/running-task';
6
- export declare function runDiscreteTasks(tasks: Task[], projectGraph: ProjectGraph, fullTaskGraph: TaskGraph, nxJson: NxJsonConfiguration, lifeCycle: LifeCycle): Promise<Array<Promise<TaskResult[]>>>;
7
- export declare function runContinuousTasks(tasks: Task[], projectGraph: ProjectGraph, fullTaskGraph: TaskGraph, nxJson: NxJsonConfiguration, lifeCycle: LifeCycle): Promise<Record<string, Promise<RunningTask>>>;
7
+ export declare function runDiscreteTasks(tasks: Task[], projectGraph: ProjectGraph, fullTaskGraph: TaskGraph, nxJson: NxJsonConfiguration, lifeCycle: LifeCycle,
8
+ /** The set to hash from, e.g. from `importIoSnapshots`; omitted hashes natively. */
9
+ ioSnapshots?: IoSnapshots): Promise<Array<Promise<TaskResult[]>>>;
10
+ export declare function runContinuousTasks(tasks: Task[], projectGraph: ProjectGraph, fullTaskGraph: TaskGraph, nxJson: NxJsonConfiguration, lifeCycle: LifeCycle,
11
+ /** The set to hash from, e.g. from `importIoSnapshots`; omitted hashes natively. */
12
+ ioSnapshots?: IoSnapshots): Promise<Record<string, Promise<RunningTask>>>;
@@ -8,10 +8,11 @@ const dotenv_1 = require("../utils/dotenv");
8
8
  const life_cycle_1 = require("./life-cycle");
9
9
  const task_orchestrator_1 = require("./task-orchestrator");
10
10
  const create_task_hasher_1 = require("../hasher/create-task-hasher");
11
+ const outputs_1 = require("../io-snapshots/outputs");
11
12
  const client_1 = require("../daemon/client/client");
12
13
  const shared_running_task_1 = require("./running-tasks/shared-running-task");
13
14
  const task_results_life_cycle_1 = require("./life-cycles/task-results-life-cycle");
14
- async function createOrchestrator(tasks, projectGraph, fullTaskGraph, nxJson, lifeCycle) {
15
+ async function createOrchestrator(tasks, projectGraph, fullTaskGraph, nxJson, lifeCycle, ioSnapshots) {
15
16
  (0, dotenv_1.loadRootEnvFiles)();
16
17
  const invokeRunnerTerminalLifecycle = new invoke_runner_terminal_output_life_cycle_1.InvokeRunnerTerminalOutputLifeCycle(tasks);
17
18
  const taskResultsLifecycle = new task_results_life_cycle_1.TaskResultsLifeCycle();
@@ -21,7 +22,6 @@ async function createOrchestrator(tasks, projectGraph, fullTaskGraph, nxJson, li
21
22
  lifeCycle,
22
23
  ]);
23
24
  const { runnerOptions: options } = (0, run_command_1.getRunner)({}, nxJson);
24
- let hasher = (0, create_task_hasher_1.createTaskHasher)(projectGraph, nxJson, options);
25
25
  const taskGraph = {
26
26
  roots: tasks.map((task) => task.id),
27
27
  tasks: tasks.reduce((acc, task) => {
@@ -37,6 +37,13 @@ async function createOrchestrator(tasks, projectGraph, fullTaskGraph, nxJson, li
37
37
  return acc;
38
38
  }, {}),
39
39
  };
40
+ // As in run-command, unhashed tasks hash from the caller's set. Applying is
41
+ // idempotent, so both graphs may share the same Task objects.
42
+ if (ioSnapshots) {
43
+ (0, outputs_1.applyIoSnapshotOutputs)(projectGraph, fullTaskGraph, ioSnapshots);
44
+ (0, outputs_1.applyIoSnapshotOutputs)(projectGraph, taskGraph, ioSnapshots);
45
+ }
46
+ const hasher = (0, create_task_hasher_1.createTaskHasher)(projectGraph, nxJson, options, ioSnapshots);
40
47
  const nxArgs = {
41
48
  ...options,
42
49
  parallel: tasks.length,
@@ -57,8 +64,10 @@ async function createOrchestrator(tasks, projectGraph, fullTaskGraph, nxJson, li
57
64
  function logDisposeFailure(e) {
58
65
  console.error('Failed to dispose the task orchestrator:', e);
59
66
  }
60
- async function runDiscreteTasks(tasks, projectGraph, fullTaskGraph, nxJson, lifeCycle) {
61
- const orchestrator = await createOrchestrator(tasks, projectGraph, fullTaskGraph, nxJson, lifeCycle);
67
+ async function runDiscreteTasks(tasks, projectGraph, fullTaskGraph, nxJson, lifeCycle,
68
+ /** The set to hash from, e.g. from `importIoSnapshots`; omitted hashes natively. */
69
+ ioSnapshots) {
70
+ const orchestrator = await createOrchestrator(tasks, projectGraph, fullTaskGraph, nxJson, lifeCycle, ioSnapshots);
62
71
  let groupId = 0;
63
72
  let nextBatch = orchestrator.nextBatch();
64
73
  const batchResults = [];
@@ -96,8 +105,10 @@ async function runDiscreteTasks(tasks, projectGraph, fullTaskGraph, nxJson, life
96
105
  .catch(logDisposeFailure);
97
106
  return results;
98
107
  }
99
- async function runContinuousTasks(tasks, projectGraph, fullTaskGraph, nxJson, lifeCycle) {
100
- const orchestrator = await createOrchestrator(tasks, projectGraph, fullTaskGraph, nxJson, lifeCycle);
108
+ async function runContinuousTasks(tasks, projectGraph, fullTaskGraph, nxJson, lifeCycle,
109
+ /** The set to hash from, e.g. from `importIoSnapshots`; omitted hashes natively. */
110
+ ioSnapshots) {
111
+ const orchestrator = await createOrchestrator(tasks, projectGraph, fullTaskGraph, nxJson, lifeCycle, ioSnapshots);
101
112
  const runningTasks = tasks.reduce((current, task, index) => {
102
113
  current[task.id] = orchestrator.startContinuousTask(task, index);
103
114
  return current;
@@ -1,17 +1,42 @@
1
- import { NxJsonConfiguration } from '../config/nx-json';
2
- import { ProjectGraph, ProjectGraphProjectNode } from '../config/project-graph';
1
+ import { NxJsonConfiguration, TargetDependencies } from '../config/nx-json';
2
+ import { ProjectGraph } from '../config/project-graph';
3
3
  import { Task, TaskGraph } from '../config/task-graph';
4
4
  import { TargetDependencyConfig } from '../config/workspace-json-project-json';
5
5
  import { NxArgs } from '../utils/command-line-utils';
6
+ import { type IoSnapshotOutcome } from '../io-snapshots/store';
7
+ import type { TaskPlanningContext } from '../hasher/task-planning-context';
8
+ /** What a command runs. */
9
+ export interface TaskSelection {
10
+ taskGraph: TaskGraph;
11
+ /**
12
+ * The tasks the command asked for, as opposed to ones pulled in as
13
+ * dependencies. A graph rebuilt after a sync is built from their projects.
14
+ */
15
+ initiatingTaskIds: string[];
16
+ /**
17
+ * What a rebuilt graph is pruned to: the selected tasks and everything they
18
+ * depend on. Unset keeps the whole rebuilt graph.
19
+ */
20
+ taskIds?: string[];
21
+ /** The planner selection used. It remembers those plans, so hashing the run reuses them. */
22
+ planningContext?: TaskPlanningContext;
23
+ /** The I/O snapshot set selection planned with; the run hashes with the same one. */
24
+ ioSnapshotOutcome?: IoSnapshotOutcome | null;
25
+ }
6
26
  import { LifeCycle, TaskResult, TaskResults } from './life-cycle';
7
27
  import { TasksRunner } from './tasks-runner';
8
- export declare function runCommand(projectsToRun: ProjectGraphProjectNode[], currentProjectGraph: ProjectGraph, { nxJson }: {
28
+ /**
29
+ * `targets` on whole projects, as `run-many` runs them: every task of the
30
+ * projects' targets and what they depend on, with those tasks initiating.
31
+ */
32
+ export declare function selectTasksForProjects(projectGraph: ProjectGraph, projectNames: string[], nxArgs: NxArgs, overrides: any, extraTargetDependencies: TargetDependencies, excludeTaskDependencies: boolean): TaskSelection;
33
+ export declare function runCommand(taskSelection: TaskSelection, currentProjectGraph: ProjectGraph, { nxJson }: {
9
34
  nxJson: NxJsonConfiguration;
10
35
  }, nxArgs: NxArgs, overrides: any, initiatingProject: string | null, extraTargetDependencies: Record<string, (TargetDependencyConfig | string)[]>, extraOptions: {
11
36
  excludeTaskDependencies: boolean;
12
37
  loadDotEnvFiles: boolean;
13
38
  }): Promise<NodeJS.Process['exitCode']>;
14
- export declare function runCommandForTasks(projectsToRun: ProjectGraphProjectNode[], currentProjectGraph: ProjectGraph, { nxJson }: {
39
+ export declare function runTasksForCommand(taskSelection: TaskSelection, currentProjectGraph: ProjectGraph, { nxJson }: {
15
40
  nxJson: NxJsonConfiguration;
16
41
  }, nxArgs: NxArgs, overrides: any, initiatingProject: string | null, extraTargetDependencies: Record<string, (TargetDependencyConfig | string)[]>, extraOptions: {
17
42
  excludeTaskDependencies: boolean;
@@ -21,7 +46,7 @@ export declare function runCommandForTasks(projectsToRun: ProjectGraphProjectNod
21
46
  completed: boolean;
22
47
  }>;
23
48
  export declare function setEnvVarsBasedOnArgs(nxArgs: NxArgs, loadDotEnvFiles: boolean): void;
24
- export declare function invokeTasksRunner({ tasks, projectGraph, taskGraph, lifeCycle, nxJson, nxArgs, loadDotEnvFiles, initiatingProject, initiatingTasks, }: {
49
+ export declare function invokeTasksRunner({ tasks, projectGraph, taskGraph, lifeCycle, nxJson, nxArgs, loadDotEnvFiles, initiatingProject, initiatingTasks, planningContext, ioSnapshotOutcome: loadedIoSnapshotOutcome, }: {
25
50
  tasks: Task[];
26
51
  projectGraph: ProjectGraph;
27
52
  taskGraph: TaskGraph;
@@ -31,10 +56,21 @@ export declare function invokeTasksRunner({ tasks, projectGraph, taskGraph, life
31
56
  loadDotEnvFiles: boolean;
32
57
  initiatingProject: string | null;
33
58
  initiatingTasks: Task[];
59
+ planningContext?: TaskPlanningContext;
60
+ /** Already loaded for this command; `undefined` loads it here. */
61
+ ioSnapshotOutcome?: IoSnapshotOutcome | null;
34
62
  }): Promise<{
35
63
  [id: string]: TaskResult;
36
64
  }>;
37
65
  export declare function constructLifeCycles(lifeCycle: LifeCycle, taskGraph: TaskGraph, nxJson?: NxJsonConfiguration, skipNxCache?: boolean): LifeCycle[];
66
+ /**
67
+ * What affected task selection reads from the runner options, so it plans as
68
+ * the run hashes. The snapshot set is loaded once, for selection and the run.
69
+ */
70
+ export declare function runnerInputsForSelection(nxArgs: NxArgs, nxJson: NxJsonConfiguration): Promise<{
71
+ ioSnapshotOutcome: IoSnapshotOutcome | null;
72
+ selectivelyHashTsConfig: boolean;
73
+ }>;
38
74
  export declare function getRunner(nxArgs: NxArgs, nxJson: NxJsonConfiguration): {
39
75
  tasksRunner: TasksRunner;
40
76
  runnerOptions: any;
@@ -1,10 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.selectTasksForProjects = selectTasksForProjects;
3
4
  exports.runCommand = runCommand;
4
- exports.runCommandForTasks = runCommandForTasks;
5
+ exports.runTasksForCommand = runTasksForCommand;
5
6
  exports.setEnvVarsBasedOnArgs = setEnvVarsBasedOnArgs;
6
7
  exports.invokeTasksRunner = invokeTasksRunner;
7
8
  exports.constructLifeCycles = constructLifeCycles;
9
+ exports.runnerInputsForSelection = runnerInputsForSelection;
8
10
  exports.getRunner = getRunner;
9
11
  exports.getRunnerOptions = getRunnerOptions;
10
12
  const tslib_1 = require("tslib");
@@ -23,6 +25,10 @@ const is_ci_1 = require("../utils/is-ci");
23
25
  const nx_cloud_utils_1 = require("../utils/nx-cloud-utils");
24
26
  const update_manager_1 = require("../nx-cloud/update-manager");
25
27
  const logger_1 = require("../utils/logger");
28
+ const outputs_1 = require("../io-snapshots/outputs");
29
+ const overrides_1 = require("../io-snapshots/overrides");
30
+ const report_1 = require("../io-snapshots/report");
31
+ const store_1 = require("../io-snapshots/store");
26
32
  const nx_key_1 = require("../utils/nx-key");
27
33
  const output_1 = require("../utils/output");
28
34
  const configure_ai_agents_disclaimer_1 = require("../ai/configure-ai-agents-disclaimer");
@@ -305,8 +311,22 @@ async function getTerminalOutputLifeCycle(initiatingProject, initiatingTasks, pr
305
311
  }
306
312
  }
307
313
  }
308
- function createTaskGraphAndRunValidations(projectGraph, extraTargetDependencies, projectNames, nxArgs, overrides, extraOptions) {
309
- const taskGraph = (0, create_task_graph_1.createTaskGraph)(projectGraph, extraTargetDependencies, projectNames, nxArgs.targets, nxArgs.configuration, overrides, extraOptions.excludeTaskDependencies);
314
+ /**
315
+ * `targets` on whole projects, as `run-many` runs them: every task of the
316
+ * projects' targets and what they depend on, with those tasks initiating.
317
+ */
318
+ function selectTasksForProjects(projectGraph, projectNames, nxArgs, overrides, extraTargetDependencies, excludeTaskDependencies) {
319
+ const taskGraph = (0, create_task_graph_1.createTaskGraph)(projectGraph, extraTargetDependencies, projectNames, nxArgs.targets, nxArgs.configuration, overrides, excludeTaskDependencies);
320
+ const projects = new Set(projectNames);
321
+ return {
322
+ taskGraph,
323
+ initiatingTaskIds: Object.values(taskGraph.tasks)
324
+ .filter((t) => projects.has(t.target.project) &&
325
+ nxArgs.targets.includes(t.target.target))
326
+ .map((t) => t.id),
327
+ };
328
+ }
329
+ function runValidations(projectGraph, taskGraph, nxArgs) {
310
330
  (0, task_graph_utils_1.assertTaskGraphDoesNotContainInvalidTargets)(taskGraph);
311
331
  const cycle = (0, task_graph_utils_1.findCycle)(taskGraph);
312
332
  if (cycle) {
@@ -332,7 +352,7 @@ function createTaskGraphAndRunValidations(projectGraph, extraTargetDependencies,
332
352
  }
333
353
  return taskGraph;
334
354
  }
335
- async function runCommand(projectsToRun, currentProjectGraph, { nxJson }, nxArgs, overrides, initiatingProject, extraTargetDependencies, extraOptions) {
355
+ async function runCommand(taskSelection, currentProjectGraph, { nxJson }, nxArgs, overrides, initiatingProject, extraTargetDependencies, extraOptions) {
336
356
  const status = await (0, handle_errors_1.handleErrors)(process.env.NX_VERBOSE_LOGGING === 'true', async () => {
337
357
  const id = (0, native_1.hashArray)([...process.argv, Date.now().toString()]);
338
358
  await (0, tasks_execution_hooks_1.runPreTasksExecution)({
@@ -342,7 +362,7 @@ async function runCommand(projectsToRun, currentProjectGraph, { nxJson }, nxArgs
342
362
  argv: process.argv,
343
363
  });
344
364
  const startTime = Date.now();
345
- const { taskResults, completed } = await runCommandForTasks(projectsToRun, currentProjectGraph, { nxJson }, {
365
+ const { taskResults, completed } = await runTasksForCommand(taskSelection, currentProjectGraph, { nxJson }, {
346
366
  ...nxArgs,
347
367
  skipNxCache: nxArgs.skipNxCache ||
348
368
  process.env.NX_SKIP_NX_CACHE === 'true' ||
@@ -368,17 +388,20 @@ async function runCommand(projectsToRun, currentProjectGraph, { nxJson }, nxArgs
368
388
  });
369
389
  return status;
370
390
  }
371
- async function runCommandForTasks(projectsToRun, currentProjectGraph, { nxJson }, nxArgs, overrides, initiatingProject, extraTargetDependencies, extraOptions) {
391
+ async function runTasksForCommand(taskSelection, currentProjectGraph, { nxJson }, nxArgs, overrides, initiatingProject, extraTargetDependencies, extraOptions) {
372
392
  // Kick off the license lookup in the background so it overlaps with task
373
393
  // execution. The log itself is deferred to the print site below so it
374
394
  // never lands in the middle of task output.
375
395
  const nxKeyPromise = (0, nx_key_1.getNxKeyInformation)().catch(() => null);
376
- const projectNames = projectsToRun.map((t) => t.name);
377
- const projectNameSet = new Set(projectNames);
378
- const { projectGraph, taskGraph } = await ensureWorkspaceIsInSyncAndGetGraphs(currentProjectGraph, nxJson, projectNames, nxArgs, overrides, extraTargetDependencies, extraOptions);
396
+ const { projectGraph, taskGraph } = await ensureWorkspaceIsInSyncAndGetGraphs(currentProjectGraph, nxJson, nxArgs, overrides, extraTargetDependencies, extraOptions, taskSelection);
379
397
  const tasks = Object.values(taskGraph.tasks);
380
- const initiatingTasks = tasks.filter((t) => projectNameSet.has(t.target.project) &&
381
- nxArgs.targets.includes(t.target.target));
398
+ // A sync generator can remove a selected task, so absent ids are skipped.
399
+ const initiatingTasks = taskSelection.initiatingTaskIds
400
+ .map((id) => taskGraph.tasks[id])
401
+ .filter(Boolean);
402
+ const projectNames = [
403
+ ...new Set(initiatingTasks.map((t) => t.target.project)),
404
+ ];
382
405
  const { lifeCycle, renderIsDone, printSummary, restoreTerminal } = await getTerminalOutputLifeCycle(initiatingProject, initiatingTasks, projectNames, tasks, taskGraph, nxArgs, nxJson, overrides);
383
406
  try {
384
407
  const taskResults = await invokeTasksRunner({
@@ -391,6 +414,8 @@ async function runCommandForTasks(projectsToRun, currentProjectGraph, { nxJson }
391
414
  loadDotEnvFiles: extraOptions.loadDotEnvFiles,
392
415
  initiatingProject,
393
416
  initiatingTasks,
417
+ planningContext: taskSelection.planningContext,
418
+ ioSnapshotOutcome: taskSelection.ioSnapshotOutcome,
394
419
  });
395
420
  await renderIsDone.finally(() => restoreTerminal?.());
396
421
  if (printSummary) {
@@ -447,8 +472,8 @@ function didCommandComplete(tasks, taskResults) {
447
472
  // Any stopped task means the run was interrupted
448
473
  return !Object.values(taskResults).some((r) => r.status === 'stopped');
449
474
  }
450
- async function ensureWorkspaceIsInSyncAndGetGraphs(projectGraph, nxJson, projectNames, nxArgs, overrides, extraTargetDependencies, extraOptions) {
451
- let taskGraph = createTaskGraphAndRunValidations(projectGraph, extraTargetDependencies ?? {}, projectNames, nxArgs, overrides, extraOptions);
475
+ async function ensureWorkspaceIsInSyncAndGetGraphs(projectGraph, nxJson, nxArgs, overrides, extraTargetDependencies, extraOptions, taskSelection) {
476
+ let taskGraph = runValidations(projectGraph, taskSelection.taskGraph, nxArgs);
452
477
  if (nxArgs.skipSync || (0, is_ci_1.isCI)()) {
453
478
  return { projectGraph, taskGraph };
454
479
  }
@@ -563,9 +588,21 @@ async function ensureWorkspaceIsInSyncAndGetGraphs(projectGraph, nxJson, project
563
588
  });
564
589
  await confirmRunningTasksWithSyncFailures();
565
590
  }
566
- // Re-create project graph and task graph
591
+ // Rebuild rather than carry: a sync generator may remove tasks or move inferred
592
+ // outputs, so the old graph and planning context are stale.
593
+ taskSelection.planningContext = undefined;
594
+ const projectNames = [
595
+ ...new Set(taskSelection.initiatingTaskIds
596
+ .filter((id) => taskGraph.tasks[id])
597
+ .map((id) => taskGraph.tasks[id].target.project)),
598
+ ];
567
599
  projectGraph = await (0, project_graph_1.createProjectGraphAsync)();
568
- taskGraph = createTaskGraphAndRunValidations(projectGraph, extraTargetDependencies ?? {}, projectNames, nxArgs, overrides, extraOptions);
600
+ const rebuilt = selectTasksForProjects(projectGraph, projectNames, nxArgs, overrides, extraTargetDependencies ?? {}, extraOptions.excludeTaskDependencies).taskGraph;
601
+ taskGraph = runValidations(projectGraph,
602
+ // Before validation, so a cycle or atomizer error names what will actually run.
603
+ taskSelection.taskIds
604
+ ? (0, utils_1.pruneToSelectedTasks)(rebuilt, taskSelection.taskIds)
605
+ : rebuilt, nxArgs);
569
606
  const successTitle = anySyncGeneratorsFailed
570
607
  ? // the identified changes were synced successfully, but the workspace
571
608
  // is still not up to date, which we'll mention next
@@ -669,16 +706,26 @@ function setEnvVarsBasedOnArgs(nxArgs, loadDotEnvFiles) {
669
706
  process.env.NX_LOAD_DOT_ENV_FILES = 'true';
670
707
  }
671
708
  }
672
- async function invokeTasksRunner({ tasks, projectGraph, taskGraph, lifeCycle, nxJson, nxArgs, loadDotEnvFiles, initiatingProject, initiatingTasks, }) {
709
+ async function invokeTasksRunner({ tasks, projectGraph, taskGraph, lifeCycle, nxJson, nxArgs, loadDotEnvFiles, initiatingProject, initiatingTasks, planningContext, ioSnapshotOutcome: loadedIoSnapshotOutcome, }) {
673
710
  setEnvVarsBasedOnArgs(nxArgs, loadDotEnvFiles);
674
711
  // this needs to be done before we start to run the tasks
675
712
  const taskDetails = (0, hash_task_1.getTaskDetails)();
676
713
  const { tasksRunner, runnerOptions } = getRunner(nxArgs, nxJson);
677
- let hasher = (0, create_task_hasher_1.createTaskHasher)(projectGraph, nxJson, runnerOptions);
714
+ // Must precede hashing: the set is the snapshot source for task hashes,
715
+ // and observed outputs join the task outputs the hasher and cache see.
716
+ const ioSnapshotOutcome = loadedIoSnapshotOutcome !== undefined
717
+ ? loadedIoSnapshotOutcome
718
+ : await (0, store_1.loadIoSnapshotsForRun)(nxJson, runnerOptions);
719
+ const ioSnapshots = (0, store_1.snapshotsOf)(ioSnapshotOutcome);
720
+ if (ioSnapshots) {
721
+ (0, outputs_1.applyIoSnapshotOutputs)(projectGraph, taskGraph, ioSnapshots);
722
+ }
723
+ let hasher = (0, create_task_hasher_1.createTaskHasher)(projectGraph, nxJson, runnerOptions, ioSnapshots, planningContext);
678
724
  // this is used for two reasons: to fetch all remote cache hits AND
679
725
  // to submit everything that is known in advance to Nx Cloud to run in
680
726
  // a distributed fashion
681
- await (0, hash_task_1.hashTasksThatDoNotDependOnOutputsOfOtherTasks)(hasher, projectGraph, taskGraph, nxJson, taskDetails);
727
+ await (0, hash_task_1.hashTasksThatDoNotDependOnOutputsOfOtherTasks)(hasher, projectGraph, taskGraph, nxJson, taskDetails, ioSnapshots);
728
+ reportIoSnapshots(ioSnapshotOutcome, projectGraph, taskGraph, nxArgs);
682
729
  const taskResultsLifecycle = new task_results_life_cycle_1.TaskResultsLifeCycle();
683
730
  const compositedLifeCycle = new life_cycle_1.CompositeLifeCycle([
684
731
  ...constructLifeCycles(lifeCycle, taskGraph, nxJson, nxArgs.skipNxCache),
@@ -825,6 +872,25 @@ function loadTasksRunner(modulePath) {
825
872
  throw e;
826
873
  }
827
874
  }
875
+ function reportIoSnapshots(outcome, projectGraph, taskGraph, nxArgs) {
876
+ if (!outcome || outcome.status === 'skipped')
877
+ return;
878
+ if (!nxArgs.verbose && process.env.NX_VERBOSE_LOGGING !== 'true')
879
+ return;
880
+ const summary = (0, report_1.formatIoSnapshotSummary)((0, overrides_1.buildIoSnapshotOverrides)(projectGraph, taskGraph, outcome.snapshots), outcome.status);
881
+ output_1.output.note({ title: summary.line, bodyLines: summary.bodyLines });
882
+ }
883
+ /**
884
+ * What affected task selection reads from the runner options, so it plans as
885
+ * the run hashes. The snapshot set is loaded once, for selection and the run.
886
+ */
887
+ async function runnerInputsForSelection(nxArgs, nxJson) {
888
+ const { runnerOptions } = getRunner(nxArgs, nxJson);
889
+ return {
890
+ ioSnapshotOutcome: await (0, store_1.loadIoSnapshotsForRun)(nxJson, runnerOptions),
891
+ selectivelyHashTsConfig: runnerOptions?.selectivelyHashTsConfig ?? false,
892
+ };
893
+ }
828
894
  function getRunner(nxArgs, nxJson) {
829
895
  let runner = nxArgs.runner;
830
896
  runner = runner ?? 'default';
@@ -1,3 +1,4 @@
1
+ import type { Task } from '../config/task-graph';
1
2
  /**
2
3
  * Maps taskId -> PID. Note that this only Returns
3
4
  * the PID that the main task process is running under,
@@ -89,8 +90,15 @@ export declare function getTaskIOService(): TaskIOService;
89
90
  /**
90
91
  * Register a task process start with both IO and metrics services.
91
92
  * This is the standard way to notify the system that a task process has started.
92
- * Both services need to be notified together - TaskIOService for external subscribers
93
- * and ProcessMetricsService for native resource monitoring.
93
+ *
94
+ * A target on `ultracache: { mode: 'off' }` reports no PID, which suppresses IO
95
+ * tracing and therefore its report. Every other mode records — they differ in
96
+ * what is done with the recording, not in whether it is taken. Metrics are
97
+ * registered either way: the opt-out covers reporting, not the process
98
+ * management that cleanup and orphan reaping depend on.
99
+ *
100
+ * Narrower than a whole `Task` because `run-commands` can synthesize an id for
101
+ * a task that is not in any graph.
94
102
  */
95
- export declare function registerTaskProcessStart(taskId: string, pid: number): void;
103
+ export declare function registerTaskProcessStart(task: Pick<Task, 'id' | 'ultracache'>, pid: number): void;
96
104
  export {};
@@ -113,10 +113,19 @@ function getTaskIOService() {
113
113
  /**
114
114
  * Register a task process start with both IO and metrics services.
115
115
  * This is the standard way to notify the system that a task process has started.
116
- * Both services need to be notified together - TaskIOService for external subscribers
117
- * and ProcessMetricsService for native resource monitoring.
116
+ *
117
+ * A target on `ultracache: { mode: 'off' }` reports no PID, which suppresses IO
118
+ * tracing and therefore its report. Every other mode records — they differ in
119
+ * what is done with the recording, not in whether it is taken. Metrics are
120
+ * registered either way: the opt-out covers reporting, not the process
121
+ * management that cleanup and orphan reaping depend on.
122
+ *
123
+ * Narrower than a whole `Task` because `run-commands` can synthesize an id for
124
+ * a task that is not in any graph.
118
125
  */
119
- function registerTaskProcessStart(taskId, pid) {
120
- getTaskIOService().notifyPidUpdate({ taskId, pid });
121
- (0, process_metrics_service_1.getProcessMetricsService)().registerTaskProcess(taskId, pid);
126
+ function registerTaskProcessStart(task, pid) {
127
+ if (task.ultracache?.mode !== 'off') {
128
+ getTaskIOService().notifyPidUpdate({ taskId: task.id, pid });
129
+ }
130
+ (0, process_metrics_service_1.getProcessMetricsService)().registerTaskProcess(task.id, pid);
122
131
  }
@@ -1019,7 +1019,7 @@ class TaskOrchestrator {
1019
1019
  };
1020
1020
  const runningTask = await (0, run_commands_impl_1.runCommands)(runCommandsOptions, {
1021
1021
  root: workspace_root_1.workspaceRoot, // only root is needed in runCommands
1022
- }, task.id);
1022
+ }, task);
1023
1023
  this.runningRunCommandsTasks.set(task.id, runningTask);
1024
1024
  runningTask.onExit(() => {
1025
1025
  this.runningRunCommandsTasks.delete(task.id);
@@ -49,6 +49,11 @@ export declare function getExecutorForTask(task: Task, projects: Record<string,
49
49
  isNxExecutor: boolean;
50
50
  };
51
51
  export declare function getCustomHasher(task: Task, projects: Record<string, ProjectConfiguration>): CustomHasher | null;
52
+ /**
53
+ * `taskGraph` pruned to `required`, which must already hold its dependencies.
54
+ * Unknown ids are ignored: a sync generator can remove a task after selection.
55
+ */
56
+ export declare function pruneToSelectedTasks(taskGraph: TaskGraph, required: Iterable<string>): TaskGraph;
52
57
  export declare function removeTasksFromTaskGraph(graph: TaskGraph, ids: string[]): TaskGraph;
53
58
  export declare function calculateReverseDeps(taskGraph: TaskGraph): Record<string, string[]>;
54
59
  export declare function getCliPath(): string;
@@ -17,6 +17,7 @@ exports.getExecutorNameForTask = getExecutorNameForTask;
17
17
  exports.expandInitiatingTasksThroughNoop = expandInitiatingTasksThroughNoop;
18
18
  exports.getExecutorForTask = getExecutorForTask;
19
19
  exports.getCustomHasher = getCustomHasher;
20
+ exports.pruneToSelectedTasks = pruneToSelectedTasks;
20
21
  exports.removeTasksFromTaskGraph = removeTasksFromTaskGraph;
21
22
  exports.calculateReverseDeps = calculateReverseDeps;
22
23
  exports.getCliPath = getCliPath;
@@ -344,6 +345,14 @@ function getCustomHasher(task, projects) {
344
345
  const factory = getExecutorForTask(task, projects).hasherFactory;
345
346
  return factory ? factory() : null;
346
347
  }
348
+ /**
349
+ * `taskGraph` pruned to `required`, which must already hold its dependencies.
350
+ * Unknown ids are ignored: a sync generator can remove a task after selection.
351
+ */
352
+ function pruneToSelectedTasks(taskGraph, required) {
353
+ const keep = new Set(required);
354
+ return removeTasksFromTaskGraph(taskGraph, Object.keys(taskGraph.tasks).filter((id) => !keep.has(id)));
355
+ }
347
356
  function removeTasksFromTaskGraph(graph, ids) {
348
357
  const newGraph = removeIdsFromTaskGraph(graph, ids, graph.tasks);
349
358
  return {
@@ -1,4 +1,5 @@
1
1
  import { ExternalObject } from '../native';
2
+ export declare function sharedWorkspaceDataDirectory(root: string): string;
2
3
  export declare function getDbConnection(opts?: {
3
4
  directory?: string;
4
5
  dbName?: string;
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.sharedWorkspaceDataDirectory = sharedWorkspaceDataDirectory;
3
4
  exports.getDbConnection = getDbConnection;
4
5
  exports.getLocalDbConnection = getLocalDbConnection;
5
6
  const native_1 = require("../native");
@@ -13,6 +13,8 @@ export interface JsonChange extends Change {
13
13
  };
14
14
  }
15
15
  export declare function isJsonChange(change: Change): change is JsonChange;
16
+ /**
17
+ * The changes from `lhs` to `rhs`: every path whose value was deleted or
18
+ * modified, containers included, then every added path.
19
+ */
16
20
  export declare function jsonDiff(lhs: any, rhs: any): JsonChange[];
17
- export declare function walkJsonTree(json: any, currPath: string[], visitor: (path: string[], value: any) => boolean): void;
18
- export declare function deepEquals(a: any, b: any): boolean;