chore(rrweb): Replace fast-mhtml with inline MHTML parser#274
chore(rrweb): Replace fast-mhtml with inline MHTML parser#274
Conversation
Remove the fast-mhtml dependency which was only used in one test utility function for parsing MHTML snapshots. Replace with a minimal inline parser (~30 lines) that handles multipart MIME boundary splitting and quoted-printable decoding. fast-mhtml pulled in cheerio, express, undici, qs, and bluebird — a massive transitive tree for a simple test helper. This removes ~584 lines from yarn.lock. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Remove dead `filename.includes('frame')` check that could never trigger
after replacing fast-mhtml with inline parser. Fix `decodeQuotedPrintable`
to correctly handle multi-byte UTF-8 sequences using TextDecoder.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Ignore compiled vitest configs and rrvideo temp directories that accumulate during local development and branch switching. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
| if (index !== -1) { | ||
| return `file-${prefix}-${index}`; | ||
| } else { | ||
| return `file-${prefix}-${resources.push(filename) - 1}`; |
There was a problem hiding this comment.
Regex null result stringified as "null" in filenames
Low Severity
When parseMhtml produces parts without a Content-Location header (frame documents), filename is ''. Then const prefix = /^\w+/.exec('') returns null, and the template literal file-${prefix}-${index} coerces null to the string "null", producing the label file-null-0. This also means all frame parts share the identical label file-null-0 (they were previously distinguishable as file-frame-4, file-frame-5, etc.), making snapshot output less informative for debugging.
Additional Locations (1)
Node.js 24 is now the latest LTS, which causes yarn v1 to hang during install. Pin to Node 20 (our tested version) until we can validate compatibility with newer versions. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
There are 2 total unresolved issues (including 1 from previous review).
Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
| const headers = part.substring(0, headerEnd); | ||
| const body = part | ||
| .substring(headerEnd + (separatorMatch?.[1].length || 4)) | ||
| .trim(); |
There was a problem hiding this comment.
Trim before QP decode corrupts trailing soft breaks
Low Severity
The .trim() is applied to the MHTML body before passing it to decodeQuotedPrintable. In quoted-printable encoding, =\r\n is a soft line break. If the last content line ends with a soft break (e.g., long line wrapping), .trim() strips the \r\n, leaving a dangling =. The QP decoder then treats this = as a literal character instead of a continuation marker, producing an extra = in the decoded output. Moving the .trim() to after decoding (or trimming only the decoded result) would avoid this.


Remove the
fast-mhtmldependency which was only used in one test utility function (packages/rrweb/test/utils.ts) for parsing MHTML snapshots in replayer E2E tests.Replace with a minimal inline parser (~30 lines) that handles multipart MIME boundary splitting and quoted-printable content decoding. All 47 replayer tests pass.
fast-mhtmlpulled incheerio,express,undici,qs,bluebird, andcookie— a massive transitive tree for a simple test helper. This removes ~584 lines fromyarn.lock.Dependabot alerts resolved
Fully resolved (vulnerable package completely removed from lockfile):
qsqsPartially resolved (some entries removed, but package still exists via other dependency chains):
undicipuppeteer(Phase 3)cookie@sveltejs/kit(Phase 5)closes https://linear.app/getsentry/issue/SDK-1097/replace-fast-mhtml-9-alerts