mirror of
https://github.com/stablyai/orca.git
synced 2026-10-21 16:03:26 +00:00
67 lines
2.0 KiB
TypeScript
67 lines
2.0 KiB
TypeScript
import type { BrowserHistoryEntry, WorkspaceSessionState } from './types'
|
|
import { redactKagiSessionToken } from './browser-url'
|
|
|
|
export const MAX_BROWSER_HISTORY_ENTRIES = 200
|
|
|
|
export function normalizeBrowserHistoryUrl(url: string): string {
|
|
try {
|
|
const parsed = new URL(redactKagiSessionToken(url))
|
|
parsed.hostname = parsed.hostname.toLowerCase()
|
|
parsed.protocol = parsed.protocol.toLowerCase()
|
|
let normalized = parsed.toString()
|
|
if (normalized.endsWith('/')) {
|
|
normalized = normalized.slice(0, -1)
|
|
}
|
|
return normalized
|
|
} catch {
|
|
return redactKagiSessionToken(url).toLowerCase()
|
|
}
|
|
}
|
|
|
|
export function normalizeBrowserHistoryEntries(
|
|
entries: readonly BrowserHistoryEntry[]
|
|
): BrowserHistoryEntry[] {
|
|
const seen = new Set<string>()
|
|
const normalizedEntries: BrowserHistoryEntry[] = []
|
|
const candidates = entries
|
|
.map((entry) => {
|
|
const safeUrl = redactKagiSessionToken(entry.url)
|
|
return {
|
|
entry,
|
|
safeUrl,
|
|
key: normalizeBrowserHistoryUrl(safeUrl)
|
|
}
|
|
})
|
|
// Why: persisted history from older builds or schema repair may not be in
|
|
// recency order; the cap must keep recent visits, not arbitrary file order.
|
|
.sort((a, b) => b.entry.lastVisitedAt - a.entry.lastVisitedAt)
|
|
|
|
for (const { entry, safeUrl, key } of candidates) {
|
|
if (seen.has(key)) {
|
|
continue
|
|
}
|
|
seen.add(key)
|
|
normalizedEntries.push({ ...entry, url: safeUrl, normalizedUrl: key })
|
|
if (normalizedEntries.length >= MAX_BROWSER_HISTORY_ENTRIES) {
|
|
break
|
|
}
|
|
}
|
|
return normalizedEntries
|
|
}
|
|
|
|
export function pruneWorkspaceSessionBrowserHistory(
|
|
session: WorkspaceSessionState
|
|
): WorkspaceSessionState {
|
|
if (!session.browserUrlHistory) {
|
|
return session
|
|
}
|
|
const browserUrlHistory = normalizeBrowserHistoryEntries(session.browserUrlHistory)
|
|
if (
|
|
browserUrlHistory.length === session.browserUrlHistory.length &&
|
|
browserUrlHistory.every((entry, index) => entry === session.browserUrlHistory?.[index])
|
|
) {
|
|
return session
|
|
}
|
|
return { ...session, browserUrlHistory }
|
|
}
|