pasta
extends the source map format with a x_com_bloomberg_sourcesFunctionMappings
field to allow for accurate function name decoding.
Source code often gets modified one way or another before hitting production - through transpilation, minification, etc. Looking at a "raw" crash stack of generated code can be hard work. Here's a comparison of crash stacks for a sample file.
// sample.js
const penne = () => { throw Error(); }
const spaghetti = () => penne();
const orzo = () => spaghetti();
orzo();
// **original** output // **compiled** output
Error Error
at penne (sample.js:2:33) at r (out.js:1:82)
at spaghetti (sample.js:3:25) vs at o (out.js:1:97)
at orzo (sample.js:4:25) at n (out.js:1:107)
Today, source maps already provide the ability to produce accurate locations (filename, line number, column number) in a crash stack, but not enclosing function names. This hinders debugging and confuses automatic crash stack consolidation.
Extra information is added into the source maps to allow immediate decoding of the name of the enclosing function, without needing to consult any other files.
Example
var a = 1; // Name: "<top-level>"
function penne () {
var b = 2; // Name: "penne"
(function () {
var c = 3; // Name: "<anonymous>"
})();
var d = 4; // Name: "penne"
return; // Name: "penne"
}
penne(); // Name: "<top-level>"
x_com_bloomberg_sourcesFunctionMappings
is a new source map field that describes, for a given range in a source, the enclosing function's name.
This implies a two-phase decode. First, the source location is decoded, the same way it is done today. Second, the function name is decoded using the source location.
The existing names
array is used to store function names.
Example source map with extension
{
"file":"generated.js",
"version":3,
"sources": [
"barilla.ts"
"muellers.ts"],
"names":[
"define",
"console",
// **NEW** supplementary function names
"penne",
"fusilli"
],
"mappings": "...",
// **NEW** for each source, a list of mappings of function names
"x_com_bloomberg_sourcesFunctionMappings": [
"<function name mappings for sources[0]>",
"<function name mappings for sources[1]>"
],
"sourceRoot":"../../.."
}
"x_com_bloomberg_sourcesFunctionMappings"
is an optional list of function mapping sequences for each source.
The function mapping sequences are listed in the same order as the sources
property.
null
may be used if there is no function mapping sequence for a given source.
A function mapping sequences is a comma-separated list of VLQ-encoded mappings for a single source. Each mapping contains exactly five integer fields:
- functionName is a zero-based index into the
names
array, relative to the previous mapping's functionName. - startLine is the zero-based starting line in the source, relative to the previous mapping's endLine.
- startColumn is the zero-based starting column in the source, relative to the previous mapping's startColumn.
- endLine is the zero-based ending line in the source, relative to startLine.
- endColumn is the zero-based ending column in the source, relative to the previous mapping's endColumn.
The first mapping in a sequence is treated as having a previous mapping with all values set to zero.
Invariants:
- Mappings are stored in order such that the starting positions are always ascending; first by line, then by column.
- Mappings can fully overlap ("nesting") but will never partially overlap.
Notes:
- There is no guarantee that mappings will be provided for all positions in a source. It may have gaps.
- Negative startLine values imply nesting.
- Relative-positioning was chosen over absolute-positioning to reduce the file-size.
Example Logical Encoding
{
"sources": [
"barilla.ts"
"muellers.ts"
],
"names": [
"penne",
"fusilli",
"orzo",
],
"x_com_bloomberg_sourcesFunctionMappings": [
[
[0,0,19,6,0], // barilla.ts (1:20)...(7:1) => "penne"
[1,-2,19,1,4] // barilla.ts (5:39)...(6:5) => "fusilli"
],
[
[2,0,10,0,79] // muellers.ts (1:11)...(1,80) => "orzo"
]
]
}
Example Physical Encoding
{
"sources": [
"barilla.ts"
"muellers.ts"
],
"names": [
"penne",
"fusilli",
"orzo",
],
"x_com_bloomberg_sourcesFunctionMappings": [
"AAmBMA,CFmBCI",
"EAUA+E"
]
}
- Source Map Revision 3 specification
- Proposal by Andy Sterland & Ron Buckton from 2014-09
- Related discussion
- Noted omission: Does not support decoding renamed object properties
- Proposal by Nick Fitzgerald from 2015-07
- Web App: Source Map Visualizer
- Web App: VLQ Encoder/Decoder
- NPM Package: source-map encoder/decoder
- Mozilla Source Map Discussion Board
- Stack Trace Analysis Tool (STAT)
- Merges multiple stack traces from independent processes together and detects similiarities.
- Sentry - Error Tracking Software
- Discusses the aggregation ("grouping") abilities of the product, including the ability to read source maps.