pnpm
Version:
Fast, disk space efficient package manager
88 lines (73 loc) • 2.28 kB
JavaScript
/** @license MIT License (c) copyright 2010-2016 original author or authors */
/** @author Brian Cavalier */
/** @author John Hann */
import Stream from '../Stream'
import fatal from '../fatalError'
import { of as just } from '../source/core'
/**
* Create a stream containing only the promise's fulfillment
* value at the time it fulfills.
* @param {Promise<T>} p promise
* @return {Stream<T>} stream containing promise's fulfillment value.
* If the promise rejects, the stream will error
*/
export function fromPromise (p) {
return awaitPromises(just(p))
}
/**
* Turn a Stream<Promise<T>> into Stream<T> by awaiting each promise.
* Event order is preserved.
* @param {Stream<Promise<T>>} stream
* @return {Stream<T>} stream of fulfillment values. The stream will
* error if any promise rejects.
*/
export function awaitPromises (stream) {
return new Stream(new Await(stream.source))
}
function Await (source) {
this.source = source
}
Await.prototype.run = function (sink, scheduler) {
return this.source.run(new AwaitSink(sink, scheduler), scheduler)
}
function AwaitSink (sink, scheduler) {
this.sink = sink
this.scheduler = scheduler
this.queue = Promise.resolve()
var self = this
// Pre-create closures, to avoid creating them per event
this._eventBound = function (x) {
self.sink.event(self.scheduler.now(), x)
}
this._endBound = function (x) {
self.sink.end(self.scheduler.now(), x)
}
this._errorBound = function (e) {
self.sink.error(self.scheduler.now(), e)
}
}
AwaitSink.prototype.event = function (t, promise) {
var self = this
this.queue = this.queue.then(function () {
return self._event(promise)
}).catch(this._errorBound)
}
AwaitSink.prototype.end = function (t, x) {
var self = this
this.queue = this.queue.then(function () {
return self._end(x)
}).catch(this._errorBound)
}
AwaitSink.prototype.error = function (t, e) {
var self = this
// Don't resolve error values, propagate directly
this.queue = this.queue.then(function () {
return self._errorBound(e)
}).catch(fatal)
}
AwaitSink.prototype._event = function (promise) {
return promise.then(this._eventBound)
}
AwaitSink.prototype._end = function (x) {
return Promise.resolve(x).then(this._endBound)
}