diff --git a/packages/replay/src/coreHandlers/handleKeyboardEvent.ts b/packages/replay/src/coreHandlers/handleKeyboardEvent.ts index f7943d34fa4f..0f7560f39584 100644 --- a/packages/replay/src/coreHandlers/handleKeyboardEvent.ts +++ b/packages/replay/src/coreHandlers/handleKeyboardEvent.ts @@ -12,7 +12,10 @@ export function handleKeyboardEvent(replay: ReplayContainer, event: KeyboardEven return; } - replay.triggerUserActivity(); + // Update user activity, but do not restart recording as it can create + // noisy/low-value replays (e.g. user comes back from idle, hits alt-tab, new + // session with a single "keydown" breadcrumb is created) + replay.updateUserActivity(); const breadcrumb = getKeyboardBreadcrumb(event); diff --git a/packages/replay/src/replay.ts b/packages/replay/src/replay.ts index 53f263b5fa3f..cbab2f8b55fb 100644 --- a/packages/replay/src/replay.ts +++ b/packages/replay/src/replay.ts @@ -480,6 +480,18 @@ export class ReplayContainer implements ReplayContainerInterface { this._updateSessionActivity(); } + /** + * Updates the user activity timestamp *without* resuming + * recording. Some user events (e.g. keydown) can be create + * low-value replays that only contain the keypress as a + * breadcrumb. Instead this would require other events to + * create a new replay after a session has expired. + */ + public updateUserActivity(): void { + this._updateUserActivity(); + this._updateSessionActivity(); + } + /** * Only flush if `this.recordingMode === 'session'` */ diff --git a/packages/replay/src/types.ts b/packages/replay/src/types.ts index 3d1d8616bb79..01efb4afc40c 100644 --- a/packages/replay/src/types.ts +++ b/packages/replay/src/types.ts @@ -542,6 +542,7 @@ export interface ReplayContainer { flushImmediate(): Promise; cancelFlush(): void; triggerUserActivity(): void; + updateUserActivity(): void; addUpdate(cb: AddUpdateCallback): void; getOptions(): ReplayPluginOptions; getSessionId(): string | undefined;