mirror of
https://github.com/getpaseo/paseo.git
synced 2026-10-27 11:42:52 +00:00
* perf(app): optimize wrapped measurements and checkpoint native layout experiment Compute full grapheme geometry only for final wrap fragments. Preserve shaped-text search behavior while bounding additive wrap probes. Keep the Android background layout experiment isolated from the normal diff renderer; native renderer integration and iOS bindings remain unfinished. * perf(server): reduce cold diff generation work Keep active diff reads owned across invalidation and wait for the initial watcher inventory before cold generation. Batch patch and blob reads while preserving per-file size isolation, bounded output, and daemon responsiveness. Avoid constructing fallback tokens when full-file highlighting already covers both sides. * test(server): exercise oversized highlighted diff rejection The single-line fixture now bypasses highlighting under the long-line guard, so it no longer reaches the structured payload limit. Use short dense lines to keep testing oversized rejection and continued socket usability. * fix(server): queue fresh diffs for forced reads A forced request following a repository mutation must not reuse an older active build. Invalidate that result and coalesce waiting callers onto one subsequent build. Give the cache a named object input and completed-value type. * test(server): share deferred diff loader setup * test(server): name completed diff cache setup * refactor(server): use aliases for new diff imports * fix(server): keep shipped diff imports resolvable by Node The TypeScript build preserves path aliases without a runtime resolver. Restore relative imports for shipped code and declarations, and correct the server import guideline that prompted the regression.
49 lines
1.8 KiB
TypeScript
49 lines
1.8 KiB
TypeScript
import { runGitCommandBytes } from "./run-git-command.js";
|
|
|
|
// Match the existing git-show ceiling. Oversized batches use bounded per-file reads.
|
|
const MAX_CONTENT_BYTES = 20 * 1024 * 1024;
|
|
|
|
/** Null means the batch cannot preserve per-file read semantics within its budget. */
|
|
export async function readGitFileContents(
|
|
cwd: string,
|
|
specs: string[],
|
|
): Promise<Map<string, string | null> | null> {
|
|
const unique = [...new Set(specs)];
|
|
if (unique.length === 0) return new Map();
|
|
// The line-based batch protocol cannot represent embedded newlines.
|
|
if (unique.some((spec) => spec.includes("\n"))) return null;
|
|
const result = await runGitCommandBytes(["cat-file", "--batch"], {
|
|
cwd,
|
|
input: unique.join("\n") + "\n",
|
|
envOverlay: { GIT_OPTIONAL_LOCKS: "0", LC_ALL: "C" },
|
|
maxOutputBytes: MAX_CONTENT_BYTES,
|
|
});
|
|
if (result.truncated) return null;
|
|
const contents = new Map<string, string | null>();
|
|
let offset = 0;
|
|
for (const spec of unique) {
|
|
const end = result.stdout.indexOf(10, offset);
|
|
if (end < 0) throw new Error("Incomplete git object header");
|
|
const header = result.stdout.subarray(offset, end).toString("utf8");
|
|
offset = end + 1;
|
|
if (header === `${spec} missing`) {
|
|
contents.set(spec, null);
|
|
continue;
|
|
}
|
|
const match = /^[a-f0-9]+ blob (\d+)$/.exec(header);
|
|
// Submodules and other non-blob objects retain git-show behavior.
|
|
if (!match) return null;
|
|
const size = Number(match[1]);
|
|
if (
|
|
!Number.isSafeInteger(size) ||
|
|
offset + size >= result.stdout.length ||
|
|
result.stdout[offset + size] !== 10
|
|
)
|
|
throw new Error("Invalid git object length");
|
|
contents.set(spec, result.stdout.subarray(offset, offset + size).toString("utf8"));
|
|
offset += size + 1;
|
|
}
|
|
if (offset !== result.stdout.length) throw new Error("Unexpected git object output");
|
|
return contents;
|
|
}
|