UNPKG

@sdc-monitor/demo

Version:

<div align="center"> <a href="#" target="_blank"> <img src="https://i.loli.net/2021/07/28/EvPwd4NjVH3tBfO.jpg" alt="mito-logo" height="90"> </a> <p>A Lightweight SDK For Monitor Web</p>

195 lines (171 loc) 6.44 kB
import { noop, getPageUrl, getDeviceId } from '../utils' import { generateUUID, toStringValidateOption } from '@sdc-monitor/utils' import { WxPerformanceDataType, WxPerformanceItemType } from '../constant' import Event from './event' import { WxPerformanceData, WxPerformanceAnyObj, WxPerformanceInitOptions, WxNetworkType, WxPerformanceItem, WxPerformanceEntryObj } from '../types/index' import { ToStringTypes } from '@sdc-monitor/shared' class Store extends Event { appId: string report: (data: Array<WxPerformanceData>) => void immediately?: boolean ignoreUrl?: RegExp maxBreadcrumbs?: number private stack: Array<WxPerformanceData> // wx getBatteryInfo: () => WechatMiniprogram.GetBatteryInfoSyncResult getNetworkType: <T extends WechatMiniprogram.GetNetworkTypeOption = WechatMiniprogram.GetNetworkTypeOption>( option?: T ) => WechatMiniprogram.PromisifySuccessResult<T, WechatMiniprogram.GetNetworkTypeOption> systemInfo: WechatMiniprogram.SystemInfo // 小程序launch时间 wxLaunchTime: number // 首次点击标志位 private firstAction = false // 路由跳转start时间记录 private navigationMap: WxPerformanceAnyObj = {} constructor(options: WxPerformanceInitOptions) { super() const { appId, report, maxBreadcrumbs, immediately, ignoreUrl } = options toStringValidateOption(appId, 'appId', ToStringTypes.String) && (this.appId = appId) toStringValidateOption(maxBreadcrumbs, 'maxBreadcrumbs', ToStringTypes.Number) && (this.maxBreadcrumbs = maxBreadcrumbs) toStringValidateOption(ignoreUrl, 'ignoreUrl', ToStringTypes.RegExp) && (this.ignoreUrl = ignoreUrl) toStringValidateOption(immediately, 'immediately', ToStringTypes.Boolean) && (this.immediately = immediately) this.report = toStringValidateOption(report, 'report', ToStringTypes.Function) ? report : noop this.stack = [] } // eslint-disable-next-line @typescript-eslint/require-await async _pushData(data: Array<WxPerformanceData>) { if (this.immediately) { this.report(data) return } this.stack = this.stack.concat(data) if (this.stack.length >= this.maxBreadcrumbs) { this.reportLeftData() } } // eslint-disable-next-line @typescript-eslint/require-await async reportLeftData() { this.report([...this.stack]) this.stack = [] } _getSystemInfo(): WechatMiniprogram.SystemInfo { !this.systemInfo && (this.systemInfo = wx.getSystemInfoSync()) return this.systemInfo } async _getNetworkType(): Promise<WxNetworkType> { let nk = { networkType: 'none', errMsg: '' } as WechatMiniprogram.GetNetworkTypeSuccessCallbackResult try { nk = await this.getNetworkType() } catch (err) { console.warn(`getNetworkType err = `, err) } return nk.networkType } async _createPerformanceData(type: WxPerformanceDataType, item: Array<WxPerformanceItem>): Promise<WxPerformanceData> { const networkType = await this._getNetworkType() const date = new Date() return { appId: this.appId, timestamp: date.getTime(), time: date.toLocaleString(), uuid: generateUUID(), deviceId: getDeviceId(), networkType: networkType, batteryLevel: this.getBatteryInfo().level, systemInfo: this._getSystemInfo(), wxLaunch: this.wxLaunchTime, page: getPageUrl(), type: type, item: item } } push(type: WxPerformanceDataType, data: WxPerformanceItem | Array<WxPerformanceItem>) { switch (type) { case WxPerformanceDataType.WX_LIFE_STYLE: case WxPerformanceDataType.WX_NETWORK: this.simpleHandle(type, data as WxPerformanceItem) break case WxPerformanceDataType.MEMORY_WARNING: this.handleMemoryWarning(data as WechatMiniprogram.OnMemoryWarningCallbackResult) break case WxPerformanceDataType.WX_PERFORMANCE: this.handleWxPerformance(data as Array<WxPerformanceItem>) break case WxPerformanceDataType.WX_USER_ACTION: this.handleWxAction(data as WxPerformanceItem) // eslint-disable-next-line no-fallthrough default: break } } async simpleHandle(type: WxPerformanceDataType, data: WxPerformanceItem) { const d = await this._createPerformanceData(type as WxPerformanceDataType, [data]) this._pushData([d]) } // 内存警告会立即上报 async handleMemoryWarning(data: WechatMiniprogram.OnMemoryWarningCallbackResult) { const d = await this._createPerformanceData(WxPerformanceDataType.MEMORY_WARNING, [ { ...data, itemType: WxPerformanceItemType.MemoryWarning, timestamp: Date.now() } ]) this.report([d]) } buildNavigationStart(entry: WxPerformanceEntryObj) { if (entry.entryType === 'navigation') { // appLaunch时没有navigationStart this.navigationMap[entry.path] = entry.navigationStart || entry.startTime } } async handleWxPerformance(data: Array<WxPerformanceItem> = []) { const _data: Array<WxPerformanceItem> = data.map((d) => { this.buildNavigationStart(d) d.itemType = WxPerformanceItemType.Performance d.timestamp = Date.now() return d }) const item = await this._createPerformanceData(WxPerformanceDataType.WX_PERFORMANCE, _data) this._pushData([item]) } // 只统计首次点击 async handleWxAction(data: WxPerformanceItem) { if (!this.firstAction) { const d = await this._createPerformanceData(WxPerformanceDataType.WX_USER_ACTION, [data]) this._pushData([d]) this.firstAction = true } } setLaunchTime(now: number) { this.wxLaunchTime = now } filterUrl(url: string) { if (this.ignoreUrl && this.ignoreUrl.test(url)) return true return false } customPaint() { const now = Date.now() const path = getPageUrl(false) // eslint-disable-next-line @typescript-eslint/no-misused-promises setTimeout(async () => { if (path && this.navigationMap[path]) { const navigationStart = this.navigationMap[path] const data = await this._createPerformanceData(WxPerformanceDataType.WX_LIFE_STYLE, [ { itemType: WxPerformanceItemType.WxCustomPaint, navigationStart: navigationStart, timestamp: now, duration: now - navigationStart } ]) this._pushData([data]) } }, 1000) } } export default Store