Skip to content

Commit 7ca8632

Browse files
committed
working
1 parent 53b83bb commit 7ca8632

File tree

2 files changed

+71
-0
lines changed

2 files changed

+71
-0
lines changed

packages/rrweb/src/replay/index.ts

+19
Original file line numberDiff line numberDiff line change
@@ -525,6 +525,25 @@ export class Replayer {
525525
this.emitter.emit(ReplayerEvents.Start);
526526
}
527527

528+
public playSingleEvent(eventIndex: number) {
529+
if (this.service.state.matches('paused')) {
530+
this.service.send({
531+
type: 'PLAY_SINGLE_EVENT',
532+
payload: { singleEvent: eventIndex },
533+
});
534+
} else {
535+
this.service.send({ type: 'PAUSE' });
536+
this.service.send({
537+
type: 'PLAY_SINGLE_EVENT',
538+
payload: { singleEvent: eventIndex },
539+
});
540+
}
541+
this.iframe.contentDocument
542+
?.getElementsByTagName('html')[0]
543+
?.classList.remove('rrweb-paused');
544+
this.emitter.emit(ReplayerEvents.Start);
545+
}
546+
528547
public pause(timeOffset?: number) {
529548
if (timeOffset === undefined && this.service.state.matches('playing')) {
530549
this.service.send({ type: 'PAUSE' });

packages/rrweb/src/replay/machine.ts

+52
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@ export type PlayerEvent =
2828
timeOffset: number;
2929
};
3030
}
31+
| {
32+
type: 'PLAY_SINGLE_EVENT';
33+
payload: {
34+
singleEvent: number;
35+
};
36+
}
3137
| {
3238
type: 'CAST_EVENT';
3339
payload: {
@@ -78,6 +84,30 @@ export function discardPriorSnapshots(
7884
return events;
7985
}
8086

87+
function discardPriorSnapshotsToEvent(
88+
events: eventWithTime[],
89+
targetIndex: number,
90+
) {
91+
const targetEvent = events[targetIndex];
92+
93+
if (!targetEvent) {
94+
return [];
95+
}
96+
97+
for (let idx = targetIndex; idx >= 0; idx--) {
98+
const event = events[idx];
99+
100+
if (!event) {
101+
continue;
102+
}
103+
104+
if (event.type === EventType.Meta) {
105+
return events.slice(idx, targetIndex + 1);
106+
}
107+
}
108+
return events;
109+
}
110+
81111
type PlayerAssets = {
82112
emitter: Emitter;
83113
applyEventsSynchronously(events: Array<eventWithTime>): void;
@@ -119,6 +149,10 @@ export function createPlayerService(
119149
target: 'playing',
120150
actions: ['recordTimeOffset', 'play'],
121151
},
152+
PLAY_SINGLE_EVENT: {
153+
target: 'paused',
154+
actions: ['playSingleEvent'],
155+
},
122156
CAST_EVENT: {
123157
target: 'paused',
124158
actions: 'castEvent',
@@ -168,6 +202,24 @@ export function createPlayerService(
168202
baselineTime: ctx.events[0].timestamp + timeOffset,
169203
};
170204
}),
205+
206+
playSingleEvent(ctx, event) {
207+
if (event.type !== 'PLAY_SINGLE_EVENT') {
208+
return;
209+
}
210+
211+
const { singleEvent } = event.payload;
212+
213+
const neededEvents2 = discardPriorSnapshotsToEvent(
214+
ctx.events,
215+
singleEvent,
216+
);
217+
218+
applyEventsSynchronously(neededEvents2);
219+
emitter.emit(ReplayerEvents.Flush);
220+
// emitter.emit(ReplayerEvents.Finish);
221+
},
222+
171223
play(ctx) {
172224
const { timer, events, baselineTime, lastPlayedEvent } = ctx;
173225
timer.clear();

0 commit comments

Comments
 (0)