Skip to content

Commit

Permalink
Merge pull request #281 from HuolalaTech/feat/mpreplay
Browse files Browse the repository at this point in the history
support mini program replay
  • Loading branch information
qkang07 authored Nov 20, 2024
2 parents c33495e + 4a3baa2 commit 3466394
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 25 deletions.
68 changes: 49 additions & 19 deletions src/pages/Replay/PluginPanel/components/StoragePanel/index.tsx
Original file line number Diff line number Diff line change
@@ -1,37 +1,67 @@
import Icon from '@ant-design/icons';
import { SpyStorage } from '@huolala-tech/page-spy-types';
import { Layout, Menu } from 'antd';
import { memo, useState } from 'react';
import { memo, useMemo, useState } from 'react';
import { ReactComponent as StorageSvg } from '@/assets/image/storage.svg';
import { ReactComponent as CookieSvg } from '@/assets/image/cookie.svg';
import { StorageContent } from './StorageContent';
import './index.less';
import { ResizableDetail } from '@/components/ResizableDetail';
import { useReplayStore } from '@/store/replay';
import { useShallow } from 'zustand/react/shallow';
import {
isMiniProgram,
isReactNative,
isUniAppNative,
} from '@/store/platform-config';

const { Sider, Content } = Layout;

const storageMenus = [
{
key: 'localStorage',
label: 'Local Storage',
icon: <Icon component={StorageSvg} />,
},
{
key: 'sessionStorage',
label: 'Session Storage',
icon: <Icon component={StorageSvg} />,
},
{
key: 'cookie',
label: 'Cookies',
icon: <Icon component={CookieSvg} />,
},
];

export const StoragePanel = memo(() => {
const [activeTab, setActiveTab] =
useState<SpyStorage.DataType>('localStorage');

const clientInfo = useReplayStore(useShallow((state) => state.clientInfo));

const storageMenus = useMemo(() => {
const menus = [
{
key: 'localStorage',
label: 'Local Storage',
icon: <Icon component={StorageSvg} />,
},
{
key: 'sessionStorage',
label: 'Session Storage',
icon: <Icon component={StorageSvg} />,
},
{
key: 'cookie',
label: 'Cookies',
icon: <Icon component={CookieSvg} />,
},
];
const browserType = clientInfo?.browser.type || 'unknown';
if (isMiniProgram(browserType) || isUniAppNative(browserType)) {
menus.splice(0);
menus.push({
key: 'mpStorage',
label: '小程序 Storage',
icon: <Icon component={StorageSvg} />,
});
} else if (isReactNative(browserType)) {
menus.splice(0);
menus.push({
key: 'asyncStorage',
label: 'Async Storage',
icon: <Icon component={StorageSvg} />,
});
}

setActiveTab(menus[0].key as SpyStorage.DataType);
return menus;
}, [clientInfo?.browser.type]);

return (
<div className="storage-panel">
<Layout className="storage-panel__layout">
Expand Down
7 changes: 6 additions & 1 deletion src/pages/Replay/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,12 @@ const Replay = () => {
const result = res.map((i: any) => {
return {
...i,
data: JSON.parse(strFromU8(unzlibSync(strToU8(i.data, true)))),
// if string, it's compressed by zlib
// or it will be plain object. because in mp env, zlib is not available
data:
typeof i.data === 'string'
? JSON.parse(strFromU8(unzlibSync(strToU8(i.data, true))))
: i.data,
};
}) as HarborDataItem[];
setAllData(result);
Expand Down
27 changes: 22 additions & 5 deletions src/store/replay.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* eslint-disable no-implicit-coercion */
import {
SpyClient,
SpyConsole,
SpyMessage,
SpyStorage,
Expand All @@ -15,6 +16,7 @@ import {
ResolvedNetworkInfo,
resolveUrlInfo,
} from '@/utils';
import { parseClientInfo, ParsedClientInfo } from '@/utils/brand';
import { DataType } from '@huolala-tech/page-spy-plugin-data-harbor/dist/types/harbor/base';

const isCaredActivity = (activity: HarborDataItem) => {
Expand Down Expand Up @@ -46,14 +48,13 @@ export interface HarborDataItem<T = any> {
data: T;
}

export interface MetaInfo {
ua?: string;
export type MetaInfo = {
title?: string;
url?: string;
remark?: string;
startTime?: number;
endTime?: number;
}
} & SpyClient.DataItem;

const isMetaInfo = (data: HarborDataItem): data is HarborDataItem<MetaInfo> => {
return data.type === 'meta';
Expand All @@ -71,6 +72,7 @@ export interface ReplayStore {
rrwebStartTime: number;
setRRWebStartTime: (timestamp: number) => void;
activity: Activity[];
clientInfo: ParsedClientInfo | null;
allConsoleMsg: HarborDataItem<SpyConsole.DataItem>[];
allNetworkMsg: HarborDataItem<ResolvedNetworkInfo>[];
allRRwebEvent: eventWithTime[];
Expand Down Expand Up @@ -123,6 +125,7 @@ export const useReplayStore = create<ReplayStore>((set, get) => ({
);
},
activity: [],
clientInfo: null,
allConsoleMsg: [],
allNetworkMsg: [],
allRRwebEvent: [],
Expand All @@ -149,15 +152,25 @@ export const useReplayStore = create<ReplayStore>((set, get) => ({
let end = data[data.length - 1].timestamp;

const lastData = data[data.length - 1];

if (isMetaInfo(lastData)) {
set(
produce((state) => {
state.metaMsg = lastData.data;
}),
);
const { data } = lastData;
data.startTime && (start = data.startTime);
data.endTime && (end = data.endTime);
if (data.startTime && data.endTime) {
data.startTime && (start = data.startTime);
data.endTime && (end = data.endTime);
}
if (data.ua) {
set(
produce((state) => {
state.clientInfo = parseClientInfo(data);
}),
);
}
}

const duration = end - start;
Expand All @@ -171,13 +184,15 @@ export const useReplayStore = create<ReplayStore>((set, get) => ({
| 'allRRwebEvent'
| 'allStorageMsg'
| 'allSystemMsg'
| 'clientInfo'
> = {
activity: [],
allConsoleMsg: [],
allNetworkMsg: [],
allRRwebEvent: [],
allStorageMsg: [],
allSystemMsg: [],
clientInfo: null,
};
const {
activity,
Expand All @@ -186,6 +201,7 @@ export const useReplayStore = create<ReplayStore>((set, get) => ({
allRRwebEvent,
allSystemMsg,
allStorageMsg,
clientInfo,
} = data.reduce((acc, cur) => {
const { type, data, timestamp } = cur;
if (timestamp < start) {
Expand Down Expand Up @@ -241,6 +257,7 @@ export const useReplayStore = create<ReplayStore>((set, get) => ({
set(
produce((state) => {
state.activity = activity;
state.clientInfo = clientInfo;
state.allConsoleMsg = allConsoleMsg;
state.allNetworkMsg = allNetworkMsg;
state.allRRwebEvent = allRRwebEvent;
Expand Down

0 comments on commit 3466394

Please sign in to comment.