From 4f94a70bf37b64f669007b0eea2ecfc3a95ef815 Mon Sep 17 00:00:00 2001 From: Jason Laster Date: Fri, 20 Sep 2024 14:28:03 -0700 Subject: [PATCH 1/7] wip --- .../src/suspense/NetworkRequestsCache.ts | 11 ++++-- packages/shared/client/ReplayClient.ts | 22 +++++++++--- packages/shared/client/types.ts | 1 + .../NetworkMonitorListRow.module.css | 31 +++++++++++++++++ .../NetworkMonitor/NetworkMonitorListRow.tsx | 34 +++++++++++++++++-- src/ui/components/NetworkMonitor/utils.ts | 3 ++ 6 files changed, 93 insertions(+), 9 deletions(-) diff --git a/packages/replay-next/src/suspense/NetworkRequestsCache.ts b/packages/replay-next/src/suspense/NetworkRequestsCache.ts index 69c5844fcba..3ad4ec958c8 100644 --- a/packages/replay-next/src/suspense/NetworkRequestsCache.ts +++ b/packages/replay-next/src/suspense/NetworkRequestsCache.ts @@ -41,6 +41,7 @@ export type NetworkRequestsData = { }; timeStampedPoint: TimeStampedPoint; triggerPoint: TimeStampedPoint | null; + serverPoint: { point: ExecutionPoint, supplementalIndex: number } | null; }; export type NetworkRequestsCacheData = { @@ -57,7 +58,7 @@ export const networkRequestsCache = createStreamingCache< getKey: () => "single-entry-cache", load: async ( options: StreamingCacheLoadOptions>, - replayClient + replayClient: ReplayClientInterface ) => { const { update, resolve } = options; @@ -69,7 +70,7 @@ export const networkRequestsCache = createStreamingCache< // Use the createOnRequestsReceived() adapter to ensure that RequestInfo objects // are always received before any associated RequestEventInfo objects const onRequestsReceived = createOnRequestsReceived(function onRequestsReceived(data) { - data.requests.forEach(({ id, point, time, triggerPoint }) => { + data.requests.forEach(({ id, point, time, triggerPoint },) => { assert( previousExecutionPoint === null || comparePoints(previousExecutionPoint, point) <= 0, "Requests should be in order" @@ -79,6 +80,11 @@ export const networkRequestsCache = createStreamingCache< ids.push(id); + const targetPoint = replayClient.getTargetPoint(point, 0); + + + + records[id] = { id, events: { @@ -92,6 +98,7 @@ export const networkRequestsCache = createStreamingCache< responseEvent: null, responseRawHeaderEvent: null, }, + serverPoint: targetPoint, requestBodyData: null, responseBodyData: null, timeStampedPoint: { diff --git a/packages/shared/client/ReplayClient.ts b/packages/shared/client/ReplayClient.ts index 3dc23555669..a28c0e254ca 100644 --- a/packages/shared/client/ReplayClient.ts +++ b/packages/shared/client/ReplayClient.ts @@ -611,7 +611,9 @@ export class ReplayClient implements ReplayClientInterface { }); } - private async maybeGetConnectionStepTarget(point: ExecutionPoint, pointSupplementalIndex: number): Promise { + getTargetPoint(point: ExecutionPoint, pointSupplementalIndex: number): { + point: ExecutionPoint | undefined, supplementalIndex: number + } | null { const recordingId = this.getSupplementalIndexRecordingId(pointSupplementalIndex); let targetPoint: ExecutionPoint | undefined; @@ -636,11 +638,21 @@ export class ReplayClient implements ReplayClientInterface { return null; } - const sessionId = await this.getSupplementalIndexSession(targetSupplementalIndex); + return { point: targetPoint, supplementalIndex: targetSupplementalIndex }; + } + + private async maybeGetConnectionStepTarget(point: ExecutionPoint, pointSupplementalIndex: number): Promise { + + const targetPoint = this.getTargetPoint(point, pointSupplementalIndex); + if (!targetPoint) { + return null; + } + + const sessionId = await this.getSupplementalIndexSession(targetPoint.supplementalIndex); - const response = await sendMessage("Session.getPointFrameSteps" as any, { point: targetPoint }, sessionId); + const response = await sendMessage("Session.getPointFrameSteps" as any, { point: targetPoint.point }, sessionId); const { steps } = response; - const desc = steps.find((step: PointDescription) => step.point == targetPoint); + const desc = steps.find((step: PointDescription) => step.point == targetPoint.point); assert(desc); this.transformSupplementalPointDescription(desc, sessionId); @@ -1542,7 +1554,7 @@ function interpolateSupplementalTime(recordingId: string, supplemental: Suppleme assert(previous.clientPoint.time <= next.clientPoint.time); assert(previous.serverPoint.time <= next.serverPoint.time); if (supplementalTime >= previous.serverPoint.time && - supplementalTime <= next.serverPoint.time) { + supplementalTime <= next.serverPoint.time) { const clientElapsed = next.clientPoint.time - previous.clientPoint.time; const serverElapsed = next.serverPoint.time - previous.serverPoint.time; const fraction = (supplementalTime - previous.serverPoint.time) / serverElapsed; diff --git a/packages/shared/client/types.ts b/packages/shared/client/types.ts index c09594a8181..9d0d596cf9d 100644 --- a/packages/shared/client/types.ts +++ b/packages/shared/client/types.ts @@ -207,6 +207,7 @@ export interface ReplayClientInterface { events: RequestEventInfo[]; requests: RequestInfo[]; }>; + getTargetPoint(point: ExecutionPoint, pointSupplementalIndex: number): { point: ExecutionPoint | undefined, supplementalIndex: number } | null; findPaints(): Promise; findPoints(selector: PointSelector, limits?: PointLimits): Promise; diff --git a/src/ui/components/NetworkMonitor/NetworkMonitorListRow.module.css b/src/ui/components/NetworkMonitor/NetworkMonitorListRow.module.css index b9920ef4bdd..20790249f47 100644 --- a/src/ui/components/NetworkMonitor/NetworkMonitorListRow.module.css +++ b/src/ui/components/NetworkMonitor/NetworkMonitorListRow.module.css @@ -89,6 +89,7 @@ color: #fff; font-weight: bold; } + .Row:hover .SeekButton { display: flex; } @@ -97,6 +98,36 @@ outline: none; } + +.ServerSeekButton { + display: none; + position: absolute; + left: 0; + top: 50%; + transform: translateY(-50%); + + padding: 0.25rem; + padding-right: 1ch; + border-top-right-radius: 0.5rem; + border-bottom-right-radius: 0.5rem; + + flex-direction: row; + align-items: center; + gap: 1ch; + + background: red !important; + color: #fff; + font-weight: bold; +} + +.Row:hover .ServerSeekButton { + display: flex; +} +.Server:focus, +.Server:hover { + outline: none; +} + .SeekButtonIcon { flex: 0 0 auto; color: currentColor; diff --git a/src/ui/components/NetworkMonitor/NetworkMonitorListRow.tsx b/src/ui/components/NetworkMonitor/NetworkMonitorListRow.tsx index f060471a420..ee86298d605 100644 --- a/src/ui/components/NetworkMonitor/NetworkMonitorListRow.tsx +++ b/src/ui/components/NetworkMonitor/NetworkMonitorListRow.tsx @@ -116,9 +116,16 @@ function RequestRow({ start: startTime, status, triggerPoint, + serverPoint, url, } = request; + + if (serverPoint) { + console.log("serverPoint!!", serverPoint); + } + + let type = documentType || cause; if (type === "unknown") { type = ""; @@ -225,7 +232,10 @@ function RequestRow({ )} {columns.name && (
- {name} {graphqlOperationName && `(${graphqlOperationName})`} + {serverPoint && ( + Server {serverPoint.supplementalIndex} {serverPoint.point} + )} + {/* {name} {graphqlOperationName && `(${graphqlOperationName})`} */}
)} {columns.method && ( @@ -254,7 +264,27 @@ function RequestRow({ )} - {triggerPoint && triggerPoint.time !== currentTime && ( + {serverPoint && ( + + )} + + {!serverPoint && triggerPoint && triggerPoint.time !== currentTime && ( )} - {!serverPoint && triggerPoint && triggerPoint.time !== currentTime && ( + {!targetPoint && triggerPoint && triggerPoint.time !== currentTime && ( +
+ + +
)} {!targetPoint && triggerPoint && triggerPoint.time !== currentTime && (