@cycle/state
Version:
Wraps your Cycle.js main function with reducer-driven state management
109 lines • 3.72 kB
JavaScript
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
import dropRepeats from 'xstream/extra/dropRepeats';
import { adapt } from '@cycle/run/lib/adapt';
function updateArrayEntry(array, scope, newVal) {
if (newVal === array[scope]) {
return array;
}
var index = parseInt(scope);
if (typeof newVal === 'undefined') {
return array.filter(function (_val, i) { return i !== index; });
}
return array.map(function (val, i) { return (i === index ? newVal : val); });
}
function makeGetter(scope) {
if (typeof scope === 'string' || typeof scope === 'number') {
return function lensGet(state) {
if (typeof state === 'undefined') {
return void 0;
}
else {
return state[scope];
}
};
}
else {
return scope.get;
}
}
function makeSetter(scope) {
if (typeof scope === 'string' || typeof scope === 'number') {
return function lensSet(state, childState) {
var _a, _b;
if (Array.isArray(state)) {
return updateArrayEntry(state, scope, childState);
}
else if (typeof state === 'undefined') {
return _a = {}, _a[scope] = childState, _a;
}
else {
return __assign({}, state, (_b = {}, _b[scope] = childState, _b));
}
};
}
else {
return scope.set;
}
}
export function isolateSource(source, scope) {
return source.select(scope);
}
export function isolateSink(innerReducer$, scope) {
var get = makeGetter(scope);
var set = makeSetter(scope);
return innerReducer$.map(function (innerReducer) {
return function outerReducer(outer) {
var prevInner = get(outer);
var nextInner = innerReducer(prevInner);
if (prevInner === nextInner) {
return outer;
}
else {
return set(outer, nextInner);
}
};
});
}
/**
* Represents a piece of application state dynamically changing over time.
*/
var StateSource = /** @class */ (function () {
function StateSource(stream, name) {
this.isolateSource = isolateSource;
this.isolateSink = isolateSink;
this._stream = stream
.filter(function (s) { return typeof s !== 'undefined'; })
.compose(dropRepeats())
.remember();
this._name = name;
this.stream = adapt(this._stream);
this._stream._isCycleSource = name;
}
/**
* Selects a part (or scope) of the state object and returns a new StateSource
* dynamically representing that selected part of the state.
*
* @param {string|number|lens} scope as a string, this argument represents the
* property you want to select from the state object. As a number, this
* represents the array index you want to select from the state array. As a
* lens object (an object with get() and set()), this argument represents any
* custom way of selecting something from the state object.
*/
StateSource.prototype.select = function (scope) {
var get = makeGetter(scope);
return new StateSource(this._stream.map(get), this._name);
};
return StateSource;
}());
export { StateSource };
//# sourceMappingURL=StateSource.js.map