perf: debounce composer draft localStorage writes

Every keystroke triggered full JSON serialization of all composer drafts
(including base64 image attachments) and a synchronous localStorage
write. At normal typing speed this caused 5+ writes/sec, blocking the
main thread and creating noticeable input lag.

Wrap the Zustand persist storage with a 300ms debounce. In-memory state
updates remain immediate; only the serialization and storage write are
deferred. A beforeunload handler flushes pending writes to prevent data
loss. The removeItem method cancels any pending setItem to avoid
resurrecting cleared drafts.

Adds unit tests for the DebouncedStorage utility covering debounce
timing, rapid writes, removeItem cancellation, flush, and edge cases.
90e0c2ab15Chukwudi Nwobodo committed on 3/9/2026, 9:02:29 PM· committed by Julius Marmingeparent7a3d4d1
2 files changedLine totals unavailable