UNPKG

pnpm

Version:

Fast, disk space efficient package manager

72 lines (58 loc) 1.83 kB
/** @license MIT License (c) copyright 2010-2016 original author or authors */ /** @author Brian Cavalier */ /** @author John Hann */ import Stream from '../Stream' /** * Compute a stream by unfolding tuples of future values from a seed value * Event times may be controlled by returning a Promise from f * @param {function(seed:*):{value:*, seed:*, done:boolean}|Promise<{value:*, seed:*, done:boolean}>} f unfolding function accepts * a seed and returns a new tuple with a value, new seed, and boolean done flag. * If tuple.done is true, the stream will end. * @param {*} seed seed value * @returns {Stream} stream containing all value of all tuples produced by the * unfolding function. */ export function unfold (f, seed) { return new Stream(new UnfoldSource(f, seed)) } function UnfoldSource (f, seed) { this.f = f this.value = seed } UnfoldSource.prototype.run = function (sink, scheduler) { return new Unfold(this.f, this.value, sink, scheduler) } function Unfold (f, x, sink, scheduler) { this.f = f this.sink = sink this.scheduler = scheduler this.active = true var self = this function err (e) { self.sink.error(self.scheduler.now(), e) } function start (unfold) { return stepUnfold(unfold, x) } Promise.resolve(this).then(start).catch(err) } Unfold.prototype.dispose = function () { this.active = false } function stepUnfold (unfold, x) { var f = unfold.f return Promise.resolve(f(x)).then(function (tuple) { return continueUnfold(unfold, tuple) }) } function continueUnfold (unfold, tuple) { if (tuple.done) { unfold.sink.end(unfold.scheduler.now(), tuple.value) return tuple.value } unfold.sink.event(unfold.scheduler.now(), tuple.value) if (!unfold.active) { return tuple.value } return stepUnfold(unfold, tuple.seed) }