Commit Graph

287 Commits

Author SHA1 Message Date
Yanzhen Yu
9d686d4302 remove the internal use of resume API 2026-04-01 12:00:00 +08:00
Yanzhen Yu
c17606630e remove global body style 2026-04-01 12:00:00 +08:00
Yanzhen Yu
a31efdc169 close #274 implement the new state management proposal 2026-04-01 12:00:00 +08:00
Eoghan Murray
9362baac3e Reset the lastPlayedEvent as it would otherwise be used to discard events in machine.ts as follows: (#250) 2026-04-01 12:00:00 +08:00
Yanzhen Yu
fc66a7eb79 Release 0.8.5 2026-04-01 12:00:00 +08:00
Yanzhen Yu
0d6fe56b80 close #263 Since we improved the block class strategy,
we need to check parent node before pushAdd.
2026-04-01 12:00:00 +08:00
Yanzhen Yu
cf272f65ef Release 0.8.4 2026-04-01 12:00:00 +08:00
Yanzhen Yu
98f08f333c close #254 hotfix: only use virtual parent in sync mode 2026-04-01 12:00:00 +08:00
Yanzhen Yu
6c87b03e0d close #240 fix block class to handle text node changes 2026-04-01 12:00:00 +08:00
Yanzhen Yu
c8cc397418 Release 0.8.3 2026-04-01 12:00:00 +08:00
Yanzhen Yu
e056f1ae88 add the patch function to utils 2026-04-01 12:00:00 +08:00
Yanzhen Yu
2a133f8214 close #228 safe access content document, which may be destroyed manually 2026-04-01 12:00:00 +08:00
Yanzhen Yu
520ddf3a4f close #244 pass fullsnapshot event to the callback 2026-04-01 12:00:00 +08:00
Yanzhen Yu
50406c27ee fix unit tests 2026-04-01 12:00:00 +08:00
yz-yu
8bb1c791f5 mask input options and sampling options (#252)
* part of #80, support mask input options

* close #188 enhance sampling options
Use a more general sampling strategy interface to describe the
configuration of sampling events collection.

Implemented mousmove, mouse interaction, scroll and input sampling
strategy.
2026-04-01 12:00:00 +08:00
Eoghan Murray
5b0539419c Restore functioning of #200 - this got broken after #242 (#246)
- What was broken was that it would just play activity from the first page view, but then would stop at the second page view (meta) as actions after that had been discarded
 - This restores the functionality given by the comment 'return the events from last meta to the end.' - we never want to discard events that are after the baseline time
 - I believe 'session' is the incorrect terminology for this function name, as a session in web analytics usually means a series of page views
2026-04-01 12:00:00 +08:00
yz-yu
a8b493799b fix the skip event calculation (#242) 2026-04-01 12:00:00 +08:00
Yanzhen Yu
ae71cf106a tweak the code of getting last session, without splice events array 2026-04-01 12:00:00 +08:00
Yanzhen Yu
19acba745a fast-forward implementation v1
related to #6

Since the currently 'play at any time offset' implementation is pretty simple,
there are many things we can do to optimize its performance.

In this patch, we do the following optimizations:
1. Ignore some of the events during fast forward.
   For example, when we are going to fast forward to 10 minutes later,
   we do not need to perform mouse movement events during this period.
2. Use a fragment element as the 'virtual parent node'.
   So newly added DOM nodes will be appended to this fragment node,
   and finally being appended into the document as a batch operation.
These changes reduce a lot of time which was spent on reflow/repaint previously.
I've seen a 10 times performance improvement within these approaches.

And there are still some things we can do better but not in this patch.
1. We can build a virtual DOM tree to store the mutations of DOM.
   This will minimize the number of DOM operations.
2. Another thing that may help UX is to make the fast forward process async and cancellable.
   This may make the drag and drop interactions in the player's UI looks smooth.
2026-04-01 12:00:00 +08:00
Eoghan Murray
c19aaa7ec0 Only execute events since most recent pageload when playing from an offset (#200)
On recordings with many full pageloads, dom state and mutations were being applied only to be discarded when a new pageload came in, resulting in very slow time to rebuild - and inability to interactively 'scrub' through these recordings
2026-04-01 12:00:00 +08:00
Eoghan Murray
753ee25832 Expose startTime and endTime in the getMetaData() call. I was using player.events[0].timestamp but player.events has gone away (since a78da77 I believe) (#235) 2026-04-01 12:00:00 +08:00
Eoghan Murray
7d7def23d1 Ensure api method .play() can be called by external code without worrying about the internal state of the finite state machine (#236) 2026-04-01 12:00:00 +08:00
Jin
dacaf57b0e :Update guide.zh_CN.md (#238)
Co-authored-by: jinwentao <jinwentao@huya.com>
2026-04-01 12:00:00 +08:00
slimlime
d83501d896 📚 Quick typo check. Update replay.md (#237)
Precise typo check of inprecise -> imprecise
2026-04-01 12:00:00 +08:00
Jeff Loiselle
730aafa5bd Update observer.md (#233) 2026-04-01 12:00:00 +08:00
Yanzhen Yu
d7086b50e8 add sponsor info 2026-04-01 12:00:00 +08:00
yz-yu
36e2a67191 Create FUNDING.yml 2026-04-01 12:00:00 +08:00
Yanzhen Yu
9c7e00a6b1 Release 0.8.2 2026-04-01 12:00:00 +08:00
Yanzhen Yu
9a5873005f hotfix: fix es module entry path 2026-04-01 12:00:00 +08:00
Yanzhen Yu
90a42a31da Release 0.8.1 2026-04-01 12:00:00 +08:00
Yanzhen Yu
42a205e4c5 update typings entry 2026-04-01 12:00:00 +08:00
Yanzhen Yu
ccb2dd0562 Release 0.8.0 2026-04-01 12:00:00 +08:00
Yanzhen Yu
191908aa1d continue #199: redesign the bundled file structure
According to @eoghanmurray's suggestion, we can support three
main scenarios:
1. record only
2. replay only
3. all in one

Since we have implemented the packer feature, which has a big
influence in bundle size, we provide another three bundles:
1. record and pack
2. replay and unpack
3. all in one with pack and unpack
2026-04-01 12:00:00 +08:00
Yanzhen Yu
81b3407dd7 export utils as public API 2026-04-01 12:00:00 +08:00
Yanzhen Yu
6b10e1c4ee update typescript to 3.9.5 2026-04-01 12:00:00 +08:00
Eoghan Murray
d57cae3d51 Move mutation processing into it's own class (#223)
* Move mutation processing into it's own object.

This should stand on it's own as a refactor, but is intended as a basis
for exposing the new MutationBuffer object to further outside control e.g.
to 'mute' or batch up mutation emission when the page becomes inactive
from a https://developer.mozilla.org/en-US/docs/Web/API/Page_Visibility_API
point of view

* The `processMutations` function needed to be bound to the `mutationBuffer` object, as otherwise `this` referred to the `MutationObserver` object itself

* Neglected to add this output of `npm run typings`

* Get around the binding problem by using Arrow function expressions

* Prettier formatting
2026-04-01 12:00:00 +08:00
Yanzhen Yu
06024b245f close #216 rebuild first full snapshot when init the replayer 2026-04-01 12:00:00 +08:00
yz-yu
2a6e2e0ef9 Live mode 2 (#226)
* refactoring play, pause, resume, load style sheet to subscribe style code

* support live mode in state machine

* 1. upgrade @xstate/fsm
2. add toggle interact methods to the player
2026-04-01 12:00:00 +08:00
Jinxing Lin
5317bf73b9 update packer unit test (#220) 2026-04-01 12:00:00 +08:00
Eoghan Murray
da2ad8b456 Keep npm run typings happy (#222) 2026-04-01 12:00:00 +08:00
Eoghan Murray
610c2b3ec4 This dimension is in px but is unitless according to https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe (#214) 2026-04-01 12:00:00 +08:00
Rifaudeen
4bb0bdb180 added custom-event emitter to replayer (#219) 2026-04-01 12:00:00 +08:00
nicolas-meunier-97
dcff282c90 Small syntaxe error (#207)
"A" should be used here, because the word after it ("unique"), begins with a consonant sound
2026-04-01 12:00:00 +08:00
yz-yu
43be602816 mutation observer v2 (#206)
There are some long-term issues in rrweb's mutation observer.

A scenario cause problem:
A list of DOM node: n1, n2, n3, n4, n5
Steps of modifying the nodes:
  1. remove n1, n2, n3, n4 sequentially
  2. append n4, n3, n2, n1 after n5 sequentially
Then we got the added node data like this:
  (id: n4, prev: null, next: n3  )
  (id: n3, prev: n4,   next: n2  )
  (id: n2, prev: n3,   next: n1  )
  (id: n1, prev: n2,   next: null)
The problem comes when we try to replay the first add node datum.
Since its prev node is null, we rely on its next sibling n3. But
n3 was not present at this moment, and in previous code, we fallback
to append n4 to the last of its parent node.

The solution is to defer the append of elements that missing
siblings. But it is also hard to tell which node is the first one
that needs to be appended.

Take a step back and rethink the design of the mutation observer,
we've found there are two implementations make things complicated.
1. We set the id to -1 when we seeing some nodes are not serialized yet.
2. We record both previous sibling and next sibling to determine the
position of the node.
But we can do better!
First, we can put nodes with un-serialized siblings
to a queue, and try to add it again later. Then we can just record the next
sibling as 'the single truth' so we can be sure which node is the last
one of its parent.

This patch has implemented the new observer strategy. Data recorded with
the new observer should no longer have any node with id -1. But for
compatibility consideration, we still keep some replayer code that helps
solve legacy data.
2026-04-01 12:00:00 +08:00
Yanzhen Yu
2a323da123 close #205
1. upgrade rollup postcss plugin
2. fix postcss plugins for bundles
2026-04-01 12:00:00 +08:00
yz-yu
1efc9ad30b Bundles (#199)
* provide more bundle outputs

* update commonJS and es module entry to boot file
2026-04-01 12:00:00 +08:00
yz-yu
bfc0c43aa7 impl basic player state machine (#198) 2026-04-01 12:00:00 +08:00
Yanzhen Yu
a7d857c9e4 update rollup terser plugin 2026-04-01 12:00:00 +08:00
Yanzhen Yu
b8366ebf2d Release 0.7.33 2026-04-01 12:00:00 +08:00
Yanzhen Yu
0a62fd730c upgrade TS 2026-04-01 12:00:00 +08:00