🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

metro-source-map

Package Overview
Dependencies
Maintainers
2
Versions
185
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

metro-source-map - npm Package Compare versions

Comparing version
0.85.0
to
0.86.0
+40
src/LineIndexedMappings.d.ts
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @noformat
* @oncall react_native
* @generated SignedSource<<b3f5bf11c317fcd72b08780359fb893c>>
*
* This file was translated from Flow by scripts/generateTypeScriptDefinitions.js
* Original file: packages/metro-source-map/src/LineIndexedMappings.js
* To regenerate, run:
* js1 build metro-ts-defs (internal) OR
* yarn run build-ts-defs (OSS)
*/
/**
* A compact, lazily-decoded view of one module's VLQ `mappings` for the
* generated -> original position lookup that `/symbolicate` performs.
*
* Construction builds a per-line index: one entry per generated line holding the
* byte offset into `mappings` where that line's segments begin and the
* source-line/source-column delta accumulators as they stand entering the line.
* A lookup jumps to the target line and decodes only that line's segments in
* place over the retained `mappings` string, allocating nothing.
*
* VLQ deltas are cumulative across the whole string, so the index snapshots the
* accumulator state at each line start to make any line independently
* decodable. The index holds O(lines) integers; generated columns reset per
* line and are not stored.
*/
declare class LineIndexedMappings {
constructor(mappings: string);
originalPositionFor(
generatedLine1Based: number,
generatedColumn0Based: number,
): null | undefined | {line1Based: number; column0Based: number};
}
export default LineIndexedMappings;
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true,
});
exports.default = void 0;
const BASE64_VALUES = (() => {
const table = new Int16Array(128).fill(-1);
const chars =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
for (let i = 0; i < chars.length; i++) {
table[chars.charCodeAt(i)] = i;
}
return table;
})();
const VLQ_SEMICOLON = 59;
const VLQ_COMMA = 44;
function readVlq(mappings, cursor) {
let shift = 0;
let value = 0;
let continuation;
let i = cursor[0];
do {
const digit = BASE64_VALUES[mappings.charCodeAt(i++)];
continuation = digit & 32;
value = value + ((digit & 31) << shift);
shift = shift + 5;
} while (continuation);
cursor[0] = i;
const shouldNegate = value & 1;
value = value >>> 1;
return shouldNegate ? -value : value;
}
function isFieldAhead(mappings, index, length) {
return (
index < length &&
mappings.charCodeAt(index) !== VLQ_SEMICOLON &&
mappings.charCodeAt(index) !== VLQ_COMMA
);
}
class LineIndexedMappings {
#mappings;
#lineByteOffset;
#srcLineAtLineStart;
#srcColAtLineStart;
#lineCount;
constructor(mappings) {
const length = mappings.length;
let lineCount = 1;
for (let i = 0; i < length; i++) {
if (mappings.charCodeAt(i) === VLQ_SEMICOLON) {
lineCount++;
}
}
const lineByteOffset = new Int32Array(lineCount);
const srcLineAtLineStart = new Int32Array(lineCount);
const srcColAtLineStart = new Int32Array(lineCount);
let originalLine = 1;
let originalColumn = 0;
let line = 0;
const cursor = [0];
lineByteOffset[0] = 0;
srcLineAtLineStart[0] = originalLine;
srcColAtLineStart[0] = originalColumn;
while (cursor[0] < length) {
const c = mappings.charCodeAt(cursor[0]);
if (c === VLQ_SEMICOLON) {
cursor[0]++;
line++;
lineByteOffset[line] = cursor[0];
srcLineAtLineStart[line] = originalLine;
srcColAtLineStart[line] = originalColumn;
continue;
}
if (c === VLQ_COMMA) {
cursor[0]++;
continue;
}
readVlq(mappings, cursor);
if (isFieldAhead(mappings, cursor[0], length)) {
readVlq(mappings, cursor);
originalLine = originalLine + readVlq(mappings, cursor);
originalColumn = originalColumn + readVlq(mappings, cursor);
if (isFieldAhead(mappings, cursor[0], length)) {
readVlq(mappings, cursor);
}
}
}
this.#mappings = mappings;
this.#lineByteOffset = lineByteOffset;
this.#srcLineAtLineStart = srcLineAtLineStart;
this.#srcColAtLineStart = srcColAtLineStart;
this.#lineCount = lineCount;
}
originalPositionFor(generatedLine1Based, generatedColumn0Based) {
if (generatedLine1Based < 1 || generatedLine1Based > this.#lineCount) {
return null;
}
const lineIndex = generatedLine1Based - 1;
const mappings = this.#mappings;
const length = mappings.length;
const cursor = [this.#lineByteOffset[lineIndex]];
let originalLine = this.#srcLineAtLineStart[lineIndex];
let originalColumn = this.#srcColAtLineStart[lineIndex];
let generatedColumn = 0;
let found = false;
let foundHasSource = false;
let foundLine = 0;
let foundColumn = 0;
while (cursor[0] < length) {
const c = mappings.charCodeAt(cursor[0]);
if (c === VLQ_SEMICOLON) {
break;
}
if (c === VLQ_COMMA) {
cursor[0]++;
continue;
}
generatedColumn = generatedColumn + readVlq(mappings, cursor);
if (generatedColumn > generatedColumn0Based) {
break;
}
if (isFieldAhead(mappings, cursor[0], length)) {
readVlq(mappings, cursor);
originalLine = originalLine + readVlq(mappings, cursor);
originalColumn = originalColumn + readVlq(mappings, cursor);
if (isFieldAhead(mappings, cursor[0], length)) {
readVlq(mappings, cursor);
}
found = true;
foundHasSource = true;
foundLine = originalLine;
foundColumn = originalColumn;
} else {
found = true;
foundHasSource = false;
}
}
if (!found || !foundHasSource) {
return null;
}
return {
line1Based: foundLine,
column0Based: foundColumn,
};
}
}
exports.default = LineIndexedMappings;

Sorry, the diff of this file is not supported yet

+3
-3
{
"name": "metro-source-map",
"version": "0.85.0",
"version": "0.86.0",
"description": "🚇 Source map generator for Metro.",

@@ -25,5 +25,5 @@ "main": "src/source-map.js",

"invariant": "^2.2.4",
"metro-symbolicate": "0.85.0",
"metro-symbolicate": "0.86.0",
"nullthrows": "^1.1.1",
"ob1": "0.85.0",
"ob1": "0.86.0",
"source-map": "^0.5.6",

@@ -30,0 +30,0 @@ "vlq": "^1.0.0"

@@ -9,3 +9,3 @@ /**

* @oncall react_native
* @generated SignedSource<<920bacbb8042b15a2cd4888e0ca47b8c>>
* @generated SignedSource<<a3b673eadec9c804b8a10df9d304100e>>
*

@@ -41,4 +41,4 @@ * This file was translated from Flow by scripts/generateTypeScriptDefinitions.js

export declare function createIndexMap(
file: string,
file: null | undefined | string,
sections: Array<IndexMapSection>,
): IndexMap;

@@ -86,5 +86,9 @@ "use strict";

version: 3,
file,
...(file != null
? {
file,
}
: null),
sections,
};
}

@@ -9,3 +9,3 @@ /**

* @oncall react_native
* @generated SignedSource<<7303fe7149cb12d764c6106cdf4f49ee>>
* @generated SignedSource<<a3a499a683d5ea557e429489802510ae>>
*

@@ -39,2 +39,14 @@ * This file was translated from Flow by scripts/generateTypeScriptDefinitions.js

| GeneratedCodeMapping;
type BabelDecodedMapSegment =
| [number]
| [number, number, number, number]
| [number, number, number, number, number];
export type BabelDecodedMap = {
readonly mappings: ReadonlyArray<ReadonlyArray<BabelDecodedMapSegment>>;
readonly names: ReadonlyArray<string>;
};
export type VlqMap = {
readonly mappings: string;
readonly names: ReadonlyArray<string>;
};
export type HermesFunctionOffsets = {

@@ -89,3 +101,31 @@ [$$Key$$: number]: ReadonlyArray<number>;

export type MixedSourceMap = IndexMap | BasicSourceMap;
export type RawMappingsModule = {
readonly map:
| (null | undefined | ReadonlyArray<MetroSourceMapSegmentTuple>)
| VlqMap;
readonly functionMap: null | undefined | FBSourceFunctionMap;
readonly path: string;
readonly source: string;
readonly code: string;
readonly isIgnored: boolean;
readonly lineCount?: number;
};
export interface SourceMapGenerator {
toMap(file?: string, options?: {excludeSource?: boolean}): MixedSourceMap;
toString(file?: string, options?: {excludeSource?: boolean}): string;
}
/**
* Result of `fromRawMappingsIndexed`: a sectioned (indexed) source map where
* each module is one section. VLQ-stored modules pass through verbatim, which is
* why building this is cheap compared to flattening into a single map.
*/
declare class IndexedSourceMapResult implements SourceMapGenerator {
constructor(sections: Array<IndexMapSection>);
toMap(file?: string, options?: {excludeSource?: boolean}): MixedSourceMap;
toString(file?: string, options?: {excludeSource?: boolean}): string;
}
declare function isVlqMap(
map: (null | undefined | ReadonlyArray<MetroSourceMapSegmentTuple>) | VlqMap,
): map is VlqMap;
/**
* Creates a source map from modules with "raw mappings", i.e. an array of

@@ -98,26 +138,21 @@ * tuples with either 2, 4, or 5 elements:

declare function fromRawMappings(
modules: ReadonlyArray<{
readonly map: null | undefined | ReadonlyArray<MetroSourceMapSegmentTuple>;
readonly functionMap: null | undefined | FBSourceFunctionMap;
readonly path: string;
readonly source: string;
readonly code: string;
readonly isIgnored: boolean;
readonly lineCount?: number;
}>,
modules: ReadonlyArray<RawMappingsModule>,
offsetLines?: number,
): Generator;
declare function fromRawMappingsNonBlocking(
modules: ReadonlyArray<{
readonly map: null | undefined | ReadonlyArray<MetroSourceMapSegmentTuple>;
readonly functionMap: null | undefined | FBSourceFunctionMap;
readonly path: string;
readonly source: string;
readonly code: string;
readonly isIgnored: boolean;
readonly lineCount?: number;
}>,
modules: ReadonlyArray<RawMappingsModule>,
offsetLines?: number,
): Promise<Generator>;
/**
* Like `fromRawMappings`, but produces an indexed (sectioned) source map with
* one section per module. VLQ-stored modules pass through verbatim — no
* decode/re-encode — which is the whole point: it's much cheaper to serialize
* than the flat path, at the cost of emitting an indexed map that consumers must
* understand. Per-module work is trivial, so this runs synchronously.
*/
declare function fromRawMappingsIndexed(
modules: ReadonlyArray<RawMappingsModule>,
offsetLines?: number,
): IndexedSourceMapResult;
/**
* Transforms a standard source map object into a Raw Mappings object, to be

@@ -132,2 +167,43 @@ * used across the bundler.

): MetroSourceMapSegmentTuple;
/**
* Converts a Babel/gen-mapping "decoded" source map (`result.decodedMap` from
* `@babel/generator`) into raw mapping tuples, byte-identical to
* `result.rawMappings.map(toSegmentTuple)`.
*
* Preferred over `result.rawMappings` because `decodedMap` is computed eagerly
* during generation, whereas accessing `rawMappings` triggers a second decode
* (`allMappings`) that allocates ~4-5 objects per segment. No terminating
* mapping is appended (callers that need one use `countLinesAndTerminateMap`).
*/
declare function tuplesFromBabelDecodedMap(
decodedMap: BabelDecodedMap,
): Array<MetroSourceMapSegmentTuple>;
/**
* Encodes raw mapping tuples into a compact VLQ `mappings` string + `names`
* table. Decode the inverse via `decodeVlqMap` (or `toBabelSegments` +
* `toSegmentTuple`). Storing maps in this form uses far less memory than the
* equivalent decoded tuple arrays.
*/
declare function vlqMapFromTuples(
mappings: ReadonlyArray<MetroSourceMapSegmentTuple>,
): VlqMap;
/**
* Encodes a `VlqMap` directly from a Babel/gen-mapping "decoded" source map
* (`result.decodedMap` from `@babel/generator`), without ever materialising the
* intermediate `Array<MetroSourceMapSegmentTuple>`.
*
* `@babel/generator` computes `decodedMap` eagerly while generating, so reusing
* it avoids the separate, more expensive `result.rawMappings` decode (which
* allocates a flat array of segment objects) plus the per-segment tuple
* allocation that `vlqMapFromTuples` would otherwise consume. The result is
* byte-identical to `vlqMapFromTuples(decoded -> tuples)`.
*
* `terminatingMapping` is a `[generatedLine1Based, generatedColumn0Based]`
* generated-only mapping appended at the end (matching the transform worker's
* `countLinesAndTerminateMap`) unless the last real mapping already sits there.
*/
declare function vlqMapFromBabelDecodedMap(
decodedMap: BabelDecodedMap,
terminatingMapping: [number, number],
): VlqMap;
export {

@@ -140,29 +216,12 @@ BundleBuilder,

fromRawMappings,
fromRawMappingsIndexed,
fromRawMappingsNonBlocking,
functionMapBabelPlugin,
isVlqMap,
normalizeSourcePath,
toBabelSegments,
toSegmentTuple,
tuplesFromBabelDecodedMap,
vlqMapFromBabelDecodedMap,
vlqMapFromTuples,
};
/**
* Backwards-compatibility with CommonJS consumers using interopRequireDefault.
* Do not add to this list.
*
* @deprecated Default import from 'metro-source-map' is deprecated, use named exports.
*/
declare const $$EXPORT_DEFAULT_DECLARATION$$: {
BundleBuilder: typeof BundleBuilder;
composeSourceMaps: typeof composeSourceMaps;
Consumer: typeof Consumer;
createIndexMap: typeof createIndexMap;
generateFunctionMap: typeof generateFunctionMap;
fromRawMappings: typeof fromRawMappings;
fromRawMappingsNonBlocking: typeof fromRawMappingsNonBlocking;
functionMapBabelPlugin: typeof functionMapBabelPlugin;
normalizeSourcePath: typeof normalizeSourcePath;
toBabelSegments: typeof toBabelSegments;
toSegmentTuple: typeof toSegmentTuple;
};
declare type $$EXPORT_DEFAULT_DECLARATION$$ =
typeof $$EXPORT_DEFAULT_DECLARATION$$;
export default $$EXPORT_DEFAULT_DECLARATION$$;

@@ -30,4 +30,4 @@ "use strict";

});
exports.default = void 0;
exports.fromRawMappings = fromRawMappings;
exports.fromRawMappingsIndexed = fromRawMappingsIndexed;
exports.fromRawMappingsNonBlocking = fromRawMappingsNonBlocking;

@@ -46,2 +46,3 @@ Object.defineProperty(exports, "functionMapBabelPlugin", {

});
exports.isVlqMap = isVlqMap;
Object.defineProperty(exports, "normalizeSourcePath", {

@@ -55,2 +56,5 @@ enumerable: true,

exports.toSegmentTuple = toSegmentTuple;
exports.tuplesFromBabelDecodedMap = tuplesFromBabelDecodedMap;
exports.vlqMapFromBabelDecodedMap = vlqMapFromBabelDecodedMap;
exports.vlqMapFromTuples = vlqMapFromTuples;
var _BundleBuilder = require("./BundleBuilder");

@@ -64,2 +68,3 @@ var _composeSourceMaps = _interopRequireDefault(require("./composeSourceMaps"));

var _Generator = _interopRequireDefault(require("./Generator"));
var _nullthrows = _interopRequireDefault(require("nullthrows"));
var _sourceMap = _interopRequireDefault(require("source-map"));

@@ -69,2 +74,27 @@ function _interopRequireDefault(e) {

}
class IndexedSourceMapResult {
#sections;
constructor(sections) {
this.#sections = sections;
}
toMap(file, options) {
const sections =
options?.excludeSource === true
? this.#sections.map((section) => {
const { sourcesContent: _, ...map } = section.map;
return {
...section,
map,
};
})
: this.#sections;
return (0, _BundleBuilder.createIndexMap)(file, sections);
}
toString(file, options) {
return JSON.stringify(this.toMap(file, options));
}
}
function isVlqMap(map) {
return map != null && !Array.isArray(map) && typeof map.mappings === "string";
}
function fromRawMappingsImpl(isBlocking, onDone, modules, offsetLines) {

@@ -78,5 +108,7 @@ const modulesToProcess = modules.slice();

}
const mod = modulesToProcess.shift();
const mod = (0, _nullthrows.default)(modulesToProcess.shift());
const { code, map } = mod;
if (Array.isArray(map)) {
if (isVlqMap(map)) {
addMappingsForFile(generator, decodeVlqMap(map), mod, carryOver);
} else if (Array.isArray(map)) {
addMappingsForFile(generator, map, mod, carryOver);

@@ -131,2 +163,50 @@ } else if (map != null) {

}
function fromRawMappingsIndexed(modules, offsetLines = 0) {
const sections = [];
let carryOver = offsetLines;
for (const mod of modules) {
if (mod.map != null) {
sections.push({
offset: {
line: carryOver,
column: 0,
},
map: toIndexMapSection(mod),
});
}
carryOver = carryOver + countLines(mod.code);
}
return new IndexedSourceMapResult(sections);
}
function toIndexMapSection(module) {
const { map, path, source, functionMap, isIgnored } = module;
if (isVlqMap(map)) {
let sectionMap = {
version: 3,
sources: [path],
sourcesContent: [source],
names: [...map.names],
mappings: map.mappings,
};
if (functionMap != null) {
sectionMap = {
...sectionMap,
x_facebook_sources: [[functionMap]],
};
}
if (isIgnored) {
sectionMap = {
...sectionMap,
x_google_ignoreList: [0],
};
}
return sectionMap;
}
if (Array.isArray(map)) {
const generator = new _Generator.default();
addMappingsForFile(generator, map, module, 0);
return generator.toMap();
}
throw new Error(`Unexpected module with full source map found: ${path}`);
}
function toBabelSegments(sourceMap) {

@@ -172,2 +252,31 @@ const rawMappings = [];

}
function tuplesFromBabelDecodedMap(decodedMap) {
const { mappings, names } = decodedMap;
const tuples = [];
for (let line = 0, n = mappings.length; line < n; ++line) {
const generatedLine = line + 1;
const segments = mappings[line];
for (let i = 0, m = segments.length; i < m; ++i) {
const segment = segments[i];
switch (segment.length) {
case 1:
tuples.push([generatedLine, segment[0]]);
break;
case 4:
tuples.push([generatedLine, segment[0], segment[2] + 1, segment[3]]);
break;
case 5:
tuples.push([
generatedLine,
segment[0],
segment[2] + 1,
segment[3],
names[segment[4]],
]);
break;
}
}
}
return tuples;
}
function addMappingsForFile(generator, mappings, module, carryOver) {

@@ -206,14 +315,75 @@ generator.startFile(module.path, module.source, module.functionMap, {

const countLines = (string) => (string.match(newline) || []).length + 1;
var _default = (exports.default = {
BundleBuilder: _BundleBuilder.BundleBuilder,
composeSourceMaps: _composeSourceMaps.default,
Consumer: _Consumer.default,
createIndexMap: _BundleBuilder.createIndexMap,
generateFunctionMap: _generateFunctionMap.generateFunctionMap,
fromRawMappings,
fromRawMappingsNonBlocking,
functionMapBabelPlugin: _generateFunctionMap.functionMapBabelPlugin,
normalizeSourcePath: _normalizeSourcePath.default,
toBabelSegments,
toSegmentTuple,
});
function decodeVlqMap(vlqMap) {
return toBabelSegments({
version: 3,
sources: [""],
names: [...vlqMap.names],
mappings: vlqMap.mappings,
}).map(toSegmentTuple);
}
function vlqMapFromTuples(mappings) {
const generator = new _Generator.default();
generator.startFile("", "", null);
for (const mapping of mappings) {
addMapping(generator, mapping, 0);
}
generator.endFile();
const map = generator.toMap();
return {
mappings: map.mappings,
names: map.names,
};
}
function vlqMapFromBabelDecodedMap(decodedMap, terminatingMapping) {
const generator = new _Generator.default();
generator.startFile("", "", null);
const { mappings, names } = decodedMap;
let lastGeneratedLine = -1;
let lastGeneratedColumn = -1;
for (let line = 0, n = mappings.length; line < n; ++line) {
const generatedLine = line + 1;
const segments = mappings[line];
for (let i = 0, m = segments.length; i < m; ++i) {
const segment = segments[i];
const generatedColumn = segment[0];
switch (segment.length) {
case 1:
generator.addSimpleMapping(generatedLine, generatedColumn);
break;
case 4:
generator.addSourceMapping(
generatedLine,
generatedColumn,
segment[2] + 1,
segment[3],
);
break;
case 5:
generator.addNamedSourceMapping(
generatedLine,
generatedColumn,
segment[2] + 1,
segment[3],
names[segment[4]],
);
break;
default:
throw new Error(`Invalid mapping: [${segment.join(", ")}]`);
}
lastGeneratedLine = generatedLine;
lastGeneratedColumn = generatedColumn;
}
}
if (
lastGeneratedLine !== terminatingMapping[0] ||
lastGeneratedColumn !== terminatingMapping[1]
) {
generator.addSimpleMapping(terminatingMapping[0], terminatingMapping[1]);
}
generator.endFile();
const map = generator.toMap();
return {
mappings: map.mappings,
names: map.names,
};
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet