nx 23.2.1 → 23.3.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/command-line/format/format.js +2 -18
- package/dist/src/command-line/graph/graph.js +42 -3
- package/dist/src/command-line/init/implementation/format.js +2 -3
- package/dist/src/command-line/migrate/agentic/definitions.js +75 -19
- package/dist/src/command-line/migrate/agentic/format-command.d.ts +14 -0
- package/dist/src/command-line/migrate/agentic/format-command.js +44 -0
- package/dist/src/command-line/migrate/agentic/handoff-gitignore.d.ts +3 -3
- package/dist/src/command-line/migrate/agentic/handoff-gitignore.js +3 -3
- package/dist/src/command-line/migrate/agentic/handoff.d.ts +27 -17
- package/dist/src/command-line/migrate/agentic/handoff.js +107 -24
- package/dist/src/command-line/migrate/agentic/instruction-files.d.ts +21 -0
- package/dist/src/command-line/migrate/agentic/instruction-files.js +36 -0
- package/dist/src/command-line/migrate/agentic/prompts/fragments.d.ts +16 -0
- package/dist/src/command-line/migrate/agentic/prompts/fragments.js +70 -0
- package/dist/src/command-line/migrate/agentic/prompts/generic-validation.js +4 -3
- package/dist/src/command-line/migrate/agentic/prompts/system-prompt.d.ts +25 -1
- package/dist/src/command-line/migrate/agentic/prompts/system-prompt.js +57 -34
- package/dist/src/command-line/migrate/agentic/run-step.js +28 -4
- package/dist/src/command-line/migrate/agentic/runner.d.ts +17 -8
- package/dist/src/command-line/migrate/agentic/runner.js +110 -55
- package/dist/src/command-line/migrate/agentic/types.d.ts +23 -8
- package/dist/src/command-line/migrate/agentic/types.js +10 -7
- package/dist/src/command-line/migrate/migrate-commits.d.ts +1 -0
- package/dist/src/command-line/migrate/migrate-commits.js +9 -0
- package/dist/src/command-line/migrate/migrate-output.d.ts +3 -7
- package/dist/src/command-line/migrate/migrate-output.js +3 -7
- package/dist/src/command-line/migrate/migrate.js +21 -8
- package/dist/src/command-line/migrate/run/agent-output.d.ts +10 -0
- package/dist/src/command-line/migrate/run/agent-output.js +16 -2
- package/dist/src/command-line/migrate/run/agent-work-payload.d.ts +37 -0
- package/dist/src/command-line/migrate/run/agent-work-payload.js +142 -0
- package/dist/src/command-line/migrate/run/atomic-write.d.ts +8 -0
- package/dist/src/command-line/migrate/run/atomic-write.js +17 -0
- package/dist/src/command-line/migrate/run/index.d.ts +1 -1
- package/dist/src/command-line/migrate/run/issues.d.ts +106 -0
- package/dist/src/command-line/migrate/run/issues.js +980 -0
- package/dist/src/command-line/migrate/run/orchestrator.d.ts +1 -0
- package/dist/src/command-line/migrate/run/orchestrator.js +662 -105
- package/dist/src/command-line/migrate/run/run-state.d.ts +43 -8
- package/dist/src/command-line/migrate/run/run-state.js +184 -20
- package/dist/src/command-line/migrate/run/runbook.d.ts +17 -0
- package/dist/src/command-line/migrate/run/runbook.js +97 -0
- package/dist/src/command-line/migrate/run/state-lock.d.ts +2 -2
- package/dist/src/command-line/migrate/run/state-lock.js +2 -2
- package/dist/src/command-line/migrate/run/state-machine.d.ts +5 -1
- package/dist/src/command-line/migrate/run/state-machine.js +27 -1
- package/dist/src/command-line/migrate/run/worker.js +206 -56
- package/dist/src/command-line/nx-cloud/connect/connect-to-nx-cloud.js +5 -1
- package/dist/src/command-line/release/publish.js +11 -4
- package/dist/src/command-line/release/utils/remote-release-clients/github.js +3 -3
- package/dist/src/command-line/release/utils/remote-release-clients/gitlab.js +3 -3
- package/dist/src/command-line/release/utils/remote-release-clients/remote-release-client.d.ts +2 -0
- package/dist/src/command-line/release/utils/remote-release-clients/remote-release-client.js +35 -0
- package/dist/src/command-line/yargs-utils/shared-options.d.ts +1 -1
- package/dist/src/command-line/yargs-utils/shared-options.js +22 -4
- package/dist/src/config/workspace-json-project-json.d.ts +2 -0
- package/dist/src/core/graph/main.js +1 -1
- package/dist/src/daemon/client/client.d.ts +4 -2
- package/dist/src/daemon/client/client.js +20 -11
- package/dist/src/daemon/message-types/run-tasks-execution-hooks.d.ts +3 -2
- package/dist/src/daemon/server/handle-hash-tasks.d.ts +8 -2
- package/dist/src/daemon/server/handle-hash-tasks.js +16 -3
- package/dist/src/daemon/server/handle-outputs-changes.d.ts +2 -2
- package/dist/src/daemon/server/handle-outputs-changes.js +21 -6
- package/dist/src/daemon/server/handle-tasks-execution-hooks.d.ts +3 -2
- package/dist/src/daemon/server/outputs-tracking.d.ts +6 -0
- package/dist/src/daemon/server/outputs-tracking.js +18 -0
- package/dist/src/daemon/server/project-graph-incremental-recomputation.d.ts +22 -7
- package/dist/src/daemon/server/project-graph-incremental-recomputation.js +99 -69
- package/dist/src/daemon/server/restart-checks.d.ts +22 -0
- package/dist/src/daemon/server/restart-checks.js +77 -0
- package/dist/src/daemon/server/server.js +28 -18
- package/dist/src/daemon/server/shutdown-utils.d.ts +0 -5
- package/dist/src/daemon/server/shutdown-utils.js +3 -26
- package/dist/src/hasher/hash-task.js +20 -16
- package/dist/src/hasher/native-task-hasher-impl.d.ts +8 -0
- package/dist/src/hasher/native-task-hasher-impl.js +46 -3
- package/dist/src/hasher/task-hasher.d.ts +9 -0
- package/dist/src/hasher/task-hasher.js +14 -0
- package/dist/src/native/index.d.ts +202 -21
- package/dist/src/native/index.js +3 -3
- package/dist/src/native/native-bindings.js +3 -1
- package/dist/src/native/nx.wasm32-wasi.debug.wasm +0 -0
- package/dist/src/native/nx.wasm32-wasi.wasm +0 -0
- package/dist/src/plugins/js/lock-file/pnpm-parser.js +1 -1
- package/dist/src/plugins/js/lock-file/utils/pnpm-normalizer.d.ts +2 -0
- package/dist/src/plugins/js/lock-file/utils/pnpm-normalizer.js +22 -0
- package/dist/src/plugins/js/utils/register.js +2 -1
- package/dist/src/project-graph/plugins/isolation/isolated-plugin.js +2 -1
- package/dist/src/project-graph/plugins/isolation/messaging.d.ts +3 -2
- package/dist/src/project-graph/plugins/isolation/plugin-worker.js +5 -1
- package/dist/src/project-graph/plugins/loaded-nx-plugin.d.ts +3 -2
- package/dist/src/project-graph/plugins/loaded-nx-plugin.js +5 -1
- package/dist/src/project-graph/plugins/task-results-stub.d.ts +50 -0
- package/dist/src/project-graph/plugins/task-results-stub.js +111 -0
- package/dist/src/project-graph/plugins/tasks-execution-hooks.d.ts +3 -2
- package/dist/src/project-graph/plugins/tasks-execution-hooks.js +2 -1
- package/dist/src/project-graph/project-graph.js +2 -0
- package/dist/src/tasks-runner/batch/run-batch.js +15 -0
- package/dist/src/tasks-runner/cache.d.ts +35 -0
- package/dist/src/tasks-runner/cache.js +40 -0
- package/dist/src/tasks-runner/create-task-graph.js +1 -0
- package/dist/src/tasks-runner/default-tasks-runner.js +1 -1
- package/dist/src/tasks-runner/forked-process-task-runner.d.ts +1 -1
- package/dist/src/tasks-runner/forked-process-task-runner.js +8 -7
- package/dist/src/tasks-runner/init-tasks-runner.js +5 -1
- package/dist/src/tasks-runner/is-tui-enabled.js +4 -3
- package/dist/src/tasks-runner/life-cycle.d.ts +7 -0
- package/dist/src/tasks-runner/life-cycle.js +7 -0
- package/dist/src/tasks-runner/life-cycles/summary-terminal-output-life-cycle.d.ts +35 -0
- package/dist/src/tasks-runner/life-cycles/summary-terminal-output-life-cycle.js +146 -0
- package/dist/src/tasks-runner/prune-task-graph.d.ts +17 -0
- package/dist/src/tasks-runner/prune-task-graph.js +45 -0
- package/dist/src/tasks-runner/run-command.js +14 -3
- package/dist/src/tasks-runner/running-tasks/batch-process.d.ts +93 -19
- package/dist/src/tasks-runner/running-tasks/batch-process.js +184 -88
- package/dist/src/tasks-runner/task-orchestrator.d.ts +64 -2
- package/dist/src/tasks-runner/task-orchestrator.js +232 -46
- package/dist/src/tasks-runner/terminal-output-path.d.ts +11 -0
- package/dist/src/tasks-runner/terminal-output-path.js +18 -0
- package/dist/src/tasks-runner/utils.js +5 -2
- package/dist/src/utils/ab-testing.d.ts +3 -0
- package/dist/src/utils/ab-testing.js +11 -3
- package/dist/src/utils/chunkify.d.ts +1 -7
- package/dist/src/utils/chunkify.js +2 -8
- package/dist/src/utils/command-line-utils.d.ts +19 -0
- package/dist/src/utils/command-line-utils.js +10 -3
- package/dist/src/utils/formatters/index.d.ts +6 -0
- package/dist/src/utils/formatters/index.js +5 -0
- package/dist/src/utils/formatters/prettier.d.ts +0 -8
- package/dist/src/utils/formatters/prettier.js +4 -26
- package/dist/src/utils/installed-nx-version.js +2 -48
- package/dist/src/utils/min-release-age/packument.js +1 -1
- package/dist/src/utils/output.d.ts +22 -3
- package/dist/src/utils/output.js +28 -5
- package/dist/src/utils/package-json.d.ts +25 -0
- package/dist/src/utils/package-json.js +41 -6
- package/dist/src/utils/package-manager.d.ts +6 -0
- package/dist/src/utils/package-manager.js +10 -0
- package/dist/src/utils/provenance.js +20 -4
- package/dist/src/utils/workspace-context.d.ts +47 -3
- package/dist/src/utils/workspace-context.js +162 -10
- package/package.json +12 -12
- package/schemas/nx-schema.json +4 -0
- package/schemas/project-schema.json +4 -0
- package/dist/src/daemon/server/file-watching/route-workspace-changes.d.ts +0 -9
- package/dist/src/daemon/server/file-watching/route-workspace-changes.js +0 -76
- package/dist/src/daemon/server/watcher.d.ts +0 -18
- package/dist/src/daemon/server/watcher.js +0 -126
|
@@ -8,10 +8,19 @@ exports.multiGlobWithWorkspaceContext = multiGlobWithWorkspaceContext;
|
|
|
8
8
|
exports.hashWithWorkspaceContext = hashWithWorkspaceContext;
|
|
9
9
|
exports.hashMultiGlobWithWorkspaceContext = hashMultiGlobWithWorkspaceContext;
|
|
10
10
|
exports.updateContextWithChangedFiles = updateContextWithChangedFiles;
|
|
11
|
+
exports.trackedFilesInContext = trackedFilesInContext;
|
|
11
12
|
exports.updateFilesInContext = updateFilesInContext;
|
|
12
13
|
exports.getAllFileDataInContext = getAllFileDataInContext;
|
|
14
|
+
exports.subscribeToWorkspaceChanges = subscribeToWorkspaceChanges;
|
|
15
|
+
exports.settleWorkspaceContext = settleWorkspaceContext;
|
|
16
|
+
exports.takeAppliedWorkspaceChanges = takeAppliedWorkspaceChanges;
|
|
17
|
+
exports.isWatchingWorkspaceContext = isWatchingWorkspaceContext;
|
|
18
|
+
exports.subscribeToWatchEvents = subscribeToWatchEvents;
|
|
19
|
+
exports.isEmptyBatch = isEmptyBatch;
|
|
20
|
+
exports.stopWatchingWorkspaceContext = stopWatchingWorkspaceContext;
|
|
13
21
|
exports.getFilesInDirectoryUsingContext = getFilesInDirectoryUsingContext;
|
|
14
22
|
exports.updateProjectFiles = updateProjectFiles;
|
|
23
|
+
exports.refreshWorkspaceContext = refreshWorkspaceContext;
|
|
15
24
|
exports.resetWorkspaceContext = resetWorkspaceContext;
|
|
16
25
|
const perf_hooks_1 = require("perf_hooks");
|
|
17
26
|
const cache_directory_1 = require("./cache-directory");
|
|
@@ -19,16 +28,36 @@ const is_on_daemon_1 = require("../daemon/is-on-daemon");
|
|
|
19
28
|
const client_1 = require("../daemon/client/client");
|
|
20
29
|
const handle_import_1 = require("./handle-import");
|
|
21
30
|
let workspaceContext;
|
|
22
|
-
|
|
31
|
+
let filesReady;
|
|
32
|
+
// Survive a reset: the daemon tears its context down and lets the next read
|
|
33
|
+
// recreate it, and that context must watch and report like the one before.
|
|
34
|
+
let contextOptions;
|
|
35
|
+
let contextRoot;
|
|
36
|
+
let contextGeneration = 0;
|
|
37
|
+
const changeListeners = new Set();
|
|
38
|
+
const eventListeners = new Set();
|
|
39
|
+
function setupWorkspaceContext(workspaceRoot, options) {
|
|
23
40
|
const { WorkspaceContext } = require('../native');
|
|
24
41
|
perf_hooks_1.performance.mark('workspace-context');
|
|
25
|
-
|
|
42
|
+
const cacheDir = (0, cache_directory_1.workspaceDataDirectoryForWorkspace)(workspaceRoot);
|
|
43
|
+
// A plugin worker is only asked for files after its host finished walking
|
|
44
|
+
// and wrote the archive, so it loads that rather than walking again.
|
|
45
|
+
workspaceContext = global.NX_PLUGIN_WORKER
|
|
46
|
+
? WorkspaceContext.fromArchive(workspaceRoot, cacheDir, options)
|
|
47
|
+
: new WorkspaceContext(workspaceRoot, cacheDir, options);
|
|
48
|
+
contextOptions = options;
|
|
49
|
+
contextRoot = workspaceRoot;
|
|
50
|
+
contextGeneration++;
|
|
51
|
+
filesReady = undefined;
|
|
52
|
+
if (options?.watch) {
|
|
53
|
+
attachSubscribers();
|
|
54
|
+
}
|
|
26
55
|
perf_hooks_1.performance.mark('workspace-context:end');
|
|
27
56
|
perf_hooks_1.performance.measure('workspace context init', 'workspace-context', 'workspace-context:end');
|
|
28
57
|
}
|
|
29
58
|
async function getNxWorkspaceFilesFromContext(workspaceRoot, projectRootMap, useDaemonProcess = true) {
|
|
30
59
|
if (!useDaemonProcess || (0, is_on_daemon_1.isOnDaemon)() || !client_1.daemonClient.enabled()) {
|
|
31
|
-
|
|
60
|
+
await ensureFilesReady(workspaceRoot);
|
|
32
61
|
return workspaceContext.getWorkspaceFiles(projectRootMap);
|
|
33
62
|
}
|
|
34
63
|
return client_1.daemonClient.getWorkspaceFiles(projectRootMap);
|
|
@@ -46,7 +75,7 @@ function globWithWorkspaceContextSync(workspaceRoot, globs, exclude) {
|
|
|
46
75
|
}
|
|
47
76
|
async function globWithWorkspaceContext(workspaceRoot, globs, exclude) {
|
|
48
77
|
if (workspaceRoot === '/virtual' || (0, is_on_daemon_1.isOnDaemon)() || !client_1.daemonClient.enabled()) {
|
|
49
|
-
|
|
78
|
+
await ensureFilesReady(workspaceRoot);
|
|
50
79
|
return workspaceContext.glob(globs, exclude);
|
|
51
80
|
}
|
|
52
81
|
else {
|
|
@@ -55,21 +84,21 @@ async function globWithWorkspaceContext(workspaceRoot, globs, exclude) {
|
|
|
55
84
|
}
|
|
56
85
|
async function multiGlobWithWorkspaceContext(workspaceRoot, globs, exclude) {
|
|
57
86
|
if (workspaceRoot === '/virtual' || (0, is_on_daemon_1.isOnDaemon)() || !client_1.daemonClient.enabled()) {
|
|
58
|
-
|
|
87
|
+
await ensureFilesReady(workspaceRoot);
|
|
59
88
|
return workspaceContext.multiGlob(globs, exclude);
|
|
60
89
|
}
|
|
61
90
|
return client_1.daemonClient.multiGlob(globs, exclude);
|
|
62
91
|
}
|
|
63
92
|
async function hashWithWorkspaceContext(workspaceRoot, globs, exclude) {
|
|
64
93
|
if ((0, is_on_daemon_1.isOnDaemon)() || !client_1.daemonClient.enabled()) {
|
|
65
|
-
|
|
94
|
+
await ensureFilesReady(workspaceRoot);
|
|
66
95
|
return workspaceContext.hashFilesMatchingGlob(globs, exclude);
|
|
67
96
|
}
|
|
68
97
|
return client_1.daemonClient.hashGlob(globs, exclude);
|
|
69
98
|
}
|
|
70
99
|
async function hashMultiGlobWithWorkspaceContext(workspaceRoot, globGroups) {
|
|
71
100
|
if ((0, is_on_daemon_1.isOnDaemon)() || !client_1.daemonClient.enabled()) {
|
|
72
|
-
|
|
101
|
+
await ensureFilesReady(workspaceRoot);
|
|
73
102
|
return workspaceContext.hashFilesMatchingGlobs(globGroups);
|
|
74
103
|
}
|
|
75
104
|
return client_1.daemonClient.hashMultiGlob(globGroups);
|
|
@@ -89,20 +118,106 @@ async function updateContextWithChangedFiles(workspaceRoot, createdFiles, update
|
|
|
89
118
|
await client_1.daemonClient.updateWorkspaceContext(createdFiles, updatedFiles, deletedFiles);
|
|
90
119
|
}
|
|
91
120
|
}
|
|
121
|
+
/**
|
|
122
|
+
* The subset of `paths` the workspace file map holds: what the watch tracks,
|
|
123
|
+
* with the ignore rules applied.
|
|
124
|
+
*/
|
|
125
|
+
function trackedFilesInContext(workspaceRoot, paths) {
|
|
126
|
+
ensureContextAvailable(workspaceRoot);
|
|
127
|
+
return workspaceContext?.trackedFiles(paths) ?? [];
|
|
128
|
+
}
|
|
92
129
|
function updateFilesInContext(workspaceRoot, updatedFiles, deletedFiles) {
|
|
93
130
|
ensureContextAvailable(workspaceRoot);
|
|
94
131
|
return workspaceContext?.incrementalUpdate(updatedFiles, deletedFiles);
|
|
95
132
|
}
|
|
96
133
|
async function getAllFileDataInContext(workspaceRoot) {
|
|
97
134
|
if ((0, is_on_daemon_1.isOnDaemon)() || !client_1.daemonClient.enabled()) {
|
|
98
|
-
|
|
135
|
+
await ensureFilesReady(workspaceRoot);
|
|
99
136
|
return workspaceContext.allFileData();
|
|
100
137
|
}
|
|
101
138
|
return client_1.daemonClient.getWorkspaceContextFileData();
|
|
102
139
|
}
|
|
140
|
+
/**
|
|
141
|
+
* Listens for the changes a watching context applies: each change reaches the
|
|
142
|
+
* listeners once, here or in `settleWorkspaceContext`, whichever takes it
|
|
143
|
+
* first. Any number of listeners may listen. Returns a function that stops
|
|
144
|
+
* this one.
|
|
145
|
+
*/
|
|
146
|
+
function subscribeToWorkspaceChanges(workspaceRoot, listener) {
|
|
147
|
+
changeListeners.add(listener);
|
|
148
|
+
ensureContextAvailable(workspaceRoot);
|
|
149
|
+
attachSubscribers();
|
|
150
|
+
return () => changeListeners.delete(listener);
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Applies every change the watcher has delivered, waiting out the kernel hop,
|
|
154
|
+
* and takes every change applied and not yet handed out. Empty when the
|
|
155
|
+
* context is not watching.
|
|
156
|
+
*/
|
|
157
|
+
function settleWorkspaceContext(workspaceRoot) {
|
|
158
|
+
ensureContextAvailable(workspaceRoot);
|
|
159
|
+
return workspaceContext.settle();
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Takes every change applied and not yet handed out, without waiting for the
|
|
163
|
+
* watcher: for a caller that has just applied changes itself.
|
|
164
|
+
*/
|
|
165
|
+
function takeAppliedWorkspaceChanges(workspaceRoot) {
|
|
166
|
+
ensureContextAvailable(workspaceRoot);
|
|
167
|
+
return workspaceContext.takeAppliedChanges();
|
|
168
|
+
}
|
|
169
|
+
function isWatchingWorkspaceContext() {
|
|
170
|
+
return !!contextOptions?.watch;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Listens for every event the context's watch delivers, including writes
|
|
174
|
+
* under ignored directories and the `rescan` marker. Any number of listeners
|
|
175
|
+
* may listen. Returns a function that stops this one.
|
|
176
|
+
*/
|
|
177
|
+
function subscribeToWatchEvents(workspaceRoot, listener) {
|
|
178
|
+
eventListeners.add(listener);
|
|
179
|
+
ensureContextAvailable(workspaceRoot);
|
|
180
|
+
attachSubscribers();
|
|
181
|
+
return () => eventListeners.delete(listener);
|
|
182
|
+
}
|
|
183
|
+
/** Whether a batch carries no change at all. */
|
|
184
|
+
function isEmptyBatch(batch) {
|
|
185
|
+
return (batch.createdFiles.length === 0 &&
|
|
186
|
+
batch.updatedFiles.length === 0 &&
|
|
187
|
+
batch.deletedFiles.length === 0);
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* The native context takes one subscriber per stream; it fans out here. A
|
|
191
|
+
* delivery a replaced context had already queued does not reach listeners as
|
|
192
|
+
* if it came from the current one.
|
|
193
|
+
*/
|
|
194
|
+
function attachSubscribers() {
|
|
195
|
+
if (!workspaceContext || !contextOptions?.watch)
|
|
196
|
+
return;
|
|
197
|
+
const generation = contextGeneration;
|
|
198
|
+
const current = () => generation === contextGeneration;
|
|
199
|
+
workspaceContext.onChanges((err, batch) => {
|
|
200
|
+
if (!current() || (!err && (!batch || isEmptyBatch(batch))))
|
|
201
|
+
return;
|
|
202
|
+
for (const listener of changeListeners)
|
|
203
|
+
listener(err, batch);
|
|
204
|
+
});
|
|
205
|
+
workspaceContext.onWatchEvents((err, events) => {
|
|
206
|
+
if (!current())
|
|
207
|
+
return;
|
|
208
|
+
for (const listener of eventListeners)
|
|
209
|
+
listener(err, events);
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
function stopWatchingWorkspaceContext() {
|
|
213
|
+
changeListeners.clear();
|
|
214
|
+
eventListeners.clear();
|
|
215
|
+
contextOptions = undefined;
|
|
216
|
+
workspaceContext?.stopWatching();
|
|
217
|
+
}
|
|
103
218
|
async function getFilesInDirectoryUsingContext(workspaceRoot, dir) {
|
|
104
219
|
if ((0, is_on_daemon_1.isOnDaemon)() || !client_1.daemonClient.enabled()) {
|
|
105
|
-
|
|
220
|
+
await ensureFilesReady(workspaceRoot);
|
|
106
221
|
return workspaceContext.getFilesInDirectory(dir);
|
|
107
222
|
}
|
|
108
223
|
return client_1.daemonClient.getFilesInDirectory(dir);
|
|
@@ -110,11 +225,48 @@ async function getFilesInDirectoryUsingContext(workspaceRoot, dir) {
|
|
|
110
225
|
function updateProjectFiles(projectRootMappings, rustReferences, updatedFiles, deletedFiles) {
|
|
111
226
|
return workspaceContext?.updateProjectFiles(projectRootMappings, rustReferences.projectFiles, rustReferences.globalFiles, updatedFiles, deletedFiles);
|
|
112
227
|
}
|
|
228
|
+
/**
|
|
229
|
+
* Waits for the walk behind the context without holding the event loop. The
|
|
230
|
+
* native readers block the calling thread until the files exist, so the async
|
|
231
|
+
* entry points await this first; a plugin host is then never frozen while a
|
|
232
|
+
* worker is connecting to it.
|
|
233
|
+
*/
|
|
234
|
+
async function ensureFilesReady(workspaceRoot) {
|
|
235
|
+
ensureContextAvailable(workspaceRoot);
|
|
236
|
+
// A binding without `ready` (an older native build, a mocked one) reads
|
|
237
|
+
// synchronously as before.
|
|
238
|
+
filesReady ??= workspaceContext.ready?.() ?? Promise.resolve();
|
|
239
|
+
await filesReady;
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Re-walks the host's files so the archive its plugin workers load includes
|
|
243
|
+
* writes made since the last walk, such as a migration flushing to disk. The
|
|
244
|
+
* walk is selective and shared through the files lock; one still running is
|
|
245
|
+
* reused rather than repeated.
|
|
246
|
+
*/
|
|
247
|
+
function refreshWorkspaceContext(workspaceRoot) {
|
|
248
|
+
if (workspaceRoot === '/virtual' || (0, is_on_daemon_1.isOnDaemon)() || client_1.daemonClient.enabled()) {
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
if (workspaceContext?.workspaceRoot !== workspaceRoot) {
|
|
252
|
+
setupWorkspaceContext(workspaceRoot);
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
workspaceContext.refresh();
|
|
256
|
+
filesReady = undefined;
|
|
257
|
+
}
|
|
113
258
|
function ensureContextAvailable(workspaceRoot) {
|
|
114
259
|
if (!workspaceContext || workspaceContext?.workspaceRoot !== workspaceRoot) {
|
|
115
|
-
setupWorkspaceContext(workspaceRoot);
|
|
260
|
+
setupWorkspaceContext(workspaceRoot, contextOptions);
|
|
116
261
|
}
|
|
117
262
|
}
|
|
118
263
|
function resetWorkspaceContext() {
|
|
264
|
+
workspaceContext?.stopWatching?.();
|
|
119
265
|
workspaceContext = undefined;
|
|
266
|
+
filesReady = undefined;
|
|
267
|
+
// A watching context is the daemon's only watch; left for the next read to
|
|
268
|
+
// re-create, output and dotenv events in between would be lost.
|
|
269
|
+
if (contextOptions?.watch && contextRoot) {
|
|
270
|
+
setupWorkspaceContext(contextRoot, contextOptions);
|
|
271
|
+
}
|
|
120
272
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nx",
|
|
3
|
-
"version": "23.
|
|
3
|
+
"version": "23.3.0-beta.1",
|
|
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.",
|
|
@@ -152,7 +152,7 @@
|
|
|
152
152
|
"semver": "7.8.4",
|
|
153
153
|
"signal-exit": "3.0.7",
|
|
154
154
|
"sisteransi": "1.0.5",
|
|
155
|
-
"smol-toml": "1.
|
|
155
|
+
"smol-toml": "1.7.1",
|
|
156
156
|
"string-width": "4.2.3",
|
|
157
157
|
"string_decoder": "1.3.0",
|
|
158
158
|
"strip-ansi": "6.0.1",
|
|
@@ -185,16 +185,16 @@
|
|
|
185
185
|
}
|
|
186
186
|
},
|
|
187
187
|
"optionalDependencies": {
|
|
188
|
-
"@nx/nx-darwin-arm64": "23.
|
|
189
|
-
"@nx/nx-darwin-x64": "23.
|
|
190
|
-
"@nx/nx-freebsd-x64": "23.
|
|
191
|
-
"@nx/nx-linux-arm-gnueabihf": "23.
|
|
192
|
-
"@nx/nx-linux-arm64-gnu": "23.
|
|
193
|
-
"@nx/nx-linux-arm64-musl": "23.
|
|
194
|
-
"@nx/nx-linux-x64-gnu": "23.
|
|
195
|
-
"@nx/nx-linux-x64-musl": "23.
|
|
196
|
-
"@nx/nx-win32-arm64-msvc": "23.
|
|
197
|
-
"@nx/nx-win32-x64-msvc": "23.
|
|
188
|
+
"@nx/nx-darwin-arm64": "23.3.0-beta.1",
|
|
189
|
+
"@nx/nx-darwin-x64": "23.3.0-beta.1",
|
|
190
|
+
"@nx/nx-freebsd-x64": "23.3.0-beta.1",
|
|
191
|
+
"@nx/nx-linux-arm-gnueabihf": "23.3.0-beta.1",
|
|
192
|
+
"@nx/nx-linux-arm64-gnu": "23.3.0-beta.1",
|
|
193
|
+
"@nx/nx-linux-arm64-musl": "23.3.0-beta.1",
|
|
194
|
+
"@nx/nx-linux-x64-gnu": "23.3.0-beta.1",
|
|
195
|
+
"@nx/nx-linux-x64-musl": "23.3.0-beta.1",
|
|
196
|
+
"@nx/nx-win32-arm64-msvc": "23.3.0-beta.1",
|
|
197
|
+
"@nx/nx-win32-x64-msvc": "23.3.0-beta.1"
|
|
198
198
|
},
|
|
199
199
|
"nx-migrations": {
|
|
200
200
|
"migrations": "./migrations.json",
|
package/schemas/nx-schema.json
CHANGED
|
@@ -664,6 +664,10 @@
|
|
|
664
664
|
"dependencies": {
|
|
665
665
|
"type": "boolean",
|
|
666
666
|
"description": "Include files matching the fileset for all the project dependencies of this target."
|
|
667
|
+
},
|
|
668
|
+
"includeIgnored": {
|
|
669
|
+
"type": "boolean",
|
|
670
|
+
"description": "Hash the glob straight from disk instead of the workspace file map, so gitignored or generated files can be inputs. A missing exact path still takes part in the hash. A ! negation only filters includeIgnored matches when it also sets includeIgnored: true."
|
|
667
671
|
}
|
|
668
672
|
},
|
|
669
673
|
"required": ["fileset"],
|
|
@@ -220,6 +220,10 @@
|
|
|
220
220
|
"dependencies": {
|
|
221
221
|
"type": "boolean",
|
|
222
222
|
"description": "Include files matching the fileset for all the project dependencies of this target."
|
|
223
|
+
},
|
|
224
|
+
"includeIgnored": {
|
|
225
|
+
"type": "boolean",
|
|
226
|
+
"description": "Hash the glob straight from disk instead of the workspace file map, so gitignored or generated files can be inputs. A missing exact path still takes part in the hash. A ! negation only filters includeIgnored matches when it also sets includeIgnored: true."
|
|
223
227
|
}
|
|
224
228
|
},
|
|
225
229
|
"required": ["fileset"],
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import type { WatchEvent } from '../../../native';
|
|
2
|
-
/**
|
|
3
|
-
* Categorise a batch of watcher events by type and route them into the
|
|
4
|
-
* recomputation queue. Deletions are taken at face value; created and
|
|
5
|
-
* updated paths are stat'd to skip directories (the project graph only
|
|
6
|
-
* cares about files). A stat error means the file was unlinked between
|
|
7
|
-
* the watcher firing and us looking — drop the event.
|
|
8
|
-
*/
|
|
9
|
-
export declare function routeWorkspaceChanges(events: WatchEvent[]): void;
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.routeWorkspaceChanges = routeWorkspaceChanges;
|
|
4
|
-
const node_fs_1 = require("node:fs");
|
|
5
|
-
const node_path_1 = require("node:path");
|
|
6
|
-
const workspace_root_1 = require("../../../utils/workspace-root");
|
|
7
|
-
const logger_1 = require("../../logger");
|
|
8
|
-
const project_graph_incremental_recomputation_1 = require("../project-graph-incremental-recomputation");
|
|
9
|
-
const SUMMARY_CAP = 10;
|
|
10
|
-
function summarize(files) {
|
|
11
|
-
if (files.length === 0)
|
|
12
|
-
return '(none)';
|
|
13
|
-
if (files.length <= SUMMARY_CAP) {
|
|
14
|
-
return files.map((f) => ` - ${f}`).join('\n');
|
|
15
|
-
}
|
|
16
|
-
return (files
|
|
17
|
-
.slice(0, SUMMARY_CAP)
|
|
18
|
-
.map((f) => ` - ${f}`)
|
|
19
|
-
.join('\n') + `\n ... and ${files.length - SUMMARY_CAP} more`);
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Categorise a batch of watcher events by type and route them into the
|
|
23
|
-
* recomputation queue. Deletions are taken at face value; created and
|
|
24
|
-
* updated paths are stat'd to skip directories (the project graph only
|
|
25
|
-
* cares about files). A stat error means the file was unlinked between
|
|
26
|
-
* the watcher firing and us looking — drop the event.
|
|
27
|
-
*/
|
|
28
|
-
function routeWorkspaceChanges(events) {
|
|
29
|
-
logger_1.serverLogger.watcherLog(`[watcher] routeWorkspaceChanges batch: ${events.length} events: ` +
|
|
30
|
-
events.map((e) => `${e.type}:${e.path}`).join(', '));
|
|
31
|
-
const updatedFilesToHash = [];
|
|
32
|
-
const createdFilesToHash = [];
|
|
33
|
-
const deletedFiles = [];
|
|
34
|
-
const droppedDirs = [];
|
|
35
|
-
const droppedStatErrors = [];
|
|
36
|
-
for (const event of events) {
|
|
37
|
-
if (event.type === 'delete') {
|
|
38
|
-
deletedFiles.push(event.path);
|
|
39
|
-
continue;
|
|
40
|
-
}
|
|
41
|
-
try {
|
|
42
|
-
const s = (0, node_fs_1.statSync)((0, node_path_1.join)(workspace_root_1.workspaceRoot, event.path));
|
|
43
|
-
if (!s.isFile()) {
|
|
44
|
-
droppedDirs.push(event.path);
|
|
45
|
-
continue;
|
|
46
|
-
}
|
|
47
|
-
if (event.type === 'update') {
|
|
48
|
-
updatedFilesToHash.push(event.path);
|
|
49
|
-
}
|
|
50
|
-
else {
|
|
51
|
-
createdFilesToHash.push(event.path);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
catch (e) {
|
|
55
|
-
droppedStatErrors.push(`${event.path} (${e instanceof Error ? e.message : String(e)})`);
|
|
56
|
-
// File deleted between watcher emit and stat — drop it.
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
if (createdFilesToHash.length ||
|
|
60
|
-
updatedFilesToHash.length ||
|
|
61
|
-
deletedFiles.length ||
|
|
62
|
-
droppedDirs.length ||
|
|
63
|
-
droppedStatErrors.length) {
|
|
64
|
-
logger_1.serverLogger.watcherLog(`File changes detected:\n` +
|
|
65
|
-
`Created:\n${summarize(createdFilesToHash)}\n` +
|
|
66
|
-
`Updated:\n${summarize(updatedFilesToHash)}\n` +
|
|
67
|
-
`Deleted:\n${summarize(deletedFiles)}` +
|
|
68
|
-
(droppedDirs.length
|
|
69
|
-
? `\nDropped (dirs):\n${summarize(droppedDirs)}`
|
|
70
|
-
: '') +
|
|
71
|
-
(droppedStatErrors.length
|
|
72
|
-
? `\nDropped (stat errors):\n${summarize(droppedStatErrors)}`
|
|
73
|
-
: ''));
|
|
74
|
-
}
|
|
75
|
-
(0, project_graph_incremental_recomputation_1.scheduleProjectGraphRecomputation)(createdFilesToHash, updatedFilesToHash, deletedFiles);
|
|
76
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { Server } from 'net';
|
|
2
|
-
import type { WatchEvent } from '../../native';
|
|
3
|
-
export type FileWatcherCallback = (err: Error | string | null, changeEvents: WatchEvent[] | null) => Promise<void>;
|
|
4
|
-
export declare function watchWorkspace(server: Server, cb: FileWatcherCallback): Promise<any>;
|
|
5
|
-
/**
|
|
6
|
-
* Synchronously drain anything the workspace watcher has buffered and feed
|
|
7
|
-
* it through the normal change-handling pipeline. Call this before serving
|
|
8
|
-
* a cached project graph so we never return data that the watcher has
|
|
9
|
-
* already seen invalidated but hasn't flushed yet.
|
|
10
|
-
*/
|
|
11
|
-
export declare function flushPendingWorkspaceChanges(): Promise<void>;
|
|
12
|
-
export declare function watchOutputFiles(server: Server, cb: FileWatcherCallback): Promise<any>;
|
|
13
|
-
/**
|
|
14
|
-
* NOTE: An event type of "create" will also apply to the case where the user has restored
|
|
15
|
-
* an original version of a file after modifying/deleting it by using git, so we adjust
|
|
16
|
-
* our log language accordingly.
|
|
17
|
-
*/
|
|
18
|
-
export declare function convertChangeEventsToLogMessage(changeEvents: WatchEvent[]): string;
|
|
@@ -1,126 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.watchWorkspace = watchWorkspace;
|
|
4
|
-
exports.flushPendingWorkspaceChanges = flushPendingWorkspaceChanges;
|
|
5
|
-
exports.watchOutputFiles = watchOutputFiles;
|
|
6
|
-
exports.convertChangeEventsToLogMessage = convertChangeEventsToLogMessage;
|
|
7
|
-
const workspace_root_1 = require("../../utils/workspace-root");
|
|
8
|
-
const path_1 = require("path");
|
|
9
|
-
const shutdown_utils_1 = require("./shutdown-utils");
|
|
10
|
-
const path_2 = require("../../utils/path");
|
|
11
|
-
const cache_1 = require("../cache");
|
|
12
|
-
const server_1 = require("./server");
|
|
13
|
-
const handle_import_1 = require("../../utils/handle-import");
|
|
14
|
-
// Captured by watchWorkspace so flushPendingWorkspaceChanges can route
|
|
15
|
-
// force-flushed events through the same handling as the async callback.
|
|
16
|
-
// Definite-assignment: dispatchWorkspaceChanges only runs after
|
|
17
|
-
// watchWorkspace has set both, so reading them as non-nullable is safe.
|
|
18
|
-
let activeServer;
|
|
19
|
-
let workspaceChangesCallback;
|
|
20
|
-
function dispatchWorkspaceChanges(events) {
|
|
21
|
-
for (const event of events) {
|
|
22
|
-
if (event.path.endsWith('.gitignore') || event.path === '.nxignore') {
|
|
23
|
-
// If the ignore files themselves have changed we need to dynamically
|
|
24
|
-
// update our cached ignoreGlobs
|
|
25
|
-
(0, shutdown_utils_1.handleServerProcessTermination)({
|
|
26
|
-
server: activeServer,
|
|
27
|
-
reason: 'Stopping the daemon the set of ignored files changed (native)',
|
|
28
|
-
sockets: server_1.openSockets,
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
return workspaceChangesCallback(null, events);
|
|
33
|
-
}
|
|
34
|
-
async function watchWorkspace(server, cb) {
|
|
35
|
-
const { Watcher } = await (0, handle_import_1.handleImport)('../../native/index.js', __dirname);
|
|
36
|
-
activeServer = server;
|
|
37
|
-
workspaceChangesCallback = cb;
|
|
38
|
-
const watcher = new Watcher(workspace_root_1.workspaceRoot);
|
|
39
|
-
watcher.watch((err, events) => {
|
|
40
|
-
if (err) {
|
|
41
|
-
return cb(err, null);
|
|
42
|
-
}
|
|
43
|
-
dispatchWorkspaceChanges(events);
|
|
44
|
-
});
|
|
45
|
-
return watcher;
|
|
46
|
-
}
|
|
47
|
-
/**
|
|
48
|
-
* Synchronously drain anything the workspace watcher has buffered and feed
|
|
49
|
-
* it through the normal change-handling pipeline. Call this before serving
|
|
50
|
-
* a cached project graph so we never return data that the watcher has
|
|
51
|
-
* already seen invalidated but hasn't flushed yet.
|
|
52
|
-
*/
|
|
53
|
-
async function flushPendingWorkspaceChanges() {
|
|
54
|
-
const watcher = (0, shutdown_utils_1.getWatcherInstance)();
|
|
55
|
-
if (!watcher)
|
|
56
|
-
return;
|
|
57
|
-
const events = watcher.forceFlushPending();
|
|
58
|
-
if (events.length === 0)
|
|
59
|
-
return;
|
|
60
|
-
await dispatchWorkspaceChanges(events);
|
|
61
|
-
}
|
|
62
|
-
async function watchOutputFiles(server, cb) {
|
|
63
|
-
const { Watcher } = await (0, handle_import_1.handleImport)('../../native/index.js', __dirname);
|
|
64
|
-
const relativeServerProcess = (0, path_2.normalizePath)((0, path_1.relative)(workspace_root_1.workspaceRoot, cache_1.serverProcessJsonPath));
|
|
65
|
-
const watcher = new Watcher(workspace_root_1.workspaceRoot, [`!${relativeServerProcess}`], false);
|
|
66
|
-
watcher.watch((err, events) => {
|
|
67
|
-
if (err) {
|
|
68
|
-
return cb(err, null);
|
|
69
|
-
}
|
|
70
|
-
for (const event of events) {
|
|
71
|
-
if (event.path == relativeServerProcess &&
|
|
72
|
-
(0, cache_1.getDaemonProcessIdSync)() !== process.pid) {
|
|
73
|
-
return (0, shutdown_utils_1.handleServerProcessTermination)({
|
|
74
|
-
server,
|
|
75
|
-
reason: 'this process is no longer the current daemon (native)',
|
|
76
|
-
sockets: server_1.openSockets,
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
if (events.length !== 0) {
|
|
81
|
-
cb(null, events);
|
|
82
|
-
}
|
|
83
|
-
});
|
|
84
|
-
return watcher;
|
|
85
|
-
}
|
|
86
|
-
/**
|
|
87
|
-
* NOTE: An event type of "create" will also apply to the case where the user has restored
|
|
88
|
-
* an original version of a file after modifying/deleting it by using git, so we adjust
|
|
89
|
-
* our log language accordingly.
|
|
90
|
-
*/
|
|
91
|
-
function convertChangeEventsToLogMessage(changeEvents) {
|
|
92
|
-
// If only a single file was changed, show the information inline
|
|
93
|
-
if (changeEvents.length === 1) {
|
|
94
|
-
const { path, type } = changeEvents[0];
|
|
95
|
-
let typeLog = 'updated';
|
|
96
|
-
switch (type) {
|
|
97
|
-
case 'create':
|
|
98
|
-
typeLog = 'created or restored';
|
|
99
|
-
break;
|
|
100
|
-
case 'update':
|
|
101
|
-
typeLog = 'modified';
|
|
102
|
-
break;
|
|
103
|
-
case 'delete':
|
|
104
|
-
typeLog = 'deleted';
|
|
105
|
-
break;
|
|
106
|
-
}
|
|
107
|
-
return `${path} was ${typeLog}`;
|
|
108
|
-
}
|
|
109
|
-
let numCreatedOrRestoredFiles = 0;
|
|
110
|
-
let numModifiedFiles = 0;
|
|
111
|
-
let numDeletedFiles = 0;
|
|
112
|
-
for (const event of changeEvents) {
|
|
113
|
-
switch (event.type) {
|
|
114
|
-
case 'create':
|
|
115
|
-
numCreatedOrRestoredFiles++;
|
|
116
|
-
break;
|
|
117
|
-
case 'update':
|
|
118
|
-
numModifiedFiles++;
|
|
119
|
-
break;
|
|
120
|
-
case 'delete':
|
|
121
|
-
numDeletedFiles++;
|
|
122
|
-
break;
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
return `${numCreatedOrRestoredFiles} file(s) created or restored, ${numModifiedFiles} file(s) modified, ${numDeletedFiles} file(s) deleted`;
|
|
126
|
-
}
|