iterable.flow

0.1.0 • Public • Published

Iterable.flow

travis package downloads styled with prettier

At the moment of writing flow does not have a proper support for Iterable/Iterator/Generator, it does not allow [Symbol.iterator] in class definitions and insteard requires use of @@iterator which on the other hand breaks babel.

This libary provides a workaround in form of Iterable.Sync / Iterable.Async classes that do have [Symbol.iterator] / [Symbol.asyncIterator] method which delegate to iterator / asyncIterator allowing you to define valid iterators that both flow and babel understand and that also works natively in JS engines with Symbol.iterator / Symbol.asyncIterator support in them.

Usage

Import

Rest of the the document & provided code examples assumes that library is installed (with yarn or npm) and imported as follows:

import Iterable from "iterable.flow"

Sync Iterator

In order to define sync iterator you'd neet to implement next method and iterator method that most likely returns this.

class RangeIterator extends Iterable.Sync<number> {
  value:number
  max:number
  static new(from:number=0, to:number=Infinity)
  constructor(from:number, to:number) {
    super()
    this.value = from
    this.max = to
  }
  iterator() {
    return this
  }
  next() {
    const {value, max} = this
    if (value <= max) {
      this.value ++
      return {done:false, value}
    } else {
      return {done:true}
    }
  }
}

console.log([...Range.new(0, 3)]) //=> [0, 1, 2, 3]

Sync Iterable

In order to define sync iteratable you just need to implemnet iterator method:

class Range extends Iterable.Sync<number> {
  from:number
  to:number
  constructor(from:number, to:number) {
    super()
    this.from = from
    this.to = to
  }
  static new(from:number=0, to:number=Infinity) {
    return new Range(from, to)
  }
  *iterator():Iterable.Iterator<number> {
    let n = this.from
    while (n <= this.to) {
      yield n++
    }
  }
}

console.log([...Range.new(0, 4)]) // [0, 1, 2, 3, 4]

Note: You can also return manually defined Iterator (as illustrated in previous example) from iterator method.

Async Iterable

class Beat extends Iterable.Async<number> {
  tempo:number
  time:number
  static new(tempo:number, time:number = 0) {
    this.tempo = tempo
    this.time = time
  }
  constructor(tempo:number, time:number) {
    super()
    this.tempo = tempo
    this.time = time
  }
  asyncIterator() {
    return this
  }
  next() {
    return new Promise(resolve => {
      setTimeout(() => {
        resolve({ done:false, value: (this.time += this.tempo) })
      }, this.tempo)
    })
  }
}


async function main() {
  for await (let time of Beat.new(100)) {
    // ...
  }
}

Install

npm install iterable.flow

Package Sidebar

Install

npm i iterable.flow

Weekly Downloads

1

Version

0.1.0

License

MIT

Unpacked Size

256 kB

Total Files

55

Last publish

Collaborators

  • gozala