0
# Source Metadata Processing
1
2
Enhanced source map processing with support for function names and Facebook-specific metadata extensions.
3
4
## Capabilities
5
6
### SourceMetadataMapConsumer Class
7
8
Processes `x_facebook_sources` metadata from source maps to provide function name resolution and enhanced debugging information.
9
10
```javascript { .api }
11
/**
12
* Consumes Facebook-specific source map metadata for function name resolution
13
* @param map - Source map object (BasicSourceMap or IndexMap)
14
* @param normalizeSourceFn - Optional function to normalize source names
15
*/
16
class SourceMetadataMapConsumer {
17
constructor(map: MixedSourceMap, normalizeSourceFn?: SourceNameNormalizer);
18
19
/**
20
* Gets function name for a specific source location
21
* @param {line, column, source} - Object containing location details
22
* @returns Function name at the location, or null if not found
23
*/
24
functionNameFor({line, column, source}: {line: number, column: number, source: ?string}): ?string;
25
26
/**
27
* Returns this map's source metadata as a new array with the same order as sources
28
* @param sources - Array of source names
29
* @returns Array of metadata objects for each source
30
*/
31
toArray(sources: Array<string>): Array<?{[number]: any}>;
32
}
33
```
34
35
**Usage Examples:**
36
37
```javascript
38
const SourceMetadataMapConsumer = require('metro-symbolicate/private/SourceMetadataMapConsumer');
39
const fs = require('fs');
40
41
// Load source map with metadata
42
const sourceMap = JSON.parse(fs.readFileSync('bundle.js.map', 'utf8'));
43
const metadataConsumer = new SourceMetadataMapConsumer(sourceMap);
44
45
// Get function name for a location
46
const functionName = metadataConsumer.functionNameFor({
47
source: 'src/utils.js',
48
line: 15,
49
column: 8
50
});
51
if (functionName) {
52
console.log(`Function at src/utils.js:15:8 is: ${functionName}`);
53
}
54
55
// Convert metadata to array format
56
const sources = ['src/app.js', 'src/utils.js'];
57
const metadataArray = metadataConsumer.toArray(sources);
58
console.log('Metadata for sources:', metadataArray);
59
```
60
61
### Function Name Resolution
62
63
Provides enhanced function name resolution beyond standard source map capabilities, particularly useful for React Native and Metro bundles.
64
65
**Function Name vs Identifier Names:**
66
67
Metro source maps can contain two types of name information:
68
- **Function names**: Actual function declarations and expressions (`function myFunction()`, `const myFunc = () => {}`)
69
- **Identifier names**: Variable and property names at specific locations
70
71
```javascript
72
// Example source code:
73
const utils = {
74
processData: function validateAndProcess(input) {
75
return input.trim();
76
}
77
};
78
79
// Function name: "validateAndProcess"
80
// Identifier name: "processData" (property name), "input" (parameter), "trim" (method call)
81
```
82
83
**Usage Examples:**
84
85
```javascript
86
const SourceMetadataMapConsumer = require('metro-symbolicate/private/SourceMetadataMapConsumer');
87
88
// Create consumer with default normalization
89
const consumer = new SourceMetadataMapConsumer(sourceMap);
90
91
// Create consumer with custom source name normalization
92
const customConsumer = new SourceMetadataMapConsumer(sourceMap, (source, options) => {
93
// Custom normalization logic
94
return source.replace(/^webpack:\/\/\//, '');
95
});
96
97
// Function name resolution examples
98
const functionName = consumer.functionNameFor({source: 'src/api.js', line: 42, column: 10});
99
switch (functionName) {
100
case null:
101
console.log('No function name available');
102
break;
103
default:
104
console.log(`Function: ${functionName}`);
105
}
106
```
107
108
### Source Map Metadata Integration
109
110
Seamlessly integrates with standard source map processing while providing enhanced metadata capabilities.
111
112
**Source Map Compatibility:**
113
114
```javascript { .api }
115
type MixedSourceMap = BasicSourceMap | IndexMap;
116
117
type BasicSourceMap = {
118
version: number;
119
sources: Array<string>;
120
names: Array<string>;
121
mappings: string;
122
file?: string;
123
sourceRoot?: string;
124
sourcesContent?: Array<?string>;
125
x_facebook_sources?: FBSourcesArray;
126
};
127
128
type IndexMap = {
129
version: number;
130
file?: string;
131
sections: Array<IndexMapSection>;
132
x_facebook_sources?: FBSourcesArray;
133
};
134
135
type SourceNameNormalizer = (
136
source: string,
137
options: { sourceRoot?: ?string }
138
) => string;
139
```
140
141
**Usage Examples:**
142
143
```javascript
144
// Working with different source map types
145
const processSourceMap = (sourceMapData) => {
146
const consumer = new SourceMetadataMapConsumer(sourceMapData);
147
148
// Handle both basic and indexed source maps
149
if (sourceMapData.sections) {
150
console.log('Processing indexed source map');
151
} else {
152
console.log('Processing basic source map');
153
}
154
155
// Function name resolution works for both types
156
return consumer.functionNameFor({source: 'src/main.js', line: 1, column: 0});
157
};
158
```
159
160
### VLQ Decoding Support
161
162
Handles Variable Length Quantity (VLQ) encoding used in Facebook source map extensions for compact metadata storage.
163
164
**Internal VLQ Processing:**
165
166
The SourceMetadataMapConsumer automatically handles VLQ-encoded function map data:
167
168
```javascript
169
// VLQ-encoded function mappings are automatically decoded
170
// No direct VLQ manipulation needed by consumers
171
172
// Example: checking for function name availability
173
const fname = consumer.functionNameFor({source: 'src/complex-component.js', line: 100, column: 25});
174
if (fname) {
175
// Function map data has been successfully decoded from VLQ format
176
console.log(`Decoded function name: ${fname}`);
177
}
178
```
179
180
### Error Handling
181
182
Graceful handling of missing or invalid metadata without breaking standard source map functionality.
183
184
**Error Scenarios:**
185
186
```javascript
187
const consumer = new SourceMetadataMapConsumer(sourceMap);
188
189
// Missing function map - returns null, doesn't throw
190
const missingFunction = consumer.functionNameFor({source: 'nonexistent.js', line: 1, column: 1});
191
console.log(missingFunction); // null
192
193
// Invalid coordinates - returns null gracefully
194
const invalidCoords = consumer.functionNameFor({source: 'src/app.js', line: -1, column: -1});
195
console.log(invalidCoords); // null
196
197
// Check availability before querying
198
const source = 'src/utils.js';
199
const functionName = consumer.functionNameFor({source, line: 50, column: 10});
200
if (functionName) {
201
// Safe to use functionName, function map exists
202
} else {
203
console.log(`No function map available for ${source}`);
204
}
205
```
206
207
## Types
208
209
```javascript { .api }
210
type FBSourcesArray = Array<?FBSourceMetadata>;
211
212
type FBSourceMetadata = Array<FBSourceMetadataField>;
213
214
type FBSourceMetadataField = FBSourceFunctionMap;
215
216
type FBSourceFunctionMap = {
217
names: Array<string>;
218
mappings: string; // VLQ-encoded function mappings
219
};
220
221
type Position = {
222
line: number;
223
column: number;
224
};
225
226
type FunctionMapping = {
227
line: number;
228
column: number;
229
name: string;
230
};
231
232
type MetadataMap = { [source: string]: ?FBSourceMetadata };
233
```