funfix-effect
Version:
Sub-package of Funfix defining monadic data types for dealing with laziness and side effects
1,491 lines (1,354 loc) • 43.9 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('funfix-core'), require('funfix-exec')) :
typeof define === 'function' && define.amd ? define(['exports', 'funfix-core', 'funfix-exec'], factory) :
(factory((global.funfixEffect = {}),global.funfixCore,global.funfixExec));
}(this, (function (exports,funfixCore,funfixExec) { 'use strict';
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(funfixCore.Either.left, funfixCore.Either.right, a);
});
}
};
funfixCore.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] : funfixExec.Scheduler.global.get();
return taskToFutureRunLoop(this, ec);
}
}, {
key: "runOnComplete",
value: function runOnComplete(cb) {
var ec = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : funfixExec.Scheduler.global.get();
var ref = ioGenericRunLoop(this, ec, null, cb, null, null, null);
return ref || funfixExec.Cancelable.empty();
}
}, {
key: "attempt",
value: function attempt() {
return this.transform(function (_) {
return funfixCore.Either.left(_);
}, funfixCore.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(funfixCore.Some(e)).flatMap(function () {
return IO.raise(e);
});
}, function (a) {
return f(funfixCore.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(funfixExec.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 funfixCore.TimeoutError(funfixExec.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 || funfixExec.Cancelable.empty());
} catch (e) {
safe(funfixCore.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(funfixCore.Try.unit());
});
conn.push(task);
});
}
}, {
key: "firstCompletedOf",
value: function firstCompletedOf(list) {
return ioListToFutureProcess(list, funfixExec.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(funfixCore.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(funfixCore.Failure(e));
}
}, {
key: "sequence",
value: function sequence(list) {
return ioSequence(list);
}
}, {
key: "gather",
value: function gather(list) {
return ioListToFutureProcess(list, funfixExec.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(funfixCore.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 = funfixCore.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 funfixExec.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(funfixCore.Either.left, funfixCore.Either.right, a);
});
}
};
funfixCore.coreInternals.fantasyLandRegister(IO, IOModule);
function ioShift(ec) {
return IO.asyncUnsafe(function (ctx, cb) {
(ec || ctx.scheduler).executeAsync(function () {
return cb(funfixCore.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 funfixCore.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 = funfixCore.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 = funfixCore.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 funfixCore.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 = funfixCore.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 funfixExec.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 funfixCore.Try) {
if (current.isSuccess()) {
var bind = _ioPopNextBind(bFirst, bRest);
if (!bind) {
scheduler.batchIndex = frameIndex;
return funfixExec.Future.pure(current.get());
}
try {
current = bind(current.get());
} catch (e) {
current = new IOPure(funfixCore.Try.failure(e));
}
} else {
var err = current.failed().get();
var _bind2 = _ioFindErrorHandler(bFirst, bRest);
if (!_bind2) {
scheduler.batchIndex = frameIndex;
return funfixExec.Future.raise(err);
}
try {
current = _bind2(err);
} catch (e) {
current = new IOPure(funfixCore.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 = funfixCore.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 funfixCore.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 = funfixExec.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(funfixCore.Failure(e));else ctx.scheduler.reportFailure(e);
}
});
});
}
exports.Eval = Eval;
exports.EvalModule = EvalModule;
exports.IO = IO;
exports.IOContext = IOContext;
exports.IOModule = IOModule;
Object.defineProperty(exports, '__esModule', { value: true });
})));
//# sourceMappingURL=umd.js.map