Skip to content

Commit

Permalink
feat: 二次封装 [localforage](https://localforage.docschina.org/) 支持设置过期时间…
Browse files Browse the repository at this point in the history
…,提供完整的类型提示
  • Loading branch information
xiaoxian521 committed Sep 27, 2023
1 parent 320ee2b commit 4020105
Show file tree
Hide file tree
Showing 4 changed files with 279 additions and 0 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
"intro.js": "^7.2.0",
"js-cookie": "^3.0.5",
"jsbarcode": "^3.11.5",
"localforage": "^1.10.0",
"md-editor-v3": "2.7.2",
"mint-filter": "^4.0.3",
"mitt": "^3.0.1",
Expand Down
18 changes: 18 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

94 changes: 94 additions & 0 deletions src/utils/localforage/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import forage from "localforage";
import { LocalForage, ProxyStorage, ExpiresData } from "./types.d";

class StorageProxy implements ProxyStorage {
protected storage: LocalForage;
constructor(storageModel) {
this.storage = storageModel;
this.storage.config({
// driver: [forage.LOCALSTORAGE],
name: "pure-admin"
});
}

/**
* @description 将对应键名的数据保存到离线仓库
* @param k 键名
* @param v 键值
* @param m 缓存时间(单位`分`,默认`0`分钟,永久缓存)
*/
public async setItem<T>(k: string, v: T, m = 0): Promise<T> {
return new Promise((resolve, reject) => {
this.storage
.setItem(k, {
data: v,
expires: new Date().getTime() + m * 60 * 1000
})
.then(value => {
resolve(value.data);
})
.catch(err => {
reject(err);
});
});
}

/**
* @description 从离线仓库中获取对应键名的值
* @param k 键名
*/
public async getItem<T>(k: string): Promise<T> {
return new Promise((resolve, reject) => {
this.storage
.getItem(k)
.then((value: ExpiresData<T>) => {
const data =
value.expires > new Date().getTime() || value.expires === 0
? value.data
: null;
resolve(data);
})
.catch(err => {
reject(err);
});
});
}

/**
* @description 从离线仓库中删除对应键名的值
* @param k 键名
*/
public async removeItem(k: string) {
return new Promise<void>((resolve, reject) => {
this.storage
.removeItem(k)
.then(() => {
resolve();
})
.catch(err => {
reject(err);
});
});
}

/**
* @description 从离线仓库中删除所有的键名,重置数据库
*/
public async clear() {
return new Promise<void>((resolve, reject) => {
this.storage
.clear()
.then(() => {
resolve();
})
.catch(err => {
reject(err);
});
});
}
}

/**
* 二次封装 [localforage](https://localforage.docschina.org/) 支持设置过期时间,提供完整的类型提示
*/
export const localForage = () => new StorageProxy(forage);
166 changes: 166 additions & 0 deletions src/utils/localforage/types.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
// https://github.com/localForage/localForage/blob/master/typings/localforage.d.ts

interface LocalForageDbInstanceOptions {
name?: string;

storeName?: string;
}

interface LocalForageOptions extends LocalForageDbInstanceOptions {
driver?: string | string[];

size?: number;

version?: number;

description?: string;
}

interface LocalForageDbMethodsCore {
getItem<T>(
key: string,
callback?: (err: any, value: T | null) => void
): Promise<T | null>;

setItem<T>(
key: string,
value: T,
callback?: (err: any, value: T) => void
): Promise<T>;

removeItem(key: string, callback?: (err: any) => void): Promise<void>;

clear(callback?: (err: any) => void): Promise<void>;

length(callback?: (err: any, numberOfKeys: number) => void): Promise<number>;

key(
keyIndex: number,
callback?: (err: any, key: string) => void
): Promise<string>;

keys(callback?: (err: any, keys: string[]) => void): Promise<string[]>;

iterate<T, U>(
iteratee: (value: T, key: string, iterationNumber: number) => U,
callback?: (err: any, result: U) => void
): Promise<U>;
}

interface LocalForageDropInstanceFn {
(
dbInstanceOptions?: LocalForageDbInstanceOptions,
callback?: (err: any) => void
): Promise<void>;
}

interface LocalForageDriverMethodsOptional {
dropInstance?: LocalForageDropInstanceFn;
}

// duplicating LocalForageDriverMethodsOptional to preserve TS v2.0 support,
// since Partial<> isn't supported there
interface LocalForageDbMethodsOptional {
dropInstance: LocalForageDropInstanceFn;
}

interface LocalForageDriverDbMethods
extends LocalForageDbMethodsCore,
LocalForageDriverMethodsOptional {}

interface LocalForageDriverSupportFunc {
(): Promise<boolean>;
}

interface LocalForageDriver extends LocalForageDriverDbMethods {
_driver: string;

_initStorage(options: LocalForageOptions): void;

_support?: boolean | LocalForageDriverSupportFunc;
}

interface LocalForageSerializer {
serialize<T>(
value: T | ArrayBuffer | Blob,
callback: (value: string, error: any) => void
): void;

deserialize<T>(value: string): T | ArrayBuffer | Blob;

stringToBuffer(serializedString: string): ArrayBuffer;

bufferToString(buffer: ArrayBuffer): string;
}

interface LocalForageDbMethods
extends LocalForageDbMethodsCore,
LocalForageDbMethodsOptional {}

export interface LocalForage extends LocalForageDbMethods {
LOCALSTORAGE: string;
WEBSQL: string;
INDEXEDDB: string;

/**
* Set and persist localForage options. This must be called before any other calls to localForage are made, but can be called after localForage is loaded.
* If you set any config values with this method they will persist after driver changes, so you can call config() then setDriver()
* @param {LocalForageOptions} options?
*/
config(options: LocalForageOptions): boolean;
config(options: string): any;
config(): LocalForageOptions;

/**
* Create a new instance of localForage to point to a different store.
* All the configuration options used by config are supported.
* @param {LocalForageOptions} options
*/
createInstance(options: LocalForageOptions): LocalForage;

driver(): string;

/**
* Force usage of a particular driver or drivers, if available.
* @param {string} driver
*/
setDriver(
driver: string | string[],
callback?: () => void,
errorCallback?: (error: any) => void
): Promise<void>;

defineDriver(
driver: LocalForageDriver,
callback?: () => void,
errorCallback?: (error: any) => void
): Promise<void>;

/**
* Return a particular driver
* @param {string} driver
*/
getDriver(driver: string): Promise<LocalForageDriver>;

getSerializer(
callback?: (serializer: LocalForageSerializer) => void
): Promise<LocalForageSerializer>;

supports(driverName: string): boolean;

ready(callback?: (error: any) => void): Promise<void>;
}

// Customize

export interface ProxyStorage {
setItem<T>(k: string, v: T, m: number): Promise<T>;
getItem<T>(k: string): Promise<T>;
removeItem(k: string): Promise<void>;
clear(): Promise<void>;
}

export interface ExpiresData<T> {
data: T;
expires: number;
}

0 comments on commit 4020105

Please sign in to comment.