diff --git a/CHANGELOG.md b/CHANGELOG.md index f074fc1271c7..25994cb12feb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ ## Changelog ##### Unreleased +- Recent updates of the [iterator helpers proposal](https://github.com/tc39/proposal-iterator-helpers), [#1101](https://github.com/zloirock/core-js/issues/1101): + - `.asIndexedPairs` renamed to `.indexed`, [proposal-iterator-helpers/183](https://github.com/tc39/proposal-iterator-helpers/pull/183): + - `Iterator.prototype.asIndexedPairs` -> `Iterator.prototype.indexed` + - `AsyncIterator.prototype.asIndexedPairs` -> `AsyncIterator.prototype.indexed` + - Avoid exposing spec fiction `%AsyncFromSyncIteratorPrototype%` in `AsyncIterator.from` and `Iterator.prototype.toAsync`, [proposal-iterator-helpers/182](https://github.com/tc39/proposal-iterator-helpers/pull/182), [proposal-iterator-helpers/202](https://github.com/tc39/proposal-iterator-helpers/pull/202) + - Avoid unnecessary promise creation in `%WrapForValidAsyncIteratorPrototype%.next`, [proposal-iterator-helpers/197](https://github.com/tc39/proposal-iterator-helpers/pull/197) + - Do not validate value in `%WrapForValid(Async)IteratorPrototype%.next`, [proposal-iterator-helpers/197](https://github.com/tc39/proposal-iterator-helpers/pull/197) and [proposal-iterator-helpers/205](https://github.com/tc39/proposal-iterator-helpers/pull/205) + - Do not forward the parameter of `.next` / `.return` to an underlying iterator by the extended iterator protocol, a part of [proposal-iterator-helpers/194](https://github.com/tc39/proposal-iterator-helpers/pull/194) + - `.throw` methods removed from all wrappers / helpers prototypes, a part of [proposal-iterator-helpers/194](https://github.com/tc39/proposal-iterator-helpers/pull/194) + - Close inner iterators in `{ Iterator, AsyncIterator }.prototype.flatMap` on `.return`, [proposal-iterator-helpers/195](https://github.com/tc39/proposal-iterator-helpers/pull/195) + - Throw `RangeError` on `NaN` in `{ Iterator, AsyncIterator }.prototype.{ drop, take }`, [proposal-iterator-helpers/181](https://github.com/tc39/proposal-iterator-helpers/pull/181) + - Many other updates and fixes of this proposal - Polyfill `Promise` with `unhandledrejection` event support (browser style) in Deno < [1.24](https://github.com/denoland/deno/releases/tag/v1.24.0) - Added compat data for Bun, [#1103](https://github.com/zloirock/core-js/issues/1103) - Added compat data for Hermes, [#1099](https://github.com/zloirock/core-js/issues/1099) diff --git a/README.md b/README.md index f124cf70b6c7..65286d17fa6d 100644 --- a/README.md +++ b/README.md @@ -2180,17 +2180,17 @@ correctionNeeded; // => [1, 1, 3] core-js(-pure)/stage/2 ``` ##### [Iterator helpers](https://github.com/tc39/proposal-iterator-helpers)[⬆](#index) -Modules [`esnext.async-iterator.constructor`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.async-iterator.constructor.js), [`esnext.async-iterator.as-indexed-pairs`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.async-iterator.as-indexed-pairs.js), [`esnext.async-iterator.drop`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.async-iterator.drop.js), [`esnext.async-iterator.every`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.async-iterator.every.js), [`esnext.async-iterator.filter`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.async-iterator.filter.js), [`esnext.async-iterator.find`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.async-iterator.find.js), [`esnext.async-iterator.flat-map`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.async-iterator.flat-map.js), [`esnext.async-iterator.for-each`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.async-iterator.for-each.js), [`esnext.async-iterator.from`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.async-iterator.from.js), [`esnext.async-iterator.map`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.async-iterator.map.js), [`esnext.async-iterator.reduce`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.async-iterator.reduce.js), [`esnext.async-iterator.some`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.async-iterator.some.js), [`esnext.async-iterator.take`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.async-iterator.take.js), [`esnext.async-iterator.to-array`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.async-iterator.to-array.js), [`esnext.iterator.constructor`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.iterator.constructor.js), [`esnext.iterator.as-indexed-pairs`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.iterator.as-indexed-pairs.js), [`esnext.iterator.drop`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.iterator.drop.js), [`esnext.iterator.every`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.iterator.every.js), [`esnext.iterator.filter`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.iterator.filter.js), [`esnext.iterator.find`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.iterator.find.js), [`esnext.iterator.flat-map`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.iterator.flat-map.js), [`esnext.iterator.for-each`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.iterator.for-each.js), [`esnext.iterator.from`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.iterator.from.js), [`esnext.iterator.map`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.iterator.map.js), [`esnext.iterator.reduce`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.iterator.reduce.js), [`esnext.iterator.some`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.iterator.some.js), [`esnext.iterator.take`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.iterator.take.js), [`esnext.iterator.to-array`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.iterator.to-array.js) and [`esnext.iterator.to-async`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.iterator.to-async.js) +Modules [`esnext.async-iterator.constructor`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.async-iterator.constructor.js), [`esnext.async-iterator.drop`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.async-iterator.drop.js), [`esnext.async-iterator.every`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.async-iterator.every.js), [`esnext.async-iterator.filter`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.async-iterator.filter.js), [`esnext.async-iterator.find`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.async-iterator.find.js), [`esnext.async-iterator.flat-map`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.async-iterator.flat-map.js), [`esnext.async-iterator.for-each`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.async-iterator.for-each.js), [`esnext.async-iterator.from`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.async-iterator.from.js), [`esnext.async-iterator.indexed`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.async-iterator.indexed.js), [`esnext.async-iterator.map`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.async-iterator.map.js), [`esnext.async-iterator.reduce`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.async-iterator.reduce.js), [`esnext.async-iterator.some`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.async-iterator.some.js), [`esnext.async-iterator.take`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.async-iterator.take.js), [`esnext.async-iterator.to-array`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.async-iterator.to-array.js), [`esnext.iterator.constructor`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.iterator.constructor.js), [`esnext.iterator.drop`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.iterator.drop.js), [`esnext.iterator.every`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.iterator.every.js), [`esnext.iterator.filter`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.iterator.filter.js), [`esnext.iterator.find`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.iterator.find.js), [`esnext.iterator.flat-map`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.iterator.flat-map.js), [`esnext.iterator.for-each`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.iterator.for-each.js), [`esnext.iterator.from`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.iterator.from.js), [`esnext.iterator.indexed`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.iterator.indexed.js), [`esnext.iterator.map`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.iterator.map.js), [`esnext.iterator.reduce`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.iterator.reduce.js), [`esnext.iterator.some`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.iterator.some.js), [`esnext.iterator.take`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.iterator.take.js), [`esnext.iterator.to-array`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.iterator.to-array.js) and [`esnext.iterator.to-async`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.iterator.to-async.js) ```js class Iterator { static from(iterable: Iterable): Iterator; - asIndexedPairs(): Iterator<[index, any]>; drop(limit: uint): Iterator; every(callbackfn: value: any => boolean): boolean; filter(callbackfn: value: any => boolean): Iterator; find(callbackfn: value: any => boolean)): any; flatMap(callbackfn: value => any: Iterable): Iterator; forEach(callbackfn: value => void): void; + indexed(): Iterator<[index, any]>; map(callbackfn: value => any): Iterator; reduce(callbackfn: (memo: any, value: any) => any, initialValue: any): any; some(callbackfn: value: any => boolean): boolean; @@ -2202,13 +2202,13 @@ class Iterator { class AsyncIterator { static from(iterable: Iterable): AsyncIterator; - asIndexedPairs(): AsyncIterator<[index, any]>; drop(limit: uint): AsyncIterator; every(async callbackfn: value: any => boolean): Promise; filter(async callbackfn: value: any => boolean): AsyncIterator; find(async callbackfn: value: any => boolean)): Promise; flatMap(async callbackfn: value => any: Iterable): AsyncIterator; forEach(async callbackfn: value => void): Promise; + indexed(): AsyncIterator<[index, any]>; map(async callbackfn: value => any): AsyncIterator; reduce(async callbackfn: (memo: any, value: any) => any, initialValue: any): Promise; some(async callbackfn: value: any => boolean): Promise; @@ -2221,7 +2221,6 @@ class AsyncIterator { ```js core-js/proposals/iterator-helpers core-js(-pure)/full/async-iterator -core-js(-pure)/full/async-iterator/as-indexed-pairs core-js(-pure)/full/async-iterator/drop core-js(-pure)/full/async-iterator/every core-js(-pure)/full/async-iterator/filter @@ -2229,13 +2228,13 @@ core-js(-pure)/full/async-iterator/find core-js(-pure)/full/async-iterator/flat-map core-js(-pure)/full/async-iterator/for-each core-js(-pure)/full/async-iterator/from +core-js(-pure)/full/async-iterator/indexed core-js(-pure)/full/async-iterator/map core-js(-pure)/full/async-iterator/reduce core-js(-pure)/full/async-iterator/some core-js(-pure)/full/async-iterator/take core-js(-pure)/full/async-iterator/to-array core-js(-pure)/full/iterator -core-js(-pure)/full/iterator/as-indexed-pairs core-js(-pure)/full/iterator/drop core-js(-pure)/full/iterator/every core-js(-pure)/full/iterator/filter @@ -2243,6 +2242,7 @@ core-js(-pure)/full/iterator/find core-js(-pure)/full/iterator/flat-map core-js(-pure)/full/iterator/for-each core-js(-pure)/full/iterator/from +core-js(-pure)/full/iterator/indexed core-js(-pure)/full/iterator/map core-js(-pure)/full/iterator/reduce core-js(-pure)/full/iterator/some diff --git a/packages/core-js-compat/src/data.mjs b/packages/core-js-compat/src/data.mjs index eb95963181cc..b9c7dbad7141 100644 --- a/packages/core-js-compat/src/data.mjs +++ b/packages/core-js-compat/src/data.mjs @@ -2080,6 +2080,7 @@ export const data = { }, 'esnext.async-iterator.constructor': { }, + // TODO: Remove from `core-js@4` 'esnext.async-iterator.as-indexed-pairs': { }, 'esnext.async-iterator.drop': { @@ -2096,6 +2097,8 @@ export const data = { }, 'esnext.async-iterator.from': { }, + 'esnext.async-iterator.indexed': { + }, 'esnext.async-iterator.map': { }, 'esnext.async-iterator.reduce': { @@ -2122,6 +2125,7 @@ export const data = { 'esnext.global-this': null, 'esnext.iterator.constructor': { }, + // TODO: Remove from `core-js@4` 'esnext.iterator.as-indexed-pairs': { }, 'esnext.iterator.drop': { @@ -2138,6 +2142,8 @@ export const data = { }, 'esnext.iterator.from': { }, + 'esnext.iterator.indexed': { + }, 'esnext.iterator.map': { }, 'esnext.iterator.reduce': { diff --git a/packages/core-js-compat/src/modules-by-versions.mjs b/packages/core-js-compat/src/modules-by-versions.mjs index 347b99a53f53..ab62620b1326 100644 --- a/packages/core-js-compat/src/modules-by-versions.mjs +++ b/packages/core-js-compat/src/modules-by-versions.mjs @@ -150,4 +150,8 @@ export default { 'esnext.array.group-to-map', 'esnext.symbol.metadata-key', ], + 3.24: [ + 'esnext.async-iterator.indexed', + 'esnext.iterator.indexed', + ], }; diff --git a/packages/core-js/full/async-iterator/index.js b/packages/core-js/full/async-iterator/index.js index 6376eee05976..867cf7f8e0ba 100644 --- a/packages/core-js/full/async-iterator/index.js +++ b/packages/core-js/full/async-iterator/index.js @@ -3,6 +3,7 @@ require('../../modules/es.object.to-string'); require('../../modules/es.promise'); require('../../modules/es.string.iterator'); require('../../modules/esnext.async-iterator.constructor'); +// TODO: Remove from `core-js@4` require('../../modules/esnext.async-iterator.as-indexed-pairs'); require('../../modules/esnext.async-iterator.drop'); require('../../modules/esnext.async-iterator.every'); @@ -11,6 +12,7 @@ require('../../modules/esnext.async-iterator.find'); require('../../modules/esnext.async-iterator.flat-map'); require('../../modules/esnext.async-iterator.for-each'); require('../../modules/esnext.async-iterator.from'); +require('../../modules/esnext.async-iterator.indexed'); require('../../modules/esnext.async-iterator.map'); require('../../modules/esnext.async-iterator.reduce'); require('../../modules/esnext.async-iterator.some'); diff --git a/packages/core-js/full/async-iterator/indexed.js b/packages/core-js/full/async-iterator/indexed.js new file mode 100644 index 000000000000..2686c40d504a --- /dev/null +++ b/packages/core-js/full/async-iterator/indexed.js @@ -0,0 +1,8 @@ +require('../../modules/es.object.to-string'); +require('../../modules/es.promise'); +require('../../modules/esnext.async-iterator.constructor'); +require('../../modules/esnext.async-iterator.indexed'); + +var entryUnbind = require('../../internals/entry-unbind'); + +module.exports = entryUnbind('AsyncIterator', 'indexed'); diff --git a/packages/core-js/full/iterator/index.js b/packages/core-js/full/iterator/index.js index 55bc312204b6..181901486408 100644 --- a/packages/core-js/full/iterator/index.js +++ b/packages/core-js/full/iterator/index.js @@ -3,6 +3,7 @@ require('../../modules/es.object.to-string'); require('../../modules/es.promise'); require('../../modules/es.string.iterator'); require('../../modules/esnext.iterator.constructor'); +// TODO: Remove from `core-js@4` require('../../modules/esnext.iterator.as-indexed-pairs'); require('../../modules/esnext.iterator.drop'); require('../../modules/esnext.iterator.every'); @@ -11,6 +12,7 @@ require('../../modules/esnext.iterator.find'); require('../../modules/esnext.iterator.flat-map'); require('../../modules/esnext.iterator.for-each'); require('../../modules/esnext.iterator.from'); +require('../../modules/esnext.iterator.indexed'); require('../../modules/esnext.iterator.map'); require('../../modules/esnext.iterator.reduce'); require('../../modules/esnext.iterator.some'); diff --git a/packages/core-js/full/iterator/indexed.js b/packages/core-js/full/iterator/indexed.js new file mode 100644 index 000000000000..133712fff554 --- /dev/null +++ b/packages/core-js/full/iterator/indexed.js @@ -0,0 +1,8 @@ +require('../../modules/es.object.to-string'); +require('../../modules/esnext.iterator.constructor'); +require('../../modules/esnext.iterator.indexed'); + +var entryUnbind = require('../../internals/entry-unbind'); + +module.exports = entryUnbind('Iterator', 'indexed'); + diff --git a/packages/core-js/internals/async-from-sync-iterator.js b/packages/core-js/internals/async-from-sync-iterator.js index 79a19e068ae1..b4070a9bba59 100644 --- a/packages/core-js/internals/async-from-sync-iterator.js +++ b/packages/core-js/internals/async-from-sync-iterator.js @@ -1,5 +1,5 @@ 'use strict'; -var apply = require('../internals/function-apply'); +var call = require('../internals/function-call'); var anObject = require('../internals/an-object'); var create = require('../internals/object-create'); var getMethod = require('../internals/get-method'); @@ -30,31 +30,19 @@ var AsyncFromSyncIterator = function AsyncIterator(iterator) { }; AsyncFromSyncIterator.prototype = defineBuiltIns(create(AsyncIteratorPrototype), { - next: function next(arg) { + next: function next() { var state = getInternalState(this); - var hasArg = !!arguments.length; return new Promise(function (resolve, reject) { - var result = anObject(apply(state.next, state.iterator, hasArg ? [arg] : [])); + var result = anObject(call(state.next, state.iterator)); asyncFromSyncIteratorContinuation(result, resolve, reject); }); }, - 'return': function (arg) { + 'return': function () { var iterator = getInternalState(this).iterator; - var hasArg = !!arguments.length; return new Promise(function (resolve, reject) { var $return = getMethod(iterator, 'return'); - if ($return === undefined) return resolve({ done: true, value: arg }); - var result = anObject(apply($return, iterator, hasArg ? [arg] : [])); - asyncFromSyncIteratorContinuation(result, resolve, reject); - }); - }, - 'throw': function (arg) { - var iterator = getInternalState(this).iterator; - var hasArg = !!arguments.length; - return new Promise(function (resolve, reject) { - var $throw = getMethod(iterator, 'throw'); - if ($throw === undefined) return reject(arg); - var result = anObject(apply($throw, iterator, hasArg ? [arg] : [])); + if ($return === undefined) return resolve({ done: true, value: undefined }); + var result = anObject(call($return, iterator)); asyncFromSyncIteratorContinuation(result, resolve, reject); }); } diff --git a/packages/core-js/internals/async-iterator-close.js b/packages/core-js/internals/async-iterator-close.js new file mode 100644 index 000000000000..d18871d8a479 --- /dev/null +++ b/packages/core-js/internals/async-iterator-close.js @@ -0,0 +1,18 @@ +var call = require('../internals/function-call'); +var getBuiltIn = require('../internals/get-built-in'); +var getMethod = require('../internals/get-method'); + +module.exports = function (iterator, method, argument, reject) { + try { + var returnMethod = getMethod(iterator, 'return'); + if (returnMethod) { + return getBuiltIn('Promise').resolve(call(returnMethod, iterator)).then(function () { + method(argument); + }, function (error) { + reject(error); + }); + } + } catch (error2) { + return reject(error2); + } method(argument); +}; diff --git a/packages/core-js/internals/async-iterator-create-proxy.js b/packages/core-js/internals/async-iterator-create-proxy.js index 7edc0d3b5f55..ee26110b9ecf 100644 --- a/packages/core-js/internals/async-iterator-create-proxy.js +++ b/packages/core-js/internals/async-iterator-create-proxy.js @@ -1,5 +1,6 @@ 'use strict'; var call = require('../internals/function-call'); +var perform = require('../internals/perform'); var anObject = require('../internals/an-object'); var create = require('../internals/object-create'); var createNonEnumerableProperty = require('../internals/create-non-enumerable-property'); @@ -9,68 +10,118 @@ var InternalStateModule = require('../internals/internal-state'); var getBuiltIn = require('../internals/get-built-in'); var getMethod = require('../internals/get-method'); var AsyncIteratorPrototype = require('../internals/async-iterator-prototype'); +var iteratorClose = require('../internals/iterator-close'); var Promise = getBuiltIn('Promise'); -var ASYNC_ITERATOR_PROXY = 'AsyncIteratorProxy'; +var ASYNC_ITERATOR_HELPER = 'AsyncIteratorHelper'; +var WRAP_FOR_VALID_ASYNC_ITERATOR = 'WrapForValidAsyncIterator'; var setInternalState = InternalStateModule.set; -var getInternalState = InternalStateModule.getterFor(ASYNC_ITERATOR_PROXY); var TO_STRING_TAG = wellKnownSymbol('toStringTag'); +var createAsyncIteratorProxyPrototype = function (IS_ITERATOR) { + var IS_GENERATOR = !IS_ITERATOR; + var ASYNC_ITERATOR_PROXY = IS_ITERATOR ? WRAP_FOR_VALID_ASYNC_ITERATOR : ASYNC_ITERATOR_HELPER; + + var getInternalState = InternalStateModule.getterFor(ASYNC_ITERATOR_PROXY); + + var getStateOrEarlyExit = function (that) { + var stateCompletion = perform(function () { + return getInternalState(that); + }); + + var stateError = stateCompletion.error; + var state = stateCompletion.value; + + if (stateError || (IS_GENERATOR && state.done)) { + return { exit: true, value: stateError ? Promise.reject(state) : Promise.resolve({ done: true, value: undefined }) }; + } return { exit: false, value: state }; + }; + + var enqueue = function (state, handler) { + var task = function () { + var promise = handler(); + if (IS_GENERATOR) { + state.awaiting = promise; + var clean = function () { + if (state.awaiting === promise) state.awaiting = null; + }; + promise.then(clean, clean); + } return promise; + }; + + return state.awaiting ? state.awaiting = state.awaiting.then(task, task) : task(); + }; + + var AsyncIteratorProxyPrototype = defineBuiltIns(create(AsyncIteratorPrototype), { + next: function next() { + var stateCompletion = getStateOrEarlyExit(this); + var exit = stateCompletion.exit; + var state = stateCompletion.value; + + return exit ? state : enqueue(state, function () { + var handlerCompletion = perform(function () { + return anObject(state.nextHandler(Promise)); + }); + var handlerError = handlerCompletion.error; + var value = handlerCompletion.value; + if (handlerError) state.done = true; + return handlerError ? Promise.reject(value) : Promise.resolve(value); + }); + }, + 'return': function () { + var stateCompletion = getStateOrEarlyExit(this); + var exit = stateCompletion.exit; + var state = stateCompletion.value; + + return exit ? state : enqueue(state, function () { + return new Promise(function (resolve, reject) { + var iterator = state.iterator; + var innerIterator = state.innerIterator; + state.done = true; + if (innerIterator) try { + iteratorClose(innerIterator, 'return'); + } catch (error) { + return iteratorClose(iterator, 'throw', error); + } + var $$return = getMethod(iterator, 'return'); + if ($$return === undefined) return resolve({ done: true, value: undefined }); + Promise.resolve(call($$return, iterator)).then(function (result) { + anObject(result); + resolve({ done: true, value: undefined }); + }, reject); + }); + }); + } + }); + + if (IS_GENERATOR) { + createNonEnumerableProperty(AsyncIteratorProxyPrototype, TO_STRING_TAG, 'Async Iterator Helper'); + } + + return AsyncIteratorProxyPrototype; +}; + +var AsyncIteratorHelperPrototype = createAsyncIteratorProxyPrototype(false); +var WrapForValidAsyncIteratorPrototype = createAsyncIteratorProxyPrototype(true); + module.exports = function (nextHandler, IS_ITERATOR) { + var ASYNC_ITERATOR_PROXY = IS_ITERATOR ? WRAP_FOR_VALID_ASYNC_ITERATOR : ASYNC_ITERATOR_HELPER; + var AsyncIteratorProxy = function AsyncIterator(record, state) { if (state) { state.iterator = record.iterator; state.next = record.next; } else state = record; state.type = ASYNC_ITERATOR_PROXY; + state.nextHandler = nextHandler; state.done = false; - state.ignoreArgument = !IS_ITERATOR; + state.awaiting = null; setInternalState(this, state); }; - AsyncIteratorProxy.prototype = defineBuiltIns(create(AsyncIteratorPrototype), { - next: function next(arg) { - var that = this; - var hasArgument = !!arguments.length; - return new Promise(function (resolve) { - var state = getInternalState(that); - var args = hasArgument ? [state.ignoreArgument ? undefined : arg] : IS_ITERATOR ? [] : [undefined]; - state.ignoreArgument = false; - resolve(state.done ? { done: true, value: undefined } : anObject(call(nextHandler, state, Promise, args))); - }); - }, - 'return': function (value) { - var that = this; - return new Promise(function (resolve, reject) { - var state = getInternalState(that); - var iterator = state.iterator; - state.done = true; - var $$return = getMethod(iterator, 'return'); - if ($$return === undefined) return resolve({ done: true, value: value }); - Promise.resolve(call($$return, iterator, value)).then(function (result) { - anObject(result); - resolve({ done: true, value: value }); - }, reject); - }); - }, - 'throw': function (value) { - var that = this; - return new Promise(function (resolve, reject) { - var state = getInternalState(that); - var iterator = state.iterator; - state.done = true; - var $$throw = getMethod(iterator, 'throw'); - if ($$throw === undefined) return reject(value); - resolve(call($$throw, iterator, value)); - }); - } - }); - - if (!IS_ITERATOR) { - createNonEnumerableProperty(AsyncIteratorProxy.prototype, TO_STRING_TAG, 'Generator'); - } + AsyncIteratorProxy.prototype = IS_ITERATOR ? WrapForValidAsyncIteratorPrototype : AsyncIteratorHelperPrototype; return AsyncIteratorProxy; }; diff --git a/packages/core-js/internals/async-iterator-indexed.js b/packages/core-js/internals/async-iterator-indexed.js new file mode 100644 index 000000000000..76deb459d4eb --- /dev/null +++ b/packages/core-js/internals/async-iterator-indexed.js @@ -0,0 +1,28 @@ +'use strict'; +// https://github.com/tc39/proposal-iterator-helpers +var call = require('../internals/function-call'); +var anObject = require('../internals/an-object'); +var getIteratorDirect = require('../internals/get-iterator-direct'); +var createAsyncIteratorProxy = require('../internals/async-iterator-create-proxy'); + +var AsyncIteratorProxy = createAsyncIteratorProxy(function (Promise) { + var state = this; + var iterator = state.iterator; + + return Promise.resolve(anObject(call(state.next, iterator))).then(function (step) { + if (anObject(step).done) { + state.done = true; + return { done: true, value: undefined }; + } + return { done: false, value: [state.index++, step.value] }; + }).then(null, function (error) { + state.done = true; + throw error; + }); +}); + +module.exports = function indexed() { + return new AsyncIteratorProxy(getIteratorDirect(this), { + index: 0 + }); +}; diff --git a/packages/core-js/internals/async-iterator-iteration.js b/packages/core-js/internals/async-iterator-iteration.js index d010dbadda69..081369db7400 100644 --- a/packages/core-js/internals/async-iterator-iteration.js +++ b/packages/core-js/internals/async-iterator-iteration.js @@ -7,7 +7,7 @@ var anObject = require('../internals/an-object'); var doesNotExceedSafeInteger = require('../internals/does-not-exceed-safe-integer'); var getBuiltIn = require('../internals/get-built-in'); var getIteratorDirect = require('../internals/get-iterator-direct'); -var getMethod = require('../internals/get-method'); +var closeAsyncIteration = require('../internals/async-iterator-close'); var createMethod = function (TYPE) { var IS_TO_ARRAY = TYPE == 0; @@ -24,28 +24,15 @@ var createMethod = function (TYPE) { if (MAPPING || !IS_TO_ARRAY) aCallable(fn); return new Promise(function (resolve, reject) { - var closeIteration = function (method, argument) { - try { - var returnMethod = getMethod(iterator, 'return'); - if (returnMethod) { - return Promise.resolve(call(returnMethod, iterator)).then(function () { - method(argument); - }, function (error) { - reject(error); - }); - } - } catch (error2) { - return reject(error2); - } method(argument); - }; - - var onError = function (error) { - closeIteration(reject, error); + var ifAbruptCloseAsyncIterator = function (error) { + closeAsyncIteration(iterator, reject, error, reject); }; var loop = function () { try { - if (IS_TO_ARRAY && MAPPING) doesNotExceedSafeInteger(index); + if (IS_TO_ARRAY && MAPPING) try { + doesNotExceedSafeInteger(index); + } catch (error5) { ifAbruptCloseAsyncIterator(error5); } Promise.resolve(anObject(call(next, iterator))).then(function (step) { try { if (anObject(step).done) { @@ -55,27 +42,31 @@ var createMethod = function (TYPE) { } else resolve(IS_SOME ? false : IS_EVERY || undefined); } else { var value = step.value; - if (MAPPING) { - Promise.resolve(IS_TO_ARRAY ? fn(value, index) : fn(value)).then(function (result) { - if (IS_FOR_EACH) { - loop(); - } else if (IS_EVERY) { - result ? loop() : closeIteration(resolve, false); - } else if (IS_TO_ARRAY) { - target[index++] = result; - loop(); - } else { - result ? closeIteration(resolve, IS_SOME || value) : loop(); - } - }, onError); - } else { - target[index++] = value; - loop(); - } + try { + if (MAPPING) { + Promise.resolve(IS_TO_ARRAY ? fn(value, index) : fn(value)).then(function (result) { + if (IS_FOR_EACH) { + loop(); + } else if (IS_EVERY) { + result ? loop() : closeAsyncIteration(iterator, resolve, false, reject); + } else if (IS_TO_ARRAY) { + try { + target[index++] = result; + loop(); + } catch (error4) { ifAbruptCloseAsyncIterator(error4); } + } else { + result ? closeAsyncIteration(iterator, resolve, IS_SOME || value, reject) : loop(); + } + }, ifAbruptCloseAsyncIterator); + } else { + target[index++] = value; + loop(); + } + } catch (error3) { ifAbruptCloseAsyncIterator(error3); } } - } catch (error) { onError(error); } - }, onError); - } catch (error2) { onError(error2); } + } catch (error2) { reject(error2); } + }, reject); + } catch (error) { reject(error); } }; loop(); diff --git a/packages/core-js/internals/async-iterator-wrap.js b/packages/core-js/internals/async-iterator-wrap.js new file mode 100644 index 000000000000..9580b5a10a2e --- /dev/null +++ b/packages/core-js/internals/async-iterator-wrap.js @@ -0,0 +1,6 @@ +var call = require('../internals/function-call'); +var createAsyncIteratorProxy = require('../internals/async-iterator-create-proxy'); + +module.exports = createAsyncIteratorProxy(function () { + return call(this.next, this.iterator); +}, true); diff --git a/packages/core-js/internals/iterator-create-proxy.js b/packages/core-js/internals/iterator-create-proxy.js index e5137ba45d2f..d85fe1bb3a50 100644 --- a/packages/core-js/internals/iterator-create-proxy.js +++ b/packages/core-js/internals/iterator-create-proxy.js @@ -8,53 +8,74 @@ var wellKnownSymbol = require('../internals/well-known-symbol'); var InternalStateModule = require('../internals/internal-state'); var getMethod = require('../internals/get-method'); var IteratorPrototype = require('../internals/iterators-core').IteratorPrototype; +var iteratorClose = require('../internals/iterator-close'); -var ITERATOR_PROXY = 'IteratorProxy'; +var ITERATOR_HELPER = 'IteratorHelper'; +var WRAP_FOR_VALID_ITERATOR = 'WrapForValidIterator'; var setInternalState = InternalStateModule.set; -var getInternalState = InternalStateModule.getterFor(ITERATOR_PROXY); var TO_STRING_TAG = wellKnownSymbol('toStringTag'); -module.exports = function (nextHandler, IS_ITERATOR) { - var IteratorProxy = function Iterator(record, state) { - if (state) { - state.iterator = record.iterator; - state.next = record.next; - } else state = record; - state.type = ITERATOR_PROXY; - state.done = false; - state.ignoreArg = !IS_ITERATOR; - setInternalState(this, state); - }; +var createIteratorProxyPrototype = function (IS_ITERATOR) { + var ITERATOR_PROXY = IS_ITERATOR ? WRAP_FOR_VALID_ITERATOR : ITERATOR_HELPER; - IteratorProxy.prototype = defineBuiltIns(create(IteratorPrototype), { - next: function next(arg) { + var getInternalState = InternalStateModule.getterFor(ITERATOR_PROXY); + + var IteratorProxyPrototype = defineBuiltIns(create(IteratorPrototype), { + next: function next() { var state = getInternalState(this); - var args = arguments.length ? [state.ignoreArg ? undefined : arg] : IS_ITERATOR ? [] : [undefined]; - state.ignoreArg = false; - var result = state.done ? undefined : call(nextHandler, state, args); - return { done: state.done, value: result }; + // for simplification: + // for `%WrapForValidIteratorPrototype%.next` our `nextHandler` returns `IterResultObject` + // for `%IteratorHelperPrototype%.next` - just a value + if (IS_ITERATOR) return state.nextHandler(); + try { + var result = state.done ? undefined : state.nextHandler(); + return { done: state.done, value: result }; + } catch (error) { + state.done = true; + throw error; + } }, - 'return': function (value) { + 'return': function () { var state = getInternalState(this); var iterator = state.iterator; + var innerIterator = state.innerIterator; state.done = true; + if (innerIterator) try { + iteratorClose(innerIterator, 'return'); + } catch (error) { + return iteratorClose(iterator, 'throw', error); + } var $$return = getMethod(iterator, 'return'); - return { done: true, value: $$return ? anObject(call($$return, iterator, value)).value : value }; - }, - 'throw': function (value) { - var state = getInternalState(this); - var iterator = state.iterator; - state.done = true; - var $$throw = getMethod(iterator, 'throw'); - if ($$throw) return call($$throw, iterator, value); - throw value; + return { done: true, value: $$return ? anObject(call($$return, iterator)).value : undefined }; } }); if (!IS_ITERATOR) { - createNonEnumerableProperty(IteratorProxy.prototype, TO_STRING_TAG, 'Generator'); + createNonEnumerableProperty(IteratorProxyPrototype, TO_STRING_TAG, 'Iterator Helper'); } + return IteratorProxyPrototype; +}; + +var IteratorHelperPrototype = createIteratorProxyPrototype(false); +var WrapForValidIteratorPrototype = createIteratorProxyPrototype(true); + +module.exports = function (nextHandler, IS_ITERATOR) { + var ITERATOR_PROXY = IS_ITERATOR ? WRAP_FOR_VALID_ITERATOR : ITERATOR_HELPER; + + var IteratorProxy = function Iterator(record, state) { + if (state) { + state.iterator = record.iterator; + state.next = record.next; + } else state = record; + state.type = ITERATOR_PROXY; + state.nextHandler = nextHandler; + state.done = false; + setInternalState(this, state); + }; + + IteratorProxy.prototype = IS_ITERATOR ? WrapForValidIteratorPrototype : IteratorHelperPrototype; + return IteratorProxy; }; diff --git a/packages/core-js/internals/iterator-indexed.js b/packages/core-js/internals/iterator-indexed.js new file mode 100644 index 000000000000..1a64ec7c486c --- /dev/null +++ b/packages/core-js/internals/iterator-indexed.js @@ -0,0 +1,18 @@ +'use strict'; +// https://github.com/tc39/proposal-iterator-helpers +var call = require('../internals/function-call'); +var anObject = require('../internals/an-object'); +var getIteratorDirect = require('../internals/get-iterator-direct'); +var createIteratorProxy = require('../internals/iterator-create-proxy'); + +var IteratorProxy = createIteratorProxy(function () { + var result = anObject(call(this.next, this.iterator)); + var done = this.done = !!result.done; + if (!done) return [this.index++, result.value]; +}); + +module.exports = function indexed() { + return new IteratorProxy(getIteratorDirect(this), { + index: 0 + }); +}; diff --git a/packages/core-js/internals/not-a-nan.js b/packages/core-js/internals/not-a-nan.js new file mode 100644 index 000000000000..cfb63bba3c4d --- /dev/null +++ b/packages/core-js/internals/not-a-nan.js @@ -0,0 +1,7 @@ +var $RangeError = RangeError; + +module.exports = function (it) { + // eslint-disable-next-line no-self-compare -- NaN check + if (it === it) return it; + throw $RangeError('NaN is not allowed'); +}; diff --git a/packages/core-js/modules/esnext.async-iterator.as-indexed-pairs.js b/packages/core-js/modules/esnext.async-iterator.as-indexed-pairs.js index 8f36b535e914..da3de5b08f06 100644 --- a/packages/core-js/modules/esnext.async-iterator.as-indexed-pairs.js +++ b/packages/core-js/modules/esnext.async-iterator.as-indexed-pairs.js @@ -1,28 +1,8 @@ -'use strict'; +// TODO: Remove from `core-js@4` // https://github.com/tc39/proposal-iterator-helpers var $ = require('../internals/export'); -var apply = require('../internals/function-apply'); -var anObject = require('../internals/an-object'); -var getIteratorDirect = require('../internals/get-iterator-direct'); -var createAsyncIteratorProxy = require('../internals/async-iterator-create-proxy'); +var indexed = require('../internals/async-iterator-indexed'); -var AsyncIteratorProxy = createAsyncIteratorProxy(function (Promise, args) { - var state = this; - var iterator = state.iterator; - - return Promise.resolve(anObject(apply(state.next, iterator, args))).then(function (step) { - if (anObject(step).done) { - state.done = true; - return { done: true, value: undefined }; - } - return { done: false, value: [state.index++, step.value] }; - }); -}); - -$({ target: 'AsyncIterator', proto: true, real: true, forced: true }, { - asIndexedPairs: function asIndexedPairs() { - return new AsyncIteratorProxy(getIteratorDirect(this), { - index: 0 - }); - } +$({ target: 'AsyncIterator', name: 'indexed', proto: true, real: true, forced: true }, { + asIndexedPairs: indexed }); diff --git a/packages/core-js/modules/esnext.async-iterator.drop.js b/packages/core-js/modules/esnext.async-iterator.drop.js index be40c4c2da31..1ed0a4ea08e1 100644 --- a/packages/core-js/modules/esnext.async-iterator.drop.js +++ b/packages/core-js/modules/esnext.async-iterator.drop.js @@ -1,21 +1,25 @@ 'use strict'; // https://github.com/tc39/proposal-iterator-helpers var $ = require('../internals/export'); -var apply = require('../internals/function-apply'); +var call = require('../internals/function-call'); var anObject = require('../internals/an-object'); var getIteratorDirect = require('../internals/get-iterator-direct'); +var notANaN = require('../internals/not-a-nan'); var toPositiveInteger = require('../internals/to-positive-integer'); var createAsyncIteratorProxy = require('../internals/async-iterator-create-proxy'); -var AsyncIteratorProxy = createAsyncIteratorProxy(function (Promise, args) { +var AsyncIteratorProxy = createAsyncIteratorProxy(function (Promise) { var state = this; return new Promise(function (resolve, reject) { + var doneAndReject = function (error) { + state.done = true; + reject(error); + }; + var loop = function () { try { - Promise.resolve( - anObject(apply(state.next, state.iterator, state.remaining ? [] : args)) - ).then(function (step) { + Promise.resolve(anObject(call(state.next, state.iterator))).then(function (step) { try { if (anObject(step).done) { state.done = true; @@ -24,9 +28,9 @@ var AsyncIteratorProxy = createAsyncIteratorProxy(function (Promise, args) { state.remaining--; loop(); } else resolve({ done: false, value: step.value }); - } catch (err) { reject(err); } - }, reject); - } catch (error) { reject(error); } + } catch (err) { doneAndReject(err); } + }, doneAndReject); + } catch (error) { doneAndReject(error); } }; loop(); @@ -36,7 +40,7 @@ var AsyncIteratorProxy = createAsyncIteratorProxy(function (Promise, args) { $({ target: 'AsyncIterator', proto: true, real: true, forced: true }, { drop: function drop(limit) { return new AsyncIteratorProxy(getIteratorDirect(this), { - remaining: toPositiveInteger(limit) + remaining: toPositiveInteger(notANaN(+limit)) }); } }); diff --git a/packages/core-js/modules/esnext.async-iterator.filter.js b/packages/core-js/modules/esnext.async-iterator.filter.js index e9a250090a3c..7ba993d02bbe 100644 --- a/packages/core-js/modules/esnext.async-iterator.filter.js +++ b/packages/core-js/modules/esnext.async-iterator.filter.js @@ -1,33 +1,46 @@ 'use strict'; // https://github.com/tc39/proposal-iterator-helpers var $ = require('../internals/export'); -var apply = require('../internals/function-apply'); +var call = require('../internals/function-call'); var aCallable = require('../internals/a-callable'); var anObject = require('../internals/an-object'); var getIteratorDirect = require('../internals/get-iterator-direct'); var createAsyncIteratorProxy = require('../internals/async-iterator-create-proxy'); +var closeAsyncIteration = require('../internals/async-iterator-close'); -var AsyncIteratorProxy = createAsyncIteratorProxy(function (Promise, args) { +var AsyncIteratorProxy = createAsyncIteratorProxy(function (Promise) { var state = this; + var iterator = state.iterator; var filterer = state.filterer; return new Promise(function (resolve, reject) { + var doneAndReject = function (error) { + state.done = true; + reject(error); + }; + + var ifAbruptCloseAsyncIterator = function (error) { + closeAsyncIteration(iterator, doneAndReject, error, doneAndReject); + }; + var loop = function () { try { - Promise.resolve(anObject(apply(state.next, state.iterator, args))).then(function (step) { + Promise.resolve(anObject(call(state.next, iterator))).then(function (step) { try { if (anObject(step).done) { state.done = true; resolve({ done: true, value: undefined }); } else { var value = step.value; - Promise.resolve(filterer(value)).then(function (selected) { - selected ? resolve({ done: false, value: value }) : loop(); - }, reject); + try { + Promise.resolve(filterer(value)).then(function (selected) { + selected ? resolve({ done: false, value: value }) : loop(); + }, ifAbruptCloseAsyncIterator); + } catch (error3) { ifAbruptCloseAsyncIterator(error3); } } - } catch (err) { reject(err); } - }, reject); - } catch (error) { reject(error); } + } catch (error2) { doneAndReject(error2); } + }, doneAndReject); + } catch (error) { doneAndReject(error); } }; loop(); diff --git a/packages/core-js/modules/esnext.async-iterator.flat-map.js b/packages/core-js/modules/esnext.async-iterator.flat-map.js index ad802137d762..dd70ef17d474 100644 --- a/packages/core-js/modules/esnext.async-iterator.flat-map.js +++ b/packages/core-js/modules/esnext.async-iterator.flat-map.js @@ -7,32 +7,46 @@ var anObject = require('../internals/an-object'); var getIteratorDirect = require('../internals/get-iterator-direct'); var createAsyncIteratorProxy = require('../internals/async-iterator-create-proxy'); var getAsyncIterator = require('../internals/get-async-iterator'); +var closeAsyncIteration = require('../internals/async-iterator-close'); var AsyncIteratorProxy = createAsyncIteratorProxy(function (Promise) { var state = this; + var iterator = state.iterator; var mapper = state.mapper; var innerIterator; return new Promise(function (resolve, reject) { + var doneAndReject = function (error) { + state.done = true; + reject(error); + }; + + var ifAbruptCloseAsyncIterator = function (error) { + closeAsyncIteration(iterator, doneAndReject, error, doneAndReject); + }; + var outerLoop = function () { try { - Promise.resolve(anObject(call(state.next, state.iterator))).then(function (step) { + Promise.resolve(anObject(call(state.next, iterator))).then(function (step) { try { if (anObject(step).done) { state.done = true; resolve({ done: true, value: undefined }); } else { - Promise.resolve(mapper(step.value)).then(function (mapped) { - try { - state.innerIterator = innerIterator = getAsyncIterator(mapped); - state.innerNext = aCallable(innerIterator.next); - return innerLoop(); - } catch (error2) { reject(error2); } - }, reject); + var value = step.value; + try { + Promise.resolve(mapper(value)).then(function (mapped) { + try { + state.innerIterator = innerIterator = getAsyncIterator(mapped); + state.innerNext = aCallable(innerIterator.next); + innerLoop(); + } catch (error4) { ifAbruptCloseAsyncIterator(error4); } + }, ifAbruptCloseAsyncIterator); + } catch (error3) { ifAbruptCloseAsyncIterator(error3); } } - } catch (error1) { reject(error1); } - }, reject); - } catch (error) { reject(error); } + } catch (error2) { doneAndReject(error2); } + }, doneAndReject); + } catch (error) { doneAndReject(error); } }; var innerLoop = function () { @@ -44,9 +58,9 @@ var AsyncIteratorProxy = createAsyncIteratorProxy(function (Promise) { state.innerIterator = state.innerNext = null; outerLoop(); } else resolve({ done: false, value: result.value }); - } catch (error1) { reject(error1); } - }, reject); - } catch (error) { reject(error); } + } catch (error1) { ifAbruptCloseAsyncIterator(error1); } + }, ifAbruptCloseAsyncIterator); + } catch (error) { ifAbruptCloseAsyncIterator(error); } } else outerLoop(); }; diff --git a/packages/core-js/modules/esnext.async-iterator.from.js b/packages/core-js/modules/esnext.async-iterator.from.js index 354922f64e4f..bea7c28619d5 100644 --- a/packages/core-js/modules/esnext.async-iterator.from.js +++ b/packages/core-js/modules/esnext.async-iterator.from.js @@ -1,11 +1,8 @@ // https://github.com/tc39/proposal-iterator-helpers var $ = require('../internals/export'); -var apply = require('../internals/function-apply'); -var anObject = require('../internals/an-object'); var toObject = require('../internals/to-object'); var isPrototypeOf = require('../internals/object-is-prototype-of'); var AsyncIteratorPrototype = require('../internals/async-iterator-prototype'); -var createAsyncIteratorProxy = require('../internals/async-iterator-create-proxy'); var getAsyncIterator = require('../internals/get-async-iterator'); var getIterator = require('../internals/get-iterator'); var getIteratorDirect = require('../internals/get-iterator-direct'); @@ -13,13 +10,10 @@ var getIteratorMethod = require('../internals/get-iterator-method'); var getMethod = require('../internals/get-method'); var wellKnownSymbol = require('../internals/well-known-symbol'); var AsyncFromSyncIterator = require('../internals/async-from-sync-iterator'); +var WrapAsyncIterator = require('../internals/async-iterator-wrap'); var ASYNC_ITERATOR = wellKnownSymbol('asyncIterator'); -var AsyncIteratorProxy = createAsyncIteratorProxy(function (Promise, args) { - return anObject(apply(this.next, this.iterator, args)); -}, true); - $({ target: 'AsyncIterator', stat: true, forced: true }, { from: function from(O) { var object = toObject(O); @@ -31,8 +25,8 @@ $({ target: 'AsyncIterator', stat: true, forced: true }, { } if (iterator === undefined) { usingIterator = getIteratorMethod(object); - if (usingIterator) return new AsyncFromSyncIterator(getIterator(object, usingIterator)); + if (usingIterator) iterator = new AsyncFromSyncIterator(getIterator(object, usingIterator)); } - return new AsyncIteratorProxy(getIteratorDirect(iterator !== undefined ? iterator : object)); + return new WrapAsyncIterator(getIteratorDirect(iterator !== undefined ? iterator : object)); } }); diff --git a/packages/core-js/modules/esnext.async-iterator.indexed.js b/packages/core-js/modules/esnext.async-iterator.indexed.js new file mode 100644 index 000000000000..5be9d38bcea5 --- /dev/null +++ b/packages/core-js/modules/esnext.async-iterator.indexed.js @@ -0,0 +1,7 @@ +// https://github.com/tc39/proposal-iterator-helpers +var $ = require('../internals/export'); +var indexed = require('../internals/async-iterator-indexed'); + +$({ target: 'AsyncIterator', proto: true, real: true, forced: true }, { + indexed: indexed +}); diff --git a/packages/core-js/modules/esnext.async-iterator.map.js b/packages/core-js/modules/esnext.async-iterator.map.js index b4cfb85475b1..76f9334bab3f 100644 --- a/packages/core-js/modules/esnext.async-iterator.map.js +++ b/packages/core-js/modules/esnext.async-iterator.map.js @@ -1,24 +1,43 @@ 'use strict'; // https://github.com/tc39/proposal-iterator-helpers var $ = require('../internals/export'); -var apply = require('../internals/function-apply'); +var call = require('../internals/function-call'); var aCallable = require('../internals/a-callable'); var anObject = require('../internals/an-object'); var getIteratorDirect = require('../internals/get-iterator-direct'); var createAsyncIteratorProxy = require('../internals/async-iterator-create-proxy'); +var closeAsyncIteration = require('../internals/async-iterator-close'); -var AsyncIteratorProxy = createAsyncIteratorProxy(function (Promise, args) { +var AsyncIteratorProxy = createAsyncIteratorProxy(function (Promise) { var state = this; + var iterator = state.iterator; var mapper = state.mapper; - return Promise.resolve(anObject(apply(state.next, state.iterator, args))).then(function (step) { - if (anObject(step).done) { + return new Promise(function (resolve, reject) { + var doneAndReject = function (error) { state.done = true; - return { done: true, value: undefined }; - } - return Promise.resolve(mapper(step.value)).then(function (value) { - return { done: false, value: value }; - }); + reject(error); + }; + + var ifAbruptCloseAsyncIterator = function (error) { + closeAsyncIteration(iterator, doneAndReject, error, doneAndReject); + }; + + Promise.resolve(anObject(call(state.next, iterator))).then(function (step) { + try { + if (anObject(step).done) { + state.done = true; + resolve({ done: true, value: undefined }); + } else { + var value = step.value; + try { + Promise.resolve(mapper(value)).then(function (mapped) { + resolve({ done: false, value: mapped }); + }, ifAbruptCloseAsyncIterator); + } catch (error2) { ifAbruptCloseAsyncIterator(error2); } + } + } catch (error) { doneAndReject(error); } + }, doneAndReject); }); }); diff --git a/packages/core-js/modules/esnext.async-iterator.reduce.js b/packages/core-js/modules/esnext.async-iterator.reduce.js index 7066f2feb158..528498359c92 100644 --- a/packages/core-js/modules/esnext.async-iterator.reduce.js +++ b/packages/core-js/modules/esnext.async-iterator.reduce.js @@ -6,6 +6,7 @@ var aCallable = require('../internals/a-callable'); var anObject = require('../internals/an-object'); var getBuiltIn = require('../internals/get-built-in'); var getIteratorDirect = require('../internals/get-iterator-direct'); +var closeAsyncIteration = require('../internals/async-iterator-close'); var Promise = getBuiltIn('Promise'); var $TypeError = TypeError; @@ -20,6 +21,10 @@ $({ target: 'AsyncIterator', proto: true, real: true, forced: true }, { aCallable(reducer); return new Promise(function (resolve, reject) { + var ifAbruptCloseAsyncIterator = function (error) { + closeAsyncIteration(iterator, reject, error, reject); + }; + var loop = function () { try { Promise.resolve(anObject(call(next, iterator))).then(function (step) { @@ -32,14 +37,14 @@ $({ target: 'AsyncIterator', proto: true, real: true, forced: true }, { noInitial = false; accumulator = value; loop(); - } else { + } else try { Promise.resolve(reducer(accumulator, value)).then(function (result) { accumulator = result; loop(); - }, reject); - } + }, ifAbruptCloseAsyncIterator); + } catch (error3) { ifAbruptCloseAsyncIterator(error3); } } - } catch (err) { reject(err); } + } catch (error2) { reject(error2); } }, reject); } catch (error) { reject(error); } }; diff --git a/packages/core-js/modules/esnext.async-iterator.take.js b/packages/core-js/modules/esnext.async-iterator.take.js index 2f62c212845f..6f31fbfc0773 100644 --- a/packages/core-js/modules/esnext.async-iterator.take.js +++ b/packages/core-js/modules/esnext.async-iterator.take.js @@ -1,32 +1,43 @@ 'use strict'; // https://github.com/tc39/proposal-iterator-helpers var $ = require('../internals/export'); -var apply = require('../internals/function-apply'); var call = require('../internals/function-call'); +var anObject = require('../internals/an-object'); var getIteratorDirect = require('../internals/get-iterator-direct'); +var notANaN = require('../internals/not-a-nan'); var toPositiveInteger = require('../internals/to-positive-integer'); var createAsyncIteratorProxy = require('../internals/async-iterator-create-proxy'); -var AsyncIteratorProxy = createAsyncIteratorProxy(function (Promise, args) { - var iterator = this.iterator; - var returnMethod, result; - if (!this.remaining--) { - result = { done: true, value: undefined }; - this.done = true; +var AsyncIteratorProxy = createAsyncIteratorProxy(function (Promise) { + var state = this; + var iterator = state.iterator; + var returnMethod; + + if (!state.remaining--) { + var resultDone = { done: true, value: undefined }; + state.done = true; returnMethod = iterator['return']; if (returnMethod !== undefined) { - return Promise.resolve(call(returnMethod, iterator)).then(function () { - return result; + return Promise.resolve(call(returnMethod, iterator, undefined)).then(function () { + return resultDone; }); } - return result; - } return apply(this.next, iterator, args); + return resultDone; + } return Promise.resolve(call(state.next, iterator)).then(function (step) { + if (anObject(step).done) { + state.done = true; + return { done: true, value: undefined }; + } return { done: false, value: step.value }; + }).then(null, function (error) { + state.done = true; + throw error; + }); }); $({ target: 'AsyncIterator', proto: true, real: true, forced: true }, { take: function take(limit) { return new AsyncIteratorProxy(getIteratorDirect(this), { - remaining: toPositiveInteger(limit) + remaining: toPositiveInteger(notANaN(+limit)) }); } }); diff --git a/packages/core-js/modules/esnext.iterator.as-indexed-pairs.js b/packages/core-js/modules/esnext.iterator.as-indexed-pairs.js index 33f16d7e3456..2e241af1a8bc 100644 --- a/packages/core-js/modules/esnext.iterator.as-indexed-pairs.js +++ b/packages/core-js/modules/esnext.iterator.as-indexed-pairs.js @@ -1,21 +1,8 @@ -'use strict'; +// TODO: Remove from `core-js@4` // https://github.com/tc39/proposal-iterator-helpers var $ = require('../internals/export'); -var apply = require('../internals/function-apply'); -var anObject = require('../internals/an-object'); -var getIteratorDirect = require('../internals/get-iterator-direct'); -var createIteratorProxy = require('../internals/iterator-create-proxy'); +var indexed = require('../internals/iterator-indexed'); -var IteratorProxy = createIteratorProxy(function (args) { - var result = anObject(apply(this.next, this.iterator, args)); - var done = this.done = !!result.done; - if (!done) return [this.index++, result.value]; -}); - -$({ target: 'Iterator', proto: true, real: true, forced: true }, { - asIndexedPairs: function asIndexedPairs() { - return new IteratorProxy(getIteratorDirect(this), { - index: 0 - }); - } +$({ target: 'Iterator', name: 'indexed', proto: true, real: true, forced: true }, { + asIndexedPairs: indexed }); diff --git a/packages/core-js/modules/esnext.iterator.drop.js b/packages/core-js/modules/esnext.iterator.drop.js index 888110bcdd99..8737e8137404 100644 --- a/packages/core-js/modules/esnext.iterator.drop.js +++ b/packages/core-js/modules/esnext.iterator.drop.js @@ -1,14 +1,14 @@ 'use strict'; // https://github.com/tc39/proposal-iterator-helpers var $ = require('../internals/export'); -var apply = require('../internals/function-apply'); var call = require('../internals/function-call'); var anObject = require('../internals/an-object'); var getIteratorDirect = require('../internals/get-iterator-direct'); +var notANaN = require('../internals/not-a-nan'); var toPositiveInteger = require('../internals/to-positive-integer'); var createIteratorProxy = require('../internals/iterator-create-proxy'); -var IteratorProxy = createIteratorProxy(function (args) { +var IteratorProxy = createIteratorProxy(function () { var iterator = this.iterator; var next = this.next; var result, done; @@ -18,7 +18,7 @@ var IteratorProxy = createIteratorProxy(function (args) { done = this.done = !!result.done; if (done) return; } - result = anObject(apply(next, iterator, args)); + result = anObject(call(next, iterator)); done = this.done = !!result.done; if (!done) return result.value; }); @@ -26,7 +26,7 @@ var IteratorProxy = createIteratorProxy(function (args) { $({ target: 'Iterator', proto: true, real: true, forced: true }, { drop: function drop(limit) { return new IteratorProxy(getIteratorDirect(this), { - remaining: toPositiveInteger(limit) + remaining: toPositiveInteger(notANaN(+limit)) }); } }); diff --git a/packages/core-js/modules/esnext.iterator.filter.js b/packages/core-js/modules/esnext.iterator.filter.js index b56aa2de15b2..d3205885065f 100644 --- a/packages/core-js/modules/esnext.iterator.filter.js +++ b/packages/core-js/modules/esnext.iterator.filter.js @@ -1,20 +1,20 @@ 'use strict'; // https://github.com/tc39/proposal-iterator-helpers var $ = require('../internals/export'); -var apply = require('../internals/function-apply'); +var call = require('../internals/function-call'); var aCallable = require('../internals/a-callable'); var anObject = require('../internals/an-object'); var getIteratorDirect = require('../internals/get-iterator-direct'); var createIteratorProxy = require('../internals/iterator-create-proxy'); var callWithSafeIterationClosing = require('../internals/call-with-safe-iteration-closing'); -var IteratorProxy = createIteratorProxy(function (args) { +var IteratorProxy = createIteratorProxy(function () { var iterator = this.iterator; var filterer = this.filterer; var next = this.next; var result, done, value; while (true) { - result = anObject(apply(next, iterator, args)); + result = anObject(call(next, iterator)); done = this.done = !!result.done; if (done) return; value = result.value; diff --git a/packages/core-js/modules/esnext.iterator.flat-map.js b/packages/core-js/modules/esnext.iterator.flat-map.js index 56b1fe1bc658..e30abcc4a142 100644 --- a/packages/core-js/modules/esnext.iterator.flat-map.js +++ b/packages/core-js/modules/esnext.iterator.flat-map.js @@ -17,17 +17,17 @@ var IteratorProxy = createIteratorProxy(function () { var result, mapped, iteratorMethod, innerIterator; while (true) { - try { - if (innerIterator = this.innerIterator) { - result = anObject(call(this.innerNext, innerIterator)); - if (!result.done) return result.value; - this.innerIterator = this.innerNext = null; - } + if (innerIterator = this.innerIterator) try { + result = anObject(call(this.innerNext, innerIterator)); + if (!result.done) return result.value; + this.innerIterator = this.innerNext = null; + } catch (error) { iteratorClose(iterator, 'throw', error); } - result = anObject(call(this.next, iterator)); + result = anObject(call(this.next, iterator)); - if (this.done = !!result.done) return; + if (this.done = !!result.done) return; + try { mapped = mapper(result.value); iteratorMethod = getIteratorMethod(mapped); @@ -37,9 +37,7 @@ var IteratorProxy = createIteratorProxy(function () { this.innerIterator = innerIterator = anObject(call(iteratorMethod, mapped)); this.innerNext = aCallable(innerIterator.next); - } catch (error) { - iteratorClose(iterator, 'throw', error); - } + } catch (error) { iteratorClose(iterator, 'throw', error); } } }); diff --git a/packages/core-js/modules/esnext.iterator.from.js b/packages/core-js/modules/esnext.iterator.from.js index dd09294701f0..17a25ab1ec84 100644 --- a/packages/core-js/modules/esnext.iterator.from.js +++ b/packages/core-js/modules/esnext.iterator.from.js @@ -1,7 +1,6 @@ // https://github.com/tc39/proposal-iterator-helpers var $ = require('../internals/export'); -var apply = require('../internals/function-apply'); -var anObject = require('../internals/an-object'); +var call = require('../internals/function-call'); var toObject = require('../internals/to-object'); var isPrototypeOf = require('../internals/object-is-prototype-of'); var IteratorPrototype = require('../internals/iterators-core').IteratorPrototype; @@ -10,10 +9,8 @@ var getIterator = require('../internals/get-iterator'); var getIteratorDirect = require('../internals/get-iterator-direct'); var getIteratorMethod = require('../internals/get-iterator-method'); -var IteratorProxy = createIteratorProxy(function (args) { - var result = anObject(apply(this.next, this.iterator, args)); - var done = this.done = !!result.done; - if (!done) return result.value; +var IteratorProxy = createIteratorProxy(function () { + return call(this.next, this.iterator); }, true); $({ target: 'Iterator', stat: true, forced: true }, { diff --git a/packages/core-js/modules/esnext.iterator.indexed.js b/packages/core-js/modules/esnext.iterator.indexed.js new file mode 100644 index 000000000000..b68c9fc12bd9 --- /dev/null +++ b/packages/core-js/modules/esnext.iterator.indexed.js @@ -0,0 +1,7 @@ +// https://github.com/tc39/proposal-iterator-helpers +var $ = require('../internals/export'); +var indexed = require('../internals/iterator-indexed'); + +$({ target: 'Iterator', proto: true, real: true, forced: true }, { + indexed: indexed +}); diff --git a/packages/core-js/modules/esnext.iterator.map.js b/packages/core-js/modules/esnext.iterator.map.js index 1d3a49f969a6..c1b4b1963ab2 100644 --- a/packages/core-js/modules/esnext.iterator.map.js +++ b/packages/core-js/modules/esnext.iterator.map.js @@ -1,16 +1,16 @@ 'use strict'; // https://github.com/tc39/proposal-iterator-helpers var $ = require('../internals/export'); -var apply = require('../internals/function-apply'); +var call = require('../internals/function-call'); var aCallable = require('../internals/a-callable'); var anObject = require('../internals/an-object'); var getIteratorDirect = require('../internals/get-iterator-direct'); var createIteratorProxy = require('../internals/iterator-create-proxy'); var callWithSafeIterationClosing = require('../internals/call-with-safe-iteration-closing'); -var IteratorProxy = createIteratorProxy(function (args) { +var IteratorProxy = createIteratorProxy(function () { var iterator = this.iterator; - var result = anObject(apply(this.next, iterator, args)); + var result = anObject(call(this.next, iterator)); var done = this.done = !!result.done; if (!done) return callWithSafeIterationClosing(iterator, this.mapper, result.value); }); diff --git a/packages/core-js/modules/esnext.iterator.take.js b/packages/core-js/modules/esnext.iterator.take.js index 5ae6cda60c91..05c5e46b51de 100644 --- a/packages/core-js/modules/esnext.iterator.take.js +++ b/packages/core-js/modules/esnext.iterator.take.js @@ -1,20 +1,21 @@ 'use strict'; // https://github.com/tc39/proposal-iterator-helpers var $ = require('../internals/export'); -var apply = require('../internals/function-apply'); +var call = require('../internals/function-call'); var anObject = require('../internals/an-object'); var getIteratorDirect = require('../internals/get-iterator-direct'); +var notANaN = require('../internals/not-a-nan'); var toPositiveInteger = require('../internals/to-positive-integer'); var createIteratorProxy = require('../internals/iterator-create-proxy'); var iteratorClose = require('../internals/iterator-close'); -var IteratorProxy = createIteratorProxy(function (args) { +var IteratorProxy = createIteratorProxy(function () { var iterator = this.iterator; if (!this.remaining--) { this.done = true; return iteratorClose(iterator, 'normal', undefined); } - var result = anObject(apply(this.next, iterator, args)); + var result = anObject(call(this.next, iterator)); var done = this.done = !!result.done; if (!done) return result.value; }); @@ -22,7 +23,7 @@ var IteratorProxy = createIteratorProxy(function (args) { $({ target: 'Iterator', proto: true, real: true, forced: true }, { take: function take(limit) { return new IteratorProxy(getIteratorDirect(this), { - remaining: toPositiveInteger(limit) + remaining: toPositiveInteger(notANaN(+limit)) }); } }); diff --git a/packages/core-js/modules/esnext.iterator.to-async.js b/packages/core-js/modules/esnext.iterator.to-async.js index 6dfb1b80c1ec..d3ccdcf396b2 100644 --- a/packages/core-js/modules/esnext.iterator.to-async.js +++ b/packages/core-js/modules/esnext.iterator.to-async.js @@ -2,9 +2,11 @@ // https://github.com/tc39/proposal-iterator-helpers var $ = require('../internals/export'); var AsyncFromSyncIterator = require('../internals/async-from-sync-iterator'); +var WrapAsyncIterator = require('../internals/async-iterator-wrap'); +var getIteratorDirect = require('../internals/get-iterator-direct'); $({ target: 'Iterator', proto: true, real: true, forced: true }, { toAsync: function toAsync() { - return new AsyncFromSyncIterator(this); + return new WrapAsyncIterator(getIteratorDirect(new AsyncFromSyncIterator(this))); } }); diff --git a/packages/core-js/proposals/iterator-helpers.js b/packages/core-js/proposals/iterator-helpers.js index a7b1355abe82..a08daf9506fe 100644 --- a/packages/core-js/proposals/iterator-helpers.js +++ b/packages/core-js/proposals/iterator-helpers.js @@ -1,5 +1,6 @@ // https://github.com/tc39/proposal-iterator-helpers require('../modules/esnext.async-iterator.constructor'); +// TODO: remove from `core-js@4` require('../modules/esnext.async-iterator.as-indexed-pairs'); require('../modules/esnext.async-iterator.drop'); require('../modules/esnext.async-iterator.every'); @@ -8,12 +9,14 @@ require('../modules/esnext.async-iterator.find'); require('../modules/esnext.async-iterator.flat-map'); require('../modules/esnext.async-iterator.for-each'); require('../modules/esnext.async-iterator.from'); +require('../modules/esnext.async-iterator.indexed'); require('../modules/esnext.async-iterator.map'); require('../modules/esnext.async-iterator.reduce'); require('../modules/esnext.async-iterator.some'); require('../modules/esnext.async-iterator.take'); require('../modules/esnext.async-iterator.to-array'); require('../modules/esnext.iterator.constructor'); +// TODO: remove from `core-js@4` require('../modules/esnext.iterator.as-indexed-pairs'); require('../modules/esnext.iterator.drop'); require('../modules/esnext.iterator.every'); @@ -22,6 +25,7 @@ require('../modules/esnext.iterator.find'); require('../modules/esnext.iterator.flat-map'); require('../modules/esnext.iterator.for-each'); require('../modules/esnext.iterator.from'); +require('../modules/esnext.iterator.indexed'); require('../modules/esnext.iterator.map'); require('../modules/esnext.iterator.reduce'); require('../modules/esnext.iterator.some'); diff --git a/scripts/check-compat-tests.mjs b/scripts/check-compat-tests.mjs index 8a2b954b67c3..058a917856ec 100644 --- a/scripts/check-compat-tests.mjs +++ b/scripts/check-compat-tests.mjs @@ -19,6 +19,8 @@ const ignore = new Set([ 'esnext.array.group-by-to-map', 'esnext.array.last-index', 'esnext.array.last-item', + 'esnext.async-iterator.as-indexed-pairs', + 'esnext.iterator.as-indexed-pairs', 'esnext.map.update-or-insert', 'esnext.map.upsert', 'esnext.math.iaddh', diff --git a/tests/commonjs.mjs b/tests/commonjs.mjs index 74aef7ef7aa9..f648c4470e07 100644 --- a/tests/commonjs.mjs +++ b/tests/commonjs.mjs @@ -685,6 +685,7 @@ for (PATH of ['core-js-pure', 'core-js']) { ok(typeof load(NS, 'async-iterator/flat-map') == 'function'); ok(typeof load(NS, 'async-iterator/for-each') == 'function'); ok(typeof load(NS, 'async-iterator/from') == 'function'); + ok(typeof load(NS, 'async-iterator/indexed') == 'function'); ok(typeof load(NS, 'async-iterator/map') == 'function'); ok(typeof load(NS, 'async-iterator/reduce') == 'function'); ok(typeof load(NS, 'async-iterator/some') == 'function'); @@ -707,6 +708,7 @@ for (PATH of ['core-js-pure', 'core-js']) { ok(typeof load(NS, 'iterator/flat-map') == 'function'); ok(typeof load(NS, 'iterator/for-each') == 'function'); ok(typeof load(NS, 'iterator/from') == 'function'); + ok(typeof load(NS, 'iterator/indexed') == 'function'); ok(typeof load(NS, 'iterator/map') == 'function'); ok(typeof load(NS, 'iterator/reduce') == 'function'); ok(typeof load(NS, 'iterator/some') == 'function'); diff --git a/tests/compat/tests.js b/tests/compat/tests.js index b37ffd96b137..10c780cdff8b 100644 --- a/tests/compat/tests.js +++ b/tests/compat/tests.js @@ -1431,9 +1431,6 @@ GLOBAL.tests = { 'esnext.async-iterator.constructor': function () { return typeof AsyncIterator == 'function'; }, - 'esnext.async-iterator.as-indexed-pairs': function () { - return AsyncIterator.prototype.asIndexedPairs; - }, 'esnext.async-iterator.drop': function () { return AsyncIterator.prototype.drop; }, @@ -1455,6 +1452,9 @@ GLOBAL.tests = { 'esnext.async-iterator.from': function () { return AsyncIterator.from; }, + 'esnext.async-iterator.indexed': function () { + return AsyncIterator.prototype.indexed; + }, 'esnext.async-iterator.map': function () { return AsyncIterator.prototype.map; }, @@ -1496,9 +1496,6 @@ GLOBAL.tests = { && Iterator.prototype === Object.getPrototypeOf(Object.getPrototypeOf([].values())); } }, - 'esnext.iterator.as-indexed-pairs': function () { - return Iterator.prototype.asIndexedPairs; - }, 'esnext.iterator.drop': function () { return Iterator.prototype.drop; }, @@ -1520,6 +1517,9 @@ GLOBAL.tests = { 'esnext.iterator.from': function () { return Iterator.from; }, + 'esnext.iterator.indexed': function () { + return Iterator.prototype.indexed; + }, 'esnext.iterator.map': function () { return Iterator.prototype.map; }, diff --git a/tests/pure/esnext.async-iterator.drop.js b/tests/pure/esnext.async-iterator.drop.js index 4eb50a150cf4..51786e74eb23 100644 --- a/tests/pure/esnext.async-iterator.drop.js +++ b/tests/pure/esnext.async-iterator.drop.js @@ -3,7 +3,7 @@ import { createIterator } from '../helpers/helpers'; import AsyncIterator from 'core-js-pure/full/async-iterator'; QUnit.test('AsyncIterator#drop', assert => { - assert.expect(12); + assert.expect(13); const async = assert.async(); const { drop } = AsyncIterator.prototype; @@ -29,4 +29,5 @@ QUnit.test('AsyncIterator#drop', assert => { assert.throws(() => drop.call({}, 1), TypeError); assert.throws(() => drop.call([], 1), TypeError); assert.throws(() => drop.call(createIterator([1, 2, 3]), -1), RangeError, 'negative'); + assert.throws(() => drop.call(createIterator([1, 2, 3]), NaN), RangeError, 'NaN'); }); diff --git a/tests/pure/esnext.async-iterator.indexed.js b/tests/pure/esnext.async-iterator.indexed.js new file mode 100644 index 000000000000..d66bf5c9e802 --- /dev/null +++ b/tests/pure/esnext.async-iterator.indexed.js @@ -0,0 +1,23 @@ +import { createIterator } from '../helpers/helpers'; + +import AsyncIterator from 'core-js-pure/full/async-iterator'; + +QUnit.test('AsyncIterator#indexed', assert => { + assert.expect(8); + const async = assert.async(); + const { indexed } = AsyncIterator.prototype; + + assert.isFunction(indexed); + assert.arity(indexed, 0); + assert.nonEnumerable(AsyncIterator.prototype, 'indexed'); + + indexed.call(createIterator(['a', 'b', 'c'])).toArray().then(it => { + assert.same(it.toString(), '0,a,1,b,2,c', 'basic functionality'); + async(); + }); + + assert.throws(() => indexed.call(undefined, () => { /* empty */ }), TypeError); + assert.throws(() => indexed.call(null, () => { /* empty */ }), TypeError); + assert.throws(() => indexed.call({}, () => { /* empty */ }), TypeError); + assert.throws(() => indexed.call([], () => { /* empty */ }), TypeError); +}); diff --git a/tests/pure/esnext.async-iterator.take.js b/tests/pure/esnext.async-iterator.take.js index dc5c0a561c5e..927c7d85fd54 100644 --- a/tests/pure/esnext.async-iterator.take.js +++ b/tests/pure/esnext.async-iterator.take.js @@ -3,7 +3,7 @@ import { createIterator } from '../helpers/helpers'; import AsyncIterator from 'core-js-pure/full/async-iterator'; QUnit.test('AsyncIterator#take', assert => { - assert.expect(12); + assert.expect(13); const async = assert.async(); const { take } = AsyncIterator.prototype; @@ -29,4 +29,5 @@ QUnit.test('AsyncIterator#take', assert => { assert.throws(() => take.call({}, 1), TypeError); assert.throws(() => take.call([], 1), TypeError); assert.throws(() => take.call(createIterator([1, 2, 3]), -1), RangeError, 'negative'); + assert.throws(() => take.call(createIterator([1, 2, 3]), NaN), RangeError, 'NaN'); }); diff --git a/tests/pure/esnext.iterator.drop.js b/tests/pure/esnext.iterator.drop.js index 83b086156665..25cf67ed0165 100644 --- a/tests/pure/esnext.iterator.drop.js +++ b/tests/pure/esnext.iterator.drop.js @@ -19,4 +19,5 @@ QUnit.test('Iterator#drop', assert => { assert.throws(() => drop.call({}, 1), TypeError); assert.throws(() => drop.call([], 1), TypeError); assert.throws(() => drop.call(createIterator([1, 2, 3]), -1), RangeError, 'negative'); + assert.throws(() => drop.call(createIterator([1, 2, 3]), NaN), RangeError, 'NaN'); }); diff --git a/tests/pure/esnext.iterator.indexed.js b/tests/pure/esnext.iterator.indexed.js new file mode 100644 index 000000000000..94454f77c4e6 --- /dev/null +++ b/tests/pure/esnext.iterator.indexed.js @@ -0,0 +1,18 @@ +import { createIterator } from '../helpers/helpers'; + +import Iterator from 'core-js-pure/full/iterator'; + +QUnit.test('Iterator#indexed', assert => { + const { indexed } = Iterator.prototype; + + assert.isFunction(indexed); + assert.arity(indexed, 0); + assert.nonEnumerable(Iterator.prototype, 'indexed'); + + assert.arrayEqual(indexed.call(createIterator(['a', 'b', 'c'])).toArray().toString(), '0,a,1,b,2,c', 'basic functionality'); + + assert.throws(() => indexed.call(undefined, TypeError)); + assert.throws(() => indexed.call(null, TypeError)); + assert.throws(() => indexed.call({}, TypeError)); + assert.throws(() => indexed.call([], TypeError)); +}); diff --git a/tests/pure/esnext.iterator.take.js b/tests/pure/esnext.iterator.take.js index 8c69455e65b9..23728d0711f8 100644 --- a/tests/pure/esnext.iterator.take.js +++ b/tests/pure/esnext.iterator.take.js @@ -19,4 +19,5 @@ QUnit.test('Iterator#take', assert => { assert.throws(() => take.call({}, 1), TypeError); assert.throws(() => take.call([], 1), TypeError); assert.throws(() => take.call(createIterator([1, 2, 3]), -1), RangeError, 'negative'); + assert.throws(() => take.call(createIterator([1, 2, 3]), NaN), RangeError, 'NaN'); }); diff --git a/tests/tests/esnext.async-iterator.as-indexed-pairs.js b/tests/tests/esnext.async-iterator.as-indexed-pairs.js index 1e4dafea7433..5ca4da06f3e2 100644 --- a/tests/tests/esnext.async-iterator.as-indexed-pairs.js +++ b/tests/tests/esnext.async-iterator.as-indexed-pairs.js @@ -1,13 +1,13 @@ import { createIterator } from '../helpers/helpers'; QUnit.test('AsyncIterator#asIndexedPairs', assert => { - assert.expect(10); + assert.expect(9); const async = assert.async(); const { asIndexedPairs } = AsyncIterator.prototype; assert.isFunction(asIndexedPairs); assert.arity(asIndexedPairs, 0); - assert.name(asIndexedPairs, 'asIndexedPairs'); + // assert.name(asIndexedPairs, 'asIndexedPairs'); assert.looksNative(asIndexedPairs); assert.nonEnumerable(AsyncIterator.prototype, 'asIndexedPairs'); diff --git a/tests/tests/esnext.async-iterator.drop.js b/tests/tests/esnext.async-iterator.drop.js index 5346d3b1cdf3..01194670daa9 100644 --- a/tests/tests/esnext.async-iterator.drop.js +++ b/tests/tests/esnext.async-iterator.drop.js @@ -1,7 +1,7 @@ import { createIterator } from '../helpers/helpers'; QUnit.test('AsyncIterator#drop', assert => { - assert.expect(14); + assert.expect(15); const async = assert.async(); const { drop } = AsyncIterator.prototype; @@ -29,4 +29,5 @@ QUnit.test('AsyncIterator#drop', assert => { assert.throws(() => drop.call({}, 1), TypeError); assert.throws(() => drop.call([], 1), TypeError); assert.throws(() => drop.call(createIterator([1, 2, 3]), -1), RangeError, 'negative'); + assert.throws(() => drop.call(createIterator([1, 2, 3]), NaN), RangeError, 'NaN'); }); diff --git a/tests/tests/esnext.async-iterator.indexed.js b/tests/tests/esnext.async-iterator.indexed.js new file mode 100644 index 000000000000..cb6ac33154c4 --- /dev/null +++ b/tests/tests/esnext.async-iterator.indexed.js @@ -0,0 +1,23 @@ +import { createIterator } from '../helpers/helpers'; + +QUnit.test('AsyncIterator#indexed', assert => { + assert.expect(10); + const async = assert.async(); + const { indexed } = AsyncIterator.prototype; + + assert.isFunction(indexed); + assert.arity(indexed, 0); + assert.name(indexed, 'indexed'); + assert.looksNative(indexed); + assert.nonEnumerable(AsyncIterator.prototype, 'indexed'); + + indexed.call(createIterator(['a', 'b', 'c'])).toArray().then(it => { + assert.same(it.toString(), '0,a,1,b,2,c', 'basic functionality'); + async(); + }); + + assert.throws(() => indexed.call(undefined, () => { /* empty */ }), TypeError); + assert.throws(() => indexed.call(null, () => { /* empty */ }), TypeError); + assert.throws(() => indexed.call({}, () => { /* empty */ }), TypeError); + assert.throws(() => indexed.call([], () => { /* empty */ }), TypeError); +}); diff --git a/tests/tests/esnext.async-iterator.take.js b/tests/tests/esnext.async-iterator.take.js index a55b51383b3a..39d855a1e1ba 100644 --- a/tests/tests/esnext.async-iterator.take.js +++ b/tests/tests/esnext.async-iterator.take.js @@ -1,7 +1,7 @@ import { createIterator } from '../helpers/helpers'; QUnit.test('AsyncIterator#take', assert => { - assert.expect(14); + assert.expect(15); const async = assert.async(); const { take } = AsyncIterator.prototype; @@ -29,4 +29,5 @@ QUnit.test('AsyncIterator#take', assert => { assert.throws(() => take.call({}, 1), TypeError); assert.throws(() => take.call([], 1), TypeError); assert.throws(() => take.call(createIterator([1, 2, 3]), -1), RangeError, 'negative'); + assert.throws(() => take.call(createIterator([1, 2, 3]), NaN), RangeError, 'NaN'); }); diff --git a/tests/tests/esnext.iterator.as-indexed-pairs.js b/tests/tests/esnext.iterator.as-indexed-pairs.js index 0917dce5d0aa..b620d82eab90 100644 --- a/tests/tests/esnext.iterator.as-indexed-pairs.js +++ b/tests/tests/esnext.iterator.as-indexed-pairs.js @@ -5,7 +5,7 @@ QUnit.test('Iterator#asIndexedPairs', assert => { assert.isFunction(asIndexedPairs); assert.arity(asIndexedPairs, 0); - assert.name(asIndexedPairs, 'asIndexedPairs'); + // assert.name(asIndexedPairs, 'asIndexedPairs'); assert.looksNative(asIndexedPairs); assert.nonEnumerable(Iterator.prototype, 'asIndexedPairs'); diff --git a/tests/tests/esnext.iterator.drop.js b/tests/tests/esnext.iterator.drop.js index 714918def202..a38931a5090c 100644 --- a/tests/tests/esnext.iterator.drop.js +++ b/tests/tests/esnext.iterator.drop.js @@ -19,4 +19,5 @@ QUnit.test('Iterator#drop', assert => { assert.throws(() => drop.call({}, 1), TypeError); assert.throws(() => drop.call([], 1), TypeError); assert.throws(() => drop.call(createIterator([1, 2, 3]), -1), RangeError, 'negative'); + assert.throws(() => drop.call(createIterator([1, 2, 3]), NaN), RangeError, 'NaN'); }); diff --git a/tests/tests/esnext.iterator.indexed.js b/tests/tests/esnext.iterator.indexed.js new file mode 100644 index 000000000000..2f3f6b042bf1 --- /dev/null +++ b/tests/tests/esnext.iterator.indexed.js @@ -0,0 +1,18 @@ +import { createIterator } from '../helpers/helpers'; + +QUnit.test('Iterator#indexed', assert => { + const { indexed } = Iterator.prototype; + + assert.isFunction(indexed); + assert.arity(indexed, 0); + assert.name(indexed, 'indexed'); + assert.looksNative(indexed); + assert.nonEnumerable(Iterator.prototype, 'indexed'); + + assert.arrayEqual(indexed.call(createIterator(['a', 'b', 'c'])).toArray().toString(), '0,a,1,b,2,c', 'basic functionality'); + + assert.throws(() => indexed.call(undefined, TypeError)); + assert.throws(() => indexed.call(null, TypeError)); + assert.throws(() => indexed.call({}, TypeError)); + assert.throws(() => indexed.call([], TypeError)); +}); diff --git a/tests/tests/esnext.iterator.take.js b/tests/tests/esnext.iterator.take.js index 1430f73b509c..7063523f4b7d 100644 --- a/tests/tests/esnext.iterator.take.js +++ b/tests/tests/esnext.iterator.take.js @@ -19,4 +19,5 @@ QUnit.test('Iterator#take', assert => { assert.throws(() => take.call({}, 1), TypeError); assert.throws(() => take.call([], 1), TypeError); assert.throws(() => take.call(createIterator([1, 2, 3]), -1), RangeError, 'negative'); + assert.throws(() => take.call(createIterator([1, 2, 3]), NaN), RangeError, 'NaN'); });