0
# Source Map Consumption
1
2
Functionality for reading and querying source maps with support for both basic and indexed source map formats, including Facebook and Hermes extensions.
3
4
## Capabilities
5
6
### Consumer Class
7
8
Main class for consuming and querying source maps. Automatically handles both basic and indexed source map formats.
9
10
```javascript { .api }
11
/**
12
* Source map consumer supporting both basic and indexed formats
13
*/
14
class Consumer {
15
/** Iteration order constant for generated positions */
16
static GENERATED_ORDER: IterationOrder;
17
18
/** Iteration order constant for original positions */
19
static ORIGINAL_ORDER: IterationOrder;
20
21
/** Lookup bias for greatest lower bound searches */
22
static GREATEST_LOWER_BOUND: LookupBias;
23
24
/** Lookup bias for least upper bound searches */
25
static LEAST_UPPER_BOUND: LookupBias;
26
27
/**
28
* Creates a consumer for the given source map
29
* @param sourceMap - Source map object (basic or indexed format)
30
*/
31
constructor(sourceMap: MixedSourceMap);
32
33
/**
34
* Find the original position for a generated position
35
* @param generatedPosition - Generated line/column with optional bias
36
* @returns Original source position or null if not found
37
*/
38
originalPositionFor(generatedPosition: GeneratedPositionLookup): SourcePosition;
39
40
/**
41
* Get an iterable of all mappings in generated order
42
* @returns Iterable of all mappings in the source map
43
*/
44
generatedMappings(): Iterable<Mapping>;
45
46
/**
47
* Iterate over all mappings in the source map
48
* @param callback - Function called for each mapping
49
* @param context - Optional context object for callback
50
* @param order - Optional iteration order (GENERATED_ORDER or ORIGINAL_ORDER)
51
*/
52
eachMapping(
53
callback: (mapping: Mapping) => mixed,
54
context?: mixed,
55
order?: IterationOrder
56
): void;
57
58
/**
59
* Get the file name associated with this source map
60
* @returns Source map file name or null
61
*/
62
get file(): ?string;
63
64
/**
65
* Get the source content for a given source file
66
* @param source - Source file path
67
* @param nullOnMissing - Must be true, returns null if source not found
68
* @returns Source file content or null
69
*/
70
sourceContentFor(source: string, nullOnMissing: true): ?string;
71
}
72
```
73
74
**Usage Examples:**
75
76
```javascript
77
const { Consumer } = require("metro-source-map");
78
79
// Create consumer from a source map
80
const sourceMap = {
81
version: 3,
82
sources: ["src/app.js"],
83
names: ["console", "log"],
84
mappings: "AAAA,QAAQ,CAAC,GAAG",
85
sourcesContent: ["console.log('hello');"]
86
};
87
88
const consumer = new Consumer(sourceMap);
89
90
// Find original position for generated position
91
const originalPos = consumer.originalPositionFor({
92
line: 1,
93
column: 8,
94
bias: Consumer.GREATEST_LOWER_BOUND
95
});
96
console.log(originalPos);
97
// { source: "src/app.js", line: 1, column: 8, name: null }
98
99
// Get source content
100
const sourceContent = consumer.sourceContentFor("src/app.js", true);
101
console.log(sourceContent);
102
// "console.log('hello');"
103
104
// Get all mappings as an iterable
105
const mappings = consumer.generatedMappings();
106
for (const mapping of mappings) {
107
console.log(`Generated: ${mapping.generatedLine}:${mapping.generatedColumn}`);
108
console.log(`Original: ${mapping.originalLine}:${mapping.originalColumn}`);
109
}
110
111
// Or iterate over all mappings with callback
112
consumer.eachMapping((mapping) => {
113
console.log(`Generated: ${mapping.generatedLine}:${mapping.generatedColumn}`);
114
console.log(`Original: ${mapping.originalLine}:${mapping.originalColumn}`);
115
console.log(`Source: ${mapping.source}`);
116
console.log(`Name: ${mapping.name}`);
117
});
118
```
119
120
### Position Types
121
122
Types representing positions in generated and original source code.
123
124
```javascript { .api }
125
/**
126
* Position in original source code
127
*/
128
interface SourcePosition {
129
/** Source file path */
130
source: ?string;
131
/** Line number (1-based) */
132
line: ?number;
133
/** Column number (0-based) */
134
column: ?number;
135
/** Symbol name at this position */
136
name: ?string;
137
}
138
139
/**
140
* Generated position lookup with optional bias
141
*/
142
interface GeneratedPositionLookup {
143
/** Line number (1-based), null to match any line */
144
line: ?number;
145
/** Column number (0-based), null to match any column */
146
column: ?number;
147
/** Search bias for inexact matches */
148
bias?: LookupBias;
149
}
150
151
/**
152
* Complete mapping information
153
*/
154
interface Mapping {
155
/** Source file path */
156
source: ?string;
157
/** Generated line number (1-based) */
158
generatedLine: number;
159
/** Generated column number (0-based) */
160
generatedColumn: number;
161
/** Original line number (1-based) */
162
originalLine: ?number;
163
/** Original column number (0-based) */
164
originalColumn: ?number;
165
/** Symbol name */
166
name: ?string;
167
}
168
```
169
170
### Constants and Types
171
172
```javascript { .api }
173
/**
174
* Iteration order for eachMapping
175
*/
176
type IterationOrder = "GENERATED_ORDER" | "ORIGINAL_ORDER";
177
178
/**
179
* Lookup bias for position searches
180
*/
181
type LookupBias = "GREATEST_LOWER_BOUND" | "LEAST_UPPER_BOUND";
182
183
/**
184
* ob1 number types (1-based and 0-based)
185
*/
186
// Note: All numeric positions use regular number type
187
// Line numbers are typically 1-based, column numbers are 0-based
188
```
189
190
### Advanced Usage
191
192
```javascript
193
const { Consumer } = require("metro-source-map");
194
195
// Working with indexed source maps
196
const indexedMap = {
197
version: 3,
198
sections: [
199
{
200
offset: { line: 0, column: 0 },
201
map: {
202
version: 3,
203
sources: ["module1.js"],
204
names: ["fn1"],
205
mappings: "AAAA"
206
}
207
},
208
{
209
offset: { line: 10, column: 0 },
210
map: {
211
version: 3,
212
sources: ["module2.js"],
213
names: ["fn2"],
214
mappings: "AAAA"
215
}
216
}
217
]
218
};
219
220
const consumer = new Consumer(indexedMap);
221
222
// Search with bias for inexact matches
223
const result = consumer.originalPositionFor({
224
line: 5,
225
column: 10,
226
bias: Consumer.GREATEST_LOWER_BOUND
227
});
228
229
// Iterate in original source order
230
consumer.eachMapping((mapping) => {
231
console.log(`${mapping.source}:${mapping.originalLine}:${mapping.originalColumn}`);
232
}, null, Consumer.ORIGINAL_ORDER);
233
234
// Handle missing source content gracefully
235
const content = consumer.sourceContentFor("missing.js", true);
236
if (content === null) {
237
console.log("Source content not available");
238
}
239
```
240
241
## Error Handling
242
243
Consumer methods may encounter the following error conditions:
244
245
- **Invalid source map format**: Malformed source map objects
246
- **Missing source content**: When `sourceContentFor` is called without `nullOnMissing=true`
247
- **Invalid position data**: When position objects have invalid line/column values
248
249
```javascript
250
try {
251
const consumer = new Consumer(sourceMap);
252
const position = consumer.originalPositionFor({ line: 1, column: 0 });
253
} catch (error) {
254
console.error('Source map consumption failed:', error);
255
}
256
257
// Safe source content access
258
const content = consumer.sourceContentFor("app.js", true);
259
if (content === null) {
260
console.warn("Source content not available for app.js");
261
}
262
```