tanmi-dock 1.0.3 → 1.0.4

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 (114) hide show
  1. package/README.md +18 -0
  2. package/dist/commands/calibrate.d.ts +10 -0
  3. package/dist/commands/calibrate.d.ts.map +1 -0
  4. package/dist/commands/calibrate.js +158 -0
  5. package/dist/commands/calibrate.js.map +1 -0
  6. package/dist/commands/check.d.ts +9 -1
  7. package/dist/commands/check.d.ts.map +1 -1
  8. package/dist/commands/check.js +261 -94
  9. package/dist/commands/check.js.map +1 -1
  10. package/dist/commands/clean.d.ts +2 -6
  11. package/dist/commands/clean.d.ts.map +1 -1
  12. package/dist/commands/clean.js +224 -209
  13. package/dist/commands/clean.js.map +1 -1
  14. package/dist/commands/dashboard.d.ts.map +1 -1
  15. package/dist/commands/dashboard.js +56 -28
  16. package/dist/commands/dashboard.js.map +1 -1
  17. package/dist/commands/link.d.ts +6 -6
  18. package/dist/commands/link.d.ts.map +1 -1
  19. package/dist/commands/link.js +417 -196
  20. package/dist/commands/link.js.map +1 -1
  21. package/dist/commands/migrate.d.ts +11 -0
  22. package/dist/commands/migrate.d.ts.map +1 -1
  23. package/dist/commands/migrate.js +277 -57
  24. package/dist/commands/migrate.js.map +1 -1
  25. package/dist/commands/reset.d.ts.map +1 -1
  26. package/dist/commands/reset.js +19 -24
  27. package/dist/commands/reset.js.map +1 -1
  28. package/dist/commands/status.d.ts +4 -0
  29. package/dist/commands/status.d.ts.map +1 -1
  30. package/dist/commands/status.js +37 -20
  31. package/dist/commands/status.js.map +1 -1
  32. package/dist/commands/unavailable.js.map +1 -1
  33. package/dist/commands/unlink.d.ts.map +1 -1
  34. package/dist/commands/unlink.js +43 -39
  35. package/dist/commands/unlink.js.map +1 -1
  36. package/dist/core/config.d.ts +3 -1
  37. package/dist/core/config.d.ts.map +1 -1
  38. package/dist/core/config.js +6 -3
  39. package/dist/core/config.js.map +1 -1
  40. package/dist/core/parser.js +1 -1
  41. package/dist/core/parser.js.map +1 -1
  42. package/dist/core/registry.d.ts +11 -29
  43. package/dist/core/registry.d.ts.map +1 -1
  44. package/dist/core/registry.js +46 -113
  45. package/dist/core/registry.js.map +1 -1
  46. package/dist/core/space/calibration-executor.d.ts +16 -0
  47. package/dist/core/space/calibration-executor.d.ts.map +1 -0
  48. package/dist/core/space/calibration-executor.js +142 -0
  49. package/dist/core/space/calibration-executor.js.map +1 -0
  50. package/dist/core/space/calibration-planner.d.ts +5 -0
  51. package/dist/core/space/calibration-planner.d.ts.map +1 -0
  52. package/dist/core/space/calibration-planner.js +157 -0
  53. package/dist/core/space/calibration-planner.js.map +1 -0
  54. package/dist/core/space/cleanup-executor.d.ts +15 -0
  55. package/dist/core/space/cleanup-executor.d.ts.map +1 -0
  56. package/dist/core/space/cleanup-executor.js +188 -0
  57. package/dist/core/space/cleanup-executor.js.map +1 -0
  58. package/dist/core/space/cleanup-journal.d.ts +43 -0
  59. package/dist/core/space/cleanup-journal.d.ts.map +1 -0
  60. package/dist/core/space/cleanup-journal.js +96 -0
  61. package/dist/core/space/cleanup-journal.js.map +1 -0
  62. package/dist/core/space/cleanup-planner.d.ts +14 -0
  63. package/dist/core/space/cleanup-planner.d.ts.map +1 -0
  64. package/dist/core/space/cleanup-planner.js +166 -0
  65. package/dist/core/space/cleanup-planner.js.map +1 -0
  66. package/dist/core/space/cleanup-selection.d.ts +10 -0
  67. package/dist/core/space/cleanup-selection.d.ts.map +1 -0
  68. package/dist/core/space/cleanup-selection.js +84 -0
  69. package/dist/core/space/cleanup-selection.js.map +1 -0
  70. package/dist/core/space/estimator.d.ts +11 -0
  71. package/dist/core/space/estimator.d.ts.map +1 -0
  72. package/dist/core/space/estimator.js +142 -0
  73. package/dist/core/space/estimator.js.map +1 -0
  74. package/dist/core/space/inventory.d.ts +15 -0
  75. package/dist/core/space/inventory.d.ts.map +1 -0
  76. package/dist/core/space/inventory.js +587 -0
  77. package/dist/core/space/inventory.js.map +1 -0
  78. package/dist/core/space/meter.d.ts +5 -0
  79. package/dist/core/space/meter.d.ts.map +1 -0
  80. package/dist/core/space/meter.js +87 -0
  81. package/dist/core/space/meter.js.map +1 -0
  82. package/dist/core/space/migration-journal.d.ts +31 -0
  83. package/dist/core/space/migration-journal.d.ts.map +1 -0
  84. package/dist/core/space/migration-journal.js +121 -0
  85. package/dist/core/space/migration-journal.js.map +1 -0
  86. package/dist/core/space/service.d.ts +26 -0
  87. package/dist/core/space/service.d.ts.map +1 -0
  88. package/dist/core/space/service.js +54 -0
  89. package/dist/core/space/service.js.map +1 -0
  90. package/dist/core/space/types.d.ts +241 -0
  91. package/dist/core/space/types.d.ts.map +1 -0
  92. package/dist/core/space/types.js +13 -0
  93. package/dist/core/space/types.js.map +1 -0
  94. package/dist/core/store.d.ts.map +1 -1
  95. package/dist/core/store.js +12 -6
  96. package/dist/core/store.js.map +1 -1
  97. package/dist/index.js +2 -0
  98. package/dist/index.js.map +1 -1
  99. package/dist/types/index.d.ts +2 -0
  100. package/dist/types/index.d.ts.map +1 -1
  101. package/dist/utils/atomic-file.d.ts +6 -0
  102. package/dist/utils/atomic-file.d.ts.map +1 -0
  103. package/dist/utils/atomic-file.js +37 -0
  104. package/dist/utils/atomic-file.js.map +1 -0
  105. package/dist/utils/fs-utils.d.ts +18 -1
  106. package/dist/utils/fs-utils.d.ts.map +1 -1
  107. package/dist/utils/fs-utils.js +150 -2
  108. package/dist/utils/fs-utils.js.map +1 -1
  109. package/dist/utils/logger.d.ts +1 -1
  110. package/dist/utils/logger.js +2 -2
  111. package/dist/utils/prompt.d.ts.map +1 -1
  112. package/dist/utils/prompt.js +4 -4
  113. package/dist/utils/prompt.js.map +1 -1
  114. package/package.json +1 -1
@@ -0,0 +1,96 @@
1
+ import fs from 'fs/promises';
2
+ import path from 'path';
3
+ import { getConfigDir } from '../platform.js';
4
+ import { writeTextFileAtomic } from '../../utils/atomic-file.js';
5
+ function getDefaultJournalDir() {
6
+ return path.join(getConfigDir(), 'space-cleanups');
7
+ }
8
+ function getJournalPath(planId, journalDir) {
9
+ return path.join(journalDir, `${planId}.json`);
10
+ }
11
+ export class CleanupJournal {
12
+ data;
13
+ filePath;
14
+ constructor(data, filePath) {
15
+ this.data = data;
16
+ this.filePath = filePath;
17
+ }
18
+ /** 创建前向恢复日志。journalDir 仅用于隔离测试或受控运行环境。 */
19
+ static async create(plan, journalDir = getDefaultJournalDir()) {
20
+ const data = {
21
+ version: 1,
22
+ planId: plan.id,
23
+ storePath: plan.storePath,
24
+ reason: plan.reason,
25
+ createdAt: Date.now(),
26
+ groups: plan.groups.map((group, index) => ({
27
+ index,
28
+ state: 'prepared',
29
+ id: group.id,
30
+ platform: group.platform,
31
+ targetPath: group.targetPath,
32
+ storeKeys: [...group.storeKeys],
33
+ libraryKey: group.libraryKey,
34
+ })),
35
+ };
36
+ const journal = new CleanupJournal(data, getJournalPath(plan.id, journalDir));
37
+ await journal.save();
38
+ return journal;
39
+ }
40
+ /** 读取可恢复日志;损坏日志保留原文件,避免猜测删除状态。 */
41
+ static async listPending(journalDir = getDefaultJournalDir()) {
42
+ return (await CleanupJournal.inspectPending(journalDir)).journals;
43
+ }
44
+ /** 同时返回可恢复日志和无法解析的日志文件。 */
45
+ static async inspectPending(journalDir = getDefaultJournalDir()) {
46
+ const directory = journalDir;
47
+ let files;
48
+ try {
49
+ files = await fs.readdir(directory);
50
+ }
51
+ catch {
52
+ return { journals: [], corruptedFiles: [] };
53
+ }
54
+ const journals = [];
55
+ const corruptedFiles = [];
56
+ for (const file of files) {
57
+ if (!file.endsWith('.json'))
58
+ continue;
59
+ const filePath = path.join(directory, file);
60
+ try {
61
+ const content = await fs.readFile(filePath, 'utf-8');
62
+ const data = JSON.parse(content);
63
+ if (data.version !== 1 || !data.planId || !Array.isArray(data.groups)) {
64
+ corruptedFiles.push(filePath);
65
+ continue;
66
+ }
67
+ journals.push(new CleanupJournal(data, filePath));
68
+ }
69
+ catch {
70
+ corruptedFiles.push(filePath);
71
+ }
72
+ }
73
+ return { journals, corruptedFiles };
74
+ }
75
+ getData() {
76
+ return this.data;
77
+ }
78
+ async updateGroup(index, state, error) {
79
+ const group = this.data.groups[index];
80
+ if (!group)
81
+ throw new Error(`清理日志不存在组 ${index}`);
82
+ group.state = state;
83
+ if (error)
84
+ group.error = error;
85
+ else
86
+ delete group.error;
87
+ await this.save();
88
+ }
89
+ async complete() {
90
+ await fs.rm(this.filePath, { force: true });
91
+ }
92
+ async save() {
93
+ await writeTextFileAtomic(this.filePath, JSON.stringify(this.data, null, 2));
94
+ }
95
+ }
96
+ //# sourceMappingURL=cleanup-journal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cleanup-journal.js","sourceRoot":"","sources":["../../../src/core/space/cleanup-journal.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { BuildCleanupPlanRequest, CleanupPlan, StoreCommitSpace, StoreSpaceSnapshot } from './types.js';
2
+ export declare function buildCleanupPlan(request: BuildCleanupPlanRequest, snapshot: StoreSpaceSnapshot): CleanupPlan;
3
+ export declare function selectHalfByAge(candidates: Array<{
4
+ selection: {
5
+ id: StoreCommitSpace['id'];
6
+ platforms: string[];
7
+ };
8
+ bytes: number;
9
+ timestamp: number;
10
+ }>): Array<{
11
+ id: StoreCommitSpace['id'];
12
+ platforms: string[];
13
+ }>;
14
+ //# sourceMappingURL=cleanup-planner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cleanup-planner.d.ts","sourceRoot":"","sources":["../../../src/core/space/cleanup-planner.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,uBAAuB,EAEvB,WAAW,EAEX,gBAAgB,EAEhB,kBAAkB,EACnB,MAAM,YAAY,CAAC;AA0GpB,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,uBAAuB,EAChC,QAAQ,EAAE,kBAAkB,GAC3B,WAAW,CA6Eb;AAED,wBAAgB,eAAe,CAC7B,UAAU,EAAE,KAAK,CAAC;IAChB,SAAS,EAAE;QAAE,EAAE,EAAE,gBAAgB,CAAC,IAAI,CAAC,CAAC;QAAC,SAAS,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAC/D,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC,GACD,KAAK,CAAC;IAAE,EAAE,EAAE,gBAAgB,CAAC,IAAI,CAAC,CAAC;IAAC,SAAS,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAW5D"}
@@ -0,0 +1,166 @@
1
+ import crypto from 'crypto';
2
+ import { GENERAL_PLATFORM, SHARED_PLATFORM } from '../platform.js';
3
+ import { isPathInsideStore } from './meter.js';
4
+ import { createSpaceAmount } from './types.js';
5
+ function sameCommit(commit, id) {
6
+ return commit.id.libName === id.libName && commit.id.commit === id.commit;
7
+ }
8
+ function combineAmounts(amounts) {
9
+ const bytes = amounts.reduce((sum, amount) => sum + amount.bytes, 0);
10
+ const quality = amounts.some((amount) => amount.quality === 'partial')
11
+ ? 'partial'
12
+ : amounts.some((amount) => amount.quality !== 'exact')
13
+ ? 'approximate'
14
+ : 'exact';
15
+ const basis = amounts.every((amount) => amount.basis === 'allocated') ? 'allocated' : 'logical';
16
+ return createSpaceAmount(bytes, basis, quality);
17
+ }
18
+ function selectedPlatformSegments(commit, platforms) {
19
+ if (commit.layout === 'general') {
20
+ return platforms === 'all' || platforms.includes(GENERAL_PLATFORM)
21
+ ? commit.segments.filter((segment) => segment.kind === 'shared')
22
+ : [];
23
+ }
24
+ const platformSet = platforms === 'all' ? null : new Set(platforms);
25
+ return commit.segments.filter((segment) => segment.kind === 'platform' && (!platformSet || platformSet.has(segment.platform)));
26
+ }
27
+ function validateUnreferenced(segments) {
28
+ const referenced = segments.filter((segment) => segment.projectRefs.length > 0);
29
+ if (referenced.length > 0) {
30
+ const names = referenced.map((segment) => segment.platform ?? SHARED_PLATFORM).join(', ');
31
+ throw new Error(`清理目标仍被项目引用: ${names}`);
32
+ }
33
+ }
34
+ function buildCommitGroup(snapshot, commit, requireUnreferenced) {
35
+ if (!isPathInsideStore(snapshot.storePath, commit.commitPath)) {
36
+ throw new Error(`清理目标超出 Store 目录: ${commit.commitPath}`);
37
+ }
38
+ const expectedRelease = commit.measured ?? createSpaceAmount(0, 'recorded', 'partial', '目标版本未测量');
39
+ return {
40
+ id: commit.id,
41
+ deleteKind: commit.measured?.reason === '目录不存在' ? 'registry-only' : 'commit',
42
+ ...(commit.measured?.reason === '目录不存在' ? {} : { targetPath: commit.commitPath }),
43
+ storeKeys: commit.segments.flatMap((segment) => segment.registryKeys),
44
+ libraryKey: `${commit.id.libName}:${commit.id.commit}`,
45
+ expectedRelease,
46
+ requireUnreferenced,
47
+ preconditions: [
48
+ { kind: 'inside-store', description: '目标必须位于当前 Store 目录内' },
49
+ { kind: 'snapshot-path', description: '执行时目标目录必须与计划一致' },
50
+ ...(requireUnreferenced
51
+ ? [{ kind: 'unreferenced', description: '执行时仍需保持无引用' }]
52
+ : []),
53
+ ],
54
+ };
55
+ }
56
+ function buildSegmentGroup(snapshot, commit, segment, requireUnreferenced) {
57
+ if (!isPathInsideStore(snapshot.storePath, segment.physicalPath)) {
58
+ throw new Error(`清理目标超出 Store 目录: ${segment.physicalPath}`);
59
+ }
60
+ return {
61
+ id: commit.id,
62
+ deleteKind: segment.measured?.reason === '目录不存在'
63
+ ? 'registry-only'
64
+ : segment.kind === 'shared'
65
+ ? 'shared'
66
+ : 'platform',
67
+ platform: segment.kind === 'shared'
68
+ ? commit.layout === 'general'
69
+ ? GENERAL_PLATFORM
70
+ : SHARED_PLATFORM
71
+ : segment.platform,
72
+ ...(segment.measured?.reason === '目录不存在' ? {} : { targetPath: segment.physicalPath }),
73
+ storeKeys: segment.registryKeys,
74
+ expectedRelease: segment.measured ?? createSpaceAmount(0, 'recorded', 'partial', '目标平台未测量'),
75
+ requireUnreferenced,
76
+ preconditions: [
77
+ { kind: 'inside-store', description: '目标必须位于当前 Store 目录内' },
78
+ { kind: 'snapshot-path', description: '执行时目标目录必须与计划一致' },
79
+ ...(requireUnreferenced
80
+ ? [{ kind: 'unreferenced', description: '执行时仍需保持无引用' }]
81
+ : []),
82
+ ],
83
+ };
84
+ }
85
+ export function buildCleanupPlan(request, snapshot) {
86
+ if (snapshot.mode !== 'targeted' && snapshot.mode !== 'audit') {
87
+ throw new Error('清理计划需要 targeted 或 audit 空间快照');
88
+ }
89
+ const groups = [];
90
+ const warnings = [];
91
+ for (const selection of request.selections) {
92
+ const commit = snapshot.commits.find((item) => sameCommit(item, selection.id));
93
+ if (!commit)
94
+ throw new Error(`找不到清理目标: ${selection.id.libName}/${selection.id.commit}`);
95
+ if (commit.segments.length === 0) {
96
+ if (commit.unknownChildren.length > 0 && !request.allowUnknownContent) {
97
+ warnings.push(`${commit.id.libName}/${commit.id.commit.slice(0, 8)} 只有未登记内容,自动清理已跳过`);
98
+ continue;
99
+ }
100
+ groups.push(buildCommitGroup(snapshot, commit, request.requireUnreferenced));
101
+ continue;
102
+ }
103
+ const selected = selectedPlatformSegments(commit, selection.platforms);
104
+ if (selected.length === 0 && commit.segments.length > 0)
105
+ continue;
106
+ const platformSegments = commit.segments.filter((segment) => segment.kind === 'platform');
107
+ const selectsWholeCommit = commit.layout === 'general' ||
108
+ (platformSegments.length > 0 && selected.length === platformSegments.length);
109
+ if (selection.includeShared && !selectsWholeCommit) {
110
+ throw new Error('shared 段只能与整版本平台选择一起清理');
111
+ }
112
+ const sharedSegment = commit.segments.find((segment) => segment.kind === 'shared');
113
+ const requestedSegments = [...selected];
114
+ if (selection.includeShared && sharedSegment && !requestedSegments.includes(sharedSegment)) {
115
+ requestedSegments.push(sharedSegment);
116
+ }
117
+ if (request.requireUnreferenced)
118
+ validateUnreferenced(requestedSegments);
119
+ if (selectsWholeCommit &&
120
+ commit.unknownChildren.length === 0 &&
121
+ !request.preservePlatformBoundaries) {
122
+ groups.push(buildCommitGroup(snapshot, commit, request.requireUnreferenced));
123
+ continue;
124
+ }
125
+ if (selectsWholeCommit && commit.unknownChildren.length > 0) {
126
+ warnings.push(`${commit.id.libName}/${commit.id.commit.slice(0, 8)} 包含未登记内容,保留 shared 与未知内容`);
127
+ if (request.allowUnknownContent && !request.preservePlatformBoundaries) {
128
+ groups.push(buildCommitGroup(snapshot, commit, request.requireUnreferenced));
129
+ continue;
130
+ }
131
+ }
132
+ const segmentGroups = requestedSegments.map((segment) => buildSegmentGroup(snapshot, commit, segment, request.requireUnreferenced));
133
+ const removesAllKnownSegments = requestedSegments.length === commit.segments.length &&
134
+ commit.segments.every((segment) => requestedSegments.includes(segment));
135
+ if (removesAllKnownSegments &&
136
+ segmentGroups.length > 0 &&
137
+ !request.preservePlatformBoundaries) {
138
+ segmentGroups[segmentGroups.length - 1].libraryKey =
139
+ `${commit.id.libName}:${commit.id.commit}`;
140
+ }
141
+ groups.push(...segmentGroups);
142
+ }
143
+ return {
144
+ id: crypto.randomBytes(8).toString('hex'),
145
+ storePath: snapshot.storePath,
146
+ reason: request.reason,
147
+ createdAt: Date.now(),
148
+ groups,
149
+ expectedRelease: combineAmounts(groups.map((group) => group.expectedRelease)),
150
+ warnings,
151
+ };
152
+ }
153
+ export function selectHalfByAge(candidates) {
154
+ const target = candidates.reduce((sum, item) => sum + item.bytes, 0) / 2;
155
+ const sorted = [...candidates].sort((a, b) => a.timestamp - b.timestamp);
156
+ const selected = [];
157
+ let accumulated = 0;
158
+ for (const candidate of sorted) {
159
+ selected.push(candidate.selection);
160
+ accumulated += candidate.bytes;
161
+ if (accumulated >= target)
162
+ break;
163
+ }
164
+ return selected;
165
+ }
166
+ //# sourceMappingURL=cleanup-planner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cleanup-planner.js","sourceRoot":"","sources":["../../../src/core/space/cleanup-planner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { CleanupCandidate, CleanupSelection } from './types.js';
2
+ interface CleanupSelectionSummary {
3
+ selections: CleanupSelection[];
4
+ registeredBytes: number;
5
+ platformCount: number;
6
+ }
7
+ export declare function buildUnreferencedSelectionSummary(candidates: CleanupCandidate[]): CleanupSelectionSummary;
8
+ export declare function buildHalfCleanupSelectionSummary(candidates: CleanupCandidate[]): CleanupSelectionSummary;
9
+ export {};
10
+ //# sourceMappingURL=cleanup-selection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cleanup-selection.d.ts","sourceRoot":"","sources":["../../../src/core/space/cleanup-selection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAA4B,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE/F,UAAU,uBAAuB;IAC/B,UAAU,EAAE,gBAAgB,EAAE,CAAC;IAC/B,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;CACvB;AAyCD,wBAAgB,iCAAiC,CAC/C,UAAU,EAAE,gBAAgB,EAAE,GAC7B,uBAAuB,CAoBzB;AAWD,wBAAgB,gCAAgC,CAC9C,UAAU,EAAE,gBAAgB,EAAE,GAC7B,uBAAuB,CAyBzB"}
@@ -0,0 +1,84 @@
1
+ function keyOf(candidate) {
2
+ return JSON.stringify([candidate.id.libName, candidate.id.commit]);
3
+ }
4
+ function toSelections(candidates, selected) {
5
+ return candidates.flatMap((candidate) => {
6
+ const platforms = selected.get(keyOf(candidate));
7
+ if (!platforms || platforms.size === 0)
8
+ return [];
9
+ return [
10
+ {
11
+ id: candidate.id,
12
+ platforms: platforms.size === candidate.platforms.length ? 'all' : [...platforms],
13
+ },
14
+ ];
15
+ });
16
+ }
17
+ function reclaimableBytesForSelection(candidate, selectedPlatforms) {
18
+ const selected = candidate.platforms.filter((platform) => selectedPlatforms.has(platform.platform));
19
+ let bytes = selected.reduce((sum, platform) => sum + platform.registeredBytes, 0);
20
+ const allPlatformsSelected = selected.length === candidate.platforms.length;
21
+ const allPlatformsUnreferenced = candidate.platforms.every((platform) => platform.referencedBy.length === 0);
22
+ if (candidate.layout !== 'general' && allPlatformsSelected && allPlatformsUnreferenced) {
23
+ bytes += candidate.sharedBytes;
24
+ }
25
+ return bytes;
26
+ }
27
+ export function buildUnreferencedSelectionSummary(candidates) {
28
+ const selected = new Map();
29
+ let platformCount = 0;
30
+ let registeredBytes = 0;
31
+ for (const candidate of candidates) {
32
+ const platforms = candidate.platforms.filter((platform) => platform.referencedBy.length === 0);
33
+ if (platforms.length === 0)
34
+ continue;
35
+ const platformSet = new Set(platforms.map((platform) => platform.platform));
36
+ selected.set(keyOf(candidate), platformSet);
37
+ platformCount += platforms.length;
38
+ registeredBytes += reclaimableBytesForSelection(candidate, platformSet);
39
+ }
40
+ const selections = toSelections(candidates, selected);
41
+ for (const candidate of candidates) {
42
+ // LibraryInfo 仍存在而 StoreEntry 和磁盘内容均缺失时,保留登记清理能力。
43
+ if (candidate.platforms.length === 0 && candidate.libraryRecordPresent) {
44
+ selections.push({ id: candidate.id, platforms: 'all' });
45
+ }
46
+ }
47
+ return { selections, registeredBytes, platformCount };
48
+ }
49
+ function ageOf(platform) {
50
+ if (platform.unlinkedAt != null)
51
+ return platform.unlinkedAt;
52
+ if (platform.createdAt) {
53
+ const value = new Date(platform.createdAt).getTime();
54
+ if (Number.isFinite(value))
55
+ return value;
56
+ }
57
+ return Number.POSITIVE_INFINITY;
58
+ }
59
+ export function buildHalfCleanupSelectionSummary(candidates) {
60
+ const full = buildUnreferencedSelectionSummary(candidates);
61
+ const target = full.registeredBytes / 2;
62
+ const items = candidates
63
+ .flatMap((candidate) => candidate.platforms
64
+ .filter((platform) => platform.referencedBy.length === 0)
65
+ .map((platform) => ({ candidate, platform, timestamp: ageOf(platform) })))
66
+ .sort((left, right) => left.timestamp - right.timestamp);
67
+ const selected = new Map();
68
+ let registeredBytes = 0;
69
+ let platformCount = 0;
70
+ for (const item of items) {
71
+ const key = keyOf(item.candidate);
72
+ const platforms = selected.get(key) ?? new Set();
73
+ const before = reclaimableBytesForSelection(item.candidate, platforms);
74
+ platforms.add(item.platform.platform);
75
+ selected.set(key, platforms);
76
+ const after = reclaimableBytesForSelection(item.candidate, platforms);
77
+ registeredBytes += after - before;
78
+ platformCount++;
79
+ if (registeredBytes >= target)
80
+ break;
81
+ }
82
+ return { selections: toSelections(candidates, selected), registeredBytes, platformCount };
83
+ }
84
+ //# sourceMappingURL=cleanup-selection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cleanup-selection.js","sourceRoot":"","sources":["../../../src/core/space/cleanup-selection.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type RegistryManager from '../registry.js';
2
+ import type { SpaceEstimate } from './types.js';
3
+ export interface DownloadSpaceRequest {
4
+ libName: string;
5
+ commit: string;
6
+ platforms: string[];
7
+ }
8
+ export declare function estimateDownloadSpace(registry: RegistryManager, requests: DownloadSpaceRequest[]): SpaceEstimate;
9
+ /** 按迁移复制规则估算目标空间:普通文件计长度,符号链接计链接本身。 */
10
+ export declare function estimateMigrationSpace(sourcePath: string): Promise<SpaceEstimate>;
11
+ //# sourceMappingURL=estimator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"estimator.d.ts","sourceRoot":"","sources":["../../../src/core/space/estimator.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,eAAe,MAAM,gBAAgB,CAAC;AAGlD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAqBD,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,eAAe,EACzB,QAAQ,EAAE,oBAAoB,EAAE,GAC/B,aAAa,CAwEf;AAED,uCAAuC;AACvC,wBAAsB,sBAAsB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CA8DvF"}
@@ -0,0 +1,142 @@
1
+ import fs from 'fs/promises';
2
+ import path from 'path';
3
+ import { GENERAL_PLATFORM, SHARED_PLATFORM } from '../platform.js';
4
+ import { createSpaceAmount } from './types.js';
5
+ import { measureDirectory } from './meter.js';
6
+ function largestEntrySize(entries) {
7
+ if (entries.length === 0)
8
+ return undefined;
9
+ return Math.max(...entries.map((entry) => entry.size));
10
+ }
11
+ function mergeDownloadRequests(requests) {
12
+ const merged = new Map();
13
+ for (const request of requests) {
14
+ const key = JSON.stringify([request.libName, request.commit]);
15
+ const existing = merged.get(key);
16
+ if (!existing) {
17
+ merged.set(key, { ...request, platforms: [...new Set(request.platforms)] });
18
+ continue;
19
+ }
20
+ existing.platforms = [...new Set([...existing.platforms, ...request.platforms])];
21
+ }
22
+ return [...merged.values()];
23
+ }
24
+ export function estimateDownloadSpace(registry, requests) {
25
+ const stores = registry.listStores();
26
+ const evidence = [];
27
+ const warnings = [];
28
+ let total = 0;
29
+ for (const request of mergeDownloadRequests(requests)) {
30
+ const libraryEntries = stores.filter((entry) => entry.libName === request.libName);
31
+ const exactCommit = libraryEntries.filter((entry) => entry.commit === request.commit);
32
+ const exactGeneral = largestEntrySize(exactCommit.filter((entry) => entry.platform === GENERAL_PLATFORM));
33
+ if (exactGeneral != null) {
34
+ total += exactGeneral;
35
+ evidence.push(`${request.libName}@${request.commit.slice(0, 8)} 使用同版本 General 登记容量 ${exactGeneral}`);
36
+ continue;
37
+ }
38
+ const historicalGeneral = largestEntrySize(libraryEntries.filter((entry) => entry.platform === GENERAL_PLATFORM));
39
+ const exactPlatformSizes = request.platforms.map((platform) => ({
40
+ platform,
41
+ bytes: largestEntrySize(exactCommit.filter((entry) => entry.platform === platform)),
42
+ }));
43
+ const canUseExactPlatforms = exactPlatformSizes.every((item) => item.bytes != null);
44
+ if (!canUseExactPlatforms && historicalGeneral != null) {
45
+ total += historicalGeneral;
46
+ evidence.push(`${request.libName} 使用历史 General 最大登记容量 ${historicalGeneral}`);
47
+ continue;
48
+ }
49
+ let requestTotal = 0;
50
+ let complete = true;
51
+ for (const item of exactPlatformSizes) {
52
+ const historicalSize = largestEntrySize(libraryEntries.filter((entry) => entry.platform === item.platform));
53
+ const bytes = item.bytes ?? historicalSize;
54
+ if (bytes == null) {
55
+ warnings.push(`${request.libName}@${request.commit.slice(0, 8)}/${item.platform} 没有可用的历史容量`);
56
+ complete = false;
57
+ continue;
58
+ }
59
+ requestTotal += bytes;
60
+ evidence.push(`${request.libName}/${item.platform} 使用${item.bytes != null ? '同版本' : '历史最大'}登记容量 ${bytes}`);
61
+ }
62
+ const sharedBytes = largestEntrySize(exactCommit.filter((entry) => entry.platform === SHARED_PLATFORM)) ??
63
+ largestEntrySize(libraryEntries.filter((entry) => entry.platform === SHARED_PLATFORM));
64
+ if (sharedBytes != null) {
65
+ requestTotal += sharedBytes;
66
+ evidence.push(`${request.libName}/_shared 使用登记容量 ${sharedBytes}`);
67
+ }
68
+ if (complete)
69
+ total += requestTotal;
70
+ }
71
+ if (warnings.length > 0) {
72
+ return { status: 'unknown', evidence, warnings };
73
+ }
74
+ return {
75
+ status: 'available',
76
+ amount: createSpaceAmount(total, 'estimated', 'approximate'),
77
+ evidence,
78
+ warnings,
79
+ };
80
+ }
81
+ /** 按迁移复制规则估算目标空间:普通文件计长度,符号链接计链接本身。 */
82
+ export async function estimateMigrationSpace(sourcePath) {
83
+ const amount = await measureDirectory(sourcePath, {
84
+ preferredBasis: 'logical',
85
+ symlinkPolicy: 'preserve',
86
+ });
87
+ if (amount.quality === 'partial') {
88
+ return {
89
+ status: 'unknown',
90
+ evidence: [],
91
+ warnings: [amount.reason ?? `无法测量迁移源目录: ${sourcePath}`],
92
+ };
93
+ }
94
+ let internalAbsoluteLinks = 0;
95
+ let externalAbsoluteLinks = 0;
96
+ let relativeLinks = 0;
97
+ try {
98
+ async function inspect(currentPath) {
99
+ const stat = await fs.lstat(currentPath);
100
+ if (stat.isSymbolicLink()) {
101
+ const target = await fs.readlink(currentPath);
102
+ if (!path.isAbsolute(target)) {
103
+ relativeLinks++;
104
+ return;
105
+ }
106
+ const relative = path.relative(path.resolve(sourcePath), path.resolve(target));
107
+ const internal = relative === '' || (!relative.startsWith('..') && !path.isAbsolute(relative));
108
+ if (internal)
109
+ internalAbsoluteLinks++;
110
+ else
111
+ externalAbsoluteLinks++;
112
+ return;
113
+ }
114
+ if (!stat.isDirectory())
115
+ return;
116
+ for (const name of await fs.readdir(currentPath)) {
117
+ await inspect(path.join(currentPath, name));
118
+ }
119
+ }
120
+ await inspect(sourcePath);
121
+ }
122
+ catch (err) {
123
+ return {
124
+ status: 'unknown',
125
+ evidence: [],
126
+ warnings: [`无法检查迁移符号链接: ${err.message}`],
127
+ };
128
+ }
129
+ const warnings = externalAbsoluteLinks > 0
130
+ ? [`发现 ${externalAbsoluteLinks} 个指向 Store 外部的绝对符号链接,迁移时保留原目标`]
131
+ : [];
132
+ return {
133
+ status: 'available',
134
+ amount: createSpaceAmount(amount.bytes, 'estimated', amount.quality, '按保留符号链接的复制规则估算'),
135
+ evidence: [
136
+ `迁移源目录按保留符号链接规则测得 ${amount.bytes} 字节`,
137
+ `符号链接: 内部绝对 ${internalAbsoluteLinks},外部绝对 ${externalAbsoluteLinks},相对 ${relativeLinks}`,
138
+ ],
139
+ warnings,
140
+ };
141
+ }
142
+ //# sourceMappingURL=estimator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"estimator.js","sourceRoot":"","sources":["../../../src/core/space/estimator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import type RegistryManager from '../registry.js';
2
+ import type { CleanupCandidate, ProjectSpaceReport, SharingSpaceReport, StoreCommitId, StoreSegmentSpace, StoreSpaceSnapshot } from './types.js';
3
+ /**
4
+ * 在删除动作内部重新核对一个未登记平台。该检查只测量目标目录,避免每个删除组
5
+ * 重复测量整个 Store,同时复用项目依赖和符号链接的引用识别规则。
6
+ */
7
+ export declare function revalidateUnregisteredPlatform(registry: RegistryManager, storePath: string, id: StoreCommitId, platform: string): Promise<StoreSegmentSpace | undefined>;
8
+ export declare function buildStoreSpaceSnapshot(registry: RegistryManager, storePath: string, options: {
9
+ mode: 'summary' | 'targeted' | 'audit';
10
+ targets?: StoreCommitId[];
11
+ }): Promise<StoreSpaceSnapshot>;
12
+ export declare function buildCleanupCandidates(snapshot: StoreSpaceSnapshot): CleanupCandidate[];
13
+ export declare function buildProjectSpaceReport(registry: RegistryManager, snapshot: StoreSpaceSnapshot, projectHash: string): ProjectSpaceReport;
14
+ export declare function buildSharingSpaceReport(snapshot: StoreSpaceSnapshot): SharingSpaceReport;
15
+ //# sourceMappingURL=inventory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inventory.d.ts","sourceRoot":"","sources":["../../../src/core/space/inventory.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,eAAe,MAAM,gBAAgB,CAAC;AAGlD,OAAO,KAAK,EACV,gBAAgB,EAChB,kBAAkB,EAClB,kBAAkB,EAGlB,aAAa,EAEb,iBAAiB,EACjB,kBAAkB,EACnB,MAAM,YAAY,CAAC;AA8bpB;;;GAGG;AACH,wBAAsB,8BAA8B,CAClD,QAAQ,EAAE,eAAe,EACzB,SAAS,EAAE,MAAM,EACjB,EAAE,EAAE,aAAa,EACjB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,iBAAiB,GAAG,SAAS,CAAC,CAuCxC;AAiCD,wBAAsB,uBAAuB,CAC3C,QAAQ,EAAE,eAAe,EACzB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE;IAAE,IAAI,EAAE,SAAS,GAAG,UAAU,GAAG,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,aAAa,EAAE,CAAA;CAAE,GAC7E,OAAO,CAAC,kBAAkB,CAAC,CAyE7B;AAED,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,kBAAkB,GAAG,gBAAgB,EAAE,CAyBvF;AAED,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,eAAe,EACzB,QAAQ,EAAE,kBAAkB,EAC5B,WAAW,EAAE,MAAM,GAClB,kBAAkB,CAyCpB;AAED,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,kBAAkB,GAAG,kBAAkB,CAgBxF"}