generated from react18-tools/turborepo-template
-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
persist.ts
65 lines (61 loc) · 1.84 KB
/
persist.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
import { Plugin } from "..";
export interface PersistOptions {
/** @defaultValue true */
sync?: boolean;
/** @defaultValue local */
storage?: "local" | "session" | "cookie";
}
/** get stored item */
const getItem = (key: string, options?: PersistOptions) => {
const cookie = document.cookie.split("; ").find(c => c.startsWith(key));
switch (options?.storage) {
case "cookie":
return cookie?.split("=")[1];
case "session":
return sessionStorage.getItem(key);
default:
return localStorage.getItem(key);
}
};
/** set item to persistant store */
const setItem = (key: string, value: string, options?: PersistOptions) => {
switch (options?.storage) {
case "cookie":
document.cookie = `${key}=${value}; max-age=31536000; SameSite=Strict;`;
if (options.sync ?? true) sessionStorage.setItem(key, value);
return;
case "session":
sessionStorage.setItem(key, value);
return;
default:
localStorage.setItem(key, value);
}
};
/**
* A plugin that persists and syncs RGS store between tabs.
*
* @returns A plugin that persists and syncs a value between tabs.
*/
export const persist = <T>(options?: PersistOptions): Plugin<T> => {
return {
init(key, _, mutate) {
if (typeof window === "undefined") return;
const persistedValue = getItem(key, options);
const newVal = JSON.parse(persistedValue || "{}").val;
if (newVal) mutate(newVal);
if (options?.sync ?? true) {
addEventListener("storage", e => {
if (e.key === key && e.newValue) {
const newVal = JSON.parse(e.newValue).val;
if (newVal !== undefined) mutate(newVal);
}
});
}
},
onChange(key, value) {
if (typeof window !== "undefined") {
setItem(key, JSON.stringify({ val: value }), options);
}
},
};
};