fix: stylelint not work
This commit is contained in:
7
packages/@vben-core/shared/chche/build.config.ts
Normal file
7
packages/@vben-core/shared/chche/build.config.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { defineBuildConfig } from 'unbuild';
|
||||
|
||||
export default defineBuildConfig({
|
||||
clean: true,
|
||||
declaration: true,
|
||||
entries: ['src/index'],
|
||||
});
|
43
packages/@vben-core/shared/chche/package.json
Normal file
43
packages/@vben-core/shared/chche/package.json
Normal file
@@ -0,0 +1,43 @@
|
||||
{
|
||||
"name": "@vben-core/cache",
|
||||
"version": "1.0.0",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/vbenjs/vue-vben-admin.git",
|
||||
"directory": "packages/@vben-core/shared/toolkit"
|
||||
},
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"scripts": {
|
||||
"build": "pnpm unbuild",
|
||||
"stub": "pnpm unbuild --stub"
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"sideEffects": false,
|
||||
"main": "./dist/index.mjs",
|
||||
"module": "./dist/index.mjs",
|
||||
"imports": {
|
||||
"#*": "./src/*"
|
||||
},
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./src/index.ts",
|
||||
"development": "./src/index.ts",
|
||||
"default": "./dist/index.mjs"
|
||||
}
|
||||
},
|
||||
"publishConfig": {
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"default": "./dist/index.mjs"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dependencies": {},
|
||||
"devDependencies": {}
|
||||
}
|
1
packages/@vben-core/shared/chche/src/index.ts
Normal file
1
packages/@vben-core/shared/chche/src/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from './storage-cache';
|
104
packages/@vben-core/shared/chche/src/storage-cache.test.ts
Normal file
104
packages/@vben-core/shared/chche/src/storage-cache.test.ts
Normal file
@@ -0,0 +1,104 @@
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
|
||||
import { StorageCache } from './storage-cache';
|
||||
|
||||
describe('storageCache', () => {
|
||||
let localStorageCache: StorageCache;
|
||||
let sessionStorageCache: StorageCache;
|
||||
|
||||
beforeEach(() => {
|
||||
localStorageCache = new StorageCache('prefix_', 'localStorage');
|
||||
sessionStorageCache = new StorageCache('prefix_', 'sessionStorage');
|
||||
localStorage.clear();
|
||||
sessionStorage.clear();
|
||||
vi.useFakeTimers();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vi.useRealTimers();
|
||||
});
|
||||
|
||||
it('should set and get an item with prefix in localStorage', () => {
|
||||
localStorageCache.setItem('testKey', 'testValue');
|
||||
const value = localStorageCache.getItem<string>('testKey');
|
||||
expect(value).toBe('testValue');
|
||||
expect(localStorage.getItem('prefix_testKey')).not.toBeNull();
|
||||
});
|
||||
|
||||
it('should set and get an item with prefix in sessionStorage', () => {
|
||||
sessionStorageCache.setItem('testKey', 'testValue');
|
||||
const value = sessionStorageCache.getItem<string>('testKey');
|
||||
expect(value).toBe('testValue');
|
||||
expect(sessionStorage.getItem('prefix_testKey')).not.toBeNull();
|
||||
});
|
||||
|
||||
it('should return null for expired item in localStorage', () => {
|
||||
localStorageCache.setItem('testKey', 'testValue', 1 / 60); // 1 second expiry
|
||||
vi.advanceTimersByTime(2000); // Fast-forward 2 seconds
|
||||
const value = localStorageCache.getItem<string>('testKey');
|
||||
expect(value).toBeNull();
|
||||
});
|
||||
|
||||
it('should return null for expired item in sessionStorage', () => {
|
||||
sessionStorageCache.setItem('testKey', 'testValue', 1 / 60); // 1 second expiry
|
||||
vi.advanceTimersByTime(2000); // Fast-forward 2 seconds
|
||||
const value = sessionStorageCache.getItem<string>('testKey');
|
||||
expect(value).toBeNull();
|
||||
});
|
||||
|
||||
it('should remove an item with prefix in localStorage', () => {
|
||||
localStorageCache.setItem('testKey', 'testValue');
|
||||
localStorageCache.removeItem('testKey');
|
||||
const value = localStorageCache.getItem<string>('testKey');
|
||||
expect(value).toBeNull();
|
||||
expect(localStorage.getItem('prefix_testKey')).toBeNull();
|
||||
});
|
||||
|
||||
it('should remove an item with prefix in sessionStorage', () => {
|
||||
sessionStorageCache.setItem('testKey', 'testValue');
|
||||
sessionStorageCache.removeItem('testKey');
|
||||
const value = sessionStorageCache.getItem<string>('testKey');
|
||||
expect(value).toBeNull();
|
||||
expect(sessionStorage.getItem('prefix_testKey')).toBeNull();
|
||||
});
|
||||
|
||||
it('should clear all items in localStorage', () => {
|
||||
localStorageCache.setItem('testKey1', 'testValue1');
|
||||
localStorageCache.setItem('testKey2', 'testValue2');
|
||||
localStorageCache.clear();
|
||||
expect(localStorageCache.length()).toBe(0);
|
||||
});
|
||||
|
||||
it('should clear all items in sessionStorage', () => {
|
||||
sessionStorageCache.setItem('testKey1', 'testValue1');
|
||||
sessionStorageCache.setItem('testKey2', 'testValue2');
|
||||
sessionStorageCache.clear();
|
||||
expect(sessionStorageCache.length()).toBe(0);
|
||||
});
|
||||
|
||||
it('should return correct length in localStorage', () => {
|
||||
localStorageCache.setItem('testKey1', 'testValue1');
|
||||
localStorageCache.setItem('testKey2', 'testValue2');
|
||||
expect(localStorageCache.length()).toBe(2);
|
||||
});
|
||||
|
||||
it('should return correct length in sessionStorage', () => {
|
||||
sessionStorageCache.setItem('testKey1', 'testValue1');
|
||||
sessionStorageCache.setItem('testKey2', 'testValue2');
|
||||
expect(sessionStorageCache.length()).toBe(2);
|
||||
});
|
||||
|
||||
it('should return correct key by index in localStorage', () => {
|
||||
localStorageCache.setItem('testKey1', 'testValue1');
|
||||
localStorageCache.setItem('testKey2', 'testValue2');
|
||||
expect(localStorageCache.key(0)).toBe('prefix_testKey1');
|
||||
expect(localStorageCache.key(1)).toBe('prefix_testKey2');
|
||||
});
|
||||
|
||||
it('should return correct key by index in sessionStorage', () => {
|
||||
sessionStorageCache.setItem('testKey1', 'testValue1');
|
||||
sessionStorageCache.setItem('testKey2', 'testValue2');
|
||||
expect(sessionStorageCache.key(0)).toBe('prefix_testKey1');
|
||||
expect(sessionStorageCache.key(1)).toBe('prefix_testKey2');
|
||||
});
|
||||
});
|
145
packages/@vben-core/shared/chche/src/storage-cache.ts
Normal file
145
packages/@vben-core/shared/chche/src/storage-cache.ts
Normal file
@@ -0,0 +1,145 @@
|
||||
import type { IStorageCache, StorageType, StorageValue } from './types';
|
||||
|
||||
class StorageCache implements IStorageCache {
|
||||
protected prefix: string;
|
||||
protected storage: Storage;
|
||||
|
||||
constructor(prefix: string = '', storageType: StorageType = 'localStorage') {
|
||||
this.prefix = prefix;
|
||||
this.storage =
|
||||
storageType === 'localStorage' ? localStorage : sessionStorage;
|
||||
}
|
||||
|
||||
// 获取带前缀的键名
|
||||
private getFullKey(key: string): string {
|
||||
return this.prefix + key;
|
||||
}
|
||||
|
||||
// 获取项之后的钩子方法
|
||||
protected afterGetItem<T>(_key: string, _value: T | null): void {}
|
||||
|
||||
// 设置项之后的钩子方法
|
||||
protected afterSetItem<T>(
|
||||
_key: string,
|
||||
_value: T,
|
||||
_expiryInMinutes?: number,
|
||||
): void {}
|
||||
|
||||
// 获取项之前的钩子方法
|
||||
protected beforeGetItem(_key: string): void {}
|
||||
|
||||
// 设置项之前的钩子方法
|
||||
protected beforeSetItem<T>(
|
||||
_key: string,
|
||||
_value: T,
|
||||
_expiryInMinutes?: number,
|
||||
): void {}
|
||||
|
||||
/**
|
||||
* 清空存储
|
||||
*/
|
||||
clear(): void {
|
||||
try {
|
||||
this.storage.clear();
|
||||
} catch (error) {
|
||||
console.error('Error clearing storage', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取存储项
|
||||
* @param key 存储键
|
||||
* @returns 存储值或 null
|
||||
*/
|
||||
getItem<T>(key: string): T | null {
|
||||
const fullKey = this.getFullKey(key);
|
||||
this.beforeGetItem(fullKey);
|
||||
|
||||
let value: T | null = null;
|
||||
try {
|
||||
const item = this.storage.getItem(fullKey);
|
||||
if (item) {
|
||||
const storageValue: StorageValue<T> = JSON.parse(item);
|
||||
if (storageValue.expiry && storageValue.expiry < Date.now()) {
|
||||
this.storage.removeItem(fullKey);
|
||||
} else {
|
||||
value = storageValue.data;
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error getting item from storage', error);
|
||||
}
|
||||
|
||||
this.afterGetItem(fullKey, value);
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取存储中的键
|
||||
* @param index 键的索引
|
||||
* @returns 存储键或 null
|
||||
*/
|
||||
key(index: number): null | string {
|
||||
try {
|
||||
return this.storage.key(index);
|
||||
} catch (error) {
|
||||
console.error('Error getting key from storage', error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取存储项的数量
|
||||
* @returns 存储项的数量
|
||||
*/
|
||||
length(): number {
|
||||
try {
|
||||
return this.storage.length;
|
||||
} catch (error) {
|
||||
console.error('Error getting storage length', error);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除存储项
|
||||
* @param key 存储键
|
||||
*/
|
||||
removeItem(key: string): void {
|
||||
const fullKey = this.getFullKey(key);
|
||||
try {
|
||||
this.storage.removeItem(fullKey);
|
||||
} catch (error) {
|
||||
console.error('Error removing item from storage', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置存储项
|
||||
* @param key 存储键
|
||||
* @param value 存储值
|
||||
* @param expiryInMinutes 过期时间(分钟)
|
||||
*/
|
||||
setItem<T>(key: string, value: T, expiryInMinutes?: number): void {
|
||||
const fullKey = this.getFullKey(key);
|
||||
this.beforeSetItem(fullKey, value, expiryInMinutes);
|
||||
|
||||
const now = Date.now();
|
||||
const expiry = expiryInMinutes ? now + expiryInMinutes * 60_000 : null;
|
||||
|
||||
const storageValue: StorageValue<T> = {
|
||||
data: value,
|
||||
expiry,
|
||||
};
|
||||
|
||||
try {
|
||||
this.storage.setItem(fullKey, JSON.stringify(storageValue));
|
||||
} catch (error) {
|
||||
console.error('Error setting item in storage', error);
|
||||
}
|
||||
|
||||
this.afterSetItem(fullKey, value, expiryInMinutes);
|
||||
}
|
||||
}
|
||||
|
||||
export { StorageCache };
|
17
packages/@vben-core/shared/chche/src/types.ts
Normal file
17
packages/@vben-core/shared/chche/src/types.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
type StorageType = 'localStorage' | 'sessionStorage';
|
||||
|
||||
interface StorageValue<T> {
|
||||
data: T;
|
||||
expiry: null | number;
|
||||
}
|
||||
|
||||
interface IStorageCache {
|
||||
clear(): void;
|
||||
getItem<T>(key: string): T | null;
|
||||
key(index: number): null | string;
|
||||
length(): number;
|
||||
removeItem(key: string): void;
|
||||
setItem<T>(key: string, value: T, expiryInMinutes?: number): void;
|
||||
}
|
||||
|
||||
export type { IStorageCache, StorageType, StorageValue };
|
5
packages/@vben-core/shared/chche/tsconfig.json
Normal file
5
packages/@vben-core/shared/chche/tsconfig.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/tsconfig",
|
||||
"extends": "@vben/tsconfig/library.json",
|
||||
"include": ["src"]
|
||||
}
|
Reference in New Issue
Block a user