mirror of
https://github.com/getpaseo/paseo.git
synced 2026-10-24 18:22:38 +00:00
* perf(app): reduce warm workspace switch work Retained workspaces avoided mounts but pane activity still rerendered the full composer, message input, and agent-control presentation. Keep the activity contract intact while moving focus-sensitive behavior behind small context consumers, and add a Playwright benchmark that measures rapid retained workspace switching on one browser clock. * perf(app): accelerate retained workspace switching Avoid repeated retained-stream layout reconciliation and unrelated workspace structure recomputation. Use the lightweight route transition while the host is already focused, while preserving targeted root POP_TO for returns from app-wide routes where it prevents duplicate hidden decks. * perf(app): defer composer focus during workspace switches * perf(app): retain recently used workspaces longer Keep up to ten workspace screens warm so normal multi-workspace navigation does not repeatedly rebuild recently used timelines. Inactive screens expire after ten minutes, while the active screen remains protected and capacity eviction stays least-recently-used. * fix(app): reconcile retained timeline geometry * fix(app): refresh retained reading position
55 lines
917 B
TypeScript
55 lines
917 B
TypeScript
interface FocusWithRetriesOptions {
|
|
focus: () => void;
|
|
isFocused: () => boolean;
|
|
deferInitialAttempt?: boolean;
|
|
timeoutMs?: number;
|
|
onSuccess?: () => void;
|
|
onTimeout?: () => void;
|
|
}
|
|
|
|
export function focusWithRetries({
|
|
focus,
|
|
isFocused,
|
|
deferInitialAttempt = false,
|
|
timeoutMs = 1500,
|
|
onSuccess,
|
|
onTimeout,
|
|
}: FocusWithRetriesOptions): () => void {
|
|
let cancelled = false;
|
|
const deadlineMs = Date.now() + timeoutMs;
|
|
|
|
const tick = () => {
|
|
if (cancelled) return;
|
|
|
|
try {
|
|
focus();
|
|
} catch {
|
|
// ignore
|
|
}
|
|
|
|
if (isFocused()) {
|
|
onSuccess?.();
|
|
return;
|
|
}
|
|
|
|
if (Date.now() >= deadlineMs) {
|
|
onTimeout?.();
|
|
return;
|
|
}
|
|
|
|
requestAnimationFrame(() => {
|
|
requestAnimationFrame(tick);
|
|
});
|
|
};
|
|
|
|
if (deferInitialAttempt) {
|
|
requestAnimationFrame(tick);
|
|
} else {
|
|
tick();
|
|
}
|
|
|
|
return () => {
|
|
cancelled = true;
|
|
};
|
|
}
|