Skip to content

Commit

Permalink
Cache instances of SourceMapConsumer
Browse files Browse the repository at this point in the history
Creating these was apparently a little expensive.

This fixes #1256 [1].

[1] #1256
  • Loading branch information
badeball committed Nov 14, 2024
1 parent 598f968 commit 1a87ddd
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 18 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ All notable changes to this project will be documented in this file.

- Correctly represent consecutive BeforeAll & AfterAll hooks in the command log, relates to [#1250](https://github.com/badeball/cypress-cucumber-preprocessor/issues/1250).

- Cache instances of SourceMapConsumer, fixes [#1256](https://github.com/badeball/cypress-cucumber-preprocessor/issues/1256).

## v21.0.2

- Cache requested source maps, fixes [#1245](https://github.com/badeball/cypress-cucumber-preprocessor/discussions/1245).
Expand Down
48 changes: 30 additions & 18 deletions lib/helpers/source-map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ function sourceMapWarn(message: string) {
isSourceMapWarned = true;
}

const cache = new Map<string, string | undefined>();
const cache = new Map<string, SourceMapConsumer | undefined>();

/**
* Taken from https://github.com/evanw/node-source-map-support/blob/v0.5.21/source-map-support.js#L148-L177.
Expand Down Expand Up @@ -63,11 +63,36 @@ export function retrieveSourceMapURL(source: string) {
return lastMatch[1];
}

export function cachedRetrieveSourceMapURL(source: string): string | undefined {
export function createSourceMapConsumer(
source: string,
): SourceMapConsumer | undefined {
const sourceMappingURL = retrieveSourceMapURL(source);

if (!sourceMappingURL) {
return;
}

const rawSourceMap = JSON.parse(
new TextDecoder().decode(
toByteArray(sourceMappingURL.slice(sourceMappingURL.indexOf(",") + 1)),
),
);

// Why? Because of Vite. Vite fails building the source-map module properly and this errors with "x is not a constructor".
if (typeof SourceMapConsumer !== "function") {
return;
}

return new SourceMapConsumer(rawSourceMap);
}

export function cachedCreateSourceMapConsumer(
source: string,
): SourceMapConsumer | undefined {
if (cache.has(source)) {
return cache.get(source);
} else {
const result = retrieveSourceMapURL(source);
const result = createSourceMapConsumer(source);
cache.set(source, result);
return result;
}
Expand All @@ -80,25 +105,12 @@ export function maybeRetrievePositionFromSourceMap(): Position | undefined {
return;
}

const sourceMappingURL = cachedRetrieveSourceMapURL(stack[0].fileName);
const sourceMap = cachedCreateSourceMapConsumer(stack[0].fileName);

if (!sourceMappingURL) {
if (!sourceMap) {
return;
}

const rawSourceMap = JSON.parse(
new TextDecoder().decode(
toByteArray(sourceMappingURL.slice(sourceMappingURL.indexOf(",") + 1)),
),
);

// Why? Because of Vite. Vite fails building the source-map module properly and this errors with "x is not a constructor".
if (typeof SourceMapConsumer !== "function") {
return;
}

const sourceMap = new SourceMapConsumer(rawSourceMap);

const relevantFrame = stack[3];

const position = sourceMap.originalPositionFor({
Expand Down

0 comments on commit 1a87ddd

Please sign in to comment.