UNPKG

pnpm

Version:

Fast, disk space efficient package manager

126 lines (103 loc) 3.05 kB
/** @license MIT License (c) copyright 2010-2016 original author or authors */ /** @author Brian Cavalier */ /** @author John Hann */ import Stream from '../Stream' import * as dispose from '../disposable/dispose' import LinkedList from '../LinkedList' import { id as identity } from '@most/prelude' export function mergeConcurrently (concurrency, stream) { return mergeMapConcurrently(identity, concurrency, stream) } export function mergeMapConcurrently (f, concurrency, stream) { return new Stream(new MergeConcurrently(f, concurrency, stream.source)) } function MergeConcurrently (f, concurrency, source) { this.f = f this.concurrency = concurrency this.source = source } MergeConcurrently.prototype.run = function (sink, scheduler) { return new Outer(this.f, this.concurrency, this.source, sink, scheduler) } function Outer (f, concurrency, source, sink, scheduler) { this.f = f this.concurrency = concurrency this.sink = sink this.scheduler = scheduler this.pending = [] this.current = new LinkedList() this.disposable = dispose.once(source.run(this, scheduler)) this.active = true } Outer.prototype.event = function (t, x) { this._addInner(t, x) } Outer.prototype._addInner = function (t, x) { if (this.current.length < this.concurrency) { this._startInner(t, x) } else { this.pending.push(x) } } Outer.prototype._startInner = function (t, x) { try { this._initInner(t, x) } catch (e) { this.error(t, e) } } Outer.prototype._initInner = function (t, x) { var innerSink = new Inner(t, this, this.sink) innerSink.disposable = mapAndRun(this.f, x, innerSink, this.scheduler) this.current.add(innerSink) } function mapAndRun (f, x, sink, scheduler) { return f(x).source.run(sink, scheduler) } Outer.prototype.end = function (t, x) { this.active = false dispose.tryDispose(t, this.disposable, this.sink) this._checkEnd(t, x) } Outer.prototype.error = function (t, e) { this.active = false this.sink.error(t, e) } Outer.prototype.dispose = function () { this.active = false this.pending.length = 0 return Promise.all([this.disposable.dispose(), this.current.dispose()]) } Outer.prototype._endInner = function (t, x, inner) { this.current.remove(inner) dispose.tryDispose(t, inner, this) if (this.pending.length === 0) { this._checkEnd(t, x) } else { this._startInner(t, this.pending.shift()) } } Outer.prototype._checkEnd = function (t, x) { if (!this.active && this.current.isEmpty()) { this.sink.end(t, x) } } function Inner (time, outer, sink) { this.prev = this.next = null this.time = time this.outer = outer this.sink = sink this.disposable = void 0 } Inner.prototype.event = function (t, x) { this.sink.event(Math.max(t, this.time), x) } Inner.prototype.end = function (t, x) { this.outer._endInner(Math.max(t, this.time), x, this) } Inner.prototype.error = function (t, e) { this.outer.error(Math.max(t, this.time), e) } Inner.prototype.dispose = function () { return this.disposable.dispose() }