UNPKG

funfix-effect

Version:

Sub-package of Funfix defining monadic data types for dealing with laziness and side effects

1,480 lines (1,345 loc) 43.1 kB
import { Either, coreInternals, Try, Success, Failure, TimeoutError, Some, None } from 'funfix-core/dist/es5'; import { Cancelable, StackedCancelable, Scheduler, Future, execInternals, Duration } from 'funfix-exec/dist/es5'; var emptyIteratorRef = { next: function next() { return { done: true }; } }; function iteratorOf(list) { if (!list) return emptyIteratorRef; if (Object.prototype.toString.call(list) !== "[object Array]") return list[Symbol.iterator](); var array = list; if (array.length === 0) return emptyIteratorRef; var cursor = 0; var next = function next() { var value = array[cursor++]; var done = cursor >= array.length; return { done: done, value: value }; }; return { next: next }; } var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; var classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; var createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var inherits = function (subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }; var possibleConstructorReturn = function (self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }; var Eval = function () { function Eval() { classCallCheck(this, Eval); } createClass(Eval, [{ key: "get", value: function get$$1() { return evalRunLoop(this); } }, { key: "map", value: function map(f) { return new FlatMap(this, function (a) { return Eval.now(f(a)); }); } }, { key: "flatMap", value: function flatMap(f) { return new FlatMap(this, f); } }, { key: "chain", value: function chain(f) { return this.flatMap(f); } }, { key: "ap", value: function ap(ff) { var _this = this; return ff.flatMap(function (f) { return _this.map(f); }); } }, { key: "memoize", value: function memoize() { var _this2 = this; switch (this._tag) { case "now": case "once": return this; case "always": return new Once(this.get); default: return new Once(function () { return _this2.get(); }); } } }, { key: "forEachL", value: function forEachL(cb) { return this.map(cb); } }, { key: "forEach", value: function forEach(cb) { this.forEachL(cb).get(); } }], [{ key: "of", value: function of(thunk) { return Eval.always(thunk); } }, { key: "pure", value: function pure(value) { return Eval.now(value); } }, { key: "now", value: function now(value) { return new Now(value); } }, { key: "unit", value: function unit() { return evalUnitRef; } }, { key: "always", value: function always(thunk) { return new Always(thunk); } }, { key: "once", value: function once(thunk) { return new Once(thunk); } }, { key: "suspend", value: function suspend(thunk) { return new Suspend(thunk); } }, { key: "defer", value: function defer(thunk) { return Eval.suspend(thunk); } }, { key: "tailRecM", value: function tailRecM(a, f) { return f(a).flatMap(function (either) { if (either.isRight()) { return Eval.now(either.get()); } else { return Eval.tailRecM(either.swap().get(), f); } }); } }, { key: "sequence", value: function sequence(list) { return evalSequence(list); } }, { key: "map2", value: function map2(fa1, fa2, f) { var fl = Eval.sequence([fa1, fa2]); return fl.map(function (lst) { return f(lst[0], lst[1]); }); } }, { key: "map3", value: function map3(fa1, fa2, fa3, f) { var fl = Eval.sequence([fa1, fa2, fa3]); return fl.map(function (lst) { return f(lst[0], lst[1], lst[2]); }); } }, { key: "map4", value: function map4(fa1, fa2, fa3, fa4, f) { var fl = Eval.sequence([fa1, fa2, fa3, fa4]); return fl.map(function (lst) { return f(lst[0], lst[1], lst[2], lst[3]); }); } }, { key: "map5", value: function map5(fa1, fa2, fa3, fa4, fa5, f) { var fl = Eval.sequence([fa1, fa2, fa3, fa4, fa5]); return fl.map(function (lst) { return f(lst[0], lst[1], lst[2], lst[3], lst[4]); }); } }, { key: "map6", value: function map6(fa1, fa2, fa3, fa4, fa5, fa6, f) { var fl = Eval.sequence([fa1, fa2, fa3, fa4, fa5, fa6]); return fl.map(function (lst) { return f(lst[0], lst[1], lst[2], lst[3], lst[4], lst[5]); }); } }]); return Eval; }(); var Now = function (_Eval) { inherits(Now, _Eval); function Now(value) { classCallCheck(this, Now); var _this3 = possibleConstructorReturn(this, (Now.__proto__ || Object.getPrototypeOf(Now)).call(this)); _this3.value = value; _this3._tag = "now"; return _this3; } createClass(Now, [{ key: "get", value: function get$$1() { return this.value; } }, { key: "toString", value: function toString() { return "Eval.now(" + JSON.stringify(this.value) + ")"; } }]); return Now; }(Eval); var evalUnitRef = new Now(undefined); var Once = function (_Eval2) { inherits(Once, _Eval2); function Once(thunk) { classCallCheck(this, Once); var _this4 = possibleConstructorReturn(this, (Once.__proto__ || Object.getPrototypeOf(Once)).call(this)); _this4._tag = "once"; _this4._thunk = thunk; return _this4; } createClass(Once, [{ key: "get", value: function get$$1() { if (this._thunk) { try { this._cache = this._thunk(); this._isError = false; } catch (e) { this._cache = e; this._isError = true; } delete this._thunk; } if (this._isError) throw this._cache; return this._cache; } }, { key: "toString", value: function toString() { return "Eval.once([thunk])"; } }]); return Once; }(Eval); var Always = function (_Eval3) { inherits(Always, _Eval3); function Always(thunk) { classCallCheck(this, Always); var _this5 = possibleConstructorReturn(this, (Always.__proto__ || Object.getPrototypeOf(Always)).call(this)); _this5._tag = "always"; _this5.get = thunk; return _this5; } createClass(Always, [{ key: "toString", value: function toString() { return "Eval.always([thunk])"; } }]); return Always; }(Eval); var Suspend = function (_Eval4) { inherits(Suspend, _Eval4); function Suspend(thunk) { classCallCheck(this, Suspend); var _this6 = possibleConstructorReturn(this, (Suspend.__proto__ || Object.getPrototypeOf(Suspend)).call(this)); _this6.thunk = thunk; _this6._tag = "suspend"; return _this6; } createClass(Suspend, [{ key: "toString", value: function toString() { return "Eval.suspend([thunk])"; } }]); return Suspend; }(Eval); var FlatMap = function (_Eval5) { inherits(FlatMap, _Eval5); function FlatMap(source, f) { classCallCheck(this, FlatMap); var _this7 = possibleConstructorReturn(this, (FlatMap.__proto__ || Object.getPrototypeOf(FlatMap)).call(this)); _this7.source = source; _this7.f = f; _this7._tag = "flatMap"; return _this7; } createClass(FlatMap, [{ key: "toString", value: function toString() { return "Eval#FlatMap(" + String(this.source) + ", [function])"; } }]); return FlatMap; }(Eval); var EvalModule = { map: function map(f, fa) { return fa.map(f); }, ap: function ap(ff, fa) { return fa.ap(ff); }, of: Eval.pure, chain: function chain(f, fa) { return fa.flatMap(f); }, chainRec: function chainRec(f, a) { return Eval.tailRecM(a, function (a) { return f(Either.left, Either.right, a); }); } }; coreInternals.fantasyLandRegister(Eval, EvalModule); function _popNextBind(bFirst, bRest) { if (bFirst) return bFirst; if (bRest && bRest.length > 0) return bRest.pop(); return null; } function evalRunLoop(start) { var current = start; var bFirst = null; var bRest = null; while (true) { switch (current._tag) { case "now": var now = current; var bind = _popNextBind(bFirst, bRest); if (!bind) return now.value; bFirst = null; current = bind(now.value); break; case "always": case "once": current = new Now(current.get()); break; case "suspend": current = current.thunk(); break; case "flatMap": if (bFirst) { if (!bRest) bRest = []; bRest.push(bFirst); } var fm = current; bFirst = fm.f; current = fm.source; break; } } } function evalSequence(list) { return Eval.of(function () { return iteratorOf(list); }).flatMap(function (cursor) { return evalSequenceLoop([], cursor); }); } function evalSequenceLoop(acc, cursor) { var _loop = function _loop() { var elem = cursor.next(); var isDone = elem.done; if (elem.value) { var io = elem.value; return { v: io.flatMap(function (a) { acc.push(a); if (isDone) return Eval.pure(acc); return evalSequenceLoop(acc, cursor); }) }; } else { if (isDone) return { v: Eval.pure(acc) }; } }; while (true) { var _ret = _loop(); if ((typeof _ret === "undefined" ? "undefined" : _typeof(_ret)) === "object") return _ret.v; } } var IO = function () { function IO() { classCallCheck(this, IO); } createClass(IO, [{ key: "run", value: function run() { var ec = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : Scheduler.global.get(); return taskToFutureRunLoop(this, ec); } }, { key: "runOnComplete", value: function runOnComplete(cb) { var ec = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : Scheduler.global.get(); var ref = ioGenericRunLoop(this, ec, null, cb, null, null, null); return ref || Cancelable.empty(); } }, { key: "attempt", value: function attempt() { return this.transform(function (_) { return Either.left(_); }, Either.right); } }, { key: "asyncBoundary", value: function asyncBoundary(ec) { return this.flatMap(function (a) { return IO.shift(ec).map(function () { return a; }); }); } }, { key: "chain", value: function chain(f) { return this.flatMap(f); } }, { key: "delayExecution", value: function delayExecution(delay) { var _this = this; return IO.delayedTick(delay).flatMap(function () { return _this; }); } }, { key: "delayResult", value: function delayResult(delay) { return this.transformWith(function (err) { return IO.delayedTick(delay).flatMap(function () { return IO.raise(err); }); }, function (a) { return IO.delayedTick(delay).map(function () { return a; }); }); } }, { key: "doOnFinish", value: function doOnFinish(f) { return this.transformWith(function (e) { return f(Some(e)).flatMap(function () { return IO.raise(e); }); }, function (a) { return f(None).map(function () { return a; }); }); } }, { key: "doOnCancel", value: function doOnCancel(callback) { var _this2 = this; return IO.asyncUnsafe(function (ctx, cb) { var ec = ctx.scheduler; ec.trampoline(function () { var conn = ctx.connection; conn.push(Cancelable.of(function () { return callback.run(ec); })); IO.unsafeStart(_this2, ctx, ioSafeCallback(ec, conn, cb)); }); }); } }, { key: "executeForked", value: function executeForked(ec) { return IO.fork(this, ec); } }, { key: "executeWithModel", value: function executeWithModel(em) { var _this3 = this; return IO.asyncUnsafe(function (ctx, cb) { var ec = ctx.scheduler.withExecutionModel(em); var ctx2 = new IOContext(ec, ctx.connection, ctx.options); ec.trampoline(function () { return IO.unsafeStart(_this3, ctx2, cb); }); }); } }, { key: "executeWithOptions", value: function executeWithOptions(set$$1) { var _this4 = this; return IO.asyncUnsafe(function (ctx, cb) { var ec = ctx.scheduler; var ctx2 = new IOContext(ec, ctx.connection, set$$1); ec.trampoline(function () { return IO.unsafeStart(_this4, ctx2, cb); }); }); } }, { key: "flatMap", value: function flatMap(f) { return new IOFlatMap(this, f); } }, { key: "ap", value: function ap(ff) { var _this5 = this; return ff.flatMap(function (f) { return _this5.map(f); }); } }, { key: "followedBy", value: function followedBy(fb) { return this.flatMap(function () { return fb; }); } }, { key: "forEach", value: function forEach(cb) { return this.map(cb); } }, { key: "forEffect", value: function forEffect(fb) { return this.flatMap(function (a) { return fb.map(function () { return a; }); }); } }, { key: "map", value: function map(f) { return new IOFlatMap(this, function (a) { return IO.now(f(a)); }); } }, { key: "memoize", value: function memoize() { switch (this._tag) { case "pure": return this; case "always": var always = this; return new IOOnce(always.thunk, false); case "memoize": var mem = this; if (!mem.onlySuccess) return mem; return new IOMemoize(this, false); default: return new IOMemoize(this, false); } } }, { key: "memoizeOnSuccess", value: function memoizeOnSuccess() { switch (this._tag) { case "pure": case "once": case "memoize": return this; case "always": var always = this; return new IOOnce(always.thunk, true); default: return new IOMemoize(this, true); } } }, { key: "recover", value: function recover(f) { return this.recoverWith(function (a) { return IO.now(f(a)); }); } }, { key: "recoverWith", value: function recoverWith(f) { return this.transformWith(f, IO.now); } }, { key: "timeout", value: function timeout(after) { var fb = IO.raise(new TimeoutError(Duration.of(after).toString())); return this.timeoutTo(after, fb); } }, { key: "timeoutTo", value: function timeoutTo(after, fallback) { var other = IO.delayedTick(after).flatMap(function () { return fallback; }); var lst = [this, other]; return IO.firstCompletedOf(lst); } }, { key: "transform", value: function transform(failure, success) { return this.transformWith(function (e) { return IO.now(failure(e)); }, function (a) { return IO.now(success(a)); }); } }, { key: "transformWith", value: function transformWith(failure, success) { return new IOFlatMap(this, success, failure); } }], [{ key: "always", value: function always(thunk) { return new IOAlways(thunk); } }, { key: "async", value: function async(register) { return IO.asyncUnsafe(function (ctx, cb) { var ec = ctx.scheduler; var conn = ctx.connection; ec.trampoline(function () { var safe = ioSafeCallback(ec, conn, cb); try { var ref = register(ec, safe); conn.push(ref || Cancelable.empty()); } catch (e) { safe(Failure(e)); } }); }); } }, { key: "asyncUnsafe", value: function asyncUnsafe(register) { return new IOAsync(register); } }, { key: "defer", value: function defer(thunk) { return IO.unit().flatMap(function () { return thunk(); }); } }, { key: "deferAction", value: function deferAction(f) { return IO.asyncUnsafe(function (ctx, cb) { var ec = ctx.scheduler; var ioa = void 0; try { ioa = f(ec); } catch (e) { ioa = IO.raise(e); } ec.trampoline(function () { return IO.unsafeStart(ioa, ctx, cb); }); }); } }, { key: "deferFuture", value: function deferFuture(thunk) { return IO.suspend(function () { return IO.fromFuture(thunk()); }); } }, { key: "deferFutureAction", value: function deferFutureAction(f) { return IO.deferAction(function (ec) { return IO.fromFuture(f(ec)); }); } }, { key: "delayedTick", value: function delayedTick(delay) { return IO.asyncUnsafe(function (ctx, cb) { var conn = ctx.connection; var task = ctx.scheduler.scheduleOnce(delay, function () { conn.pop(); cb(Try.unit()); }); conn.push(task); }); } }, { key: "firstCompletedOf", value: function firstCompletedOf(list) { return ioListToFutureProcess(list, Future.firstCompletedOf); } }, { key: "fromFuture", value: function fromFuture(fa) { if (!fa.value().isEmpty()) return IO.fromTry(fa.value().get()); return IO.asyncUnsafe(function (ctx, cb) { ctx.connection.push(fa); fa.onComplete(function (result) { ctx.connection.pop(); cb(result); }); }); } }, { key: "fromTry", value: function fromTry(a) { return new IOPure(a); } }, { key: "fork", value: function fork(fa, ec) { return IO.shift(ec).flatMap(function () { return fa; }); } }, { key: "map2", value: function map2(fa1, fa2, f) { var fl = IO.sequence([fa1, fa2]); return fl.map(function (lst) { return f(lst[0], lst[1]); }); } }, { key: "map3", value: function map3(fa1, fa2, fa3, f) { var fl = IO.sequence([fa1, fa2, fa3]); return fl.map(function (lst) { return f(lst[0], lst[1], lst[2]); }); } }, { key: "map4", value: function map4(fa1, fa2, fa3, fa4, f) { var fl = IO.sequence([fa1, fa2, fa3, fa4]); return fl.map(function (lst) { return f(lst[0], lst[1], lst[2], lst[3]); }); } }, { key: "map5", value: function map5(fa1, fa2, fa3, fa4, fa5, f) { var fl = IO.sequence([fa1, fa2, fa3, fa4, fa5]); return fl.map(function (lst) { return f(lst[0], lst[1], lst[2], lst[3], lst[4]); }); } }, { key: "map6", value: function map6(fa1, fa2, fa3, fa4, fa5, fa6, f) { var fl = IO.sequence([fa1, fa2, fa3, fa4, fa5, fa6]); return fl.map(function (lst) { return f(lst[0], lst[1], lst[2], lst[3], lst[4], lst[5]); }); } }, { key: "now", value: function now(value) { return new IOPure(Success(value)); } }, { key: "of", value: function of(thunk) { return IO.always(thunk); } }, { key: "once", value: function once(thunk) { return new IOOnce(thunk, false); } }, { key: "parMap2", value: function parMap2(fa1, fa2, f) { var fl = IO.gather([fa1, fa2]); return fl.map(function (lst) { return f(lst[0], lst[1]); }); } }, { key: "parMap3", value: function parMap3(fa1, fa2, fa3, f) { var fl = IO.gather([fa1, fa2, fa3]); return fl.map(function (lst) { return f(lst[0], lst[1], lst[2]); }); } }, { key: "parMap4", value: function parMap4(fa1, fa2, fa3, fa4, f) { var fl = IO.gather([fa1, fa2, fa3, fa4]); return fl.map(function (lst) { return f(lst[0], lst[1], lst[2], lst[3]); }); } }, { key: "parMap5", value: function parMap5(fa1, fa2, fa3, fa4, fa5, f) { var fl = IO.gather([fa1, fa2, fa3, fa4, fa5]); return fl.map(function (lst) { return f(lst[0], lst[1], lst[2], lst[3], lst[4]); }); } }, { key: "parMap6", value: function parMap6(fa1, fa2, fa3, fa4, fa5, fa6, f) { var fl = IO.gather([fa1, fa2, fa3, fa4, fa5, fa6]); return fl.map(function (lst) { return f(lst[0], lst[1], lst[2], lst[3], lst[4], lst[5]); }); } }, { key: "pure", value: function pure(value) { return IO.now(value); } }, { key: "raise", value: function raise(e) { return new IOPure(Failure(e)); } }, { key: "sequence", value: function sequence(list) { return ioSequence(list); } }, { key: "gather", value: function gather(list) { return ioListToFutureProcess(list, Future.sequence); } }, { key: "shift", value: function shift(ec) { if (!ec) return ioShiftDefaultRef; return ioShift(ec); } }, { key: "suspend", value: function suspend(thunk) { return IO.unit().flatMap(function () { return thunk(); }); } }, { key: "tailRecM", value: function tailRecM(a, f) { try { return f(a).flatMap(function (either) { if (either.isRight()) { return IO.now(either.get()); } else { return IO.tailRecM(either.swap().get(), f); } }); } catch (e) { return IO.raise(e); } } }, { key: "unit", value: function unit() { return ioUnitRef; } }, { key: "unsafeStart", value: function unsafeStart(source, context, cb) { return ioGenericRunLoop(source, context.scheduler, context, cb, null, null, null); } }]); return IO; }(); var IOPure = function (_IO) { inherits(IOPure, _IO); function IOPure(value) { classCallCheck(this, IOPure); var _this6 = possibleConstructorReturn(this, (IOPure.__proto__ || Object.getPrototypeOf(IOPure)).call(this)); _this6.value = value; _this6._tag = "pure"; return _this6; } return IOPure; }(IO); var ioUnitRef = new IOPure(Try.unit()); var IOOnce = function (_IO2) { inherits(IOOnce, _IO2); function IOOnce(thunk, onlyOnSuccess) { classCallCheck(this, IOOnce); var _this7 = possibleConstructorReturn(this, (IOOnce.__proto__ || Object.getPrototypeOf(IOOnce)).call(this)); _this7._tag = "once"; _this7._thunk = thunk; _this7.onlyOnSuccess = onlyOnSuccess; return _this7; } createClass(IOOnce, [{ key: "memoize", value: function memoize() { if (this.onlyOnSuccess && this._thunk) return new IOOnce(this._thunk, false);else return this; } }, { key: "runTry", value: function runTry() { if (this._thunk) { var result = Try.of(this._thunk); if (result.isSuccess() || !this.onlyOnSuccess) { delete this._thunk; delete this.onlyOnSuccess; this.cache = result; } return result; } return this.cache; } }]); return IOOnce; }(IO); var IOAlways = function (_IO3) { inherits(IOAlways, _IO3); function IOAlways(thunk) { classCallCheck(this, IOAlways); var _this8 = possibleConstructorReturn(this, (IOAlways.__proto__ || Object.getPrototypeOf(IOAlways)).call(this)); _this8.thunk = thunk; _this8._tag = "always"; return _this8; } return IOAlways; }(IO); var IOFlatMap = function (_IO4) { inherits(IOFlatMap, _IO4); function IOFlatMap(source, f, g) { classCallCheck(this, IOFlatMap); var _this9 = possibleConstructorReturn(this, (IOFlatMap.__proto__ || Object.getPrototypeOf(IOFlatMap)).call(this)); _this9.source = source; _this9.f = f; _this9.g = g; _this9._tag = "flatMap"; return _this9; } return IOFlatMap; }(IO); var IOAsync = function (_IO5) { inherits(IOAsync, _IO5); function IOAsync(register) { classCallCheck(this, IOAsync); var _this10 = possibleConstructorReturn(this, (IOAsync.__proto__ || Object.getPrototypeOf(IOAsync)).call(this)); _this10.register = register; _this10._tag = "async"; return _this10; } return IOAsync; }(IO); var IOMemoize = function (_IO6) { inherits(IOMemoize, _IO6); function IOMemoize(source, onlySuccess) { classCallCheck(this, IOMemoize); var _this11 = possibleConstructorReturn(this, (IOMemoize.__proto__ || Object.getPrototypeOf(IOMemoize)).call(this)); _this11._tag = "memoize"; _this11.source = source; _this11.result = null; _this11.onlySuccess = onlySuccess; return _this11; } return IOMemoize; }(IO); var IOContext = function () { function IOContext(scheduler) { var connection = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : new StackedCancelable(); var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : { autoCancelableRunLoops: false }; classCallCheck(this, IOContext); this.scheduler = scheduler; this.options = options; this.connection = connection; if (options.autoCancelableRunLoops) this.shouldCancel = function () { return connection.isCanceled(); }; } createClass(IOContext, [{ key: "markAsyncBoundary", value: function markAsyncBoundary() { this.scheduler.batchIndex = 0; } }, { key: "shouldCancel", value: function shouldCancel() { return false; } }]); return IOContext; }(); var IOModule = { map: function map(f, fa) { return fa.map(f); }, ap: function ap(ff, fa) { return fa.ap(ff); }, of: IO.pure, chain: function chain(f, fa) { return fa.flatMap(f); }, chainRec: function chainRec(f, a) { return IO.tailRecM(a, function (a) { return f(Either.left, Either.right, a); }); } }; coreInternals.fantasyLandRegister(IO, IOModule); function ioShift(ec) { return IO.asyncUnsafe(function (ctx, cb) { (ec || ctx.scheduler).executeAsync(function () { return cb(Try.unit()); }); }); } var ioShiftDefaultRef = ioShift(); function _ioPopNextBind(bFirst, bRest) { var f = undefined; if (bFirst) f = bFirst;else if (bRest && bRest.length > 0) f = bRest.pop(); if (f) return typeof f === "function" ? f : f[0]; return null; } function _ioFindErrorHandler(bFirst, bRest) { var cursor = bFirst; do { if (cursor && typeof cursor !== "function") return cursor[1]; cursor = bRest ? bRest.pop() : null; } while (cursor); return null; } var RestartCallback = function () { function RestartCallback(context, callback) { classCallCheck(this, RestartCallback); this.context = context; this.callback = callback; this.canCall = false; this.bFirst = null; this.bRest = null; this.asFunction = this.signal.bind(this); } createClass(RestartCallback, [{ key: "prepare", value: function prepare(bFirst, bRest) { this.bFirst = bFirst; this.bRest = bRest; this.canCall = true; } }, { key: "signal", value: function signal(result) { if (this.canCall) { this.canCall = false; ioGenericRunLoop(new IOPure(result), this.context.scheduler, this.context, this.callback, this, this.bFirst, this.bRest); } else if (result.isFailure()) { this.context.scheduler.reportFailure(result.failed().get()); } } }]); return RestartCallback; }(); function ioExecuteAsync(register, context, cb, rcb, bFirst, bRest, frameIndex) { if (!context.shouldCancel()) { context.scheduler.batchIndex = frameIndex; var restart = rcb || new RestartCallback(context, cb); restart.prepare(bFirst, bRest); register(context, restart.asFunction); } } function ioRestartAsync(start, context, cb, rcb, bFirstInit, bRestInit) { if (!context.shouldCancel()) context.scheduler.executeAsync(function () { ioGenericRunLoop(start, context.scheduler, context, cb, rcb, bFirstInit, bRestInit); }); } function ioGenericRunLoop(start, scheduler, context, cb, rcb, bFirstInit, bRestInit) { var current = start; var bFirst = bFirstInit; var bRest = bRestInit; var modulus = scheduler.executionModel.recommendedBatchSize - 1; var frameIndex = scheduler.batchIndex; while (true) { if (current instanceof Try) { if (current.isSuccess()) { var bind = _ioPopNextBind(bFirst, bRest); if (!bind) { scheduler.batchIndex = frameIndex; return cb(current); } try { current = bind(current.get()); } catch (e) { current = Try.failure(e); } } else { var _bind = _ioFindErrorHandler(bFirst, bRest); if (!_bind) { scheduler.batchIndex = frameIndex; return cb(current); } try { current = _bind(current.failed().get()); } catch (e) { current = Try.failure(e); } } bFirst = null; var nextIndex = frameIndex + 1 & modulus; if (nextIndex) { frameIndex = nextIndex; } else { var ctx = context || new IOContext(scheduler); var boxed = current instanceof Try ? new IOPure(current) : current; ioRestartAsync(boxed, ctx, cb, rcb, bFirst, bRest); return ctx.connection; } } else switch (current._tag) { case "pure": current = current.value; break; case "always": current = Try.of(current.thunk); break; case "once": current = current.runTry(); break; case "flatMap": var flatM = current; if (bFirst) { if (!bRest) bRest = []; bRest.push(bFirst); } bFirst = !flatM.g ? flatM.f : [flatM.f, flatM.g]; current = flatM.source; break; case "async": var async = current; var _ctx = context || new IOContext(scheduler); ioExecuteAsync(async.register, _ctx, cb, rcb, bFirst, bRest, frameIndex); return _ctx.connection; case "memoize": var mem = current; return ioStartMemoize(mem, scheduler, context, cb, bFirst, bRest, frameIndex); } } } function ioToFutureGoAsync(start, scheduler, bFirst, bRest, forcedAsync) { return Future.create(function (cb) { var ctx = new IOContext(scheduler); if (forcedAsync) ioRestartAsync(start, ctx, cb, null, bFirst, bRest);else ioGenericRunLoop(start, scheduler, ctx, cb, null, bFirst, bRest); return ctx.connection; }); } function taskToFutureRunLoop(start, scheduler) { var current = start; var bFirst = null; var bRest = null; var modulus = scheduler.executionModel.recommendedBatchSize - 1; var frameIndex = scheduler.batchIndex; while (true) { if (current instanceof Try) { if (current.isSuccess()) { var bind = _ioPopNextBind(bFirst, bRest); if (!bind) { scheduler.batchIndex = frameIndex; return Future.pure(current.get()); } try { current = bind(current.get()); } catch (e) { current = new IOPure(Try.failure(e)); } } else { var err = current.failed().get(); var _bind2 = _ioFindErrorHandler(bFirst, bRest); if (!_bind2) { scheduler.batchIndex = frameIndex; return Future.raise(err); } try { current = _bind2(err); } catch (e) { current = new IOPure(Try.failure(e)); } } bFirst = null; var nextIndex = frameIndex + 1 & modulus; if (nextIndex) { frameIndex = nextIndex; } else { return ioToFutureGoAsync(current, scheduler, bFirst, bRest, true); } } else switch (current._tag) { case "pure": current = current.value; break; case "always": current = Try.of(current.thunk); break; case "once": current = current.runTry(); break; case "flatMap": var flatM = current; if (bFirst) { if (!bRest) bRest = []; bRest.push(bFirst); } bFirst = !flatM.g ? flatM.f : [flatM.f, flatM.g]; current = flatM.source; break; case "async": case "memoize": return ioToFutureGoAsync(current, scheduler, bFirst, bRest, false); } } } function ioSafeCallback(ec, conn, cb) { var called = false; return function (r) { if (!called) { called = true; ec.trampoline(function () { conn.pop(); cb(r); }); } else if (r.isFailure()) { ec.reportFailure(r.failed().get()); } }; } function ioStartMemoize(fa, ec, context, cb, bFirstInit, bRestInit, frameIndex) { ec.batchIndex = frameIndex; var state = void 0; if (fa.result) { state = fa.result; } else { var f = ioToFutureGoAsync(fa.source, ec, null, null, false); if (f.value().isEmpty()) { fa.result = f; state = f; f.onComplete(function (r) { if (r.isSuccess() || !fa.onlySuccess) { fa.result = r; delete fa.source; } else { fa.result = null; } }); } else { state = f.value().get(); if (state.isSuccess() || !fa.onlySuccess) fa.result = state; } } var io = state instanceof Try ? new IOPure(state) : IO.fromFuture(state); ioGenericRunLoop(io, ec, context, cb, null, bFirstInit, bRestInit); } function ioSequence(list) { return IO.of(function () { return iteratorOf(list); }).flatMap(function (cursor) { return ioSequenceLoop([], cursor); }); } function ioSequenceLoop(acc, cursor) { var _loop = function _loop() { var elem = cursor.next(); var isDone = elem.done; if (elem.value) { var io = elem.value; return { v: io.flatMap(function (a) { acc.push(a); if (isDone) return IO.pure(acc); return ioSequenceLoop(acc, cursor); }) }; } else { if (isDone) return { v: IO.pure(acc) }; } }; while (true) { var _ret = _loop(); if ((typeof _ret === "undefined" ? "undefined" : _typeof(_ret)) === "object") return _ret.v; } } function ioListToFutureProcess(list, f) { return IO.asyncUnsafe(function (ctx, cb) { ctx.scheduler.trampoline(function () { var streamErrors = true; try { var futures = []; var array = execInternals.iterableToArray(list); streamErrors = false; for (var i = 0; i < array.length; i++) { var io = array[i]; var _f = io.run(ctx.scheduler); futures.push(_f); } var all = f(futures, ctx.scheduler); ctx.connection.push(all); all.onComplete(ioSafeCallback(ctx.scheduler, ctx.connection, cb)); } catch (e) { if (streamErrors) cb(Failure(e));else ctx.scheduler.reportFailure(e); } }); }); } export { Eval, EvalModule, IO, IOContext, IOModule }; //# sourceMappingURL=es5.js.map