git.fiddlerwoaroof.com
Raw Blame History
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]);
}