Skip to content

Conversation

@sethfowler-datadog
Copy link
Contributor

Motivation

Change records are a new, experimental data format for session replay data that's designed to record the same information in a more compact, more compressible form.

We've already landed support for recording full snapshots as Change records behind an experiment flag. The next step is to introduce support for incremental snapshots, as well. This requires making improvements to a number of different aspects of the recording code. This PR is the third in a series that will work toward the goal of supporting incremental snapshots; for the previous PR, see #4164.

Changes

The existing code compares Change records to V1 records (the old format) by first converting the Change records to V1 records. That code lives in changeConversions.specHelper.ts. It supports converting full snapshot records from the Change format to the V1 format, but unfortunately, it uses a simple approach that's quite hard to extend to support incremental snapshots.

The challenge is that the V1 format includes lots of unnecessary information in its full snapshots -- for example, when a node is removed from the DOM, the V1 data format includes the parent id of the removed node, even though replay does not need this information. Similarly, when a new node is added to the document, the Change format does not necessarily include its parent id, since just the id of the next sibling is enough, but the V1 format always includes both. This means that, if you just look at a Change record representing an incremental snapshot, there is simply not enough information to construct the equivalent V1 incremental snapshot record.

The solution is to replay each Change record as part of the conversion process and construct a VDOM. This VDOM can then be "rendered" to generate the equivalent V1 record at the current point in time. In particular, this PR adds the following files:

  1. ChangeConverter replaces the code in changeConversions.specHelper.ts. It's a stateful object now, rather than a function; it owns a VDOM, and replays a series of Change records against that VDOM, generating an equivalent V1 record each time.
  2. VDocument, VNode, and VStyleSheet implement the VDOM. They expose APIs which are somewhat similar to the real DOM. Beyond keeping track of what the virtual document looks like, these objects also make lots of assertions internally, which helps verify that the Change record we're playing back is constructed correctly.
  3. StringTable is directly lifted from changeConversions.specHelper.ts; it keeps track of the string table which the series of Change records builds up.
  4. MutationLog is used to track the mutations made in each Change record -- the set of nodes added and removed, changed attributes, and changed text -- so that we can generate the corresponding V1 record. The MutationLog is automatically populated when the VDOM is changed.
  5. NodeIdRemapper and RenderOptions are helper types. RenderOptions lets you customize the rendered V1 record output generated by VDocument#render(). NodeIdRemapper is used to implement one of those customizations; it lets you take the node ids generated by the V1 serialization algorithm and swap them in during rendering, replacing the node ids assigned by the Change serialization algorithm. This makes it much easier to compare the results.

There are lots of tests. Beyond the new tests added in the PR, the change to serialization.specHelper.ts make us use ChangeConverter instead of the old code in changeConversions.specHelper.ts; in turn, this means that a ton of serialization unit tests are also running through ChangeConverter now.

With these changes, we'll have the majority of testing infrastructure we'll need in the PR that actually adds support for incremental snapshot Change records. Unbelievably, given how huge this PR is, there's actually a little bit more that we'll add in the next few PRs, but this is the vast majority of the new testing code.

Checklist

  • Tested locally
  • Tested on staging
  • Added unit tests for this change.
  • Added e2e/integration tests for this change.
  • Updated documentation and/or relevant AGENTS.md file

@sethfowler-datadog sethfowler-datadog requested review from a team as code owners February 11, 2026 18:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant