Skip to content

Commit 59c2d5c

Browse files
committed
ref(replay): Extract span listeners out
1 parent 2a1cfed commit 59c2d5c

File tree

6 files changed

+87
-67
lines changed

6 files changed

+87
-67
lines changed

packages/replay/src/coreHandlers/handleFetch.ts

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import { ReplayPerformanceEntry } from '../createPerformanceEntry';
2+
import { ReplayContainer } from '../replay';
23
import { isIngestHost } from '../util/isIngestHost';
34

4-
export interface FetchHandlerData {
5+
interface FetchHandlerData {
56
args: Parameters<typeof fetch>;
67
fetchData: {
78
method: string;
@@ -18,6 +19,7 @@ export interface FetchHandlerData {
1819
endTimestamp?: number;
1920
}
2021

22+
/** only exported for tests */
2123
export function handleFetch(handlerData: FetchHandlerData): null | ReplayPerformanceEntry {
2224
if (!handlerData.endTimestamp) {
2325
return null;
@@ -41,3 +43,26 @@ export function handleFetch(handlerData: FetchHandlerData): null | ReplayPerform
4143
},
4244
};
4345
}
46+
47+
export function handleFetchSpanListener(replay: ReplayContainer): (handlerData: FetchHandlerData) => void {
48+
return (handlerData: FetchHandlerData) => {
49+
// @ts-ignore private
50+
if (!replay._isEnabled) {
51+
return;
52+
}
53+
54+
const result = handleFetch(handlerData);
55+
56+
if (result === null) {
57+
return;
58+
}
59+
60+
replay.addUpdate(() => {
61+
void replay.createPerformanceSpans([result]);
62+
// Returning true will cause `addUpdate` to not flush
63+
// We do not want network requests to cause a flush. This will prevent
64+
// recurring/polling requests from keeping the replay session alive.
65+
return true;
66+
});
67+
};
68+
}

packages/replay/src/coreHandlers/handleHistory.ts

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import { ReplayPerformanceEntry } from '../createPerformanceEntry';
2+
import { ReplayContainer } from '../replay';
23

3-
export interface HistoryHandlerData {
4+
interface HistoryHandlerData {
45
from: string;
56
to: string;
67
}
78

8-
export function handleHistory(handlerData: HistoryHandlerData): ReplayPerformanceEntry {
9+
function handleHistory(handlerData: HistoryHandlerData): ReplayPerformanceEntry {
910
const { from, to } = handlerData;
1011

1112
const now = new Date().getTime() / 1000;
@@ -20,3 +21,29 @@ export function handleHistory(handlerData: HistoryHandlerData): ReplayPerformanc
2021
},
2122
};
2223
}
24+
25+
export function handleHistorySpanListener(replay: ReplayContainer): (handlerData: HistoryHandlerData) => void {
26+
return (handlerData: HistoryHandlerData) => {
27+
// @ts-ignore private
28+
if (!replay._isEnabled) {
29+
return;
30+
}
31+
32+
const result = handleHistory(handlerData);
33+
34+
if (result === null) {
35+
return;
36+
}
37+
38+
// Need to collect visited URLs
39+
// @ts-ignore private
40+
replay._context.urls.push(result.name);
41+
replay.triggerUserActivity();
42+
43+
replay.addUpdate(() => {
44+
void replay.createPerformanceSpans([result]);
45+
// Returning false to flush
46+
return false;
47+
});
48+
};
49+
}

packages/replay/src/coreHandlers/handleXhr.ts

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { ReplayPerformanceEntry } from '../createPerformanceEntry';
2+
import { ReplayContainer } from '../replay';
23
import { isIngestHost } from '../util/isIngestHost';
34

45
// From sentry-javascript
@@ -19,14 +20,14 @@ interface SentryWrappedXMLHttpRequest extends XMLHttpRequest {
1920
__sentry_own_request__?: boolean;
2021
}
2122

22-
export interface XhrHandlerData {
23+
interface XhrHandlerData {
2324
args: [string, string];
2425
xhr: SentryWrappedXMLHttpRequest;
2526
startTimestamp: number;
2627
endTimestamp?: number;
2728
}
2829

29-
export function handleXhr(handlerData: XhrHandlerData): ReplayPerformanceEntry | null {
30+
function handleXhr(handlerData: XhrHandlerData): ReplayPerformanceEntry | null {
3031
if (handlerData.xhr.__sentry_own_request__) {
3132
// Taken from sentry-javascript
3233
// Only capture non-sentry requests
@@ -61,3 +62,26 @@ export function handleXhr(handlerData: XhrHandlerData): ReplayPerformanceEntry |
6162
},
6263
};
6364
}
65+
66+
export function handleXhrSpanListener(replay: ReplayContainer): (handlerData: XhrHandlerData) => void {
67+
return (handlerData: XhrHandlerData) => {
68+
// @ts-ignore private
69+
if (!replay._isEnabled) {
70+
return;
71+
}
72+
73+
const result = handleXhr(handlerData);
74+
75+
if (result === null) {
76+
return;
77+
}
78+
79+
replay.addUpdate(() => {
80+
void replay.createPerformanceSpans([result]);
81+
// Returning true will cause `addUpdate` to not flush
82+
// We do not want network requests to cause a flush. This will prevent
83+
// recurring/polling requests from keeping the replay session alive.
84+
return true;
85+
});
86+
};
87+
}

packages/replay/src/coreHandlers/spanHandler.ts

Lines changed: 0 additions & 17 deletions
This file was deleted.

packages/replay/src/replay.ts

Lines changed: 6 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ import {
1414
WINDOW,
1515
} from './constants';
1616
import { breadcrumbHandler } from './coreHandlers/breadcrumbHandler';
17-
import { spanHandler } from './coreHandlers/spanHandler';
17+
import { handleFetchSpanListener } from './coreHandlers/handleFetch';
18+
import { handleHistorySpanListener } from './coreHandlers/handleHistory';
19+
import { handleXhrSpanListener } from './coreHandlers/handleXhr';
1820
import { createMemoryEntry, createPerformanceEntries, ReplayPerformanceEntry } from './createPerformanceEntry';
1921
import { createEventBuffer, EventBuffer } from './eventBuffer';
2022
import { deleteSession } from './session/deleteSession';
@@ -24,7 +26,6 @@ import { Session } from './session/Session';
2426
import type {
2527
AllPerformanceEntry,
2628
InstrumentationTypeBreadcrumb,
27-
InstrumentationTypeSpan,
2829
InternalEventContext,
2930
PopEventContext,
3031
RecordingEvent,
@@ -314,9 +315,9 @@ export class ReplayContainer {
314315
const scope = getCurrentHub().getScope();
315316
scope?.addScopeListener(this.handleCoreBreadcrumbListener('scope'));
316317
addInstrumentationHandler('dom', this.handleCoreBreadcrumbListener('dom'));
317-
addInstrumentationHandler('fetch', this.handleCoreSpanListener('fetch'));
318-
addInstrumentationHandler('xhr', this.handleCoreSpanListener('xhr'));
319-
addInstrumentationHandler('history', this.handleCoreSpanListener('history'));
318+
addInstrumentationHandler('fetch', handleFetchSpanListener(this));
319+
addInstrumentationHandler('xhr', handleXhrSpanListener(this));
320+
addInstrumentationHandler('history', handleHistorySpanListener(this));
320321

321322
// Tag all (non replay) events that get sent to Sentry with the current
322323
// replay ID so that we can reference them later in the UI
@@ -590,39 +591,6 @@ export class ReplayContainer {
590591
this.doChangeToForegroundTasks(breadcrumb);
591592
};
592593

593-
/**
594-
* Handler for Sentry Core SDK events.
595-
*
596-
* These specific events will create span-like objects in the recording.
597-
*/
598-
handleCoreSpanListener: (type: InstrumentationTypeSpan) => (handlerData: unknown) => void =
599-
(type: InstrumentationTypeSpan) =>
600-
(handlerData: unknown): void => {
601-
if (!this._isEnabled) {
602-
return;
603-
}
604-
605-
const result = spanHandler(type, handlerData);
606-
607-
if (result === null) {
608-
return;
609-
}
610-
611-
if (type === 'history') {
612-
// Need to collect visited URLs
613-
this._context.urls.push(result.name);
614-
this.triggerUserActivity();
615-
}
616-
617-
this.addUpdate(() => {
618-
void this.createPerformanceSpans([result as ReplayPerformanceEntry]);
619-
// Returning true will cause `addUpdate` to not flush
620-
// We do not want network requests to cause a flush. This will prevent
621-
// recurring/polling requests from keeping the replay session alive.
622-
return ['xhr', 'fetch'].includes(type);
623-
});
624-
};
625-
626594
/**
627595
* Handler for Sentry Core SDK events.
628596
*

packages/replay/src/types.ts

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,6 @@ export interface SendReplay {
1616
}
1717

1818
export type InstrumentationTypeBreadcrumb = 'dom' | 'scope';
19-
export type InstrumentationTypeSpan = 'fetch' | 'xhr' | 'history';
20-
export type InstrumentationType =
21-
| InstrumentationTypeBreadcrumb
22-
| InstrumentationTypeSpan
23-
| 'console'
24-
| 'error'
25-
| 'unhandledrejection';
2619

2720
/**
2821
* The request payload to worker

0 commit comments

Comments
 (0)