refactor: storage factory + singleton

- Make storage easier.

(cherry picked from commit ed84a4732d7dd3ce6b2c22f30553ab5c59f85dbb)
This commit is contained in:
鲁树人 2021-12-20 22:19:44 +00:00
parent 8673adfda6
commit d8b362efbe
8 changed files with 81 additions and 8 deletions

View File

@ -13,7 +13,7 @@
</template>
<script>
import storage from '../utils/storage';
import { storage } from '@/utils/storage';
export default {
components: {},

View File

@ -2,8 +2,8 @@ import { DecryptResult } from './entity';
import { AudioMimeType, GetArrayBuffer, SniffAudioExt } from './utils';
import jooxFactory from '@unlock-music/joox-crypto';
import storage from '@/utils/storage';
import { MergeUint8Array } from '@/utils/MergeUint8Array';
import { storage } from '@/utils/storage';
export async function Decrypt(file: Blob, raw_filename: string, raw_ext: string): Promise<DecryptResult> {
const uuid = await storage.loadJooxUUID('');

View File

@ -1,7 +1,3 @@
import BaseStorage from './storage/BaseStorage';
import BrowserNativeStorage from './storage/BrowserNativeStorage';
import ChromeExtensionStorage from './storage/ChromeExtensionStorage';
import storageFactory from './storage/StorageFactory';
const storage: BaseStorage = ChromeExtensionStorage.works ? new ChromeExtensionStorage() : new BrowserNativeStorage();
export default storage;
export const storage = storageFactory();

View File

@ -3,6 +3,8 @@ const KEY_JOOX_UUID = 'joox.uuid';
export default abstract class BaseStorage {
protected abstract save<T>(name: string, value: T): Promise<void>;
protected abstract load<T>(name: string, defaultValue: T): Promise<T>;
public abstract getAll(): Promise<Record<string, any>>;
public abstract setAll(obj: Record<string, any>): Promise<void>;
public saveJooxUUID(uuid: string): Promise<void> {
return this.save(KEY_JOOX_UUID, uuid);

View File

@ -1,6 +1,10 @@
import BaseStorage from './BaseStorage';
export default class BrowserNativeStorage extends BaseStorage {
public static get works() {
return typeof localStorage !== 'undefined' && localStorage.getItem;
}
protected async load<T>(name: string, defaultValue: T): Promise<T> {
const result = localStorage.getItem(name);
if (result === null) {
@ -12,4 +16,18 @@ export default class BrowserNativeStorage extends BaseStorage {
protected async save<T>(name: string, value: T): Promise<void> {
localStorage.setItem(name, JSON.stringify(value));
}
public async getAll(): Promise<Record<string, any>> {
const result = {};
for (const [key, value] of Object.entries(localStorage)) {
Object.assign(result, { [key]: JSON.parse(value) });
}
return result;
}
public async setAll(obj: Record<string, any>): Promise<void> {
for (const [key, value] of Object.entries(obj)) {
localStorage.setItem(key, JSON.stringify(value));
}
}
}

View File

@ -24,4 +24,16 @@ export default class ChromeExtensionStorage extends BaseStorage {
chrome.storage.local.set({ [name]: value }, resolve);
});
}
public async getAll(): Promise<Record<string, any>> {
return new Promise((resolve) => {
chrome.storage.local.get(null, resolve);
});
}
public async setAll(obj: Record<string, any>): Promise<void> {
return new Promise((resolve) => {
chrome.storage.local.set(obj, resolve);
});
}
}

View File

@ -0,0 +1,32 @@
import BaseStorage from './BaseStorage';
export default class InMemoryStorage extends BaseStorage {
private values = new Map<string, any>();
protected async load<T>(name: string, defaultValue: T): Promise<T> {
if (this.values.has(name)) {
return this.values.get(name);
}
return defaultValue;
}
protected async save<T>(name: string, value: T): Promise<void> {
this.values.set(name, value);
}
public async getAll(): Promise<Record<string, any>> {
const result = {};
this.values.forEach((value, key) => {
Object.assign(result, {
[key]: value,
});
});
return result;
}
public async setAll(obj: Record<string, any>): Promise<void> {
for (const [key, value] of Object.entries(obj)) {
this.values.set(key, value);
}
}
}

View File

@ -0,0 +1,13 @@
import BaseStorage from './BaseStorage';
import BrowserNativeStorage from './BrowserNativeStorage';
import ChromeExtensionStorage from './ChromeExtensionStorage';
import InMemoryStorage from './InMemoryStorage';
export default function storageFactory(): BaseStorage {
if (ChromeExtensionStorage.works) {
return new ChromeExtensionStorage();
} else if (BrowserNativeStorage.works) {
return new BrowserNativeStorage();
}
return new InMemoryStorage();
}