Something went wrong. Try again.
opencode v2 mirror
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127import { createStore, produce } from "solid-js/store"
export type SessionScroll = { x: number y: number}
type ScrollMap = Record<string, SessionScroll>
type Options = { debounceMs?: number getSnapshot: (sessionKey: string) => ScrollMap | undefined onFlush: (sessionKey: string, scroll: ScrollMap) => void}
export function createScrollPersistence(opts: Options) { const wait = opts.debounceMs ?? 200 const [cache, setCache] = createStore<Record<string, ScrollMap>>({}) const dirty = new Set<string>() const timers = new Map<string, ReturnType<typeof setTimeout>>()
function clone(input?: ScrollMap) { const out: ScrollMap = {} if (!input) return out
for (const key of Object.keys(input)) { const pos = input[key] if (!pos) continue out[key] = { x: pos.x, y: pos.y } }
return out }
function seed(sessionKey: string) { const next = clone(opts.getSnapshot(sessionKey)) const current = cache[sessionKey] if (!current) { setCache(sessionKey, next) return }
if (Object.keys(current).length > 0) return if (Object.keys(next).length === 0) return setCache(sessionKey, next) }
function scroll(sessionKey: string, tab: string) { seed(sessionKey) return cache[sessionKey]?.[tab] ?? opts.getSnapshot(sessionKey)?.[tab] }
function schedule(sessionKey: string) { const prev = timers.get(sessionKey) if (prev) clearTimeout(prev) timers.set( sessionKey, setTimeout(() => flush(sessionKey), wait), ) }
function setScroll(sessionKey: string, tab: string, pos: SessionScroll) { seed(sessionKey)
const prev = cache[sessionKey]?.[tab] if (prev?.x === pos.x && prev?.y === pos.y) return
setCache(sessionKey, tab, { x: pos.x, y: pos.y }) dirty.add(sessionKey) schedule(sessionKey) }
function flush(sessionKey: string) { const timer = timers.get(sessionKey) if (timer) clearTimeout(timer) timers.delete(sessionKey)
if (!dirty.has(sessionKey)) return dirty.delete(sessionKey)
opts.onFlush(sessionKey, clone(cache[sessionKey])) }
function flushAll() { const keys = Array.from(dirty) if (keys.length === 0) return
for (const key of keys) { flush(key) } }
function drop(keys: string[]) { if (keys.length === 0) return
for (const key of keys) { const timer = timers.get(key) if (timer) clearTimeout(timer) timers.delete(key) dirty.delete(key) }
setCache( produce((draft) => { for (const key of keys) { delete draft[key] } }), ) }
function dispose() { drop(Array.from(timers.keys())) }
return { cache, drop, flush, flushAll, scroll, seed, setScroll, dispose, }}