| ... | ... | @@ -14,6 +14,7 @@ import { |
| 14 | 14 | DEFAULT_RUNTIME_MODE, |
| 15 | 15 | type ChatImageAttachment, |
| 16 | 16 | } from "./types"; |
| 17 | import { Debouncer } from "@tanstack/react-pacer"; |
| 17 | 18 | import { create } from "zustand"; |
| 18 | 19 | import { createJSONStorage, persist, type StateStorage } from "zustand/middleware"; |
| 19 | 20 | |
| ... | ... | @@ -27,41 +28,24 @@ interface DebouncedStorage extends StateStorage { |
| 27 | 28 | } |
| 28 | 29 | |
| 29 | 30 | export function createDebouncedStorage(baseStorage: StateStorage): DebouncedStorage { |
| 30 | | let timer: ReturnType<typeof setTimeout> | null = null; |
| 31 | | let pendingName: string | null = null; |
| 32 | | let pendingValue: string | null = null; |
| 31 | const debouncedSetItem = new Debouncer( |
| 32 | (name: string, value: string) => { |
| 33 | baseStorage.setItem(name, value); |
| 34 | }, |
| 35 | { wait: COMPOSER_PERSIST_DEBOUNCE_MS }, |
| 36 | ); |
| 37 | |
| 33 | 38 | return { |
| 34 | 39 | getItem: (name) => baseStorage.getItem(name), |
| 35 | 40 | setItem: (name, value) => { |
| 36 | | pendingName = name; |
| 37 | | pendingValue = value; |
| 38 | | if (timer !== null) { |
| 39 | | clearTimeout(timer); |
| 40 | | } |
| 41 | | timer = setTimeout(() => { |
| 42 | | timer = null; |
| 43 | | pendingName = null; |
| 44 | | pendingValue = null; |
| 45 | | baseStorage.setItem(name, value); |
| 46 | | }, COMPOSER_PERSIST_DEBOUNCE_MS); |
| 41 | debouncedSetItem.maybeExecute(name, value); |
| 47 | 42 | }, |
| 48 | 43 | removeItem: (name) => { |
| 49 | | if (timer !== null) { |
| 50 | | clearTimeout(timer); |
| 51 | | timer = null; |
| 52 | | pendingName = null; |
| 53 | | pendingValue = null; |
| 54 | | } |
| 44 | debouncedSetItem.cancel(); |
| 55 | 45 | baseStorage.removeItem(name); |
| 56 | 46 | }, |
| 57 | 47 | flush: () => { |
| 58 | | if (timer !== null && pendingName !== null && pendingValue !== null) { |
| 59 | | clearTimeout(timer); |
| 60 | | timer = null; |
| 61 | | baseStorage.setItem(pendingName, pendingValue); |
| 62 | | pendingName = null; |
| 63 | | pendingValue = null; |
| 64 | | } |
| 48 | debouncedSetItem.flush(); |
| 65 | 49 | }, |
| 66 | 50 | }; |
| 67 | 51 | } |