fix: Treat a stored JSON null as a missing persisted value

readJSON returned any successfully parsed value, so a localStorage
entry holding the literal "null" came back as null instead of the
fallback — and a null inputState crashes module init on every load
until storage is cleared. The deleted MacFJA persist layer guarded
this with `null !== initialValue`; restore that behavior.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Sidharth Vinod
2026-06-10 23:53:00 +05:30
co-authored by Claude Fable 5
parent 144b4dc190
commit 59105628f4
2 changed files with 18 additions and 1 deletions
+12
View File
@@ -22,6 +22,12 @@ describe('readJSON', () => {
window.localStorage.setItem('legacy', 'undefined');
expect(readJSON('legacy', 'fallback')).toBe('fallback');
});
it('returns the fallback when the stored value parses to null', () => {
// The pre-runes persistence layer treated a stored null as absent.
window.localStorage.setItem('legacy-null', 'null');
expect(readJSON('legacy-null', 'fallback')).toBe('fallback');
});
});
describe('writeJSON', () => {
@@ -51,4 +57,10 @@ describe('persisted', () => {
expect(counter.value).toBe(42);
expect(window.localStorage.getItem('counter')).toBe('42');
});
it('uses the initial value when storage holds a literal null', () => {
window.localStorage.setItem('settings', 'null');
const settings = persisted('settings', { theme: 'default' });
expect(settings.value).toEqual({ theme: 'default' });
});
});
+6 -1
View File
@@ -15,7 +15,12 @@ export const readJSON = <T>(key: string, fallback: T): T => {
}
try {
const raw = window.localStorage.getItem(key);
return raw === null ? fallback : (JSON.parse(raw) as T);
if (raw === null) {
return fallback;
}
// A stored literal "null" means the value is absent: the pre-runes
// persistence layer never wrote null and treated it as missing.
return (JSON.parse(raw) as T) ?? fallback;
} catch {
return fallback;
}