Files
nodarium/app/src/lib/helpers/localState.svelte.ts
T
release-bot 7e71a41e52
🚀 Lint & Test & Deploy / release (pull_request) Successful in 4m0s
feat: merge localState recursively with initial
Closes #17
2026-02-12 12:50:58 +01:00

70 lines
1.5 KiB
TypeScript

import { browser } from '$app/environment';
function mergeRecursive<T>(current: T, initial: T): T {
if (typeof initial === 'number') {
if (typeof current === 'number') return current;
return initial;
}
if (typeof initial === 'boolean') {
if (typeof current === 'boolean') return current;
return initial;
}
if (Array.isArray(initial)) {
if (Array.isArray(current)) return current;
return initial;
}
if (typeof initial === 'object' && initial) {
const merged = initial;
if (typeof current === 'object' && current) {
for (const key of Object.keys(initial)) {
if (key in current) {
// @ts-expect-error It's safe dont worry about it
merged[key] = mergeRecursive(current[key], initial[key]);
}
}
}
return merged;
}
return current;
}
export class LocalStore<T> {
value = $state<T>() as T;
key = '';
constructor(key: string, value: T) {
this.key = key;
this.value = value;
if (browser) {
const item = localStorage.getItem(key);
if (item) {
const storedValue = this.deserialize(item);
this.value = mergeRecursive(storedValue, value);
}
}
$effect.root(() => {
$effect(() => {
localStorage.setItem(this.key, this.serialize(this.value));
});
});
}
serialize(value: T): string {
return JSON.stringify(value);
}
deserialize(item: string): T {
return JSON.parse(item);
}
}
export function localState<T>(key: string, value: T) {
return new LocalStore(key, value);
}