import { Map, fromJS } from 'immutable';
let Symbol = (window['Symbol'] !== undefined) ? window['Symbol'] : x => `_Symbol__${x}`;
export const fireListeners = Symbol('fireListeners');
const noOpTransform = val => val;
export function lensTransformer(
lens,
getTransform = noOpTransform,
setTransform = noOpTransform
) {
return {
get: () => getTransform(lens.get()),
set: (val) => lens.set(setTransform(val)),
withValue(cb) {
return cb(this.get());
},
};
}
export function makeLens(key, self) {
const createLens = (keyPath) => {
return {
get() {
let result = self._currentState.getIn(keyPath);
if (result && result.toJS !== undefined) {
result = result.toJS();
}
return result;
},
set(val) {
const oldState = self._currentState;
if (self._currentState.getIn(keyPath) === undefined) {
for (let x = 0; x < keyPath.length; x++) {
const subPath = keyPath.slice(0, x);
if (self._currentState.getIn(subPath) === undefined && self._currentState.hasIn(subPath)) {
self._currentState = self._currentState.setIn(subPath, Map());
}
}
}
self._currentState = self._currentState.setIn(keyPath, fromJS(val));
self[fireListeners](oldState, self._currentState);
},
lensFor(key) {
let subPath = key instanceof Array ? key : [key];
return createLens([...keyPath, ...subPath]);
},
withValue(cb, ...rest) {
return cb(this.get(), ...rest);
},
swap(cb) {
this.set(cb(this.get()));
return this.get();
}
};
};
return createLens(key instanceof Array ? key : [key]);
}