Skip to content

add support for base64 encoded inline source maps of formats#17

Merged
rmuratov merged 3 commits into
rmuratov:mainfrom
davidfiala:main
Apr 21, 2026
Merged

add support for base64 encoded inline source maps of formats#17
rmuratov merged 3 commits into
rmuratov:mainfrom
davidfiala:main

Conversation

@davidfiala
Copy link
Copy Markdown
Contributor

add support for base64 encoded inline source maps of formats:
data:application/json;base64,XXX

and

//# sourceMappingURL=data:application/json;base64,XXX

data:application/json;base64,XXX

and

//# sourceMappingURL=data:application/json;base64,XXX
@davidfiala
Copy link
Copy Markdown
Contributor Author

@rmuratov thank you so much for this online tool! It was hard to find on Google directly, but fortunately a perplexity query got me straight to you. The only thing extra I needed was inline source map support. I got tired of decoding them myself manually and pasting, so voila this PR. The extra textencoder (vs a direct atob) was recommended by AI to handle any corner cases with unicode filenames.

Note I that I tried to write tests for this, but vitest failed to run even without my commit (see below).

I ended up doing manual testing with npm run dev and trying to paste in some of my inline source maps.

$ node --version ; npm --version
v25.9.0
11.12.1
$ npm run test

> sourcemap.tools@0.0.1 test
> vitest --run


 RUN  v3.2.4 /sm

(node:9156) Warning: `--localstorage-file` was provided without a valid path
(Use `node --trace-warnings ...` to show where the warning was created)
 ❯ src/__tests__/app.test.tsx (22 tests | 22 failed) 27ms
   × general > renders 11ms
     → localStorage.getItem is not a function
   × stack trace > parses stack trace and shows file names 1ms
     → localStorage.getItem is not a function
   × stack trace > shows warning if parsing failed 1ms
     → localStorage.getItem is not a function
   × stack trace > clears the result after deleting stack trace 1ms
     → localStorage.getItem is not a function
   × source maps > allows selecting multiple source map files 1ms
     → localStorage.getItem is not a function
   × source maps > allows providing source map contents through text input 1ms
     → localStorage.getItem is not a function
   × source maps > updates related lines in the result after deleting sourcemap 1ms
     → localStorage.getItem is not a function
   × source maps > shows empty result after deleting all sourcemaps 1ms
     → localStorage.getItem is not a function
   × source maps > ignores empty files list 1ms
     → localStorage.getItem is not a function
   × source maps > shows warning if the file is not source map 1ms
     → localStorage.getItem is not a function
   × source maps > shows warning if the source map text content is not source map 1ms
     → localStorage.getItem is not a function
   × source maps > ignores existing source map 1ms
     → localStorage.getItem is not a function
   × source maps > allows opening file selector using keyboard 1ms
     → localStorage.getItem is not a function
   × source maps > handles null files in file input 1ms
     → localStorage.getItem is not a function
   × source maps > displays fallback name when source map has no fileName or fileNameInline 1ms
     → localStorage.getItem is not a function
   × source maps > decodes base64 data URL source map pasted into textarea 1ms
     → localStorage.getItem is not a function
   × source maps > decodes base64 data URL with charset parameter 1ms
     → localStorage.getItem is not a function
   × source maps > shows warning for malformed base64 data URL 1ms
     → localStorage.getItem is not a function
   × source maps > treats plain source map text as non-base64 (regression) 1ms
     → localStorage.getItem is not a function
   × theme > renders with light theme if prefers light theme 1ms
     → localStorage.getItem is not a function
   × theme > renders with dark theme if prefers dark theme 0ms
     → localStorage.getItem is not a function
   × theme > allows changing the theme 1ms
     → localStorage.getItem is not a function

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Failed Tests 22 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯

 FAIL  src/__tests__/app.test.tsx > general > renders
 FAIL  src/__tests__/app.test.tsx > stack trace > parses stack trace and shows file names
 FAIL  src/__tests__/app.test.tsx > stack trace > shows warning if parsing failed
 FAIL  src/__tests__/app.test.tsx > stack trace > clears the result after deleting stack trace
 FAIL  src/__tests__/app.test.tsx > source maps > allows selecting multiple source map files
 FAIL  src/__tests__/app.test.tsx > source maps > allows providing source map contents through text input
 FAIL  src/__tests__/app.test.tsx > source maps > updates related lines in the result after deleting sourcemap
 FAIL  src/__tests__/app.test.tsx > source maps > shows empty result after deleting all sourcemaps
 FAIL  src/__tests__/app.test.tsx > source maps > ignores empty files list
 FAIL  src/__tests__/app.test.tsx > source maps > shows warning if the file is not source map
 FAIL  src/__tests__/app.test.tsx > source maps > shows warning if the source map text content is not source map
 FAIL  src/__tests__/app.test.tsx > source maps > ignores existing source map
 FAIL  src/__tests__/app.test.tsx > source maps > allows opening file selector using keyboard
 FAIL  src/__tests__/app.test.tsx > source maps > handles null files in file input
 FAIL  src/__tests__/app.test.tsx > source maps > displays fallback name when source map has no fileName or fileNameInline
 FAIL  src/__tests__/app.test.tsx > source maps > decodes base64 data URL source map pasted into textarea
 FAIL  src/__tests__/app.test.tsx > source maps > decodes base64 data URL with charset parameter
 FAIL  src/__tests__/app.test.tsx > source maps > shows warning for malformed base64 data URL
 FAIL  src/__tests__/app.test.tsx > source maps > treats plain source map text as non-base64 (regression)
 FAIL  src/__tests__/app.test.tsx > theme > renders with light theme if prefers light theme
 FAIL  src/__tests__/app.test.tsx > theme > renders with dark theme if prefers dark theme
 FAIL  src/__tests__/app.test.tsx > theme > allows changing the theme
TypeError: localStorage.getItem is not a function
 ❯ themeFromLocalStorageGetSnapshot src/use-theme.ts:25:23
     23|
     24| function themeFromLocalStorageGetSnapshot(): null | Theme {
     25|   return localStorage.getItem('theme') as null | Theme
       |                       ^
     26| }
     27|
 ❯ mountSyncExternalStore node_modules/react-dom/cjs/react-dom-client.development.js:8125:24
 ❯ Object.useSyncExternalStore node_modules/react-dom/cjs/react-dom-client.development.js:26269:16
 ❯ process.env.NODE_ENV.exports.useSyncExternalStore node_modules/react/cjs/react.development.js:1270:34
 ❯ useThemeFromLocalStorage src/use-theme.ts:18:10
 ❯ useTheme src/use-theme.ts:11:33
 ❯ App src/app.tsx:22:17
 ❯ Object.react_stack_bottom_frame node_modules/react-dom/cjs/react-dom-client.development.js:25904:20
 ❯ renderWithHooks node_modules/react-dom/cjs/react-dom-client.development.js:7662:22
 ❯ updateFunctionComponent node_modules/react-dom/cjs/react-dom-client.development.js:10166:19

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/22]⎯


 Test Files  1 failed (1)
      Tests  22 failed (22)
   Start at  19:09:08
   Duration  540ms (transform 49ms, setup 29ms, collect 84ms, tests 27ms, environment 175ms, prepare 129ms)

@rmuratov
Copy link
Copy Markdown
Owner

rmuratov commented Apr 19, 2026

Hi @davidfiala! Thanks for your PR.

I tried it and found that the tests don't work on Node.js 25 due to a bug in Node itself (vitest-dev/vitest#8757, nodejs/node#60303). There are workarounds, but I'd rather wait until it's properly fixed and lands in an LTS release.

Could you try running and writing the tests on Node 24?

…ith node24 for devops security and reproducibility
@davidfiala
Copy link
Copy Markdown
Contributor Author

@rmuratov tests passing on node24. I now see you had a .nvmrc, but I also added a devcontainer for future contributors to have a safe, known-good environment baseline.

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 19, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (e2be9bd) to head (ae6523f).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff            @@
##              main       #17   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files            9         9           
  Lines          474       487   +13     
  Branches        97       102    +5     
=========================================
+ Hits           474       487   +13     

☔ View full report in Codecov by Sentry.
📢 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
Copy link
Copy Markdown
Owner

@davidfiala Thank you! I am merging it now for the sake of speed.

I do not know much about devcontainers now, so I might revise and refactor this part later.

@rmuratov rmuratov merged commit c3e81fe into rmuratov:main Apr 21, 2026
3 checks passed
@davidfiala
Copy link
Copy Markdown
Contributor Author

Thank you!

I'd always be happy to sync offline and share my thoughts on devcontainers. Pretty awesome stuff if you aren't already using them. My email is on my website, or LinkedIn.

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.

2 participants