New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
chore: destroy source maps consumers when spec finishes #23708
Changes from all commits
f4535ec
463313a
72a96f0
ea0a28f
fd894f4
930a9b7
2d75601
efe3343
153419f
1da18f1
b6fdc92
5068cf6
c791a14
64786d0
7828ea3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
import _ from 'lodash' | ||
import { SourceMapConsumer } from 'source-map' | ||
|
||
import type { BasicSourceMapConsumer } from 'source-map' | ||
// @ts-ignore | ||
import mappingsWasm from 'source-map/lib/mappings.wasm' | ||
|
||
|
@@ -9,9 +10,9 @@ import $utils from './utils' | |
const sourceMapExtractionRegex = /\/\/\s*[@#]\s*sourceMappingURL\s*=\s*(data:[^\s]*)/g | ||
const regexDataUrl = /data:[^;\n]+(?:;charset=[^;\n]+)?;base64,([a-zA-Z0-9+/]+={0,2})/ // matches data urls | ||
|
||
let sourceMapConsumers = {} | ||
let sourceMapConsumers: Record<string, BasicSourceMapConsumer> = {} | ||
|
||
const initializeSourceMapConsumer = async (file, sourceMap) => { | ||
const initializeSourceMapConsumer = async (script, sourceMap): Promise<BasicSourceMapConsumer | null> => { | ||
if (!sourceMap) return null | ||
|
||
// @ts-ignore | ||
|
@@ -21,18 +22,29 @@ const initializeSourceMapConsumer = async (file, sourceMap) => { | |
|
||
const consumer = await new SourceMapConsumer(sourceMap) | ||
|
||
sourceMapConsumers[file.fullyQualifiedUrl] = consumer | ||
sourceMapConsumers[script.fullyQualifiedUrl] = consumer | ||
|
||
return consumer | ||
} | ||
|
||
const extractSourceMap = (file, fileContents) => { | ||
let sourceMapMatch = fileContents.match(sourceMapExtractionRegex) | ||
const extractSourceMap = (fileContents) => { | ||
let dataUrlMatch | ||
|
||
if (!sourceMapMatch) return null | ||
try { | ||
let sourceMapMatch = fileContents.match(sourceMapExtractionRegex) | ||
|
||
if (!sourceMapMatch) return null | ||
|
||
const url = _.last(sourceMapMatch) as any | ||
|
||
const url = _.last(sourceMapMatch) as any | ||
const dataUrlMatch = url.match(regexDataUrl) | ||
dataUrlMatch = url.match(regexDataUrl) | ||
} catch (err) { | ||
// ignore unable to match regex. there's nothing we | ||
// can do about it and we don't want to thrown an exception | ||
if (err.message === 'Maximum call stack size exceeded') return null | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Might be worth checking if this error is the same in FF and WebKit There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was going to suggest checking the error type instead, but it looks like the error type is inconsistent (InternalError in Firefox; RangeError in Chrome and Safari.), but the error message is the same across browsers. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Too_much_recursion |
||
|
||
throw err | ||
} | ||
|
||
if (!dataUrlMatch) return null | ||
|
||
|
@@ -61,15 +73,16 @@ const getSourcePosition = (filePath, position) => { | |
|
||
if (!sourceMapConsumer) return null | ||
|
||
const sourcePosition = sourceMapConsumer.originalPositionFor(position) | ||
const { source, line, column } = sourcePosition | ||
const { source, line, column } = sourceMapConsumer.originalPositionFor(position) | ||
|
||
if (!source || line == null || column == null) return | ||
|
||
// if the file is outside of the projectRoot | ||
// originalPositionFor will not provide the correct relative path | ||
// https://github.com/cypress-io/cypress/issues/16255 | ||
// @ts-expect-error | ||
const sourceIndex = sourceMapConsumer._absoluteSources.indexOf(source) | ||
// @ts-expect-error | ||
const file = sourceMapConsumer._sources.at(sourceIndex) | ||
|
||
return { | ||
|
@@ -89,9 +102,16 @@ const base64toJs = (base64) => { | |
} | ||
} | ||
|
||
const destroySourceMapConsumers = () => { | ||
Object.values(sourceMapConsumers).forEach((consumer) => { | ||
consumer.destroy() | ||
}) | ||
} | ||
|
||
export default { | ||
getSourcePosition, | ||
getSourceContents, | ||
extractSourceMap, | ||
initializeSourceMapConsumer, | ||
destroySourceMapConsumers, | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could use
Map
, I think it makes the intention a bit more clear.