import { createAPI, t, registerCanIUse } from './base'; import { createCommands, getH5ApiHost } from '@jolibox/common'; import { httpClientManager } from '@/h5/http'; import { context } from '@/common/context'; import { StorageResponse } from '@jolibox/types'; import localForage from 'localforage'; const commands = createCommands(); export class JoliboxCloudStorage { private gameId: string; private httpClient = httpClientManager.create({ baseUrl: getH5ApiHost(context.testMode) }); private gameStore: LocalForage; constructor() { this.gameId = this.getGameId(); //没有game的情况使用全局空间 this.gameStore = localForage.createInstance({ name: this.gameId.length ? this.gameId : 'default' }); } /** * Cloud storage getItem api */ private getGameId = () => context.mpId; /** * * @param key getItem key */ getItem = async (key: string): Promise> => { const { code, data: originData, message } = await this.httpClient.get< StorageResponse<{ key: string; value: string | null; }> >(`/api/games/user-storage/${this.gameId}`, { query: { key } }); let data = originData?.value; let fallbackmsg = message; if (code !== 'SUCCESS') { // Only when data cannot be retrieved from the cloud should it be read locally. data = await this.gameStore.getItem(key); console.info('[SDK] cloud storage getItem failed, read from localstorage', data); fallbackmsg += 'fallback to localstorage'; } const res = { code, message: fallbackmsg, data: data && data !== 'undefined' ? data : null }; return res; }; /** * Cloud storage setItem api * @param progress - The progress of the loading, should be an integer between 0 and 100 */ setItem = async (key: string, value: string | boolean | number): Promise> => { const valueToStore = typeof value == 'string' ? value : String(value); //Regardless of whether the cloud operation is successful, corresponding changes should be made locally. const { code, message } = await this.httpClient.post(`/api/games/user-storage/${this.gameId}`, { data: { key, value: valueToStore } }); await this.gameStore.setItem(key, valueToStore); return { code, message }; }; removeItem = async (key: string): Promise> => { await this.gameStore.removeItem(key); const { code, message } = await this.httpClient.post(`/api/games/user-storage/${this.gameId}/remove`, { data: { key } }); return { code, message }; }; clear = async (): Promise> => { await this.gameStore.clear(); const { code, message } = await this.httpClient.post(`/api/games/user-storage/${this.gameId}/clear`, {}); return { code, message }; }; } const storageImpl = new JoliboxCloudStorage(); const getStorage = createAPI('getLocalStorage', { paramsSchema: t.tuple(t.string()), async implement(key) { return await storageImpl.getItem(key); } }); commands.registerCommand('StorageSDK.getItem', getStorage); registerCanIUse('storage.getItem', { version: '1.0.0', properties: { key: '1.0.0', value: '1.0.0' } }); const setStorage = createAPI('setStorage', { paramsSchema: t.tuple(t.string(), t.or(t.string(), t.boolean(), t.number())), async implement(key, value) { return await storageImpl.setItem(key, value); } }); commands.registerCommand('StorageSDK.setItem', setStorage); registerCanIUse('storage.setItem', { version: '1.0.0', properties: { key: '1.0.0', value: '1.0.0' } }); /** * 移除指定key */ export const removeStorage = createAPI('removeStorage', { paramsSchema: t.tuple(t.string()), async implement(key) { return await storageImpl.removeItem(key); } }); commands.registerCommand('StorageSDK.removeItem', removeStorage); registerCanIUse('storage.removeItem', { version: '1.0.0', properties: { key: '1.0.0' } }); /** * 清理本地数据缓存 */ const clearStorage = createAPI('clearStorage', { async implement() { return await storageImpl.clear(); } }); commands.registerCommand('StorageSDK.clear', clearStorage); registerCanIUse('storage.clear', { version: '1.0.0' });