nx 23.3.0-beta.4 → 23.3.0-beta.6

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 (113) hide show
  1. package/dist/nx-cloud-internals.d.ts +1 -0
  2. package/dist/nx-cloud-internals.js +9 -0
  3. package/dist/plugins/package-json.js +1 -1
  4. package/dist/src/command-line/affected/affected.js +51 -9
  5. package/dist/src/command-line/graph/graph.d.ts +31 -0
  6. package/dist/src/command-line/graph/graph.js +71 -17
  7. package/dist/src/command-line/release/publish.js +7 -11
  8. package/dist/src/command-line/release/utils/get-touched-projects-for-group.js +3 -3
  9. package/dist/src/command-line/run/run-one.js +5 -1
  10. package/dist/src/command-line/run-many/run-many.js +6 -12
  11. package/dist/src/command-line/show/projects.js +30 -1
  12. package/dist/src/config/task-graph.d.ts +1 -1
  13. package/dist/src/config/workspace-json-project-json.d.ts +21 -1
  14. package/dist/src/core/graph/main.js +1 -1
  15. package/dist/src/core/graph/runtime.js +1 -1
  16. package/dist/src/core/graph/styles.js +1 -1
  17. package/dist/src/daemon/client/client.d.ts +7 -2
  18. package/dist/src/daemon/client/client.js +15 -2
  19. package/dist/src/daemon/message-types/io-snapshot-version.d.ts +5 -0
  20. package/dist/src/daemon/message-types/io-snapshot-version.js +2 -0
  21. package/dist/src/daemon/message-types/select-affected-tasks.d.ts +18 -0
  22. package/dist/src/daemon/message-types/select-affected-tasks.js +11 -0
  23. package/dist/src/daemon/server/handle-hash-tasks.d.ts +2 -0
  24. package/dist/src/daemon/server/handle-hash-tasks.js +5 -3
  25. package/dist/src/daemon/server/handle-select-affected-tasks.d.ts +3 -0
  26. package/dist/src/daemon/server/handle-select-affected-tasks.js +23 -0
  27. package/dist/src/daemon/server/io-snapshots-state.d.ts +7 -0
  28. package/dist/src/daemon/server/io-snapshots-state.js +35 -0
  29. package/dist/src/daemon/server/planning-context.d.ts +8 -0
  30. package/dist/src/daemon/server/planning-context.js +18 -0
  31. package/dist/src/daemon/server/server.d.ts +1 -0
  32. package/dist/src/daemon/server/server.js +6 -0
  33. package/dist/src/executors/run-commands/run-commands.impl.d.ts +2 -1
  34. package/dist/src/executors/run-commands/run-commands.impl.js +19 -5
  35. package/dist/src/executors/run-commands/running-tasks.d.ts +5 -4
  36. package/dist/src/executors/run-commands/running-tasks.js +13 -13
  37. package/dist/src/hasher/create-task-hasher.d.ts +8 -1
  38. package/dist/src/hasher/create-task-hasher.js +13 -3
  39. package/dist/src/hasher/hash-plan-inspector.js +2 -2
  40. package/dist/src/hasher/hash-task.d.ts +2 -2
  41. package/dist/src/hasher/hash-task.js +7 -1
  42. package/dist/src/hasher/native-task-hasher-impl.d.ts +13 -5
  43. package/dist/src/hasher/native-task-hasher-impl.js +38 -15
  44. package/dist/src/hasher/task-hasher.d.ts +17 -9
  45. package/dist/src/hasher/task-hasher.js +16 -11
  46. package/dist/src/hasher/task-planning-context.d.ts +13 -0
  47. package/dist/src/hasher/task-planning-context.js +12 -0
  48. package/dist/src/io-snapshots/config.d.ts +23 -0
  49. package/dist/src/io-snapshots/config.js +32 -0
  50. package/dist/src/io-snapshots/fetch.d.ts +21 -0
  51. package/dist/src/io-snapshots/fetch.js +43 -0
  52. package/dist/src/io-snapshots/outputs.d.ts +12 -0
  53. package/dist/src/io-snapshots/outputs.js +33 -0
  54. package/dist/src/io-snapshots/overrides.d.ts +12 -0
  55. package/dist/src/io-snapshots/overrides.js +49 -0
  56. package/dist/src/io-snapshots/report.d.ts +13 -0
  57. package/dist/src/io-snapshots/report.js +68 -0
  58. package/dist/src/io-snapshots/store.d.ts +37 -0
  59. package/dist/src/io-snapshots/store.js +162 -0
  60. package/dist/src/native/index.d.ts +264 -2
  61. package/dist/src/native/native-bindings.js +10 -0
  62. package/dist/src/native/nx.wasm32-wasi.debug.wasm +0 -0
  63. package/dist/src/native/nx.wasm32-wasi.wasm +0 -0
  64. package/dist/src/native/transform-objects.d.ts +11 -2
  65. package/dist/src/native/transform-objects.js +46 -0
  66. package/dist/src/nx-cloud/update-manager.d.ts +3 -0
  67. package/dist/src/plugins/js/project-graph/affected/lock-file-changes.d.ts +10 -2
  68. package/dist/src/plugins/js/project-graph/affected/lock-file-changes.js +51 -29
  69. package/dist/src/plugins/js/project-graph/affected/npm-packages.d.ts +10 -2
  70. package/dist/src/plugins/js/project-graph/affected/npm-packages.js +32 -11
  71. package/dist/src/plugins/package-json/create-nodes.d.ts +2 -2
  72. package/dist/src/plugins/package-json/create-nodes.js +13 -13
  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/readme-template.md +16 -0
  106. package/schemas/nx-schema.json +34 -0
  107. package/schemas/project-schema.json +31 -0
  108. package/dist/src/project-graph/affected/locators/project-glob-changes.d.ts +0 -2
  109. package/dist/src/project-graph/affected/locators/project-glob-changes.js +0 -40
  110. package/dist/src/project-graph/affected/locators/workspace-json-changes.d.ts +0 -4
  111. package/dist/src/project-graph/affected/locators/workspace-json-changes.js +0 -47
  112. package/dist/src/project-graph/affected/locators/workspace-projects.d.ts +0 -3
  113. package/dist/src/project-graph/affected/locators/workspace-projects.js +0 -74
@@ -0,0 +1,37 @@
1
+ import type { NxJsonConfiguration } from '../config/nx-json';
2
+ import { IoSnapshotStore, type IoSnapshots } from '../native';
3
+ import { type IoSnapshotCloudOptions, type IoSnapshotEnv } from './config';
4
+ import { type ReadIoSnapshotsResult } from './fetch';
5
+ /** What resolving this run's snapshot set came to. Only a set that resolved carries one. */
6
+ export type IoSnapshotOutcome = {
7
+ status: 'fetched' | 'cached';
8
+ snapshots: IoSnapshots;
9
+ } | {
10
+ status: 'skipped';
11
+ reason: string;
12
+ message: string;
13
+ };
14
+ export declare function skippedIoSnapshots(reason: string, message: string): IoSnapshotOutcome;
15
+ /** The set an outcome resolved to, if any. */
16
+ export declare function snapshotsOf(outcome: IoSnapshotOutcome | null): IoSnapshots | undefined;
17
+ /** The snapshot store in this process's workspace database. */
18
+ export declare function getIoSnapshotStore(): IoSnapshotStore;
19
+ /**
20
+ * Stores a set the Nx Cloud client read for `requestedCommit` and returns its
21
+ * handle, for `runDiscreteTasks` and `runContinuousTasks`. Exposed to the
22
+ * client through `nx/nx-cloud-internals`. Throws with the store's `code`.
23
+ */
24
+ export declare function importIoSnapshots(requestedCommit: string, snapshots: ReadIoSnapshotsResult['snapshots']): IoSnapshots;
25
+ /**
26
+ * The stored version `importIoSnapshots` returned, reopened by its commit and
27
+ * `resolution.fetchedAt`, so other processes hash from it without importing
28
+ * it again. `null` when it isn't stored. Exposed through `nx/nx-cloud-internals`.
29
+ */
30
+ export declare function openIoSnapshots(commit: string, fetchedAt: number): IoSnapshots | null;
31
+ /**
32
+ * This run's I/O snapshot set for HEAD, in the process that owns the fetch:
33
+ * the stored set while it is fresh, otherwise what Nx Cloud reads, imported
34
+ * into the store. Returns `null` when snapshots are not enabled for this
35
+ * workspace; never throws.
36
+ */
37
+ export declare function loadIoSnapshotsForRun(nxJson: NxJsonConfiguration, runnerOptions: IoSnapshotCloudOptions, env?: IoSnapshotEnv): Promise<IoSnapshotOutcome | null>;
@@ -0,0 +1,162 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.skippedIoSnapshots = skippedIoSnapshots;
4
+ exports.snapshotsOf = snapshotsOf;
5
+ exports.getIoSnapshotStore = getIoSnapshotStore;
6
+ exports.importIoSnapshots = importIoSnapshots;
7
+ exports.openIoSnapshots = openIoSnapshots;
8
+ exports.loadIoSnapshotsForRun = loadIoSnapshotsForRun;
9
+ const path_1 = require("path");
10
+ const native_1 = require("../native");
11
+ const db_connection_1 = require("../utils/db-connection");
12
+ const git_utils_1 = require("../utils/git-utils");
13
+ const logger_1 = require("../utils/logger");
14
+ const output_1 = require("../utils/output");
15
+ const workspace_root_1 = require("../utils/workspace-root");
16
+ const config_1 = require("./config");
17
+ const fetch_1 = require("./fetch");
18
+ function skippedIoSnapshots(reason, message) {
19
+ return { status: 'skipped', reason, message };
20
+ }
21
+ /** The set an outcome resolved to, if any. */
22
+ function snapshotsOf(outcome) {
23
+ return outcome && outcome.status !== 'skipped'
24
+ ? outcome.snapshots
25
+ : undefined;
26
+ }
27
+ /**
28
+ * Younger sets are served without asking Nx Cloud; older ones re-fetch, since
29
+ * a closer ancestor's recording may have landed.
30
+ */
31
+ const STORED_SET_MAX_AGE_MS = 60 * 60 * 1000;
32
+ // Reasons that indicate misconfiguration rather than an expected offline
33
+ // state or a client that simply predates snapshots.
34
+ const WARNED_REASONS = new Set([
35
+ 'unauthorized',
36
+ 'invalid-response',
37
+ 'write-failed',
38
+ ]);
39
+ /** The snapshot store in this process's workspace database. */
40
+ function getIoSnapshotStore() {
41
+ return new native_1.IoSnapshotStore((0, db_connection_1.getDbConnection)());
42
+ }
43
+ /**
44
+ * Stores a set the Nx Cloud client read for `requestedCommit` and returns its
45
+ * handle, for `runDiscreteTasks` and `runContinuousTasks`. Exposed to the
46
+ * client through `nx/nx-cloud-internals`. Throws with the store's `code`.
47
+ */
48
+ function importIoSnapshots(requestedCommit, snapshots) {
49
+ return getIoSnapshotStore().import({
50
+ requestedCommit,
51
+ snapshotsJson: JSON.stringify(snapshots),
52
+ });
53
+ }
54
+ /**
55
+ * The stored version `importIoSnapshots` returned, reopened by its commit and
56
+ * `resolution.fetchedAt`, so other processes hash from it without importing
57
+ * it again. `null` when it isn't stored. Exposed through `nx/nx-cloud-internals`.
58
+ */
59
+ function openIoSnapshots(commit, fetchedAt) {
60
+ return getIoSnapshotStore().getVersion(commit, fetchedAt);
61
+ }
62
+ /**
63
+ * This run's I/O snapshot set for HEAD, in the process that owns the fetch:
64
+ * the stored set while it is fresh, otherwise what Nx Cloud reads, imported
65
+ * into the store. Returns `null` when snapshots are not enabled for this
66
+ * workspace; never throws.
67
+ */
68
+ async function loadIoSnapshotsForRun(nxJson, runnerOptions, env = (0, config_1.ioSnapshotEnv)()) {
69
+ if (!(0, config_1.isIoSnapshotFetchEnabled)(nxJson, runnerOptions, env)) {
70
+ return null;
71
+ }
72
+ const head = (0, git_utils_1.getLatestCommitSha)();
73
+ if (!head) {
74
+ return reportIoSnapshotResolution(skippedIoSnapshots('not-a-git-repo', 'Could not resolve HEAD'));
75
+ }
76
+ try {
77
+ const store = getIoSnapshotStore();
78
+ const cached = () => {
79
+ const stored = store.get(head, STORED_SET_MAX_AGE_MS);
80
+ return (stored &&
81
+ reportIoSnapshotResolution({
82
+ status: 'cached',
83
+ snapshots: stored,
84
+ }));
85
+ };
86
+ return (cached() ??
87
+ // Processes that miss together fetch once: the rest find its set.
88
+ (await withIoSnapshotFetchLock(async () => {
89
+ const stored = cached();
90
+ if (stored) {
91
+ return stored;
92
+ }
93
+ const result = await (0, fetch_1.fetchIoSnapshots)(runnerOptions);
94
+ return reportIoSnapshotResolution({
95
+ status: 'fetched',
96
+ snapshots: store.import({
97
+ requestedCommit: head,
98
+ snapshotsJson: JSON.stringify(result.snapshots),
99
+ }),
100
+ });
101
+ })));
102
+ }
103
+ catch (e) {
104
+ // No fallback to an older set for this commit: it would hash from a
105
+ // recording the run could not refresh, and CI can hash natively instead.
106
+ return reportIoSnapshotResolution(skippedIoSnapshots(reasonFromError(e), errorMessage(e)));
107
+ }
108
+ }
109
+ /** Runs `fetch` holding a lock beside the workspace database, across processes. */
110
+ async function withIoSnapshotFetchLock(fetch) {
111
+ if (native_1.IS_WASM) {
112
+ return fetch();
113
+ }
114
+ const lock = new native_1.FileLock((0, path_1.join)((0, db_connection_1.sharedWorkspaceDataDirectory)(workspace_root_1.workspaceRoot), 'io-snapshots.lock'));
115
+ while (!lock.tryLock()) {
116
+ await lock.wait();
117
+ }
118
+ try {
119
+ return await fetch();
120
+ }
121
+ finally {
122
+ lock.unlock();
123
+ }
124
+ }
125
+ const OFFLINE_CODES = new Set([
126
+ 'ECONNABORTED',
127
+ 'ECONNREFUSED',
128
+ 'ECONNRESET',
129
+ 'ENOTFOUND',
130
+ 'EAI_AGAIN',
131
+ 'ETIMEDOUT',
132
+ ]);
133
+ /** A skip reason from an error's `code`: from the Nx Cloud read or the store. */
134
+ function reasonFromError(e) {
135
+ const code = e?.code;
136
+ if (typeof code !== 'string')
137
+ return 'fetch-failed';
138
+ if (OFFLINE_CODES.has(code))
139
+ return 'offline';
140
+ return code.toLowerCase().replace(/_/g, '-');
141
+ }
142
+ function errorMessage(e) {
143
+ return e instanceof Error ? e.message : String(e);
144
+ }
145
+ /** Warns or logs what a resolution came to. */
146
+ function reportIoSnapshotResolution(outcome) {
147
+ if (outcome.status === 'skipped') {
148
+ if (WARNED_REASONS.has(outcome.reason)) {
149
+ output_1.output.warn({
150
+ title: `Nx Cloud I/O snapshots are unavailable (${outcome.reason})`,
151
+ bodyLines: [outcome.message, 'Tasks will be hashed without them.'],
152
+ });
153
+ }
154
+ else {
155
+ logger_1.logger.verbose(`Skipping Nx Cloud I/O snapshots (${outcome.reason}): ${outcome.message}`);
156
+ }
157
+ return outcome;
158
+ }
159
+ const { resolution } = outcome.snapshots;
160
+ logger_1.logger.verbose(`Nx Cloud I/O snapshots ${outcome.status}: ${resolution.tasks} tasks for ${resolution.requestedCommit.slice(0, 12)}`);
161
+ return outcome;
162
+ }
@@ -96,8 +96,14 @@ export declare class HashPlanInspector {
96
96
 
97
97
  export declare class HashPlanner {
98
98
  constructor(nxJson: NxJson, projectGraph: ExternalObject<ProjectGraph>)
99
- getPlans(taskIds: Array<string>, taskGraph: TaskGraph): Record<string, string[]>
100
- getPlansReference(taskIds: Array<string>, taskGraph: TaskGraph): ExternalObject<Record<string, Array<HashInstruction>>>
99
+ /**
100
+ * `snapshots` is this run's I/O snapshot set; a task with an eligible
101
+ * entry hashes its observed reads instead of its declared filesets.
102
+ * `options` carries the task ids decided in JS, where executors and
103
+ * target configuration are resolved.
104
+ */
105
+ getPlans(taskIds: Array<string>, taskGraph: TaskGraph, snapshots?: IoSnapshots | undefined | null, options?: IoSnapshotEligibilityOptions | undefined | null): Record<string, string[]>
106
+ getPlansReference(taskIds: Array<string>, taskGraph: TaskGraph, snapshots?: IoSnapshots | undefined | null, options?: IoSnapshotEligibilityOptions | undefined | null): ExternalObject<Record<string, Array<HashInstruction>>>
101
107
  }
102
108
 
103
109
  export declare class HttpRemoteCache {
@@ -121,6 +127,43 @@ export declare class ImportResult {
121
127
  staticImportExpressions: Array<string>
122
128
  }
123
129
 
130
+ /**
131
+ * One stored version of a commit's snapshot set. Handed to the hash planner as-is.
132
+ * A fresh import holds every entry; a handle reopened from storage reads
133
+ * them per task as they are asked for and remembers them, so it costs the
134
+ * tasks it plans rather than the workspace's whole set.
135
+ */
136
+ export declare class IoSnapshots {
137
+ get commit(): string
138
+ get resolution(): IoSnapshotResolution
139
+ }
140
+
141
+ /**
142
+ * The workspace database's snapshot sets. Each import is its own version,
143
+ * keyed by commit and fetch time, so a run that pinned one keeps reading it
144
+ * while a newer one is imported. Failures throw with a `code` JS maps to a
145
+ * skip reason: `STORE_UNAVAILABLE`, `INVALID_RESPONSE` or `WRITE_FAILED`.
146
+ */
147
+ export declare class IoSnapshotStore {
148
+ constructor(db: ExternalObject<NxDbConnection>)
149
+ /**
150
+ * Stores the set the Nx Cloud client read for `requested_commit` as a new
151
+ * version, and returns it with every entry in hand.
152
+ */
153
+ import(options: IoSnapshotImportOptions): IoSnapshots
154
+ /**
155
+ * The newest stored set for `commit`, without touching the network;
156
+ * `null` when none is stored, its row cannot be read, or it was fetched
157
+ * more than `max_age_ms` ago. Reads only the version's summary row.
158
+ */
159
+ get(commit: string, maxAgeMs?: number | undefined | null): IoSnapshots | null
160
+ /**
161
+ * Exactly the version of `commit` fetched at `fetched_at`; `null` when it
162
+ * is not stored or its row cannot be read.
163
+ */
164
+ getVersion(commit: string, fetchedAt: number): IoSnapshots | null
165
+ }
166
+
124
167
  export declare class NxCache {
125
168
  cacheDirectory: string
126
169
  constructor(workspaceRoot: string, cachePath: string, dbConnection: ExternalObject<NxDbConnection>, linkTaskDetails?: boolean | undefined | null, maxCacheSize?: number | undefined | null)
@@ -382,6 +425,73 @@ export declare class WorkspaceContext {
382
425
  stopWatching(): void
383
426
  }
384
427
 
428
+ export interface AffectedOptions {
429
+ /**
430
+ * `createNodes` globs of every loaded plugin. Resolved in TypeScript because
431
+ * `getPlugins` is async and spawns plugin workers.
432
+ */
433
+ projectGlobPatterns: Array<string>
434
+ projectDeletionAffectsAllProjects: boolean
435
+ workspaceRoot: string
436
+ }
437
+
438
+ export declare function affectedTasks(projectGraph: ExternalObject<ProjectGraph>, hashPlans: ExternalObject<Record<string, Array<HashInstruction>>>, taskGraph: TaskGraph, changedFiles: Array<string>, options: AffectedTasksOptions): AffectedTaskSelection
439
+
440
+ export interface AffectedTaskSelection {
441
+ /** Every affected task, sorted. */
442
+ affected: Array<string>
443
+ /** `affected` plus everything it depends on, sorted: what a run keeps. */
444
+ required: Array<string>
445
+ }
446
+
447
+ export interface AffectedTasksOptions {
448
+ /**
449
+ * `createNodes` globs of every loaded plugin. Resolved in TypeScript because
450
+ * `getPlugins` is async and spawns plugin workers.
451
+ */
452
+ projectGlobPatterns: Array<string>
453
+ workspaceRoot: string
454
+ /**
455
+ * Tasks touched whatever their plan says: those of projects a dependency
456
+ * change names outright (`projectsAffectedByDependencyUpdates`, or a
457
+ * workspace project the root package.json depends on), and those whose
458
+ * executor hashes outside its plan. Ids not in the task graph are ignored.
459
+ */
460
+ alwaysTouchedTaskIds: Array<string>
461
+ /**
462
+ * External node names whose version or integrity moved. A plan carries them
463
+ * as `External(name)`, so a package is matched the way a path is.
464
+ */
465
+ changedExternals: Array<string>
466
+ /**
467
+ * Ecosystems whose manifest changed without the change being pinnable to
468
+ * packages, `npm` for a lock file. Every node of that type counts as
469
+ * moved, and a node of any other type does not: a pnpm lock file cannot
470
+ * have moved a Maven artifact.
471
+ */
472
+ changedExternalTypes: Array<string>
473
+ /**
474
+ * Projects `--exclude` names. Their tasks are dropped from the selection
475
+ * after the walk, so they still carry a change to the tasks reading them.
476
+ */
477
+ excludedProjects: Array<string>
478
+ /**
479
+ * The targets the command asked for. The graph also holds what they depend
480
+ * on, which carries a change but is only ever run as a dependency.
481
+ */
482
+ targets: Array<string>
483
+ /**
484
+ * Where a field-filtered JSON input's file is read at both ends of the diff.
485
+ * Unset, as for `--files`, such a file counts as changed whole.
486
+ */
487
+ revisions?: FileRevisions
488
+ /**
489
+ * The runner's `selectivelyHashTsConfig`: a task hashes only its own
490
+ * project's tsconfig `paths` entries, rather than none.
491
+ */
492
+ selectivelyHashTsConfig: boolean
493
+ }
494
+
385
495
  export interface BatchInfo {
386
496
  executorName: string
387
497
  taskIds: Array<string>
@@ -453,6 +563,18 @@ export interface DepsOutputsInput {
453
563
  */
454
564
  export declare function detectAiAgent(): string | null
455
565
 
566
+ /**
567
+ * `jsonDiff(JSON.parse(lhs), JSON.parse(rhs))`, or `null` when either side is
568
+ * not strict JSON, where `JSON.parse` would throw.
569
+ */
570
+ export declare function diffJson(lhs: string, rhs: string): Array<JsonChange> | null
571
+
572
+ /**
573
+ * Only the projects that own a changed file, one entry per file, in input
574
+ * order. `nx release` version plans ignore implicit and config-derived touches.
575
+ */
576
+ export declare function directlyTouchedProjects(projectGraph: ExternalObject<ProjectGraph>, touchedFiles: Array<string>): Array<string>
577
+
456
578
  export interface EnvironmentInput {
457
579
  env: string
458
580
  }
@@ -512,6 +634,11 @@ export interface ExternalDependenciesInput {
512
634
  }
513
635
 
514
636
  export interface ExternalNode {
637
+ /**
638
+ * The ecosystem the node belongs to, `npm` for a package the JS lock-file
639
+ * parsers found. Optional because a plugin may leave it unset.
640
+ */
641
+ type?: string
515
642
  packageName?: string
516
643
  version: string
517
644
  hash?: string
@@ -527,6 +654,15 @@ export interface FileMap {
527
654
  nonProjectFiles: Array<FileData>
528
655
  }
529
656
 
657
+ /**
658
+ * Where a changed file's two versions are read: `base` from git, `head` from
659
+ * git or, unset, the working tree.
660
+ */
661
+ export interface FileRevisions {
662
+ base: string
663
+ head?: string
664
+ }
665
+
530
666
  export interface FileSetInput {
531
667
  fileset: string
532
668
  dependencies?: boolean
@@ -576,12 +712,30 @@ export declare function getFilesForOutputsBatch(directory: string, entriesBatch:
576
712
  */
577
713
  export declare function getHardcodedIgnorePatterns(): Array<string>
578
714
 
715
+ /**
716
+ * Tasks whose snapshot read another task's outputs: they hash after their
717
+ * producers ran, because those files only exist then. Needs no project graph,
718
+ * so the client can call it before the first hashing wave on the daemon path.
719
+ * Opted-out and custom-hasher tasks are not excluded: deferring a task that
720
+ * ends up hashed natively only delays its hash, it never changes it.
721
+ */
722
+ export declare function getIoSnapshotDeferredTaskIds(snapshots: IoSnapshots, taskGraph: TaskGraph): Array<string>
723
+
724
+ /** The eligibility report, for the run summary. */
725
+ export declare function getIoSnapshotReport(snapshots: IoSnapshots, taskGraph: TaskGraph, options?: IoSnapshotEligibilityOptions | undefined | null): IoSnapshotReport
726
+
579
727
  /**
580
728
  * If `workspace_root` is inside a git worktree, returns the main repo root.
581
729
  * Returns `None` when already in the main repo (or not in a git repo at all).
582
730
  */
583
731
  export declare function getMainWorktreeRoot(workspaceRoot: string): string | null
584
732
 
733
+ /**
734
+ * Observed outputs per eligible task, for the runner to union into
735
+ * `task.outputs`.
736
+ */
737
+ export declare function getObservedIoSnapshotOutputs(snapshots: IoSnapshots, taskGraph: TaskGraph, options?: IoSnapshotEligibilityOptions | undefined | null): Record<string, Array<string>>
738
+
585
739
  export declare function getTransformableOutputs(outputs: Array<string>): Array<string>
586
740
 
587
741
  /**
@@ -676,6 +830,46 @@ export interface InvocationRecord {
676
830
  taskId: string
677
831
  }
678
832
 
833
+ /**
834
+ * Why a task (or the whole run) hashes natively; `reason` is rendered by the
835
+ * run summary.
836
+ */
837
+ export interface IoSnapshotDiagnostic {
838
+ reason: string
839
+ taskId?: string
840
+ glob?: string
841
+ message?: string
842
+ }
843
+
844
+ /** What JS knows about a run's tasks that the eligibility walk needs. */
845
+ export interface IoSnapshotEligibilityOptions {
846
+ /** Tasks whose executor ships a custom hasher. */
847
+ customHasherTaskIds?: Array<string>
848
+ }
849
+
850
+ /** The snapshot set the Nx Cloud client read for HEAD, as JS hands it over. */
851
+ export interface IoSnapshotImportOptions {
852
+ requestedCommit: string
853
+ /** `Record<taskId, { commit, inputs, outputs }>` as JSON. */
854
+ snapshotsJson: string
855
+ }
856
+
857
+ export interface IoSnapshotReport {
858
+ /** Task ids hashed from their snapshot. */
859
+ used: Array<string>
860
+ /** Subset of `used` whose snapshot also contributes observed outputs. */
861
+ tasksWithOutputs: Array<string>
862
+ diagnostics: Array<IoSnapshotDiagnostic>
863
+ resolution: IoSnapshotResolution
864
+ }
865
+
866
+ /** What was resolved for a commit; stored beside its entries. */
867
+ export interface IoSnapshotResolution {
868
+ requestedCommit: string
869
+ fetchedAt: number
870
+ tasks: number
871
+ }
872
+
679
873
  export const IS_WASM: boolean
680
874
 
681
875
  /**
@@ -688,6 +882,18 @@ export declare function isAiAgent(): boolean
688
882
 
689
883
  export declare function isEditorInstalled(editor: SupportedEditor): Promise<boolean>
690
884
 
885
+ /** One entry of `jsonDiff`'s result: `type` is a `JsonDiffType` value. */
886
+ export interface JsonChange {
887
+ type: string
888
+ path: Array<string>
889
+ value: JsonChangeValue
890
+ }
891
+
892
+ export interface JsonChangeValue {
893
+ lhs?: any
894
+ rhs?: any
895
+ }
896
+
691
897
  export interface JsonInput {
692
898
  json: string
693
899
  fields?: Array<string>
@@ -720,6 +926,15 @@ export interface Link {
720
926
  href: string
721
927
  }
722
928
 
929
+ /**
930
+ * Runs every locator and returns the touched project names, in locator order,
931
+ * unsorted overall and with duplicates. Callers dedupe by walking the graph.
932
+ *
933
+ * Every branch is deterministic, and must stay so: this order reaches
934
+ * `result.nodes` insertion order and so `nx show projects --affected`.
935
+ */
936
+ export declare function locateTouchedProjects(projectGraph: ExternalObject<ProjectGraph>, nxJson: NxJson, touchedFiles: Array<string>, options: AffectedOptions, jsLocators: Array<(files: string[]) => Promise<string[]>>): Promise<Array<string>>
937
+
723
938
  export declare function logDebug(message: string): void
724
939
 
725
940
  /**
@@ -919,6 +1134,8 @@ export interface Task {
919
1134
  parallelism?: boolean
920
1135
  /** This denotes if the task runs continuously */
921
1136
  continuous?: boolean
1137
+ /** The target's ultracache configuration, if declared */
1138
+ ultracache?: TaskUltracacheConfiguration
922
1139
  }
923
1140
 
924
1141
  /** Graph of Tasks to be executed */
@@ -987,6 +1204,26 @@ export interface TaskTarget {
987
1204
  configuration?: string
988
1205
  }
989
1206
 
1207
+ /** Ultracache configuration of a task's target */
1208
+ export interface TaskUltracacheConfiguration {
1209
+ /** How this target's tasks participate. Defaults to `on`. */
1210
+ mode?: 'on' | 'warn' | 'error' | 'off'
1211
+ /**
1212
+ * Workspace-relative glob patterns for reads that should be excluded
1213
+ * from ultracache reports. The first path segment cannot contain `*`,
1214
+ * and `?`, `!`, `[`, `]` and extglobs are not supported; anchor the
1215
+ * pattern to a directory instead of leading with `**`.
1216
+ */
1217
+ ignoredReads?: Array<string>
1218
+ /**
1219
+ * Workspace-relative glob patterns for writes that should be excluded
1220
+ * from ultracache reports. The first path segment cannot contain `*`,
1221
+ * and `?`, `!`, `[`, `]` and extglobs are not supported; anchor the
1222
+ * pattern to a directory instead of leading with `**`.
1223
+ */
1224
+ ignoredWrites?: Array<string>
1225
+ }
1226
+
990
1227
  export interface TerminalOutputRecord {
991
1228
  hash: string
992
1229
  /**
@@ -1020,6 +1257,31 @@ export interface TuiConfig {
1020
1257
  suppressHints?: boolean
1021
1258
  }
1022
1259
 
1260
+ /**
1261
+ * How a target's tasks participate in ultracache. Nx Cloud only: nothing in
1262
+ * the OSS runner records or applies IO, so every mode behaves as `Off` without
1263
+ * it.
1264
+ */
1265
+ export declare const enum UltracacheMode {
1266
+ /**
1267
+ * Record IO and let the recording stand in for the target's declared
1268
+ * inputs and outputs. The default.
1269
+ */
1270
+ On = 'on',
1271
+ /**
1272
+ * Record IO and report undeclared reads and writes, but hash and cache
1273
+ * from what the target declared.
1274
+ */
1275
+ Warn = 'warn',
1276
+ /**
1277
+ * Reserved for failing the task on an undeclared read or write. Nothing
1278
+ * enforces that per target yet, so it behaves as `Warn` today.
1279
+ */
1280
+ Error = 'error',
1281
+ /** Record nothing, so no report is produced and nothing is applied. */
1282
+ Off = 'off'
1283
+ }
1284
+
1023
1285
  export interface UpdatedWorkspaceFiles {
1024
1286
  fileMap: FileMap
1025
1287
  externalReferences: NxWorkspaceFilesExternals
@@ -584,6 +584,8 @@ module.exports.HashPlanner = nativeBinding.HashPlanner
584
584
  module.exports.HttpRemoteCache = nativeBinding.HttpRemoteCache
585
585
  module.exports.IgnoredIndexReader = nativeBinding.IgnoredIndexReader
586
586
  module.exports.ImportResult = nativeBinding.ImportResult
587
+ module.exports.IoSnapshots = nativeBinding.IoSnapshots
588
+ module.exports.IoSnapshotStore = nativeBinding.IoSnapshotStore
587
589
  module.exports.NxCache = nativeBinding.NxCache
588
590
  module.exports.NxConsolePreferences = nativeBinding.NxConsolePreferences
589
591
  module.exports.NxPluginCapabilities = nativeBinding.NxPluginCapabilities
@@ -595,6 +597,7 @@ module.exports.TaskDetails = nativeBinding.TaskDetails
595
597
  module.exports.TaskHasher = nativeBinding.TaskHasher
596
598
  module.exports.TaskInvocationTracker = nativeBinding.TaskInvocationTracker
597
599
  module.exports.WorkspaceContext = nativeBinding.WorkspaceContext
600
+ module.exports.affectedTasks = nativeBinding.affectedTasks
598
601
  module.exports.BatchStatus = nativeBinding.BatchStatus
599
602
  module.exports.canInstallNxConsole = nativeBinding.canInstallNxConsole
600
603
  module.exports.canInstallNxConsoleForEditor = nativeBinding.canInstallNxConsoleForEditor
@@ -602,6 +605,8 @@ module.exports.closeDbConnection = nativeBinding.closeDbConnection
602
605
  module.exports.connectToNxDb = nativeBinding.connectToNxDb
603
606
  module.exports.copy = nativeBinding.copy
604
607
  module.exports.detectAiAgent = nativeBinding.detectAiAgent
608
+ module.exports.diffJson = nativeBinding.diffJson
609
+ module.exports.directlyTouchedProjects = nativeBinding.directlyTouchedProjects
605
610
  module.exports.EventType = nativeBinding.EventType
606
611
  module.exports.expandFilesInput = nativeBinding.expandFilesInput
607
612
  module.exports.expandOutputs = nativeBinding.expandOutputs
@@ -613,7 +618,10 @@ module.exports.getDefaultMaxCacheSize = nativeBinding.getDefaultMaxCacheSize
613
618
  module.exports.getEventDimensions = nativeBinding.getEventDimensions
614
619
  module.exports.getFilesForOutputsBatch = nativeBinding.getFilesForOutputsBatch
615
620
  module.exports.getHardcodedIgnorePatterns = nativeBinding.getHardcodedIgnorePatterns
621
+ module.exports.getIoSnapshotDeferredTaskIds = nativeBinding.getIoSnapshotDeferredTaskIds
622
+ module.exports.getIoSnapshotReport = nativeBinding.getIoSnapshotReport
616
623
  module.exports.getMainWorktreeRoot = nativeBinding.getMainWorktreeRoot
624
+ module.exports.getObservedIoSnapshotOutputs = nativeBinding.getObservedIoSnapshotOutputs
617
625
  module.exports.getTransformableOutputs = nativeBinding.getTransformableOutputs
618
626
  module.exports.GroupType = nativeBinding.GroupType
619
627
  module.exports.hashArray = nativeBinding.hashArray
@@ -627,6 +635,7 @@ module.exports.isAiAgent = nativeBinding.isAiAgent
627
635
  module.exports.isEditorInstalled = nativeBinding.isEditorInstalled
628
636
  module.exports.killProcessTree = nativeBinding.killProcessTree
629
637
  module.exports.killProcessTreeGraceful = nativeBinding.killProcessTreeGraceful
638
+ module.exports.locateTouchedProjects = nativeBinding.locateTouchedProjects
630
639
  module.exports.logDebug = nativeBinding.logDebug
631
640
  module.exports.matchGlobPaths = nativeBinding.matchGlobPaths
632
641
  module.exports.matchOutputPaths = nativeBinding.matchOutputPaths
@@ -641,5 +650,6 @@ module.exports.testOnlyTransferFileMap = nativeBinding.testOnlyTransferFileMap
641
650
  module.exports.trackEvent = nativeBinding.trackEvent
642
651
  module.exports.trackPageView = nativeBinding.trackPageView
643
652
  module.exports.transferProjectGraph = nativeBinding.transferProjectGraph
653
+ module.exports.UltracacheMode = nativeBinding.UltracacheMode
644
654
  module.exports.validateOutputs = nativeBinding.validateOutputs
645
655
  module.exports.WorkspaceErrors = nativeBinding.WorkspaceErrors
Binary file
@@ -1,3 +1,12 @@
1
1
  import { ProjectGraph } from '../config/project-graph';
2
- import { ProjectGraph as RustProjectGraph } from './index';
3
- export declare function transformProjectGraphForRust(graph: ProjectGraph): RustProjectGraph;
2
+ import { ExternalObject, ProjectGraph as RustProjectGraph } from './index';
3
+ /** The graph copied into Rust, once per graph. */
4
+ export declare function transformProjectGraphForRust(graph: ProjectGraph): ExternalObject<RustProjectGraph>;
5
+ /**
6
+ * Only what the touched-project locators read: project roots, named inputs and
7
+ * target inputs. Copying target options and every edge costs several times
8
+ * what the locators themselves do on a large workspace.
9
+ */
10
+ export declare function transformProjectGraphForLocators(graph: ProjectGraph): ExternalObject<RustProjectGraph>;
11
+ /** The graph in Rust's shape, still a JS object. Uncached, so safe to edit. */
12
+ export declare function toRustProjectGraph(graph: ProjectGraph): RustProjectGraph;