forked from OlegWock/anori
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnamespaced-storage.ts
68 lines (56 loc) · 2.04 KB
/
namespaced-storage.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
66
67
68
import { AtomWithBrowserStorage, atomWithBrowserStorage, focusAtomWithStorage, getAtomWithStorageValue, setAtomWithStorageValue, useAtomWithStorage } from "./storage";
import { useMemo } from "react";
import browser from 'webextension-polyfill';
export class NamespacedStorage<T extends {} = {}> {
ns: string;
atom: AtomWithBrowserStorage<Partial<T>>;
loaded: boolean;
private _loadingPromise: Promise<void>;
static get<T extends {} = {}>(ns: string): NamespacedStorage<T> {
const inCache = cache.get(ns);
if (inCache) {
return inCache as NamespacedStorage<T>;
}
const nsStorage = new NamespacedStorage<T>(ns);
cache.set(ns, nsStorage);
return nsStorage;
}
private constructor(ns: string) {
let onLoad = () => { };
this.ns = ns;
this._loadingPromise = new Promise((resolve) => {
onLoad = () => {
this.loaded = true;
resolve();
};
});
this.atom = atomWithBrowserStorage<Partial<T>>(ns, {}, {
forceLoad: true,
onLoad: onLoad,
});
this.loaded = false;
}
waitForLoad() {
return this._loadingPromise;
}
get<K extends keyof T>(name: K): T[K] | undefined {
const { value } = getAtomWithStorageValue(this.atom);
return value[name];
}
set<K extends keyof T>(name: K, val: T[K]) {
const { value: currentState } = getAtomWithStorageValue(this.atom);
setAtomWithStorageValue(this.atom, {
...currentState,
[name]: val,
});
}
clear() {
setAtomWithStorageValue(this.atom, {});
return browser.storage.local.remove(this.ns);
}
useValue<K extends keyof T>(name: K, defaultValue: T[K]) {
const focusedAtom = useMemo(() => focusAtomWithStorage(this.atom, name, defaultValue), [name]) as AtomWithBrowserStorage<Required<T>[K]>;
return useAtomWithStorage(focusedAtom);
}
}
const cache: Map<string, NamespacedStorage> = new Map();