Source

Mutation observation scope

Both Trackers query the same #tracked-region with the same rules. Only their MutationObserver target differs: the scoped Tracker uses the sourceRoot default, while the broad Tracker watches document.body.

What this scenario demonstrates

sourceRoot controls where rules query for marker sources and, by default, where MutationObserver listens.

updates.mutation.targets can change the second responsibility independently. Watching document.body does not expand marker queries beyond #tracked-region.

The inserted experiment nodes intentionally match no Tracker rule. They exist only to demonstrate mutation invalidation scope.

Expected behavior

Mutation location Scoped observer Broad observer
Inside sourceRoot Observes Observes
Outside sourceRoot, inside document.body Does not observe Observes

Scoped observer

Query scope: #tracked-region

Mutation scope: #tracked-region through the default target

tracker.mount({
  sourceRoot: trackedRegion,
});
Mutation callbacks
Render requests
Tracked markers

Broad observer

Query scope: #tracked-region

Mutation scope: document.body through a custom target

updates: {
  mutation: {
    targets: ({ document }) => [document.body],
  },
}
Mutation callbacks
Render requests
Tracked markers

Why two counters? Mutation callbacks can be debounced or coalesced before rendering, so they do not promise a one-to-one relationship with render transactions.

Experiment controls

Inside sourceRoot

Both observers should process this mutation.

Outside sourceRoot

Only the broad observer should process this mutation.

Tracked region

This is the shared source/query scope for both Trackers.

Outside the tracked region

This region is outside sourceRoot but remains inside the broad observer's document.body target.