Skip to content

Commit 94e5587

Browse files
committed
Merge remote-tracking branch 'origin/master' into ej/sourceMapSupportRedirect
2 parents 44c3bce + c98a759 commit 94e5587

9 files changed

+166
-60
lines changed

CONTRIBUTING.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
## Release process
2+
3+
* Publish with [`np`](https://npm.im/np)
4+
* Update the changelog in [#24](https://github.com/cspotcode/node-source-map-support/issues/24)

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ From here you have two options.
3030

3131
```bash
3232
node -r @cspotcode/source-map-support/register compiled.js
33+
# Or to enable hookRequire
34+
node -r @cspotcode/source-map-support/register-hook-require compiled.js
3335
```
3436

3537
##### Programmatic Usage

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@cspotcode/source-map-support",
33
"description": "Fixes stack traces for files with source maps",
4-
"version": "0.6.0",
4+
"version": "0.6.1",
55
"main": "./source-map-support.js",
66
"types": "./source-map-support.d.ts",
77
"scripts": {
@@ -12,6 +12,8 @@
1212
"files": [
1313
"/register.d.ts",
1414
"/register.js",
15+
"/register-hook-require.d.ts",
16+
"/register-hook-require.js",
1517
"/source-map-support.d.ts",
1618
"/source-map-support.js"
1719
],
@@ -28,10 +30,10 @@
2830
},
2931
"repository": {
3032
"type": "git",
31-
"url": "https://github.com/evanw/node-source-map-support"
33+
"url": "https://github.com/cspotcode/node-source-map-support"
3234
},
3335
"bugs": {
34-
"url": "https://github.com/evanw/node-source-map-support/issues"
36+
"url": "https://github.com/cspotcode/node-source-map-support/issues"
3537
},
3638
"license": "MIT",
3739
"engines": {

register-hook-require.d.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// tslint:disable:no-useless-files
2+
3+
// For following usage:
4+
// import '@cspotcode/source-map-support/register-hook-require'
5+
// Instead of:
6+
// import sourceMapSupport from '@cspotcode/source-map-support'
7+
// sourceMapSupport.install({hookRequire: true})

register-hook-require.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
require('./').install({
2+
hookRequire: true
3+
});

register.d.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// tslint:disable:no-useless-files
22

33
// For following usage:
4-
// import 'source-map-support/register'
4+
// import '@cspotcode/source-map-support/register'
55
// Instead of:
6-
// import sourceMapSupport from 'source-map-support'
6+
// import sourceMapSupport from '@cspotcode/source-map-support'
77
// sourceMapSupport.install()

source-map-support.js

Lines changed: 99 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -23,29 +23,75 @@ function dynamicRequire(mod, request) {
2323
return mod.require(request);
2424
}
2525

26-
// Only install once if called multiple times
27-
var errorFormatterInstalled = false;
28-
var uncaughtShimInstalled = false;
26+
// Increment this if the format of sharedData changes in a breaking way.
27+
var sharedDataVersion = 1;
28+
29+
function initializeSharedData(defaults) {
30+
var sharedDataKey = 'source-map-support/sharedData';
31+
if (typeof Symbol !== 'undefined') {
32+
sharedDataKey = Symbol.for(sharedDataKey);
33+
}
34+
var sharedData = this[sharedDataKey];
35+
if (!sharedData) {
36+
sharedData = { version: sharedDataVersion };
37+
if (Object.defineProperty) {
38+
Object.defineProperty(this, sharedDataKey, { value: sharedData });
39+
} else {
40+
this[sharedDataKey] = sharedData;
41+
}
42+
}
43+
if (sharedDataVersion !== sharedData.version) {
44+
throw new Error("Multiple incompatible instances of source-map-support were loaded");
45+
}
46+
for (var key in defaults) {
47+
if (!(key in sharedData)) {
48+
sharedData[key] = defaults[key];
49+
}
50+
}
51+
return sharedData;
52+
}
2953

30-
// If true, the caches are reset before a stack trace formatting operation
31-
var emptyCacheBetweenOperations = false;
54+
// If multiple instances of source-map-support are loaded into the same
55+
// context, they shouldn't overwrite each other. By storing handlers, caches,
56+
// and other state on a shared object, different instances of
57+
// source-map-support can work together in a limited way. This does require
58+
// that future versions of source-map-support continue to support the fields on
59+
// this object. If this internal contract ever needs to be broken, increment
60+
// sharedDataVersion. (This version number is not the same as any of the
61+
// package's version numbers, which should reflect the *external* API of
62+
// source-map-support.)
63+
var sharedData = initializeSharedData({
3264

33-
// Supports {browser, node, auto}
34-
var environment = "auto";
65+
// Only install once if called multiple times
66+
errorFormatterInstalled: false,
67+
uncaughtShimInstalled: false,
68+
69+
// If true, the caches are reset before a stack trace formatting operation
70+
emptyCacheBetweenOperations: false,
71+
72+
// Maps a file path to a string containing the file contents
73+
fileContentsCache: {},
74+
75+
// Maps a file path to a source map for that file
76+
sourceMapCache: {},
3577

36-
// Maps a file path to a string containing the file contents
37-
var fileContentsCache = {};
78+
// Priority list of retrieve handlers
79+
retrieveFileHandlers: [],
80+
retrieveMapHandlers: [],
3881

39-
// Maps a file path to a source map for that file
40-
var sourceMapCache = {};
82+
// Priority list of internally-implemented handlers.
83+
// When resetting state, we must keep these.
84+
internalRetrieveFileHandlers: [],
85+
internalRetrieveMapHandlers: [],
86+
87+
});
88+
89+
// Supports {browser, node, auto}
90+
var environment = "auto";
4191

4292
// Regex for detecting source maps
4393
var reSourceMap = /^data:application\/json[^,]+base64,/;
4494

45-
// Priority list of retrieve handlers
46-
var retrieveFileHandlers = [];
47-
var retrieveMapHandlers = [];
48-
4995
function isInBrowser() {
5096
if (environment === "browser")
5197
return true;
@@ -58,21 +104,27 @@ function hasGlobalProcessEventEmitter() {
58104
return ((typeof process === 'object') && (process !== null) && (typeof process.on === 'function'));
59105
}
60106

61-
function handlerExec(list) {
107+
function handlerExec(list, internalList) {
62108
return function(arg) {
63109
for (var i = 0; i < list.length; i++) {
64110
var ret = list[i](arg);
65111
if (ret) {
66112
return ret;
67113
}
68114
}
115+
for (var i = 0; i < internalList.length; i++) {
116+
var ret = internalList[i](arg);
117+
if (ret) {
118+
return ret;
119+
}
120+
}
69121
return null;
70122
};
71123
}
72124

73-
var retrieveFile = handlerExec(retrieveFileHandlers);
125+
var retrieveFile = handlerExec(sharedData.retrieveFileHandlers, sharedData.internalRetrieveFileHandlers);
74126

75-
retrieveFileHandlers.push(function(path) {
127+
sharedData.internalRetrieveFileHandlers.push(function(path) {
76128
// Trim the path to make sure there is no extra whitespace.
77129
path = path.trim();
78130
if (/^file:/.test(path)) {
@@ -83,8 +135,8 @@ retrieveFileHandlers.push(function(path) {
83135
'/'; // file:///root-dir/file -> /root-dir/file
84136
});
85137
}
86-
if (path in fileContentsCache) {
87-
return fileContentsCache[path];
138+
if (path in sharedData.fileContentsCache) {
139+
return sharedData.fileContentsCache[path];
88140
}
89141

90142
var contents = '';
@@ -105,7 +157,7 @@ retrieveFileHandlers.push(function(path) {
105157
/* ignore any errors */
106158
}
107159

108-
return fileContentsCache[path] = contents;
160+
return sharedData.fileContentsCache[path] = contents;
109161
});
110162

111163
// Support URLs relative to a directory, but be careful about a protocol prefix
@@ -160,8 +212,8 @@ function retrieveSourceMapURL(source) {
160212
// there is no source map. The map field may be either a string or the parsed
161213
// JSON object (ie, it must be a valid argument to the SourceMapConsumer
162214
// constructor).
163-
var retrieveSourceMap = handlerExec(retrieveMapHandlers);
164-
retrieveMapHandlers.push(function(source) {
215+
var retrieveSourceMap = handlerExec(sharedData.retrieveMapHandlers, sharedData.internalRetrieveMapHandlers);
216+
sharedData.internalRetrieveMapHandlers.push(function(source) {
165217
var sourceMappingURL = retrieveSourceMapURL(source);
166218
if (!sourceMappingURL) return null;
167219

@@ -189,12 +241,12 @@ retrieveMapHandlers.push(function(source) {
189241
});
190242

191243
function mapSourcePosition(position) {
192-
var sourceMap = sourceMapCache[position.source];
244+
var sourceMap = sharedData.sourceMapCache[position.source];
193245
if (!sourceMap) {
194246
// Call the (overrideable) retrieveSourceMap function to get the source map.
195247
var urlAndMap = retrieveSourceMap(position.source);
196248
if (urlAndMap) {
197-
sourceMap = sourceMapCache[position.source] = {
249+
sourceMap = sharedData.sourceMapCache[position.source] = {
198250
url: urlAndMap.url,
199251
map: new SourceMapConsumer(urlAndMap.map)
200252
};
@@ -206,12 +258,12 @@ function mapSourcePosition(position) {
206258
var contents = sourceMap.map.sourcesContent[i];
207259
if (contents) {
208260
var url = supportRelativeURL(sourceMap.url, source);
209-
fileContentsCache[url] = contents;
261+
sharedData.fileContentsCache[url] = contents;
210262
}
211263
});
212264
}
213265
} else {
214-
sourceMap = sourceMapCache[position.source] = {
266+
sourceMap = sharedData.sourceMapCache[position.source] = {
215267
url: null,
216268
map: null
217269
};
@@ -434,9 +486,9 @@ const ErrorPrototypeToString = (err) =>Error.prototype.toString.call(err);
434486
// This function is part of the V8 stack trace API, for more info see:
435487
// https://v8.dev/docs/stack-trace-api
436488
function prepareStackTrace(error, stack) {
437-
if (emptyCacheBetweenOperations) {
438-
fileContentsCache = {};
439-
sourceMapCache = {};
489+
if (sharedData.emptyCacheBetweenOperations) {
490+
sharedData.fileContentsCache = {};
491+
sharedData.sourceMapCache = {};
440492
}
441493

442494
// node gives its own errors special treatment. Mimic that behavior
@@ -474,7 +526,7 @@ function getErrorSource(error) {
474526
var column = +match[3];
475527

476528
// Support the inline sourceContents inside the source map
477-
var contents = fileContentsCache[source];
529+
var contents = sharedData.fileContentsCache[source];
478530

479531
// Support files on disk
480532
if (!contents && fs && fs.existsSync(source)) {
@@ -537,8 +589,8 @@ function shimEmitUncaughtException () {
537589
};
538590
}
539591

540-
var originalRetrieveFileHandlers = retrieveFileHandlers.slice(0);
541-
var originalRetrieveMapHandlers = retrieveMapHandlers.slice(0);
592+
var originalRetrieveFileHandlers = sharedData.retrieveFileHandlers.slice(0);
593+
var originalRetrieveMapHandlers = sharedData.retrieveMapHandlers.slice(0);
542594

543595
exports.wrapCallSite = wrapCallSite;
544596
exports.getErrorSource = getErrorSource;
@@ -582,20 +634,20 @@ exports.install = function(options) {
582634
// directly from disk.
583635
if (options.retrieveFile) {
584636
if (options.overrideRetrieveFile) {
585-
retrieveFileHandlers.length = 0;
637+
sharedData.retrieveFileHandlers.length = 0;
586638
}
587639

588-
retrieveFileHandlers.unshift(options.retrieveFile);
640+
sharedData.retrieveFileHandlers.unshift(options.retrieveFile);
589641
}
590642

591643
// Allow source maps to be found by methods other than reading the files
592644
// directly from disk.
593645
if (options.retrieveSourceMap) {
594646
if (options.overrideRetrieveSourceMap) {
595-
retrieveMapHandlers.length = 0;
647+
sharedData.retrieveMapHandlers.length = 0;
596648
}
597649

598-
retrieveMapHandlers.unshift(options.retrieveSourceMap);
650+
sharedData.retrieveMapHandlers.unshift(options.retrieveSourceMap);
599651
}
600652

601653
// Support runtime transpilers that include inline source maps
@@ -604,8 +656,8 @@ exports.install = function(options) {
604656

605657
if (!$compile.__sourceMapSupport) {
606658
Module.prototype._compile = function(content, filename) {
607-
fileContentsCache[filename] = content;
608-
sourceMapCache[filename] = undefined;
659+
sharedData.fileContentsCache[filename] = content;
660+
sharedData.sourceMapCache[filename] = undefined;
609661
return $compile.call(this, content, filename);
610662
};
611663

@@ -614,18 +666,18 @@ exports.install = function(options) {
614666
}
615667

616668
// Configure options
617-
if (!emptyCacheBetweenOperations) {
618-
emptyCacheBetweenOperations = 'emptyCacheBetweenOperations' in options ?
669+
if (!sharedData.emptyCacheBetweenOperations) {
670+
sharedData.emptyCacheBetweenOperations = 'emptyCacheBetweenOperations' in options ?
619671
options.emptyCacheBetweenOperations : false;
620672
}
621673

622674
// Install the error reformatter
623-
if (!errorFormatterInstalled) {
624-
errorFormatterInstalled = true;
675+
if (!sharedData.errorFormatterInstalled) {
676+
sharedData.errorFormatterInstalled = true;
625677
Error.prepareStackTrace = prepareStackTrace;
626678
}
627679

628-
if (!uncaughtShimInstalled) {
680+
if (!sharedData.uncaughtShimInstalled) {
629681
var installHandler = 'handleUncaughtExceptions' in options ?
630682
options.handleUncaughtExceptions : true;
631683

@@ -648,19 +700,13 @@ exports.install = function(options) {
648700
// generated JavaScript code will be shown above the stack trace instead of
649701
// the original source code.
650702
if (installHandler && hasGlobalProcessEventEmitter()) {
651-
uncaughtShimInstalled = true;
703+
sharedData.uncaughtShimInstalled = true;
652704
shimEmitUncaughtException();
653705
}
654706
}
655707
};
656708

657709
exports.resetRetrieveHandlers = function() {
658-
retrieveFileHandlers.length = 0;
659-
retrieveMapHandlers.length = 0;
660-
661-
retrieveFileHandlers = originalRetrieveFileHandlers.slice(0);
662-
retrieveMapHandlers = originalRetrieveMapHandlers.slice(0);
663-
664-
retrieveSourceMap = handlerExec(retrieveMapHandlers);
665-
retrieveFile = handlerExec(retrieveFileHandlers);
710+
sharedData.retrieveFileHandlers.length = 0;
711+
sharedData.retrieveMapHandlers.length = 0;
666712
}

0 commit comments

Comments
 (0)