Skip to content

Commit

Permalink
Polyfill Symbol.asyncIterator everywhere
Browse files Browse the repository at this point in the history
  • Loading branch information
MattiasBuelens committed Jan 14, 2024
1 parent 877bc37 commit 574130c
Show file tree
Hide file tree
Showing 5 changed files with 20 additions and 25 deletions.
8 changes: 7 additions & 1 deletion src/lib/abstract-ops/ecmascript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,12 @@ export function CreateAsyncFromSyncIterator<T>(syncIteratorRecord: SyncIteratorR
return { iterator: asyncIterator, nextMethod, done: false };
}

// Aligns with core-js/modules/es.symbol.async-iterator.js
export const SymbolAsyncIterator: (typeof Symbol)['asyncIterator'] =
Symbol.asyncIterator ??
Symbol.for?.('Symbol.asyncIterator') ??
'@@asyncIterator';

export type SyncOrAsyncIterable<T> = Iterable<T> | AsyncIterable<T>;
export type SyncOrAsyncIteratorMethod<T> = () => (Iterator<T> | AsyncIterator<T>);

Expand All @@ -131,7 +137,7 @@ function GetIterator<T>(
assert(hint === 'sync' || hint === 'async');
if (method === undefined) {
if (hint === 'async') {
method = GetMethod(obj as AsyncIterable<T>, Symbol.asyncIterator);
method = GetMethod(obj as AsyncIterable<T>, SymbolAsyncIterator);
if (method === undefined) {
const syncMethod = GetMethod(obj as Iterable<T>, Symbol.iterator);
const syncIteratorRecord = GetIterator(obj as Iterable<T>, 'sync', syncMethod);
Expand Down
8 changes: 1 addition & 7 deletions src/lib/readable-stream.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ import type {
} from './readable-stream/underlying-source';
import { noop } from '../utils';
import { setFunctionName, typeIsObject } from './helpers/miscellaneous';
import { CreateArrayFromList } from './abstract-ops/ecmascript';
import { CreateArrayFromList, SymbolAsyncIterator } from './abstract-ops/ecmascript';
import { CancelSteps } from './abstract-ops/internal-methods';
import { IsNonNegativeNumber } from './abstract-ops/miscellaneous';
import { assertObject, assertRequiredArgument } from './validators/basic';
Expand Down Expand Up @@ -80,12 +80,6 @@ export type ReadableByteStream = ReadableStream<NonShared<Uint8Array>> & {

type ReadableStreamState = 'readable' | 'closed' | 'errored';

// Aligns with core-js/modules/es.symbol.async-iterator.js
const SymbolAsyncIterator: (typeof Symbol)['asyncIterator'] =
Symbol.asyncIterator ??
Symbol.for?.('Symbol.asyncIterator') ??
'@@asyncIterator';

/**
* A readable stream represents a source of data, from which you can read.
*
Expand Down
4 changes: 1 addition & 3 deletions src/lib/readable-stream/async-iterator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,9 +140,7 @@ const ReadableStreamAsyncIteratorPrototype: ReadableStreamAsyncIteratorInstance<
return this._asyncIteratorImpl.return(value);
}
} as any;
if (AsyncIteratorPrototype !== undefined) {
Object.setPrototypeOf(ReadableStreamAsyncIteratorPrototype, AsyncIteratorPrototype);
}
Object.setPrototypeOf(ReadableStreamAsyncIteratorPrototype, AsyncIteratorPrototype);

// Abstract operations for the ReadableStream.

Expand Down
2 changes: 1 addition & 1 deletion src/target/es2018/stub/async-iterator-prototype.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/// <reference lib="es2018.asynciterable" />

/* eslint-disable @typescript-eslint/no-empty-function */
export const AsyncIteratorPrototype: AsyncIterable<any> | undefined =
export const AsyncIteratorPrototype: AsyncIterable<any> =
Object.getPrototypeOf(Object.getPrototypeOf(async function* (): AsyncIterableIterator<any> {}).prototype);
23 changes: 10 additions & 13 deletions src/target/es5/stub/async-iterator-prototype.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
/// <reference lib="es2018.asynciterable" />

export let AsyncIteratorPrototype: AsyncIterable<any> | undefined;
import { SymbolAsyncIterator } from '../../../lib/abstract-ops/ecmascript';

if (typeof Symbol.asyncIterator === 'symbol') {
// We're running inside a ES2018+ environment, but we're compiling to an older syntax.
// We cannot access %AsyncIteratorPrototype% without non-ES2018 syntax, but we can re-create it.
AsyncIteratorPrototype = {
// 25.1.3.1 %AsyncIteratorPrototype% [ @@asyncIterator ] ( )
// https://tc39.github.io/ecma262/#sec-asynciteratorprototype-asynciterator
[Symbol.asyncIterator](this: AsyncIterator<any>) {
return this;
}
};
Object.defineProperty(AsyncIteratorPrototype, Symbol.asyncIterator, { enumerable: false });
}
// We cannot access %AsyncIteratorPrototype% without non-ES2018 syntax, but we can re-create it.
export const AsyncIteratorPrototype: AsyncIterable<any> = {
// 25.1.3.1 %AsyncIteratorPrototype% [ @@asyncIterator ] ( )
// https://tc39.github.io/ecma262/#sec-asynciteratorprototype-asynciterator
[SymbolAsyncIterator](this: AsyncIterator<any>) {
return this;
}
};
Object.defineProperty(AsyncIteratorPrototype, SymbolAsyncIterator, { enumerable: false });

0 comments on commit 574130c

Please sign in to comment.