cyclejs-utils
Version:
A few utility functions for dealing with merging of sinks
136 lines • 5.07 kB
JavaScript
import xs from 'xstream';
/**
* Applies xs.merge to all sinks in the array
* @param {Sinks[]} sinks the sinks to be merged
* @param {MergeExceptions} exceptions a dictionary of special channels, e.g. DOM
* @return {Sinks} the new unified sink
*/
export function mergeSinks(sinks, exceptions) {
if (exceptions === void 0) { exceptions = {}; }
var drivers = sinks
.map(Object.keys)
.reduce(function (acc, curr) { return acc.concat(curr); }, [])
.reduce(function (acc, curr) { return (acc.indexOf(curr) === -1 ? acc.concat([curr]) : acc); }, []);
var emptySinks = drivers
.map(function (s) {
var _a;
return (_a = {}, _a[s] = [], _a);
})
.reduce(function (acc, curr) { return Object.assign(acc, curr); }, {});
var combinedSinks = sinks.reduce(function (acc, curr) {
return Object.keys(acc)
.map(function (s) {
var _a;
return (_a = {}, _a[s] = acc[s], _a);
})
.map(function (o) {
var _a;
var name = Object.keys(o)[0];
return !curr[name]
? o
: (_a = {},
_a[name] = o[name].concat([curr[name]]),
_a);
})
.reduce(function (a, c) { return Object.assign(a, c); }, {});
}, emptySinks);
var merged = Object.keys(combinedSinks)
.filter(function (name) { return Object.keys(exceptions).indexOf(name) === -1; })
.map(function (s) { return [s, combinedSinks[s]]; })
.map(function (_a) {
var s = _a[0], arr = _a[1];
var _b;
return (_b = {},
_b[s] = arr.length === 1 ? arr[0] : xs.merge.apply(xs, arr),
_b);
});
var special = Object.keys(exceptions)
.map(function (key) { return [key, combinedSinks[key]]; })
.filter(function (_a) {
var _ = _a[0], arr = _a[1];
return arr !== undefined;
})
.map(function (_a) {
var key = _a[0], arr = _a[1];
var _b;
return (_b = {}, _b[key] = exceptions[key](arr), _b);
});
return merged
.concat(special)
.reduce(function (acc, curr) { return Object.assign(acc, curr); }, {});
}
/**
* Just like mergeSinks, but for onionify collections
* @see mergeSinks
*/
export function pickMergeSinks(driverNames, exceptions) {
if (exceptions === void 0) { exceptions = {}; }
return function (instances) {
var merged = driverNames
.filter(function (name) { return Object.keys(exceptions).indexOf(name) === -1; })
.map(function (name) {
var _a;
return (_a = {}, _a[name] = instances.pickMerge(name), _a);
});
var special = Object.keys(exceptions).map(function (key) {
var _a;
return (_a = {},
_a[key] = exceptions[key](instances),
_a);
});
return merged
.concat(special)
.reduce(function (acc, curr) { return Object.assign(acc, curr); }, {});
};
}
/**
* Extracts the sinks from a Stream of Sinks
* @param {Stream<Sinks>} sinks$
* @param {string[]} driverNames the names of all drivers that are possibly in the stream, it's best to use Object.keys() on your driver object
* @return {Sinks} A sinks containing the streams of the last emission in the sinks$
*/
export function extractSinks(sinks$, driverNames) {
return driverNames
.map(function (d) {
var _a;
return (_a = {},
_a[d] = sinks$
.map(function (s) { return s[d]; })
.filter(function (b) { return !!b; })
.flatten(),
_a);
})
.reduce(function (acc, curr) { return Object.assign(acc, curr); }, {});
}
/**
* Can be used to load a component lazy (with webpack code splitting)
* @param {() => any} moduleLoader A function like `() => import('./myModule')`
* @param {string[]} driverNames The names of the drivers the lazy component uses
* @param {string} name The name of the export. For loading a default export simply ignore
* @return {Component} A dummy that loads the actual component
*/
export function loadAsync(moduleLoader, driverNames, name) {
if (name === void 0) { name = 'default'; }
return function (sources) {
var lazyComponent$ = xs
.fromPromise(moduleLoader())
.map(function (m) { return m[name]; })
.map(function (m) { return m(sources); });
return extractSinks(lazyComponent$, driverNames);
};
}
/**
* Composes two lenses to one
* @param {Lens<A, B>} outer
* @param {Lens<B, C>} inner
* @return {Lens<A, C>} composed lens
*/
export function composeLenses(outer, inner) {
return {
get: function (parent) { return inner.get(outer.get(parent)); },
set: function (parent, child) {
return outer.set(parent, inner.set(outer.get(parent), child));
}
};
}
//# sourceMappingURL=index.js.map