Files
karma/ui/src/Common/LocalStore.ts
2026-03-23 11:00:11 +00:00

53 lines
1.1 KiB
TypeScript

import { observable, autorun, set, toJS, runInAction } from "mobx";
interface LocalStoreResult<T> {
value: T;
destroy: () => void;
}
function localStored<T extends object>(
key: string,
defaultValue: T,
): LocalStoreResult<T> {
const initial: T = { ...defaultValue };
const fromStorage = localStorage.getItem(key);
if (fromStorage) {
try {
Object.assign(initial, JSON.parse(fromStorage));
} catch {
// ignore malformed JSON, use defaults
}
}
const obsVal = observable(initial);
const disposeAutorun = autorun(
() => {
localStorage.setItem(key, JSON.stringify(toJS(obsVal)));
},
{ delay: 0 },
);
const onStorageEvent = (e: StorageEvent) => {
if (e.key === key && e.newValue) {
try {
runInAction(() => set(obsVal, JSON.parse(e.newValue!)));
} catch {
// ignore malformed JSON from other tabs
}
}
};
window.addEventListener("storage", onStorageEvent);
return {
value: obsVal,
destroy() {
disposeAutorun();
window.removeEventListener("storage", onStorageEvent);
},
};
}
export { localStored };