@vltpkg/graph 1.6.1 → 1.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,6 @@
1
1
  import { baseDepID, getTuple, hydrate, joinDepIDTuple, joinExtra, splitDepID, } from '@vltpkg/dep-id';
2
2
  import { error } from '@vltpkg/error-cause';
3
+ import { trace } from '@vltpkg/output/trace';
3
4
  import { Spec } from '@vltpkg/spec';
4
5
  import { satisfies } from '@vltpkg/satisfies';
5
6
  import { parse as parseVersion } from '@vltpkg/semver';
@@ -700,6 +701,13 @@ export const appendNodes = async (packageInfo, graph, fromNode, deps, scurry, op
700
701
  // BFS MAIN LOOP: Process level by level until no more deps
701
702
  while (currentLevelDeps.length > 0) {
702
703
  const nextLevelDeps = [];
704
+ /* c8 ignore next */
705
+ const depth = currentLevelDeps[0]?.depth ?? 0;
706
+ trace('build:level', {
707
+ from: fromNode.id,
708
+ depth,
709
+ entries: currentLevelDeps.length,
710
+ });
703
711
  // ============================================================
704
712
  // PHASE A: PARALLEL FETCH (READ-ONLY)
705
713
  // ============================================================
@@ -721,6 +729,7 @@ export const appendNodes = async (packageInfo, graph, fromNode, deps, scurry, op
721
729
  result,
722
730
  };
723
731
  }));
732
+ trace('build:level:fetched', { from: fromNode.id, depth });
724
733
  // ============================================================
725
734
  // PHASE B: SERIAL MUTATIONS (DETERMINISTIC ORDER)
726
735
  // ============================================================
@@ -776,6 +785,11 @@ export const appendNodes = async (packageInfo, graph, fromNode, deps, scurry, op
776
785
  nextLevelDeps.push({ ...childDep, depth: nextDepth });
777
786
  }
778
787
  }
788
+ trace('build:level:placed', {
789
+ from: fromNode.id,
790
+ depth,
791
+ next: nextLevelDeps.length,
792
+ });
779
793
  // Advance to next BFS level
780
794
  currentLevelDeps = nextLevelDeps;
781
795
  }
@@ -1,4 +1,5 @@
1
1
  import { appendNodes } from "./append-nodes.js";
2
+ import { mark } from '@vltpkg/output/trace';
2
3
  import { compareByHasPeerDeps, getNodeOrderedDependencies, } from "./sorting.js";
3
4
  import { baseDepID } from '@vltpkg/dep-id';
4
5
  /**
@@ -122,6 +123,7 @@ export const refreshIdealGraph = async ({ add, graph, modifiers, packageInfo, sc
122
123
  }
123
124
  // Wait for all extraction promises to complete
124
125
  if (extractPromises?.length) {
126
+ mark('build:extract-wait', { jobs: extractPromises.length });
125
127
  await Promise.all(extractPromises);
126
128
  }
127
129
  };
@@ -1,4 +1,5 @@
1
1
  import { graphStep } from '@vltpkg/output';
2
+ import { mark } from '@vltpkg/output/trace';
2
3
  import { availableParallelism } from 'node:os';
3
4
  import { callLimit } from 'promise-call-limit';
4
5
  import { load as loadActual } from "../actual/load.js";
@@ -18,6 +19,12 @@ import { updatePackageJson } from "./update-importers-package-json.js";
18
19
  import { copyFileSync } from 'node:fs';
19
20
  import { binChmodAll } from "./bin-chmod.js";
20
21
  import { filterNodesByQuery } from "../filter-nodes-by-query.js";
22
+ // How many extractions reify has in flight at once. An extraction is a
23
+ // download followed by an unpack, so this also bounds the downloaded
24
+ // tarballs held in memory. Raising it to 64 to match the registry
25
+ // client's connection floor was measured slower on 4 vCPUs (svelte -9%,
26
+ // next -4% from a lockfile with the cap at 24): more downloads in flight
27
+ // only lengthen the queue in front of the unpack workers.
21
28
  const limit = Math.max(availableParallelism() - 1, 1) * 8;
22
29
  /**
23
30
  * Make the current project match the supplied graph.
@@ -101,6 +108,10 @@ export const reify = async (options) => {
101
108
  res.buildQueue = buildQueue;
102
109
  }
103
110
  finally {
111
+ // Free the placement worker threads now that placement is done. A
112
+ // failure here must not hide the install's own error or skip the
113
+ // rollback below.
114
+ await options.packageInfo.closeTarPool().catch(() => { });
104
115
  /* c8 ignore start */
105
116
  if (!success) {
106
117
  await rollback(remover, diff, scurry).catch(() => { });
@@ -121,18 +132,27 @@ const reify_ = async (options, diff, remover, saveImportersPackageJson) => {
121
132
  // unsupported optional deps are dropped only after that, so the
122
133
  // lockfile keeps them for other platforms
123
134
  pruneUnsupportedOptional(diff);
135
+ // start the unpack workers now that the set of packages to place is
136
+ // final (the pruned optionals would otherwise inflate it past the
137
+ // pool's minimum), so they boot while the first packages are fetched
138
+ // rather than on the critical path of the first unpack. It never
139
+ // rejects, so there is nothing to await.
140
+ void packageInfo.warmTarPool(diff.nodes.add);
124
141
  const actions = addNodes(diff, scurry, remover, options, packageInfo).concat(deleteEdges(diff, scurry, remover));
125
142
  // need to wait, so that the nodes exist to link to
143
+ mark('reify:extract', { jobs: actions.length, limit });
126
144
  if (actions.length)
127
145
  await callLimit(actions, { limit });
128
146
  // create all node_modules symlinks, and link bins to nm/.bin
129
147
  const edgeActions = addEdges(diff, scurry, remover);
148
+ mark('reify:edges', { jobs: edgeActions.length });
130
149
  if (edgeActions.length)
131
150
  await callLimit(edgeActions, { limit });
132
151
  // link bins that deleted edges removed but other deps still declare
133
152
  const binActions = relinkBins(diff, scurry, remover);
134
153
  if (binActions.length)
135
154
  await callLimit(binActions, { limit });
155
+ mark('reify:hoist');
136
156
  await internalHoist(diff.to, options, remover);
137
157
  // looks up all nodes setting buildState = 'needed'
138
158
  // on nodes that require building
@@ -140,8 +160,10 @@ const reify_ = async (options, diff, remover, saveImportersPackageJson) => {
140
160
  // Filter nodes allowed to run scripts if allowScripts query is provided
141
161
  const allowScriptsNodes = await filterNodesByQuery(diff.to, allowScripts);
142
162
  // ensure that all added bins are chmod +x
163
+ mark('reify:chmod');
143
164
  await binChmodAll(diff.nodes.add, scurry);
144
165
  // run install lifecycle scripts and link any binary files
166
+ mark('reify:scripts');
145
167
  await build(diff, packageJson, scurry, allowScriptsNodes);
146
168
  // set the buildQueue on the result object containing
147
169
  // an array with all the ids of nodes that need building
@@ -159,9 +181,11 @@ const reify_ = async (options, diff, remover, saveImportersPackageJson) => {
159
181
  }
160
182
  }
161
183
  /* c8 ignore stop */
184
+ mark('reify:lockfile');
162
185
  saveHidden(options);
163
186
  // delete garbage from the store.
164
187
  const rmActions = deleteNodes(diff, remover, scurry, options.keepNodes);
188
+ mark('reify:delete', { jobs: rmActions.length });
165
189
  if (rmActions.length)
166
190
  await Promise.all(rmActions);
167
191
  // updates package.json files if anything was added / removed
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@vltpkg/graph",
3
3
  "description": "A library that helps understanding & expressing what happens on an install",
4
- "version": "1.6.1",
4
+ "version": "1.6.2",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "git+https://github.com/vltpkg/vltpkg.git",
@@ -13,26 +13,26 @@
13
13
  "url": "http://vlt.sh"
14
14
  },
15
15
  "dependencies": {
16
- "@vltpkg/cmd-shim": "1.6.1",
17
- "@vltpkg/dep-id": "1.6.1",
18
- "@vltpkg/dss-breadcrumb": "1.6.1",
19
- "@vltpkg/error-cause": "1.6.1",
20
- "@vltpkg/fast-split": "1.6.1",
21
- "@vltpkg/graph-run": "1.6.1",
22
- "@vltpkg/init": "1.6.1",
23
- "@vltpkg/output": "1.6.1",
24
- "@vltpkg/package-info": "1.6.1",
25
- "@vltpkg/package-json": "1.6.1",
26
- "@vltpkg/pick-manifest": "1.6.1",
27
- "@vltpkg/query": "1.6.1",
28
- "@vltpkg/rollback-remove": "1.6.1",
29
- "@vltpkg/run": "1.6.1",
30
- "@vltpkg/satisfies": "1.6.1",
31
- "@vltpkg/security-archive": "1.6.1",
32
- "@vltpkg/spec": "1.6.1",
33
- "@vltpkg/types": "1.6.1",
34
- "@vltpkg/vlt-json": "1.6.1",
35
- "@vltpkg/workspaces": "1.6.1",
16
+ "@vltpkg/cmd-shim": "1.6.2",
17
+ "@vltpkg/dep-id": "1.6.2",
18
+ "@vltpkg/dss-breadcrumb": "1.6.2",
19
+ "@vltpkg/error-cause": "1.6.2",
20
+ "@vltpkg/fast-split": "1.6.2",
21
+ "@vltpkg/graph-run": "1.6.2",
22
+ "@vltpkg/init": "1.6.2",
23
+ "@vltpkg/output": "1.6.2",
24
+ "@vltpkg/package-info": "1.6.2",
25
+ "@vltpkg/package-json": "1.6.2",
26
+ "@vltpkg/pick-manifest": "1.6.2",
27
+ "@vltpkg/query": "1.6.2",
28
+ "@vltpkg/rollback-remove": "1.6.2",
29
+ "@vltpkg/run": "1.6.2",
30
+ "@vltpkg/satisfies": "1.6.2",
31
+ "@vltpkg/security-archive": "1.6.2",
32
+ "@vltpkg/spec": "1.6.2",
33
+ "@vltpkg/types": "1.6.2",
34
+ "@vltpkg/vlt-json": "1.6.2",
35
+ "@vltpkg/workspaces": "1.6.2",
36
36
  "path-scurry": "^2.0.1",
37
37
  "promise-call-limit": "^3.0.2"
38
38
  },