@vltpkg/graph 1.0.0-rc.3 → 1.0.0-rc.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.
- package/README.md +101 -22
- package/dist/{esm/actual → actual}/load.d.ts +8 -1
- package/dist/{esm/actual → actual}/load.js +57 -22
- package/dist/{esm/browser.d.ts → browser.d.ts} +0 -1
- package/dist/{esm/browser.js → browser.js} +0 -1
- package/dist/{esm/build.d.ts → build.d.ts} +0 -1
- package/dist/{esm/build.js → build.js} +0 -1
- package/dist/{esm/dependencies.d.ts → dependencies.d.ts} +0 -1
- package/dist/{esm/dependencies.js → dependencies.js} +0 -1
- package/dist/{esm/diff.d.ts → diff.d.ts} +4 -1
- package/dist/{esm/diff.js → diff.js} +5 -2
- package/dist/{esm/edge.d.ts → edge.d.ts} +1 -1
- package/dist/{esm/edge.js → edge.js} +4 -1
- package/dist/fixup-added-names.d.ts +18 -0
- package/dist/fixup-added-names.js +46 -0
- package/dist/{esm/graph.d.ts → graph.d.ts} +25 -5
- package/dist/{esm/graph.js → graph.js} +92 -43
- package/dist/ideal/append-nodes.d.ts +31 -0
- package/dist/ideal/append-nodes.js +560 -0
- package/dist/{esm/ideal → ideal}/build-ideal-from-starting-graph.d.ts +4 -5
- package/dist/ideal/build-ideal-from-starting-graph.js +69 -0
- package/dist/{esm/ideal → ideal}/build.d.ts +0 -1
- package/dist/ideal/build.js +84 -0
- package/dist/{esm/ideal → ideal}/get-importer-specs.d.ts +9 -3
- package/dist/{esm/ideal → ideal}/get-importer-specs.js +80 -6
- package/dist/ideal/peers.d.ts +160 -0
- package/dist/ideal/peers.js +696 -0
- package/dist/ideal/refresh-ideal-graph.d.ts +43 -0
- package/dist/ideal/refresh-ideal-graph.js +62 -0
- package/dist/{esm/ideal → ideal}/remove-satisfied-specs.d.ts +0 -1
- package/dist/{esm/ideal → ideal}/remove-satisfied-specs.js +8 -1
- package/dist/ideal/sorting.d.ts +45 -0
- package/dist/ideal/sorting.js +70 -0
- package/dist/ideal/types.d.ts +107 -0
- package/dist/ideal/types.js +1 -0
- package/dist/{esm/index.d.ts → index.d.ts} +1 -1
- package/dist/{esm/index.js → index.js} +1 -1
- package/dist/{esm/install.d.ts → install.d.ts} +3 -3
- package/dist/{esm/install.js → install.js} +49 -9
- package/dist/{esm/lockfile → lockfile}/load-edges.d.ts +0 -1
- package/dist/{esm/lockfile → lockfile}/load-edges.js +7 -4
- package/dist/{esm/lockfile → lockfile}/load-nodes.d.ts +0 -1
- package/dist/{esm/lockfile → lockfile}/load-nodes.js +10 -4
- package/dist/{esm/lockfile → lockfile}/load.d.ts +0 -5
- package/dist/{esm/lockfile → lockfile}/load.js +31 -33
- package/dist/{esm/lockfile → lockfile}/save.d.ts +1 -2
- package/dist/{esm/lockfile → lockfile}/save.js +8 -7
- package/dist/{esm/lockfile → lockfile}/types.d.ts +7 -1
- package/dist/{esm/lockfile → lockfile}/types.js +6 -1
- package/dist/{esm/modifiers.d.ts → modifiers.d.ts} +0 -1
- package/dist/{esm/modifiers.js → modifiers.js} +0 -1
- package/dist/{esm/node.d.ts → node.d.ts} +16 -1
- package/dist/{esm/node.js → node.js} +21 -1
- package/dist/{esm/non-empty-list.d.ts → non-empty-list.d.ts} +0 -1
- package/dist/{esm/non-empty-list.js → non-empty-list.js} +0 -1
- package/dist/{esm/reify → reify}/add-edge.d.ts +0 -1
- package/dist/{esm/reify → reify}/add-edge.js +10 -4
- package/dist/{esm/reify → reify}/add-edges.d.ts +1 -2
- package/dist/{esm/reify → reify}/add-edges.js +2 -2
- package/dist/{esm/reify → reify}/add-nodes.d.ts +0 -1
- package/dist/{esm/reify → reify}/add-nodes.js +0 -1
- package/dist/{esm/reify → reify}/bin-chmod.d.ts +0 -1
- package/dist/{esm/reify → reify}/bin-chmod.js +0 -1
- package/dist/{esm/reify → reify}/build.d.ts +0 -1
- package/dist/{esm/reify → reify}/build.js +12 -4
- package/dist/{esm/reify → reify}/calculate-save-value.d.ts +0 -1
- package/dist/{esm/reify → reify}/calculate-save-value.js +6 -1
- package/dist/{esm/reify → reify}/check-needed-build.d.ts +10 -1
- package/dist/reify/check-needed-build.js +71 -0
- package/dist/{esm/reify → reify}/delete-edge.d.ts +0 -1
- package/dist/{esm/reify → reify}/delete-edge.js +0 -1
- package/dist/{esm/reify → reify}/delete-edges.d.ts +0 -1
- package/dist/{esm/reify → reify}/delete-edges.js +0 -1
- package/dist/{esm/reify → reify}/delete-nodes.d.ts +0 -1
- package/dist/{esm/reify → reify}/delete-nodes.js +0 -1
- package/dist/{esm/reify → reify}/extract-node.d.ts +0 -1
- package/dist/{esm/reify → reify}/extract-node.js +10 -3
- package/dist/{esm/reify → reify}/index.d.ts +1 -1
- package/dist/{esm/reify → reify}/index.js +4 -4
- package/dist/{esm/reify → reify}/internal-hoist.d.ts +0 -1
- package/dist/{esm/reify → reify}/internal-hoist.js +0 -1
- package/dist/{esm/reify → reify}/optional-fail.d.ts +0 -1
- package/dist/{esm/reify → reify}/optional-fail.js +0 -1
- package/dist/{esm/reify → reify}/rollback.d.ts +0 -1
- package/dist/{esm/reify → reify}/rollback.js +0 -1
- package/dist/{esm/reify → reify}/update-importers-package-json.d.ts +1 -2
- package/dist/{esm/reify → reify}/update-importers-package-json.js +19 -17
- package/dist/{esm/remove-optional-subgraph.d.ts → remove-optional-subgraph.d.ts} +0 -1
- package/dist/{esm/remove-optional-subgraph.js → remove-optional-subgraph.js} +0 -1
- package/dist/{esm/resolve-save-type.d.ts → resolve-save-type.d.ts} +0 -1
- package/dist/{esm/resolve-save-type.js → resolve-save-type.js} +0 -1
- package/dist/{esm/stringify-node.d.ts → stringify-node.d.ts} +0 -1
- package/dist/{esm/stringify-node.js → stringify-node.js} +10 -2
- package/dist/{esm/transfer-data → transfer-data}/load.d.ts +0 -1
- package/dist/{esm/transfer-data → transfer-data}/load.js +5 -3
- package/dist/{esm/uninstall.d.ts → uninstall.d.ts} +0 -1
- package/dist/{esm/uninstall.js → uninstall.js} +27 -7
- package/dist/{esm/update.d.ts → update.d.ts} +0 -1
- package/dist/{esm/update.js → update.js} +11 -1
- package/dist/{esm/virtual-root.d.ts → virtual-root.d.ts} +0 -1
- package/dist/{esm/virtual-root.js → virtual-root.js} +0 -1
- package/dist/{esm/visualization → visualization}/human-readable-output.d.ts +0 -1
- package/dist/{esm/visualization → visualization}/human-readable-output.js +7 -3
- package/dist/{esm/visualization → visualization}/json-output.d.ts +2 -2
- package/dist/{esm/visualization → visualization}/json-output.js +2 -3
- package/dist/{esm/visualization → visualization}/mermaid-output.d.ts +2 -2
- package/dist/visualization/mermaid-output.js +170 -0
- package/dist/{esm/visualization → visualization}/object-like-output.d.ts +0 -1
- package/dist/{esm/visualization → visualization}/object-like-output.js +0 -1
- package/package.json +51 -63
- package/dist/esm/actual/load.d.ts.map +0 -1
- package/dist/esm/actual/load.js.map +0 -1
- package/dist/esm/browser.d.ts.map +0 -1
- package/dist/esm/browser.js.map +0 -1
- package/dist/esm/build.d.ts.map +0 -1
- package/dist/esm/build.js.map +0 -1
- package/dist/esm/dependencies.d.ts.map +0 -1
- package/dist/esm/dependencies.js.map +0 -1
- package/dist/esm/diff.d.ts.map +0 -1
- package/dist/esm/diff.js.map +0 -1
- package/dist/esm/edge.d.ts.map +0 -1
- package/dist/esm/edge.js.map +0 -1
- package/dist/esm/graph.d.ts.map +0 -1
- package/dist/esm/graph.js.map +0 -1
- package/dist/esm/ideal/add-nodes.d.ts +0 -34
- package/dist/esm/ideal/add-nodes.d.ts.map +0 -1
- package/dist/esm/ideal/add-nodes.js +0 -39
- package/dist/esm/ideal/add-nodes.js.map +0 -1
- package/dist/esm/ideal/append-nodes.d.ts +0 -19
- package/dist/esm/ideal/append-nodes.d.ts.map +0 -1
- package/dist/esm/ideal/append-nodes.js +0 -289
- package/dist/esm/ideal/append-nodes.js.map +0 -1
- package/dist/esm/ideal/build-ideal-from-starting-graph.d.ts.map +0 -1
- package/dist/esm/ideal/build-ideal-from-starting-graph.js +0 -55
- package/dist/esm/ideal/build-ideal-from-starting-graph.js.map +0 -1
- package/dist/esm/ideal/build.d.ts.map +0 -1
- package/dist/esm/ideal/build.js +0 -48
- package/dist/esm/ideal/build.js.map +0 -1
- package/dist/esm/ideal/get-importer-specs.d.ts.map +0 -1
- package/dist/esm/ideal/get-importer-specs.js.map +0 -1
- package/dist/esm/ideal/remove-nodes.d.ts +0 -7
- package/dist/esm/ideal/remove-nodes.d.ts.map +0 -1
- package/dist/esm/ideal/remove-nodes.js +0 -19
- package/dist/esm/ideal/remove-nodes.js.map +0 -1
- package/dist/esm/ideal/remove-satisfied-specs.d.ts.map +0 -1
- package/dist/esm/ideal/remove-satisfied-specs.js.map +0 -1
- package/dist/esm/ideal/types.d.ts +0 -35
- package/dist/esm/ideal/types.d.ts.map +0 -1
- package/dist/esm/ideal/types.js +0 -2
- package/dist/esm/ideal/types.js.map +0 -1
- package/dist/esm/index.d.ts.map +0 -1
- package/dist/esm/index.js.map +0 -1
- package/dist/esm/install.d.ts.map +0 -1
- package/dist/esm/install.js.map +0 -1
- package/dist/esm/lockfile/load-edges.d.ts.map +0 -1
- package/dist/esm/lockfile/load-edges.js.map +0 -1
- package/dist/esm/lockfile/load-nodes.d.ts.map +0 -1
- package/dist/esm/lockfile/load-nodes.js.map +0 -1
- package/dist/esm/lockfile/load.d.ts.map +0 -1
- package/dist/esm/lockfile/load.js.map +0 -1
- package/dist/esm/lockfile/save.d.ts.map +0 -1
- package/dist/esm/lockfile/save.js.map +0 -1
- package/dist/esm/lockfile/types.d.ts.map +0 -1
- package/dist/esm/lockfile/types.js.map +0 -1
- package/dist/esm/modifiers.d.ts.map +0 -1
- package/dist/esm/modifiers.js.map +0 -1
- package/dist/esm/node.d.ts.map +0 -1
- package/dist/esm/node.js.map +0 -1
- package/dist/esm/non-empty-list.d.ts.map +0 -1
- package/dist/esm/non-empty-list.js.map +0 -1
- package/dist/esm/package.json +0 -3
- package/dist/esm/reify/add-edge.d.ts.map +0 -1
- package/dist/esm/reify/add-edge.js.map +0 -1
- package/dist/esm/reify/add-edges.d.ts.map +0 -1
- package/dist/esm/reify/add-edges.js.map +0 -1
- package/dist/esm/reify/add-nodes.d.ts.map +0 -1
- package/dist/esm/reify/add-nodes.js.map +0 -1
- package/dist/esm/reify/bin-chmod.d.ts.map +0 -1
- package/dist/esm/reify/bin-chmod.js.map +0 -1
- package/dist/esm/reify/build.d.ts.map +0 -1
- package/dist/esm/reify/build.js.map +0 -1
- package/dist/esm/reify/calculate-save-value.d.ts.map +0 -1
- package/dist/esm/reify/calculate-save-value.js.map +0 -1
- package/dist/esm/reify/check-needed-build.d.ts.map +0 -1
- package/dist/esm/reify/check-needed-build.js +0 -50
- package/dist/esm/reify/check-needed-build.js.map +0 -1
- package/dist/esm/reify/delete-edge.d.ts.map +0 -1
- package/dist/esm/reify/delete-edge.js.map +0 -1
- package/dist/esm/reify/delete-edges.d.ts.map +0 -1
- package/dist/esm/reify/delete-edges.js.map +0 -1
- package/dist/esm/reify/delete-nodes.d.ts.map +0 -1
- package/dist/esm/reify/delete-nodes.js.map +0 -1
- package/dist/esm/reify/extract-node.d.ts.map +0 -1
- package/dist/esm/reify/extract-node.js.map +0 -1
- package/dist/esm/reify/index.d.ts.map +0 -1
- package/dist/esm/reify/index.js.map +0 -1
- package/dist/esm/reify/internal-hoist.d.ts.map +0 -1
- package/dist/esm/reify/internal-hoist.js.map +0 -1
- package/dist/esm/reify/optional-fail.d.ts.map +0 -1
- package/dist/esm/reify/optional-fail.js.map +0 -1
- package/dist/esm/reify/rollback.d.ts.map +0 -1
- package/dist/esm/reify/rollback.js.map +0 -1
- package/dist/esm/reify/update-importers-package-json.d.ts.map +0 -1
- package/dist/esm/reify/update-importers-package-json.js.map +0 -1
- package/dist/esm/remove-optional-subgraph.d.ts.map +0 -1
- package/dist/esm/remove-optional-subgraph.js.map +0 -1
- package/dist/esm/resolve-save-type.d.ts.map +0 -1
- package/dist/esm/resolve-save-type.js.map +0 -1
- package/dist/esm/stringify-node.d.ts.map +0 -1
- package/dist/esm/stringify-node.js.map +0 -1
- package/dist/esm/transfer-data/load.d.ts.map +0 -1
- package/dist/esm/transfer-data/load.js.map +0 -1
- package/dist/esm/uninstall.d.ts.map +0 -1
- package/dist/esm/uninstall.js.map +0 -1
- package/dist/esm/update.d.ts.map +0 -1
- package/dist/esm/update.js.map +0 -1
- package/dist/esm/virtual-root.d.ts.map +0 -1
- package/dist/esm/virtual-root.js.map +0 -1
- package/dist/esm/visualization/human-readable-output.d.ts.map +0 -1
- package/dist/esm/visualization/human-readable-output.js.map +0 -1
- package/dist/esm/visualization/json-output.d.ts.map +0 -1
- package/dist/esm/visualization/json-output.js.map +0 -1
- package/dist/esm/visualization/mermaid-output.d.ts.map +0 -1
- package/dist/esm/visualization/mermaid-output.js +0 -123
- package/dist/esm/visualization/mermaid-output.js.map +0 -1
- package/dist/esm/visualization/object-like-output.d.ts.map +0 -1
- package/dist/esm/visualization/object-like-output.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: '@vltpkg/graph'
|
|
3
|
+
---
|
|
4
|
+
|
|
1
5
|

|
|
2
6
|
|
|
3
7
|
# @vltpkg/graph
|
|
@@ -41,57 +45,87 @@ At a glance:
|
|
|
41
45
|
`node_modules/.vlt-lock.json` mirroring the current on-disk state to
|
|
42
46
|
accelerate subsequent loads of the Actual graph.
|
|
43
47
|
- Modifiers: Configuration for selectively altering dependency
|
|
44
|
-
resolution
|
|
45
|
-
|
|
48
|
+
resolution via DSS queries in `vlt.json`.
|
|
49
|
+
- Peer Contexts: Isolation mechanism for peer dependencies that allows
|
|
50
|
+
multiple versions of the same package when peer requirements differ.
|
|
46
51
|
|
|
47
52
|
## API
|
|
48
53
|
|
|
49
|
-
### `actual.load(
|
|
54
|
+
### `actual.load(options): Graph`
|
|
50
55
|
|
|
51
56
|
Recursively loads the `node_modules` folder found at `projectRoot` in
|
|
52
57
|
order to create a graph representation of the current installed
|
|
53
58
|
packages.
|
|
54
59
|
|
|
55
|
-
### `
|
|
60
|
+
### `ideal.build(options): Promise<Graph>`
|
|
56
61
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
local file system.
|
|
62
|
+
Builds the ideal dependency graph by loading from lockfile (preferred)
|
|
63
|
+
or actual graph, then expanding dependencies by fetching manifests.
|
|
64
|
+
Requires `packageInfo` and `remover` in addition to standard options.
|
|
61
65
|
|
|
62
|
-
### `lockfile.load(
|
|
66
|
+
### `lockfile.load(options): Graph`
|
|
63
67
|
|
|
64
68
|
Loads the lockfile file found at `projectRoot` and returns the graph.
|
|
65
69
|
|
|
66
|
-
### `
|
|
70
|
+
### `lockfile.save(options): void`
|
|
71
|
+
|
|
72
|
+
Saves the graph to `vlt-lock.json`.
|
|
73
|
+
|
|
74
|
+
### `reify(options): Promise<ReifyResult>`
|
|
67
75
|
|
|
68
76
|
Computes a `Diff` between the Actual and Ideal graphs and applies the
|
|
69
77
|
minimal filesystem changes (creating/deleting links, writing
|
|
70
78
|
lockfiles, hoisting, lifecycle scripts) to make the on-disk install
|
|
71
|
-
match the Ideal graph.
|
|
79
|
+
match the Ideal graph. Returns `{ diff, buildQueue }`.
|
|
80
|
+
|
|
81
|
+
### `install(options, add?): Promise<{ graph, diff, buildQueue }>`
|
|
82
|
+
|
|
83
|
+
High-level install orchestration that handles graph building, reify,
|
|
84
|
+
and lockfile management. Supports `--frozen-lockfile`,
|
|
85
|
+
`--clean-install`, and `--lockfile-only` modes.
|
|
86
|
+
|
|
87
|
+
### `mermaidOutput(graph): string`
|
|
88
|
+
|
|
89
|
+
Generates Mermaid flowchart syntax from graph data.
|
|
90
|
+
|
|
91
|
+
### `humanReadableOutput(graph, options): string`
|
|
92
|
+
|
|
93
|
+
Generates ASCII tree output with optional colors. Used in `vlt ls`.
|
|
94
|
+
|
|
95
|
+
### `jsonOutput(graph): JSONOutputItem[]`
|
|
96
|
+
|
|
97
|
+
Returns array of `{name, fromID, spec, type, to, overridden}` items.
|
|
72
98
|
|
|
73
99
|
## Usage
|
|
74
100
|
|
|
75
|
-
|
|
76
|
-
method to build a graph representation of the install defined at the
|
|
77
|
-
`projectRoot` directory.
|
|
101
|
+
### High-Level Install
|
|
78
102
|
|
|
79
|
-
```
|
|
80
|
-
import {
|
|
103
|
+
```ts
|
|
104
|
+
import { install } from '@vltpkg/graph'
|
|
81
105
|
|
|
82
|
-
const graph = await
|
|
106
|
+
const { graph, diff, buildQueue } = await install({
|
|
107
|
+
projectRoot: process.cwd(),
|
|
108
|
+
packageInfo,
|
|
109
|
+
packageJson,
|
|
110
|
+
scurry,
|
|
111
|
+
allowScripts: '*',
|
|
112
|
+
})
|
|
83
113
|
```
|
|
84
114
|
|
|
85
115
|
### Load Actual Graph and Reify
|
|
86
116
|
|
|
87
117
|
```ts
|
|
88
118
|
import { actual, ideal, reify } from '@vltpkg/graph'
|
|
119
|
+
import { RollbackRemove } from '@vltpkg/rollback-remove'
|
|
120
|
+
|
|
121
|
+
const remover = new RollbackRemove()
|
|
89
122
|
|
|
90
123
|
// Load current on-disk state
|
|
91
124
|
const from = actual.load({
|
|
92
125
|
projectRoot: process.cwd(),
|
|
93
126
|
packageJson,
|
|
94
127
|
scurry,
|
|
128
|
+
loadManifests: true,
|
|
95
129
|
})
|
|
96
130
|
|
|
97
131
|
// Build intended end state (may start from lockfile or actual)
|
|
@@ -100,15 +134,18 @@ const to = await ideal.build({
|
|
|
100
134
|
packageInfo,
|
|
101
135
|
packageJson,
|
|
102
136
|
scurry,
|
|
137
|
+
remover,
|
|
103
138
|
})
|
|
104
139
|
|
|
105
140
|
// Apply minimal changes to match Ideal
|
|
106
|
-
await reify({
|
|
141
|
+
const { diff, buildQueue } = await reify({
|
|
107
142
|
graph: to,
|
|
108
143
|
actual: from,
|
|
109
144
|
packageInfo,
|
|
110
145
|
packageJson,
|
|
111
146
|
scurry,
|
|
147
|
+
remover,
|
|
148
|
+
allowScripts: '*',
|
|
112
149
|
})
|
|
113
150
|
```
|
|
114
151
|
|
|
@@ -118,15 +155,48 @@ await reify({
|
|
|
118
155
|
import { lockfile } from '@vltpkg/graph'
|
|
119
156
|
|
|
120
157
|
// Load virtual graph from vlt-lock.json
|
|
121
|
-
const
|
|
158
|
+
const graph = lockfile.load({
|
|
122
159
|
projectRoot,
|
|
123
160
|
mainManifest,
|
|
124
161
|
packageJson,
|
|
125
|
-
scurry,
|
|
126
162
|
})
|
|
127
163
|
|
|
128
|
-
// Save
|
|
129
|
-
lockfile.save({ graph
|
|
164
|
+
// Save to vlt-lock.json
|
|
165
|
+
lockfile.save({ graph })
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### Graph Visualization
|
|
169
|
+
|
|
170
|
+
```ts
|
|
171
|
+
import {
|
|
172
|
+
mermaidOutput,
|
|
173
|
+
humanReadableOutput,
|
|
174
|
+
jsonOutput,
|
|
175
|
+
} from '@vltpkg/graph'
|
|
176
|
+
|
|
177
|
+
// Mermaid flowchart (for docs, dashboards)
|
|
178
|
+
const mermaid = mermaidOutput({
|
|
179
|
+
edges: [...graph.edges],
|
|
180
|
+
nodes: [...graph.nodes.values()],
|
|
181
|
+
importers: graph.importers,
|
|
182
|
+
})
|
|
183
|
+
|
|
184
|
+
// ASCII tree with colors (used in `vlt ls`)
|
|
185
|
+
const tree = humanReadableOutput(
|
|
186
|
+
{
|
|
187
|
+
edges: [...graph.edges],
|
|
188
|
+
nodes: [...graph.nodes.values()],
|
|
189
|
+
importers: graph.importers,
|
|
190
|
+
},
|
|
191
|
+
{ colors: true },
|
|
192
|
+
)
|
|
193
|
+
|
|
194
|
+
// JSON array of dependency items
|
|
195
|
+
const json = jsonOutput({
|
|
196
|
+
edges: [...graph.edges],
|
|
197
|
+
nodes: [...graph.nodes.values()],
|
|
198
|
+
importers: graph.importers,
|
|
199
|
+
})
|
|
130
200
|
```
|
|
131
201
|
|
|
132
202
|
## Architecture
|
|
@@ -137,6 +207,7 @@ Graph construction modes supported by the library:
|
|
|
137
207
|
- Load and save via `src/lockfile/load.ts` and
|
|
138
208
|
`src/lockfile/save.ts`
|
|
139
209
|
- Hidden lockfile: `node_modules/.vlt-lock.json` for faster loads
|
|
210
|
+
- 📖 [Lockfile README](./src/lockfile/README.md)
|
|
140
211
|
|
|
141
212
|
- Actual Graphs (filesystem-based)
|
|
142
213
|
- Loaded by traversing `node_modules` via `src/actual/load.ts`
|
|
@@ -150,20 +221,28 @@ Graph construction modes supported by the library:
|
|
|
150
221
|
`src/ideal/get-importer-specs.ts`
|
|
151
222
|
- Fetches and expands manifests using `@vltpkg/package-info`, reuses
|
|
152
223
|
existing nodes that satisfy specs
|
|
224
|
+
- 📖 [Ideal README](./src/ideal/README.md)
|
|
153
225
|
|
|
154
226
|
Finally, `src/diff.ts` computes changes and `src/reify/` applies them
|
|
155
227
|
to the filesystem.
|
|
156
228
|
|
|
229
|
+
- 📖 [Reify README](./src/reify/README.md)
|
|
230
|
+
- 📖 [Architecture Guide](./ARCHITECTURE.md)
|
|
231
|
+
|
|
157
232
|
## Related Workspaces
|
|
158
233
|
|
|
159
234
|
- `@vltpkg/dep-id`: Unique IDs for packages, ensuring `Node` identity
|
|
160
235
|
- `@vltpkg/spec`: Parse/normalize dependency specifiers and registry
|
|
161
236
|
semantics
|
|
162
237
|
- `@vltpkg/semver`: Semantic version parsing/comparison
|
|
238
|
+
- `@vltpkg/satisfies`: Check if a DepID satisfies a Spec
|
|
163
239
|
- `@vltpkg/package-info`: Fetch remote manifests and artifacts
|
|
164
240
|
(registry, git, tarball)
|
|
165
241
|
- `@vltpkg/package-json`: Read and cache local `package.json` files
|
|
166
242
|
- `@vltpkg/workspaces`: Monorepo workspace discovery and grouping
|
|
243
|
+
- `@vltpkg/rollback-remove`: Safe file removal with rollback
|
|
244
|
+
capability
|
|
245
|
+
- `@vltpkg/vlt-json`: Load `vlt.json` configuration (modifiers, etc.)
|
|
167
246
|
|
|
168
247
|
## References
|
|
169
248
|
|
|
@@ -91,10 +91,17 @@ export declare const asStoreConfigObject: (obj: unknown) => StoreConfigObject;
|
|
|
91
91
|
* path-based or a registry spec, otherwise returns `undefined`.
|
|
92
92
|
*/
|
|
93
93
|
export declare const getPathBasedId: (spec: Spec, path: Path) => DepID | undefined;
|
|
94
|
+
/**
|
|
95
|
+
* Verify that all importer node_modules directories exist on disk.
|
|
96
|
+
* The hidden lockfile may report deps as installed even when a
|
|
97
|
+
* workspace's node_modules has been manually deleted. Throws if
|
|
98
|
+
* any importer node_modules directory is missing, causing the
|
|
99
|
+
* caller to fall through to filesystem-based graph loading.
|
|
100
|
+
*/
|
|
101
|
+
export declare const verifyImporterNodeModules: (graph: Graph, projectRoot: string) => void;
|
|
94
102
|
/**
|
|
95
103
|
* Read the file system looking for `node_modules` folders and
|
|
96
104
|
* returns a new {@link Graph} that represents the relationship
|
|
97
105
|
* between the dependencies found.
|
|
98
106
|
*/
|
|
99
107
|
export declare const load: (options: LoadOptions) => Graph;
|
|
100
|
-
//# sourceMappingURL=load.d.ts.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { asDepID, hydrate, joinDepIDTuple } from '@vltpkg/dep-id';
|
|
1
|
+
import { asDepID, hydrate, joinDepIDTuple, joinExtra, splitDepID, splitExtra, } from '@vltpkg/dep-id';
|
|
2
2
|
import { Spec } from '@vltpkg/spec';
|
|
3
3
|
import { graphStep } from '@vltpkg/output';
|
|
4
4
|
import { isObject } from '@vltpkg/types';
|
|
@@ -6,7 +6,8 @@ import { shorten, getRawDependencies, getDependencies, } from "../dependencies.j
|
|
|
6
6
|
import { Graph } from "../graph.js";
|
|
7
7
|
import { loadHidden } from "../lockfile/load.js";
|
|
8
8
|
import { saveHidden } from "../lockfile/save.js";
|
|
9
|
-
import { readFileSync } from 'node:fs';
|
|
9
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
10
|
+
import { resolve } from 'node:path';
|
|
10
11
|
/**
|
|
11
12
|
* Checks if a given object is a {@link StoreConfigObject}.
|
|
12
13
|
*/
|
|
@@ -136,12 +137,14 @@ const parseDir = (options, scurry, packageJson, depsFound, graph, fromNode, curr
|
|
|
136
137
|
if (!loadManifests) {
|
|
137
138
|
const depId = findDepID(realpath);
|
|
138
139
|
if (depId) {
|
|
139
|
-
let h = hydrate(depId, alias,
|
|
140
|
-
...options,
|
|
141
|
-
});
|
|
140
|
+
let h = hydrate(depId, alias, options);
|
|
142
141
|
// if the parsed registry value is using the default value, then
|
|
143
142
|
// the node should inherit the registry value from its parent node
|
|
144
|
-
h.
|
|
143
|
+
if (h.type === 'registry' &&
|
|
144
|
+
h.registry === h.options.registry &&
|
|
145
|
+
fromNode.registry) {
|
|
146
|
+
h.registry = fromNode.registry;
|
|
147
|
+
}
|
|
145
148
|
// Check for active modifiers and replace spec even when not loading manifests
|
|
146
149
|
const { spec: modifiedSpec, queryModifier } = maybeApplyModifierToSpec(h, alias, modifierRefs);
|
|
147
150
|
h = modifiedSpec;
|
|
@@ -152,7 +155,7 @@ const parseDir = (options, scurry, packageJson, depsFound, graph, fromNode, curr
|
|
|
152
155
|
h, // uses spec from hydrated id
|
|
153
156
|
{
|
|
154
157
|
name,
|
|
155
|
-
}, depId, queryModifier);
|
|
158
|
+
}, depId, joinExtra({ modifier: queryModifier }));
|
|
156
159
|
// Update active entry after placing package
|
|
157
160
|
const activeModifier = modifierRefs?.get(alias);
|
|
158
161
|
if (activeModifier && node) {
|
|
@@ -177,15 +180,31 @@ const parseDir = (options, scurry, packageJson, depsFound, graph, fromNode, curr
|
|
|
177
180
|
const depType = shorten(type, alias, fromNode.manifest);
|
|
178
181
|
let spec = Spec.parse(alias, bareSpec, {
|
|
179
182
|
...options,
|
|
183
|
+
// fall back to options.registry (which the lockfile merges into)
|
|
184
|
+
// so importer-level edges don't silently revert to the default
|
|
185
|
+
// npm registry. see vltpkg/vltpkg#1580.
|
|
186
|
+
registry: fromNode.registry ?? options.registry,
|
|
180
187
|
});
|
|
181
|
-
// if the parsed registry value is using the default value, then
|
|
182
|
-
// the node should inherit the registry value from its parent node
|
|
183
|
-
spec.inheritedRegistry = fromNode.registry;
|
|
184
188
|
// Check for active modifiers and replace spec if a modifier is complete
|
|
185
189
|
const { spec: modifiedSpec, queryModifier } = maybeApplyModifierToSpec(spec, alias, modifierRefs);
|
|
186
190
|
spec = modifiedSpec;
|
|
187
191
|
const maybeId = getPathBasedId(spec, realpath);
|
|
188
|
-
|
|
192
|
+
let peerSetHash;
|
|
193
|
+
if (maybeId) {
|
|
194
|
+
// parses extra info from depID to retrieve peerSetHash
|
|
195
|
+
try {
|
|
196
|
+
const tuple = splitDepID(maybeId);
|
|
197
|
+
const type = tuple[0];
|
|
198
|
+
const extra = type === 'registry' || type === 'git' ?
|
|
199
|
+
tuple[3]
|
|
200
|
+
: tuple[2];
|
|
201
|
+
peerSetHash =
|
|
202
|
+
extra ? splitExtra(extra).peerSetHash : undefined;
|
|
203
|
+
/* c8 ignore next - impossible: getPathBasedId asserts valid dep id */
|
|
204
|
+
}
|
|
205
|
+
catch { }
|
|
206
|
+
}
|
|
207
|
+
node = graph.placePackage(fromNode, depType, spec, mani, maybeId, joinExtra({ modifier: queryModifier, peerSetHash }));
|
|
189
208
|
// Update active entry after placing package
|
|
190
209
|
const activeModifier = modifierRefs?.get(alias);
|
|
191
210
|
if (activeModifier && node) {
|
|
@@ -223,14 +242,27 @@ const parseDir = (options, scurry, packageJson, depsFound, graph, fromNode, curr
|
|
|
223
242
|
const depType = shorten(type, name, fromNode.manifest);
|
|
224
243
|
let spec = Spec.parse(name, bareSpec, {
|
|
225
244
|
...options,
|
|
245
|
+
registry: fromNode.registry ?? options.registry,
|
|
226
246
|
});
|
|
227
|
-
// if the parsed registry value is using the default value, then
|
|
228
|
-
// the node should inherit the registry value from its parent node
|
|
229
|
-
spec.inheritedRegistry = fromNode.registry;
|
|
230
247
|
// Check for active modifiers and replace spec for missing dependencies
|
|
231
248
|
const { spec: modifiedSpec, queryModifier } = maybeApplyModifierToSpec(spec, name, modifierRefs);
|
|
232
249
|
spec = modifiedSpec;
|
|
233
|
-
graph.placePackage(fromNode, depType, spec, undefined, undefined, queryModifier);
|
|
250
|
+
graph.placePackage(fromNode, depType, spec, undefined, undefined, joinExtra({ modifier: queryModifier }));
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
};
|
|
254
|
+
/**
|
|
255
|
+
* Verify that all importer node_modules directories exist on disk.
|
|
256
|
+
* The hidden lockfile may report deps as installed even when a
|
|
257
|
+
* workspace's node_modules has been manually deleted. Throws if
|
|
258
|
+
* any importer node_modules directory is missing, causing the
|
|
259
|
+
* caller to fall through to filesystem-based graph loading.
|
|
260
|
+
*/
|
|
261
|
+
export const verifyImporterNodeModules = (graph, projectRoot) => {
|
|
262
|
+
for (const importer of graph.importers) {
|
|
263
|
+
const nm = resolve(projectRoot, importer.location, 'node_modules');
|
|
264
|
+
if (!existsSync(nm)) {
|
|
265
|
+
throw new Error(`Missing node_modules for importer: ${importer.location}`);
|
|
234
266
|
}
|
|
235
267
|
}
|
|
236
268
|
};
|
|
@@ -254,12 +286,14 @@ export const load = (options) => {
|
|
|
254
286
|
monorepo,
|
|
255
287
|
scurry,
|
|
256
288
|
});
|
|
289
|
+
verifyImporterNodeModules(graph, projectRoot);
|
|
257
290
|
done();
|
|
258
291
|
return graph;
|
|
259
292
|
}
|
|
260
293
|
catch {
|
|
261
|
-
//
|
|
262
|
-
// fall back to filesystem traversal
|
|
294
|
+
// Hidden lockfile is cache-only, safe to regenerate on any error
|
|
295
|
+
// as it will fall back to filesystem traversal
|
|
296
|
+
// TODO: Warn version mismatch to @vltpkg/output for debugging
|
|
263
297
|
}
|
|
264
298
|
}
|
|
265
299
|
const graph = new Graph({ ...options, mainManifest });
|
|
@@ -293,12 +327,13 @@ export const load = (options) => {
|
|
|
293
327
|
// Clean up any pending modifier entries that were never completed
|
|
294
328
|
modifiers?.rollbackActiveEntries();
|
|
295
329
|
// caches the load result to the hidden lockfile when enabled
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
330
|
+
if (scurry.cwd.resolve('node_modules').lstatSync()?.isDirectory()) {
|
|
331
|
+
saveHidden({
|
|
332
|
+
...options,
|
|
333
|
+
graph,
|
|
334
|
+
});
|
|
335
|
+
}
|
|
300
336
|
}
|
|
301
337
|
done();
|
|
302
338
|
return graph;
|
|
303
339
|
};
|
|
304
|
-
//# sourceMappingURL=load.js.map
|
|
@@ -12,4 +12,3 @@ declare const transfer: {
|
|
|
12
12
|
load: (transfered: import("./transfer-data/load.ts").TransferData) => import("./transfer-data/load.ts").LoadResult;
|
|
13
13
|
};
|
|
14
14
|
export { asDependencyTypeShort, getBooleanFlagsFromNum, lockfile, longDependencyTypes, shorten, stringifyNode, transfer, };
|
|
15
|
-
//# sourceMappingURL=browser.d.ts.map
|
|
@@ -63,4 +63,3 @@ export declare const getRawDependencies: (node: NodeLike) => Map<string, RawDepe
|
|
|
63
63
|
* from a given node manifest, including missing dependencies.
|
|
64
64
|
*/
|
|
65
65
|
export declare const getDependencies: (node: NodeLike, options: SpecOptions) => Map<string, Dependency>;
|
|
66
|
-
//# sourceMappingURL=dependencies.d.ts.map
|
|
@@ -53,6 +53,7 @@ export declare class Diff {
|
|
|
53
53
|
nodes: {
|
|
54
54
|
add: {
|
|
55
55
|
rawManifest?: import("@vltpkg/types").Override<import("@vltpkg/types").Manifest, import("@vltpkg/types").NormalizedFields> | undefined;
|
|
56
|
+
peerSetHash?: string | undefined;
|
|
56
57
|
id: import("@vltpkg/dep-id").DepID;
|
|
57
58
|
name: string;
|
|
58
59
|
version: string | undefined;
|
|
@@ -70,11 +71,13 @@ export declare class Diff {
|
|
|
70
71
|
engines?: Record<string, string>;
|
|
71
72
|
os?: string[] | string;
|
|
72
73
|
cpu?: string[] | string;
|
|
74
|
+
libc?: string[] | string;
|
|
73
75
|
} | undefined;
|
|
74
76
|
buildState: "none" | "needed" | "built" | "failed";
|
|
75
77
|
}[];
|
|
76
78
|
delete: {
|
|
77
79
|
rawManifest?: import("@vltpkg/types").Override<import("@vltpkg/types").Manifest, import("@vltpkg/types").NormalizedFields> | undefined;
|
|
80
|
+
peerSetHash?: string | undefined;
|
|
78
81
|
id: import("@vltpkg/dep-id").DepID;
|
|
79
82
|
name: string;
|
|
80
83
|
version: string | undefined;
|
|
@@ -92,6 +95,7 @@ export declare class Diff {
|
|
|
92
95
|
engines?: Record<string, string>;
|
|
93
96
|
os?: string[] | string;
|
|
94
97
|
cpu?: string[] | string;
|
|
98
|
+
libc?: string[] | string;
|
|
95
99
|
} | undefined;
|
|
96
100
|
buildState: "none" | "needed" | "built" | "failed";
|
|
97
101
|
}[];
|
|
@@ -113,4 +117,3 @@ export declare class Diff {
|
|
|
113
117
|
};
|
|
114
118
|
}
|
|
115
119
|
export {};
|
|
116
|
-
//# sourceMappingURL=diff.d.ts.map
|
|
@@ -80,8 +80,12 @@ export class Diff {
|
|
|
80
80
|
continue;
|
|
81
81
|
if (fromEdge?.to)
|
|
82
82
|
this.edges.delete.add(fromEdge);
|
|
83
|
-
if (edge.to)
|
|
83
|
+
if (edge.to) {
|
|
84
84
|
this.edges.add.add(edge);
|
|
85
|
+
if (!edge.optional) {
|
|
86
|
+
this.optionalOnly = false;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
85
89
|
}
|
|
86
90
|
for (const edge of this.from.edges) {
|
|
87
91
|
// the node with this dep, in the to graph
|
|
@@ -145,4 +149,3 @@ ${lines
|
|
|
145
149
|
};
|
|
146
150
|
}
|
|
147
151
|
}
|
|
148
|
-
//# sourceMappingURL=diff.js.map
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Spec } from '@vltpkg/spec';
|
|
2
|
+
import type { Dependency } from './dependencies.ts';
|
|
3
|
+
import type { Manifest } from '@vltpkg/types';
|
|
4
|
+
import type { SpecOptions } from '@vltpkg/spec';
|
|
5
|
+
/**
|
|
6
|
+
* When adding new dependencies, it's very common to not have a dependency
|
|
7
|
+
* name directly available to reference, e.g: `file:local/folder` or
|
|
8
|
+
* `remote:tarball-url.tgz`. In these cases, a placeholder `(unknown)` name
|
|
9
|
+
* is used in the `Spec` object and the `add` Map structure that holds
|
|
10
|
+
* references to added dependencies will use the stringified spec as a key.
|
|
11
|
+
*
|
|
12
|
+
* This helper function fixes unknown names in the `add` map by replacing
|
|
13
|
+
* placeholder specs with the correct names from the provided manifest.
|
|
14
|
+
*
|
|
15
|
+
* It also fixes empty bareSpec values (from CLI args like `vlt install foo`)
|
|
16
|
+
* by calculating the proper semver range from the resolved manifest version.
|
|
17
|
+
*/
|
|
18
|
+
export declare const fixupAddedNames: (add: Map<string, Dependency> | undefined, manifest: Pick<Manifest, "name" | "version"> | undefined, options: SpecOptions, spec: Spec) => Spec;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { Spec } from '@vltpkg/spec';
|
|
2
|
+
import { calculateSaveValue } from "./reify/calculate-save-value.js";
|
|
3
|
+
/**
|
|
4
|
+
* When adding new dependencies, it's very common to not have a dependency
|
|
5
|
+
* name directly available to reference, e.g: `file:local/folder` or
|
|
6
|
+
* `remote:tarball-url.tgz`. In these cases, a placeholder `(unknown)` name
|
|
7
|
+
* is used in the `Spec` object and the `add` Map structure that holds
|
|
8
|
+
* references to added dependencies will use the stringified spec as a key.
|
|
9
|
+
*
|
|
10
|
+
* This helper function fixes unknown names in the `add` map by replacing
|
|
11
|
+
* placeholder specs with the correct names from the provided manifest.
|
|
12
|
+
*
|
|
13
|
+
* It also fixes empty bareSpec values (from CLI args like `vlt install foo`)
|
|
14
|
+
* by calculating the proper semver range from the resolved manifest version.
|
|
15
|
+
*/
|
|
16
|
+
export const fixupAddedNames = (add, manifest, options, spec) => {
|
|
17
|
+
// Handle nameless dependencies
|
|
18
|
+
if (add && manifest?.name && spec.name === '(unknown)') {
|
|
19
|
+
const s = add.get(String(spec));
|
|
20
|
+
if (s) {
|
|
21
|
+
// removes the previous, placeholder entry key
|
|
22
|
+
add.delete(String(spec));
|
|
23
|
+
// replaces spec with a version with the correct name
|
|
24
|
+
spec = Spec.parse(manifest.name, spec.bareSpec, options);
|
|
25
|
+
// updates the add map with the fixed up spec
|
|
26
|
+
const n = {
|
|
27
|
+
type: s.type,
|
|
28
|
+
spec,
|
|
29
|
+
};
|
|
30
|
+
add.set(manifest.name, n);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
// Fix empty bareSpec (usually from CLI args like `vlt install foo`)
|
|
34
|
+
// by calculating the proper semver range from the resolved manifest version
|
|
35
|
+
if (add && manifest?.version && !spec.bareSpec) {
|
|
36
|
+
const addEntry = add.get(spec.name);
|
|
37
|
+
if (addEntry) {
|
|
38
|
+
const saveValue = calculateSaveValue(spec.final.type, spec, undefined, manifest.version);
|
|
39
|
+
if (saveValue && saveValue !== spec.bareSpec) {
|
|
40
|
+
spec = Spec.parse(spec.name, saveValue, options);
|
|
41
|
+
addEntry.spec = spec;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return spec;
|
|
46
|
+
};
|
|
@@ -6,6 +6,7 @@ import type { Monorepo } from '@vltpkg/workspaces';
|
|
|
6
6
|
import type { InspectOptions } from 'node:util';
|
|
7
7
|
import { Edge } from './edge.ts';
|
|
8
8
|
import { Node } from './node.ts';
|
|
9
|
+
import type { PeerContext } from './ideal/types.ts';
|
|
9
10
|
declare const kCustomInspect: unique symbol;
|
|
10
11
|
export type ManifestInventory = Map<DepID, NormalizedManifest>;
|
|
11
12
|
export type GraphOptions = SpecOptions & {
|
|
@@ -73,7 +74,26 @@ export declare class Graph implements GraphLike {
|
|
|
73
74
|
* The root of the project this graph represents
|
|
74
75
|
*/
|
|
75
76
|
projectRoot: string;
|
|
77
|
+
/**
|
|
78
|
+
* The peer context sets used to resolve peer dependencies within this graph.
|
|
79
|
+
*/
|
|
80
|
+
peerContexts: PeerContext[];
|
|
81
|
+
/**
|
|
82
|
+
* Cache of forked peer contexts so identical fork operations can reuse
|
|
83
|
+
* previously created contexts instead of duplicating them.
|
|
84
|
+
*
|
|
85
|
+
* Key format is internal and constructed in `ideal/peers.ts`.
|
|
86
|
+
*/
|
|
87
|
+
peerContextForkCache: Map<string, PeerContext>;
|
|
88
|
+
/**
|
|
89
|
+
* Tracks the current peer context index.
|
|
90
|
+
*/
|
|
91
|
+
currentPeerContextIndex: number;
|
|
76
92
|
constructor(options: GraphOptions);
|
|
93
|
+
/**
|
|
94
|
+
* Get the next peer context index.
|
|
95
|
+
*/
|
|
96
|
+
nextPeerContextIndex(): number;
|
|
77
97
|
/**
|
|
78
98
|
* Delete all nodes and edges that are unreachable from the importers.
|
|
79
99
|
* The collection of deleted nodes is returned.
|
|
@@ -93,7 +113,7 @@ export declare class Graph implements GraphLike {
|
|
|
93
113
|
/**
|
|
94
114
|
* Find an existing node to satisfy a dependency
|
|
95
115
|
*/
|
|
96
|
-
findResolution(spec: Spec, fromNode: Node,
|
|
116
|
+
findResolution(spec: Spec, fromNode: Node, extra?: string): Node | undefined;
|
|
97
117
|
/**
|
|
98
118
|
* Create a new node in the graph.
|
|
99
119
|
*/
|
|
@@ -121,13 +141,13 @@ export declare class Graph implements GraphLike {
|
|
|
121
141
|
/**
|
|
122
142
|
* Removes the resolved node of a given edge.
|
|
123
143
|
*/
|
|
124
|
-
removeEdgeResolution(edge: Edge,
|
|
144
|
+
removeEdgeResolution(edge: Edge, extra?: string): void;
|
|
125
145
|
/**
|
|
126
|
-
*
|
|
146
|
+
* Remove all edges from the graph while preserving nodes and resolution caches.
|
|
147
|
+
* This allows the graph to be reconstructed efficiently using the existing nodes.
|
|
127
148
|
*/
|
|
128
|
-
|
|
149
|
+
resetEdges(): void;
|
|
129
150
|
toJSON(): import("./index.ts").LockfileData;
|
|
130
151
|
[kCustomInspect](_: number, options: InspectOptions): string;
|
|
131
152
|
}
|
|
132
153
|
export {};
|
|
133
|
-
//# sourceMappingURL=graph.d.ts.map
|