'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.transduce = transduce; var _Stream = require('../Stream'); var _Stream2 = _interopRequireDefault(_Stream); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * 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 */ function transduce(transducer, stream) { return new _Stream2.default(new Transduce(transducer, stream.source)); } /** @license MIT License (c) copyright 2010-2016 original author or authors */ /** @author Brian Cavalier */ /** @author John Hann */ 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; };