Skip to content

Commit b1c810c

Browse files
committed
feat: handle zod parse errors by using safeParse
If there is an existing localStorage entry for `key`, the library should not throw an error, but replace the existing `localStorage` entry with the `initialValue`. This allows users of this library to modify stores with new schemas with ease.
1 parent e8ab834 commit b1c810c

File tree

1 file changed

+25
-5
lines changed

1 file changed

+25
-5
lines changed

src/index.ts

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { writable, type Writable, get } from "svelte/store";
2-
import { z } from "zod";
2+
import { SafeParseReturnType, z } from "zod";
33

44
type Equals<X, Y> = (<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y
55
? 1
@@ -30,6 +30,26 @@ export default function storedWritable<
3030
> & { clear: () => void } {
3131
const stored = !disableLocalStorage ? localStorage.getItem(key) : null;
3232

33+
const parseFromJson = (
34+
content: string
35+
): SafeParseReturnType<string, T["_output"]> => {
36+
return z
37+
.string()
38+
.transform((_, ctx) => {
39+
try {
40+
return JSON.parse(content);
41+
} catch {
42+
ctx.addIssue({
43+
code: z.ZodIssueCode.custom,
44+
message: "invalid json",
45+
});
46+
return z.never;
47+
}
48+
})
49+
.pipe(schema)
50+
.safeParse(content);
51+
};
52+
3353
// Subscribe to window storage event to keep changes from another tab in sync.
3454
if (!disableLocalStorage) {
3555
window?.addEventListener("storage", (event) => {
@@ -39,14 +59,14 @@ export default function storedWritable<
3959
return;
4060
}
4161

42-
w.set(schema.parse(JSON.parse(event.newValue)));
62+
const { success, data } = parseFromJson(event.newValue);
63+
w.set(success ? data : initialValue);
4364
}
4465
});
4566
}
4667

47-
const w = writable<S>(
48-
stored ? schema.parse(JSON.parse(stored)) : initialValue
49-
);
68+
const parsed = stored ? parseFromJson(stored) : null;
69+
const w = writable<S>(parsed?.success ? parsed.data : initialValue);
5070

5171
/**
5272
* Set writable value and inform subscribers. Updates the writeable's stored data in

0 commit comments

Comments
 (0)