summaryrefslogtreecommitdiffhomepage
path: root/packages/app/src/context/layout-scroll.test.ts
diff options
context:
space:
mode:
authorAdam <[email protected]>2026-01-06 04:18:20 -0600
committerAdam <[email protected]>2026-01-06 08:18:49 -0600
commit3f463bc9168abd907be9ae582e161ff89c3a27c9 (patch)
tree5b4aad62e698be847dccb6e93b80ac2c3f84844f /packages/app/src/context/layout-scroll.test.ts
parent0b02f6d22f793387322d96f937cfc1c8eee9bfbb (diff)
downloadopencode-3f463bc9168abd907be9ae582e161ff89c3a27c9.tar.gz
opencode-3f463bc9168abd907be9ae582e161ff89c3a27c9.zip
fix(app): scroll store performance
Diffstat (limited to 'packages/app/src/context/layout-scroll.test.ts')
-rw-r--r--packages/app/src/context/layout-scroll.test.ts73
1 files changed, 73 insertions, 0 deletions
diff --git a/packages/app/src/context/layout-scroll.test.ts b/packages/app/src/context/layout-scroll.test.ts
new file mode 100644
index 000000000..b7962c411
--- /dev/null
+++ b/packages/app/src/context/layout-scroll.test.ts
@@ -0,0 +1,73 @@
+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<string, string>()
+ 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<void>((resolve, reject) => {
+ createRoot((dispose) => {
+ const [raw, setRaw] = createStore({
+ sessionView: {} as Record<string, { scroll: Record<string, { x: number; y: number }> }>,
+ })
+
+ 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()
+ })
+ })
+ })
+ })
+})