Skip to content

Commit

Permalink
perf: improve persistent logic
Browse files Browse the repository at this point in the history
  • Loading branch information
anncwb committed Feb 27, 2021
1 parent 11d3f39 commit f57eb94
Show file tree
Hide file tree
Showing 14 changed files with 295 additions and 214 deletions.
2 changes: 1 addition & 1 deletion .env
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ VITE_PORT = 3100
VITE_GLOB_APP_TITLE = Vben Admin

# spa shortname
VITE_GLOB_APP_SHORT_NAME = vue_vben_admin_2x
VITE_GLOB_APP_SHORT_NAME = vue_vben_admin
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
id: release_tag
uses: yyx990803/release-tag@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_TOKEN: ${{ secrets.OPER_TOKEN }}
with:
tag_name: ${{ github.ref }}
body: |
Expand Down
2 changes: 1 addition & 1 deletion .vscode/extensions.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"stylelint.vscode-stylelint",
"esbenp.prettier-vscode",
"mrmlnc.vscode-less",
"antfu.i18n-ally",
"lokalise.i18n-ally",
"antfu.iconify",
"mikestead.dotenv",
"heybourn.headwind"
Expand Down
10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
},
"dependencies": {
"@iconify/iconify": "^2.0.0-rc.6",
"@vueuse/core": "^4.2.2",
"@vueuse/core": "^4.3.0",
"@zxcvbn-ts/core": "^0.2.0",
"ant-design-vue": "2.0.0",
"apexcharts": "^3.25.0",
Expand All @@ -41,7 +41,7 @@
"sortablejs": "^1.13.0",
"vditor": "^3.8.1",
"vue": "3.0.5",
"vue-i18n": "9.0.0-rc.8",
"vue-i18n": "^9.0.0",
"vue-router": "^4.0.4",
"vue-types": "^3.0.2",
"vuex": "^4.0.0",
Expand All @@ -68,7 +68,7 @@
"@typescript-eslint/eslint-plugin": "^4.15.2",
"@typescript-eslint/parser": "^4.15.2",
"@vitejs/plugin-legacy": "^1.3.1",
"@vitejs/plugin-vue": "^1.1.4",
"@vitejs/plugin-vue": "^1.1.5",
"@vitejs/plugin-vue-jsx": "^1.1.2",
"@vue/compiler-sfc": "3.0.5",
"autoprefixer": "^10.2.4",
Expand Down Expand Up @@ -97,7 +97,7 @@
"stylelint-order": "^4.1.0",
"ts-node": "^9.1.1",
"typescript": "4.1.5",
"vite": "2.0.3",
"vite": "2.0.4",
"vite-plugin-compression": "^0.2.2",
"vite-plugin-html": "^2.0.2",
"vite-plugin-imagemin": "^0.2.8",
Expand All @@ -106,7 +106,7 @@
"vite-plugin-pwa": "^0.5.5",
"vite-plugin-style-import": "^0.7.5",
"vite-plugin-theme": "^0.4.8",
"vite-plugin-windicss": "0.5.3",
"vite-plugin-windicss": "0.5.4",
"vue-eslint-parser": "^7.5.0",
"yargs": "^16.2.0"
},
Expand Down
8 changes: 7 additions & 1 deletion src/enums/cacheEnum.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// token key
export const TOKEN_KEY = 'TOKEN';
export const TOKEN_KEY = 'TOKEN__';

// user info key
export const USER_INFO_KEY = 'USER__INFO__';
Expand All @@ -19,6 +19,12 @@ export const BASE_LOCAL_CACHE_KEY = 'LOCAL__CACHE__KEY__';
// base global session key
export const BASE_SESSION_CACHE_KEY = 'SESSION__CACHE__KEY__';

// base global local key
export const APP_LOCAL_CACHE_KEY = 'LOCAL__CACHE__KEY__';

// base global session key
export const APP_SESSION_CACHE_KEY = 'SESSION__CACHE__KEY__';

export enum CacheTypeEnum {
SESSION,
LOCAL,
Expand Down
4 changes: 2 additions & 2 deletions src/logics/initAppConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import type { ProjectConfig } from '/#/config';
import { PROJ_CFG_KEY } from '/@/enums/cacheEnum';

import projectSetting from '/@/settings/projectSetting';
import { getLocal } from '/@/utils/cache/persistent';
import { Persistent } from '/@/utils/cache/persistent';
import { updateHeaderBgColor, updateSidebarBgColor } from '/@/logics/theme/updateBackground';
import { updateColorWeak } from '/@/logics/theme/updateColorWeak';
import { updateGrayMode } from '/@/logics/theme/updateGrayMode';
Expand All @@ -19,7 +19,7 @@ import { primaryColor } from '../../build/config/themeConfig';

// Initial project configuration
export function initAppConfigStore() {
let projCfg: ProjectConfig = getLocal(PROJ_CFG_KEY) as ProjectConfig;
let projCfg: ProjectConfig = Persistent.getLocal(PROJ_CFG_KEY) as ProjectConfig;
projCfg = deepMerge(projectSetting, projCfg || {});
try {
const {
Expand Down
1 change: 1 addition & 0 deletions src/settings/designSetting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export default {

// app theme preset color
export const APP_PRESET_COLOR_LIST: string[] = [
'#0960bd',
'#0084f4',
'#009688',
'#536dfe',
Expand Down
9 changes: 4 additions & 5 deletions src/store/modules/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import store from '/@/store';
import { PROJ_CFG_KEY } from '/@/enums/cacheEnum';

import { hotModuleUnregisterModule } from '/@/utils/helper/vuexHelper';
import { setLocal, getLocal, clearSession, clearLocal } from '/@/utils/cache/persistent';
import { Persistent } from '/@/utils/cache/persistent';
import { deepMerge } from '/@/utils';

import { resetRouter } from '/@/router';
Expand All @@ -29,7 +29,7 @@ export default class App extends VuexModule {
private pageLoadingState = false;

// project config
private projectConfigState: ProjectConfig | null = getLocal(PROJ_CFG_KEY);
private projectConfigState: ProjectConfig | null = Persistent.getLocal(PROJ_CFG_KEY);

// set main overflow hidden
private lockMainScrollState = false;
Expand Down Expand Up @@ -59,14 +59,13 @@ export default class App extends VuexModule {
@Mutation
commitProjectConfigState(proCfg: DeepPartial<ProjectConfig>): void {
this.projectConfigState = deepMerge(this.projectConfigState || {}, proCfg);
setLocal(PROJ_CFG_KEY, this.projectConfigState);
Persistent.setLocal(PROJ_CFG_KEY, this.projectConfigState);
}

@Action
async resumeAllState() {
resetRouter();
clearSession();
clearLocal();
Persistent.clearAll();

permissionStore.commitResetState();
tabStore.commitResetState();
Expand Down
8 changes: 4 additions & 4 deletions src/store/modules/lock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import store from '/@/store';
import { LOCK_INFO_KEY } from '/@/enums/cacheEnum';

import { hotModuleUnregisterModule } from '/@/utils/helper/vuexHelper';
import { setLocal, getLocal, removeLocal } from '/@/utils/cache/persistent';
import { Persistent } from '/@/utils/cache/persistent';

import { userStore } from './user';

Expand All @@ -18,7 +18,7 @@ hotModuleUnregisterModule(NAME);
@Module({ dynamic: true, namespaced: true, store, name: NAME })
class Lock extends VuexModule {
// lock info
private lockInfoState: LockInfo | null = getLocal(LOCK_INFO_KEY);
private lockInfoState: LockInfo | null = Persistent.getLocal(LOCK_INFO_KEY);

get getLockInfo(): LockInfo {
return this.lockInfoState || ({} as LockInfo);
Expand All @@ -27,12 +27,12 @@ class Lock extends VuexModule {
@Mutation
commitLockInfoState(info: LockInfo): void {
this.lockInfoState = Object.assign({}, this.lockInfoState, info);
setLocal(LOCK_INFO_KEY, this.lockInfoState);
Persistent.setLocal(LOCK_INFO_KEY, this.lockInfoState);
}

@Mutation
resetLockInfo(): void {
removeLocal(LOCK_INFO_KEY);
Persistent.removeLocal(LOCK_INFO_KEY);
this.lockInfoState = null;
}

Expand Down
25 changes: 9 additions & 16 deletions src/store/modules/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,30 +18,23 @@ import router from '/@/router';

import { loginApi, getUserInfoById } from '/@/api/sys/user';

import { setLocal, getLocal, getSession, setSession } from '/@/utils/cache/persistent';
import { useProjectSetting } from '/@/hooks/setting';
import { Persistent, BasicKeys } from '/@/utils/cache/persistent';
import { useI18n } from '/@/hooks/web/useI18n';
import { ErrorMessageMode } from '/@/utils/http/axios/types';
import projectSetting from '/@/settings/projectSetting';

export type UserInfo = Omit<GetUserInfoByUserIdModel, 'roles'>;

const NAME = 'user';
hotModuleUnregisterModule(NAME);

const { permissionCacheType } = useProjectSetting();

function getCache<T>(key: string) {
const fn = permissionCacheType === CacheTypeEnum.LOCAL ? getLocal : getSession;
function getCache<T>(key: BasicKeys) {
const { permissionCacheType } = projectSetting;
const fn =
permissionCacheType === CacheTypeEnum.LOCAL ? Persistent.getLocal : Persistent.getSession;
return fn(key) as T;
}

function setCache(USER_INFO_KEY: string, info: any) {
if (!info) return;
setLocal(USER_INFO_KEY, info, true);
// TODO
setSession(USER_INFO_KEY, info, true);
}

@Module({ namespaced: true, name: NAME, dynamic: true, store })
class User extends VuexModule {
// user info
Expand Down Expand Up @@ -75,19 +68,19 @@ class User extends VuexModule {
@Mutation
commitUserInfoState(info: UserInfo): void {
this.userInfoState = info;
setCache(USER_INFO_KEY, info);
Persistent.setLocal(USER_INFO_KEY, info);
}

@Mutation
commitRoleListState(roleList: RoleEnum[]): void {
this.roleListState = roleList;
setCache(ROLES_KEY, roleList);
Persistent.setLocal(ROLES_KEY, roleList);
}

@Mutation
commitTokenState(info: string): void {
this.tokenState = info;
setCache(TOKEN_KEY, info);
Persistent.setLocal(TOKEN_KEY, info);
}

/**
Expand Down
22 changes: 16 additions & 6 deletions src/utils/cache/index.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,32 @@
import { getStorageShortName } from '/@/utils/env';
import { createStorage as create } from './storageCache';
import { createStorage as create, CreateStorageParams } from './storageCache';
import { enableStorageEncryption } from '/@/settings/encryptionSetting';
import { DEFAULT_CACHE_TIME } from '/@/settings/encryptionSetting';

const createOptions = (storage = sessionStorage) => {
export type Options = Partial<CreateStorageParams>;

const createOptions = (storage: Storage, options: Options = {}): Options => {
return {
// No encryption in debug mode
hasEncrypt: enableStorageEncryption,
storage,
prefixKey: getStorageShortName(),
timeout: DEFAULT_CACHE_TIME,

...options,
};
};

export const WebStorage = create(createOptions());
export const WebStorage = create(createOptions(sessionStorage));

export const createStorage = (storage: Storage = sessionStorage, options: Options = {}) => {
return create(createOptions(storage, options));
};

export const createStorage = (storage: Storage = sessionStorage) => {
return create(createOptions(storage))!;
export const createPersistentStorage = (
storage: Storage = sessionStorage,
options: Options = {}
) => {
return createStorage(storage, { ...options, timeout: DEFAULT_CACHE_TIME });
};

export default WebStorage;
98 changes: 98 additions & 0 deletions src/utils/cache/memory.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
export interface Cache<V = any> {
value?: V;
timeoutId?: ReturnType<typeof setTimeout>;
time?: number;
alive?: number;
}

const NOT_ALIVE = 0;

export class Memory<T = any, V = any> {
private cache: { [key in keyof T]?: Cache<V> } = {};
private alive: number;

constructor(alive = NOT_ALIVE) {
// Unit second
this.alive = alive * 1000;
}

get getCache() {
return this.cache;
}

setCache(cache) {
this.cache = cache;
}

// get<K extends keyof T>(key: K) {
// const item = this.getItem(key);
// const time = item?.time;
// if (!isNullOrUnDef(time) && time < new Date().getTime()) {
// this.remove(key);
// }
// return item?.value ?? undefined;
// }

get<K extends keyof T>(key: K) {
return this.cache[key];
}

set<K extends keyof T>(key: K, value: V, expires?: number) {
let item = this.get(key);

if (!expires || (expires as number) <= 0) {
expires = this.alive;
}
if (item) {
if (item.timeoutId) {
clearTimeout(item.timeoutId);
item.timeoutId = undefined;
}
item.value = value;
} else {
item = { value, alive: expires };
this.cache[key] = item;
}

if (!expires) {
return value;
}
item.time = new Date().getTime() + this.alive * 1000;
item.timeoutId = setTimeout(() => {
this.remove(key);
}, expires);

return value;
}

remove<K extends keyof T>(key: K) {
const item = this.get(key);
Reflect.deleteProperty(this.cache, key);
if (item) {
clearTimeout(item.timeoutId!);
return item.value;
}
}

resetCache(cache: { [K in keyof T]: Cache }) {
Object.keys(cache).forEach((key) => {
const k = (key as any) as keyof T;
const item = cache[k];
if (item && item.time) {
const now = new Date().getTime();
const expire = now + item.time * 1000;
if (expire > now) {
this.set(k, item.value, expire);
}
}
});
}

clear() {
Object.keys(this.cache).forEach((key) => {
const item = this.cache[key];
item.timeoutId && clearTimeout(item.timeoutId);
});
this.cache = {};
}
}
Loading

0 comments on commit f57eb94

Please sign in to comment.