Skip to content
This repository was archived by the owner on Jul 6, 2025. It is now read-only.

Commit 31eff29

Browse files
committed
Minify polyfills
1 parent 7bfbc70 commit 31eff29

File tree

6 files changed

+315
-38
lines changed

6 files changed

+315
-38
lines changed

bundler/polyfills/es2016/mod.ts

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,55 @@
11
import '../es2017/mod.ts'
22

33
// Array#includes is stage 4, in ES7/ES2016
4-
import includesShim from 'https://esm.sh/array-includes/shim'
4+
// Copied from https://github.com/kevlatus/polyfill-array-includes/blob/master/array-includes.js
5+
// Licensed MIT
6+
if (!Array.prototype.includes) {
7+
Object.defineProperty(Array.prototype, 'includes', {
8+
value: function (searchElement, fromIndex) {
59

6-
includesShim()
10+
// 1. Let O be ? ToObject(this value).
11+
if (this == null) {
12+
throw new TypeError('"this" is null or not defined')
13+
}
14+
15+
var o = Object(this)
16+
17+
// 2. Let len be ? ToLength(? Get(O, "length")).
18+
var len = o.length >>> 0
19+
20+
// 3. If len is 0, return false.
21+
if (len === 0) {
22+
return false
23+
}
24+
25+
// 4. Let n be ? ToInteger(fromIndex).
26+
// (If fromIndex is undefined, this step produces the value 0.)
27+
var n = fromIndex | 0
28+
29+
// 5. If n ≥ 0, then
30+
// a. Let k be n.
31+
// 6. Else n < 0,
32+
// a. Let k be len + n.
33+
// b. If k < 0, let k be 0.
34+
var k = Math.max(n >= 0 ? n : len - Math.abs(n), 0)
35+
36+
function sameValueZero(x, y) {
37+
return x === y || (typeof x === 'number' && typeof y === 'number' && isNaN(x) && isNaN(y))
38+
}
39+
40+
// 7. Repeat, while k < len
41+
while (k < len) {
42+
// a. Let elementK be the result of ? Get(O, ! ToString(k)).
43+
// b. If SameValueZero(searchElement, elementK) is true, return true.
44+
// c. Increase k by 1.
45+
if (sameValueZero(o[k], searchElement)) {
46+
return true
47+
}
48+
k++
49+
}
50+
51+
// 8. Return false
52+
return false
53+
}
54+
})
55+
}

bundler/polyfills/es2017/mod.ts

Lines changed: 80 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,88 @@
11
import '../es2018/mod.ts'
22

33
// Object.values/Object.entries are stage 4, in ES2017
4-
import valuesShim from 'https://esm.sh/object.values/shim'
5-
import entriesShim from 'https://esm.sh/object.entries/shim'
4+
// Copied from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries
5+
if (!Object.values) {
6+
Object.values = function values(obj) {
7+
var ownProps = Object.keys(obj),
8+
i = ownProps.length,
9+
resArray = new Array(i) // preallocate the Array
10+
while (i--)
11+
resArray[i] = obj[ownProps[i]]
12+
13+
return resArray
14+
}
15+
}
16+
17+
if (!Object.entries) {
18+
Object.entries = function (obj) {
19+
var ownProps = Object.keys(obj),
20+
i = ownProps.length,
21+
resArray = new Array(i) // preallocate the Array
22+
while (i--)
23+
resArray[i] = [ownProps[i], obj[ownProps[i]]]
24+
25+
return resArray
26+
}
27+
}
628

729
// String#padStart/String#padEnd are stage 4, in ES2017
8-
import padStartShim from 'https://esm.sh/string.prototype.padstart/shim'
9-
import padEndShim from 'https://esm.sh/string.prototype.padend/shim'
30+
// Copied from https://github.com/behnammodi/polyfill/blob/master/string.polyfill.js
31+
if (!String.prototype.padStart) {
32+
Object.defineProperty(String.prototype, 'padStart', {
33+
configurable: true,
34+
writable: true,
35+
value: function (targetLength, padString) {
36+
targetLength = targetLength >> 0 //floor if number or convert non-number to 0;
37+
padString = String(typeof padString !== 'undefined' ? padString : ' ')
38+
if (this.length > targetLength) {
39+
return String(this)
40+
} else {
41+
targetLength = targetLength - this.length
42+
if (targetLength > padString.length) {
43+
padString += padString.repeat(targetLength / padString.length) //append to original to ensure we are longer than needed
44+
}
45+
return padString.slice(0, targetLength) + String(this)
46+
}
47+
},
48+
})
49+
}
50+
if (!String.prototype.padEnd) {
51+
Object.defineProperty(String.prototype, 'padEnd', {
52+
configurable: true,
53+
writable: true,
54+
value: function (targetLength, padString) {
55+
targetLength = targetLength >> 0 //floor if number or convert non-number to 0;
56+
padString = String(typeof padString !== 'undefined' ? padString : ' ')
57+
if (this.length > targetLength) {
58+
return String(this)
59+
} else {
60+
targetLength = targetLength - this.length
61+
if (targetLength > padString.length) {
62+
padString += padString.repeat(targetLength / padString.length) //append to original to ensure we are longer than needed
63+
}
64+
return String(this) + padString.slice(0, targetLength)
65+
}
66+
},
67+
})
68+
}
1069

1170
// Object.getOwnPropertyDescriptors is stage 4, in ES2017
12-
import getOwnPropertyDescriptorsShim from 'https://esm.sh/object.getownpropertydescriptors/shim'
71+
// Copied from https://github.com/watson/get-own-property-descriptors-polyfill/blob/master/index.js
72+
// Licensed MIT
73+
if (!Object.getOwnPropertyDescriptors) {
74+
Object.getOwnPropertyDescriptors = function (obj) {
75+
if (obj === null || obj === undefined) {
76+
throw new TypeError('Cannot convert undefined or null to object')
77+
}
78+
79+
const protoPropDescriptor = Object.getOwnPropertyDescriptor(obj, '__proto__')
80+
const descriptors = protoPropDescriptor ? { ['__proto__']: protoPropDescriptor } : {}
81+
82+
for (const name of Object.getOwnPropertyNames(obj)) {
83+
descriptors[name] = Object.getOwnPropertyDescriptor(obj, name)
84+
}
1385

14-
valuesShim()
15-
entriesShim()
16-
padStartShim()
17-
padEndShim()
18-
getOwnPropertyDescriptorsShim()
86+
return descriptors
87+
}
88+
}

bundler/polyfills/es2018/mod.ts

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,34 @@
11
import '../es2019/mod.ts'
22

3-
import finallyShim from 'https://esm.sh/promise.prototype.finally/shim'
3+
/**
4+
* Available in:
5+
* Edge: 18
6+
* Firefox: 58
7+
* Chrome: 63
8+
* Safari: 11.1
9+
*
10+
* https://caniuse.com/promise-finally
11+
*/
12+
// Copied from https://github.com/vercel/next.js/blob/canary/packages/next-polyfill-module/src/index.js
13+
// Licensed MIT
14+
if (!Promise.prototype.finally) {
15+
Promise.prototype.finally = function (callback) {
16+
if (typeof callback !== 'function') {
17+
return this.then(callback, callback)
18+
}
419

5-
if (typeof Promise === 'function') {
6-
finallyShim()
20+
var P = this.constructor || Promise
21+
return this.then(
22+
function (value) {
23+
return P.resolve(callback()).then(function () {
24+
return value
25+
})
26+
},
27+
function (err) {
28+
return P.resolve(callback()).then(function () {
29+
throw err
30+
})
31+
}
32+
)
33+
}
734
}

bundler/polyfills/es2019/mod.ts

Lines changed: 71 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,73 @@
11
import '../es2020/mod.ts'
22

3-
import flatShim from 'https://esm.sh/array.prototype.flat/shim'
4-
import flatMapShim from 'https://esm.sh/array.prototype.flatmap/shim'
5-
import descriptionShim from 'https://esm.sh/symbol.prototype.description/shim'
6-
import fromEntriesShim from 'https://esm.sh/object.fromentries/shim'
7-
import trimStartShim from 'https://esm.sh/string.prototype.trimstart/shim'
8-
import trimEndShim from 'https://esm.sh/string.prototype.trimend/shim'
9-
10-
flatShim()
11-
flatMapShim()
12-
descriptionShim()
13-
fromEntriesShim()
14-
trimStartShim()
15-
trimEndShim()
3+
if (!('fromEntries' in Object.prototype)) {
4+
Object.prototype.fromEntries = function fromEntries(iterable) {
5+
return [...iterable].reduce((obj, [key, val]) => {
6+
obj[key] = val
7+
return obj
8+
}, {})
9+
}
10+
}
11+
12+
/**
13+
* Available in:
14+
* Edge: never
15+
* Firefox: 61
16+
* Chrome: 66
17+
* Safari: 12
18+
*
19+
* https://caniuse.com/mdn-javascript_builtins_string_trimstart
20+
* https://caniuse.com/mdn-javascript_builtins_string_trimend
21+
*/
22+
// Copied from https://github.com/vercel/next.js/blob/canary/packages/next-polyfill-module/src/index.js
23+
// Licensed MIT
24+
if (!('trimStart' in String.prototype)) {
25+
String.prototype.trimStart = String.prototype.trimLeft
26+
}
27+
if (!('trimEnd' in String.prototype)) {
28+
String.prototype.trimEnd = String.prototype.trimRight
29+
}
30+
31+
/**
32+
* Available in:
33+
* Edge: never
34+
* Firefox: 63
35+
* Chrome: 70
36+
* Safari: 12.1
37+
*
38+
* https://caniuse.com/mdn-javascript_builtins_symbol_description
39+
*/
40+
// Copied from https://github.com/vercel/next.js/blob/canary/packages/next-polyfill-module/src/index.js
41+
// Licensed MIT
42+
if (!('description' in Symbol.prototype)) {
43+
Object.defineProperty(Symbol.prototype, 'description', {
44+
configurable: true,
45+
get: function get() {
46+
var m = /\((.*)\)/.exec(this.toString())
47+
return m ? m[1] : undefined
48+
},
49+
})
50+
}
51+
52+
/**
53+
* Available in:
54+
* Edge: never
55+
* Firefox: 62
56+
* Chrome: 69
57+
* Safari: 12
58+
*
59+
* https://caniuse.com/array-flat
60+
*/
61+
// Copied from https://gist.github.com/developit/50364079cf0390a73e745e513fa912d9
62+
// Licensed Apache-2.0
63+
if (!('flat' in Array.prototype)) {
64+
Array.prototype.flat = function flat(d, c) {
65+
return (
66+
(c = this.concat.apply([], this)),
67+
d > 1 && c.some(Array.isArray) ? c.flat(d - 1) : c
68+
)
69+
}
70+
Array.prototype.flatMap = function flatMap(c, a) {
71+
return this.map(c, a).flat()
72+
}
73+
}

bundler/polyfills/es2020/mod.ts

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,30 @@
11
import '../es2021/mod.ts'
22

3-
import matchallShim from 'https://esm.sh/string.prototype.matchall/shim'
4-
import globalthisShim from 'https://esm.sh/globalthis/shim'
5-
import allsettledShim from 'https://esm.sh/promise.allsettled/shim'
3+
// todo: add string.prototype.matchall shim
64

7-
matchallShim()
8-
globalthisShim()
9-
allsettledShim()
5+
// globalThis
6+
// Copied from https://mathiasbynens.be/notes/globalthis
7+
if (typeof globalThis !== 'object') {
8+
Object.defineProperty(Object.prototype, '__magic__', {
9+
get: function () {
10+
return this
11+
},
12+
configurable: true // This makes it possible to `delete` the getter later.
13+
})
14+
__magic__.globalThis = __magic__ // lolwat
15+
delete Object.prototype.__magic__
16+
}
17+
18+
// Promise.allSettled
19+
if (!Promise.allSettled) {
20+
Promise.allSettled = (promises) => Promise.all(promises.map(p => p
21+
.then(value => ({
22+
status: 'fulfilled',
23+
value,
24+
}))
25+
.catch(reason => ({
26+
status: 'rejected',
27+
reason,
28+
}))
29+
))
30+
}

bundler/polyfills/es2021/mod.ts

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,57 @@
1-
import stringReplaceAllShim from 'https://esm.sh/string.prototype.replaceall/shim'
2-
import promiseAnyShim from 'https://esm.sh/promise.any/shim'
1+
// String.prototype.replaceAll() polyfill
2+
// Copied from https://gomakethings.com/how-to-replace-a-section-of-a-string-with-another-one-with-vanilla-js/
3+
// Licensed MIT
4+
if (!String.prototype.replaceAll) {
5+
String.prototype.replaceAll = function (str, newStr) {
36

4-
stringReplaceAllShim()
5-
promiseAnyShim()
7+
// If a regex pattern
8+
if (Object.prototype.toString.call(str).toLowerCase() === '[object regexp]') {
9+
return this.replace(str, newStr)
10+
}
11+
12+
// If a string
13+
return this.replace(new RegExp(str, 'g'), newStr)
14+
15+
}
16+
}
17+
18+
/**
19+
* An implementation of the upcoming `Promise.any` functionality.
20+
*
21+
* @author Trevor Sears <[email protected]>
22+
* @version v0.1.0
23+
* @since v0.1.0
24+
*/
25+
if (!Promise.any) {
26+
Promise.any = async (values) => {
27+
28+
return new Promise((resolve, reject) => {
29+
30+
let hasResolved = false
31+
let iterableCount = 0
32+
let rejectionReasons = []
33+
34+
const resolveOnce = (value) => {
35+
if (!hasResolved) {
36+
hasResolved = true
37+
resolve(value)
38+
}
39+
}
40+
const rejectionCheck = (reason) => {
41+
rejectionReasons.push(reason)
42+
if (rejectionReasons.length >= iterableCount) reject(rejectionReasons)
43+
}
44+
for (let value of values) {
45+
iterableCount++
46+
if ((value).then !== undefined) {
47+
let promiseLikeValue = value
48+
promiseLikeValue.then((result) => resolveOnce(result))
49+
if ((value).catch !== undefined) {
50+
let promiseValue = promiseLikeValue
51+
promiseValue.catch((reason) => rejectionCheck(reason))
52+
}
53+
}
54+
}
55+
})
56+
}
57+
}

0 commit comments

Comments
 (0)