UNPKG

pnpm

Version:

Fast, disk space efficient package manager

122 lines (103 loc) 3.06 kB
/** @license MIT License (c) copyright 2010-2016 original author or authors */ /** @author Brian Cavalier */ /** @author John Hann */ import Stream from '../Stream' /** * Transform a stream by passing its events through a transducer. * @param {function} transducer transducer function * @param {Stream} stream stream whose events will be passed through the * transducer * @return {Stream} stream of events transformed by the transducer */ export function transduce (transducer, stream) { return new Stream(new Transduce(transducer, stream.source)) } function Transduce (transducer, source) { this.transducer = transducer this.source = source } Transduce.prototype.run = function (sink, scheduler) { var xf = this.transducer(new Transformer(sink)) return this.source.run(new TransduceSink(getTxHandler(xf), sink), scheduler) } function TransduceSink (adapter, sink) { this.xf = adapter this.sink = sink } TransduceSink.prototype.event = function (t, x) { var next = this.xf.step(t, x) return this.xf.isReduced(next) ? this.sink.end(t, this.xf.getResult(next)) : next } TransduceSink.prototype.end = function (t, x) { return this.xf.result(x) } TransduceSink.prototype.error = function (t, e) { return this.sink.error(t, e) } function Transformer (sink) { this.time = -Infinity this.sink = sink } Transformer.prototype['@@transducer/init'] = Transformer.prototype.init = function () {} Transformer.prototype['@@transducer/step'] = Transformer.prototype.step = function (t, x) { if (!isNaN(t)) { this.time = Math.max(t, this.time) } return this.sink.event(this.time, x) } Transformer.prototype['@@transducer/result'] = Transformer.prototype.result = function (x) { return this.sink.end(this.time, x) } /** * Given an object supporting the new or legacy transducer protocol, * create an adapter for it. * @param {object} tx transform * @returns {TxAdapter|LegacyTxAdapter} */ function getTxHandler (tx) { return typeof tx['@@transducer/step'] === 'function' ? new TxAdapter(tx) : new LegacyTxAdapter(tx) } /** * Adapter for new official transducer protocol * @param {object} tx transform * @constructor */ function TxAdapter (tx) { this.tx = tx } TxAdapter.prototype.step = function (t, x) { return this.tx['@@transducer/step'](t, x) } TxAdapter.prototype.result = function (x) { return this.tx['@@transducer/result'](x) } TxAdapter.prototype.isReduced = function (x) { return x != null && x['@@transducer/reduced'] } TxAdapter.prototype.getResult = function (x) { return x['@@transducer/value'] } /** * Adapter for older transducer protocol * @param {object} tx transform * @constructor */ function LegacyTxAdapter (tx) { this.tx = tx } LegacyTxAdapter.prototype.step = function (t, x) { return this.tx.step(t, x) } LegacyTxAdapter.prototype.result = function (x) { return this.tx.result(x) } LegacyTxAdapter.prototype.isReduced = function (x) { return x != null && x.__transducers_reduced__ } LegacyTxAdapter.prototype.getResult = function (x) { return x.value }