272a0697 |
import * as R from 'ramda';
import {
Map,
fromJS
} from 'immutable';
|
ee0444ba |
import { makeLens, lensTransformer, fireListeners } from './lens';
|
272a0697 |
|
7524a4a6 |
let common_state = {
get(key) {
return this.lensFor(key).get();
},
set(key, value) {
this.lensFor(key).set(value);
},
getState() {
return this._currentState.toJS();
},
lensFor(key) {
return makeLens(key instanceof Array ? key : [key], this);
},
getRecorder() {
return new RecordingStateContainer(this);
},
commit(recorder) {
recorder.replay(this);
},
onUpdate(listener) {
this.listeners.push(listener);
|
1abf40ca |
return () => {
this.listeners.splice(this.listeners.indexOf(listener), 1);
|
7524a4a6 |
};
},
[fireListeners](oldState, newState) {
this.listeners.forEach((listener) => {
listener(oldState, newState);
});
},
};
|
272a0697 |
function RecordingStateContainer(container) {
this.localStore = Map();
this.container = container;
this.listeners = [];
this.actions = [];
|
ee0444ba |
}
|
272a0697 |
|
7524a4a6 |
RecordingStateContainer.prototype = Object.assign({
|
272a0697 |
setState(newState) {
|
7524a4a6 |
const oldState = this._currentState;
|
272a0697 |
this.localStore = this.localStore.merge(newState);
|
7524a4a6 |
this.actions = [[['setState', this.localStore]]];
this[fireListeners](oldState, this._currentState);
|
272a0697 |
},
|
7524a4a6 |
get _currentState() {
|
272a0697 |
const con = new StateContainer(this.container.getState());
this._replay(con);
return con._currentState;
},
|
7524a4a6 |
set _currentState(value) {
this.setState(value);
|
272a0697 |
},
_replay(container) {
R.forEach(
R.reduce(
(cur, [key, ...args]) => cur[key](...args),
container,
R.__
),
this.actions
);
},
replay(container) {
if (container !== this.container) {
throw new Error("Trying to replay into wrong parent container");
}
this._replay(container);
this.localStore = Map();
this.actions = [];
},
|
7524a4a6 |
}, common_state);
|
272a0697 |
|
ee0444ba |
export { lensTransformer };
export default function StateContainer(data = {}) {
|
7524a4a6 |
var state = fromJS(data);
|
272a0697 |
|
7524a4a6 |
return Object.assign({
listeners: [],
|
272a0697 |
get _currentState() {
|
7524a4a6 |
return state;
|
272a0697 |
},
set _currentState(value) {
|
7524a4a6 |
state = value;
|
272a0697 |
},
/**
* setState merges state shallowly
* */
setState(newState) {
const oldState = this._currentState;
this._currentState = this._currentState.merge(newState);
|
ee0444ba |
this[fireListeners](oldState, this._currentState);
|
272a0697 |
},
|
7524a4a6 |
}, common_state);
|
272a0697 |
}
|