# Source: framework.js

    "use strict";
    const Now_1 = require("./Now");
    const Now_2 = require("./Now");
    const Behavior_1 = require("./Behavior");
    const B = require("./Behavior");
    const Future_1 = require("./Future");
    const Stream_1 = require("./Stream");
    class Component {
        constructor(content) {
            this.content = content;
            this.of = Component.of;
        }
        static of(b) {
            // We need this decleration because TS can't infer the tuple type :'(
            const pair = [b, []];
            return new Component(Now_1.Now.of(pair));
        }
        static fromPair(b, nodes) {
            const pair = [b, nodes];
            return new Component(Now_1.Now.of(pair));
        }
        chain(f) {
            return new Component(this.content.chain(([a, nodes]) => {
                return f(a).content.map(([b, moreNodes]) => {
                    return [b, nodes.concat(moreNodes)];
                });
            }));
        }
        flatten(now) {
            return now.chain((n) => n);
        }
        map(f) {
            return this.chain((a) => this.of(f(a)));
        }
        mapTo(b) {
            return this.chain((_) => this.of(b));
        }
        lift(f, ...ms) {
            const { of } = ms[0];
            switch (f.length) {
                case 1:
                    return ms[0].map(f);
                case 2:
                    return ms[0].chain((a) => ms[1].chain((b) => of(f(a, b))));
                case 3:
                    return ms[0].chain((a) => ms[1].chain((b) => ms[2].chain((c) => of(f(a, b, c)))));
            }
        }
    }
    exports.Component = Component;
    class MfixNow extends Now_1.Now {
        constructor(fn) {
            super();
            this.fn = fn;
        }
        ;
        run() {
            const placeholders = {
                behaviors: [Behavior_1.placeholder(), Behavior_1.placeholder(), Behavior_1.placeholder(), Behavior_1.placeholder()],
                streams: [Stream_1.empty(), Stream_1.empty(), Stream_1.empty(), Stream_1.empty()]
            };
            const arg = this.fn([placeholders, []]).run();
            const [{ behaviors, streams }, _] = arg;
            // Tie the recursive knot
            if (behaviors !== undefined) {
                for (let i = 0; i < behaviors.length; ++i) {
                    placeholders.behaviors[i].replaceWith(behaviors[i]);
                }
            }
            if (streams !== undefined) {
                for (let i = 0; i < streams.length; ++i) {
                    placeholders.streams[i].def = streams[i];
                }
            }
            return arg;
        }
        ;
    }
    /**
     * Something resembling the monadic fixpoint combinatior for Now.
     */
    function mfixNow(comp) {
        return new MfixNow(comp);
    }
    exports.mfixNow = mfixNow;
    function runComponent(c) {
        return c.content;
    }
    function component({ model, view }) {
        return new Component(mfixNow(([v, _]) => model(v).chain((m) => runComponent(view(m)))));
    }
    exports.component = component;
    function runMain(selector, c) {
        const element = document.querySelector(selector);
        Now_2.runNow(runComponent(c).map(([_, nodes]) => {
            for (const node of nodes) {
                element.appendChild(node);
            }
            return Future_1.Future.of({});
        }));
    }
    exports.runMain = runMain;
    function behaviorFromEvent(initial, eventName, extractor, dom) {
        const b = Behavior_1.sink(initial);
        dom.addEventListener(eventName, (ev) => {
            b.publish(extractor(ev));
        });
        return b;
    }
    function streamFromEvent(eventName, extractor, dom) {
        const s = Stream_1.empty();
        dom.addEventListener(eventName, (ev) => {
            s.publish(extractor(ev));
        });
        return s;
    }
    function input() {
        const elm = document.createElement("input");
        const inputValue = behaviorFromEvent("", "input", (ev) => ev.target.value, elm);
        return Component.fromPair({ inputValue }, [elm]);
    }
    exports.input = input;
    function br() {
        const elm = document.createElement("br");
        return Component.fromPair({}, [elm]);
    }
    exports.br = br;
    function span(text) {
        const elm = document.createElement("span");
        elm.innerText = text;
        return Component.fromPair({}, [elm]);
    }
    exports.span = span;
    function text(tOrB) {
        const elm = document.createTextNode("");
        if (typeof tOrB === "string") {
            elm.nodeValue = tOrB;
        }
        else {
            if (tOrB.pushing === true) {
                elm.nodeValue = B.at(tOrB).toString();
            }
            Behavior_1.subscribe((t) => elm.nodeValue = t.toString(), tOrB);
        }
        return Component.fromPair({}, [elm]);
    }
    exports.text = text;
    function button(label) {
        const elm = document.createElement("button");
        elm.textContent = label;
        const click = streamFromEvent("click", (ev) => ev, elm);
        return Component.fromPair({ click }, [elm]);
    }
    exports.button = button;
    //# sourceMappingURL=framework.js.map