Skip to content

Commit 07ed34e

Browse files
committed
add polyfill originals
1 parent 6496a11 commit 07ed34e

15 files changed

+267
-0
lines changed

rollup/jsPolyfills/README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
## Javascript Polyfills
2+
3+
This is a collection of syntax polyfills either copied directly from or heavily inspired by those used by [Rollup](https://github.com/rollup/rollup) and [Sucrase](https://github.com/alangpierce/sucrase). When either tool uses one of these polyfills during a build, it injects the function source code into each file needing the function, which can lead to a great deal of duplication. For our builds, we have therefore implemented something similar to [`tsc`'s `importHelpers` behavior](https://www.typescriptlang.org/tsconfig#importHelpers): Instead of leaving the polyfills injected in multiple places, we instead replace each injected function with an `import` or `require` statement. This directory is the location from which we import. For simplicity (and greater treeshaking ability when using tools which only work on a file-by-file level), each polyfill lives in its own file.
4+
5+
During build, this directory is copied over to the root level of `@sentry/utils`, and the polyfills are compiled into esm and cjs versions. When the injected implementations are replaced by either `import` or `require` by our rollup plugin, each `import`/`require` pulls from the correct module format's folder. (In other words, the injected `import` statements import from `@sentry/utils/jsPolyfills/esm` and the injected `require` statements pull from `@sentry/utils/jsPolyfills/cjs`.)
6+
7+
Note that not all polyfills are currently used by the SDK, but all are included here for future compatitibility, should they ever be needed.
8+
9+
--------
10+
11+
_Code from both Rollup and Sucrase is used under the MIT license, copyright 2017 and 2012-2018, respectively._
12+
13+
_Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:_
14+
15+
_The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software._
16+
17+
_THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE._
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// adapted from Sucrase (https://github.com/alangpierce/sucrase)
2+
3+
export async function _asyncNullishCoalesce(lhs, rhsFn) {
4+
// by checking for loose equality to `null`, we catch both `null` and `undefined`
5+
return lhs != null ? lhs : rhsFn();
6+
}
7+
8+
// Sucrase version:
9+
// async function _asyncNullishCoalesce(lhs, rhsFn) {
10+
// if (lhs != null) {
11+
// return lhs;
12+
// } else {
13+
// return await rhsFn();
14+
// }
15+
// }
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// adapted from Sucrase (https://github.com/alangpierce/sucrase)
2+
3+
export async function _asyncOptionalChain(ops) {
4+
let lastAccessLHS = undefined;
5+
let value = ops[0];
6+
let i = 1;
7+
while (i < ops.length) {
8+
const op = ops[i];
9+
const fn = ops[i + 1];
10+
i += 2;
11+
// by checking for loose equality to `null`, we catch both `null` and `undefined`
12+
if (op in ['optionalAccess', 'optionalCall'] && value == null) {
13+
// really we're meaning to return `undefined` as an actual value here, but it saves bytes not to write it
14+
return;
15+
}
16+
if (op in ['access', 'optionalAccess']) {
17+
lastAccessLHS = value;
18+
value = await fn(value);
19+
} else if (op in ['call', 'optionalCall']) {
20+
value = await fn((...args) => value.call(lastAccessLHS, ...args));
21+
lastAccessLHS = undefined;
22+
}
23+
}
24+
return value;
25+
}
26+
27+
// Sucrase version:
28+
// async function _asyncOptionalChain(ops) {
29+
// let lastAccessLHS = undefined;
30+
// let value = ops[0];
31+
// let i = 1;
32+
// while (i < ops.length) {
33+
// const op = ops[i];
34+
// const fn = ops[i + 1];
35+
// i += 2;
36+
// if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) {
37+
// return undefined;
38+
// }
39+
// if (op === 'access' || op === 'optionalAccess') {
40+
// lastAccessLHS = value;
41+
// value = await fn(value);
42+
// } else if (op === 'call' || op === 'optionalCall') {
43+
// value = await fn((...args) => value.call(lastAccessLHS, ...args));
44+
// lastAccessLHS = undefined;
45+
// }
46+
// }
47+
// return value;
48+
// }
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// originally from Sucrase (https://github.com/alangpierce/sucrase)
2+
3+
import { _asyncOptionalChain } from './_asyncOptionalChain';
4+
5+
export async function _asyncOptionalChainDelete(ops) {
6+
const result = await _asyncOptionalChain(ops);
7+
// by checking for loose equality to `null`, we catch both `null` and `undefined`
8+
return result == null ? true : result;
9+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// adapted from Sucrase (https://github.com/alangpierce/sucrase)
2+
3+
export function _createNamedExportFrom(obj, localName, importedName) {
4+
exports[localName] = obj[importedName];
5+
}
6+
7+
// Sucrase version:
8+
// function _createNamedExportFrom(obj, localName, importedName) {
9+
// Object.defineProperty(exports, localName, {enumerable: true, get: () => obj[importedName]});
10+
// }
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// adapted from Sucrase (https://github.com/alangpierce/sucrase)
2+
3+
export function _createStarExport(obj) {
4+
Object.keys(obj)
5+
.filter(key => key !== 'default' && key !== '__esModule' && !(key in exports))
6+
.forEach(key => (exports[key] = obj[key]));
7+
}
8+
9+
// Sucrase version:
10+
// function _createStarExport(obj) {
11+
// Object.keys(obj)
12+
// .filter(key => key !== 'default' && key !== '__esModule')
13+
// .forEach(key => {
14+
// if (exports.hasOwnProperty(key)) {
15+
// return;
16+
// }
17+
// Object.defineProperty(exports, key, { enumerable: true, get: () => obj[key] });
18+
// });
19+
// }

rollup/jsPolyfills/_interopDefault.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// adapted from Rollup (https://github.com/rollup/rollup)
2+
3+
export function _interopDefault(importTarget) {
4+
return importTarget.__esModule ? importTarget.default : importTarget;
5+
}
6+
7+
// Rollup version:
8+
// function _interopDefault(e) {
9+
// return e && e.__esModule ? e['default'] : e;
10+
// }
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// adapted from Rollup (https://github.com/rollup/rollup)
2+
3+
export function _interopNamespace(importTarget) {
4+
return importTarget.__esModule ? importTarget : { ...importTarget, default: importTarget };
5+
}
6+
7+
// Rollup version (with `output.externalLiveBindings` and `output.freeze` both set to false)
8+
// function _interopNamespace(e) {
9+
// if (e && e.__esModule) return e;
10+
// var n = Object.create(null);
11+
// if (e) {
12+
// for (var k in e) {
13+
// n[k] = e[k];
14+
// }
15+
// }
16+
// n["default"] = e;
17+
// return n;
18+
// }
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// adapted from Sucrase (https://github.com/alangpierce/sucrase)
2+
3+
export function _interopRequireDefault(importTarget) {
4+
return importTarget.__esModule ? importTarget : { default: importTarget };
5+
}
6+
7+
// Sucrase version
8+
// function _interopRequireDefault(obj) {
9+
// return obj && obj.__esModule ? obj : { default: obj };
10+
// }
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// adapted from Sucrase (https://github.com/alangpierce/sucrase)
2+
3+
export function _interopRequireWildcard(importTarget) {
4+
return importTarget.__esModule ? importTarget : { ...importTarget, default: importTarget };
5+
}
6+
7+
// Sucrase version
8+
// function _interopRequireWildcard(obj) {
9+
// if (obj && obj.__esModule) {
10+
// return obj;
11+
// } else {
12+
// var newObj = {};
13+
// if (obj != null) {
14+
// for (var key in obj) {
15+
// if (Object.prototype.hasOwnProperty.call(obj, key)) {
16+
// newObj[key] = obj[key];
17+
// }
18+
// }
19+
// }
20+
// newObj.default = obj;
21+
// return newObj;
22+
// }
23+
// }
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// adapted from Sucrase (https://github.com/alangpierce/sucrase)
2+
3+
export function _nullishCoalesce(lhs, rhsFn) {
4+
// by checking for loose equality to `null`, we catch both `null` and `undefined`
5+
return lhs != null ? lhs : rhsFn();
6+
}
7+
8+
// Sucrase version
9+
// function _nullishCoalesce(lhs, rhsFn) {
10+
// if (lhs != null) {
11+
// return lhs;
12+
// } else {
13+
// return rhsFn();
14+
// }
15+
// }

rollup/jsPolyfills/_optionalChain.js

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// adapted from Sucrase (https://github.com/alangpierce/sucrase)
2+
3+
export function _optionalChain(ops) {
4+
let lastAccessLHS = undefined;
5+
let value = ops[0];
6+
let i = 1;
7+
while (i < ops.length) {
8+
const op = ops[i];
9+
const fn = ops[i + 1];
10+
i += 2;
11+
// by checking for loose equality to `null`, we catch both `null` and `undefined`
12+
if (op in ['optionalAccess', 'optionalCall'] && value == null) {
13+
// really we're meaning to return `undefined` as an actual value here, but it saves bytes not to write it
14+
return;
15+
}
16+
if (op in ['access', 'optionalAccess']) {
17+
lastAccessLHS = value;
18+
value = fn(value);
19+
} else if (op in ['call', 'optionalCall']) {
20+
value = fn((...args) => value.call(lastAccessLHS, ...args));
21+
lastAccessLHS = undefined;
22+
}
23+
}
24+
return value;
25+
}
26+
27+
// Sucrase version
28+
// function _optionalChain(ops) {
29+
// let lastAccessLHS = undefined;
30+
// let value = ops[0];
31+
// let i = 1;
32+
// while (i < ops.length) {
33+
// const op = ops[i];
34+
// const fn = ops[i + 1];
35+
// i += 2;
36+
// if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) {
37+
// return undefined;
38+
// }
39+
// if (op === 'access' || op === 'optionalAccess') {
40+
// lastAccessLHS = value;
41+
// value = fn(value);
42+
// } else if (op === 'call' || op === 'optionalCall') {
43+
// value = fn((...args) => value.call(lastAccessLHS, ...args));
44+
// lastAccessLHS = undefined;
45+
// }
46+
// }
47+
// return value;
48+
// }
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// originally from Sucrase (https://github.com/alangpierce/sucrase)
2+
3+
import { _optionalChain } from './_optionalChain';
4+
5+
export function _optionalChainDelete(ops) {
6+
const result = _optionalChain(ops);
7+
// by checking for loose equality to `null`, we catch both `null` and `undefined`
8+
return result == null ? true : result;
9+
}

rollup/jsPolyfills/index.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
export { _asyncNullishCoalesce } from './_asyncNullishCoalesce';
2+
export { _asyncOptionalChain } from './_asyncOptionalChain';
3+
export { _asyncOptionalChainDelete } from './_asyncOptionalChainDelete';
4+
export { _createNamedExportFrom } from './_createNamedExportFrom';
5+
export { _createStarExport } from './_createStarExport';
6+
export { _interopDefault } from './_interopDefault';
7+
export { _interopNamespace } from './_interopNamespace';
8+
export { _interopRequireDefault } from './_interopRequireDefault';
9+
export { _interopRequireWildcard } from './_interopRequireWildcard';
10+
export { _nullishCoalesce } from './_nullishCoalesce';
11+
export { _optionalChain } from './_optionalChain';
12+
export { _optionalChainDelete } from './_optionalChainDelete';

rollup/npmHelpers.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@ export function makeBaseNPMConfig(options = {}) {
5959
// });
6060
externalLiveBindings: false,
6161

62+
// Don't call `Object.freeze` on the results of `import * as someModule from '...'`
63+
// (We don't need it, so why waste the bytes?)
64+
freeze: false,
65+
6266
// Equivalent to `esModuleInterop` in tsconfig.
6367
// Controls whether rollup emits helpers to handle special cases where turning
6468
// `import * as dogs from 'dogs'`

0 commit comments

Comments
 (0)