mirror of
https://github.com/irislib/iris-messenger.git
synced 2024-10-18 06:03:22 +00:00
more efficient local storage & mem adapter
This commit is contained in:
parent
d7a7c752aa
commit
7145ebcfb7
@ -1,5 +1,7 @@
|
||||
import LocalStorageMemoryAdapter from '@/state/LocalStorageMemoryAdapter.ts';
|
||||
|
||||
import Node from './Node';
|
||||
|
||||
const localState = new Node();
|
||||
const localState = new Node({ adapters: [new LocalStorageMemoryAdapter()] });
|
||||
|
||||
export default localState;
|
||||
|
80
src/js/state/LocalStorageMemoryAdapter.ts
Normal file
80
src/js/state/LocalStorageMemoryAdapter.ts
Normal file
@ -0,0 +1,80 @@
|
||||
import { Adapter, Callback, NodeValue, Unsubscribe } from '@/state/types.ts';
|
||||
|
||||
export default class LocalStorageMemoryAdapter extends Adapter {
|
||||
private storage = new Map<string, NodeValue>();
|
||||
private isLoaded = false;
|
||||
private loadingPromise: Promise<void>;
|
||||
private resolveLoading: (() => void) | null = null;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.loadingPromise = new Promise((resolve) => {
|
||||
this.resolveLoading = resolve;
|
||||
});
|
||||
this.loadFromLocalStorage();
|
||||
}
|
||||
|
||||
private loadFromLocalStorage() {
|
||||
for (let i = 0; i < localStorage.length; i++) {
|
||||
const key = localStorage.key(i) as string;
|
||||
const value = JSON.parse(localStorage.getItem(key) || '') as NodeValue;
|
||||
this.storage.set(key, value);
|
||||
}
|
||||
this.isLoaded = true;
|
||||
if (this.resolveLoading) {
|
||||
this.resolveLoading();
|
||||
}
|
||||
}
|
||||
|
||||
private listFromStorage(path: string, callback: Callback) {
|
||||
for (const [storedPath, storedValue] of this.storage) {
|
||||
const remainingPath = storedPath.replace(`${path}/`, '');
|
||||
if (
|
||||
storedPath.startsWith(`${path}/`) &&
|
||||
remainingPath.length &&
|
||||
!remainingPath.includes('/')
|
||||
) {
|
||||
callback(storedValue.value, storedPath, storedValue.updatedAt, () => {});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
get(path: string, callback: Callback): Unsubscribe {
|
||||
const storedValue = this.storage.get(path) || { value: undefined, updatedAt: undefined };
|
||||
callback(storedValue.value, path, storedValue.updatedAt, () => {});
|
||||
|
||||
if (!this.isLoaded) {
|
||||
this.loadingPromise.then(() => {
|
||||
const updatedValue = this.storage.get(path) || { value: undefined, updatedAt: undefined };
|
||||
if (updatedValue !== storedValue) {
|
||||
callback(updatedValue.value, path, updatedValue.updatedAt, () => {});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return () => {};
|
||||
}
|
||||
|
||||
async set(path: string, value: NodeValue) {
|
||||
await this.loadingPromise;
|
||||
|
||||
if (value.updatedAt === undefined) {
|
||||
throw new Error(`Invalid value: ${JSON.stringify(value)}`);
|
||||
}
|
||||
|
||||
this.storage.set(path, value);
|
||||
localStorage.setItem(path, JSON.stringify(value));
|
||||
}
|
||||
|
||||
list(path: string, callback: Callback): Unsubscribe {
|
||||
this.listFromStorage(path, callback);
|
||||
|
||||
if (!this.isLoaded) {
|
||||
this.loadingPromise.then(() => {
|
||||
this.listFromStorage(path, callback);
|
||||
});
|
||||
}
|
||||
|
||||
return () => {};
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user