import type { AbortableMapper, AbortablePredicate } from '../types.js' import { END, SKIP } from '../types.js' /** * Iterable2 is a wrapper around Iterable that implements "Iterator Helpers proposal": * https://github.com/tc39/proposal-iterator-helpers * * Iterable2 can be removed after the proposal is widely implemented in Node & browsers. * * @experimental */ export class Iterable2 implements Iterable { private constructor(private it: Iterable) {} static of(it: Iterable): Iterable2 { return new Iterable2(it) } static empty(): Iterable2 { return new Iterable2([]) } [Symbol.iterator](): Iterator { return this.it[Symbol.iterator]() } toArray(): T[] { return Array.from(this.it) } forEach(cb: (v: T, i: number) => any | typeof END): void { let i = 0 for (const v of this.it) { if (cb(v, i++) === END) return } } some(cb: AbortablePredicate): boolean { // oxlint-disable-next-line unicorn/prefer-array-some return !!this.find(cb) } every(cb: AbortablePredicate): boolean { let i = 0 for (const v of this.it) { const r = cb(v, i++) if (r === END || !r) return false } return true } find(cb: AbortablePredicate): T | undefined { let i = 0 for (const v of this.it) { const r = cb(v, i++) if (r === END) return if (r) return v } } filter(cb: AbortablePredicate): Iterable2 { const { it } = this return new Iterable2({ *[Symbol.iterator]() { let i = 0 for (const v of it) { const r = cb(v, i++) if (r === END) return if (r) yield v } }, }) } map(mapper: AbortableMapper): Iterable2 { const { it } = this return new Iterable2({ *[Symbol.iterator]() { let i = 0 for (const v of it) { const r = mapper(v, i++) if (r === END) return if (r === SKIP) continue yield r } }, }) } }