Socket
Socket
Sign inDemoInstall

fluture

Package Overview
Dependencies
3
Maintainers
1
Versions
109
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 12.0.0-beta.3 to 12.0.0-beta.4

index.cjs

44

index.d.ts

@@ -66,3 +66,3 @@ declare module 'fluture' {

'fantasy-land/bimap'<LB, RB>(lmapper: (reason: L) => LB, rmapper: (value: R) => RB): FutureInstance<LB, RB>
'fantasy-land/chain'<RB>(mapper: (value: R) => FutureInstance<L, RB>): FutureInstance<L, RB>
'fantasy-land/chain'<LB, RB>(mapper: (value: R) => FutureInstance<LB, RB>): FutureInstance<L | LB, RB>

@@ -72,3 +72,3 @@ }

/** Creates a Future which resolves after the given duration with the given value. See https://github.com/fluture-js/Fluture#after */
export function after<L, R>(duration: number): (value: R) => FutureInstance<L, R>
export function after(duration: number): <R>(value: R) => FutureInstance<never, R>

@@ -85,6 +85,6 @@ /** Logical and for Futures. See https://github.com/fluture-js/Fluture#and */

/** Apply the function in the left Future to the value in the right Future. See https://github.com/fluture-js/Fluture#ap */
export function ap<L, RA, RB>(value: FutureInstance<L, RA>): (apply: FutureInstance<L, (value: RA) => RB>) => FutureInstance<L, RB>
export function ap<L, RA>(value: FutureInstance<L, RA>): <RB>(apply: FutureInstance<L, (value: RA) => RB>) => FutureInstance<L, RB>
/** Apply the function in the left ConcurrentFuture to the value in the right ConcurrentFuture. See https://github.com/fluture-js/Fluture#ap */
export function ap<L, RA, RB>(value: ConcurrentFutureInstance<L, RA>): (apply: ConcurrentFutureInstance<L, (value: RA) => RB>) => ConcurrentFutureInstance<L, RB>
export function ap<L, RA>(value: ConcurrentFutureInstance<L, RA>): <RB>(apply: ConcurrentFutureInstance<L, (value: RA) => RB>) => ConcurrentFutureInstance<L, RB>

@@ -98,6 +98,6 @@ /** Create a Future which resolves with the return value of the given function, or rejects with the error it throws. See https://github.com/fluture-js/Fluture#attempt */

/** Map over both branched of the given Bifunctor at once. See https://github.com/fluture-js/Fluture#bimap */
export function bimap<LA, LB, RA, RB>(lmapper: (reason: LA) => LB): (rmapper: (value: RA) => RB) => (source: FutureInstance<LA, RA>) => FutureInstance<LB, RB>
export function bimap<LA, LB>(lmapper: (reason: LA) => LB): <RA, RB>(rmapper: (value: RA) => RB) => (source: FutureInstance<LA, RA>) => FutureInstance<LB, RB>
/** Wait for both Futures to resolve in parallel. See https://github.com/fluture-js/Fluture#both */
export function both<L, A, B>(left: FutureInstance<L, A>): (right: FutureInstance<L, B>) => FutureInstance<L, [A, B]>
export function both<L, A>(left: FutureInstance<L, A>): <B>(right: FutureInstance<L, B>) => FutureInstance<L, [A, B]>

@@ -108,6 +108,6 @@ /** Cache the outcome of the given Future. See https://github.com/fluture-js/Fluture#cache */

/** Create a Future using the resolution value of the given Future. See https://github.com/fluture-js/Fluture#chain */
export function chain<L, RA, RB>(mapper: (value: RA) => FutureInstance<L, RB>): (source: FutureInstance<L, RA>) => FutureInstance<L, RB>
export function chain<LB, RA, RB>(mapper: (value: RA) => FutureInstance<LB, RB>): <LA>(source: FutureInstance<LA, RA>) => FutureInstance<LA | LB, RB>
/** Create a Future using the rejection reason of the given Future. See https://github.com/fluture-js/Fluture#chain */
export function chainRej<LA, LB, R>(mapper: (reason: LA) => FutureInstance<LB, R>): (source: FutureInstance<LA, R>) => FutureInstance<LB, R>
export function chainRej<LA, LB, RB>(mapper: (reason: LA) => FutureInstance<LB, RB>): <RA>(source: FutureInstance<LA, RA>) => FutureInstance<LB, RA | RB>

@@ -129,10 +129,10 @@ /** Fork the given Future into a Node-style callback. See https://github.com/fluture-js/Fluture#done */

/** Fold both branches into the resolution branch. See https://github.com/fluture-js/Fluture#fold */
export function fold<LA, RA, LB, RB>(lmapper: (left: LA) => RB): (rmapper: (right: RA) => RB) => (source: FutureInstance<LA, RA>) => FutureInstance<LB, RB>
/** Coalesce both branches into the resolution branch. See https://github.com/fluture-js/Fluture#coalesce */
export function coalesce<LA, R>(lmapper: (left: LA) => R): <RA>(rmapper: (right: RA) => R) => (source: FutureInstance<LA, RA>) => FutureInstance<never, R>
/** Fork the given Future into the given continuations. See https://github.com/fluture-js/Fluture#fork */
export function fork<L, R>(reject: RejectFunction<L>): (resolve: ResolveFunction<R>) => (source: FutureInstance<L, R>) => Cancel
export function fork<L>(reject: RejectFunction<L>): <R>(resolve: ResolveFunction<R>) => (source: FutureInstance<L, R>) => Cancel
/** Fork with exception recovery. See https://github.com/fluture-js/Fluture#forkCatch */
export function forkCatch<L, R>(recover: RecoverFunction): (reject: RejectFunction<L>) => (resolve: ResolveFunction<R>) => (source: FutureInstance<L, R>) => Cancel
export function forkCatch(recover: RecoverFunction): <L>(reject: RejectFunction<L>) => <R>(resolve: ResolveFunction<R>) => (source: FutureInstance<L, R>) => Cancel

@@ -143,3 +143,3 @@ /** Build a coroutine using Futures. See https://github.com/fluture-js/Fluture#go */

/** Manage resources before and after the computation that needs them. See https://github.com/fluture-js/Fluture#hook */
export function hook<L, H, R>(acquire: FutureInstance<L, H>): (dispose: (handle: H) => FutureInstance<any, any>) => (consume: (handle: H) => FutureInstance<L, R>) => FutureInstance<L, R>
export function hook<L, H>(acquire: FutureInstance<L, H>): (dispose: (handle: H) => FutureInstance<any, any>) => <R>(consume: (handle: H) => FutureInstance<L, R>) => FutureInstance<L, R>

@@ -153,12 +153,12 @@ /** Returns true for Futures. See https://github.com/fluture-js/Fluture#isfuture */

/** Set up a cleanup Future to run after the given action has settled. See https://github.com/fluture-js/Fluture#lastly */
export function lastly<L, R>(cleanup: FutureInstance<L, any>): (action: FutureInstance<L, R>) => FutureInstance<L, R>
export function lastly<L>(cleanup: FutureInstance<L, any>): <R>(action: FutureInstance<L, R>) => FutureInstance<L, R>
/** Map over the resolution value of the given Future. See https://github.com/fluture-js/Fluture#map */
export function map<L, RA, RB>(mapper: (value: RA) => RB): (source: FutureInstance<L, RA>) => FutureInstance<L, RB>
export function map<RA, RB>(mapper: (value: RA) => RB): <L>(source: FutureInstance<L, RA>) => FutureInstance<L, RB>
/** Map over the resolution value of the given ConcurrentFuture. See https://github.com/fluture-js/Fluture#map */
export function map<L, RA, RB>(mapper: (value: RA) => RB): (source: ConcurrentFutureInstance<L, RA>) => ConcurrentFutureInstance<L, RB>
export function map<RA, RB>(mapper: (value: RA) => RB): <L>(source: ConcurrentFutureInstance<L, RA>) => ConcurrentFutureInstance<L, RB>
/** Map over the rejection reason of the given Future. See https://github.com/fluture-js/Fluture#maprej */
export function mapRej<LA, LB, R>(mapper: (reason: LA) => LB): (source: FutureInstance<LA, R>) => FutureInstance<LB, R>
export function mapRej<LA, LB>(mapper: (reason: LA) => LB): <R>(source: FutureInstance<LA, R>) => FutureInstance<LB, R>

@@ -172,6 +172,6 @@ /** A Future that never settles. See https://github.com/fluture-js/Fluture#never */

/** Create a Future with the given resolution value. See https://github.com/fluture-js/Fluture#of */
export function resolve<L, R>(value: R): FutureInstance<L, R>
export function resolve<R>(value: R): FutureInstance<never, R>
/** Run an Array of Futures in parallel, under the given concurrency limit. See https://github.com/fluture-js/Fluture#parallel */
export function parallel<L, R>(concurrency: number): (futures: Array<FutureInstance<L, R>>) => FutureInstance<L, Array<R>>
export function parallel(concurrency: number): <L, R>(futures: Array<FutureInstance<L, R>>) => FutureInstance<L, Array<R>>

@@ -185,6 +185,6 @@ /** Convert a Future to a Promise. See https://github.com/fluture-js/Fluture#promise */

/** Create a Future with the given rejection reason. See https://github.com/fluture-js/Fluture#reject */
export function reject<L, R>(reason: L): FutureInstance<L, R>
export function reject<L>(reason: L): FutureInstance<L, never>
/** Creates a Future which rejects after the given duration with the given reason. See https://github.com/fluture-js/Fluture#rejectafter */
export function rejectAfter<L, R>(duration: number): (reason: L) => FutureInstance<L, R>
export function rejectAfter(duration: number): <L>(reason: L) => FutureInstance<L, never>

@@ -209,3 +209,3 @@ /** Convert a ConcurrentFuture to a regular Future. See https://github.com/fluture-js/Fluture#concurrentfuture */

resolve: ResolveFunction<R>
) => Cancel | void): FutureInstance<L, R>
) => Cancel): FutureInstance<L, R>

@@ -212,0 +212,0 @@ 'fantasy-land/chainRec'<L, I, R>(iterator: (next: (value: I) => Next<I>, done: (value: R) => Done<R>, value: I) => FutureInstance<L, Next<I> | Done<R>>, initial: I): FutureInstance<L, R>

@@ -1,1743 +0,46 @@

(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('sanctuary-type-identifiers'), require('sanctuary-show'), require('concurrify')) :
typeof define === 'function' && define.amd ? define(['sanctuary-type-identifiers', 'sanctuary-show', 'concurrify'], factory) :
(global = global || self, global.Fluture = factory(global.sanctuaryTypeIdentifiers, global.sanctuaryShow, global.concurrify));
}(this, function (type, show, concurrify) { 'use strict';
export {
Future as default,
Future,
isFuture,
isNever,
never,
reject,
resolve
} from './src/future.js';
type = type && type.hasOwnProperty('default') ? type['default'] : type;
show = show && show.hasOwnProperty('default') ? show['default'] : show;
concurrify = concurrify && concurrify.hasOwnProperty('default') ? concurrify['default'] : concurrify;
export {after} from './src/after.js';
export {alt} from './src/alt.js';
export {and} from './src/and.js';
export {ap} from './src/ap.js';
export {attemptP} from './src/attempt-p.js';
export {attempt} from './src/attempt.js';
export {bimap} from './src/bimap.js';
export {both} from './src/both.js';
export {cache} from './src/cache.js';
export {chainRej} from './src/chain-rej.js';
export {chain} from './src/chain.js';
export {done} from './src/done.js';
export {encaseP} from './src/encase-p.js';
export {encase} from './src/encase.js';
export {extractLeft} from './src/extract-left.js';
export {extractRight} from './src/extract-right.js';
export {coalesce} from './src/coalesce.js';
export {forkCatch} from './src/fork-catch.js';
export {fork} from './src/fork.js';
export {go} from './src/go.js';
export {hook} from './src/hook.js';
export {lastly} from './src/lastly.js';
export {mapRej} from './src/map-rej.js';
export {map} from './src/map.js';
export {node} from './src/node.js';
export {parallelAp} from './src/parallel-ap.js';
export {parallel} from './src/parallel.js';
export {Par} from './src/par.js';
export {promise} from './src/promise.js';
export {race} from './src/race.js';
export {rejectAfter} from './src/reject-after.js';
export {seq} from './src/seq.js';
export {swap} from './src/swap.js';
export {value} from './src/value.js';
var FL = {
alt: 'fantasy-land/alt',
ap: 'fantasy-land/ap',
bimap: 'fantasy-land/bimap',
chain: 'fantasy-land/chain',
chainRec: 'fantasy-land/chainRec',
map: 'fantasy-land/map',
of: 'fantasy-land/of',
zero: 'fantasy-land/zero'
};
var ordinal = ['first', 'second', 'third', 'fourth', 'fifth'];
var namespace = 'fluture';
var name = 'Future';
var version = 5;
var $$type = namespace + '/' + name + '@' + version;
function List(head, tail){
this.head = head;
this.tail = tail;
}
List.prototype.toJSON = function(){
return toArray(this);
};
var nil = new List(null, null);
nil.tail = nil;
function isNil(list){
return list.tail === list;
}
// cons :: (a, List a) -> List a
// -- O(1) append operation
function cons(head, tail){
return new List(head, tail);
}
// reverse :: List a -> List a
// -- O(n) list reversal
function reverse(xs){
var ys = nil, tail = xs;
while(!isNil(tail)){
ys = cons(tail.head, ys);
tail = tail.tail;
}
return ys;
}
// cat :: (List a, List a) -> List a
// -- O(n) list concatenation
function cat(xs, ys){
var zs = ys, tail = reverse(xs);
while(!isNil(tail)){
zs = cons(tail.head, zs);
tail = tail.tail;
}
return zs;
}
// toArray :: List a -> Array a
// -- O(n) list to Array
function toArray(xs){
var tail = xs, arr = [];
while(!isNil(tail)){
arr.push(tail.head);
tail = tail.tail;
}
return arr;
}
/* istanbul ignore next: non v8 compatibility */
var captureStackTrace = Error.captureStackTrace || captureStackTraceFallback;
var _debug = debugHandleNone;
function debugMode(debug){
_debug = debug ? debugHandleAll : debugHandleNone;
}
function debugHandleNone(x){
return x;
}
function debugHandleAll(x, fn, a, b, c){
return fn(a, b, c);
}
function debug(x, fn, a, b, c){
return _debug(x, fn, a, b, c);
}
function captureContext(previous, tag, fn){
return debug(previous, debugCaptureContext, previous, tag, fn);
}
function debugCaptureContext(previous, tag, fn){
var context = {tag: tag, name: ' from ' + tag + ':'};
captureStackTrace(context, fn);
return cons(context, previous);
}
function captureApplicationContext(context, n, f){
return debug(context, debugCaptureApplicationContext, context, n, f);
}
function debugCaptureApplicationContext(context, n, f){
return debugCaptureContext(context, ordinal[n - 1] + ' application of ' + f.name, f);
}
function captureStackTraceFallback(x){
var e = new Error;
/* istanbul ignore else: non v8 compatibility */
if(typeof e.stack === 'string'){
x.stack = x.name + '\n' + e.stack.split('\n').slice(1).join('\n');
}else{
x.stack = x.name;
}
}
/* istanbul ignore next: non v8 compatibility */
var setImmediate = typeof setImmediate === 'undefined' ? setImmediateFallback : setImmediate;
function noop(){}
function moop(){ return this }
function call(f, x){ return f(x) }
function setImmediateFallback(f, x){
return setTimeout(f, 0, x);
}
function raise(x){
setImmediate(function rethrowErrorDelayedToEscapePromiseCatch(){
throw x;
});
}
function showArg(x){
return show(x) + ' :: ' + type.parse(type(x)).name;
}
function error(message){
return new Error(message);
}
function typeError(message){
return new TypeError(message);
}
function invalidArgument(it, at, expected, actual){
return typeError(
it + '() expects its ' + ordinal[at] + ' argument to ' + expected + '.' +
'\n Actual: ' + showArg(actual)
);
}
function invalidArgumentOf(expected){
return function(it, at, actual){
return invalidArgument(it, at, expected, actual);
};
}
function invalidArity(f, args){
return new TypeError(
f.name + '() expects to be called with a single argument per invocation\n' +
' Saw: ' + args.length + ' arguments' +
Array.prototype.slice.call(args).map(function(arg, i){
return '\n ' + (
ordinal[i] ?
ordinal[i].charAt(0).toUpperCase() + ordinal[i].slice(1) :
'Argument ' + String(i + 1)
) + ': ' + showArg(arg);
}).join('')
);
}
function invalidNamespace(m, x){
return (
'The Future was not created by ' + namespace + '. '
+ 'Make sure you transform other Futures to ' + namespace + ' Futures. '
+ 'Got ' + (x ? ('a Future from ' + x) : 'an unscoped Future') + '.'
+ '\n See: https://github.com/fluture-js/Fluture#casting-futures'
);
}
function invalidVersion(m, x){
return (
'The Future was created by ' + (x < version ? 'an older' : 'a newer')
+ ' version of ' + namespace + '. '
+ 'This means that one of the sources which creates Futures is outdated. '
+ 'Update this source, or transform its created Futures to be compatible.'
+ '\n See: https://github.com/fluture-js/Fluture#casting-futures'
);
}
function invalidFuture(desc, m, s){
var id = type.parse(type(m));
var info = id.name === name ? '\n' + (
id.namespace !== namespace ? invalidNamespace(m, id.namespace)
: id.version !== version ? invalidVersion(m, id.version)
: 'Nothing seems wrong. Contact the Fluture maintainers.') : '';
return typeError(
desc + ' to be a valid Future.' + info + '\n' +
' Actual: ' + show(m) + ' :: ' + id.name + (s || '')
);
}
function invalidFutureArgument(it, at, m, s){
return invalidFuture(it + '() expects its ' + ordinal[at] + ' argument', m, s);
}
function ensureError(value, fn){
var message;
try{
if(value instanceof Error) return value;
message = 'A Non-Error was thrown from a Future: ' + show(value);
}catch (_){
message = 'Something was thrown from a Future, but it could not be converted to String';
}
var e = error(message);
captureStackTrace(e, fn);
return e;
}
function assignUnenumerable(o, prop, value){
Object.defineProperty(o, prop, {value: value, writable: true, configurable: true});
}
function wrapException(caught, callingFuture){
var origin = ensureError(caught, wrapException);
var context = cat(origin.context || nil, callingFuture.context);
var e = error(origin.message);
assignUnenumerable(e, 'future', origin.future || callingFuture);
assignUnenumerable(e, 'reason', origin.reason || origin);
assignUnenumerable(e, 'stack', e.reason.stack);
return withExtraContext(e, context);
}
function withExtraContext(e, context){
assignUnenumerable(e, 'context', context);
assignUnenumerable(e, 'stack', e.stack + contextToStackTrace(context));
return e;
}
function contextToStackTrace(context){
var stack = '', tail = context;
while(tail !== nil){
stack = stack + '\n' + tail.head.stack;
tail = tail.tail;
}
return stack;
}
function isFunction(f){
return typeof f === 'function';
}
function isThenable(m){
return m instanceof Promise || m != null && isFunction(m.then);
}
function isBoolean(f){
return typeof f === 'boolean';
}
function isNumber(f){
return typeof f === 'number';
}
function isUnsigned(n){
return (n === Infinity || isNumber(n) && n > 0 && n % 1 === 0);
}
function isObject(o){
return o !== null && typeof o === 'object';
}
function isIterator(i){
return isObject(i) && isFunction(i.next);
}
function isArray(x){
return Array.isArray(x);
}
function hasMethod(method, x){
return x != null && isFunction(x[method]);
}
function isFunctor(x){
return hasMethod(FL.map, x);
}
function isAlt(x){
return isFunctor(x) && hasMethod(FL.alt, x);
}
function isApply(x){
return isFunctor(x) && hasMethod(FL.ap, x);
}
function isBifunctor(x){
return isFunctor(x) && hasMethod(FL.bimap, x);
}
function isChain(x){
return isApply(x) && hasMethod(FL.chain, x);
}
function Next(x){
return {done: false, value: x};
}
function Done(x){
return {done: true, value: x};
}
function isIteration(x){
return isObject(x) && isBoolean(x.done);
}
/*eslint no-cond-assign:0, no-constant-condition:0 */
function alwaysTrue(){
return true;
}
function getArgs(it){
var args = new Array(it.arity);
for(var i = 1; i <= it.arity; i++){
args[i - 1] = it['$' + String(i)];
}
return args;
}
function showArg$1(arg){
return ' (' + show(arg) + ')';
}
var any = {pred: alwaysTrue, error: invalidArgumentOf('be anything')};
var func = {pred: isFunction, error: invalidArgumentOf('be a Function')};
var future = {pred: isFuture, error: invalidFutureArgument};
var positiveInteger = {pred: isUnsigned, error: invalidArgumentOf('be a positive Integer')};
function application(n, f, type, args, prev){
if(args.length < 2 && type.pred(args[0])) return captureApplicationContext(prev, n, f);
var e = args.length > 1 ? invalidArity(f, args) : type.error(f.name, n - 1, args[0]);
captureStackTrace(e, f);
throw withExtraContext(e, prev);
}
function application1(f, type, args){
return application(1, f, type, args, nil);
}
function Future(computation){
var context = application1(Future, func, arguments);
return new Computation(context, computation);
}
function isFuture(x){
return x instanceof Future || type(x) === $$type;
}
Future['@@type'] = $$type;
Future[FL.of] = resolve;
Future[FL.chainRec] = chainRec;
Future.prototype['@@show'] = function Future$show(){
return this.toString();
};
Future.prototype.pipe = function Future$pipe(f){
if(!isFunction(f)) throw invalidArgument('Future#pipe', 0, 'be a Function', f);
return f(this);
};
Future.prototype[FL.ap] = function Future$FL$ap(other){
var context = captureContext(nil, 'a Fantasy Land dispatch to ap', Future$FL$ap);
return other._transform(new ApTransformation(context, this));
};
Future.prototype[FL.map] = function Future$FL$map(mapper){
var context = captureContext(nil, 'a Fantasy Land dispatch to map', Future$FL$map);
return this._transform(new MapTransformation(context, mapper));
};
Future.prototype[FL.bimap] = function Future$FL$bimap(lmapper, rmapper){
var context = captureContext(nil, 'a Fantasy Land dispatch to bimap', Future$FL$bimap);
return this._transform(new BimapTransformation(context, lmapper, rmapper));
};
Future.prototype[FL.chain] = function Future$FL$chain(mapper){
var context = captureContext(nil, 'a Fantasy Land dispatch to chain', Future$FL$chain);
return this._transform(new ChainTransformation(context, mapper));
};
Future.prototype[FL.alt] = function Future$FL$alt(other){
var context = captureContext(nil, 'a Fantasy Land dispatch to alt', Future$FL$alt);
return this._transform(new AltTransformation(context, other));
};
Future.prototype.extractLeft = function Future$extractLeft(){
return [];
};
Future.prototype.extractRight = function Future$extractRight(){
return [];
};
Future.prototype._transform = function Future$transform(transformation){
return new Transformer(transformation.context, this, cons(transformation, nil));
};
Future.prototype.isTransformer = false;
Future.prototype.context = nil;
Future.prototype.arity = 0;
Future.prototype.name = 'future';
Future.prototype.toString = function Future$toString(){
return this.name + getArgs(this).map(showArg$1).join('');
};
Future.prototype.toJSON = function Future$toJSON(){
return {$: $$type, kind: 'interpreter', type: this.name, args: getArgs(this)};
};
function createInterpreter(arity, name, interpret){
var Interpreter = function(context, $1, $2, $3){
this.context = context;
this.$1 = $1;
this.$2 = $2;
this.$3 = $3;
};
Interpreter.prototype = Object.create(Future.prototype);
Interpreter.prototype.arity = arity;
Interpreter.prototype.name = name;
Interpreter.prototype._interpret = interpret;
return Interpreter;
}
var Computation =
createInterpreter(1, 'Future', function Computation$interpret(rec, rej, res){
var computation = this.$1, open = false, cancel = noop, cont = function(){ open = true; };
try{
cancel = computation(function Computation$rej(x){
cont = function Computation$rej$cont(){
open = false;
rej(x);
};
if(open){
cont();
}
}, function Computation$res(x){
cont = function Computation$res$cont(){
open = false;
res(x);
};
if(open){
cont();
}
}) || noop;
}catch(e){
rec(wrapException(e, this));
return noop;
}
if(!(isFunction(cancel) && cancel.length === 0)){
rec(wrapException(typeError(
'The computation was expected to return a nullary function or void\n' +
' Actual: ' + show(cancel)
), this));
return noop;
}
cont();
return function Computation$cancel(){
if(open){
open = false;
cancel && cancel();
}
};
});
var Never = createInterpreter(0, 'never', function Never$interpret(){
return noop;
});
Never.prototype._isNever = true;
var never = new Never(nil);
function isNever(x){
return isFuture(x) && x._isNever === true;
}
var Crash = createInterpreter(1, 'crash', function Crash$interpret(rec){
rec(this.$1);
return noop;
});
function crash(x){
return new Crash(application1(crash, any, arguments), x);
}
var Reject = createInterpreter(1, 'reject', function Reject$interpret(rec, rej){
rej(this.$1);
return noop;
});
Reject.prototype.extractLeft = function Reject$extractLeft(){
return [this.$1];
};
function reject(x){
return new Reject(application1(reject, any, arguments), x);
}
var Resolve = createInterpreter(1, 'resolve', function Resolve$interpret(rec, rej, res){
res(this.$1);
return noop;
});
Resolve.prototype.extractRight = function Resolve$extractRight(){
return [this.$1];
};
function resolve(x){
return new Resolve(application1(resolve, any, arguments), x);
}
//Note: This function is not curried because it's only used to satisfy the
// Fantasy Land ChainRec specification.
function chainRec(step, init){
return resolve(Next(init))._transform(new ChainTransformation(nil, function chainRec$recur(o){
return o.done ?
resolve(o.value) :
step(Next, Done, o.value)._transform(new ChainTransformation(nil, chainRec$recur));
}));
}
var Transformer =
createInterpreter(2, 'transform', function Transformer$interpret(rec, rej, res){
//These are the cold, and hot, transformation stacks. The cold actions are those that
//have yet to run parallel computations, and hot are those that have.
var cold = nil, hot = nil;
//These combined variables define our current state.
// future = the future we are currently forking
// transformation = the transformation to be informed when the future settles
// cancel = the cancel function of the current future
// settled = a boolean indicating whether a new tick should start
// async = a boolean indicating whether we are awaiting a result asynchronously
var future, transformation, cancel = noop, settled, async = true, it;
//Takes a transformation from the top of the hot stack and returns it.
function nextHot(){
var x = hot.head;
hot = hot.tail;
return x;
}
//Takes a transformation from the top of the cold stack and returns it.
function nextCold(){
var x = cold.head;
cold = cold.tail;
return x;
}
//This function is called with a future to use in the next tick.
//Here we "flatten" the actions of another Sequence into our own actions,
//this is the magic that allows for infinitely stack safe recursion because
//actions like ChainAction will return a new Sequence.
//If we settled asynchronously, we call drain() directly to run the next tick.
function settle(m){
settled = true;
future = m;
if(future.isTransformer){
var tail = future.$2;
while(!isNil(tail)){
cold = cons(tail.head, cold);
tail = tail.tail;
}
future = future.$1;
}
if(async) drain();
}
//This function serves as a rejection handler for our current future.
//It will tell the current transformation that the future rejected, and it will
//settle the current tick with the transformation's answer to that.
function rejected(x){
settle(transformation.rejected(x));
}
//This function serves as a resolution handler for our current future.
//It will tell the current transformation that the future resolved, and it will
//settle the current tick with the transformation's answer to that.
function resolved(x){
settle(transformation.resolved(x));
}
//This function is passed into actions when they are "warmed up".
//If the transformation decides that it has its result, without the need to await
//anything else, then it can call this function to force "early termination".
//When early termination occurs, all actions which were stacked prior to the
//terminator will be skipped. If they were already hot, they will also be
//sent a cancel signal so they can cancel their own concurrent computations,
//as their results are no longer needed.
function early(m, terminator){
cancel();
cold = nil;
if(async && transformation !== terminator){
transformation.cancel();
while((it = nextHot()) && it !== terminator) it.cancel();
}
settle(m);
}
//This will cancel the current Future, the current transformation, and all stacked hot actions.
function Sequence$cancel(){
cancel();
transformation && transformation.cancel();
while(it = nextHot()) it.cancel();
}
//This function is called when an exception is caught.
function exception(e){
Sequence$cancel();
settled = true;
cold = hot = nil;
var error = wrapException(e, future);
future = never;
rec(error);
}
//This function serves to kickstart concurrent computations.
//Takes all actions from the cold stack in reverse order, and calls run() on
//each of them, passing them the "early" function. If any of them settles (by
//calling early()), we abort. After warming up all actions in the cold queue,
//we warm up the current transformation as well.
function warmupActions(){
cold = reverse(cold);
while(cold !== nil){
it = cold.head.run(early);
if(settled) return;
hot = cons(it, hot);
cold = cold.tail;
}
transformation = transformation.run(early);
}
//This function represents our main execution loop. By "tick", we've been
//referring to the execution of one iteration in the while-loop below.
function drain(){
async = false;
while(true){
settled = false;
if(transformation = nextCold()){
cancel = future._interpret(exception, rejected, resolved);
if(!settled) warmupActions();
}else if(transformation = nextHot()){
cancel = future._interpret(exception, rejected, resolved);
}else break;
if(settled) continue;
async = true;
return;
}
cancel = future._interpret(exception, rej, res);
}
//Start the execution loop.
settle(this);
//Return the cancellation function.
return Sequence$cancel;
});
Transformer.prototype.isTransformer = true;
Transformer.prototype._transform = function Transformer$_transform(transformation){
return new Transformer(transformation.context, this.$1, cons(transformation, this.$2));
};
Transformer.prototype.toString = function Transformer$toString(){
return toArray(reverse(this.$2)).reduce(function(str, action){
return action.name + getArgs(action).map(showArg$1).join('') + ' (' + str + ')';
}, this.$1.toString());
};
function BaseTransformation$rejected(x){
this.cancel();
return new Reject(this.context, x);
}
function BaseTransformation$resolved(x){
this.cancel();
return new Resolve(this.context, x);
}
function BaseTransformation$toJSON(){
return {$: $$type, kind: 'transformation', type: this.name, args: getArgs(this)};
}
var BaseTransformation = {
rejected: BaseTransformation$rejected,
resolved: BaseTransformation$resolved,
run: moop,
cancel: noop,
context: nil,
arity: 0,
name: 'transform',
toJSON: BaseTransformation$toJSON
};
function wrapHandler(handler){
return function transformationHandler(x){
var m;
try{
m = handler.call(this, x);
}catch(e){
return new Crash(this.context, e);
}
if(isFuture(m)){
return m;
}
return new Crash(this.context, invalidFuture(
this.name + ' expects the return value from the function it\'s given', m,
'\n When called with: ' + show(x)
));
};
}
function createTransformation(arity, name, prototype){
var Transformation = function(context, $1, $2){
this.context = context;
this.$1 = $1;
this.$2 = $2;
};
Transformation.prototype = Object.create(BaseTransformation);
Transformation.prototype.arity = arity;
Transformation.prototype.name = name;
if(typeof prototype.rejected === 'function'){
Transformation.prototype.rejected = wrapHandler(prototype.rejected);
}
if(typeof prototype.resolved === 'function'){
Transformation.prototype.resolved = wrapHandler(prototype.resolved);
}
if(typeof prototype.run === 'function'){
Transformation.prototype.run = prototype.run;
}
return Transformation;
}
var ApTransformation = createTransformation(1, 'ap', {
resolved: function ApTransformation$resolved(f){
if(isFunction(f)) return this.$1._transform(new MapTransformation(this.context, f));
throw typeError(
'ap expects the second Future to resolve to a Function\n' +
' Actual: ' + show(f)
);
}
});
var AltTransformation = createTransformation(1, 'alt', {
rejected: function AltTransformation$rejected(){ return this.$1 }
});
var MapTransformation = createTransformation(1, 'map', {
resolved: function MapTransformation$resolved(x){
return new Resolve(this.context, call(this.$1, x));
}
});
var BimapTransformation = createTransformation(2, 'bimap', {
rejected: function BimapTransformation$rejected(x){
return new Reject(this.context, call(this.$1, x));
},
resolved: function BimapTransformation$resolved(x){
return new Resolve(this.context, call(this.$2, x));
}
});
var ChainTransformation = createTransformation(1, 'chain', {
resolved: function ChainTransformation$resolved(x){ return call(this.$1, x) }
});
var After = createInterpreter(2, 'after', function After$interpret(rec, rej, res){
var id = setTimeout(res, this.$1, this.$2);
return function After$cancel(){ clearTimeout(id); };
});
After.prototype.extractRight = function After$extractRight(){
return [this.$2];
};
function alwaysNever(_){
return never;
}
function after(time){
var context1 = application1(after, positiveInteger, arguments);
return time === Infinity ? alwaysNever : (function after(value){
var context2 = application(2, after, any, arguments, context1);
return new After(context2, time, value);
});
}
var alternative = {pred: isAlt, error: invalidArgumentOf('have Alt implemented')};
function alt(left){
if(isFuture(left)){
var context1 = application1(alt, future, arguments);
return function alt(right){
var context2 = application(2, alt, future, arguments, context1);
return right._transform(new AltTransformation(context2, left));
};
}
var context = application1(alt, alternative, arguments);
return function alt(right){
application(2, alt, alternative, arguments, context);
return left[FL.alt](right);
};
}
var AndTransformation = createTransformation(1, 'and', {
resolved: function AndTransformation$resolved(){ return this.$1 }
});
function and(left){
var context1 = application1(and, future, arguments);
return function and(right){
var context2 = application(2, and, future, arguments, context1);
return right._transform(new AndTransformation(context2, left));
};
}
var apply = {pred: isApply, error: invalidArgumentOf('have Apply implemented')};
function ap(mx){
if(isFuture(mx)){
var context1 = application1(ap, future, arguments);
return function ap(mf){
var context2 = application(2, ap, future, arguments, context1);
return mf._transform(new ApTransformation(context2, mx));
};
}
var context = application1(ap, apply, arguments);
return function ap(mf){
application(2, ap, apply, arguments, context);
return mx[FL.ap](mf);
};
}
function invalidPromise(p, f, a){
return typeError(
'encaseP() expects the function it\'s given to return a Promise/Thenable'
+ '\n Actual: ' + show(p) + '\n From calling: ' + show(f)
+ '\n With: ' + show(a)
);
}
var EncaseP = createInterpreter(2, 'encaseP', function EncaseP$interpret(rec, rej, res){
var open = true, fn = this.$1, arg = this.$2, p;
try{
p = fn(arg);
}catch(e){
rec(wrapException(e, this));
return noop;
}
if(!isThenable(p)){
rec(wrapException(invalidPromise(p, fn, arg), this));
return noop;
}
p.then(function EncaseP$res(x){
if(open){
open = false;
res(x);
}
}, function EncaseP$rej(x){
if(open){
open = false;
rej(x);
}
});
return function EncaseP$cancel(){ open = false; };
});
function encaseP(f){
var context1 = application1(encaseP, func, arguments);
return function encaseP(x){
var context2 = application(2, encaseP, any, arguments, context1);
return new EncaseP(context2, f, x);
};
}
function attemptP(_){
return encaseP.apply(this, arguments)(undefined);
}
var Encase = createInterpreter(2, 'encase', function Encase$interpret(rec, rej, res){
var fn = this.$1, r;
try{ r = fn(this.$2); }catch(e){ rej(e); return noop }
res(r);
return noop;
});
function encase(f){
var context1 = application1(encase, func, arguments);
return function encase(x){
var context2 = application(2, encase, any, arguments, context1);
return new Encase(context2, f, x);
};
}
function attempt(_){
return encase.apply(this, arguments)(undefined);
}
var bifunctor = {pred: isBifunctor, error: invalidArgumentOf('have Bifunctor implemented')};
function bimap(f){
var context1 = application1(bimap, func, arguments);
return function bimap(g){
var context2 = application(2, bimap, func, arguments, context1);
return function bimap(m){
var context3 = application(3, bimap, bifunctor, arguments, context2);
return isFuture(m) ?
m._transform(new BimapTransformation(context3, f, g)) :
m[FL.bimap](f, g);
};
};
}
function Eager(future){
var _this = this;
_this.rec = noop;
_this.rej = noop;
_this.res = noop;
_this.crashed = false;
_this.rejected = false;
_this.resolved = false;
_this.value = null;
_this.cancel = future._interpret(function Eager$crash(x){
_this.value = x;
_this.crashed = true;
_this.cancel = noop;
_this.rec(x);
}, function Eager$reject(x){
_this.value = x;
_this.rejected = true;
_this.cancel = noop;
_this.rej(x);
}, function Eager$resolve(x){
_this.value = x;
_this.resolved = true;
_this.cancel = noop;
_this.res(x);
});
}
Eager.prototype = Object.create(Future.prototype);
Eager.prototype._interpret = function Eager$interpret(rec, rej, res){
if(this.crashed) rec(this.value);
else if(this.rejected) rej(this.value);
else if(this.resolved) res(this.value);
else{
this.rec = rec;
this.rej = rej;
this.res = res;
}
return this.cancel;
};
function earlyCrash(early, x){
early(crash(x));
}
function earlyReject(early, x){
early(reject(x));
}
function earlyResolve(early, x){
early(resolve(x));
}
function createParallelTransformation(name, rec, rej, res, prototype){
var ParallelTransformation = createTransformation(1, name, Object.assign({
run: function Parallel$run(early){
var eager = new Eager(this.$1);
var transformation = new ParallelTransformation(this.context, eager);
function Parallel$early(m){ early(m, transformation); }
transformation.cancel = eager._interpret(
function Parallel$rec(x){ rec(Parallel$early, x); },
function Parallel$rej(x){ rej(Parallel$early, x); },
function Parallel$res(x){ res(Parallel$early, x); }
);
return transformation;
}
}, prototype));
return ParallelTransformation;
}
var PairTransformation = createTransformation(1, 'pair', {
resolved: function PairTransformation$resolved(x){
return new Resolve(this.context, [x, this.$1]);
}
});
var BothTransformation =
createParallelTransformation('both', earlyCrash, earlyReject, noop, {
resolved: function BothTransformation$resolved(x){
return this.$1._transform(new PairTransformation(this.context, x));
}
});
function both(left){
var context1 = application1(both, future, arguments);
return function both(right){
var context2 = application(2, both, future, arguments, context1);
return right._transform(new BothTransformation(context2, left));
};
}
var Cold = 0;
var Pending = 1;
var Crashed = 2;
var Rejected = 3;
var Resolved = 4;
function Queued(rec, rej, res){
this[Crashed] = rec;
this[Rejected] = rej;
this[Resolved] = res;
}
var Cache = createInterpreter(1, 'cache', function Cache$interpret(rec, rej, res){
var cancel = noop;
switch(this._state){
case Pending: cancel = this._addToQueue(rec, rej, res); break;
case Crashed: rec(this._value); break;
case Rejected: rej(this._value); break;
case Resolved: res(this._value); break;
default: cancel = this._addToQueue(rec, rej, res); this.run();
}
return cancel;
});
Cache.prototype._cancel = noop;
Cache.prototype._queue = [];
Cache.prototype._queued = 0;
Cache.prototype._value = undefined;
Cache.prototype._state = Cold;
Cache.prototype.extractLeft = function Cache$extractLeft(){
return this._state === Rejected ? [this._value] : [];
};
Cache.prototype.extractRight = function Cache$extractRight(){
return this._state === Resolved ? [this._value] : [];
};
Cache.prototype._addToQueue = function Cache$addToQueue(rec, rej, res){
var _this = this;
if(_this._state > Pending) return noop;
var i = _this._queue.push(new Queued(rec, rej, res)) - 1;
_this._queued = _this._queued + 1;
return function Cache$removeFromQueue(){
if(_this._state > Pending) return;
_this._queue[i] = undefined;
_this._queued = _this._queued - 1;
if(_this._queued === 0) _this.reset();
};
};
Cache.prototype._drainQueue = function Cache$drainQueue(){
if(this._state <= Pending) return;
if(this._queued === 0) return;
var queue = this._queue;
var length = queue.length;
var state = this._state;
var value = this._value;
for(var i = 0; i < length; i++){
queue[i] && queue[i][state](value);
queue[i] = undefined;
}
this._queue = undefined;
this._queued = 0;
};
Cache.prototype.crash = function Cache$crash(error){
if(this._state > Pending) return;
this._value = error;
this._state = Crashed;
this._drainQueue();
};
Cache.prototype.reject = function Cache$reject(reason){
if(this._state > Pending) return;
this._value = reason;
this._state = Rejected;
this._drainQueue();
};
Cache.prototype.resolve = function Cache$resolve(value){
if(this._state > Pending) return;
this._value = value;
this._state = Resolved;
this._drainQueue();
};
Cache.prototype.run = function Cache$run(){
var _this = this;
if(_this._state > Cold) return;
_this._state = Pending;
_this._cancel = _this.$1._interpret(
function Cache$fork$rec(x){ _this.crash(x); },
function Cache$fork$rej(x){ _this.reject(x); },
function Cache$fork$res(x){ _this.resolve(x); }
);
};
Cache.prototype.reset = function Cache$reset(){
if(this._state === Cold) return;
if(this._state === Pending) this._cancel();
this._cancel = noop;
this._queue = [];
this._queued = 0;
this._value = undefined;
this._state = Cold;
};
function cache(m){
return new Cache(application1(cache, future, arguments), m);
}
var ChainRejTransformation = createTransformation(1, 'chainRej', {
rejected: function ChainRejTransformation$rejected(x){ return call(this.$1, x) }
});
function chainRej(f){
var context1 = application1(chainRej, func, arguments);
return function chainRej(m){
var context2 = application(2, chainRej, future, arguments, context1);
return m._transform(new ChainRejTransformation(context2, f));
};
}
var monad = {pred: isChain, error: invalidArgumentOf('have Chain implemented')};
function chain(f){
var context1 = application1(chain, func, arguments);
return function chain(m){
var context2 = application(2, chain, monad, arguments, context1);
return isFuture(m) ?
m._transform(new ChainTransformation(context2, f)) :
m[FL.chain](f);
};
}
function done(callback){
var context1 = application1(done, func, arguments);
function done$res(x){
callback(null, x);
}
return function done(m){
application(2, done, future, arguments, context1);
return m._interpret(raise, callback, done$res);
};
}
function extractLeft(m){
application1(extractLeft, future, arguments);
return m.extractLeft();
}
function extractRight(m){
application1(extractRight, future, arguments);
return m.extractRight();
}
var FoldTransformation = createTransformation(2, 'fold', {
rejected: function FoldTransformation$rejected(x){
return new Resolve(this.context, call(this.$1, x));
},
resolved: function FoldTransformation$resolved(x){
return new Resolve(this.context, call(this.$2, x));
}
});
function fold(f){
var context1 = application1(fold, func, arguments);
return function fold(g){
var context2 = application(2, fold, func, arguments, context1);
return function fold(m){
var context3 = application(3, fold, future, arguments, context2);
return m._transform(new FoldTransformation(context3, f, g));
};
};
}
function forkCatch(f){
var context1 = application1(forkCatch, func, arguments);
return function forkCatch(g){
var context2 = application(2, forkCatch, func, arguments, context1);
return function forkCatch(h){
var context3 = application(3, forkCatch, func, arguments, context2);
return function forkCatch(m){
application(4, forkCatch, future, arguments, context3);
return m._interpret(f, g, h);
};
};
};
}
function fork(f){
var context1 = application1(fork, func, arguments);
return function fork(g){
var context2 = application(2, fork, func, arguments, context1);
return function fork(m){
application(3, fork, future, arguments, context2);
return m._interpret(raise, f, g);
};
};
}
var Undetermined = 0;
var Synchronous = 1;
var Asynchronous = 2;
/*eslint consistent-return: 0 */
function invalidIteration(o){
return typeError(
'The iterator did not return a valid iteration from iterator.next()\n' +
' Actual: ' + show(o)
);
}
function invalidState(x){
return invalidFuture(
'go() expects the value produced by the iterator', x,
'\n Tip: If you\'re using a generator, make sure you always yield a Future'
);
}
var Go = createInterpreter(1, 'go', function Go$interpret(rec, rej, res){
var _this = this, timing = Undetermined, cancel = noop, state, value, iterator;
function crash(e){
rec(wrapException(e, _this));
}
try{
iterator = _this.$1();
}catch(e){
crash(e);
return noop;
}
if(!isIterator(iterator)){
crash(invalidArgument('go', 0, 'return an iterator, maybe you forgot the "*"', iterator));
return noop;
}
function resolved(x){
value = x;
if(timing === Asynchronous) return drain();
timing = Synchronous;
}
function drain(){
//eslint-disable-next-line no-constant-condition
while(true){
try{
state = iterator.next(value);
}catch(e){
return crash(e);
}
if(!isIteration(state)) return crash(invalidIteration(state));
if(state.done) break;
if(!isFuture(state.value)){
return crash(invalidState(state.value));
}
timing = Undetermined;
cancel = state.value._interpret(crash, rej, resolved);
if(timing === Undetermined) return timing = Asynchronous;
}
res(state.value);
}
drain();
return function Go$cancel(){ cancel(); };
});
function go(generator){
return new Go(application1(go, func, arguments), generator);
}
function invalidDisposal(m, f, x){
return invalidFuture(
'hook() expects the return value from the first function it\'s given', m,
'\n From calling: ' + show(f) + '\n With: ' + show(x)
);
}
function invalidConsumption(m, f, x){
return invalidFuture(
'hook() expects the return value from the second function it\'s given', m,
'\n From calling: ' + show(f) + '\n With: ' + show(x)
);
}
var Hook = createInterpreter(3, 'hook', function Hook$interpret(rec, rej, res){
var _this = this, _acquire = this.$1, _dispose = this.$2, _consume = this.$3;
var cancel, cancelConsume = noop, resource, value, cont = noop;
function Hook$done(){
cont(value);
}
function Hook$rec(x){
rec(wrapException(x, _this));
}
function Hook$dispose(){
var disposal;
try{
disposal = _dispose(resource);
}catch(e){
return Hook$rec(e);
}
if(!isFuture(disposal)){
return Hook$rec(invalidDisposal(disposal, _dispose, resource));
}
cancel = Hook$cancelDisposal;
disposal._interpret(Hook$rec, Hook$disposalRejected, Hook$done);
}
function Hook$cancelConsumption(){
cancelConsume();
Hook$dispose();
Hook$cancelDisposal();
}
function Hook$cancelDisposal(){
cont = noop;
}
function Hook$disposalRejected(x){
Hook$rec(new Error('The disposal Future rejected with ' + show(x)));
}
function Hook$consumptionException(x){
cont = Hook$rec;
value = x;
Hook$dispose();
}
function Hook$consumptionRejected(x){
cont = rej;
value = x;
Hook$dispose();
}
function Hook$consumptionResolved(x){
cont = res;
value = x;
Hook$dispose();
}
function Hook$consume(x){
resource = x;
var consumption;
try{
consumption = _consume(resource);
}catch(e){
return Hook$consumptionException(e);
}
if(!isFuture(consumption)){
return Hook$consumptionException(invalidConsumption(consumption, _consume, resource));
}
cancel = Hook$cancelConsumption;
cancelConsume = consumption._interpret(
Hook$consumptionException,
Hook$consumptionRejected,
Hook$consumptionResolved
);
}
var cancelAcquire = _acquire._interpret(Hook$rec, rej, Hook$consume);
cancel = cancel || cancelAcquire;
return function Hook$fork$cancel(){
rec = raise;
cancel();
};
});
function hook(acquire){
var context1 = application1(hook, future, arguments);
return function hook(dispose){
var context2 = application(2, hook, func, arguments, context1);
return function hook(consume){
var context3 = application(3, hook, func, arguments, context2);
return new Hook(context3, acquire, dispose, consume);
};
};
}
var LastlyTransformation = createTransformation(1, 'lastly', {
rejected: function LastlyAction$rejected(x){
return this.$1._transform(new AndTransformation(this.context, new Reject(this.context, x)));
},
resolved: function LastlyAction$resolved(x){
return this.$1._transform(new AndTransformation(this.context, new Resolve(this.context, x)));
}
});
function lastly(cleanup){
var context1 = application1(lastly, future, arguments);
return function lastly(program){
var context2 = application(2, lastly, future, arguments, context1);
return program._transform(new LastlyTransformation(context2, cleanup));
};
}
var MapRejTransformation = createTransformation(1, 'mapRej', {
rejected: function MapRejTransformation$rejected(x){
return new Reject(this.context, call(this.$1, x));
}
});
function mapRej(f){
var context1 = application1(mapRej, func, arguments);
return function mapRej(m){
var context2 = application(2, mapRej, future, arguments, context1);
return m._transform(new MapRejTransformation(context2, f));
};
}
var functor = {pred: isFunctor, error: invalidArgumentOf('have Functor implemented')};
function map(f){
var context1 = application1(map, func, arguments);
return function map(m){
var context2 = application(2, map, functor, arguments, context1);
return isFuture(m) ?
m._transform(new MapTransformation(context2, f)) :
m[FL.map](f);
};
}
var Node = createInterpreter(1, 'node', function Node$interpret(rec, rej, res){
function Node$done(err, val){
cont = err ? function EncaseN3$rej(){
open = false;
rej(err);
} : function EncaseN3$res(){
open = false;
res(val);
};
if(open){
cont();
}
}
var open = false, cont = function(){ open = true; };
try{
call(this.$1, Node$done);
}catch(e){
rec(wrapException(e, this));
open = false;
return noop;
}
cont();
return function Node$cancel(){ open = false; };
});
function node(f){
return new Node(application1(node, func, arguments), f);
}
var ParallelApTransformation =
createParallelTransformation('parallelAp', earlyCrash, earlyReject, noop, {
resolved: function ParallelApTransformation$resolved(f){
if(isFunction(f)) return this.$1._transform(new MapTransformation(this.context, f));
throw typeError(
'parallelAp expects the second Future to resolve to a Function\n' +
' Actual: ' + show(f)
);
}
});
function parallelAp(mx){
var context1 = application1(parallelAp, future, arguments);
return function parallelAp(mf){
var context2 = application(2, parallelAp, future, arguments, context1);
return mf._transform(new ParallelApTransformation(context2, mx));
};
}
function isFutureArray(xs){
if(!isArray(xs)) return false;
for(var i = 0; i < xs.length; i++){
if(!isFuture(xs[i])) return false;
}
return true;
}
var futureArray = {
pred: isFutureArray,
error: invalidArgumentOf('be an Array of valid Futures')
};
var Parallel = createInterpreter(2, 'parallel', function Parallel$interpret(rec, rej, res){
var _this = this, futures = this.$2, length = futures.length;
var max = Math.min(this.$1, length), cancels = new Array(length), out = new Array(length);
var cursor = 0, running = 0, blocked = false, cont = noop;
function Parallel$cancel(){
rec = noop;
rej = noop;
res = noop;
cursor = length;
for(var n = 0; n < length; n++) cancels[n] && cancels[n]();
}
function Parallel$run(idx){
running++;
cancels[idx] = futures[idx]._interpret(function Parallel$rec(e){
cont = rec;
cancels[idx] = noop;
Parallel$cancel();
cont(wrapException(e, _this));
}, function Parallel$rej(reason){
cont = rej;
cancels[idx] = noop;
Parallel$cancel();
cont(reason);
}, function Parallel$res(value){
cancels[idx] = noop;
out[idx] = value;
running--;
if(cursor === length && running === 0) res(out);
else if(blocked) Parallel$drain();
});
}
function Parallel$drain(){
blocked = false;
while(cursor < length && running < max) Parallel$run(cursor++);
blocked = true;
}
Parallel$drain();
return Parallel$cancel;
});
var emptyArray = resolve([]);
function parallel(max){
var context1 = application1(parallel, positiveInteger, arguments);
return function parallel(ms){
var context2 = application(2, parallel, futureArray, arguments, context1);
return ms.length === 0 ? emptyArray : new Parallel(context2, max, ms);
};
}
var RaceTransformation =
createParallelTransformation('race', earlyCrash, earlyReject, earlyResolve, {});
function race(left){
var context1 = application1(race, future, arguments);
return function race(right){
var context2 = application(2, race, future, arguments, context1);
return right._transform(new RaceTransformation(context2, left));
};
}
function uncurry(f){
return function(a, b){
return f(a)(b);
};
}
var Par = concurrify(Future, never, uncurry(race), uncurry(parallelAp));
function isParallel(x){
return x instanceof Par || type(x) === Par['@@type'];
}
function promise(m){
application1(promise, future, arguments);
return new Promise(function promise$computation(res, rej){
m._interpret(rej, rej, res);
});
}
var RejectAfter =
createInterpreter(2, 'rejectAfter', function RejectAfter$interpret(rec, rej){
var id = setTimeout(rej, this.$1, this.$2);
return function RejectAfter$cancel(){ clearTimeout(id); };
});
RejectAfter.prototype.extractLeft = function RejectAfter$extractLeft(){
return [this.$2];
};
function alwaysNever$1(_){
return never;
}
function rejectAfter(time){
var context1 = application1(rejectAfter, positiveInteger, arguments);
return time === Infinity ? alwaysNever$1 : (function rejectAfter(value){
var context2 = application(2, rejectAfter, any, arguments, context1);
return new RejectAfter(context2, time, value);
});
}
var parallel$1 = {pred: isParallel, error: invalidArgumentOf('be a ConcurrentFuture')};
function seq(par){
application1(seq, parallel$1, arguments);
return par.sequential;
}
var SwapTransformation = createTransformation(0, 'swap', {
resolved: function SwapTransformation$resolved(x){
return new Reject(this.context, x);
},
rejected: function SwapTransformation$rejected(x){
return new Resolve(this.context, x);
}
});
function swap(m){
var context = application1(swap, future, arguments);
return m._transform(new SwapTransformation(context));
}
function value(res){
var context1 = application1(value, func, arguments);
return function value(m){
application(2, value, future, arguments, context1);
function value$rej(x){
raise(error(
'Future#value was called on a rejected Future\n' +
' Rejection: ' + show(x) + '\n' +
' Future: ' + show(m)
));
}
return m._interpret(raise, value$rej, res);
};
}
var Fluture = /*#__PURE__*/Object.freeze({
'default': Future,
Future: Future,
reject: reject,
resolve: resolve,
isFuture: isFuture,
never: never,
isNever: isNever,
after: after,
alt: alt,
and: and,
ap: ap,
attemptP: attemptP,
attempt: attempt,
bimap: bimap,
both: both,
cache: cache,
chainRej: chainRej,
chain: chain,
done: done,
encaseP: encaseP,
encase: encase,
extractLeft: extractLeft,
extractRight: extractRight,
fold: fold,
forkCatch: forkCatch,
fork: fork,
go: go,
hook: hook,
lastly: lastly,
mapRej: mapRej,
map: map,
node: node,
parallelAp: parallelAp,
parallel: parallel,
Par: Par,
promise: promise,
race: race,
rejectAfter: rejectAfter,
seq: seq,
swap: swap,
value: value,
debugMode: debugMode
});
var index_cjs = Object.assign(Future, Fluture);
return index_cjs;
}));
export {debugMode} from './src/internal/debug.js';
{
"name": "fluture",
"version": "12.0.0-beta.3",
"version": "12.0.0-beta.4",
"description": "FantasyLand compliant (monadic) alternative to Promises",
"main": "index",
"main": "index.cjs",
"type": "module",
"types": "index.d.ts",
"module": "index.mjs",
"module": "index.js",
"files": [
"src",
"index.cjs",
"index.js",
"index.mjs",
"index.d.ts"
"index.d.ts",
"test/arbitraries.js",
"test/assertions.js"
],
"repository": "https://github.com/fluture-js/Fluture.git",
"scripts": {
"bench": "npm run build && sanctuary-benchmark",
"bench": "NODE_OPTIONS='--experimental-modules --no-warnings' ./scripts/bench",
"build": "rollup -c rollup.config.js",
"build:dist": "rollup -c rollup.config.dist.js",
"clean": "rimraf npm-debug.log coverage index.js .esm-cache .nyc_output node_modules/.cache",
"lint": "eslint --ext mjs src test index.mjs index.cjs.mjs",
"clean": "rimraf npm-debug.log coverage index.cjs .esm-cache .nyc_output node_modules/.cache",
"lint": "eslint src test index.js index.cjs.js",
"lint:readme": "remark --no-stdout --frail -u remark-validate-links README.md",
"release": "xyz --edit --repo git@github.com:fluture-js/Fluture.git --tag 'X.Y.Z' --script scripts/distribute --increment",
"test": "npm run lint && npm run lint:readme && npm run test:unit && npm run test:prop && npm run test:integration && npm run test:types && npm run test:build",
"test:integration": "npm run clean && mocha --require esm --ui bdd --reporter list --full-trace --check-leaks --bail test/integration.js",
"test:unit": "npm run clean && mocha --require esm --ui bdd --reporter list --full-trace --check-leaks --bail test/unit.js",
"test:prop": "npm run clean && mocha --require esm --ui bdd --reporter list --full-trace --bail test/prop.js",
"test:build": "npm run clean && npm run build && es-check es5 index.js && mocha --require esm --ui bdd --reporter dot --bail test/build.js",
"test:coverage": "npm run clean && nyc --extension .mjs --include src mocha --require esm --ui bdd --reporter dot test/unit.js test/prop.js test/integration.js || true",
"coverage:upload": "nyc report --exclude-after-remap=false --reporter=text-lcov > coverage.lcov && codecov",
"coverage:report": "nyc report --exclude-after-remap=false --reporter=html",
"test": "npm run lint && npm run lint:readme && ./scripts/test-esm && npm run test:code && npm run test:types && npm run test:build",
"test:code": "c8 node --experimental-modules --no-warnings -- ./node_modules/.bin/oletus test/unit/*.js test/integration/*.js test/prop/*.js",
"test:mem": "NODE_OPTIONS='--experimental-modules --no-warnings' ./scripts/test-mem",
"test:build": "npm run build && node --experimental-modules --no-warnings -- ./node_modules/.bin/oletus test/build/*.js",
"coverage:upload": "c8 report --reporter=text-lcov > coverage.lcov && codecov",
"coverage:report": "c8 report --reporter=html",
"test:types": "tsc --lib es6 index.d.ts"

@@ -67,2 +68,3 @@ },

"devDependencies": {
"c8": "^5.0.4",
"chai": "^4.1.2",

@@ -73,7 +75,5 @@ "codecov": "^3.0.0",

"eslint-config-warp": "^3.0.0",
"esm": "^3.0.81",
"fantasy-laws": "^1.0.1",
"jsverify": "^0.8.3",
"mocha": "^6.1.2",
"nyc": "^14.1.1",
"oletus": "^2.0.0",
"ramda": "^0.26.1",

@@ -80,0 +80,0 @@ "remark-cli": "^7.0.0",

@@ -56,7 +56,27 @@ # [![Fluture](logo.png)](#butterfly)

### CommonJS Module
Although the Fluture source uses the EcmaScript module system,
the `main` file points to a CommonJS version of Fluture.
```js
const fs = require ('fs')
const Future = require ('fluture')
const getPackageName = function (file) {
return Future.node (function (done) { fs.readFile (file, 'utf8', done) })
.pipe (Future.chain (Future.encase (JSON.parse)))
.pipe (Future.map (function (x) { return x.name }))
}
getPackageName ('package.json')
.pipe (Future.fork (console.error) (console.log))
```
### EcmaScript Module
Fluture is written as modular JavaScript (`.mjs`). It can be loaded directly
by Node 9 and up using `--experimental-modules`, with the [esm loader][esm], or
with TypeScript (typings included).
Fluture is written as modular JavaScript. It can be loaded directly by Node 12
and up using `--experimental-modules`, or with the [esm loader][esm].
Note that the ESM code lives at `fluture/index.js`, which is not the `main`
file and must be imported explicitly.

@@ -68,3 +88,3 @@ Besides the module system, no other ES5+ features are used in Fluture's source,

import {readFile} from 'fs'
import {node, encase, chain, map, fork} from 'fluture'
import {node, encase, chain, map, fork} from 'fluture/index.js'

@@ -81,26 +101,6 @@ const getPackageName = file => (

### CommonJS Module
Although the Fluture source uses the EcmaScript module system, versions
downloaded from the npm registry include a CommonJS build, which will
automatically be used when loading Fluture with `require`.
```js
const fs = require ('fs')
const Future = require ('fluture')
const getPackageName = function (file) {
return Future.node (function (done) { fs.readFile (file, 'utf8', done) })
.pipe (Future.chain (Future.encase (JSON.parse)))
.pipe (Future.map (function (x) { return x.name }))
}
getPackageName ('package.json')
.pipe (Future.fork (console.error) (console.log))
```
### Global Bundle (CDN)
Fluture is hosted in full with all of its dependencies at
https://cdn.jsdelivr.net/gh/fluture-js/Fluture@12.0.0-beta.3/dist/bundle.js
https://cdn.jsdelivr.net/gh/fluture-js/Fluture@12.0.0-beta.4/dist/bundle.js

@@ -188,3 +188,3 @@ This script will add `Fluture` to the global scope.

- [`chainRej`: Asynchronously process the failure value in a Future](#chainrej)
- [`fold`: Coerce success and failure values into the same success value](#fold)
- [`coalesce`: Coerce success and failure values into the same success value](#coalesce)
- [`ap`: Combine the success values of multiple Futures using a function](#ap)

@@ -272,3 +272,3 @@ - [`and`: Logical *and* for Futures](#and)

- **Cancel** - The nullary [cancellation](#cancellation) functions returned from computations.
- **Catchable e f** - A function `f` which may throw an exception `e`.
- **Throwing e a b** - A function from `a` to `b` that may throw an exception `e`.
- **List** - Fluture's internal linked-list structure: `{ head :: Any, tail :: List }`.

@@ -551,5 +551,10 @@ - **Context** - Fluture's internal debugging context object:

Additionally, the computation may return a nullary function containing
Additionally, the computation must return a nullary function containing
cancellation logic. See [Cancellation](#cancellation).
If you find that there is no way to cancel your computation, you can return a
`noop` function as a cancellation function. However, at this point there is
usually a more fitting way to [create that Future](#creating-futures)
(like for example via [`node`](#node)).
```js

@@ -559,3 +564,4 @@ > fork (log ('rejection'))

. (Future (function computation (reject, resolve) {
. setTimeout (resolve, 20, 42)
. const t = setTimeout (resolve, 20, 42)
. return () => clearTimeout (t)
. }))

@@ -659,9 +665,9 @@ [resolution]: 42

To handle rejections *inside* the coroutine, we need to [`fold`](#fold) the
error into our control domain.
To handle rejections *inside* the coroutine, we need to [`coalesce`](#coalesce)
the error into our control domain.
I recommend folding into an [`Either`][S:Either].
I recommend using coalesce with an [`Either`][S:Either].
```js
> const control = fold (S.Left) (S.Right)
> const control = coalesce (S.Left) (S.Right)

@@ -680,3 +686,3 @@ > fork (log ('rejection')) (log ('resolution')) (go (function*() {

```hs
attempt :: Catchable e (Undefined -> r) -> Future e r
attempt :: Throwing e Undefined r -> Future e r
```

@@ -737,3 +743,3 @@

```hs
encase :: (Catchable e (a -> r)) -> a -> Future e r
encase :: Throwing e a r -> a -> Future e r
```

@@ -945,6 +951,6 @@

#### fold
#### coalesce
```hs
fold :: (a -> c) -> (b -> c) -> Future a b -> Future d c
coalesce :: (a -> c) -> (b -> c) -> Future a b -> Future d c
```

@@ -962,3 +968,3 @@

. (log ('resolution'))
. (fold (S.Left) (S.Right) (resolve ('hello'))
. (coalesce (S.Left) (S.Right) (resolve ('hello'))
[resolution]: Right ("hello")

@@ -968,3 +974,3 @@

. (log ('resolution'))
. (fold (S.Left) (S.Right) (reject ('It broke!'))
. (coalesce (S.Left) (S.Right) (reject ('It broke!'))
[resolution]: Left ("It broke!")

@@ -1179,3 +1185,3 @@ ```

if you are sure the Future is going to be resolved, for example; after using
[`fold`](#fold). If the Future rejects, `value` will throw an Error.
[`coalesce`](#coalesce). If the Future rejects, `value` will throw an Error.

@@ -1221,4 +1227,4 @@ As with [`fork`](#fork), `value` returns an `unsubscribe` function. See

If an exception was encountered during the computation, the promise will reject
with it. I recommend using [`fold`](#fold) before `promise` to ensure that
exceptions and rejections are not mixed into the Promise rejection branch.
with it. I recommend using [`coalesce`](#coalesce) before `promise` to ensure
that exceptions and rejections are not mixed into the Promise rejection branch.

@@ -1303,3 +1309,4 @@ Cancellation capabilities are lost when using `promise` to consume the Future.

the resulting Future will reject. If you want to settle all Futures, even if
some may fail, you can use `parallel` in combination with [fold](#fold).
some may fail, you can use `parallel` in combination with
[coalesce](#coalesce).

@@ -1310,3 +1317,3 @@ ```js

. (parallel (2) ([resolve (42), reject ('It broke!')]
. .map (fold (S.Left) (S.Right))))
. .map (coalesce (S.Left) (S.Right))))
[resolution]: [Right (42), Left ("It broke!")]

@@ -1313,0 +1320,0 @@ ```

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc