nx 22.7.0-beta.13 → 22.7.0-beta.15

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.
@@ -741,7 +741,37 @@ async function downloadPackageMigrationsFromRegistry(packageName, packageVersion
741
741
  }
742
742
  return result;
743
743
  }
744
+ function createConcurrencyLimiter(concurrency) {
745
+ const queue = [];
746
+ let active = 0;
747
+ function next() {
748
+ while (queue.length > 0 && active < concurrency) {
749
+ active++;
750
+ queue.shift()();
751
+ }
752
+ }
753
+ return function limit(fn) {
754
+ return new Promise((resolve, reject) => {
755
+ queue.push(() => {
756
+ fn()
757
+ .then(resolve, reject)
758
+ .finally(() => {
759
+ active--;
760
+ next();
761
+ });
762
+ });
763
+ next();
764
+ });
765
+ };
766
+ }
767
+ const installConcurrencyLimit = process.env.NX_MIGRATE_INSTALL_CONCURRENCY
768
+ ? createConcurrencyLimiter(Math.max(1, Math.floor(Number(process.env.NX_MIGRATE_INSTALL_CONCURRENCY)) || 1))
769
+ : null;
744
770
  async function getPackageMigrationsUsingInstall(packageName, packageVersion) {
771
+ const run = () => getPackageMigrationsUsingInstallImpl(packageName, packageVersion);
772
+ return installConcurrencyLimit ? installConcurrencyLimit(run) : run();
773
+ }
774
+ async function getPackageMigrationsUsingInstallImpl(packageName, packageVersion) {
745
775
  const { dir, cleanup } = (0, package_manager_1.createTempNpmDirectory)();
746
776
  let result;
747
777
  if ((0, provenance_1.getNxPackageGroup)().includes(packageName)) {
@@ -37,7 +37,6 @@ export declare class DaemonClient {
37
37
  enabled(): boolean;
38
38
  reset(): void;
39
39
  private getSocketPath;
40
- private parseMessage;
41
40
  requestShutdown(): Promise<void>;
42
41
  getProjectGraphAndSourceMaps(): Promise<{
43
42
  projectGraph: ProjectGraph;
@@ -6,7 +6,6 @@ const child_process_1 = require("child_process");
6
6
  const promises_1 = require("fs/promises");
7
7
  const net_1 = require("net");
8
8
  const node_fs_1 = require("node:fs");
9
- const node_v8_1 = require("node:v8");
10
9
  const path_1 = require("path");
11
10
  const perf_hooks_1 = require("perf_hooks");
12
11
  const configuration_1 = require("../../config/configuration");
@@ -143,11 +142,6 @@ class DaemonClient {
143
142
  throw daemonProcessException('Unable to connect to daemon: no socket path available');
144
143
  }
145
144
  }
146
- parseMessage(message) {
147
- return (0, consume_messages_from_socket_1.isJsonMessage)(message)
148
- ? JSON.parse(message)
149
- : (0, node_v8_1.deserialize)(Buffer.from(message, 'binary'));
150
- }
151
145
  async requestShutdown() {
152
146
  return this.sendToDaemonViaQueue({ type: 'REQUEST_SHUTDOWN' });
153
147
  }
@@ -221,7 +215,7 @@ class DaemonClient {
221
215
  const socketPath = this.getSocketPath();
222
216
  this.fileWatcherMessenger = new daemon_socket_messenger_1.DaemonSocketMessenger((0, net_1.connect)(socketPath)).listen((message) => {
223
217
  try {
224
- const parsedMessage = this.parseMessage(message);
218
+ const parsedMessage = (0, consume_messages_from_socket_1.parseMessage)(message);
225
219
  // Notify all callbacks
226
220
  for (const cb of this.fileWatcherCallbacks.values()) {
227
221
  cb(null, parsedMessage);
@@ -307,7 +301,7 @@ class DaemonClient {
307
301
  const socketPath = this.getSocketPath();
308
302
  this.fileWatcherMessenger = new daemon_socket_messenger_1.DaemonSocketMessenger((0, net_1.connect)(socketPath)).listen((message) => {
309
303
  try {
310
- const parsedMessage = this.parseMessage(message);
304
+ const parsedMessage = (0, consume_messages_from_socket_1.parseMessage)(message);
311
305
  for (const cb of this.fileWatcherCallbacks.values()) {
312
306
  cb(null, parsedMessage);
313
307
  }
@@ -375,7 +369,7 @@ class DaemonClient {
375
369
  const socketPath = this.getSocketPath();
376
370
  this.projectGraphListenerMessenger = new daemon_socket_messenger_1.DaemonSocketMessenger((0, net_1.connect)(socketPath)).listen((message) => {
377
371
  try {
378
- const parsedMessage = this.parseMessage(message);
372
+ const parsedMessage = (0, consume_messages_from_socket_1.parseMessage)(message);
379
373
  // Notify all callbacks
380
374
  for (const cb of this.projectGraphListenerCallbacks.values()) {
381
375
  cb(null, parsedMessage);
@@ -459,7 +453,7 @@ class DaemonClient {
459
453
  // Try to reconnect
460
454
  this.projectGraphListenerMessenger = new daemon_socket_messenger_1.DaemonSocketMessenger((0, net_1.connect)(socketPath)).listen((message) => {
461
455
  try {
462
- const parsedMessage = this.parseMessage(message);
456
+ const parsedMessage = (0, consume_messages_from_socket_1.parseMessage)(message);
463
457
  for (const cb of this.projectGraphListenerCallbacks.values()) {
464
458
  cb(null, parsedMessage);
465
459
  }
@@ -894,9 +888,7 @@ class DaemonClient {
894
888
  handleMessage(serializedResult) {
895
889
  try {
896
890
  perf_hooks_1.performance.mark('result-parse-start-' + this.currentMessage.type);
897
- const parsedResult = (0, consume_messages_from_socket_1.isJsonMessage)(serializedResult)
898
- ? JSON.parse(serializedResult)
899
- : (0, node_v8_1.deserialize)(Buffer.from(serializedResult, 'binary'));
891
+ const parsedResult = (0, consume_messages_from_socket_1.parseMessage)(serializedResult);
900
892
  perf_hooks_1.performance.mark('result-parse-end-' + this.currentMessage.type);
901
893
  perf_hooks_1.performance.measure('deserialize daemon response - ' + this.currentMessage.type, 'result-parse-start-' + this.currentMessage.type, 'result-parse-end-' + this.currentMessage.type);
902
894
  if (parsedResult.error) {
@@ -242,7 +242,8 @@ function expandSingleProjectInputs(inputs, namedInputs) {
242
242
  d.runtime ||
243
243
  d.externalDependencies ||
244
244
  d.dependentTasksOutputFiles ||
245
- d.workingDirectory) {
245
+ d.workingDirectory ||
246
+ d.json) {
246
247
  expanded.push(d);
247
248
  }
248
249
  else {
Binary file
@@ -45,7 +45,25 @@ function loadPnpmHoistedDepsDefinition() {
45
45
  */
46
46
  function parseAndNormalizePnpmLockfile(content) {
47
47
  const { load } = require('@zkochan/js-yaml');
48
- return convertToLockfileObject(load(content));
48
+ return convertToLockfileObject(load(extractMainLockfileDocument(content)));
49
+ }
50
+ // https://github.com/pnpm/pnpm/blob/main/lockfile/fs/src/yamlDocuments.ts
51
+ const YAML_DOCUMENT_START = '---\n';
52
+ const YAML_DOCUMENT_SEPARATOR = '\n---\n';
53
+ // pnpm 11 writes a two-document lockfile when `managePackageManagerVersions` is
54
+ // enabled: the first document holds package-manager metadata, and the second
55
+ // holds the workspace lockfile. Mirror pnpm's own positional extraction so we
56
+ // always read the workspace document.
57
+ // https://github.com/pnpm/pnpm/blob/main/lockfile/fs/src/yamlDocuments.ts
58
+ function extractMainLockfileDocument(content) {
59
+ if (!content.startsWith(YAML_DOCUMENT_START)) {
60
+ return content;
61
+ }
62
+ const separatorIndex = content.indexOf(YAML_DOCUMENT_SEPARATOR, YAML_DOCUMENT_START.length);
63
+ if (separatorIndex === -1) {
64
+ return '';
65
+ }
66
+ return content.slice(separatorIndex + YAML_DOCUMENT_SEPARATOR.length);
49
67
  }
50
68
  // https://github.com/pnpm/pnpm/blob/50e37072f42bcca6d393a74bed29f7f0e029805d/lockfile/lockfile-file/src/write.ts#L22
51
69
  const LOCKFILE_YAML_FORMAT = {
@@ -47,7 +47,7 @@ class IsolatedPlugin {
47
47
  this.responseHandlers = new Map();
48
48
  this.exitHandler = null;
49
49
  this.handleSocketData = (raw) => {
50
- const message = JSON.parse(raw);
50
+ const message = (0, consume_messages_from_socket_1.parseMessage)(raw);
51
51
  if (!(0, messaging_1.isPluginWorkerResult)(message)) {
52
52
  return;
53
53
  }
@@ -4,6 +4,7 @@ exports.isPluginWorkerMessage = isPluginWorkerMessage;
4
4
  exports.isPluginWorkerResult = isPluginWorkerResult;
5
5
  exports.consumeMessage = consumeMessage;
6
6
  exports.sendMessageOverSocket = sendMessageOverSocket;
7
+ const socket_utils_1 = require("../../../daemon/socket-utils");
7
8
  const consume_messages_from_socket_1 = require("../../../utils/consume-messages-from-socket");
8
9
  // =============================================================================
9
10
  // TYPE GUARDS
@@ -69,5 +70,6 @@ async function consumeMessage(socket, raw, handlers) {
69
70
  * Sends a message over the socket with proper formatting.
70
71
  */
71
72
  function sendMessageOverSocket(socket, message) {
72
- socket.write(JSON.stringify(message) + consume_messages_from_socket_1.MESSAGE_END_SEQ);
73
+ socket.write((0, socket_utils_1.serialize)(message));
74
+ socket.write(consume_messages_from_socket_1.MESSAGE_END_SEQ);
73
75
  }
@@ -33,7 +33,7 @@ const server = (0, net_1.createServer)((socket) => {
33
33
  'This likely indicates that the host process was terminated before the worker could be instructed to load the plugin. ' +
34
34
  'If you are seeing this issue, please report it to the Nx team at https://github.com/nrwl/nx/issues.');
35
35
  socket.on('data', (0, consume_messages_from_socket_1.consumeMessagesFromSocket)((raw) => {
36
- const message = JSON.parse(raw.toString());
36
+ const message = (0, consume_messages_from_socket_1.parseMessage)(raw);
37
37
  if (!(0, messaging_1.isPluginWorkerMessage)(message)) {
38
38
  return;
39
39
  }
@@ -65,7 +65,7 @@ class PseudoIPCServer {
65
65
  }
66
66
  registerChildMessages(socket) {
67
67
  socket.on('data', (0, consume_messages_from_socket_1.consumeMessagesFromSocket)(async (rawMessage) => {
68
- const { type, message } = JSON.parse(rawMessage);
68
+ const { type, message } = (0, consume_messages_from_socket_1.parseMessage)(rawMessage);
69
69
  if (type === 'TO_PARENT_FROM_CHILDREN') {
70
70
  for (const childMessage of this.childMessages) {
71
71
  childMessage.onMessage(message);
@@ -91,14 +91,14 @@ class PseudoIPCServer {
91
91
  }
92
92
  sendMessageToChildren(message) {
93
93
  this.sockets.forEach((socket) => {
94
- socket.write(JSON.stringify({ type: 'TO_CHILDREN_FROM_PARENT', message }));
94
+ socket.write((0, socket_utils_1.serialize)({ type: 'TO_CHILDREN_FROM_PARENT', message }));
95
95
  // send EOT to indicate that the message has been fully written
96
96
  socket.write(consume_messages_from_socket_1.MESSAGE_END_SEQ);
97
97
  });
98
98
  }
99
99
  sendMessageToChild(id, message) {
100
100
  this.sockets.forEach((socket) => {
101
- socket.write(JSON.stringify({ type: 'TO_CHILDREN_FROM_PARENT', id, message }));
101
+ socket.write((0, socket_utils_1.serialize)({ type: 'TO_CHILDREN_FROM_PARENT', id, message }));
102
102
  socket.write(consume_messages_from_socket_1.MESSAGE_END_SEQ);
103
103
  });
104
104
  }
@@ -121,12 +121,12 @@ class PseudoIPCClient {
121
121
  this.socket = (0, net_1.connect)(this.path);
122
122
  }
123
123
  sendMessageToParent(message) {
124
- this.socket.write(JSON.stringify({ type: 'TO_PARENT_FROM_CHILDREN', message }));
124
+ this.socket.write((0, socket_utils_1.serialize)({ type: 'TO_PARENT_FROM_CHILDREN', message }));
125
125
  // send EOT to indicate that the message has been fully written
126
126
  this.socket.write(consume_messages_from_socket_1.MESSAGE_END_SEQ);
127
127
  }
128
128
  notifyChildIsReady(id) {
129
- this.socket.write(JSON.stringify({
129
+ this.socket.write((0, socket_utils_1.serialize)({
130
130
  type: 'CHILD_READY',
131
131
  message: id,
132
132
  }));
@@ -135,7 +135,7 @@ class PseudoIPCClient {
135
135
  }
136
136
  onMessageFromParent(forkId, onMessage, onClose = () => { }, onError = (err) => { }) {
137
137
  this.socket.on('data', (0, consume_messages_from_socket_1.consumeMessagesFromSocket)(async (rawMessage) => {
138
- const { id, type, message } = JSON.parse(rawMessage);
138
+ const { id, type, message } = (0, consume_messages_from_socket_1.parseMessage)(rawMessage);
139
139
  if (type === 'TO_CHILDREN_FROM_PARENT') {
140
140
  if (id && id === forkId) {
141
141
  onMessage(message);
@@ -159,7 +159,7 @@ class TaskOrchestrator {
159
159
  .map((id) => this.taskGraph.tasks[id])
160
160
  .filter((t) => !t.hash &&
161
161
  this.taskGraph.dependencies[t.id].every((depId) => this.completedTasks.has(depId)));
162
- if (unhashed.length > 1) {
162
+ if (unhashed.length > 0) {
163
163
  const perTaskEnvs = {};
164
164
  for (const task of unhashed) {
165
165
  perTaskEnvs[task.id] = (0, task_env_1.getTaskSpecificEnv)(task, this.projectGraph);
@@ -561,6 +561,9 @@ class TaskOrchestrator {
561
561
  const cacheableTasks = tasks.filter((t) => (0, utils_1.isCacheableTask)(t, this.options));
562
562
  if (cacheableTasks.length === 0)
563
563
  return [];
564
+ // Wait for any queued processTask promises to settle so task.hash is
565
+ // populated before cache.getBatch maps it into a Rust String.
566
+ await Promise.all(cacheableTasks.map((t) => this.processedTasks.get(t.id)));
564
567
  const cacheHits = await this.fetchCacheHits(cacheableTasks);
565
568
  if (cacheHits.length === 0)
566
569
  return [];
@@ -1,3 +1,9 @@
1
1
  export declare const MESSAGE_END_SEQ: string;
2
2
  export declare function consumeMessagesFromSocket(callback: (message: string) => void): (data: any) => void;
3
3
  export declare function isJsonMessage(message: string): boolean;
4
+ /**
5
+ * Parse a message that was produced by `serialize()` in
6
+ * `daemon/socket-utils.ts`. Auto-detects JSON vs. v8-serialized payloads using
7
+ * `isJsonMessage()` and decodes the binary path via `v8.deserialize`.
8
+ */
9
+ export declare function parseMessage<T = unknown>(message: string): T;
@@ -3,7 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.MESSAGE_END_SEQ = void 0;
4
4
  exports.consumeMessagesFromSocket = consumeMessagesFromSocket;
5
5
  exports.isJsonMessage = isJsonMessage;
6
+ exports.parseMessage = parseMessage;
6
7
  const string_decoder_1 = require("string_decoder");
8
+ const v8_1 = require("v8");
7
9
  const VERY_END_CODE = 4;
8
10
  exports.MESSAGE_END_SEQ = 'NX_MSG_END' + String.fromCharCode(VERY_END_CODE);
9
11
  function consumeMessagesFromSocket(callback) {
@@ -42,3 +44,13 @@ function isJsonMessage(message) {
42
44
  // numbers
43
45
  /^[0-9]+(\.?[0-9]+)?$/.test(message));
44
46
  }
47
+ /**
48
+ * Parse a message that was produced by `serialize()` in
49
+ * `daemon/socket-utils.ts`. Auto-detects JSON vs. v8-serialized payloads using
50
+ * `isJsonMessage()` and decodes the binary path via `v8.deserialize`.
51
+ */
52
+ function parseMessage(message) {
53
+ return isJsonMessage(message)
54
+ ? JSON.parse(message)
55
+ : (0, v8_1.deserialize)(Buffer.from(message, 'binary'));
56
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nx",
3
- "version": "22.7.0-beta.13",
3
+ "version": "22.7.0-beta.15",
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.",
@@ -171,16 +171,16 @@
171
171
  }
172
172
  },
173
173
  "optionalDependencies": {
174
- "@nx/nx-darwin-arm64": "22.7.0-beta.13",
175
- "@nx/nx-darwin-x64": "22.7.0-beta.13",
176
- "@nx/nx-freebsd-x64": "22.7.0-beta.13",
177
- "@nx/nx-linux-arm-gnueabihf": "22.7.0-beta.13",
178
- "@nx/nx-linux-arm64-gnu": "22.7.0-beta.13",
179
- "@nx/nx-linux-arm64-musl": "22.7.0-beta.13",
180
- "@nx/nx-linux-x64-gnu": "22.7.0-beta.13",
181
- "@nx/nx-linux-x64-musl": "22.7.0-beta.13",
182
- "@nx/nx-win32-arm64-msvc": "22.7.0-beta.13",
183
- "@nx/nx-win32-x64-msvc": "22.7.0-beta.13"
174
+ "@nx/nx-darwin-arm64": "22.7.0-beta.15",
175
+ "@nx/nx-darwin-x64": "22.7.0-beta.15",
176
+ "@nx/nx-freebsd-x64": "22.7.0-beta.15",
177
+ "@nx/nx-linux-arm-gnueabihf": "22.7.0-beta.15",
178
+ "@nx/nx-linux-arm64-gnu": "22.7.0-beta.15",
179
+ "@nx/nx-linux-arm64-musl": "22.7.0-beta.15",
180
+ "@nx/nx-linux-x64-gnu": "22.7.0-beta.15",
181
+ "@nx/nx-linux-x64-musl": "22.7.0-beta.15",
182
+ "@nx/nx-win32-arm64-msvc": "22.7.0-beta.15",
183
+ "@nx/nx-win32-x64-msvc": "22.7.0-beta.15"
184
184
  },
185
185
  "nx-migrations": {
186
186
  "migrations": "./migrations.json",