@vltpkg/graph 0.0.0-3 → 0.0.0-31

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 (172) hide show
  1. package/README.md +148 -12
  2. package/dist/esm/actual/load.d.ts +49 -3
  3. package/dist/esm/actual/load.d.ts.map +1 -1
  4. package/dist/esm/actual/load.js +124 -73
  5. package/dist/esm/actual/load.js.map +1 -1
  6. package/dist/esm/browser.d.ts +8 -4
  7. package/dist/esm/browser.d.ts.map +1 -1
  8. package/dist/esm/browser.js +6 -2
  9. package/dist/esm/browser.js.map +1 -1
  10. package/dist/esm/build.d.ts +29 -0
  11. package/dist/esm/build.d.ts.map +1 -0
  12. package/dist/esm/build.js +79 -0
  13. package/dist/esm/build.js.map +1 -0
  14. package/dist/esm/dependencies.d.ts +14 -5
  15. package/dist/esm/dependencies.d.ts.map +1 -1
  16. package/dist/esm/dependencies.js +67 -2
  17. package/dist/esm/dependencies.js.map +1 -1
  18. package/dist/esm/diff.d.ts +67 -0
  19. package/dist/esm/diff.d.ts.map +1 -1
  20. package/dist/esm/diff.js +25 -0
  21. package/dist/esm/diff.js.map +1 -1
  22. package/dist/esm/edge.d.ts +8 -3
  23. package/dist/esm/edge.d.ts.map +1 -1
  24. package/dist/esm/edge.js +9 -1
  25. package/dist/esm/edge.js.map +1 -1
  26. package/dist/esm/graph.d.ts +22 -12
  27. package/dist/esm/graph.d.ts.map +1 -1
  28. package/dist/esm/graph.js +122 -23
  29. package/dist/esm/graph.js.map +1 -1
  30. package/dist/esm/ideal/add-nodes.d.ts +17 -2
  31. package/dist/esm/ideal/add-nodes.d.ts.map +1 -1
  32. package/dist/esm/ideal/add-nodes.js +15 -4
  33. package/dist/esm/ideal/add-nodes.js.map +1 -1
  34. package/dist/esm/ideal/append-nodes.d.ts +11 -1
  35. package/dist/esm/ideal/append-nodes.d.ts.map +1 -1
  36. package/dist/esm/ideal/append-nodes.js +176 -31
  37. package/dist/esm/ideal/append-nodes.js.map +1 -1
  38. package/dist/esm/ideal/build-ideal-from-starting-graph.d.ts.map +1 -1
  39. package/dist/esm/ideal/build-ideal-from-starting-graph.js +9 -5
  40. package/dist/esm/ideal/build-ideal-from-starting-graph.js.map +1 -1
  41. package/dist/esm/ideal/build.d.ts +9 -0
  42. package/dist/esm/ideal/build.d.ts.map +1 -1
  43. package/dist/esm/ideal/build.js +4 -1
  44. package/dist/esm/ideal/build.js.map +1 -1
  45. package/dist/esm/ideal/get-importer-specs.d.ts +3 -2
  46. package/dist/esm/ideal/get-importer-specs.d.ts.map +1 -1
  47. package/dist/esm/ideal/get-importer-specs.js +7 -5
  48. package/dist/esm/ideal/get-importer-specs.js.map +1 -1
  49. package/dist/esm/index.d.ts +8 -4
  50. package/dist/esm/index.d.ts.map +1 -1
  51. package/dist/esm/index.js +4 -1
  52. package/dist/esm/index.js.map +1 -1
  53. package/dist/esm/install.d.ts +11 -5
  54. package/dist/esm/install.d.ts.map +1 -1
  55. package/dist/esm/install.js +167 -23
  56. package/dist/esm/install.js.map +1 -1
  57. package/dist/esm/lockfile/load-edges.d.ts +8 -1
  58. package/dist/esm/lockfile/load-edges.d.ts.map +1 -1
  59. package/dist/esm/lockfile/load-edges.js +79 -15
  60. package/dist/esm/lockfile/load-edges.js.map +1 -1
  61. package/dist/esm/lockfile/load-nodes.d.ts +3 -2
  62. package/dist/esm/lockfile/load-nodes.d.ts.map +1 -1
  63. package/dist/esm/lockfile/load-nodes.js +69 -12
  64. package/dist/esm/lockfile/load-nodes.js.map +1 -1
  65. package/dist/esm/lockfile/load.d.ts +18 -5
  66. package/dist/esm/lockfile/load.d.ts.map +1 -1
  67. package/dist/esm/lockfile/load.js +53 -22
  68. package/dist/esm/lockfile/load.js.map +1 -1
  69. package/dist/esm/lockfile/save.d.ts +12 -3
  70. package/dist/esm/lockfile/save.d.ts.map +1 -1
  71. package/dist/esm/lockfile/save.js +45 -16
  72. package/dist/esm/lockfile/save.js.map +1 -1
  73. package/dist/esm/lockfile/types.d.ts +33 -4
  74. package/dist/esm/lockfile/types.d.ts.map +1 -1
  75. package/dist/esm/lockfile/types.js +31 -0
  76. package/dist/esm/lockfile/types.js.map +1 -1
  77. package/dist/esm/modifiers.d.ts +189 -0
  78. package/dist/esm/modifiers.d.ts.map +1 -0
  79. package/dist/esm/modifiers.js +330 -0
  80. package/dist/esm/modifiers.js.map +1 -0
  81. package/dist/esm/node.d.ts +73 -6
  82. package/dist/esm/node.d.ts.map +1 -1
  83. package/dist/esm/node.js +94 -2
  84. package/dist/esm/node.js.map +1 -1
  85. package/dist/esm/reify/add-edge.d.ts +1 -1
  86. package/dist/esm/reify/add-edge.d.ts.map +1 -1
  87. package/dist/esm/reify/add-edge.js +36 -14
  88. package/dist/esm/reify/add-edge.js.map +1 -1
  89. package/dist/esm/reify/add-nodes.d.ts.map +1 -1
  90. package/dist/esm/reify/add-nodes.js +4 -27
  91. package/dist/esm/reify/add-nodes.js.map +1 -1
  92. package/dist/esm/reify/bin-paths.d.ts +1 -1
  93. package/dist/esm/reify/bin-paths.d.ts.map +1 -1
  94. package/dist/esm/reify/bin-paths.js.map +1 -1
  95. package/dist/esm/reify/build.d.ts +10 -1
  96. package/dist/esm/reify/build.d.ts.map +1 -1
  97. package/dist/esm/reify/build.js +36 -7
  98. package/dist/esm/reify/build.js.map +1 -1
  99. package/dist/esm/reify/calculate-save-value.d.ts +3 -0
  100. package/dist/esm/reify/calculate-save-value.d.ts.map +1 -0
  101. package/dist/esm/reify/calculate-save-value.js +45 -0
  102. package/dist/esm/reify/calculate-save-value.js.map +1 -0
  103. package/dist/esm/reify/check-needed-build.d.ts +25 -0
  104. package/dist/esm/reify/check-needed-build.d.ts.map +1 -0
  105. package/dist/esm/reify/check-needed-build.js +50 -0
  106. package/dist/esm/reify/check-needed-build.js.map +1 -0
  107. package/dist/esm/reify/delete-edge.js +1 -1
  108. package/dist/esm/reify/delete-edge.js.map +1 -1
  109. package/dist/esm/reify/delete-nodes.d.ts.map +1 -1
  110. package/dist/esm/reify/delete-nodes.js +4 -0
  111. package/dist/esm/reify/delete-nodes.js.map +1 -1
  112. package/dist/esm/reify/extract-node.d.ts +24 -0
  113. package/dist/esm/reify/extract-node.d.ts.map +1 -0
  114. package/dist/esm/reify/extract-node.js +76 -0
  115. package/dist/esm/reify/extract-node.js.map +1 -0
  116. package/dist/esm/reify/index.d.ts +18 -1
  117. package/dist/esm/reify/index.d.ts.map +1 -1
  118. package/dist/esm/reify/index.js +78 -13
  119. package/dist/esm/reify/index.js.map +1 -1
  120. package/dist/esm/reify/internal-hoist.d.ts +9 -0
  121. package/dist/esm/reify/internal-hoist.d.ts.map +1 -0
  122. package/dist/esm/reify/internal-hoist.js +121 -0
  123. package/dist/esm/reify/internal-hoist.js.map +1 -0
  124. package/dist/esm/reify/update-importers-package-json.d.ts +1 -1
  125. package/dist/esm/reify/update-importers-package-json.d.ts.map +1 -1
  126. package/dist/esm/reify/update-importers-package-json.js +35 -12
  127. package/dist/esm/reify/update-importers-package-json.js.map +1 -1
  128. package/dist/esm/remove-optional-subgraph.js +1 -1
  129. package/dist/esm/remove-optional-subgraph.js.map +1 -1
  130. package/dist/esm/resolve-save-type.d.ts +6 -0
  131. package/dist/esm/resolve-save-type.d.ts.map +1 -0
  132. package/dist/esm/resolve-save-type.js +5 -0
  133. package/dist/esm/resolve-save-type.js.map +1 -0
  134. package/dist/esm/stringify-node.d.ts +1 -1
  135. package/dist/esm/stringify-node.d.ts.map +1 -1
  136. package/dist/esm/stringify-node.js.map +1 -1
  137. package/dist/esm/transfer-data/load.d.ts +44 -0
  138. package/dist/esm/transfer-data/load.d.ts.map +1 -0
  139. package/dist/esm/transfer-data/load.js +176 -0
  140. package/dist/esm/transfer-data/load.js.map +1 -0
  141. package/dist/esm/uninstall.d.ts +8 -6
  142. package/dist/esm/uninstall.d.ts.map +1 -1
  143. package/dist/esm/uninstall.js +51 -22
  144. package/dist/esm/uninstall.js.map +1 -1
  145. package/dist/esm/update.d.ts +13 -0
  146. package/dist/esm/update.d.ts.map +1 -0
  147. package/dist/esm/update.js +63 -0
  148. package/dist/esm/update.js.map +1 -0
  149. package/dist/esm/virtual-root.d.ts +16 -0
  150. package/dist/esm/virtual-root.d.ts.map +1 -0
  151. package/dist/esm/virtual-root.js +79 -0
  152. package/dist/esm/virtual-root.js.map +1 -0
  153. package/dist/esm/visualization/human-readable-output.d.ts +4 -5
  154. package/dist/esm/visualization/human-readable-output.d.ts.map +1 -1
  155. package/dist/esm/visualization/human-readable-output.js +51 -24
  156. package/dist/esm/visualization/human-readable-output.js.map +1 -1
  157. package/dist/esm/visualization/json-output.d.ts +7 -3
  158. package/dist/esm/visualization/json-output.d.ts.map +1 -1
  159. package/dist/esm/visualization/json-output.js +35 -12
  160. package/dist/esm/visualization/json-output.js.map +1 -1
  161. package/dist/esm/visualization/mermaid-output.d.ts +7 -1
  162. package/dist/esm/visualization/mermaid-output.d.ts.map +1 -1
  163. package/dist/esm/visualization/mermaid-output.js +64 -9
  164. package/dist/esm/visualization/mermaid-output.js.map +1 -1
  165. package/dist/esm/visualization/object-like-output.d.ts +1 -1
  166. package/dist/esm/visualization/object-like-output.d.ts.map +1 -1
  167. package/dist/esm/visualization/object-like-output.js.map +1 -1
  168. package/package.json +30 -25
  169. package/dist/esm/types.d.ts +0 -39
  170. package/dist/esm/types.d.ts.map +0 -1
  171. package/dist/esm/types.js +0 -2
  172. package/dist/esm/types.js.map +0 -1
@@ -1,8 +1,15 @@
1
+ import type { PathScurry } from 'path-scurry';
1
2
  import type { PackageInfoClient } from '@vltpkg/package-info';
2
3
  import type { SpecOptions } from '@vltpkg/spec';
3
- import type { PathScurry } from 'path-scurry';
4
+ import type { RollbackRemove } from '@vltpkg/rollback-remove';
4
5
  import type { BuildIdealAddOptions, BuildIdealFromGraphOptions } from './types.ts';
6
+ import type { GraphModifier } from '../modifiers.ts';
7
+ import type { Graph } from '../graph.ts';
5
8
  export type AddNodesOptions = BuildIdealAddOptions & BuildIdealFromGraphOptions & SpecOptions & {
9
+ /**
10
+ * The graph modifiers helper object.
11
+ */
12
+ modifiers?: GraphModifier;
6
13
  /**
7
14
  * A {@link PathScurry} instance based on the `projectRoot` path
8
15
  */
@@ -11,9 +18,17 @@ export type AddNodesOptions = BuildIdealAddOptions & BuildIdealFromGraphOptions
11
18
  * A {@link PackageInfoClient} instance to read manifest info from.
12
19
  */
13
20
  packageInfo: PackageInfoClient;
21
+ /**
22
+ * The actual graph to compare against for early extraction
23
+ */
24
+ actual?: Graph;
25
+ /**
26
+ * A {@link RollbackRemove} instance to handle extraction rollbacks
27
+ */
28
+ remover: RollbackRemove;
14
29
  };
15
30
  /**
16
31
  * Add new nodes in the given `graph` for dependencies specified at `add`.
17
32
  */
18
- export declare const addNodes: ({ add, graph, packageInfo, scurry, ...specOptions }: AddNodesOptions) => Promise<void>;
33
+ export declare const addNodes: ({ add, graph, modifiers, packageInfo, scurry, actual, remover, ...specOptions }: AddNodesOptions) => Promise<void>;
19
34
  //# sourceMappingURL=add-nodes.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"add-nodes.d.ts","sourceRoot":"","sources":["../../../src/ideal/add-nodes.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AAC7D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAC/C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAE7C,OAAO,KAAK,EACV,oBAAoB,EACpB,0BAA0B,EAC3B,MAAM,YAAY,CAAA;AAEnB,MAAM,MAAM,eAAe,GAAG,oBAAoB,GAChD,0BAA0B,GAC1B,WAAW,GAAG;IACZ;;OAEG;IACH,MAAM,EAAE,UAAU,CAAA;IAElB;;OAEG;IACH,WAAW,EAAE,iBAAiB,CAAA;CAC/B,CAAA;AAEH;;GAEG;AACH,eAAO,MAAM,QAAQ,wDAMlB,eAAe,kBA+BjB,CAAA"}
1
+ {"version":3,"file":"add-nodes.d.ts","sourceRoot":"","sources":["../../../src/ideal/add-nodes.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAE7C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AAC7D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAC/C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAA;AAC7D,OAAO,KAAK,EACV,oBAAoB,EACpB,0BAA0B,EAC3B,MAAM,YAAY,CAAA;AACnB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAEpD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AAExC,MAAM,MAAM,eAAe,GAAG,oBAAoB,GAChD,0BAA0B,GAC1B,WAAW,GAAG;IACZ;;OAEG;IACH,SAAS,CAAC,EAAE,aAAa,CAAA;IACzB;;OAEG;IACH,MAAM,EAAE,UAAU,CAAA;IAElB;;OAEG;IACH,WAAW,EAAE,iBAAiB,CAAA;IAE9B;;OAEG;IACH,MAAM,CAAC,EAAE,KAAK,CAAA;IAEd;;OAEG;IACH,OAAO,EAAE,cAAc,CAAA;CACxB,CAAA;AAEH;;GAEG;AACH,eAAO,MAAM,QAAQ,oFASlB,eAAe,kBAiDjB,CAAA"}
@@ -1,10 +1,13 @@
1
1
  import { error } from '@vltpkg/error-cause';
2
2
  import { appendNodes } from "./append-nodes.js";
3
+ import { resolveSaveType } from "../resolve-save-type.js";
3
4
  /**
4
5
  * Add new nodes in the given `graph` for dependencies specified at `add`.
5
6
  */
6
- export const addNodes = async ({ add, graph, packageInfo, scurry, ...specOptions }) => {
7
+ export const addNodes = async ({ add, graph, modifiers, packageInfo, scurry, actual, remover, ...specOptions }) => {
7
8
  const seen = new Set();
9
+ const extractPromises = [];
10
+ const seenExtracted = new Set();
8
11
  // iterates on the list of dependencies per importer updating
9
12
  // the graph using metadata fetch from the registry manifest files
10
13
  for (const [depID, dependencies] of add) {
@@ -12,17 +15,25 @@ export const addNodes = async ({ add, graph, packageInfo, scurry, ...specOptions
12
15
  if (!importer) {
13
16
  throw error('Could not find importer', { found: depID });
14
17
  }
18
+ modifiers?.tryImporter(importer);
15
19
  // Removes any edges and nodes that are currently part of the
16
20
  // graph but are also in the list of dependencies to be installed
17
21
  const deps = [...dependencies.values()];
18
- for (const { spec } of deps) {
19
- const node = importer.edgesOut.get(spec.name)?.to;
22
+ for (const dep of deps) {
23
+ const { spec } = dep;
24
+ const existingEdge = importer.edgesOut.get(spec.name);
25
+ dep.type = resolveSaveType(importer, spec.name, dep.type);
26
+ const node = existingEdge?.to;
20
27
  if (node)
21
28
  graph.removeNode(node);
22
29
  }
23
30
  // Add new nodes for packages defined in the dependencies list fetching
24
31
  // metadata from the registry manifests and updating the graph
25
- await appendNodes(dependencies, packageInfo, graph, importer, deps, scurry, specOptions, seen);
32
+ await appendNodes(dependencies, packageInfo, graph, importer, deps, scurry, specOptions, seen, modifiers, modifiers?.tryDependencies(importer, deps), extractPromises, actual, seenExtracted, remover);
33
+ }
34
+ // Wait for all extraction promises to complete
35
+ if (extractPromises.length > 0) {
36
+ await Promise.all(extractPromises);
26
37
  }
27
38
  };
28
39
  //# sourceMappingURL=add-nodes.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"add-nodes.js","sourceRoot":"","sources":["../../../src/ideal/add-nodes.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAA;AAI3C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAoB/C;;GAEG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,KAAK,EAAE,EAC7B,GAAG,EACH,KAAK,EACL,WAAW,EACX,MAAM,EACN,GAAG,WAAW,EACE,EAAE,EAAE;IACpB,MAAM,IAAI,GAAG,IAAI,GAAG,EAAS,CAAA;IAC7B,6DAA6D;IAC7D,kEAAkE;IAClE,KAAK,MAAM,CAAC,KAAK,EAAE,YAAY,CAAC,IAAI,GAAG,EAAE,CAAC;QACxC,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;QACvC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,MAAM,KAAK,CAAC,yBAAyB,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAA;QAC1D,CAAC;QAED,6DAA6D;QAC7D,iEAAiE;QACjE,MAAM,IAAI,GAAG,CAAC,GAAG,YAAY,CAAC,MAAM,EAAE,CAAC,CAAA;QACvC,KAAK,MAAM,EAAE,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC;YAC5B,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAA;YACjD,IAAI,IAAI;gBAAE,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAA;QAClC,CAAC;QAED,uEAAuE;QACvE,8DAA8D;QAC9D,MAAM,WAAW,CACf,YAAY,EACZ,WAAW,EACX,KAAK,EACL,QAAQ,EACR,IAAI,EACJ,MAAM,EACN,WAAW,EACX,IAAI,CACL,CAAA;IACH,CAAC;AACH,CAAC,CAAA","sourcesContent":["import type { DepID } from '@vltpkg/dep-id'\nimport { error } from '@vltpkg/error-cause'\nimport type { PackageInfoClient } from '@vltpkg/package-info'\nimport type { SpecOptions } from '@vltpkg/spec'\nimport type { PathScurry } from 'path-scurry'\nimport { appendNodes } from './append-nodes.ts'\nimport type {\n BuildIdealAddOptions,\n BuildIdealFromGraphOptions,\n} from './types.ts'\n\nexport type AddNodesOptions = BuildIdealAddOptions &\n BuildIdealFromGraphOptions &\n SpecOptions & {\n /**\n * A {@link PathScurry} instance based on the `projectRoot` path\n */\n scurry: PathScurry\n\n /**\n * A {@link PackageInfoClient} instance to read manifest info from.\n */\n packageInfo: PackageInfoClient\n }\n\n/**\n * Add new nodes in the given `graph` for dependencies specified at `add`.\n */\nexport const addNodes = async ({\n add,\n graph,\n packageInfo,\n scurry,\n ...specOptions\n}: AddNodesOptions) => {\n const seen = new Set<DepID>()\n // iterates on the list of dependencies per importer updating\n // the graph using metadata fetch from the registry manifest files\n for (const [depID, dependencies] of add) {\n const importer = graph.nodes.get(depID)\n if (!importer) {\n throw error('Could not find importer', { found: depID })\n }\n\n // Removes any edges and nodes that are currently part of the\n // graph but are also in the list of dependencies to be installed\n const deps = [...dependencies.values()]\n for (const { spec } of deps) {\n const node = importer.edgesOut.get(spec.name)?.to\n if (node) graph.removeNode(node)\n }\n\n // Add new nodes for packages defined in the dependencies list fetching\n // metadata from the registry manifests and updating the graph\n await appendNodes(\n dependencies,\n packageInfo,\n graph,\n importer,\n deps,\n scurry,\n specOptions,\n seen,\n )\n }\n}\n"]}
1
+ {"version":3,"file":"add-nodes.js","sourceRoot":"","sources":["../../../src/ideal/add-nodes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAA;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AA0CzD;;GAEG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,KAAK,EAAE,EAC7B,GAAG,EACH,KAAK,EACL,SAAS,EACT,WAAW,EACX,MAAM,EACN,MAAM,EACN,OAAO,EACP,GAAG,WAAW,EACE,EAAE,EAAE;IACpB,MAAM,IAAI,GAAG,IAAI,GAAG,EAAS,CAAA;IAC7B,MAAM,eAAe,GAA6B,EAAE,CAAA;IACpD,MAAM,aAAa,GAAG,IAAI,GAAG,EAAS,CAAA;IAEtC,6DAA6D;IAC7D,kEAAkE;IAClE,KAAK,MAAM,CAAC,KAAK,EAAE,YAAY,CAAC,IAAI,GAAG,EAAE,CAAC;QACxC,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;QACvC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,MAAM,KAAK,CAAC,yBAAyB,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAA;QAC1D,CAAC;QACD,SAAS,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAA;QAEhC,6DAA6D;QAC7D,iEAAiE;QACjE,MAAM,IAAI,GAAG,CAAC,GAAG,YAAY,CAAC,MAAM,EAAE,CAAC,CAAA;QACvC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,MAAM,EAAE,IAAI,EAAE,GAAG,GAAG,CAAA;YACpB,MAAM,YAAY,GAAG,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YACrD,GAAG,CAAC,IAAI,GAAG,eAAe,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,CAAA;YACzD,MAAM,IAAI,GAAG,YAAY,EAAE,EAAE,CAAA;YAC7B,IAAI,IAAI;gBAAE,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAA;QAClC,CAAC;QAED,uEAAuE;QACvE,8DAA8D;QAC9D,MAAM,WAAW,CACf,YAAY,EACZ,WAAW,EACX,KAAK,EACL,QAAQ,EACR,IAAI,EACJ,MAAM,EACN,WAAW,EACX,IAAI,EACJ,SAAS,EACT,SAAS,EAAE,eAAe,CAAC,QAAQ,EAAE,IAAI,CAAC,EAC1C,eAAe,EACf,MAAM,EACN,aAAa,EACb,OAAO,CACR,CAAA;IACH,CAAC;IAED,+CAA+C;IAC/C,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/B,MAAM,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAA;IACpC,CAAC;AACH,CAAC,CAAA","sourcesContent":["import { error } from '@vltpkg/error-cause'\nimport { appendNodes } from './append-nodes.ts'\nimport { resolveSaveType } from '../resolve-save-type.ts'\nimport type { PathScurry } from 'path-scurry'\nimport type { DepID } from '@vltpkg/dep-id'\nimport type { PackageInfoClient } from '@vltpkg/package-info'\nimport type { SpecOptions } from '@vltpkg/spec'\nimport type { RollbackRemove } from '@vltpkg/rollback-remove'\nimport type {\n BuildIdealAddOptions,\n BuildIdealFromGraphOptions,\n} from './types.ts'\nimport type { GraphModifier } from '../modifiers.ts'\nimport type { ExtractResult } from '../reify/extract-node.ts'\nimport type { Graph } from '../graph.ts'\n\nexport type AddNodesOptions = BuildIdealAddOptions &\n BuildIdealFromGraphOptions &\n SpecOptions & {\n /**\n * The graph modifiers helper object.\n */\n modifiers?: GraphModifier\n /**\n * A {@link PathScurry} instance based on the `projectRoot` path\n */\n scurry: PathScurry\n\n /**\n * A {@link PackageInfoClient} instance to read manifest info from.\n */\n packageInfo: PackageInfoClient\n\n /**\n * The actual graph to compare against for early extraction\n */\n actual?: Graph\n\n /**\n * A {@link RollbackRemove} instance to handle extraction rollbacks\n */\n remover: RollbackRemove\n }\n\n/**\n * Add new nodes in the given `graph` for dependencies specified at `add`.\n */\nexport const addNodes = async ({\n add,\n graph,\n modifiers,\n packageInfo,\n scurry,\n actual,\n remover,\n ...specOptions\n}: AddNodesOptions) => {\n const seen = new Set<DepID>()\n const extractPromises: Promise<ExtractResult>[] = []\n const seenExtracted = new Set<DepID>()\n\n // iterates on the list of dependencies per importer updating\n // the graph using metadata fetch from the registry manifest files\n for (const [depID, dependencies] of add) {\n const importer = graph.nodes.get(depID)\n if (!importer) {\n throw error('Could not find importer', { found: depID })\n }\n modifiers?.tryImporter(importer)\n\n // Removes any edges and nodes that are currently part of the\n // graph but are also in the list of dependencies to be installed\n const deps = [...dependencies.values()]\n for (const dep of deps) {\n const { spec } = dep\n const existingEdge = importer.edgesOut.get(spec.name)\n dep.type = resolveSaveType(importer, spec.name, dep.type)\n const node = existingEdge?.to\n if (node) graph.removeNode(node)\n }\n\n // Add new nodes for packages defined in the dependencies list fetching\n // metadata from the registry manifests and updating the graph\n await appendNodes(\n dependencies,\n packageInfo,\n graph,\n importer,\n deps,\n scurry,\n specOptions,\n seen,\n modifiers,\n modifiers?.tryDependencies(importer, deps),\n extractPromises,\n actual,\n seenExtracted,\n remover,\n )\n }\n\n // Wait for all extraction promises to complete\n if (extractPromises.length > 0) {\n await Promise.all(extractPromises)\n }\n}\n"]}
@@ -5,5 +5,15 @@ import type { PathScurry } from 'path-scurry';
5
5
  import type { Dependency } from '../dependencies.ts';
6
6
  import type { Graph } from '../graph.ts';
7
7
  import type { Node } from '../node.ts';
8
- export declare const appendNodes: (add: Map<string, Dependency>, packageInfo: PackageInfoClient, graph: Graph, fromNode: Node, deps: Dependency[], scurry: PathScurry, options: SpecOptions, seen: Set<DepID>) => Promise<void>;
8
+ import type { GraphModifier, ModifierActiveEntry } from '../modifiers.ts';
9
+ import type { ExtractResult } from '../reify/extract-node.ts';
10
+ import type { RollbackRemove } from '@vltpkg/rollback-remove';
11
+ /**
12
+ * Append new nodes in the given `graph` for dependencies specified at `add`
13
+ * and missing dependencies from the `deps` parameter.
14
+ *
15
+ * It also applies any modifiers that applies to a given node as it processes
16
+ * and builds the graph.
17
+ */
18
+ export declare const appendNodes: (add: Map<string, Dependency>, packageInfo: PackageInfoClient, graph: Graph, fromNode: Node, deps: Dependency[], scurry: PathScurry, options: SpecOptions, seen: Set<DepID>, modifiers?: GraphModifier, modifierRefs?: Map<string, ModifierActiveEntry>, extractPromises?: Promise<ExtractResult>[], actual?: Graph, seenExtracted?: Set<DepID>, remover?: RollbackRemove) => Promise<void>;
9
19
  //# sourceMappingURL=append-nodes.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"append-nodes.d.ts","sourceRoot":"","sources":["../../../src/ideal/append-nodes.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAA;AAE3C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AAE7D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAG/C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAE7C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AACpD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAA;AAuDtC,eAAO,MAAM,WAAW,QACjB,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,eACf,iBAAiB,SACvB,KAAK,YACF,IAAI,QACR,UAAU,EAAE,UACV,UAAU,WACT,WAAW,QACd,GAAG,CAAC,KAAK,CAAC,kBAwIjB,CAAA"}
1
+ {"version":3,"file":"append-nodes.d.ts","sourceRoot":"","sources":["../../../src/ideal/append-nodes.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAA;AAE3C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AAE7D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAO/C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAE7C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AACpD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAA;AAEtC,OAAO,KAAK,EACV,aAAa,EACb,mBAAmB,EACpB,MAAM,iBAAiB,CAAA;AACxB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AAE7D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAA;AA6W7D;;;;;;GAMG;AACH,eAAO,MAAM,WAAW,QACjB,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,eACf,iBAAiB,SACvB,KAAK,YACF,IAAI,QACR,UAAU,EAAE,UACV,UAAU,WACT,WAAW,QACd,GAAG,CAAC,KAAK,CAAC,cACJ,aAAa,iBACV,GAAG,CAAC,MAAM,EAAE,mBAAmB,CAAC,oBAC7B,OAAO,CAAC,aAAa,CAAC,EAAE,WACjC,KAAK,kBACE,GAAG,CAAC,KAAK,CAAC,YAChB,cAAc,kBA2EzB,CAAA"}
@@ -1,9 +1,10 @@
1
1
  import { joinDepIDTuple } from '@vltpkg/dep-id';
2
2
  import { error } from '@vltpkg/error-cause';
3
3
  import { Spec } from '@vltpkg/spec';
4
- import { longDependencyTypes } from '@vltpkg/types';
4
+ import { longDependencyTypes, normalizeManifest } from '@vltpkg/types';
5
5
  import { asDependency, shorten } from "../dependencies.js";
6
6
  import { removeOptionalSubgraph } from "../remove-optional-subgraph.js";
7
+ import { extractNode } from "../reify/extract-node.js";
7
8
  /**
8
9
  * Only install devDeps for git dependencies and importers
9
10
  * Everything else always gets installed
@@ -36,22 +37,47 @@ const getFileTypeInfo = (spec, fromNode, scurry) => {
36
37
  };
37
38
  };
38
39
  const isStringArray = (a) => Array.isArray(a) && !a.some(b => typeof b !== 'string');
39
- export const appendNodes = async (add, packageInfo, graph, fromNode, deps, scurry, options, seen) => {
40
- /* c8 ignore next */
41
- if (seen.has(fromNode.id))
42
- return;
43
- seen.add(fromNode.id);
44
- await Promise.all(deps.map(async ({ spec, type }) => {
45
- // see if there's a satisfying node in the graph currently
40
+ /**
41
+ * Fetch manifests for dependencies and create placement tasks.
42
+ */
43
+ const fetchManifestsForDeps = async (packageInfo, graph, fromNode, deps, scurry, modifierRefs, depth = 0) => {
44
+ // Create fetch tasks for all dependencies at this level
45
+ const fetchTasks = [];
46
+ for (const { spec: originalSpec, type } of deps) {
47
+ let spec = originalSpec;
46
48
  const fileTypeInfo = getFileTypeInfo(spec, fromNode, scurry);
47
- const existingNode = graph.findResolution(spec, fromNode);
49
+ const activeModifier = modifierRefs?.get(spec.name);
50
+ // here is the place we swap specs if a edge modifier was defined
51
+ const queryModifier = activeModifier?.modifier.query;
52
+ const completeModifier = activeModifier &&
53
+ activeModifier.interactiveBreadcrumb.current ===
54
+ activeModifier.modifier.breadcrumb.last;
55
+ if (queryModifier &&
56
+ completeModifier &&
57
+ 'spec' in activeModifier.modifier) {
58
+ spec = activeModifier.modifier.spec;
59
+ if (spec.bareSpec === '-') {
60
+ continue;
61
+ }
62
+ }
63
+ const existingNode = graph.findResolution(spec, fromNode, queryModifier);
48
64
  if (existingNode) {
49
- graph.addEdge(type, spec, fromNode, existingNode);
50
- return;
65
+ // For peerOptional dependencies, create a dangling edge instead of linking to existing node
66
+ if (type === 'peerOptional') {
67
+ /* c8 ignore next 3 */
68
+ // This case happens when peerOptional dep already exists in graph
69
+ graph.addEdge(type, spec, fromNode);
70
+ }
71
+ else {
72
+ graph.addEdge(type, spec, fromNode, existingNode);
73
+ }
74
+ continue;
51
75
  }
52
76
  const edgeOptional = type === 'optional' || type === 'peerOptional';
53
- const mani = await packageInfo
77
+ // Start manifest fetch immediately for parallel processing
78
+ const manifestPromise = packageInfo
54
79
  .manifest(spec, { from: scurry.resolve(fromNode.location) })
80
+ .then(manifest => manifest)
55
81
  .catch((er) => {
56
82
  // optional deps ignored if inaccessible
57
83
  if (edgeOptional || fromNode.optional) {
@@ -59,36 +85,72 @@ export const appendNodes = async (add, packageInfo, graph, fromNode, deps, scurr
59
85
  }
60
86
  throw er;
61
87
  });
62
- // when an user is adding a nameless dependency, e.g: `github:foo/bar`,
63
- // `file:./foo/bar`, we need to update the `add` option value to set the
64
- // correct name once we have it, so that it can properly be stored in
65
- // the `package.json` file at the end of reify.
66
- if (mani?.name && spec.name === '(unknown)') {
88
+ const fetchTask = {
89
+ spec,
90
+ type,
91
+ fromNode,
92
+ fileTypeInfo,
93
+ activeModifier,
94
+ queryModifier,
95
+ edgeOptional,
96
+ manifestPromise,
97
+ depth,
98
+ };
99
+ fetchTasks.push(fetchTask);
100
+ }
101
+ // Create placement tasks
102
+ const placementTasks = [];
103
+ for (const fetchTask of fetchTasks) {
104
+ const manifest = await fetchTask.manifestPromise;
105
+ placementTasks.push({
106
+ fetchTask,
107
+ manifest,
108
+ });
109
+ }
110
+ return placementTasks;
111
+ };
112
+ /**
113
+ * Process placement tasks and collect child dependencies
114
+ */
115
+ const processPlacementTasks = async (add, graph, options, placementTasks, modifiers, scurry, packageInfo, extractPromises, actual, seenExtracted, remover) => {
116
+ const childDepsToProcess = [];
117
+ for (const placementTask of placementTasks) {
118
+ const { fetchTask, manifest } = placementTask;
119
+ let { spec } = fetchTask;
120
+ const type = fetchTask.type;
121
+ const fromNode = fetchTask.fromNode;
122
+ const fileTypeInfo = fetchTask.fileTypeInfo;
123
+ const activeModifier = fetchTask.activeModifier;
124
+ const queryModifier = fetchTask.queryModifier;
125
+ const edgeOptional = fetchTask.edgeOptional;
126
+ // Handle nameless dependencies
127
+ if (manifest?.name && spec.name === '(unknown)') {
67
128
  const s = add.get(String(spec));
68
129
  if (s) {
69
130
  // removes the previous, placeholder entry key
70
131
  add.delete(String(spec));
71
132
  // replaces spec with a version with the correct name
72
- spec = Spec.parse(mani.name, spec.bareSpec, options);
133
+ spec = Spec.parse(manifest.name, spec.bareSpec, options);
73
134
  // updates the add map with the fixed up spec
74
135
  const n = asDependency({
75
136
  ...s,
76
137
  spec,
77
138
  });
78
- add.set(mani.name, n);
139
+ add.set(manifest.name, n);
79
140
  }
80
141
  }
81
- if (!mani) {
142
+ // handles missing manifest resolution
143
+ if (!manifest) {
82
144
  if (!edgeOptional && fromNode.isOptional()) {
83
145
  // failed resolution of a non-optional dep of an optional node
84
146
  // have to clean up the dependents
85
147
  removeOptionalSubgraph(graph, fromNode);
86
- return;
148
+ continue;
87
149
  }
88
150
  else if (edgeOptional) {
89
151
  // failed resolution of an optional dep, just ignore it,
90
152
  // nothing to prune because we never added it in the first place.
91
- return;
153
+ continue;
92
154
  }
93
155
  else {
94
156
  throw error('failed to resolve dependency', {
@@ -97,7 +159,14 @@ export const appendNodes = async (add, packageInfo, graph, fromNode, deps, scurr
97
159
  });
98
160
  }
99
161
  }
100
- const node = graph.placePackage(fromNode, type, spec, mani, fileTypeInfo?.id);
162
+ // Skip placing peerOptional dependencies, just create a dangling edge
163
+ if (type === 'peerOptional') {
164
+ /* c8 ignore next 3 */
165
+ graph.addEdge(type, spec, fromNode);
166
+ continue;
167
+ }
168
+ // places a new node in the graph representing a newly seen dependency
169
+ const node = graph.placePackage(fromNode, type, spec, normalizeManifest(manifest), fileTypeInfo?.id, queryModifier);
101
170
  /* c8 ignore start - not possible, already ensured manifest */
102
171
  if (!node) {
103
172
  throw error('failed to place package', {
@@ -106,26 +175,52 @@ export const appendNodes = async (add, packageInfo, graph, fromNode, deps, scurr
106
175
  });
107
176
  }
108
177
  /* c8 ignore stop */
178
+ // update the node modifier tracker
179
+ if (activeModifier) {
180
+ modifiers?.updateActiveEntry(node, activeModifier);
181
+ }
182
+ // Extract the node if it doesn't exist in the actual graph and we have the necessary parameters
183
+ if (remover &&
184
+ extractPromises &&
185
+ actual &&
186
+ scurry &&
187
+ packageInfo &&
188
+ node.inVltStore()) {
189
+ /* c8 ignore start */
190
+ if (seenExtracted?.has(node.id)) {
191
+ continue;
192
+ }
193
+ /* c8 ignore stop */
194
+ seenExtracted?.add(node.id);
195
+ const actualNode = actual.nodes.get(node.id);
196
+ if (!actualNode?.equals(node)) {
197
+ // Extract the node without awaiting - push the promise to the array
198
+ const extractPromise = extractNode(node, scurry, remover, options, packageInfo);
199
+ extractPromises.push(extractPromise);
200
+ }
201
+ }
202
+ // updates graph node information
109
203
  if (fileTypeInfo?.path && fileTypeInfo.isDirectory) {
110
204
  node.location = fileTypeInfo.path;
111
205
  }
112
206
  node.setResolved();
113
- const nestedAppends = [];
114
- const bundleDeps = node.manifest?.bundleDependencies;
207
+ // Collect child dependencies for processing in the next level
208
+ const bundleDeps = manifest.bundleDependencies;
115
209
  const bundled = new Set((node.id.startsWith('git') ||
116
210
  node.importer ||
117
211
  !isStringArray(bundleDeps)) ?
118
212
  []
119
213
  : bundleDeps);
214
+ // recursively process all child dependencies in the manifest
120
215
  const nextDeps = [];
121
216
  for (const depTypeName of longDependencyTypes) {
122
- const depRecord = mani[depTypeName];
217
+ const depRecord = manifest[depTypeName];
123
218
  if (depRecord && shouldInstallDepType(node, depTypeName)) {
124
219
  for (const [name, bareSpec] of Object.entries(depRecord)) {
125
220
  if (bundled.has(name))
126
221
  continue;
127
222
  nextDeps.push({
128
- type: shorten(depTypeName, name, mani),
223
+ type: shorten(depTypeName, name, manifest),
129
224
  spec: Spec.parse(name, bareSpec, {
130
225
  ...options,
131
226
  registry: spec.registry,
@@ -134,10 +229,60 @@ export const appendNodes = async (add, packageInfo, graph, fromNode, deps, scurr
134
229
  }
135
230
  }
136
231
  }
137
- if (nextDeps.length) {
138
- nestedAppends.push(appendNodes(add, packageInfo, graph, node, nextDeps, scurry, options, seen));
232
+ if (nextDeps.length > 0) {
233
+ childDepsToProcess.push({
234
+ node,
235
+ deps: nextDeps,
236
+ modifierRefs: modifiers?.tryDependencies(node, nextDeps),
237
+ });
238
+ }
239
+ }
240
+ return { childDepsToProcess };
241
+ };
242
+ /**
243
+ * Append new nodes in the given `graph` for dependencies specified at `add`
244
+ * and missing dependencies from the `deps` parameter.
245
+ *
246
+ * It also applies any modifiers that applies to a given node as it processes
247
+ * and builds the graph.
248
+ */
249
+ export const appendNodes = async (add, packageInfo, graph, fromNode, deps, scurry, options, seen, modifiers, modifierRefs, extractPromises, actual, seenExtracted, remover) => {
250
+ /* c8 ignore next */
251
+ if (seen.has(fromNode.id))
252
+ return;
253
+ seen.add(fromNode.id);
254
+ // Use a queue for breadth-first processing
255
+ let currentLevelDeps = [
256
+ { node: fromNode, deps, modifierRefs, depth: 0 },
257
+ ];
258
+ while (currentLevelDeps.length > 0) {
259
+ const nextLevelDeps = [];
260
+ // Process all nodes at the current level in parallel
261
+ const levelResults = await Promise.all(currentLevelDeps.map(async ({ node, deps: nodeDeps, modifierRefs: nodeModifierRefs, depth, }) => {
262
+ // Mark node as seen when we start processing its dependencies
263
+ seen.add(node.id);
264
+ // Fetch manifests for this node's dependencies
265
+ const placementTasks = await fetchManifestsForDeps(packageInfo, graph, node,
266
+ // Sort dependencies by spec.name for deterministic ordering
267
+ nodeDeps.sort((a, b) => a.spec.name.localeCompare(b.spec.name, 'en')), scurry, nodeModifierRefs, depth);
268
+ // Process the placement tasks and get child dependencies
269
+ return await processPlacementTasks(add, graph, options, placementTasks, modifiers, scurry, packageInfo, extractPromises, actual, seenExtracted, remover);
270
+ }));
271
+ // Collect all child dependencies for the next level
272
+ for (const { childDepsToProcess } of levelResults) {
273
+ for (const childDep of childDepsToProcess) {
274
+ if (!seen.has(childDep.node.id)) {
275
+ /* c8 ignore next */
276
+ const currentDepth = currentLevelDeps[0]?.depth ?? 0;
277
+ nextLevelDeps.push({
278
+ ...childDep,
279
+ depth: currentDepth + 1,
280
+ });
281
+ }
282
+ }
139
283
  }
140
- await Promise.all(nestedAppends);
141
- }));
284
+ // Move to the next level
285
+ currentLevelDeps = nextLevelDeps;
286
+ }
142
287
  };
143
288
  //# sourceMappingURL=append-nodes.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"append-nodes.js","sourceRoot":"","sources":["../../../src/ideal/append-nodes.ts"],"names":[],"mappings":"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","sourcesContent":["import { joinDepIDTuple } from '@vltpkg/dep-id'\nimport type { DepID } from '@vltpkg/dep-id'\nimport { error } from '@vltpkg/error-cause'\nimport type { PackageInfoClient } from '@vltpkg/package-info'\nimport { Spec } from '@vltpkg/spec'\nimport type { SpecOptions } from '@vltpkg/spec'\nimport { longDependencyTypes } from '@vltpkg/types'\nimport type { DependencyTypeLong } from '@vltpkg/types'\nimport type { PathScurry } from 'path-scurry'\nimport { asDependency, shorten } from '../dependencies.ts'\nimport type { Dependency } from '../dependencies.ts'\nimport type { Graph } from '../graph.ts'\nimport type { Node } from '../node.ts'\nimport { removeOptionalSubgraph } from '../remove-optional-subgraph.ts'\n\ntype FileTypeInfo = {\n id: DepID\n path: string\n isDirectory: boolean\n}\n\n/**\n * Only install devDeps for git dependencies and importers\n * Everything else always gets installed\n */\nconst shouldInstallDepType = (\n node: Node,\n depType: DependencyTypeLong,\n) =>\n depType !== 'devDependencies' ||\n node.importer ||\n node.id.startsWith('git')\n\n/**\n * Retrieve the {@link DepID} and location for a `file:` type {@link Node}.\n */\nconst getFileTypeInfo = (\n spec: Spec,\n fromNode: Node,\n scurry: PathScurry,\n): FileTypeInfo | undefined => {\n const f = spec.final\n if (f.type !== 'file') return\n\n /* c8 ignore start - should be impossible */\n if (!f.file) {\n throw error('no path on file specifier', { spec })\n }\n /* c8 ignore stop */\n\n // Given that both linked folders and local tarballs (both defined with\n // usage of the `file:` spec prefix) location needs to be relative to their\n // parents, build the expected path and use it for both location and id\n const target = scurry.cwd.resolve(fromNode.location).resolve(f.file)\n const path = target.relativePosix()\n const id = joinDepIDTuple(['file', path])\n\n return {\n path,\n id,\n isDirectory: !!target.lstatSync()?.isDirectory(),\n }\n}\n\nconst isStringArray = (a: unknown): a is string[] =>\n Array.isArray(a) && !a.some(b => typeof b !== 'string')\n\nexport const appendNodes = async (\n add: Map<string, Dependency>,\n packageInfo: PackageInfoClient,\n graph: Graph,\n fromNode: Node,\n deps: Dependency[],\n scurry: PathScurry,\n options: SpecOptions,\n seen: Set<DepID>,\n) => {\n /* c8 ignore next */\n if (seen.has(fromNode.id)) return\n seen.add(fromNode.id)\n\n await Promise.all(\n deps.map(async ({ spec, type }) => {\n // see if there's a satisfying node in the graph currently\n const fileTypeInfo = getFileTypeInfo(spec, fromNode, scurry)\n const existingNode = graph.findResolution(spec, fromNode)\n if (existingNode) {\n graph.addEdge(type, spec, fromNode, existingNode)\n return\n }\n const edgeOptional =\n type === 'optional' || type === 'peerOptional'\n const mani = await packageInfo\n .manifest(spec, { from: scurry.resolve(fromNode.location) })\n .catch((er: unknown) => {\n // optional deps ignored if inaccessible\n if (edgeOptional || fromNode.optional) {\n return undefined\n }\n throw er\n })\n\n // when an user is adding a nameless dependency, e.g: `github:foo/bar`,\n // `file:./foo/bar`, we need to update the `add` option value to set the\n // correct name once we have it, so that it can properly be stored in\n // the `package.json` file at the end of reify.\n if (mani?.name && spec.name === '(unknown)') {\n const s = add.get(String(spec))\n if (s) {\n // removes the previous, placeholder entry key\n add.delete(String(spec))\n // replaces spec with a version with the correct name\n spec = Spec.parse(mani.name, spec.bareSpec, options)\n // updates the add map with the fixed up spec\n const n = asDependency({\n ...s,\n spec,\n })\n add.set(mani.name, n)\n }\n }\n\n if (!mani) {\n if (!edgeOptional && fromNode.isOptional()) {\n // failed resolution of a non-optional dep of an optional node\n // have to clean up the dependents\n removeOptionalSubgraph(graph, fromNode)\n return\n } else if (edgeOptional) {\n // failed resolution of an optional dep, just ignore it,\n // nothing to prune because we never added it in the first place.\n return\n } else {\n throw error('failed to resolve dependency', {\n spec,\n from: fromNode.location,\n })\n }\n }\n\n const node = graph.placePackage(\n fromNode,\n type,\n spec,\n mani,\n fileTypeInfo?.id,\n )\n\n /* c8 ignore start - not possible, already ensured manifest */\n if (!node) {\n throw error('failed to place package', {\n from: fromNode.location,\n spec,\n })\n }\n /* c8 ignore stop */\n\n if (fileTypeInfo?.path && fileTypeInfo.isDirectory) {\n node.location = fileTypeInfo.path\n }\n node.setResolved()\n const nestedAppends: Promise<unknown>[] = []\n\n const bundleDeps = node.manifest?.bundleDependencies\n const bundled = new Set<string>(\n (\n node.id.startsWith('git') ||\n node.importer ||\n !isStringArray(bundleDeps)\n ) ?\n []\n : bundleDeps,\n )\n\n const nextDeps: Dependency[] = []\n\n for (const depTypeName of longDependencyTypes) {\n const depRecord: Record<string, string> | undefined =\n mani[depTypeName]\n\n if (depRecord && shouldInstallDepType(node, depTypeName)) {\n for (const [name, bareSpec] of Object.entries(depRecord)) {\n if (bundled.has(name)) continue\n nextDeps.push({\n type: shorten(depTypeName, name, mani),\n spec: Spec.parse(name, bareSpec, {\n ...options,\n registry: spec.registry,\n }),\n })\n }\n }\n }\n\n if (nextDeps.length) {\n nestedAppends.push(\n appendNodes(\n add,\n packageInfo,\n graph,\n node,\n nextDeps,\n scurry,\n options,\n seen,\n ),\n )\n }\n await Promise.all(nestedAppends)\n }),\n )\n}\n"]}
1
+ {"version":3,"file":"append-nodes.js","sourceRoot":"","sources":["../../../src/ideal/append-nodes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAE/C,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAA;AAE3C,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAA;AAEnC,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA;AAOtE,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAA;AAI1D,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAA;AAMvE,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AAStD;;;GAGG;AACH,MAAM,oBAAoB,GAAG,CAC3B,IAAU,EACV,OAA2B,EAC3B,EAAE,CACF,OAAO,KAAK,iBAAiB;IAC7B,IAAI,CAAC,QAAQ;IACb,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,CAAA;AAE3B;;GAEG;AACH,MAAM,eAAe,GAAG,CACtB,IAAU,EACV,QAAc,EACd,MAAkB,EACQ,EAAE;IAC5B,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAA;IACpB,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM;QAAE,OAAM;IAE7B,4CAA4C;IAC5C,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACZ,MAAM,KAAK,CAAC,2BAA2B,EAAE,EAAE,IAAI,EAAE,CAAC,CAAA;IACpD,CAAC;IACD,oBAAoB;IAEpB,uEAAuE;IACvE,2EAA2E;IAC3E,uEAAuE;IACvE,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;IACpE,MAAM,IAAI,GAAG,MAAM,CAAC,aAAa,EAAE,CAAA;IACnC,MAAM,EAAE,GAAG,cAAc,CAAC,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAA;IAEzC,OAAO;QACL,IAAI;QACJ,EAAE;QACF,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,SAAS,EAAE,EAAE,WAAW,EAAE;KACjD,CAAA;AACH,CAAC,CAAA;AAED,MAAM,aAAa,GAAG,CAAC,CAAU,EAAiB,EAAE,CAClD,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAA;AAsCzD;;GAEG;AACH,MAAM,qBAAqB,GAAG,KAAK,EACjC,WAA8B,EAC9B,KAAY,EACZ,QAAc,EACd,IAAkB,EAClB,MAAkB,EAClB,YAA+C,EAC/C,KAAK,GAAG,CAAC,EACqB,EAAE;IAChC,wDAAwD;IACxD,MAAM,UAAU,GAAwB,EAAE,CAAA;IAE1C,KAAK,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC;QAChD,IAAI,IAAI,GAAG,YAAY,CAAA;QACvB,MAAM,YAAY,GAAG,eAAe,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAA;QAC5D,MAAM,cAAc,GAAG,YAAY,EAAE,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAEnD,iEAAiE;QACjE,MAAM,aAAa,GAAG,cAAc,EAAE,QAAQ,CAAC,KAAK,CAAA;QACpD,MAAM,gBAAgB,GACpB,cAAc;YACd,cAAc,CAAC,qBAAqB,CAAC,OAAO;gBAC1C,cAAc,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAA;QAC3C,IACE,aAAa;YACb,gBAAgB;YAChB,MAAM,IAAI,cAAc,CAAC,QAAQ,EACjC,CAAC;YACD,IAAI,GAAG,cAAc,CAAC,QAAQ,CAAC,IAAI,CAAA;YACnC,IAAI,IAAI,CAAC,QAAQ,KAAK,GAAG,EAAE,CAAC;gBAC1B,SAAQ;YACV,CAAC;QACH,CAAC;QAED,MAAM,YAAY,GAAG,KAAK,CAAC,cAAc,CACvC,IAAI,EACJ,QAAQ,EACR,aAAa,CACd,CAAA;QACD,IAAI,YAAY,EAAE,CAAC;YACjB,4FAA4F;YAC5F,IAAI,IAAI,KAAK,cAAc,EAAE,CAAC;gBAC5B,sBAAsB;gBACtB,kEAAkE;gBAClE,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAA;YACrC,CAAC;iBAAM,CAAC;gBACN,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAA;YACnD,CAAC;YACD,SAAQ;QACV,CAAC;QAED,MAAM,YAAY,GAChB,IAAI,KAAK,UAAU,IAAI,IAAI,KAAK,cAAc,CAAA;QAEhD,2DAA2D;QAC3D,MAAM,eAAe,GAAG,WAAW;aAChC,QAAQ,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;aAC3D,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,QAAgC,CAAC;aAClD,KAAK,CAAC,CAAC,EAAW,EAAE,EAAE;YACrB,wCAAwC;YACxC,IAAI,YAAY,IAAI,QAAQ,CAAC,QAAQ,EAAE,CAAC;gBACtC,OAAO,SAAS,CAAA;YAClB,CAAC;YACD,MAAM,EAAE,CAAA;QACV,CAAC,CAAC,CAAA;QAEJ,MAAM,SAAS,GAAsB;YACnC,IAAI;YACJ,IAAI;YACJ,QAAQ;YACR,YAAY;YACZ,cAAc;YACd,aAAa;YACb,YAAY;YACZ,eAAe;YACf,KAAK;SACN,CAAA;QAED,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;IAC5B,CAAC;IAED,yBAAyB;IACzB,MAAM,cAAc,GAAwB,EAAE,CAAA;IAC9C,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACnC,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,eAAe,CAAA;QAEhD,cAAc,CAAC,IAAI,CAAC;YAClB,SAAS;YACT,QAAQ;SACT,CAAC,CAAA;IACJ,CAAC;IAED,OAAO,cAAc,CAAA;AACvB,CAAC,CAAA;AAED;;GAEG;AACH,MAAM,qBAAqB,GAAG,KAAK,EACjC,GAA4B,EAC5B,KAAY,EACZ,OAAoB,EACpB,cAAmC,EACnC,SAAyB,EACzB,MAAmB,EACnB,WAA+B,EAC/B,eAA0C,EAC1C,MAAc,EACd,aAA0B,EAC1B,OAAwB,EAGvB,EAAE;IACH,MAAM,kBAAkB,GAAqC,EAAE,CAAA;IAE/D,KAAK,MAAM,aAAa,IAAI,cAAc,EAAE,CAAC;QAC3C,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,aAAa,CAAA;QAC7C,IAAI,EAAE,IAAI,EAAE,GAAG,SAAS,CAAA;QACxB,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,CAAA;QAC3B,MAAM,QAAQ,GAAG,SAAS,CAAC,QAAQ,CAAA;QACnC,MAAM,YAAY,GAAG,SAAS,CAAC,YAAY,CAAA;QAC3C,MAAM,cAAc,GAAG,SAAS,CAAC,cAAc,CAAA;QAC/C,MAAM,aAAa,GAAG,SAAS,CAAC,aAAa,CAAA;QAC7C,MAAM,YAAY,GAAG,SAAS,CAAC,YAAY,CAAA;QAE3C,+BAA+B;QAC/B,IAAI,QAAQ,EAAE,IAAI,IAAI,IAAI,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YAChD,MAAM,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAA;YAC/B,IAAI,CAAC,EAAE,CAAC;gBACN,8CAA8C;gBAC9C,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAA;gBACxB,qDAAqD;gBACrD,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;gBACxD,6CAA6C;gBAC7C,MAAM,CAAC,GAAG,YAAY,CAAC;oBACrB,GAAG,CAAC;oBACJ,IAAI;iBACL,CAAC,CAAA;gBACF,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,CAAA;YAC3B,CAAC;QACH,CAAC;QAED,sCAAsC;QACtC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,IAAI,CAAC,YAAY,IAAI,QAAQ,CAAC,UAAU,EAAE,EAAE,CAAC;gBAC3C,8DAA8D;gBAC9D,kCAAkC;gBAClC,sBAAsB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAA;gBACvC,SAAQ;YACV,CAAC;iBAAM,IAAI,YAAY,EAAE,CAAC;gBACxB,wDAAwD;gBACxD,iEAAiE;gBACjE,SAAQ;YACV,CAAC;iBAAM,CAAC;gBACN,MAAM,KAAK,CAAC,8BAA8B,EAAE;oBAC1C,IAAI;oBACJ,IAAI,EAAE,QAAQ,CAAC,QAAQ;iBACxB,CAAC,CAAA;YACJ,CAAC;QACH,CAAC;QAED,sEAAsE;QACtE,IAAI,IAAI,KAAK,cAAc,EAAE,CAAC;YAC5B,sBAAsB;YACtB,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAA;YACnC,SAAQ;QACV,CAAC;QAED,sEAAsE;QACtE,MAAM,IAAI,GAAG,KAAK,CAAC,YAAY,CAC7B,QAAQ,EACR,IAAI,EACJ,IAAI,EACJ,iBAAiB,CAAC,QAAQ,CAAC,EAC3B,YAAY,EAAE,EAAE,EAChB,aAAa,CACd,CAAA;QAED,8DAA8D;QAC9D,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,MAAM,KAAK,CAAC,yBAAyB,EAAE;gBACrC,IAAI,EAAE,QAAQ,CAAC,QAAQ;gBACvB,IAAI;aACL,CAAC,CAAA;QACJ,CAAC;QACD,oBAAoB;QAEpB,mCAAmC;QACnC,IAAI,cAAc,EAAE,CAAC;YACnB,SAAS,EAAE,iBAAiB,CAAC,IAAI,EAAE,cAAc,CAAC,CAAA;QACpD,CAAC;QAED,gGAAgG;QAChG,IACE,OAAO;YACP,eAAe;YACf,MAAM;YACN,MAAM;YACN,WAAW;YACX,IAAI,CAAC,UAAU,EAAE,EACjB,CAAC;YACD,qBAAqB;YACrB,IAAI,aAAa,EAAE,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;gBAChC,SAAQ;YACV,CAAC;YACD,oBAAoB;YACpB,aAAa,EAAE,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;YAC3B,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;YAC5C,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC9B,oEAAoE;gBACpE,MAAM,cAAc,GAAG,WAAW,CAChC,IAAI,EACJ,MAAM,EACN,OAAO,EACP,OAAO,EACP,WAAW,CACZ,CAAA;gBACD,eAAe,CAAC,IAAI,CAAC,cAAc,CAAC,CAAA;YACtC,CAAC;QACH,CAAC;QAED,iCAAiC;QACjC,IAAI,YAAY,EAAE,IAAI,IAAI,YAAY,CAAC,WAAW,EAAE,CAAC;YACnD,IAAI,CAAC,QAAQ,GAAG,YAAY,CAAC,IAAI,CAAA;QACnC,CAAC;QACD,IAAI,CAAC,WAAW,EAAE,CAAA;QAElB,8DAA8D;QAC9D,MAAM,UAAU,GAAG,QAAQ,CAAC,kBAAkB,CAAA;QAC9C,MAAM,OAAO,GAAG,IAAI,GAAG,CACrB,CACE,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC;YACzB,IAAI,CAAC,QAAQ;YACb,CAAC,aAAa,CAAC,UAAU,CAAC,CAC3B,CAAC,CAAC;YACD,EAAE;YACJ,CAAC,CAAC,UAAU,CACb,CAAA;QAED,6DAA6D;QAC7D,MAAM,QAAQ,GAAiB,EAAE,CAAA;QAEjC,KAAK,MAAM,WAAW,IAAI,mBAAmB,EAAE,CAAC;YAC9C,MAAM,SAAS,GACb,QAAQ,CAAC,WAAW,CAAC,CAAA;YAEvB,IAAI,SAAS,IAAI,oBAAoB,CAAC,IAAI,EAAE,WAAW,CAAC,EAAE,CAAC;gBACzD,KAAK,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;oBACzD,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;wBAAE,SAAQ;oBAC/B,QAAQ,CAAC,IAAI,CAAC;wBACZ,IAAI,EAAE,OAAO,CAAC,WAAW,EAAE,IAAI,EAAE,QAAQ,CAAC;wBAC1C,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,QAAQ,EAAE;4BAC/B,GAAG,OAAO;4BACV,QAAQ,EAAE,IAAI,CAAC,QAAQ;yBACxB,CAAC;qBACH,CAAC,CAAA;gBACJ,CAAC;YACH,CAAC;QACH,CAAC;QAED,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxB,kBAAkB,CAAC,IAAI,CAAC;gBACtB,IAAI;gBACJ,IAAI,EAAE,QAAQ;gBACd,YAAY,EAAE,SAAS,EAAE,eAAe,CAAC,IAAI,EAAE,QAAQ,CAAC;aACzD,CAAC,CAAA;QACJ,CAAC;IACH,CAAC;IAED,OAAO,EAAE,kBAAkB,EAAE,CAAA;AAC/B,CAAC,CAAA;AAED;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,KAAK,EAC9B,GAA4B,EAC5B,WAA8B,EAC9B,KAAY,EACZ,QAAc,EACd,IAAkB,EAClB,MAAkB,EAClB,OAAoB,EACpB,IAAgB,EAChB,SAAyB,EACzB,YAA+C,EAC/C,eAA0C,EAC1C,MAAc,EACd,aAA0B,EAC1B,OAAwB,EACxB,EAAE;IACF,oBAAoB;IACpB,IAAI,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;QAAE,OAAM;IACjC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAA;IAErB,2CAA2C;IAC3C,IAAI,gBAAgB,GAAsB;QACxC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC,EAAE;KACjD,CAAA;IAED,OAAO,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACnC,MAAM,aAAa,GAAsB,EAAE,CAAA;QAE3C,qDAAqD;QACrD,MAAM,YAAY,GAAG,MAAM,OAAO,CAAC,GAAG,CACpC,gBAAgB,CAAC,GAAG,CAClB,KAAK,EAAE,EACL,IAAI,EACJ,IAAI,EAAE,QAAQ,EACd,YAAY,EAAE,gBAAgB,EAC9B,KAAK,GACW,EAAE,EAAE;YACpB,8DAA8D;YAC9D,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;YAEjB,+CAA+C;YAC/C,MAAM,cAAc,GAAG,MAAM,qBAAqB,CAChD,WAAW,EACX,KAAK,EACL,IAAI;YACJ,4DAA4D;YAC5D,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CACrB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAC7C,EACD,MAAM,EACN,gBAAgB,EAChB,KAAK,CACN,CAAA;YAED,yDAAyD;YACzD,OAAO,MAAM,qBAAqB,CAChC,GAAG,EACH,KAAK,EACL,OAAO,EACP,cAAc,EACd,SAAS,EACT,MAAM,EACN,WAAW,EACX,eAAe,EACf,MAAM,EACN,aAAa,EACb,OAAO,CACR,CAAA;QACH,CAAC,CACF,CACF,CAAA;QAED,oDAAoD;QACpD,KAAK,MAAM,EAAE,kBAAkB,EAAE,IAAI,YAAY,EAAE,CAAC;YAClD,KAAK,MAAM,QAAQ,IAAI,kBAAkB,EAAE,CAAC;gBAC1C,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;oBAChC,oBAAoB;oBACpB,MAAM,YAAY,GAAG,gBAAgB,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC,CAAA;oBACpD,aAAa,CAAC,IAAI,CAAC;wBACjB,GAAG,QAAQ;wBACX,KAAK,EAAE,YAAY,GAAG,CAAC;qBACxB,CAAC,CAAA;gBACJ,CAAC;YACH,CAAC;QACH,CAAC;QAED,yBAAyB;QACzB,gBAAgB,GAAG,aAAa,CAAA;IAClC,CAAC;AACH,CAAC,CAAA","sourcesContent":["import { joinDepIDTuple } from '@vltpkg/dep-id'\nimport type { DepID } from '@vltpkg/dep-id'\nimport { error } from '@vltpkg/error-cause'\nimport type { PackageInfoClient } from '@vltpkg/package-info'\nimport { Spec } from '@vltpkg/spec'\nimport type { SpecOptions } from '@vltpkg/spec'\nimport { longDependencyTypes, normalizeManifest } from '@vltpkg/types'\nimport type {\n DependencyTypeLong,\n DependencySaveType,\n Manifest,\n} from '@vltpkg/types'\nimport type { PathScurry } from 'path-scurry'\nimport { asDependency, shorten } from '../dependencies.ts'\nimport type { Dependency } from '../dependencies.ts'\nimport type { Graph } from '../graph.ts'\nimport type { Node } from '../node.ts'\nimport { removeOptionalSubgraph } from '../remove-optional-subgraph.ts'\nimport type {\n GraphModifier,\n ModifierActiveEntry,\n} from '../modifiers.ts'\nimport type { ExtractResult } from '../reify/extract-node.ts'\nimport { extractNode } from '../reify/extract-node.ts'\nimport type { RollbackRemove } from '@vltpkg/rollback-remove'\n\ntype FileTypeInfo = {\n id: DepID\n path: string\n isDirectory: boolean\n}\n\n/**\n * Only install devDeps for git dependencies and importers\n * Everything else always gets installed\n */\nconst shouldInstallDepType = (\n node: Node,\n depType: DependencyTypeLong,\n) =>\n depType !== 'devDependencies' ||\n node.importer ||\n node.id.startsWith('git')\n\n/**\n * Retrieve the {@link DepID} and location for a `file:` type {@link Node}.\n */\nconst getFileTypeInfo = (\n spec: Spec,\n fromNode: Node,\n scurry: PathScurry,\n): FileTypeInfo | undefined => {\n const f = spec.final\n if (f.type !== 'file') return\n\n /* c8 ignore start - should be impossible */\n if (!f.file) {\n throw error('no path on file specifier', { spec })\n }\n /* c8 ignore stop */\n\n // Given that both linked folders and local tarballs (both defined with\n // usage of the `file:` spec prefix) location needs to be relative to their\n // parents, build the expected path and use it for both location and id\n const target = scurry.cwd.resolve(fromNode.location).resolve(f.file)\n const path = target.relativePosix()\n const id = joinDepIDTuple(['file', path])\n\n return {\n path,\n id,\n isDirectory: !!target.lstatSync()?.isDirectory(),\n }\n}\n\nconst isStringArray = (a: unknown): a is string[] =>\n Array.isArray(a) && !a.some(b => typeof b !== 'string')\n\n/**\n * Represents a manifest fetch operation with all the context needed.\n */\ntype ManifestFetchTask = {\n spec: Spec\n type: DependencySaveType\n fromNode: Node\n fileTypeInfo?: FileTypeInfo\n activeModifier?: ModifierActiveEntry\n queryModifier?: string\n edgeOptional: boolean\n manifestPromise: Promise<Manifest | undefined>\n depth: number\n}\n\n/**\n * Represents a node placement operation that depends on a resolved manifest.\n */\ntype NodePlacementTask = {\n fetchTask: ManifestFetchTask\n manifest: Manifest | undefined\n node?: Node\n childDeps?: Dependency[]\n childModifierRefs?: Map<string, ModifierActiveEntry>\n}\n\n/**\n * Represents an ongoing append operation for a node and its dependencies.\n */\ntype AppendNodeEntry = {\n node: Node\n deps: Dependency[]\n modifierRefs?: Map<string, ModifierActiveEntry>\n depth: number\n}\n\n/**\n * Fetch manifests for dependencies and create placement tasks.\n */\nconst fetchManifestsForDeps = async (\n packageInfo: PackageInfoClient,\n graph: Graph,\n fromNode: Node,\n deps: Dependency[],\n scurry: PathScurry,\n modifierRefs?: Map<string, ModifierActiveEntry>,\n depth = 0,\n): Promise<NodePlacementTask[]> => {\n // Create fetch tasks for all dependencies at this level\n const fetchTasks: ManifestFetchTask[] = []\n\n for (const { spec: originalSpec, type } of deps) {\n let spec = originalSpec\n const fileTypeInfo = getFileTypeInfo(spec, fromNode, scurry)\n const activeModifier = modifierRefs?.get(spec.name)\n\n // here is the place we swap specs if a edge modifier was defined\n const queryModifier = activeModifier?.modifier.query\n const completeModifier =\n activeModifier &&\n activeModifier.interactiveBreadcrumb.current ===\n activeModifier.modifier.breadcrumb.last\n if (\n queryModifier &&\n completeModifier &&\n 'spec' in activeModifier.modifier\n ) {\n spec = activeModifier.modifier.spec\n if (spec.bareSpec === '-') {\n continue\n }\n }\n\n const existingNode = graph.findResolution(\n spec,\n fromNode,\n queryModifier,\n )\n if (existingNode) {\n // For peerOptional dependencies, create a dangling edge instead of linking to existing node\n if (type === 'peerOptional') {\n /* c8 ignore next 3 */\n // This case happens when peerOptional dep already exists in graph\n graph.addEdge(type, spec, fromNode)\n } else {\n graph.addEdge(type, spec, fromNode, existingNode)\n }\n continue\n }\n\n const edgeOptional =\n type === 'optional' || type === 'peerOptional'\n\n // Start manifest fetch immediately for parallel processing\n const manifestPromise = packageInfo\n .manifest(spec, { from: scurry.resolve(fromNode.location) })\n .then(manifest => manifest as Manifest | undefined)\n .catch((er: unknown) => {\n // optional deps ignored if inaccessible\n if (edgeOptional || fromNode.optional) {\n return undefined\n }\n throw er\n })\n\n const fetchTask: ManifestFetchTask = {\n spec,\n type,\n fromNode,\n fileTypeInfo,\n activeModifier,\n queryModifier,\n edgeOptional,\n manifestPromise,\n depth,\n }\n\n fetchTasks.push(fetchTask)\n }\n\n // Create placement tasks\n const placementTasks: NodePlacementTask[] = []\n for (const fetchTask of fetchTasks) {\n const manifest = await fetchTask.manifestPromise\n\n placementTasks.push({\n fetchTask,\n manifest,\n })\n }\n\n return placementTasks\n}\n\n/**\n * Process placement tasks and collect child dependencies\n */\nconst processPlacementTasks = async (\n add: Map<string, Dependency>,\n graph: Graph,\n options: SpecOptions,\n placementTasks: NodePlacementTask[],\n modifiers?: GraphModifier,\n scurry?: PathScurry,\n packageInfo?: PackageInfoClient,\n extractPromises?: Promise<ExtractResult>[],\n actual?: Graph,\n seenExtracted?: Set<DepID>,\n remover?: RollbackRemove,\n): Promise<{\n childDepsToProcess: Omit<AppendNodeEntry, 'depth'>[]\n}> => {\n const childDepsToProcess: Omit<AppendNodeEntry, 'depth'>[] = []\n\n for (const placementTask of placementTasks) {\n const { fetchTask, manifest } = placementTask\n let { spec } = fetchTask\n const type = fetchTask.type\n const fromNode = fetchTask.fromNode\n const fileTypeInfo = fetchTask.fileTypeInfo\n const activeModifier = fetchTask.activeModifier\n const queryModifier = fetchTask.queryModifier\n const edgeOptional = fetchTask.edgeOptional\n\n // Handle nameless dependencies\n if (manifest?.name && spec.name === '(unknown)') {\n const s = add.get(String(spec))\n if (s) {\n // removes the previous, placeholder entry key\n add.delete(String(spec))\n // replaces spec with a version with the correct name\n spec = Spec.parse(manifest.name, spec.bareSpec, options)\n // updates the add map with the fixed up spec\n const n = asDependency({\n ...s,\n spec,\n })\n add.set(manifest.name, n)\n }\n }\n\n // handles missing manifest resolution\n if (!manifest) {\n if (!edgeOptional && fromNode.isOptional()) {\n // failed resolution of a non-optional dep of an optional node\n // have to clean up the dependents\n removeOptionalSubgraph(graph, fromNode)\n continue\n } else if (edgeOptional) {\n // failed resolution of an optional dep, just ignore it,\n // nothing to prune because we never added it in the first place.\n continue\n } else {\n throw error('failed to resolve dependency', {\n spec,\n from: fromNode.location,\n })\n }\n }\n\n // Skip placing peerOptional dependencies, just create a dangling edge\n if (type === 'peerOptional') {\n /* c8 ignore next 3 */\n graph.addEdge(type, spec, fromNode)\n continue\n }\n\n // places a new node in the graph representing a newly seen dependency\n const node = graph.placePackage(\n fromNode,\n type,\n spec,\n normalizeManifest(manifest),\n fileTypeInfo?.id,\n queryModifier,\n )\n\n /* c8 ignore start - not possible, already ensured manifest */\n if (!node) {\n throw error('failed to place package', {\n from: fromNode.location,\n spec,\n })\n }\n /* c8 ignore stop */\n\n // update the node modifier tracker\n if (activeModifier) {\n modifiers?.updateActiveEntry(node, activeModifier)\n }\n\n // Extract the node if it doesn't exist in the actual graph and we have the necessary parameters\n if (\n remover &&\n extractPromises &&\n actual &&\n scurry &&\n packageInfo &&\n node.inVltStore()\n ) {\n /* c8 ignore start */\n if (seenExtracted?.has(node.id)) {\n continue\n }\n /* c8 ignore stop */\n seenExtracted?.add(node.id)\n const actualNode = actual.nodes.get(node.id)\n if (!actualNode?.equals(node)) {\n // Extract the node without awaiting - push the promise to the array\n const extractPromise = extractNode(\n node,\n scurry,\n remover,\n options,\n packageInfo,\n )\n extractPromises.push(extractPromise)\n }\n }\n\n // updates graph node information\n if (fileTypeInfo?.path && fileTypeInfo.isDirectory) {\n node.location = fileTypeInfo.path\n }\n node.setResolved()\n\n // Collect child dependencies for processing in the next level\n const bundleDeps = manifest.bundleDependencies\n const bundled = new Set<string>(\n (\n node.id.startsWith('git') ||\n node.importer ||\n !isStringArray(bundleDeps)\n ) ?\n []\n : bundleDeps,\n )\n\n // recursively process all child dependencies in the manifest\n const nextDeps: Dependency[] = []\n\n for (const depTypeName of longDependencyTypes) {\n const depRecord: Record<string, string> | undefined =\n manifest[depTypeName]\n\n if (depRecord && shouldInstallDepType(node, depTypeName)) {\n for (const [name, bareSpec] of Object.entries(depRecord)) {\n if (bundled.has(name)) continue\n nextDeps.push({\n type: shorten(depTypeName, name, manifest),\n spec: Spec.parse(name, bareSpec, {\n ...options,\n registry: spec.registry,\n }),\n })\n }\n }\n }\n\n if (nextDeps.length > 0) {\n childDepsToProcess.push({\n node,\n deps: nextDeps,\n modifierRefs: modifiers?.tryDependencies(node, nextDeps),\n })\n }\n }\n\n return { childDepsToProcess }\n}\n\n/**\n * Append new nodes in the given `graph` for dependencies specified at `add`\n * and missing dependencies from the `deps` parameter.\n *\n * It also applies any modifiers that applies to a given node as it processes\n * and builds the graph.\n */\nexport const appendNodes = async (\n add: Map<string, Dependency>,\n packageInfo: PackageInfoClient,\n graph: Graph,\n fromNode: Node,\n deps: Dependency[],\n scurry: PathScurry,\n options: SpecOptions,\n seen: Set<DepID>,\n modifiers?: GraphModifier,\n modifierRefs?: Map<string, ModifierActiveEntry>,\n extractPromises?: Promise<ExtractResult>[],\n actual?: Graph,\n seenExtracted?: Set<DepID>,\n remover?: RollbackRemove,\n) => {\n /* c8 ignore next */\n if (seen.has(fromNode.id)) return\n seen.add(fromNode.id)\n\n // Use a queue for breadth-first processing\n let currentLevelDeps: AppendNodeEntry[] = [\n { node: fromNode, deps, modifierRefs, depth: 0 },\n ]\n\n while (currentLevelDeps.length > 0) {\n const nextLevelDeps: AppendNodeEntry[] = []\n\n // Process all nodes at the current level in parallel\n const levelResults = await Promise.all(\n currentLevelDeps.map(\n async ({\n node,\n deps: nodeDeps,\n modifierRefs: nodeModifierRefs,\n depth,\n }: AppendNodeEntry) => {\n // Mark node as seen when we start processing its dependencies\n seen.add(node.id)\n\n // Fetch manifests for this node's dependencies\n const placementTasks = await fetchManifestsForDeps(\n packageInfo,\n graph,\n node,\n // Sort dependencies by spec.name for deterministic ordering\n nodeDeps.sort((a, b) =>\n a.spec.name.localeCompare(b.spec.name, 'en'),\n ),\n scurry,\n nodeModifierRefs,\n depth,\n )\n\n // Process the placement tasks and get child dependencies\n return await processPlacementTasks(\n add,\n graph,\n options,\n placementTasks,\n modifiers,\n scurry,\n packageInfo,\n extractPromises,\n actual,\n seenExtracted,\n remover,\n )\n },\n ),\n )\n\n // Collect all child dependencies for the next level\n for (const { childDepsToProcess } of levelResults) {\n for (const childDep of childDepsToProcess) {\n if (!seen.has(childDep.node.id)) {\n /* c8 ignore next */\n const currentDepth = currentLevelDeps[0]?.depth ?? 0\n nextLevelDeps.push({\n ...childDep,\n depth: currentDepth + 1,\n })\n }\n }\n }\n\n // Move to the next level\n currentLevelDeps = nextLevelDeps\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"build-ideal-from-starting-graph.d.ts","sourceRoot":"","sources":["../../../src/ideal/build-ideal-from-starting-graph.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AAGxC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAErD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAA;AAE3D,MAAM,MAAM,kCAAkC,GAAG,eAAe,GAC9D,kBAAkB,GAAG;IACnB,WAAW,EAAE,MAAM,CAAA;CACpB,CAAA;AAEH;;;;;;GAMG;AACH,eAAO,MAAM,2BAA2B,YAC7B,kCAAkC,KAC1C,OAAO,CAAC,KAAK,CA+Cf,CAAA"}
1
+ {"version":3,"file":"build-ideal-from-starting-graph.d.ts","sourceRoot":"","sources":["../../../src/ideal/build-ideal-from-starting-graph.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AAGxC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAErD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAA;AAE3D,MAAM,MAAM,kCAAkC,GAAG,eAAe,GAC9D,kBAAkB,GAAG;IACnB,WAAW,EAAE,MAAM,CAAA;CACpB,CAAA;AAEH;;;;;;GAMG;AACH,eAAO,MAAM,2BAA2B,YAC7B,kCAAkC,KAC1C,OAAO,CAAC,KAAK,CAoDf,CAAA"}
@@ -37,11 +37,15 @@ export const buildIdealFromStartingGraph = async (options) => {
37
37
  }
38
38
  }
39
39
  }
40
- // add nodes, fetching remote manifests for each dependency to be added
41
- await addNodes(options);
42
- // move things into their default locations, if possible
43
- for (const node of options.graph.nodes.values()) {
44
- node.setDefaultLocation();
40
+ // hydrate the resolution cache
41
+ if (options.add.modifiedDependencies) {
42
+ options.graph.resetResolution();
43
+ // add nodes, fetching remote manifests for each dependency to be added
44
+ await addNodes(options);
45
+ // move things into their default locations, if possible
46
+ for (const node of options.graph.nodes.values()) {
47
+ node.setDefaultLocation();
48
+ }
45
49
  }
46
50
  // removes any dependencies that are listed in the `remove` option
47
51
  removeNodes({ ...options, remove: importerSpecs.remove });
@@ -1 +1 @@
1
- {"version":3,"file":"build-ideal-from-starting-graph.js","sourceRoot":"","sources":["../../../src/ideal/build-ideal-from-starting-graph.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAC1D,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAEzC,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAQ/C;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAG,KAAK,EAC9C,OAA2C,EAC3B,EAAE;IAClB,sEAAsE;IACtE,wEAAwE;IACxE,sEAAsE;IACtE,oDAAoD;IACpD,MAAM,aAAa,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAA;IAE/C,mCAAmC;IACnC,OAAO,CAAC,GAAG,CAAC,oBAAoB;QAC9B,OAAO,CAAC,GAAG,CAAC,oBAAoB;YAChC,aAAa,CAAC,GAAG,CAAC,oBAAoB,CAAA;IACxC,OAAO,CAAC,MAAM,CAAC,oBAAoB;QACjC,OAAO,CAAC,MAAM,CAAC,oBAAoB;YACnC,aAAa,CAAC,MAAM,CAAC,oBAAoB,CAAA;IAE3C,4CAA4C;IAC5C,0CAA0C;IAC1C,KAAK,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,IAAI,aAAa,CAAC,GAAG,EAAE,CAAC;QACnD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;YACjC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU,EAAE,IAAI,CAAC,CAAA;YACjC,SAAQ;QACV,CAAC;QAED,2DAA2D;QAC3D,2DAA2D;QAC3D,4CAA4C;QAC5C,KAAK,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC;YAClC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC/C,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,CAAA;YAChD,CAAC;QACH,CAAC;IACH,CAAC;IAED,uEAAuE;IACvE,MAAM,QAAQ,CAAC,OAAO,CAAC,CAAA;IAEvB,wDAAwD;IACxD,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;QAChD,IAAI,CAAC,kBAAkB,EAAE,CAAA;IAC3B,CAAC;IAED,kEAAkE;IAClE,WAAW,CAAC,EAAE,GAAG,OAAO,EAAE,MAAM,EAAE,aAAa,CAAC,MAAM,EAAE,CAAC,CAAA;IAEzD,OAAO,CAAC,KAAK,CAAC,EAAE,EAAE,CAAA;IAElB,OAAO,OAAO,CAAC,KAAK,CAAA;AACtB,CAAC,CAAA","sourcesContent":["import type { Graph } from '../graph.ts'\nimport { getImporterSpecs } from './get-importer-specs.ts'\nimport { addNodes } from './add-nodes.ts'\nimport type { AddNodesOptions } from './add-nodes.ts'\nimport { removeNodes } from './remove-nodes.ts'\nimport type { RemoveNodesOptions } from './remove-nodes.ts'\n\nexport type BuildIdealFromStartingGraphOptions = AddNodesOptions &\n RemoveNodesOptions & {\n projectRoot: string\n }\n\n/**\n * Builds an ideal {@link Graph} representing the dependencies that\n * should be present in order to fulfill the requirements defined\n * by the `package.json` and `vlt-lock.json` files using the `graph` set\n * in options as a starting point. Also add / remove any dependencies\n * listed in the `add` and `remove` properties.\n */\nexport const buildIdealFromStartingGraph = async (\n options: BuildIdealFromStartingGraphOptions,\n): Promise<Graph> => {\n // Gets a map of dependencies that are keyed to its importer node ids,\n // merging values already found in the graph with user specified values.\n // Any dependencies that are already satisfied in the starting `graph`\n // are going to be pruned from the resulting object.\n const importerSpecs = getImporterSpecs(options)\n\n // merge modifiedDependencies flags\n options.add.modifiedDependencies =\n options.add.modifiedDependencies ||\n importerSpecs.add.modifiedDependencies\n options.remove.modifiedDependencies =\n options.remove.modifiedDependencies ||\n importerSpecs.remove.modifiedDependencies\n\n // merge values found on importer specs with\n // user-provided values from `options.add`\n for (const [importerId, deps] of importerSpecs.add) {\n if (!options.add.has(importerId)) {\n options.add.set(importerId, deps)\n continue\n }\n\n // merge any deps found when reading the importers manifest\n // with the ones provided by the user in the `add` options,\n // user-provided deps should take precedence\n for (const [depName, dep] of deps) {\n if (!options.add.get(importerId)?.has(depName)) {\n options.add.get(importerId)?.set(depName, dep)\n }\n }\n }\n\n // add nodes, fetching remote manifests for each dependency to be added\n await addNodes(options)\n\n // move things into their default locations, if possible\n for (const node of options.graph.nodes.values()) {\n node.setDefaultLocation()\n }\n\n // removes any dependencies that are listed in the `remove` option\n removeNodes({ ...options, remove: importerSpecs.remove })\n\n options.graph.gc()\n\n return options.graph\n}\n"]}
1
+ {"version":3,"file":"build-ideal-from-starting-graph.js","sourceRoot":"","sources":["../../../src/ideal/build-ideal-from-starting-graph.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAC1D,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAEzC,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAQ/C;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAG,KAAK,EAC9C,OAA2C,EAC3B,EAAE;IAClB,sEAAsE;IACtE,wEAAwE;IACxE,sEAAsE;IACtE,oDAAoD;IACpD,MAAM,aAAa,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAA;IAE/C,mCAAmC;IACnC,OAAO,CAAC,GAAG,CAAC,oBAAoB;QAC9B,OAAO,CAAC,GAAG,CAAC,oBAAoB;YAChC,aAAa,CAAC,GAAG,CAAC,oBAAoB,CAAA;IACxC,OAAO,CAAC,MAAM,CAAC,oBAAoB;QACjC,OAAO,CAAC,MAAM,CAAC,oBAAoB;YACnC,aAAa,CAAC,MAAM,CAAC,oBAAoB,CAAA;IAE3C,4CAA4C;IAC5C,0CAA0C;IAC1C,KAAK,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,IAAI,aAAa,CAAC,GAAG,EAAE,CAAC;QACnD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;YACjC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU,EAAE,IAAI,CAAC,CAAA;YACjC,SAAQ;QACV,CAAC;QAED,2DAA2D;QAC3D,2DAA2D;QAC3D,4CAA4C;QAC5C,KAAK,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC;YAClC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC/C,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,CAAA;YAChD,CAAC;QACH,CAAC;IACH,CAAC;IAED,+BAA+B;IAC/B,IAAI,OAAO,CAAC,GAAG,CAAC,oBAAoB,EAAE,CAAC;QACrC,OAAO,CAAC,KAAK,CAAC,eAAe,EAAE,CAAA;QAE/B,uEAAuE;QACvE,MAAM,QAAQ,CAAC,OAAO,CAAC,CAAA;QAEvB,wDAAwD;QACxD,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;YAChD,IAAI,CAAC,kBAAkB,EAAE,CAAA;QAC3B,CAAC;IACH,CAAC;IAED,kEAAkE;IAClE,WAAW,CAAC,EAAE,GAAG,OAAO,EAAE,MAAM,EAAE,aAAa,CAAC,MAAM,EAAE,CAAC,CAAA;IAEzD,OAAO,CAAC,KAAK,CAAC,EAAE,EAAE,CAAA;IAElB,OAAO,OAAO,CAAC,KAAK,CAAA;AACtB,CAAC,CAAA","sourcesContent":["import type { Graph } from '../graph.ts'\nimport { getImporterSpecs } from './get-importer-specs.ts'\nimport { addNodes } from './add-nodes.ts'\nimport type { AddNodesOptions } from './add-nodes.ts'\nimport { removeNodes } from './remove-nodes.ts'\nimport type { RemoveNodesOptions } from './remove-nodes.ts'\n\nexport type BuildIdealFromStartingGraphOptions = AddNodesOptions &\n RemoveNodesOptions & {\n projectRoot: string\n }\n\n/**\n * Builds an ideal {@link Graph} representing the dependencies that\n * should be present in order to fulfill the requirements defined\n * by the `package.json` and `vlt-lock.json` files using the `graph` set\n * in options as a starting point. Also add / remove any dependencies\n * listed in the `add` and `remove` properties.\n */\nexport const buildIdealFromStartingGraph = async (\n options: BuildIdealFromStartingGraphOptions,\n): Promise<Graph> => {\n // Gets a map of dependencies that are keyed to its importer node ids,\n // merging values already found in the graph with user specified values.\n // Any dependencies that are already satisfied in the starting `graph`\n // are going to be pruned from the resulting object.\n const importerSpecs = getImporterSpecs(options)\n\n // merge modifiedDependencies flags\n options.add.modifiedDependencies =\n options.add.modifiedDependencies ||\n importerSpecs.add.modifiedDependencies\n options.remove.modifiedDependencies =\n options.remove.modifiedDependencies ||\n importerSpecs.remove.modifiedDependencies\n\n // merge values found on importer specs with\n // user-provided values from `options.add`\n for (const [importerId, deps] of importerSpecs.add) {\n if (!options.add.has(importerId)) {\n options.add.set(importerId, deps)\n continue\n }\n\n // merge any deps found when reading the importers manifest\n // with the ones provided by the user in the `add` options,\n // user-provided deps should take precedence\n for (const [depName, dep] of deps) {\n if (!options.add.get(importerId)?.has(depName)) {\n options.add.get(importerId)?.set(depName, dep)\n }\n }\n }\n\n // hydrate the resolution cache\n if (options.add.modifiedDependencies) {\n options.graph.resetResolution()\n\n // add nodes, fetching remote manifests for each dependency to be added\n await addNodes(options)\n\n // move things into their default locations, if possible\n for (const node of options.graph.nodes.values()) {\n node.setDefaultLocation()\n }\n }\n\n // removes any dependencies that are listed in the `remove` option\n removeNodes({ ...options, remove: importerSpecs.remove })\n\n options.graph.gc()\n\n return options.graph\n}\n"]}
@@ -2,7 +2,12 @@ import type { PackageInfoClient } from '@vltpkg/package-info';
2
2
  import type { LoadOptions as LoadActualOptions } from '../actual/load.ts';
3
3
  import type { AddImportersDependenciesMap, RemoveImportersDependenciesMap } from '../dependencies.ts';
4
4
  import type { Graph } from '../graph.ts';
5
+ import type { RollbackRemove } from '@vltpkg/rollback-remove';
5
6
  export type BuildIdealOptions = LoadActualOptions & {
7
+ /**
8
+ * An actual graph
9
+ */
10
+ actual?: Graph;
6
11
  /**
7
12
  * A `Map` in which keys are {@link DepID} linking to another `Map` in which
8
13
  * keys are the dependency names and values are {@link Dependency}. This
@@ -16,6 +21,10 @@ export type BuildIdealOptions = LoadActualOptions & {
16
21
  * dependency names to be removed from its dependency list.
17
22
  */
18
23
  remove?: RemoveImportersDependenciesMap;
24
+ /**
25
+ * A {@link RollbackRemove} instance to handle extraction rollbacks
26
+ */
27
+ remover: RollbackRemove;
19
28
  /**
20
29
  * A {@link PackageInfoClient} instance to read manifest info from.
21
30
  */
@@ -1 +1 @@
1
- {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../../src/ideal/build.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AAE7D,OAAO,KAAK,EAAE,WAAW,IAAI,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AACzE,OAAO,KAAK,EACV,2BAA2B,EAC3B,8BAA8B,EAE/B,MAAM,oBAAoB,CAAA;AAC3B,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AASxC,MAAM,MAAM,iBAAiB,GAAG,iBAAiB,GAAG;IAClD;;;;;OAKG;IACH,GAAG,CAAC,EAAE,2BAA2B,CAAA;IACjC;;;;OAIG;IACH,MAAM,CAAC,EAAE,8BAA8B,CAAA;IACvC;;OAEG;IACH,WAAW,EAAE,iBAAiB,CAAA;CAC/B,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,KAAK,YACP,iBAAiB,KACzB,OAAO,CAAC,KAAK,CAiCf,CAAA"}
1
+ {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../../src/ideal/build.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AAC7D,OAAO,KAAK,EAAE,WAAW,IAAI,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AACzE,OAAO,KAAK,EACV,2BAA2B,EAC3B,8BAA8B,EAE/B,MAAM,oBAAoB,CAAA;AAC3B,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AAExC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAA;AAK7D,MAAM,MAAM,iBAAiB,GAAG,iBAAiB,GAAG;IAClD;;OAEG;IACH,MAAM,CAAC,EAAE,KAAK,CAAA;IACd;;;;;OAKG;IACH,GAAG,CAAC,EAAE,2BAA2B,CAAA;IACjC;;;;OAIG;IACH,MAAM,CAAC,EAAE,8BAA8B,CAAA;IACvC;;OAEG;IACH,OAAO,EAAE,cAAc,CAAA;IACvB;;OAEG;IACH,WAAW,EAAE,iBAAiB,CAAA;CAC/B,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,KAAK,YACP,iBAAiB,KACzB,OAAO,CAAC,KAAK,CAoCf,CAAA"}
@@ -1,7 +1,7 @@
1
+ import { graphStep } from '@vltpkg/output';
1
2
  import { load as loadActual } from "../actual/load.js";
2
3
  import { load as loadVirtual } from "../lockfile/load.js";
3
4
  import { buildIdealFromStartingGraph } from "./build-ideal-from-starting-graph.js";
4
- import { graphStep } from '@vltpkg/output';
5
5
  const getMap = (m) => m ?? new Map();
6
6
  /**
7
7
  * Builds an ideal {@link Graph} representing the dependencies that
@@ -22,6 +22,7 @@ export const build = async (options) => {
22
22
  ...options,
23
23
  mainManifest,
24
24
  monorepo,
25
+ skipLoadingNodesOnModifiersChange: true,
25
26
  });
26
27
  }
27
28
  catch {
@@ -29,6 +30,7 @@ export const build = async (options) => {
29
30
  ...options,
30
31
  mainManifest,
31
32
  monorepo,
33
+ skipLoadingNodesOnModifiersChange: true,
32
34
  });
33
35
  }
34
36
  const res = await buildIdealFromStartingGraph({
@@ -38,6 +40,7 @@ export const build = async (options) => {
38
40
  graph,
39
41
  packageInfo,
40
42
  remove: getMap(options.remove),
43
+ actual: options.actual,
41
44
  });
42
45
  done();
43
46
  return res;