const assert = require('assert');
import {Effect, Types, Result, Action, perform} from '..';
import {update as updateCounter, init as initCounter, types} from './counter.js';

const update = (state, action) => {
    const {type} = action;
    const side = type;
    const unwrapped = Action.unwrap(action);
    const before = state[side];
    const {state: after, effect} = updateCounter(before,unwrapped);
    state[side] = after;
    const mainEffect = effect.map(Action.wrap(side));
    return Result(state, mainEffect);
};

const init = () => ({
    left: initCounter(),
    right: initCounter(),
});

const view = (state) => {
    console.log(state);
}

const main = Effect.app({init, update, view});
const {increment, incrementLater} = types;
const left = Action.wrap('left');
const right = Action.wrap('right');
main.next(left(Action(increment)));
main.next(left(Action(increment)));
main.next(left(Action(increment)));
const act = left(Action(incrementLater));
main.next(act);
// const delay = ms => new Promise(resolve => {
//     setTimeout(resolve, ms);
// });
// const waitAndInc = (ms) => delay(ms).then(() => Action(types.increment));
// const effect = Effect.all(
//     [
//         Effect.call(waitAndInc, 300),
//         Effect.call(waitAndInc, 500)
//     ]
// ).map(actions => {
//     const count = actions.length;
//     console.log({count});
//     return Action(types.incrementBy, count);
// });
// perform(effect).then(a => {
//     console.log({a});
// });
// main.next()
// main.next(left(Action(increment)));
// main.next(left(Action(incrementLater)));
// main.next(left(Action(increment)));
// main.next(right(Action(increment)));

// main.next(left(Action(incrementLater)));
// main.next(left(Action(increment)));
// main.next(left(Action(increment)));

// const actions = new Bus();
// main(actions);
// const incLaterAction = Action('INCREMENT_LATER');
// actions.push(inc);
// actions.push(incLaterAction);
// actions.push(inc);

// const assertEffect = (type, next) => effect => {
//     assert.equal(type, effect.type);
//     return Promise.resolve(next(effect.data));
// };

// const testEffects = (fn,expected,ininitialState) => function*() {
//     let state = ininitialState;
//     let i = 0;
//     while(i < expected.length) {
//         let action = yield; //wait for action
//         while(action) {
//             console.log({action});
//             let [value, effectAssert] = expected[i];
//             const {state: next, effect} = fn(state, action);
//             console.log({next, effect});
//             assert.equal(value, next);
//             state = next;
//             action = yield effectAssert(effect);
//             i++;
//         }
//     }
// };
// const noop = () => {};

// const seq = (fn,promises) => {
//     return promises.reduce((p) => {
//         return Promise.resolve(p).then(fn);
//     }, Promise.resolve());
// };

// const testUpdate = () => {
//     let startState = 4;
//     const expected = [
//         [5, assertEffect('NONE', noop)],
//         [6, assertEffect('NONE', noop)]
//     ];
//     const test = testEffects(update,expected,startState)();
//     const actions = [Action('INCREMENT'), Action('INCREMENT')];
//     actions.reduce((promise, action) => {

//     }, Promise.resolve([]));
//     test.next(Action('INCREMENT'));
//     test.next(Action('INCREMENT'));
// };
// testUpdate();

@@ -982,2412 +982,4 @@
 t);%0A
-// const delay = ms =%3E new Promise(resolve =%3E %7B%0A//     setTimeout(resolve, ms);%0A// %7D);%0A// const waitAndInc = (ms) =%3E delay(ms).then(() =%3E Action(types.increment));%0A// const effect = Effect.all(%0A//     %5B%0A//         Effect.call(waitAndInc, 300),%0A//         Effect.call(waitAndInc, 500)%0A//     %5D%0A// ).map(actions =%3E %7B%0A//     const count = actions.length;%0A//     console.log(%7Bcount%7D);%0A//     return Action(types.incrementBy, count);%0A// %7D);%0A// perform(effect).then(a =%3E %7B%0A//     console.log(%7Ba%7D);%0A// %7D);%0A// main.next()%0A// main.next(left(Action(increment)));%0A// main.next(left(Action(incrementLater)));%0A// main.next(left(Action(increment)));%0A// main.next(right(Action(increment)));%0A%0A// main.next(left(Action(incrementLater)));%0A// main.next(left(Action(increment)));%0A// main.next(left(Action(increment)));%0A%0A// const actions = new Bus();%0A// main(actions);%0A// const incLaterAction = Action('INCREMENT_LATER');%0A// actions.push(inc);%0A// actions.push(incLaterAction);%0A// actions.push(inc);%0A%0A// const assertEffect = (type, next) =%3E effect =%3E %7B%0A//     assert.equal(type, effect.type);%0A//     return Promise.resolve(next(effect.data));%0A// %7D;%0A%0A// const testEffects = (fn,expected,ininitialState) =%3E function*() %7B%0A//     let state = ininitialState;%0A//     let i = 0;%0A//     while(i %3C expected.length) %7B%0A//         let action = yield; //wait for action%0A//         while(action) %7B%0A//             console.log(%7Baction%7D);%0A//             let %5Bvalue, effectAssert%5D = expected%5Bi%5D;%0A//             const %7Bstate: next, effect%7D = fn(state, action);%0A//             console.log(%7Bnext, effect%7D);%0A//             assert.equal(value, next);%0A//             state = next;%0A//             action = yield effectAssert(effect);%0A//             i++;%0A//         %7D%0A//     %7D%0A// %7D;%0A// const noop = () =%3E %7B%7D;%0A%0A// const seq = (fn,promises) =%3E %7B%0A//     return promises.reduce((p) =%3E %7B%0A//         return Promise.resolve(p).then(fn);%0A//     %7D, Promise.resolve());%0A// %7D;%0A%0A// const testUpdate = () =%3E %7B%0A//     let startState = 4;%0A//     const expected = %5B%0A//         %5B5, assertEffect('NONE', noop)%5D,%0A//         %5B6, assertEffect('NONE', noop)%5D%0A//     %5D;%0A//     const test = testEffects(update,expected,startState)();%0A//     const actions = %5BAction('INCREMENT'), Action('INCREMENT')%5D;%0A//     actions.reduce((promise, action) =%3E %7B%0A%0A//     %7D, Promise.resolve(%5B%5D));%0A//     test.next(Action('INCREMENT'));%0A//     test.next(Action('INCREMENT'));%0A// %7D;%0A// testUpdate();%0A

Remove commented code.