feat(global-state-store): ✨ implement GlobalStateStore and utils
* Create GlobalStateStore for managing application state. * Add utility functions for loading and saving state to storage. * Define types for global state and session management. * Implement ProgramDataWrapper for fetching and updating program data.
This commit is contained in:
109
src/GlobalStateStore/GlobalStateStore.utils.ts
Normal file
109
src/GlobalStateStore/GlobalStateStore.utils.ts
Normal file
@@ -0,0 +1,109 @@
|
||||
import { createStore, entries, set, type UseStore } from 'idb-keyval';
|
||||
|
||||
const STORAGE_KEY = 'app-data';
|
||||
|
||||
const initilizeStore = () => {
|
||||
if (indexedDB) {
|
||||
try {
|
||||
return createStore('programdata', 'programdata');
|
||||
} catch (e) {
|
||||
console.error('Failed to initialize indexedDB store: ', STORAGE_KEY, e);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
const programDataIndexDBStore: null | UseStore = initilizeStore();
|
||||
|
||||
const skipKeysCallback = (dataKey: string, dataValue: any) => {
|
||||
if (typeof dataValue === 'function') {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (
|
||||
dataKey === 'loading' ||
|
||||
dataKey === 'error' ||
|
||||
dataKey === 'security' ||
|
||||
dataKey === 'meta' ||
|
||||
dataKey === 'help'
|
||||
) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return dataValue;
|
||||
};
|
||||
|
||||
async function loadStorage<T = any>(storageKey?: string): Promise<T> {
|
||||
if (indexedDB) {
|
||||
try {
|
||||
const storeValues = await entries(programDataIndexDBStore);
|
||||
const obj: any = {};
|
||||
|
||||
storeValues.forEach((arr: string[]) => {
|
||||
const k = String(arr[0]);
|
||||
obj[k] = JSON.parse(arr[1]);
|
||||
});
|
||||
|
||||
return obj;
|
||||
} catch (e) {
|
||||
console.error('Failed to load storage: ', storageKey ?? STORAGE_KEY, e);
|
||||
}
|
||||
} else if (localStorage) {
|
||||
try {
|
||||
const storagedata = localStorage.getItem(storageKey ?? STORAGE_KEY);
|
||||
if (storagedata && storagedata.length > 0) {
|
||||
const obj = JSON.parse(storagedata, (_dataKey, dataValue) => {
|
||||
if (typeof dataValue === 'string' && dataValue.startsWith('function')) {
|
||||
return undefined;
|
||||
}
|
||||
return dataValue;
|
||||
});
|
||||
return obj;
|
||||
}
|
||||
return {} as T;
|
||||
} catch (e) {
|
||||
console.error('Failed to load storage: ', storageKey ?? STORAGE_KEY, e);
|
||||
}
|
||||
}
|
||||
|
||||
return {} as T;
|
||||
}
|
||||
|
||||
async function saveStorage<T = any>(data: T, storageKey?: string): Promise<T> {
|
||||
if (indexedDB) {
|
||||
try {
|
||||
const keys = Object.keys(data as object).filter(
|
||||
(key) =>
|
||||
key !== 'loading' &&
|
||||
key !== 'error' &&
|
||||
key !== 'help' &&
|
||||
key !== 'meta' &&
|
||||
key !== 'security' &&
|
||||
typeof data[key as keyof T] !== 'function'
|
||||
);
|
||||
const promises = keys.map((key) => {
|
||||
return set(
|
||||
key,
|
||||
JSON.stringify((data as any)[key], skipKeysCallback) ?? '{}',
|
||||
programDataIndexDBStore
|
||||
);
|
||||
});
|
||||
await Promise.all(promises);
|
||||
return data;
|
||||
} catch (e) {
|
||||
console.error('Failed to save indexedDB storage: ', storageKey ?? STORAGE_KEY, e);
|
||||
}
|
||||
} else if (localStorage) {
|
||||
try {
|
||||
const dataString = JSON.stringify(data, skipKeysCallback);
|
||||
|
||||
localStorage.setItem(storageKey ?? STORAGE_KEY, dataString ?? '{}');
|
||||
return data;
|
||||
} catch (e) {
|
||||
console.error('Failed to save localStorage storage: ', storageKey ?? STORAGE_KEY, e);
|
||||
}
|
||||
}
|
||||
return {} as T;
|
||||
}
|
||||
|
||||
export { loadStorage, saveStorage };
|
||||
Reference in New Issue
Block a user