Files
ompweb/hooks/useAgentSession-queue.ts
Khaled Ahmed 13df407e99 refactor: split god modules into focused sibling modules
Verbatim extractions, no behavior change:
- hooks/useAgentSession (3442->2998) + stream/queue/notices helpers
- SessionSidebar (3112->1599) + helpers/chrome/rows
- ChatInput (2814->2560) + model-options/slash-commands/draft-attachments/banners
- AppShell (2436->2283) + app-update/provider-usage/layout
- ModelsConfig (2385->1736) + types/panels
- MessageView (1827->1409) + tool-format/task-panel/diff-view
Contract test points the archive flow at SessionSidebar-rows.
2026-09-03 00:32:32 +03:00

69 lines
2.4 KiB
TypeScript

// Queued-prompt tracking and sessionStorage persistence helpers
// extracted from useAgentSession (pure logic only — no hook state).
export interface QueuedMessages {
steering: string[];
followUp: string[];
}
export const EMPTY_QUEUE: QueuedMessages = { steering: [], followUp: [] };
// omp reports only queuedMessageCount over RPC; the queued texts live in React
// state and would vanish on reload. Mirror them into sessionStorage (per
// session, best-effort, size-bounded) so a reload can restore the queue panel.
export const QUEUE_STORAGE_PREFIX = "omp-queue-";
export const QUEUE_STORAGE_MAX_CHARS = 50_000;
export function isEmptyQueue(queue: QueuedMessages): boolean {
return queue.steering.length === 0 && queue.followUp.length === 0;
}
export function readPersistedQueue(sessionId: string): QueuedMessages | null {
try {
const raw = sessionStorage.getItem(QUEUE_STORAGE_PREFIX + sessionId);
if (!raw) return null;
const parsed = JSON.parse(raw) as Partial<QueuedMessages> | null;
const onlyStrings = (value: unknown): string[] =>
Array.isArray(value) ? value.filter((item): item is string => typeof item === "string") : [];
const queue = { steering: onlyStrings(parsed?.steering), followUp: onlyStrings(parsed?.followUp) };
return isEmptyQueue(queue) ? null : queue;
} catch {
return null;
}
}
export function persistQueue(sessionId: string, queue: QueuedMessages): void {
try {
const key = QUEUE_STORAGE_PREFIX + sessionId;
if (isEmptyQueue(queue)) {
sessionStorage.removeItem(key);
return;
}
// Size bound: drop oldest texts until the payload fits.
let bounded = queue;
let raw = JSON.stringify(bounded);
while (raw.length > QUEUE_STORAGE_MAX_CHARS && bounded.steering.length + bounded.followUp.length > 1) {
bounded = bounded.steering.length >= bounded.followUp.length
? { ...bounded, steering: bounded.steering.slice(1) }
: { ...bounded, followUp: bounded.followUp.slice(1) };
raw = JSON.stringify(bounded);
}
if (raw.length > QUEUE_STORAGE_MAX_CHARS) {
sessionStorage.removeItem(key);
return;
}
sessionStorage.setItem(key, raw);
} catch {
// Best-effort only (quota exceeded, private mode, SSR).
}
}
export function clearPersistedQueue(sessionId: string | null): void {
if (!sessionId) return;
try {
sessionStorage.removeItem(QUEUE_STORAGE_PREFIX + sessionId);
} catch {
// ignore storage errors
}
}