Skip to content

Destroy consumers of rejected duplicates, keep state updaters pure - #36

Merged
rmuratov merged 2 commits into
mainfrom
fix-consumer-lifecycle
Jul 5, 2026
Merged

Destroy consumers of rejected duplicates, keep state updaters pure#36
rmuratov merged 2 commits into
mainfrom
fix-consumer-lifecycle

Conversation

@rmuratov

@rmuratov rmuratov commented Jul 5, 2026

Copy link
Copy Markdown
Owner

Closes #23
Closes #24

What

Reworks useSourcemapsStore so that SourceMapConsumer lifecycle management happens outside the React state updaters.

Deliberately not destroying consumers on unmount: StrictMode's dev-only remount preserves state while running effect cleanups, so an unmount cleanup would destroy consumers that are still referenced after the remount. The store lives in the root component, where unmount means page unload anyway.

Tests

Three new integration tests in the source map lifecycle suite spy on destroy() via the prototype of the concrete consumer class:

  • re-uploading the same file destroys the rejected duplicate's consumer and keeps one list item,
  • selecting two identical files together adds the map once and destroys the extra consumer,
  • deleting a source map under StrictMode destroys the consumer exactly once.

All three fail against the previous implementation and pass with the fix; the full suite is 29/29.

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 5, 2026

Copy link
Copy Markdown

Deploying sourcemap-tools with  Cloudflare Pages  Cloudflare Pages

Latest commit: 3284631
Status: ✅  Deploy successful!
Preview URL: https://5ccb458c.sourcemap-tools.pages.dev
Branch Preview URL: https://fix-consumer-lifecycle.sourcemap-tools.pages.dev

View logs

@codecov

codecov Bot commented Jul 5, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (5be63c6) to head (3284631).

Additional details and impacted files
@@            Coverage Diff            @@
##              main       #36   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files            9         9           
  Lines          203       208    +5     
  Branches        51        52    +1     
=========================================
+ Hits           203       208    +5     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@rmuratov

rmuratov commented Jul 5, 2026

Copy link
Copy Markdown
Owner Author

Added a follow-up commit that restores 100% coverage and enforces it via coverage.thresholds: { 100: true } in vite.config.ts (CI runs npm run coverage, so any future drop below 100% fails the build).

The three uncovered spots and how they were handled:

  • use-sourcemaps-store.ts — the if (!target) return guard in deleteSourceMap was unreachable through the UI (delete buttons only exist for rendered items; this gap existed on main too). Replaced the not-found special case with a loop that destroys matching consumers — both branch outcomes are exercised by existing tests.
  • lib.ts — the position.column == null ? null : … arm in toUnifiedPosition was dead code: when originalPositionFor finds a mapping, source, line, and column are always present. Replaced the ternary with an isResolvedPosition type guard in tryGetOriginalPosition, so toUnifiedPosition now takes a fully resolved position and the dead branch is gone.
  • app.tsx — the non-Enter path of the file-upload button's keydown handler (uncovered since before this PR) is now covered by firing a KeyA keydown and asserting the file selector does not open.

@rmuratov
rmuratov merged commit 88b68db into main Jul 5, 2026
4 checks passed
@rmuratov
rmuratov deleted the fix-consumer-lifecycle branch July 5, 2026 16:45
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.

Side effect inside setState updater in deleteSourceMap Memory leak: SourceMapConsumer never destroyed for rejected duplicates

1 participant