Speed up cold diffs and wrapped text measurement (#4676)

* 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.
This commit is contained in:
Mohamed Boudra
2026-09-11 08:07:01 +02:00
committed by GitHub
parent 16d932651c
commit 33a52d0ae7
32 changed files with 1409 additions and 186 deletions
+35 -6
View File
@@ -46,6 +46,7 @@ export function configureGitProcessPolicy(policy: GitProcessPolicy): void {
export interface GitCommandOptions {
cwd: string;
input?: string | Buffer;
env?: ProcessEnvRecord;
envOverlay?: ProcessEnvRecord;
logger?: Pick<Logger, "trace">;
@@ -54,8 +55,8 @@ export interface GitCommandOptions {
acceptExitCodes?: number[];
}
export interface GitCommandResult {
stdout: string;
export interface GitCommandResult<Output = string> {
stdout: Output;
stderr: string;
truncated: boolean;
exitCode: number | null;
@@ -263,6 +264,23 @@ function runGitCommandWithProvenance(
options: GitCommandOptions,
provenance?: string,
): Promise<GitCommandResult> {
return executeGitCommand(args, options, (output) => output.toString("utf8"), provenance);
}
/** Binary stdout preserves cat-file byte framing before text decoding. */
export function runGitCommandBytes(
args: string[],
options: GitCommandOptions,
): Promise<GitCommandResult<Buffer>> {
return executeGitCommand(args, options, (output) => output);
}
function executeGitCommand<Output>(
args: string[],
options: GitCommandOptions,
decode: (output: Buffer) => Output,
provenance?: string,
): Promise<GitCommandResult<Output>> {
const metricsState = submitGitCommandMetric(args, options.cwd);
const commandTrace = submitGitCommandTrace(args, options.cwd, {
active: gitProcessScheduler.activeCount,
@@ -274,7 +292,7 @@ function runGitCommandWithProvenance(
const exited = new Promise<void>((resolve) => {
releaseProcessSlot = resolve;
});
const resultPromise = new Promise<GitCommandResult>((resolve, reject) => {
const resultPromise = new Promise<GitCommandResult<Output>>((resolve, reject) => {
startGitCommandTrace(commandTrace, {
active: gitProcessScheduler.activeCount,
pending: gitProcessScheduler.pendingCount,
@@ -385,7 +403,7 @@ function runGitCommandWithProvenance(
cwd: options.cwd,
envOverlay,
shell: false,
stdio: ["ignore", "pipe", "pipe"],
stdio: [options.input === undefined ? "ignore" : "pipe", "pipe", "pipe"],
},
);
spawnGitCommandTrace(commandTrace, child.pid);
@@ -465,12 +483,23 @@ function runGitCommandWithProvenance(
}
});
if (options.input !== undefined) {
child.stdin!.on("error", (error: NodeJS.ErrnoException) => {
// A command may close stdin when it exits or reaches the output limit.
if (error.code !== "EPIPE") {
processError = error;
child.kill("SIGKILL");
}
});
child.stdin!.end(options.input);
}
child.on("exit", markProcessExited);
child.on("close", (exitCode, signal) => {
markProcessExited(exitCode, signal);
const result: GitCommandResult = {
stdout: Buffer.concat(stdoutChunks).toString("utf8"),
const result: GitCommandResult<Output> = {
stdout: decode(Buffer.concat(stdoutChunks)),
stderr: Buffer.concat(stderrChunks).toString("utf8"),
truncated,
exitCode,