UNPKG

@cycle/core

Version:

The Cycle run() function meant to be used with RxJS v4

233 lines (225 loc) 9.89 kB
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Cycle = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ "use strict"; var base_1 = require('@cycle/base'); var rx_adapter_1 = require('@cycle/rx-adapter'); /** * A function that prepares the Cycle application to be executed. Takes a `main` * function and prepares to circularly connects it to the given collection of * driver functions. As an output, `Cycle()` returns an object with three * properties: `sources`, `sinks` and `run`. Only when `run()` is called will * the application actually execute. Refer to the documentation of `run()` for * more details. * * **Example:** * ```js * const {sources, sinks, run} = Cycle(main, drivers); * // ... * const dispose = run(); // Executes the application * // ... * dispose(); * ``` * * @param {Function} main a function that takes `sources` as input * and outputs a collection of `sinks` Observables. * @param {Object} drivers an object where keys are driver names and values * are driver functions. * @return {Object} an object with three properties: `sources`, `sinks` and * `run`. `sources` is the collection of driver sources, `sinks` is the * collection of driver sinks, these can be used for debugging or testing. `run` * is the function that once called will execute the application. * @function Cycle */ var Cycle = function Cycle(main, drivers) { return base_1.default(main, drivers, { streamAdapter: rx_adapter_1.default }); }; /** * Takes a `main` function and circularly connects it to the given collection * of driver functions. * * **Example:** * ```js * const dispose = Cycle.run(main, drivers); * // ... * dispose(); * ``` * * The `main` function expects a collection of "source" Observables (returned * from drivers) as input, and should return a collection of "sink" Observables * (to be given to drivers). A "collection of Observables" is a JavaScript * object where keys match the driver names registered by the `drivers` object, * and values are the Observables. Refer to the documentation of each driver to * see more details on what types of sources it outputs and sinks it receives. * * @param {Function} main a function that takes `sources` as input * and outputs a collection of `sinks` Observables. * @param {Object} drivers an object where keys are driver names and values * are driver functions. * @return {Function} a dispose function, used to terminate the execution of the * Cycle.js program, cleaning up resources used. * @function run */ function run(main, drivers) { var run = base_1.default(main, drivers, { streamAdapter: rx_adapter_1.default }).run; return run(); } exports.run = run; Cycle.run = run; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = Cycle; },{"@cycle/base":2,"@cycle/rx-adapter":3}],2:[function(require,module,exports){ "use strict"; var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; }; function logToConsoleError(err) { var target = err.stack || err; if (console && console.error) { console.error(target); } else if (console && console.log) { console.log(target); } } function makeSinkProxies(drivers, streamAdapter) { var sinkProxies = {}; for (var name_1 in drivers) { if (drivers.hasOwnProperty(name_1)) { var holdSubject = streamAdapter.makeSubject(); var driverStreamAdapter = drivers[name_1].streamAdapter || streamAdapter; var stream = driverStreamAdapter.adapt(holdSubject.stream, streamAdapter.streamSubscribe); sinkProxies[name_1] = { stream: stream, observer: holdSubject.observer }; } } return sinkProxies; } function callDrivers(drivers, sinkProxies, streamAdapter) { var sources = {}; for (var name_2 in drivers) { if (drivers.hasOwnProperty(name_2)) { var driverOutput = drivers[name_2](sinkProxies[name_2].stream, streamAdapter, name_2); var driverStreamAdapter = drivers[name_2].streamAdapter; if (driverStreamAdapter && driverStreamAdapter.isValidStream(driverOutput)) { sources[name_2] = streamAdapter.adapt(driverOutput, driverStreamAdapter.streamSubscribe); } else { sources[name_2] = driverOutput; } } } return sources; } function replicateMany(sinks, sinkProxies, streamAdapter) { var results = Object.keys(sinks).filter(function (name) { return !!sinkProxies[name]; }).map(function (name) { return streamAdapter.streamSubscribe(sinks[name], { next: function next(x) { sinkProxies[name].observer.next(x); }, error: function error(err) { logToConsoleError(err); sinkProxies[name].observer.error(err); }, complete: function complete(x) { sinkProxies[name].observer.complete(x); } }); }); var disposeFunctions = results.filter(function (dispose) { return typeof dispose === 'function'; }); return function () { disposeFunctions.forEach(function (dispose) { return dispose(); }); }; } function disposeSources(sources) { for (var k in sources) { if (sources.hasOwnProperty(k) && sources[k] && typeof sources[k].dispose === 'function') { sources[k].dispose(); } } } var isObjectEmpty = function isObjectEmpty(obj) { return Object.keys(obj).length === 0; }; function Cycle(main, drivers, options) { if (typeof main !== "function") { throw new Error("First argument given to Cycle must be the 'main' " + "function."); } if ((typeof drivers === 'undefined' ? 'undefined' : _typeof(drivers)) !== "object" || drivers === null) { throw new Error("Second argument given to Cycle must be an object " + "with driver functions as properties."); } if (isObjectEmpty(drivers)) { throw new Error("Second argument given to Cycle must be an object " + "with at least one driver function declared as a property."); } var streamAdapter = options.streamAdapter; if (!streamAdapter || isObjectEmpty(streamAdapter)) { throw new Error("Third argument given to Cycle must be an options object " + "with the streamAdapter key supplied with a valid stream adapter."); } var sinkProxies = makeSinkProxies(drivers, streamAdapter); var sources = callDrivers(drivers, sinkProxies, streamAdapter); var sinks = main(sources); if (typeof window !== 'undefined') { window.Cyclejs = { sinks: sinks }; } var run = function run() { var disposeReplication = replicateMany(sinks, sinkProxies, streamAdapter); return function () { disposeSources(sources); disposeReplication(); }; }; return { sinks: sinks, sources: sources, run: run }; } Object.defineProperty(exports, "__esModule", { value: true }); exports.default = Cycle; },{}],3:[function(require,module,exports){ "use strict"; var Rx = require('rx'); var RxJSAdapter = { adapt: function (originStream, originStreamSubscribe) { if (this.isValidStream(originStream)) { return originStream; } return Rx.Observable.create(function (destinationObserver) { var originObserver = { next: function (x) { return destinationObserver.onNext(x); }, error: function (e) { return destinationObserver.onError(e); }, complete: function () { return destinationObserver.onCompleted(); }, }; var dispose = originStreamSubscribe(originStream, originObserver); return function () { if (typeof dispose === 'function') { dispose.call(null); } }; }); }, remember: function (observable) { return observable.shareReplay(1); }, makeSubject: function () { var stream = new Rx.Subject(); var observer = { next: function (x) { stream.onNext(x); }, error: function (err) { stream.onError(err); }, complete: function (x) { stream.onCompleted(); } }; return { stream: stream, observer: observer }; }, isValidStream: function (stream) { return (typeof stream.subscribeOnNext === 'function' && typeof stream.onValue !== 'function'); }, streamSubscribe: function (stream, observer) { var subscription = stream.subscribe(function (x) { return observer.next(x); }, function (e) { return observer.error(e); }, function (x) { return observer.complete(x); }); return function () { subscription.dispose(); }; } }; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = RxJSAdapter; },{"rx":undefined}]},{},[1])(1) });