mirror of
https://github.com/anomalyco/opencode.git
synced 2026-02-01 22:48:16 +00:00
chore: cleanup
This commit is contained in:
@@ -16,6 +16,9 @@ type PersistTarget = {
|
||||
|
||||
const LEGACY_STORAGE = "default.dat"
|
||||
const GLOBAL_STORAGE = "opencode.global.dat"
|
||||
const LOCAL_PREFIX = "opencode."
|
||||
const fallback = { disabled: false }
|
||||
const cache = new Map<string, string>()
|
||||
|
||||
function quota(error: unknown) {
|
||||
if (error instanceof DOMException) {
|
||||
@@ -40,10 +43,42 @@ function quota(error: unknown) {
|
||||
return false
|
||||
}
|
||||
|
||||
type Evict = { key: string; size: number }
|
||||
|
||||
function evict(storage: Storage, keep: string, value: string) {
|
||||
const total = storage.length
|
||||
const indexes = Array.from({ length: total }, (_, index) => index)
|
||||
const items: Evict[] = []
|
||||
|
||||
for (const index of indexes) {
|
||||
const name = storage.key(index)
|
||||
if (!name) continue
|
||||
if (!name.startsWith(LOCAL_PREFIX)) continue
|
||||
if (name === keep) continue
|
||||
const stored = storage.getItem(name)
|
||||
items.push({ key: name, size: stored?.length ?? 0 })
|
||||
}
|
||||
|
||||
items.sort((a, b) => b.size - a.size)
|
||||
|
||||
for (const item of items) {
|
||||
storage.removeItem(item.key)
|
||||
|
||||
try {
|
||||
storage.setItem(keep, value)
|
||||
return true
|
||||
} catch (error) {
|
||||
if (!quota(error)) throw error
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
function write(storage: Storage, key: string, value: string) {
|
||||
try {
|
||||
storage.setItem(key, value)
|
||||
return
|
||||
return true
|
||||
} catch (error) {
|
||||
if (!quota(error)) throw error
|
||||
}
|
||||
@@ -51,9 +86,12 @@ function write(storage: Storage, key: string, value: string) {
|
||||
try {
|
||||
storage.removeItem(key)
|
||||
storage.setItem(key, value)
|
||||
return true
|
||||
} catch (error) {
|
||||
if (!quota(error)) throw error
|
||||
}
|
||||
|
||||
return evict(storage, key, value)
|
||||
}
|
||||
|
||||
function snapshot(value: unknown) {
|
||||
@@ -108,17 +146,64 @@ function localStorageWithPrefix(prefix: string): SyncStorage {
|
||||
const base = `${prefix}:`
|
||||
const item = (key: string) => base + key
|
||||
return {
|
||||
getItem: (key) => localStorage.getItem(item(key)),
|
||||
setItem: (key, value) => write(localStorage, item(key), value),
|
||||
removeItem: (key) => localStorage.removeItem(item(key)),
|
||||
getItem: (key) => {
|
||||
const name = item(key)
|
||||
const cached = cache.get(name)
|
||||
if (fallback.disabled && cached !== undefined) return cached
|
||||
|
||||
const stored = localStorage.getItem(name)
|
||||
if (stored === null) return cached ?? null
|
||||
cache.set(name, stored)
|
||||
return stored
|
||||
},
|
||||
setItem: (key, value) => {
|
||||
const name = item(key)
|
||||
cache.set(name, value)
|
||||
if (fallback.disabled) return
|
||||
try {
|
||||
if (write(localStorage, name, value)) return
|
||||
} catch {
|
||||
fallback.disabled = true
|
||||
return
|
||||
}
|
||||
fallback.disabled = true
|
||||
},
|
||||
removeItem: (key) => {
|
||||
const name = item(key)
|
||||
cache.delete(name)
|
||||
if (fallback.disabled) return
|
||||
localStorage.removeItem(name)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
function localStorageDirect(): SyncStorage {
|
||||
return {
|
||||
getItem: (key) => localStorage.getItem(key),
|
||||
setItem: (key, value) => write(localStorage, key, value),
|
||||
removeItem: (key) => localStorage.removeItem(key),
|
||||
getItem: (key) => {
|
||||
const cached = cache.get(key)
|
||||
if (fallback.disabled && cached !== undefined) return cached
|
||||
|
||||
const stored = localStorage.getItem(key)
|
||||
if (stored === null) return cached ?? null
|
||||
cache.set(key, stored)
|
||||
return stored
|
||||
},
|
||||
setItem: (key, value) => {
|
||||
cache.set(key, value)
|
||||
if (fallback.disabled) return
|
||||
try {
|
||||
if (write(localStorage, key, value)) return
|
||||
} catch {
|
||||
fallback.disabled = true
|
||||
return
|
||||
}
|
||||
fallback.disabled = true
|
||||
},
|
||||
removeItem: (key) => {
|
||||
cache.delete(key)
|
||||
if (fallback.disabled) return
|
||||
localStorage.removeItem(key)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -363,7 +363,7 @@ export function UserMessageDisplay(props: { message: UserMessage; parts: PartTyp
|
||||
}
|
||||
|
||||
return (
|
||||
<div data-component="user-message" data-expanded={expanded()} data-can-expand={canExpand()}>
|
||||
<div data-component="user-message" data-expanded={expanded()} data-can-expand={canExpand()} onClick={toggleExpanded}>
|
||||
<Show when={attachments().length > 0}>
|
||||
<div data-slot="user-message-attachments">
|
||||
<For each={attachments()}>
|
||||
@@ -371,7 +371,8 @@ export function UserMessageDisplay(props: { message: UserMessage; parts: PartTyp
|
||||
<div
|
||||
data-slot="user-message-attachment"
|
||||
data-type={file.mime.startsWith("image/") ? "image" : "file"}
|
||||
onClick={() => {
|
||||
onClick={(event) => {
|
||||
event.stopPropagation()
|
||||
if (file.mime.startsWith("image/") && file.url) {
|
||||
openImagePreview(file.url, file.filename)
|
||||
}
|
||||
@@ -393,7 +394,7 @@ export function UserMessageDisplay(props: { message: UserMessage; parts: PartTyp
|
||||
</div>
|
||||
</Show>
|
||||
<Show when={text()}>
|
||||
<div data-slot="user-message-text" ref={(el) => (textRef = el)} onClick={toggleExpanded}>
|
||||
<div data-slot="user-message-text" ref={(el) => (textRef = el)}>
|
||||
<HighlightedText text={text()} references={inlineFiles()} agents={agents()} />
|
||||
<button
|
||||
data-slot="user-message-expand"
|
||||
|
||||
Reference in New Issue
Block a user