Skip to content

ExpireStorage 一个会过期的本地存储库

可选择使用 localStorage 或 sessionStorage 实现,并支持设置过期时间。

代码实现

ts
export interface ExpireStorageMetadata {
  /** 过期时间:毫秒 */
  expire?: number;
}

export interface ExpireStorageMetadataTTL extends ExpireStorageMetadata {
  /** 还有多久过期:秒 */
  ttl?: number;
}

export class ExpireStorage {
  public metedataKey!: string;
  public storage!: Storage;
  constructor(op?: { metedataKey?: string; storage?: Storage }) {
    this.metedataKey = op?.metedataKey || 'expire_storage_metadata';
    this.storage = op?.storage || window.localStorage;
  }

  public get metedata(): Record<string, ExpireStorageMetadata | void> {
    return JSON.parse(this.storage.getItem(this.metedataKey) || '{}');
  }

  public set metedata(value: Record<string, ExpireStorageMetadata | void>) {
    this.storage.setItem(this.metedataKey, JSON.stringify(value));
  }
  public getItem(key: string) {
    const expire = this.metedata[key]?.expire;
    // 未设置过期时间
    if (expire === void 0) return this.storage.getItem(key);
    // 未过期
    if (expire > Date.now()) return this.storage.getItem(key);
    // 已过期
    this.removeItem(key);
    return null;
  }

  public getItemJSON<T>(key: string): T | null {
    return JSON.parse(this.getItem(key) || 'null');
  }

  public setItem(key: string, value: string, metedata?: ExpireStorageMetadataTTL) {
    const { ttl, ..._metedata } = metedata || {};
    metedata = _metedata;
    if (ttl) metedata = { ..._metedata, expire: Date.now() + ttl * 1000 };
    this.storage.setItem(key, value);
    this.metedata = { ...this.metedata, [key]: metedata };
  }

  public setItemJSON(key: string, value: any, metedata?: ExpireStorageMetadataTTL) {
    this.setItem(key, JSON.stringify(value), metedata);
  }

  public removeItem(key: string) {
    const { metedata } = this;
    this.storage.removeItem(key);
    delete metedata[key];
    this.metedata = { ...metedata };
  }
}

使用示例

ts
import { ExpireStorage } from './expire-storage';
export const expireStorage = new ExpireStorage();

interface JsonData {
  name: string;
  age: number;
}
const jsonData: JsonData = { name: '张三', age: 18 };
// 设置10天后过期
expireStorage.setItemJSON('json_data', jsonData, { ttl: 60 * 60 * 24 * 10 });
const data = expireStorage.getItemJSON<JsonData>('json_data');
console.log(data); // { name: '张三', age: 18 }