@antongolub/lockfile 0.0.0-snapshot.70 → 0.0.0-snapshot.72
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +12 -0
- package/dist/modify.js +6 -0
- package/dist/optimize.d.ts +22 -5
- package/dist/optimize.js +60 -3
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -10609,6 +10609,12 @@ async function replaceVersion(graph, selector, toRange, context, options = {}) {
|
|
|
10609
10609
|
currentGraph = currentGraph.mutate((m) => {
|
|
10610
10610
|
for (const e of staleOut) m.removeEdge(targetId, e.dst, e.kind);
|
|
10611
10611
|
}).graph;
|
|
10612
|
+
for (const e of staleOut) {
|
|
10613
|
+
const dst = currentGraph.getNode(e.dst);
|
|
10614
|
+
if (dst !== void 0 && dst.workspacePath === void 0 && currentGraph.in(e.dst).length === 0) {
|
|
10615
|
+
recentlyOrphaned.add(e.dst);
|
|
10616
|
+
}
|
|
10617
|
+
}
|
|
10612
10618
|
}
|
|
10613
10619
|
replaced.push({ from: node.id, to: targetId });
|
|
10614
10620
|
recentlyAdded.add(targetId);
|
|
@@ -10939,6 +10945,12 @@ function optimize(graph, options = {}) {
|
|
|
10939
10945
|
}
|
|
10940
10946
|
}
|
|
10941
10947
|
}
|
|
10948
|
+
for (const node of graph.nodes()) {
|
|
10949
|
+
if (!live.has(node.id)) continue;
|
|
10950
|
+
if (node.patch === void 0 && node.source === void 0) continue;
|
|
10951
|
+
const baseId = serializeNodeId(node.name, node.version, node.peerContext, void 0, void 0);
|
|
10952
|
+
if (baseId !== node.id && graph.getNode(baseId) !== void 0) live.add(baseId);
|
|
10953
|
+
}
|
|
10942
10954
|
const removed = [];
|
|
10943
10955
|
const unresolved = [];
|
|
10944
10956
|
let next = graph;
|
package/dist/modify.js
CHANGED
|
@@ -628,6 +628,12 @@ async function replaceVersion(graph, selector, toRange, context, options = {}) {
|
|
|
628
628
|
currentGraph = currentGraph.mutate((m) => {
|
|
629
629
|
for (const e of staleOut) m.removeEdge(targetId, e.dst, e.kind);
|
|
630
630
|
}).graph;
|
|
631
|
+
for (const e of staleOut) {
|
|
632
|
+
const dst = currentGraph.getNode(e.dst);
|
|
633
|
+
if (dst !== void 0 && dst.workspacePath === void 0 && currentGraph.in(e.dst).length === 0) {
|
|
634
|
+
recentlyOrphaned.add(e.dst);
|
|
635
|
+
}
|
|
636
|
+
}
|
|
631
637
|
}
|
|
632
638
|
replaced.push({ from: node.id, to: targetId });
|
|
633
639
|
recentlyAdded.add(targetId);
|
package/dist/optimize.d.ts
CHANGED
|
@@ -9,9 +9,17 @@ interface PruneOrphansOptions {
|
|
|
9
9
|
/**
|
|
10
10
|
* Bound the sweep to a candidate set. When provided, ONLY these NodeIds (and
|
|
11
11
|
* the closure they transitively strand) are removal candidates — any OTHER
|
|
12
|
-
* pre-existing in-degree-0 node is left untouched.
|
|
13
|
-
*
|
|
14
|
-
*
|
|
12
|
+
* pre-existing in-degree-0 node is left untouched.
|
|
13
|
+
*
|
|
14
|
+
* **Seeded is the SAFE / recommended mode for post-mutation GC.** Pass the
|
|
15
|
+
* mutation's orphaned NodeIds (`replaceVersion`'s `recentlyOrphaned` — which
|
|
16
|
+
* now includes the targets whose last incoming edge a rebind's edge-refresh
|
|
17
|
+
* dropped). The sweep then retires exactly that delta and CANNOT touch a node
|
|
18
|
+
* the mutation never affected — including ones that only LOOK orphaned because
|
|
19
|
+
* an incoming edge is unresolved in the parse (e.g. berry `@patch:…!builtin`
|
|
20
|
+
* fsevents). Omit only for a whole-graph sweep on a graph whose edges you trust
|
|
21
|
+
* to be complete; the unseeded path over-prunes such unresolved-edge nodes and
|
|
22
|
+
* is guarded against wiping a rootless lock (PRUNE_NO_ROOTS).
|
|
15
23
|
*/
|
|
16
24
|
seed?: ReadonlySet<NodeId>;
|
|
17
25
|
}
|
|
@@ -42,7 +50,7 @@ interface OptimizeDiagnostic extends Diagnostic {
|
|
|
42
50
|
* rationale — the NodeId alone may carry a long peerContext suffix.
|
|
43
51
|
*/
|
|
44
52
|
declare function optimizeNodeRemoved(nodeId: NodeId): OptimizeDiagnostic;
|
|
45
|
-
type PruneDiagnosticCode = 'PRUNE_NODE_REMOVED' | 'PRUNE_NOOP';
|
|
53
|
+
type PruneDiagnosticCode = 'PRUNE_NODE_REMOVED' | 'PRUNE_NOOP' | 'PRUNE_NO_ROOTS';
|
|
46
54
|
interface PruneDiagnostic extends Diagnostic {
|
|
47
55
|
code: PruneDiagnosticCode;
|
|
48
56
|
}
|
|
@@ -50,6 +58,15 @@ interface PruneDiagnostic extends Diagnostic {
|
|
|
50
58
|
declare function pruneNodeRemoved(nodeId: NodeId): PruneDiagnostic;
|
|
51
59
|
/** Fires once per `pruneOrphans(graph)` call when nothing was removed. */
|
|
52
60
|
declare function pruneNoop(): PruneDiagnostic;
|
|
61
|
+
/**
|
|
62
|
+
* Fires when an UNSEEDED pruneOrphans runs on a non-empty graph with no
|
|
63
|
+
* workspace anchor (e.g. a rootless yarn-classic lock). Without a workspace
|
|
64
|
+
* every top-level dependency is itself in-degree 0, so a whole-graph sweep would
|
|
65
|
+
* cascade and wipe the lock. We no-op instead — the caller bounds the sweep with
|
|
66
|
+
* an explicit `seed` (or `preserve`) to GC a rootless graph. Mirrors
|
|
67
|
+
* OPTIMIZE_NO_ROOTS.
|
|
68
|
+
*/
|
|
69
|
+
declare function pruneNoRoots(): PruneDiagnostic;
|
|
53
70
|
declare function optimizeWorkspaceUnreachable(nodeId: NodeId): OptimizeDiagnostic;
|
|
54
71
|
/**
|
|
55
72
|
* Fires once per `optimize(graph)` call when `removed.length === 0`. The
|
|
@@ -60,4 +77,4 @@ declare function optimizeWorkspaceUnreachable(nodeId: NodeId): OptimizeDiagnosti
|
|
|
60
77
|
*/
|
|
61
78
|
declare function optimizeNoop(): OptimizeDiagnostic;
|
|
62
79
|
|
|
63
|
-
export { type OptimizeDiagnostic, type OptimizeDiagnosticCode, type PruneDiagnostic, type PruneDiagnosticCode, type PruneOrphansOptions, type PruneOrphansResult, optimizeNodeRemoved, optimizeNoop, optimizeWorkspaceUnreachable, pruneNodeRemoved, pruneNoop, pruneOrphans };
|
|
80
|
+
export { type OptimizeDiagnostic, type OptimizeDiagnosticCode, type PruneDiagnostic, type PruneDiagnosticCode, type PruneOrphansOptions, type PruneOrphansResult, optimizeNodeRemoved, optimizeNoop, optimizeWorkspaceUnreachable, pruneNoRoots, pruneNodeRemoved, pruneNoop, pruneOrphans };
|
package/dist/optimize.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import 'crypto';
|
|
2
2
|
import 'buffer';
|
|
3
3
|
|
|
4
|
-
// src/main/ts/
|
|
4
|
+
// src/main/ts/errors.ts
|
|
5
5
|
|
|
6
6
|
// src/main/ts/graph.ts
|
|
7
7
|
function nameOf(id) {
|
|
@@ -15,6 +15,16 @@ function nameOf(id) {
|
|
|
15
15
|
}
|
|
16
16
|
return lastAt < 0 ? id : id.slice(0, lastAt);
|
|
17
17
|
}
|
|
18
|
+
function serializeNodeId(name, version, peerContext, patch, source) {
|
|
19
|
+
const base = toTarballKey({ name, version});
|
|
20
|
+
if (peerContext.length === 0) return base;
|
|
21
|
+
return base + peerContext.map((p) => `(${p})`).join("");
|
|
22
|
+
}
|
|
23
|
+
function toTarballKey(inputs) {
|
|
24
|
+
const slots = [];
|
|
25
|
+
return slots.length === 0 ? `${inputs.name}@${inputs.version}` : `${inputs.name}@${inputs.version}+${slots.sort(cmpStr).join("+")}`;
|
|
26
|
+
}
|
|
27
|
+
var cmpStr = (a, b) => a < b ? -1 : a > b ? 1 : 0;
|
|
18
28
|
|
|
19
29
|
// src/main/ts/optimize/diagnostics.ts
|
|
20
30
|
function optimizeNodeRemoved(nodeId) {
|
|
@@ -58,6 +68,14 @@ function pruneNoop() {
|
|
|
58
68
|
message: "pruneOrphans: no unreferenced nodes to collect"
|
|
59
69
|
};
|
|
60
70
|
}
|
|
71
|
+
function pruneNoRoots() {
|
|
72
|
+
return {
|
|
73
|
+
code: "PRUNE_NO_ROOTS",
|
|
74
|
+
severity: "warning",
|
|
75
|
+
subject: "graph",
|
|
76
|
+
message: "pruneOrphans: no workspace anchor and no seed on a non-empty graph \u2014 kept all nodes to avoid wiping a rootless lock"
|
|
77
|
+
};
|
|
78
|
+
}
|
|
61
79
|
function optimizeWorkspaceUnreachable(nodeId) {
|
|
62
80
|
return {
|
|
63
81
|
code: "OPTIMIZE_WORKSPACE_UNREACHABLE",
|
|
@@ -128,6 +146,12 @@ function optimize(graph, options = {}) {
|
|
|
128
146
|
}
|
|
129
147
|
}
|
|
130
148
|
}
|
|
149
|
+
for (const node of graph.nodes()) {
|
|
150
|
+
if (!live.has(node.id)) continue;
|
|
151
|
+
if (node.patch === void 0 && node.source === void 0) continue;
|
|
152
|
+
const baseId = serializeNodeId(node.name, node.version, node.peerContext);
|
|
153
|
+
if (baseId !== node.id && graph.getNode(baseId) !== void 0) live.add(baseId);
|
|
154
|
+
}
|
|
131
155
|
const removed = [];
|
|
132
156
|
const unresolved = [];
|
|
133
157
|
let next = graph;
|
|
@@ -177,12 +201,33 @@ function pruneOrphans(graph, options = {}) {
|
|
|
177
201
|
if (onDiagnostic !== void 0) onDiagnostic(d);
|
|
178
202
|
};
|
|
179
203
|
let current = graph;
|
|
204
|
+
if (options.seed === void 0) {
|
|
205
|
+
let hasNodes = false;
|
|
206
|
+
let hasWorkspace = false;
|
|
207
|
+
for (const node of current.nodes()) {
|
|
208
|
+
hasNodes = true;
|
|
209
|
+
if (node.workspacePath !== void 0) {
|
|
210
|
+
hasWorkspace = true;
|
|
211
|
+
break;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
if (hasNodes && !hasWorkspace) {
|
|
215
|
+
const diag = pruneNoRoots();
|
|
216
|
+
const guarded = current.mutate((m) => {
|
|
217
|
+
m.diagnostic(diag);
|
|
218
|
+
}).graph;
|
|
219
|
+
emit(diag);
|
|
220
|
+
return { graph: guarded, removed, unresolved };
|
|
221
|
+
}
|
|
222
|
+
}
|
|
180
223
|
const collectable = (id) => {
|
|
181
224
|
const node = current.getNode(id);
|
|
182
225
|
if (node === void 0) return false;
|
|
183
226
|
if (node.workspacePath !== void 0) return false;
|
|
184
227
|
if (preserve.has(id)) return false;
|
|
185
|
-
|
|
228
|
+
if (current.in(id).length > 0) return false;
|
|
229
|
+
if (hasLivePatchedVariant(current, node)) return false;
|
|
230
|
+
return true;
|
|
186
231
|
};
|
|
187
232
|
const queue = [];
|
|
188
233
|
if (options.seed !== void 0) {
|
|
@@ -217,6 +262,18 @@ function pruneOrphans(graph, options = {}) {
|
|
|
217
262
|
}
|
|
218
263
|
return { graph: current, removed, unresolved };
|
|
219
264
|
}
|
|
265
|
+
function hasLivePatchedVariant(graph, node) {
|
|
266
|
+
if (node.patch !== void 0 || node.source !== void 0) return false;
|
|
267
|
+
for (const id of graph.byName(node.name)) {
|
|
268
|
+
if (id === node.id) continue;
|
|
269
|
+
const other = graph.getNode(id);
|
|
270
|
+
if (other === void 0) continue;
|
|
271
|
+
if (other.patch === void 0 && other.source === void 0) continue;
|
|
272
|
+
if (other.version !== node.version) continue;
|
|
273
|
+
if (serializeNodeId(other.name, other.version, other.peerContext) === node.id) return true;
|
|
274
|
+
}
|
|
275
|
+
return false;
|
|
276
|
+
}
|
|
220
277
|
function tarballSharedByOther(graph, removingId, key) {
|
|
221
278
|
for (const id of graph.byName(key.name)) {
|
|
222
279
|
if (id === removingId) continue;
|
|
@@ -226,4 +283,4 @@ function tarballSharedByOther(graph, removingId, key) {
|
|
|
226
283
|
return false;
|
|
227
284
|
}
|
|
228
285
|
|
|
229
|
-
export { optimize, optimizeNodeRemoved, optimizeNoop, optimizeWorkspaceUnreachable, pruneNodeRemoved, pruneNoop, pruneOrphans };
|
|
286
|
+
export { optimize, optimizeNodeRemoved, optimizeNoop, optimizeWorkspaceUnreachable, pruneNoRoots, pruneNodeRemoved, pruneNoop, pruneOrphans };
|