UNPKG

vite-uni-dev-tool

Version:

vite-uni-dev-tool, debug, uni-app, 一处编写,到处调试

733 lines (620 loc) 18.6 kB
import type { DevTool } from '../type'; import { DEV_TOOL_INFO } from '../const'; import { isNil, isNumber, setValueByPath, getLanIp, getMicroAppIp, getWifiIp, isBoolean, } from '../utils/index'; import { backup } from '../core'; import { getDevToolInfo, setDevToolInfo } from '../devToolInfo'; /** 数据存储中心 */ export class DevStore { /** 状态数据 */ private state: DevTool.WindowData = { consoleList: [], networkList: [], storageList: [], routeList: [], vuexList: {}, piniaList: {}, deviceInfo: {}, windowInfo: {}, systemInfo: {}, appInfo: {}, wsList: [], netWorkStatus: {}, uploadList: [], eventList: [], eventCount: { on: 0, once: 0, emit: 0, off: 0, }, captureScreenList: [], }; /** 调试配置 */ private devToolOptions: DevTool.DevToolOptions | undefined; /** 日志最大值 */ private uploadMaxSize = 1000; /** 日志最大值 */ private consoleMaxSize = 1000; /** 网络最大值 */ private networkMaxSize = 1000; /** ws数据最大值 */ private wsDataMaxSize = 1000; /** 事件列表最大值 */ private eventListMaxSize = 1000; /** 截屏最大值 */ private captureScreenMaxSize = 1000; /** 缓存最大值 */ cacheMaxSize = 8 * 1024 * 1024 * 10; private vuexStore: any; private piniaStore: any; private uploadTaskMap = new Map<number | string, UniApp.UploadTask>(); private requestIndex = -1; private uploadIndex = -1; /** 是否显示按钮 */ private devToolVisible = false; /** 是否销毁 */ private devToolDestroy = false; /** 是否开启拦截Promise reject错误 */ enableInterceptPromiseReject = false; private zIndex = 1000; constructor() { const { devToolDestroy = false, devToolButtonVisible = false } = uni.getStorageSync(DEV_TOOL_INFO); this.devToolDestroy = devToolDestroy; this.devToolVisible = devToolButtonVisible; } setDevToolVisible(visible: boolean) { this.devToolVisible = visible; setDevToolInfo({ devToolButtonVisible: visible, }); } getDevToolVisible() { return this.devToolVisible; } setWindowInfo(windowInfo: Record<string, any>) { this.state.windowInfo = windowInfo; } setDeviceInfo(deviceInfo: Record<string, any>) { this.state.deviceInfo = deviceInfo; } setSystemInfo(systemInfo: Record<string, any>) { this.state.systemInfo = systemInfo; } setNetWorkStatus(netWorkStatus: Record<string, any>) { this.state.netWorkStatus = netWorkStatus; } setVuexList(vuexList: Record<string, any>) { this.state.vuexList = vuexList; } setPiniaList(piniaList: Record<string, any>) { this.state.piniaList = { ...(this.state.piniaList || {}), ...piniaList, }; } setRequestIndex(index: number) { this.requestIndex = index; return this.requestIndex; } getDevToolOptions() { return this.devToolOptions; } getRequestIndex() { return this.requestIndex; } setUploadIndex(index: number) { this.uploadIndex = index; return this.uploadIndex; } getUploadIndex() { return this.uploadIndex; } setDevToolOptions(options: DevTool.DevToolOptions) { this.devToolOptions = options; this.uploadMaxSize = options.uploadMaxSize || 1000; this.consoleMaxSize = options.consoleMaxSize || 1000; this.networkMaxSize = options.networkMaxSize || 1000; this.wsDataMaxSize = options.wsDataMaxSize || 1000; this.cacheMaxSize = options.cacheMaxSize || 8 * 1024 * 1024 * 10; this.eventListMaxSize = options.eventListMaxSize || 1000; this.captureScreenMaxSize = options.captureScreenMaxSize || 1000; this.zIndex = options.zIndex || 1000; const { devToolButtonVisible } = getDevToolInfo(); this.devToolVisible = isBoolean(devToolButtonVisible) ? devToolButtonVisible : (options.initShowDevTool ?? true); this.setDevToolVisible(this.devToolVisible); const pages = options.pagesJson?.pages.map((page) => { const isNav = options.pagesJson?.tabBar?.list?.some( (nav) => nav.pagePath === page.path, ); return { ...page, type: isNav ? 'nav' : 'main', }; }) ?? []; // 处理 subPackages options.pagesJson?.subPackages?.forEach((pack) => { pack.pages.forEach((page) => { const p = { ...page, path: `${pack.root}/${page.path}`, type: 'sub', }; pages.push(p); }); }); this.setRouteList(pages); } async getDevData() { const networkType = await uni.getNetworkType(); const systemInfo = uni.getSystemInfoSync(); const deviceInfo = uni.getDeviceInfo(); const windowInfo = uni.getWindowInfo(); const appInfo = { ...(await uni.getAppBaseInfo()), // #ifndef H5 ...(await uni.getAppAuthorizeSetting()), // #endif }; const ip = getWifiIp() || getLanIp() || (await getMicroAppIp()); return { ...this.state, systemInfo, deviceInfo, windowInfo, devToolVisible: this.getDevToolVisible(), appInfo, netWorkStatus: { ip, ...networkType, isConnected: networkType.networkType !== 'none', }, }; } updateStore(data: { key: string; _oldKey: string; value: any }) { const { key, _oldKey, value } = data; if (_oldKey !== key) { uni.removeStorageSync(_oldKey); this.state.storageList = this.state.storageList?.filter( (item) => item.key === _oldKey, ); } uni.setStorageSync(key, value); this.state.storageList?.push({ key, _oldKey, value, }); return this.state.storageList; } updateVuexStore(data: Record<string, any>) { try { // 更改vuex数据 Object.assign(this.vuexStore?.state ?? {}, data); } catch (error) { console.error('[DevTool] updateVuexStore error', error); } // 更新vuexList this.setVuexList({ ...(this.vuexStore?.state ?? {}), }); return this.state.vuexList; } setPiniaStore(piniaStore: any) { this.piniaStore = piniaStore; } updatePiniaStore(data: Record<string, any>) { try { if (!this.piniaStore) { console.error('[DevTool] updatePiniaStore piniaStore is undefined'); return {}; } const [key, value] = Object.entries(data)[0]; if (isNil(key)) { console.error('[DevTool] updatePiniaStore key is undefined or null'); return {}; } setValueByPath(this.piniaStore.state.value, key, value); this.setPiniaList({ ...(this.piniaStore.state.value ?? {}), }); } catch (error) { console.error('[DevTool] updatePiniaStore error', error); } return this.state.piniaList ?? {}; } getExportData(exports: { exportLog: boolean; exportNetwork: boolean; exportStorage: boolean; exportWebSocket: boolean; exportUpload: boolean; exportWindow: boolean; exportDevice: boolean; exportSystem: boolean; }) { const data: DevTool.WindowData = {}; if (exports.exportLog) { data['consoleList'] = this.state.consoleList; } if (exports.exportNetwork) { data['networkList'] = this.state.networkList; } if (exports.exportStorage) { data['storageList'] = this.state.storageList; data['vuexList'] = this.state.vuexList; data['piniaList'] = this.state.piniaList; } if (exports.exportUpload) { data['uploadList'] = this.state.uploadList; } if (exports.exportWebSocket) { data['wsList'] = this.state.wsList; } if (exports.exportWindow) { data['windowInfo'] = this.state.windowInfo; } if (exports.exportDevice) { data['deviceInfo'] = this.state.deviceInfo; } if (exports.exportSystem) { data['systemInfo'] = this.state.systemInfo; } return data; } clearConsoleList() { this.state.consoleList = []; } clearDevCache() { this.state.consoleList = []; this.state.networkList = []; this.state.wsList = []; this.state.uploadList = []; this.state.eventList = []; this.state.eventCount = { on: 0, once: 0, emit: 0, off: 0, }; } clearAll() { this.state.consoleList = []; this.state.networkList = []; this.state.storageList = []; this.state.routeList = []; this.state.wsList = []; this.state.uploadList = []; this.state.vuexList = {}; this.state.piniaList = {}; this.state.deviceInfo = {}; this.state.windowInfo = {}; this.state.systemInfo = {}; this.state.netWorkStatus = {}; this.state.appInfo = {}; this.state.eventList = []; this.state.eventCount = { on: 0, once: 0, emit: 0, off: 0, }; this.state.captureScreenList = []; } addUploadTask(index: number | string, task: UniApp.UploadTask) { this.uploadTaskMap.set(index, task); } removeUploadTask(index: number | string) { this.uploadTaskMap.delete(index); } clearUploadTask() { this.uploadTaskMap.clear(); } clearWsList() { this.state.wsList = []; } updateWsList(item: DevTool.WS) { if (!this.getDevToolVisible()) { return []; } const index = this.state?.wsList?.findIndex((w) => w.url === item.url) ?? -1; if (index > -1) { if (this.state.wsList?.[index]) { const ws = this.state.wsList[index]; ws.headers = item.headers ?? ws.headers; ws.readyState = item.readyState ?? ws.readyState; ws.method = item.method ?? ws.method; ws.protocols = item.protocols ?? ws.protocols; ws.message = [ ...(this.state.wsList[index].message ?? []), ...(item.message ?? []), ]; const max = this.wsDataMaxSize; const len = ws?.message?.length ?? 0; if (Array.isArray(ws?.message) && len > max) { ws?.message?.splice(0, len - max); } } } else { this.state.wsList?.push(item); } return this.state.wsList; } clearWsMessage(url: string) { const wsIndex = this.state?.wsList?.findIndex((item) => item.url === url) ?? -1; if (wsIndex === -1) return; if (this.state.wsList?.[wsIndex]) { this.state.wsList[wsIndex].message = []; } } clearStorageList() { this.state.storageList = []; uni.clearStorage(); return this.state.storageList; } setStorageList(items: DevTool.StorageItem[]) { if (!this.getDevToolVisible()) return; this.state.storageList = items; return this.state.storageList; } removeStorage(key: string) { this.state.storageList = this.state.storageList?.filter((item) => item.key !== key) ?? []; uni.removeStorageSync(key); return this.state.storageList; } addStorage(data: { key: string; value: any }) { const { key, value } = data; this.state.storageList?.unshift({ key, _oldKey: key, value, }); uni.setStorageSync(key, value); return this.state.storageList; } refreshStore() { const { keys } = uni.getStorageInfoSync(); this.state.storageList = keys.map((key) => { const value = uni.getStorageSync(key); return { key, _oldKey: key, value, }; }); return this.state.storageList; } updateStoreList(addItems: DevTool.StorageItem[]) { const cur = addItems[0]; const index = this.state.storageList?.findIndex((item) => item.key === cur._oldKey) ?? -1; if (index > -1 && addItems.length === 1) { if (this.state.storageList?.[index]) { this.state.storageList[index] = addItems[0]; } } else { this.state.storageList?.push(...addItems); } return this.state.storageList; } setRouteList(pages: DevTool.Page[], currentPath?: string) { if (!this.getDevToolVisible()) return; const currentP = currentPath || pages?.[0]?.path || ''; this.state.routeList = pages.map((item, index) => { return { type: item.type, path: item.path, style: item.style, index: item.path === currentP && index === 0 ? 4 : item.path === currentP ? 3 : index === 0 ? 2 : 1, name: item.style.navigationBarTitleText || '无名', }; }); return this.state.routeList; } getRouteList() { return this.state.routeList; } updateCurrentPagePath(path: string) { if (!this.getDevToolVisible()) return; path = path === '/' ? (this.state.routeList?.[0]?.path ?? path) : path; this.state.routeList = this.state.routeList?.map((item, index) => { return { type: item.type, path: item.path, style: item.style, index: item.path === path && index === 0 ? 4 : item.path === path ? 3 : index === 0 ? 2 : 1, name: item.style.navigationBarTitleText || '无名', }; }) ?? []; return this.state.routeList; } setConsoleList(items: DevTool.ConsoleItem[]) { if (!this.getDevToolVisible()) return; if ( (this.state?.consoleList?.length ?? 0) + items.length > this.consoleMaxSize ) { this.state.consoleList = []; } this.state.consoleList = items; } updateConsoleList(addItems: DevTool.ConsoleItem[], index?: number) { if (!this.getDevToolVisible()) return; if (isNumber(index) && index > -1 && addItems.length === 1) { if (this.state.consoleList?.[index]) { this.state.consoleList[index] = addItems[0]; } } else { if ( (this.state?.consoleList?.length ?? 0) + addItems.length > this.cacheMaxSize ) { this.state.consoleList?.splice( 0, this.state.consoleList.length - this.cacheMaxSize - addItems.length, ); } this.state?.consoleList?.push(...addItems); } return this.state.consoleList; } clearNetworkList() { this.state.networkList = []; } setNetworkList(items: DevTool.NetworkItem[]) { if (!this.getDevToolVisible()) return; if ( (this.state?.networkList?.length ?? 0) + items.length > this.networkMaxSize ) { this.state.networkList = []; } this.state.networkList = items; } updateNetworkList(addItems: DevTool.NetworkItem[], index?: number) { if (isNumber(index) && index > -1) { if (this.state?.networkList?.[index]) { this.state.networkList[index] = addItems[0]; } } else { const max = this.networkMaxSize; const len = this.state?.networkList?.length ?? 0; if (len + addItems.length > max) { this.state.networkList?.splice(0, len - max - addItems.length); } this.state?.networkList?.push(...addItems); } return this.state.networkList; } updateUploadList(addItems: DevTool.UploadItem[], index?: number) { if (isNumber(index) && index > -1 && addItems.length === 1) { if (this.state.uploadList?.[index]) { this.state.uploadList[index] = { ...this.state.uploadList[index], ...addItems[0], }; } else { const max = this.uploadMaxSize; const len = this.state?.uploadList?.length ?? 0; if (len + addItems.length > max) { this.state.uploadList?.splice(0, len - max - addItems.length); } this.state.uploadList?.push(addItems[0]); } } return this.state.uploadList; } clearUploadList() { this.state.uploadList = []; } setDevToolDestroy(destroy: boolean) { this.devToolDestroy = destroy; setDevToolInfo({ devToolDestroy: destroy, }); } getDevToolDestroy() { const { devToolDestroy = false } = uni.getStorageSync(DEV_TOOL_INFO); return this.devToolDestroy ?? devToolDestroy; } getCurrentPagePath() { let pages = getCurrentPages(); let item = pages[pages.length - 1]; if (item && item.route) { return item.route; } return ''; } /** * 新增事件 * * @param {DevTool.EventItem} event * @memberof DevStore */ addEventItem(event: DevTool.EventItem) { if (!this.state.eventList) { this.state.eventList = []; } this.state.eventList?.push(event); } /** * 增加注册事件的数量 * * @param {DevTool.EventCountKey} type * @memberof DevStore */ updateUniEventCount(type: DevTool.EventCountKey) { if (!this.state.eventCount) { this.state.eventCount = { on: 0, once: 0, emit: 0, off: 0, }; } this.state.eventCount[type] = this.state.eventCount[type] + 1; } updateUniEventList(evenList: DevTool.EventItem[]) { const len = this.state.eventList?.length ?? 0; const max = this.eventListMaxSize; if (len + evenList.length > max) { this.state.eventList?.splice(0, len - max - evenList.length); } this.state.eventList?.push(...evenList); return this.state.eventList; } uniEventClear() { this.state.eventCount = { on: 0, once: 0, emit: 0, off: 0, }; this.state.eventList = []; } updateCaptureScreenList(captureScreenList: DevTool.CaptureScreenItem[]) { const len = this.state.captureScreenList?.length ?? 0; const max = this.captureScreenMaxSize; if (len + captureScreenList.length > max) { this.state.captureScreenList?.splice( 0, len - max - captureScreenList.length, ); } this.state.captureScreenList?.push(...captureScreenList); return this.state.captureScreenList; } clearCaptureScreenList() { this.state.captureScreenList = []; } }