Skip to content

MD-3009 Cut more replaceRange shapes with one callback - #45

Merged
benney merged 6 commits into
mainfrom
feature/md-3009-mos-proxy-cut-more-replacerange-shapes-with-one-callback
Nov 6, 2026
Merged

benney merged 6 commits into
mainfrom
feature/md-3009-mos-proxy-cut-more-replacerange-shapes-with-one-callback

Conversation

@benney

@benney benney commented Nov 5, 2026 •

Copy link
Copy Markdown
Member

Stacked on #43.

More decisions and pages use the one-callback range cut, so the per-element path is left for nested end markers and a few rare shapes.

  • A nested start marker uses the fast path when its range is the only one: pass 1 marks the cut with sentinel comments, a rewriter pass over just the kept prefix finds the start marker's open ancestors, and the bytes are spliced with their end tags
  • Content other components insert inside the cut is removed with it, whatever the component order
  • A marker removed by another component still marks where the cut starts or ends
  • Raw-text containers (textarea, script, …) are left alone
  • Nested containers: only the outermost is cut
  • Selector lists, several range components, and other content on the range component use the fast path; lists also apply per part on the per-element path

CPU per request on real pages, marker two levels deep: 1 MB 75 → 1.7 ms, 5 MB 404 → 8.4 ms, output identical to the per-element path. Direct-child markers are unchanged.

The fuzz compares fast-path pages with each range applied on its own by the per-element path, and fallback pages with the per-element path as is.

Minor changeset.

@changeset-bot

changeset-bot Bot commented Nov 5, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 31c289d

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@monetizationos/proxy Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The wrapped-range logic can corrupt SVG markup when namespace data is missing and leave later containers uncut when implicitly closed descendants leave stale nesting depth.

2 open issues
What changed in this PR

Expands the optimized replaceRange path in the surface-components pipeline, reducing per-element processing for more page shapes while retaining fallback handling.

Changes:

  • Adds sentinel-based cuts for nested start markers and supports multiple ranges and selector lists.
  • Updates interactions with other components, removed markers, raw-text containers, and nested containers.
  • Extends regression tests and randomized comparisons, with a minor Changeset.
File Description
test/​stages/​wrappedRange.spec.ts Adds coverage for expanded fast paths, fallback cases, and component interactions.
test/​fakes/​EndTagSpyRewriter.ts Records rewriter sessions and selectors for path assertions.
src/​stages/​wrappedRange.ts Implements expanded range planning, sentinel splicing, and selector helpers.
src/​stages/​voidElements.ts Exports the HTML namespace constant for range checks.
src/​stages/​surfaceComponents.ts Integrates nested-range splicing and multiple unwrap handlers.
src/​stages/​findMarkerPositions.ts Applies marker selectors correctly across selector lists.
src/​stages/​buildReplacementHandlers.ts Combines selector lists for per-element replacement handlers.
.changeset/​range-wrapper-more-shapes.md Documents the behavior changes as a minor release.

Review effort: Balanced

Comment thread src/stages/wrappedRange.ts Resolved
Comment thread src/stages/wrappedRange.ts Resolved
@benney
benney added this pull request to stack #44 November 5, 2026 14:28
@benney
benney force-pushed the feature/md-3009-mos-proxy-cut-more-replacerange-shapes-with-one-callback branch from d129c82 to a3e664f Compare November 5, 2026 15:25
@benney
benney force-pushed the feature/md-3009-mos-proxy-cut-more-replacerange-shapes-with-one-callback branch 3 times, most recently from 617234e to 4858d36 Compare November 6, 2026 10:58
Base automatically changed from feature/md-2768-mos-proxy-cut-replacerange-with-one-callback to main November 6, 2026 12:32
The wrapper now owns the shapes it used to hand back to the element path.
What other components insert inside the cut is removed with it, whatever
their order, and a marker another component removes still marks the cut,
so the inserting-component watchers and the removed-marker checks are gone.
A container holding raw text is left alone. Nested
containers are tracked by depth and only the outermost is cut, so a marker
that is a direct child of an inner one is still a nested marker.

Container and marker selector lists are split per part before the `>` and
descendant selectors are built, and the element path now builds its
descendant selectors the same way. Each range component gets its own
wrapper tag, so several ranges and other content on the range component
take the fast path. An element that is the container of two ranges, or the
container of one and a marker of another, sends the page back to the
element path.

The fuzz compares the wrapper with each range applied element by element
on its own ahead of the other components, and covers selector lists,
several ranges and content on the range component.
@benney
benney force-pushed the feature/md-3009-mos-proxy-cut-more-replacerange-shapes-with-one-callback branch from 4858d36 to d3e9ac7 Compare November 6, 2026 12:32
Comment thread test/stages/wrappedRange.spec.ts Resolved
@benney
benney requested a review from JFL110 November 6, 2026 14:06
@benney
benney merged commit 74e9663 into main Nov 6, 2026
3 checks passed
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.

3 participants