# Source: Now.js

    "use strict";
    const io_1 = require("jabz/io");
    const Future_1 = require("./Future");
    const Behavior_1 = require("./Behavior");
    /**
     * The Now monad represents a computation that takes place in a given
     * momemt and where the moment will always be now when the computation
     * is run.
     */
    class Now {
        of(b) {
            return new OfNow(b);
        }
        static of(b) {
            return new OfNow(b);
        }
        chain(f) {
            return new ChainNow(this, f);
        }
        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.Now = Now;
    class OfNow extends Now {
        constructor(value) {
            super();
            this.value = value;
        }
        run() {
            return this.value;
        }
    }
    class ChainNow extends Now {
        constructor(first, f) {
            super();
            this.first = first;
            this.f = f;
        }
        run() {
            return this.f(this.first.run()).run();
        }
    }
    class AsyncNow extends Now {
        constructor(comp) {
            super();
            this.comp = comp;
        }
        run() {
            return Future_1.fromPromise(io_1.runIO(this.comp));
        }
    }
    /**
     * Run an asynchronous IO action and return a future in the Now monad
     * that resolves with the eventual result of the IO action once it
     * completes. This function is what allows the Now monad to execute
     * imperative actions in a way that is pure and integrated with FRP.
     */
    function async(comp) {
        return new AsyncNow(comp);
    }
    exports.async = async;
    class SampleNow extends Now {
        constructor(b) {
            super();
            this.b = b;
        }
        run() {
            return Behavior_1.at(this.b);
        }
    }
    /**
     * Returns the current value of a behavior in the Now monad. This is
     * possible because computations in the Now monad has an associated
     * point in time.
     */
    function sample(b) {
        return new SampleNow(b);
    }
    exports.sample = sample;
    function run(now) {
        return now.run();
    }
    class PlanNow extends Now {
        constructor(future) {
            super();
            this.future = future;
        }
        run() {
            return this.future.map(run);
        }
    }
    /**
     * Convert a future now computation into a now computation of a
     * future. This function is what allows a Now-computation to reach
     * beyond the current moment that it is running in.
     */
    function plan(future) {
        return new PlanNow(future);
    }
    exports.plan = plan;
    /**
     * Run the given Now-computation. The returned promise resolves once
     * the future that is the result of running the now computation
     * occurs. This is an impure function and should not be used in normal
     * application code.
     */
    function runNow(now) {
        return new Promise((resolve, reject) => {
            now.run().subscribe(resolve);
        });
    }
    exports.runNow = runNow;
    //# sourceMappingURL=Now.js.map