lody 0.63.1 → 0.63.3
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.
|
@@ -3,8 +3,8 @@ import { readFile, mkdir, writeFile, rename } from "node:fs/promises";
|
|
|
3
3
|
import os__default from "node:os";
|
|
4
4
|
import path__default from "node:path";
|
|
5
5
|
import process from "node:process";
|
|
6
|
-
const reviewViewerVersion = "0.63.
|
|
7
|
-
const reviewViewerSha256 = "
|
|
6
|
+
const reviewViewerVersion = "0.63.3";
|
|
7
|
+
const reviewViewerSha256 = "50ab599b652bdf4b959b539ea948454dd588703039bd4c5c037c7877ce10696f";
|
|
8
8
|
const reviewViewerFileName = "standalone.html";
|
|
9
9
|
const DEFAULT_CDN_BASES = ["https://cdn.jsdelivr.net/npm", "https://unpkg.com"];
|
|
10
10
|
function cacheDir() {
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import { opendir } from "node:fs/promises";
|
|
2
|
+
import path__default from "node:path";
|
|
3
|
+
import { H as buildCodeCollabFileIndexState, J as scanGitDirectoryEntries, a3 as joinWorkspacePath, a4 as isInsideGitWorktree, G as computeAllChanges, a5 as pathSegmentComparisonKey, K as closeDirectoryQuietly } from "./chunks/directory-handle-CaB_XCLI.js";
|
|
4
|
+
import "node:child_process";
|
|
5
|
+
import "node:util";
|
|
6
|
+
import "./chunks/diff-line-counts-BLxwWP6r.js";
|
|
7
|
+
import "node:fs";
|
|
8
|
+
import "node:os";
|
|
9
|
+
const DEFAULT_IGNORED_DIRECTORY_NAMES = /* @__PURE__ */ new Set([
|
|
10
|
+
".git",
|
|
11
|
+
"node_modules",
|
|
12
|
+
".next",
|
|
13
|
+
"dist",
|
|
14
|
+
"build",
|
|
15
|
+
"target"
|
|
16
|
+
]);
|
|
17
|
+
async function fileIndexScanWorker(input) {
|
|
18
|
+
if (input.kind === "full-state") {
|
|
19
|
+
return await computeFullFileIndexState(input);
|
|
20
|
+
}
|
|
21
|
+
const entries = await scanDirectoryEntries(input);
|
|
22
|
+
return { kind: "scan", entries: [...entries] };
|
|
23
|
+
}
|
|
24
|
+
async function computeFullFileIndexState(input) {
|
|
25
|
+
const startedAtMs = Date.now();
|
|
26
|
+
const allChangesResult = await resolveFullStateAllChanges(input);
|
|
27
|
+
if (allChangesResult.status !== "ok") {
|
|
28
|
+
return {
|
|
29
|
+
kind: "full-state",
|
|
30
|
+
status: "needs-provided-all-changes",
|
|
31
|
+
reason: allChangesResult.reason
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
const scanStartedAtMs = Date.now();
|
|
35
|
+
const fileTreeEntries = await scanDirectoryEntries({
|
|
36
|
+
directoryAbsolutePath: input.workspaceRoot,
|
|
37
|
+
directoryWorkspacePath: "",
|
|
38
|
+
maxRawTextBytes: input.maxRawTextBytes,
|
|
39
|
+
entryBudget: input.entryBudget,
|
|
40
|
+
recursive: true
|
|
41
|
+
});
|
|
42
|
+
const scanMs = Date.now() - scanStartedAtMs;
|
|
43
|
+
const fileTree = Object.fromEntries(fileTreeEntries);
|
|
44
|
+
const buildStartedAtMs = Date.now();
|
|
45
|
+
const fileIndex = buildCodeCollabFileIndexState(fileTree, allChangesResult.allChanges);
|
|
46
|
+
const buildMs = Date.now() - buildStartedAtMs;
|
|
47
|
+
return {
|
|
48
|
+
kind: "full-state",
|
|
49
|
+
status: "ok",
|
|
50
|
+
fileTreeEntries: [...fileTreeEntries],
|
|
51
|
+
allChanges: allChangesResult.allChanges,
|
|
52
|
+
fileIndex,
|
|
53
|
+
allChangesSource: allChangesResult.source,
|
|
54
|
+
changedPaths: Object.keys(allChangesResult.allChanges).length,
|
|
55
|
+
pathCount: Object.keys(fileIndex).length,
|
|
56
|
+
durationMs: Date.now() - startedAtMs,
|
|
57
|
+
scanMs,
|
|
58
|
+
allChangesMs: allChangesResult.allChangesMs,
|
|
59
|
+
buildMs
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
async function resolveFullStateAllChanges(input) {
|
|
63
|
+
if (input.providedAllChanges) {
|
|
64
|
+
return {
|
|
65
|
+
status: "ok",
|
|
66
|
+
source: input.providedAllChanges.source,
|
|
67
|
+
allChanges: input.providedAllChanges.state,
|
|
68
|
+
allChangesMs: input.providedAllChanges.computeMs
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
if (!await isInsideGitWorktree(input.workspaceRoot)) {
|
|
72
|
+
return { status: "needs-provided-all-changes", reason: "not-git" };
|
|
73
|
+
}
|
|
74
|
+
const allChangesStartedAtMs = Date.now();
|
|
75
|
+
const allChanges = await computeAllChanges(input.workspaceRoot, {
|
|
76
|
+
preferredBaseBranch: input.preferredBaseBranch
|
|
77
|
+
});
|
|
78
|
+
return {
|
|
79
|
+
status: "ok",
|
|
80
|
+
source: "git",
|
|
81
|
+
allChanges,
|
|
82
|
+
allChangesMs: Date.now() - allChangesStartedAtMs
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
async function scanDirectoryEntries(options) {
|
|
86
|
+
const gitEntries = await scanGitDirectoryEntries(options);
|
|
87
|
+
if (gitEntries) {
|
|
88
|
+
return gitEntries;
|
|
89
|
+
}
|
|
90
|
+
const entries = /* @__PURE__ */ new Map();
|
|
91
|
+
const queue = [
|
|
92
|
+
{
|
|
93
|
+
absolutePath: options.directoryAbsolutePath,
|
|
94
|
+
workspacePath: options.directoryWorkspacePath
|
|
95
|
+
}
|
|
96
|
+
];
|
|
97
|
+
let remainingEntries = Math.max(0, options.entryBudget);
|
|
98
|
+
while (queue.length > 0 && remainingEntries > 0) {
|
|
99
|
+
const currentDirectory = queue.shift();
|
|
100
|
+
if (!currentDirectory) {
|
|
101
|
+
break;
|
|
102
|
+
}
|
|
103
|
+
const directoryEntries = await readDirectoryEntriesForScan(currentDirectory).catch(
|
|
104
|
+
(error) => {
|
|
105
|
+
if (currentDirectory.workspacePath === options.directoryWorkspacePath) {
|
|
106
|
+
throw error;
|
|
107
|
+
}
|
|
108
|
+
entries.set(currentDirectory.workspacePath, scanDirectoryReadErrorValue(error));
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
);
|
|
112
|
+
if (!directoryEntries) {
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
const collisionKeys = findDirectoryEntryCollisionKeys(directoryEntries);
|
|
116
|
+
for (const { entry, comparisonKey } of directoryEntries) {
|
|
117
|
+
if (remainingEntries <= 0) {
|
|
118
|
+
break;
|
|
119
|
+
}
|
|
120
|
+
const workspacePath = joinWorkspacePath(currentDirectory.workspacePath, entry.name);
|
|
121
|
+
const absolutePath = path__default.join(currentDirectory.absolutePath, entry.name);
|
|
122
|
+
const value = collisionKeys.has(comparisonKey) ? { kind: "skipped", reason: "path_conflict" } : classifyDirectoryEntry(entry);
|
|
123
|
+
if (value === void 0) {
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
entries.set(workspacePath, value);
|
|
127
|
+
remainingEntries -= 1;
|
|
128
|
+
if (options.recursive && isLazyDirectoryValue(value) && remainingEntries > 0) {
|
|
129
|
+
queue.push({ absolutePath, workspacePath });
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return entries;
|
|
134
|
+
}
|
|
135
|
+
function scanDirectoryReadErrorValue(error) {
|
|
136
|
+
const code = errorCode(error);
|
|
137
|
+
if (code === "EACCES" || code === "EPERM") {
|
|
138
|
+
return { kind: "skipped", reason: "permission_denied" };
|
|
139
|
+
}
|
|
140
|
+
if (code === "ENOENT" || code === "ENOTDIR") {
|
|
141
|
+
return { kind: "skipped", reason: "not_found" };
|
|
142
|
+
}
|
|
143
|
+
return { kind: "skipped", reason: "transient_io" };
|
|
144
|
+
}
|
|
145
|
+
function errorCode(error) {
|
|
146
|
+
if (!error || typeof error !== "object" || !("code" in error)) {
|
|
147
|
+
return void 0;
|
|
148
|
+
}
|
|
149
|
+
const code = error.code;
|
|
150
|
+
return typeof code === "string" ? code : void 0;
|
|
151
|
+
}
|
|
152
|
+
async function readDirectoryEntriesForScan(directoryPath) {
|
|
153
|
+
const directory = await opendir(directoryPath.absolutePath);
|
|
154
|
+
try {
|
|
155
|
+
const directoryEntries = [];
|
|
156
|
+
for await (const entry of directory) {
|
|
157
|
+
if (entry.name === "." || entry.name === "..") {
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
directoryEntries.push({
|
|
161
|
+
entry,
|
|
162
|
+
comparisonKey: pathSegmentComparisonKey(entry.name)
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
return directoryEntries.sort((left, right) => {
|
|
166
|
+
const keyOrder = left.comparisonKey.localeCompare(right.comparisonKey);
|
|
167
|
+
return keyOrder === 0 ? left.entry.name.localeCompare(right.entry.name) : keyOrder;
|
|
168
|
+
});
|
|
169
|
+
} finally {
|
|
170
|
+
await closeDirectoryQuietly(directory);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
function classifyDirectoryEntry(entry) {
|
|
174
|
+
if (entry.isDirectory()) {
|
|
175
|
+
return DEFAULT_IGNORED_DIRECTORY_NAMES.has(entry.name) ? void 0 : { kind: "lazy" };
|
|
176
|
+
}
|
|
177
|
+
if (entry.isSymbolicLink()) {
|
|
178
|
+
return { kind: "skipped", reason: "symlink" };
|
|
179
|
+
}
|
|
180
|
+
if (!entry.isFile()) {
|
|
181
|
+
return { kind: "skipped", reason: "special" };
|
|
182
|
+
}
|
|
183
|
+
return true;
|
|
184
|
+
}
|
|
185
|
+
function findDirectoryEntryCollisionKeys(entries) {
|
|
186
|
+
const namesByKey = /* @__PURE__ */ new Map();
|
|
187
|
+
for (const { entry, comparisonKey } of entries) {
|
|
188
|
+
const names = namesByKey.get(comparisonKey);
|
|
189
|
+
if (names) {
|
|
190
|
+
names.add(entry.name);
|
|
191
|
+
} else {
|
|
192
|
+
namesByKey.set(comparisonKey, /* @__PURE__ */ new Set([entry.name]));
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
const collisionKeys = /* @__PURE__ */ new Set();
|
|
196
|
+
for (const [comparisonKey, names] of namesByKey) {
|
|
197
|
+
if (names.size > 1) {
|
|
198
|
+
collisionKeys.add(comparisonKey);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
return collisionKeys;
|
|
202
|
+
}
|
|
203
|
+
function isLazyDirectoryValue(value) {
|
|
204
|
+
return value !== void 0 && value !== true && value.kind === "lazy";
|
|
205
|
+
}
|
|
206
|
+
export {
|
|
207
|
+
fileIndexScanWorker as default
|
|
208
|
+
};
|