import { describe, expect, test } from "bun:test" import { createRoot } from "solid-js" import { createStore } from "solid-js/store" import { makePersisted, type SyncStorage } from "@solid-primitives/storage" import { createScrollPersistence } from "./layout-scroll" describe("createScrollPersistence", () => { test("debounces persisted scroll writes", async () => { const key = "layout-scroll.test" const data = new Map() const writes: string[] = [] const stats = { flushes: 0 } const storage = { getItem: (k: string) => data.get(k) ?? null, setItem: (k: string, v: string) => { data.set(k, v) if (k === key) writes.push(v) }, removeItem: (k: string) => { data.delete(k) }, } as SyncStorage await new Promise((resolve, reject) => { createRoot((dispose) => { const [raw, setRaw] = createStore({ sessionView: {} as Record }>, }) const [store, setStore] = makePersisted([raw, setRaw], { name: key, storage }) const scroll = createScrollPersistence({ debounceMs: 30, getSnapshot: (sessionKey) => store.sessionView[sessionKey]?.scroll, onFlush: (sessionKey, next) => { stats.flushes += 1 const current = store.sessionView[sessionKey] if (!current) { setStore("sessionView", sessionKey, { scroll: next }) return } setStore("sessionView", sessionKey, "scroll", (prev) => ({ ...(prev ?? {}), ...next })) }, }) const run = async () => { await new Promise((r) => setTimeout(r, 0)) writes.length = 0 for (const i of Array.from({ length: 100 }, (_, n) => n)) { scroll.setScroll("session", "review", { x: 0, y: i }) } await new Promise((r) => setTimeout(r, 120)) expect(stats.flushes).toBeGreaterThanOrEqual(1) expect(writes.length).toBeGreaterThanOrEqual(1) expect(writes.length).toBeLessThanOrEqual(2) } void run() .then(resolve) .catch(reject) .finally(() => { scroll.dispose() dispose() }) }) }) }) })