Skip to content

Instantly share code, notes, and snippets.

@jeongtae
Last active May 30, 2023 04:49
Show Gist options
  • Select an option

  • Save jeongtae/1725904a53f772c0639255a8f7ca0c4c to your computer and use it in GitHub Desktop.

Select an option

Save jeongtae/1725904a53f772c0639255a8f7ca0c4c to your computer and use it in GitHub Desktop.
[Vue composable] useExpirableStorage
const LS_KEY_PREFIX = '__expirable-storage-';
export interface ExpirableStorage<T = any> {
getItem(key: string): T | null;
hasItem(key: string): boolean;
setItem(key: string, value: T, expiresAt: number): void;
}
/** 설정한 기간이 지나면 파기되는 스토리지를 만든다. */
export function useExpirableStorage<T = any>(
storageKey: string,
): ExpirableStorage<T> {
const storageMap = loadStorage(LS_KEY_PREFIX + storageKey);
return {
getItem(key) {
updateAndSaveStorage(storageMap);
return storageMap.get(key)?.value ?? null;
},
hasItem(key) {
updateAndSaveStorage(storageMap);
return storageMap.has(key);
},
setItem(key, value, expiresAt) {
storageMap.set(key, { value, expiresAt });
updateAndSaveStorage(storageMap);
},
};
}
interface ExpirableStorageItem {
expiresAt: number;
value: any;
}
type ExpirableStorageMap = Map<string, ExpirableStorageItem>;
function updateAndSaveStorage(storage: ExpirableStorageMap) {
const now = Date.now();
const keysToDelete: string[] = [];
for (const [key, { expiresAt }] of storage.entries()) {
if (now >= expiresAt) {
keysToDelete.push(key);
}
}
for (const key of keysToDelete) {
storage.delete(key);
}
}
function loadStorage(key: string): Map<string, ExpirableStorageItem> {
try {
const storedItem = localStorage.getItem(key);
if (!storedItem) return new Map();
const parsed = JSON.parse(storedItem);
if (!Array.isArray(parsed)) return new Map();
return new Map(parsed);
} catch {
return new Map();
}
}
function saveStorage(key: string, storage: ExpirableStorageMap) {
const json = JSON.stringify(Array.from(storage.entries()));
localStorage.setItem(key, json);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment