Skip to content

Move Array.fromAsync to stable ES #1432

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 28, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@
- `AsyncIterator.prototype[@@asyncDispose]`
- Moved to stable ES, [May 2025 TC39 meeting](https://x.com/robpalmer2/status/1927744934343213085)
- Added `es.` namespace module, `/es/` and `/stable/` namespaces entries
- [`Array.fromAsync` proposal](https://github.com/tc39/proposal-array-from-async):
- Built-ins:
- `Array.fromAsync`
- Moved to stable ES, [May 2025 TC39 meeting](https://github.com/tc39/proposal-array-from-async/issues/14#issuecomment-2916645435)
- Added `es.` namespace module, `/es/` and `/stable/` namespaces entries
- [`Error.isError` proposal](https://github.com/tc39/proposal-is-error):
- Built-ins:
- `Error.isError`
Expand Down
38 changes: 20 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ structuredClone(new Set([1, 2, 3])); // => new Set([1, 2, 3])
- [`Array` find from last](#array-find-from-last)
- [Change `Array` by copy](#change-array-by-copy)
- [`Array` grouping](#array-grouping)
- [`Array.fromAsync`](#arrayfromasync)
- [`ArrayBuffer.prototype.transfer` and friends](#arraybufferprototypetransfer-and-friends)
- [`Error.isError`](#erroriserror)
- [Explicit Resource Management](#explicit-resource-management)
Expand Down Expand Up @@ -164,7 +165,6 @@ structuredClone(new Set([1, 2, 3])); // => new Set([1, 2, 3])
- [Well-formed unicode strings](#well-formed-unicode-strings)
- [New `Set` methods](#new-set-methods)
- [Stage 3 proposals](#stage-3-proposals)
- [`Array.fromAsync`](#arrayfromasync)
- [`JSON.parse` source text access](#jsonparse-source-text-access)
- [`Uint8Array` to / from base64 and hex](#uint8array-to--from-base64-and-hex)
- [`Math.sumPrecise`](#mathsumprecise)
Expand Down Expand Up @@ -704,7 +704,7 @@ Error.isError(Object.create(Error.prototype)); // => false
> We have no bulletproof way to polyfill this `Error.isError` / check if the object is an error, so it's an enough naive implementation.

#### ECMAScript: Array[⬆](#index)
Modules [`es.array.from`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.from.js), [`es.array.is-array`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.is-array.js), [`es.array.of`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.of.js), [`es.array.copy-within`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.copy-within.js), [`es.array.fill`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.fill.js), [`es.array.find`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.find.js), [`es.array.find-index`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.find-index.js), [`es.array.find-last`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.find-last.js), [`es.array.find-last-index`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.find-last-index.js), [`es.array.iterator`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.iterator.js), [`es.array.includes`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.includes.js), [`es.array.push`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.push.js), [`es.array.slice`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.slice.js), [`es.array.join`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.join.js), [`es.array.unshift`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.unshift.js), [`es.array.index-of`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.index-of.js), [`es.array.last-index-of`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.last-index-of.js), [`es.array.every`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.every.js), [`es.array.some`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.some.js), [`es.array.for-each`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.for-each.js), [`es.array.map`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.map.js), [`es.array.filter`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.filter.js), [`es.array.reduce`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.reduce.js), [`es.array.reduce-right`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.reduce-right.js), [`es.array.reverse`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.reverse.js), [`es.array.sort`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.sort.js), [`es.array.flat`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.flat.js), [`es.array.flat-map`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.flat-map.js), [`es.array.unscopables.flat`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.unscopables.flat.js), [`es.array.unscopables.flat-map`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.unscopables.flat-map.js), [`es.array.at`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.at.js), [`es.array.to-reversed`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.to-reversed.js), [`es.array.to-sorted`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.to-sorted.js), [`es.array.to-spliced`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.to-spliced.js), [`es.array.with`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.with.js).
Modules [`es.array.from`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.from.js), [`es.array.from-async`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.from-async.js), [`es.array.is-array`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.is-array.js), [`es.array.of`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.of.js), [`es.array.copy-within`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.copy-within.js), [`es.array.fill`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.fill.js), [`es.array.find`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.find.js), [`es.array.find-index`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.find-index.js), [`es.array.find-last`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.find-last.js), [`es.array.find-last-index`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.find-last-index.js), [`es.array.iterator`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.iterator.js), [`es.array.includes`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.includes.js), [`es.array.push`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.push.js), [`es.array.slice`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.slice.js), [`es.array.join`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.join.js), [`es.array.unshift`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.unshift.js), [`es.array.index-of`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.index-of.js), [`es.array.last-index-of`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.last-index-of.js), [`es.array.every`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.every.js), [`es.array.some`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.some.js), [`es.array.for-each`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.for-each.js), [`es.array.map`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.map.js), [`es.array.filter`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.filter.js), [`es.array.reduce`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.reduce.js), [`es.array.reduce-right`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.reduce-right.js), [`es.array.reverse`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.reverse.js), [`es.array.sort`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.sort.js), [`es.array.flat`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.flat.js), [`es.array.flat-map`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.flat-map.js), [`es.array.unscopables.flat`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.unscopables.flat.js), [`es.array.unscopables.flat-map`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.unscopables.flat-map.js), [`es.array.at`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.at.js), [`es.array.to-reversed`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.to-reversed.js), [`es.array.to-sorted`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.to-sorted.js), [`es.array.to-spliced`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.to-spliced.js), [`es.array.with`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.with.js).
```ts
class Array {
at(index: int): any;
Expand Down Expand Up @@ -744,6 +744,7 @@ class Array {
@@iterator(): Iterator<value>;
@@unscopables: { [newMethodNames: string]: true };
static from(items: Iterable | ArrayLike, mapFn?: (value: any, index: number) => any, thisArg?: any): Array<mixed>;
static fromAsync(asyncItems: AsyncIterable | Iterable | ArrayLike, mapfn?: (value: any, index: number) => any, thisArg?: any): Array;
static isArray(value: any): boolean;
static of(...args: Array<mixed>): Array<mixed>;
}
Expand All @@ -756,6 +757,7 @@ class Arguments {
```
core-js(-pure)/es|stable|actual|full/array
core-js(-pure)/es|stable|actual|full/array/from
core-js(-pure)/es|stable|actual|full/array/from-async
core-js(-pure)/es|stable|actual|full/array/of
core-js(-pure)/es|stable|actual|full/array/is-array
core-js(-pure)/es|stable|actual|full/array(/virtual)/at
Expand Down Expand Up @@ -861,6 +863,11 @@ correctionNeeded.with(1, 2); // => [1, 2, 3]
correctionNeeded; // => [1, 1, 3]
```

[*`Array.fromAsync` example*](https://tinyurl.com/2bt9bhwn):
```js
await Array.fromAsync((async function * () { yield * [1, 2, 3]; })(), i => i ** 2); // => [1, 4, 9]
```

#### ECMAScript: Iterator[⬆](#index)
Modules [`es.iterator.constructor`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.iterator.constructor.js), [`es.iterator.dispose`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.iterator.dispose.js), [`es.iterator.drop`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.iterator.drop.js), [`es.iterator.every`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.iterator.every.js), [`es.iterator.filter`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.iterator.filter.js), [`es.iterator.find`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.iterator.find.js), [`es.iterator.flat-map`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.iterator.flat-map.js), [`es.iterator.for-each`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.iterator.for-each.js), [`es.iterator.from`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.iterator.from.js), [`es.iterator.map`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.iterator.map.js), [`es.iterator.reduce`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.iterator.reduce.js), [`es.iterator.some`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.iterator.some.js), [`es.iterator.take`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.iterator.take.js), [`es.iterator.to-array`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.iterator.to-array.js)
```ts
Expand Down Expand Up @@ -2246,6 +2253,17 @@ class Map {
core-js/proposals/array-grouping-v2
```

##### [`Array.fromAsync`](https://github.com/tc39/proposal-array-from-async)[⬆](#index)
```ts
class Array {
static fromAsync(asyncItems: AsyncIterable | Iterable | ArrayLike, mapfn?: (value: any, index: number) => any, thisArg?: any): Array;
}
```
[*CommonJS entry points:*](#commonjs-api)
```
core-js/proposals/array-from-async-stage-2
```

##### [`ArrayBuffer.prototype.transfer` and friends](https://github.com/tc39/proposal-arraybuffer-transfer)[⬆](#index)
```ts
class ArrayBuffer {
Expand Down Expand Up @@ -2612,22 +2630,6 @@ core-js/proposals/set-methods-v2
```
core-js(-pure)/stage/3
```
##### [`Array.fromAsync`](https://github.com/tc39/proposal-array-from-async)[⬆](#index)
Modules [`esnext.array.from-async`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.array.from-async.js).
```ts
class Array {
static fromAsync(asyncItems: AsyncIterable | Iterable | ArrayLike, mapfn?: (value: any, index: number) => any, thisArg?: any): Array;
}
```
[*CommonJS entry points:*](#commonjs-api)
```
core-js/proposals/array-from-async-stage-2
core-js(-pure)/actual|full/array/from-async
```
[*Example*](https://tinyurl.com/2bt9bhwn):
```js
await Array.fromAsync((async function * () { yield * [1, 2, 3]; })(), it => it ** 2); // => [1, 4, 9]
```

##### [`JSON.parse` source text access](https://github.com/tc39/proposal-json-parse-with-source)[⬆](#index)
Modules [`esnext.json.is-raw-json`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.json.is-raw-json.js), [`esnext.json.parse`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.json.parse.js), [`esnext.json.raw-json`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.json.raw-json.js).
Expand Down
21 changes: 12 additions & 9 deletions packages/core-js-compat/src/data.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -1442,6 +1442,15 @@ export const data = {
firefox: '121',
safari: '17.4',
},
'es.array.from-async': { // <- `Array#values` and `Promise` dependencies should be loaded before
// https://bugs.webkit.org/show_bug.cgi?id=271703
bun: '1.1.2', // '0.3.0',
chrome: '121',
deno: '1.38',
firefox: '115',
// https://bugs.webkit.org/show_bug.cgi?id=271703
safari: '18.0', // '16.4',
},
'es.async-disposable-stack.constructor': { // `Promise` dependency should be loaded before
// added in 133, reverted in 134, https://issues.chromium.org/issues/42203506#comment25
// https://github.com/tc39/proposal-explicit-resource-management/issues/256, fixed in early 135
Expand Down Expand Up @@ -2315,15 +2324,8 @@ export const data = {
'esnext.aggregate-error': null,
// TODO: Remove from `core-js@4`
'esnext.suppressed-error.constructor': null,
'esnext.array.from-async': {
// https://bugs.webkit.org/show_bug.cgi?id=271703
bun: '1.1.2', // '0.3.0',
chrome: '121',
deno: '1.38',
firefox: '115',
// https://bugs.webkit.org/show_bug.cgi?id=271703
safari: '18.0', // '16.4',
},
// TODO: Remove from `core-js@4`
'esnext.array.from-async': null,
// TODO: Remove from `core-js@4`
'esnext.array.at': null,
// TODO: Remove from `core-js@4`
Expand Down Expand Up @@ -3088,6 +3090,7 @@ export const renamed = new Map([
['esnext.array.at', 'es.array.at'],
['esnext.array.find-last', 'es.array.find-last'],
['esnext.array.find-last-index', 'es.array.find-last-index'],
['esnext.array.from-async', 'es.array.from-async'],
['esnext.array.to-reversed', 'es.array.to-reversed'],
['esnext.array.to-sorted', 'es.array.to-sorted'],
['esnext.array.to-spliced', 'es.array.to-spliced'],
Expand Down
1 change: 1 addition & 0 deletions packages/core-js-compat/src/modules-by-versions.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,7 @@ export default {
'es.regexp.escape',
],
3.43: [
'es.array.from-async',
'es.async-disposable-stack.constructor',
'es.async-iterator.async-dispose',
'es.disposable-stack.constructor',
Expand Down
8 changes: 2 additions & 6 deletions packages/core-js/actual/array/from-async.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
'use strict';
require('../../modules/es.array.iterator');
require('../../modules/es.object.to-string');
require('../../modules/es.promise');
require('../../modules/es.string.iterator');
var parent = require('../../stable/array/from-async');
require('../../modules/esnext.array.from-async');
var path = require('../../internals/path');

module.exports = path.Array.fromAsync;
module.exports = parent;
2 changes: 0 additions & 2 deletions packages/core-js/actual/array/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
'use strict';
var parent = require('../../stable/array');
require('../../modules/es.promise');
require('../../modules/es.object.to-string');
require('../../modules/esnext.array.from-async');
require('../../modules/esnext.array.group');
require('../../modules/esnext.array.group-to-map');
Expand Down
9 changes: 9 additions & 0 deletions packages/core-js/es/array/from-async.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
'use strict';
require('../../modules/es.array.iterator');
require('../../modules/es.array.from-async');
require('../../modules/es.object.to-string');
require('../../modules/es.promise');
require('../../modules/es.string.iterator');
var path = require('../../internals/path');

module.exports = path.Array.fromAsync;
2 changes: 2 additions & 0 deletions packages/core-js/es/array/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ require('../../modules/es.array.for-each');
require('../../modules/es.array.includes');
require('../../modules/es.array.index-of');
require('../../modules/es.array.iterator');
require('../../modules/es.array.from-async');
require('../../modules/es.array.join');
require('../../modules/es.array.last-index-of');
require('../../modules/es.array.map');
Expand All @@ -39,6 +40,7 @@ require('../../modules/es.array.unshift');
require('../../modules/es.array.with');
require('../../modules/es.object.to-string');
require('../../modules/es.string.iterator');
require('../../modules/es.promise');
var path = require('../../internals/path');

module.exports = path.Array;
22 changes: 22 additions & 0 deletions packages/core-js/modules/es.array.from-async.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
'use strict';
var $ = require('../internals/export');
var fromAsync = require('../internals/array-from-async');
var fails = require('../internals/fails');

// eslint-disable-next-line es/no-nonstandard-array-properties -- safe
var nativeFromAsync = Array.fromAsync;
// https://bugs.webkit.org/show_bug.cgi?id=271703
var INCORRECT_CONSTRUCTURING = !nativeFromAsync || fails(function () {
var counter = 0;
nativeFromAsync.call(function () {
counter++;
return [];
}, { length: 0 });
return counter !== 1;
});

// `Array.fromAsync` method
// https://github.com/tc39/proposal-array-from-async
$({ target: 'Array', stat: true, forced: INCORRECT_CONSTRUCTURING }, {
fromAsync: fromAsync
});
23 changes: 2 additions & 21 deletions packages/core-js/modules/esnext.array.from-async.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,3 @@
'use strict';
var $ = require('../internals/export');
var fromAsync = require('../internals/array-from-async');
var fails = require('../internals/fails');

// eslint-disable-next-line es/no-nonstandard-array-properties -- safe
var nativeFromAsync = Array.fromAsync;
// https://bugs.webkit.org/show_bug.cgi?id=271703
var INCORRECT_CONSTRUCTURING = !nativeFromAsync || fails(function () {
var counter = 0;
nativeFromAsync.call(function () {
counter++;
return [];
}, { length: 0 });
return counter !== 1;
});

// `Array.fromAsync` method
// https://github.com/tc39/proposal-array-from-async
$({ target: 'Array', stat: true, forced: INCORRECT_CONSTRUCTURING }, {
fromAsync: fromAsync
});
// TODO: Remove from `core-js@4`
require('../modules/es.array.from-async');
4 changes: 4 additions & 0 deletions packages/core-js/stable/array/from-async.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
'use strict';
var parent = require('../../es/array/from-async');

module.exports = parent;
Loading