From c5e2d95b7cfa9f2cf8be6a48ebf2f1127dabdcd4 Mon Sep 17 00:00:00 2001 From: Denis Pushkarev Date: Wed, 21 Dec 2022 01:00:42 +0700 Subject: [PATCH] add `set(Timeout|Interval|Immediate)` extra arguments fix for Bun (similarly to IE9-) https://github.com/oven-sh/bun/issues/1633 --- CHANGELOG.md | 1 + packages/core-js-compat/src/data.mjs | 15 ++++--- packages/core-js/internals/engine-is-bun.js | 2 + packages/core-js/internals/schedulers-fix.js | 40 +++++++++---------- packages/core-js/modules/web.set-immediate.js | 6 ++- packages/core-js/modules/web.set-interval.js | 6 ++- packages/core-js/modules/web.set-timeout.js | 6 ++- tests/compat/tests.js | 11 +++-- 8 files changed, 53 insertions(+), 34 deletions(-) create mode 100644 packages/core-js/internals/engine-is-bun.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 02d3e42a0f2a..860c1b22d336 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -104,6 +104,7 @@ - `{ Map, WeakMap }.prototype.emplace` became stricter [by the spec draft](https://tc39.es/proposal-upsert/) - Removed some generic behavior (like `@@species` pattern) of some `.prototype` methods from the [new collections methods proposal](https://github.com/tc39/proposal-collection-methods) and the [`Array` deduplication proposal](https://github.com/tc39/proposal-array-unique) that *most likely* will not be implemented since it contradicts the current TC39 policy - Added pure version of the `Number` constructor, [#1154](https://github.com/zloirock/core-js/issues/1154), [#1155](https://github.com/zloirock/core-js/issues/1155), thanks [@trosos](https://github.com/trosos) +- Added `set(Timeout|Interval|Immediate)` extra arguments fix for Bun (similarly to IE9-), [bun/1633](https://github.com/oven-sh/bun/issues/1633) - Fixed handling of sparse arrays in `structuredClone`, [#1156](https://github.com/zloirock/core-js/issues/1156) - Fixed a theoretically possible future conflict of polyfills definitions in the pure version - Some refactoring and optimization diff --git a/packages/core-js-compat/src/data.mjs b/packages/core-js-compat/src/data.mjs index 1cc3adb65020..c44c58fbc8e2 100644 --- a/packages/core-js-compat/src/data.mjs +++ b/packages/core-js-compat/src/data.mjs @@ -2299,7 +2299,8 @@ export const data = { }, // TODO: Remove this module from `core-js@4` since it's split to submodules 'web.immediate': { - bun: '0.1.7', + // https://github.com/oven-sh/bun/issues/1633 + // bun: '0.1.7', ie: '10', node: '0.9.1', }, @@ -2322,13 +2323,15 @@ export const data = { safari: '10', }, 'web.set-immediate': { - bun: '0.1.7', + // https://github.com/oven-sh/bun/issues/1633 + // bun: '0.1.7', ie: '10', node: '0.9.1', }, 'web.set-interval': { android: '1.5', - bun: '0.1.1', + // https://github.com/oven-sh/bun/issues/1633 + // bun: '0.1.1', chrome: '1', deno: '1.0', firefox: '1', @@ -2341,7 +2344,8 @@ export const data = { }, 'web.set-timeout': { android: '1.5', - bun: '0.1.1', + // https://github.com/oven-sh/bun/issues/1633 + // bun: '0.1.1', chrome: '1', deno: '1.0', firefox: '1', @@ -2362,7 +2366,8 @@ export const data = { // TODO: Remove this module from `core-js@4` since it's split to submodules 'web.timers': { android: '1.5', - bun: '0.1.1', + // https://github.com/oven-sh/bun/issues/1633 + // bun: '0.1.1', chrome: '1', deno: '1.0', firefox: '1', diff --git a/packages/core-js/internals/engine-is-bun.js b/packages/core-js/internals/engine-is-bun.js new file mode 100644 index 000000000000..a9b891d37b1e --- /dev/null +++ b/packages/core-js/internals/engine-is-bun.js @@ -0,0 +1,2 @@ +/* global Bun -- Deno case */ +module.exports = typeof Bun == 'function' && Bun && typeof Bun.version == 'string'; diff --git a/packages/core-js/internals/schedulers-fix.js b/packages/core-js/internals/schedulers-fix.js index 1c9302511d51..0445431e5864 100644 --- a/packages/core-js/internals/schedulers-fix.js +++ b/packages/core-js/internals/schedulers-fix.js @@ -1,31 +1,31 @@ +'use strict'; var global = require('../internals/global'); var apply = require('../internals/function-apply'); var isCallable = require('../internals/is-callable'); -var userAgent = require('../internals/engine-user-agent'); +var ENGINE_IS_BUN = require('../internals/engine-is-bun'); +var USER_AGENT = require('../internals/engine-user-agent'); var arraySlice = require('../internals/array-slice'); var validateArgumentsLength = require('../internals/validate-arguments-length'); -var MSIE = /MSIE .\./.test(userAgent); // <- dirty ie9- check var Function = global.Function; +// dirty IE9- and Bun 0.3.0- checks +var WRAP = /MSIE .\./.test(USER_AGENT) || ENGINE_IS_BUN && (function () { + var version = global.Bun.version.split('.'); + return version.length < 3 || version[0] == 0 && (version[1] < 3 || version[1] == 3 && version[2] == 0); +}); -var wrap = function (scheduler) { - return MSIE ? function (handler, timeout /* , ...arguments */) { - var boundArgs = validateArgumentsLength(arguments.length, 1) > 2; +// IE9- / Bun 0.3.0- setTimeout / setInterval / setImmediate additional parameters fix +// https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#timers +// https://github.com/oven-sh/bun/issues/1633 +module.exports = function (scheduler, hasTimeArg) { + var firstParamIndex = hasTimeArg ? 2 : 1; + return WRAP ? function (handler, timeout /* , ...arguments */) { + var boundArgs = validateArgumentsLength(arguments.length, 1) > firstParamIndex; var fn = isCallable(handler) ? handler : Function(handler); - var args = boundArgs ? arraySlice(arguments, 2) : undefined; - return scheduler(boundArgs ? function () { - apply(fn, this, args); - } : fn, timeout); + var params = boundArgs ? arraySlice(arguments, firstParamIndex) : []; + var callback = boundArgs ? function () { + apply(fn, this, params); + } : fn; + return hasTimeArg ? scheduler(callback, timeout) : scheduler(callback); } : scheduler; }; - -// ie9- setTimeout & setInterval additional parameters fix -// https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#timers -module.exports = { - // `setTimeout` method - // https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#dom-settimeout - setTimeout: wrap(global.setTimeout), - // `setInterval` method - // https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#dom-setinterval - setInterval: wrap(global.setInterval) -}; diff --git a/packages/core-js/modules/web.set-immediate.js b/packages/core-js/modules/web.set-immediate.js index 79e7441b1704..ed8c4bade568 100644 --- a/packages/core-js/modules/web.set-immediate.js +++ b/packages/core-js/modules/web.set-immediate.js @@ -1,6 +1,10 @@ var $ = require('../internals/export'); var global = require('../internals/global'); -var setImmediate = require('../internals/task').set; +var setTask = require('../internals/task').set; +var schedulersFix = require('../internals/schedulers-fix'); + +// https://github.com/oven-sh/bun/issues/1633 +var setImmediate = global.setImmediate ? schedulersFix(setTask, false) : setTask; // `setImmediate` method // http://w3c.github.io/setImmediate/#si-setImmediate diff --git a/packages/core-js/modules/web.set-interval.js b/packages/core-js/modules/web.set-interval.js index 68ba32c32417..50391126c6c9 100644 --- a/packages/core-js/modules/web.set-interval.js +++ b/packages/core-js/modules/web.set-interval.js @@ -1,8 +1,10 @@ var $ = require('../internals/export'); var global = require('../internals/global'); -var setInterval = require('../internals/schedulers-fix').setInterval; +var schedulersFix = require('../internals/schedulers-fix'); -// ie9- setInterval additional parameters fix +var setInterval = schedulersFix(global.setInterval, true); + +// Bun / IE9- setInterval additional parameters fix // https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#dom-setinterval $({ global: true, bind: true, forced: global.setInterval !== setInterval }, { setInterval: setInterval diff --git a/packages/core-js/modules/web.set-timeout.js b/packages/core-js/modules/web.set-timeout.js index 38cbceabd62c..728565e49753 100644 --- a/packages/core-js/modules/web.set-timeout.js +++ b/packages/core-js/modules/web.set-timeout.js @@ -1,8 +1,10 @@ var $ = require('../internals/export'); var global = require('../internals/global'); -var setTimeout = require('../internals/schedulers-fix').setTimeout; +var schedulersFix = require('../internals/schedulers-fix'); -// ie9- setTimeout additional parameters fix +var setTimeout = schedulersFix(global.setTimeout, true); + +// Bun / IE9- setTimeout additional parameters fix // https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#dom-settimeout $({ global: true, bind: true, forced: global.setTimeout !== setTimeout }, { setTimeout: setTimeout diff --git a/tests/compat/tests.js b/tests/compat/tests.js index 4825dcb6909d..a46d1581bdd0 100644 --- a/tests/compat/tests.js +++ b/tests/compat/tests.js @@ -8,6 +8,7 @@ var NOT_WHITESPACES = '\u200B\u0085\u180E'; var USERAGENT = GLOBAL.navigator && GLOBAL.navigator.userAgent || ''; var process = GLOBAL.process; +var Bun = GLOBAL.Bun; var Deno = GLOBAL.Deno; var versions = process && process.versions || Deno && Deno.version; var v8 = versions && versions.v8; @@ -32,7 +33,7 @@ if (!V8_VERSION && USERAGENT) { } var IS_BROWSER = typeof window == 'object' && typeof Deno != 'object'; - +var IS_BUN = typeof Bun == 'function' && Bun && typeof Bun.version == 'string'; var IS_DENO = typeof Deno == 'object' && Deno && typeof Deno.version == 'object'; // var IS_NODE = Object.prototype.toString.call(process) == '[object process]'; @@ -222,11 +223,11 @@ function createStringTrimMethodTest(METHOD_NAME) { } function IMMEDIATE() { - return setImmediate && clearImmediate; + return setImmediate && clearImmediate && !IS_BUN; } function TIMERS() { - return !/MSIE .\./.test(USERAGENT); + return !IS_BUN && !/MSIE .\./.test(USERAGENT); } GLOBAL.tests = { @@ -1799,7 +1800,9 @@ GLOBAL.tests = { return typeof btoa == 'function'; } }, - 'web.clear-immediate': IMMEDIATE, + 'web.clear-immediate': function () { + return setImmediate && clearImmediate; + }, 'web.dom-collections.for-each': function () { return (!GLOBAL.NodeList || (NodeList.prototype.forEach && NodeList.prototype.forEach === [].forEach)) && (!GLOBAL.DOMTokenList || (DOMTokenList.prototype.forEach && DOMTokenList.prototype.forEach === [].forEach));