Skip to content

Commit

Permalink
feat(sourcemap): Add support for sourcemap debug IDs (#6221)
Browse files Browse the repository at this point in the history
The sourcemap [`debugId`
proposal](https://github.com/tc39/source-map/blob/main/proposals/debug-id.md)
adds globally unique build or debug IDs to source maps and generated
code, making build artifacts self-identifying.

Support for debug IDs was added to
[`rust-sourcemap`](getsentry/rust-sourcemap#66)
in 2023 and Sentry have made use of this to aid in matching up source
and sourcemap files without having to worry about path mismatches or
release versions.

I want to add debug ID support to Rolldown but it uses `oxc::sourcemap`
so it looks like I need to start here first!
  • Loading branch information
timfish authored Oct 7, 2024
1 parent 9e62396 commit f6e42b6
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 1 deletion.
3 changes: 3 additions & 0 deletions crates/oxc_sourcemap/src/decode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ pub struct JSONSourceMap {
pub sources_content: Option<Vec<Option<String>>>,
/// A list of symbol names used by the “mappings” entry.
pub names: Vec<String>,
/// An optional field containing the debugId for this sourcemap.
pub debug_id: Option<String>,
}

pub fn decode(json: JSONSourceMap) -> Result<SourceMap> {
Expand All @@ -38,6 +40,7 @@ pub fn decode(json: JSONSourceMap) -> Result<SourceMap> {
tokens,
token_chunks: None,
x_google_ignore_list: None,
debug_id: json.debug_id,
})
}

Expand Down
10 changes: 9 additions & 1 deletion crates/oxc_sourcemap/src/encode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ pub fn encode(sourcemap: &SourceMap) -> JSONSourceMap {
.as_ref()
.map(|x| x.iter().map(ToString::to_string).map(Some).collect()),
names: sourcemap.names.iter().map(ToString::to_string).collect(),
debug_id: sourcemap.get_debug_id().map(ToString::to_string),
}
}

Expand Down Expand Up @@ -76,6 +77,12 @@ pub fn encode_to_string(sourcemap: &SourceMap) -> String {

contents.push("],\"mappings\":\"".into());
contents.push(serialize_sourcemap_mappings(sourcemap).into());

if let Some(debug_id) = sourcemap.get_debug_id() {
contents.push("\",\"debugId\":\"".into());
contents.push(debug_id.into());
}

contents.push("\"}".into());

// Check we calculated number of segments required correctly
Expand Down Expand Up @@ -401,9 +408,10 @@ fn test_encode_escape_string() {
None,
);
sm.set_x_google_ignore_list(vec![0]);
sm.set_debug_id("56431d54-c0a6-451d-8ea2-ba5de5d8ca2e");
assert_eq!(
sm.to_json_string(),
r#"{"version":3,"names":["name_length_greater_than_16_\u0000"],"sources":["\u0000"],"sourcesContent":["emoji-👀-\u0000"],"x_google_ignoreList":[0],"mappings":""}"#
r#"{"version":3,"names":["name_length_greater_than_16_\u0000"],"sources":["\u0000"],"sourcesContent":["emoji-👀-\u0000"],"x_google_ignoreList":[0],"mappings":"","debugId":"56431d54-c0a6-451d-8ea2-ba5de5d8ca2e"}"#
);
}

Expand Down
10 changes: 10 additions & 0 deletions crates/oxc_sourcemap/src/sourcemap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ pub struct SourceMap {
/// The `x_google_ignoreList` field refers to the `sources` array, and lists the indices of all the known third-party sources in that source map.
/// When parsing the source map, developer tools can use this to determine sections of the code that the browser loads and runs that could be automatically ignore-listed.
pub(crate) x_google_ignore_list: Option<Vec<u32>>,
pub(crate) debug_id: Option<String>,
}

#[allow(clippy::cast_possible_truncation)]
Expand All @@ -43,6 +44,7 @@ impl SourceMap {
tokens,
token_chunks,
x_google_ignore_list: None,
debug_id: None,
}
}

Expand Down Expand Up @@ -95,6 +97,14 @@ impl SourceMap {
self.x_google_ignore_list = Some(x_google_ignore_list);
}

pub fn set_debug_id(&mut self, debug_id: &str) {
self.debug_id = Some(debug_id.into());
}

pub fn get_debug_id(&self) -> Option<&str> {
self.debug_id.as_deref()
}

pub fn get_names(&self) -> impl Iterator<Item = &str> {
self.names.iter().map(AsRef::as_ref)
}
Expand Down

0 comments on commit f6e42b6

Please sign in to comment.