Socket
Socket
Sign inDemoInstall

fluture

Package Overview
Dependencies
2
Maintainers
1
Versions
109
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.3.1 to 0.4.0

197

fluture.js

@@ -75,3 +75,3 @@ /*global define*/

function check$chain$f(m, f, x){
if(!m || typeof m.fork !== 'function') throw new TypeError(error(
if(!(m instanceof FutureClass)) throw new TypeError(error(
'Future#chain expects the function its given to return a Future',

@@ -92,3 +92,3 @@ `${toString(m)}\n From calling: ${toString(f)}\n With: ${toString(x)}`

function check$ap(m){
if(!m || typeof m.fork !== 'function') throw new TypeError(error(
if(!(m instanceof FutureClass)) throw new TypeError(error(
'Future#ap expects its argument to be a Future',

@@ -107,5 +107,61 @@ toString(m)

function check$liftNode(f){
if(typeof f !== 'function') throw new TypeError(error(
'Future.liftNode expects its first argument to be a function',
toString(f)
));
}
function check$liftPromise(f){
if(typeof f !== 'function') throw new TypeError(error(
'Future.liftPromise expects its first argument to be a function',
toString(f)
));
}
function check$liftPromise$f(m, f, x){
if(!m || typeof m.then !== 'function') throw new TypeError(error(
'Future.liftPromise expects the function its given to return a Promise',
`${toString(m)}\n From calling: ${toString(f)}\n With: ${toString(x)}`
));
}
function check$after(n){
if(typeof n !== 'number') throw new TypeError(error(
'Future.after expects its first argument to be a number',
toString(n)
));
}
function check$try(f){
if(typeof f !== 'function') throw new TypeError(error(
'Future.try expects its first argument to be a function',
toString(f)
));
}
function check$node(f){
if(typeof f !== 'function') throw new TypeError(error(
'Future.node expects its first argument to be a function',
toString(f)
));
}
function check$race$m1(m){
if(!(m instanceof FutureClass)) throw new TypeError(error(
'Future.race expects its first argument to be a Future',
toString(m)
));
}
function check$race$m2(m){
if(!(m instanceof FutureClass)) throw new TypeError(error(
'Future.race expects its second argument to be a Future',
toString(m)
));
}
//The of method.
function Future$of(x){
return new Future(function Future$of$fork(rej, res){
return new FutureClass(function Future$of$fork(rej, res){
res(x)

@@ -116,4 +172,3 @@ });

//Constructor.
function Future(f){
check$Future(f);
function FutureClass(f){
this._f = f;

@@ -123,8 +178,9 @@ }

//A createFuture function which pretends to be Future.
function createFuture(f){
return new Future(f);
function Future(f){
check$Future(f);
return new FutureClass(f);
}
//Give Future a prototype.
Future.prototype = createFuture.prototype = {
FutureClass.prototype = Future.prototype = {

@@ -144,7 +200,7 @@ _f: null,

const _this = this;
return new Future(function Future$chain$fork(rej, res){
_this.fork(rej, function Future$chain$res(x){
return new FutureClass(function Future$chain$fork(rej, res){
_this._f(rej, function Future$chain$res(x){
const m = f(x);
check$chain$f(m, f, x);
m.fork(rej, res);
m._f(rej, res);
});

@@ -157,4 +213,4 @@ });

const _this = this;
return new Future(function Future$map$fork(rej, res){
_this.fork(rej, function Future$map$res(x){
return new FutureClass(function Future$map$fork(rej, res){
_this._f(rej, function Future$map$res(x){
res(f(x));

@@ -168,6 +224,6 @@ });

const _this = this;
return new Future(function Future$ap$fork(g, h){
return new FutureClass(function Future$ap$fork(g, h){
let _f, _x, ok1, ok2, ko;
const rej = x => ko || (ko = 1, g(x));
_this.fork(rej, function Future$ap$resThis(f){
_this._f(rej, function Future$ap$resThis(f){
if(!ok2) return void (ok1 = 1, _f = f);

@@ -177,3 +233,3 @@ check$ap$f(f);

});
m.fork(rej, function Future$ap$resThat(x){
m._f(rej, function Future$ap$resThat(x){
if(!ok1) return void (ok2 = 1, _x = x)

@@ -193,12 +249,24 @@ check$ap$f(_f);

//Expose `of` statically as well.
Future[FL.of] = createFuture[FL.of] = Future$of;
Future[FL.of] = Future[FL.of] = Future$of;
//Expose Future statically for ease of destructuring.
createFuture.Future = Future;
Future.Future = Future;
//Turn a continuation-passing-style function into a function which returns a Future.
createFuture.liftNode = function Future$liftNode(f){
/**
* Turn a node continuation-passing-style function into a function which returns a Future.
*
* Takes a function which uses a node-style callback for continuation and
* returns a function which returns a Future for continuation.
*
* @sig liftNode :: (x..., (a, b -> Void) -> Void) -> x... -> Future[a, b]
*
* @param {Function} f The node function to wrap.
*
* @return {Function} A function which returns a Future.
*/
Future.liftNode = function Future$liftNode(f){
check$liftNode(f);
return function Future$liftNode$lifted(){
const xs = arguments;
return new Future(function Future$liftNode$fork(rej, res){
return new FutureClass(function Future$liftNode$fork(rej, res){
return f(...xs, function Future$liftNode$callback(err, result){

@@ -211,8 +279,19 @@ err ? rej(err) : res(result);

//Turn a function which returns a Promise into a function which returns a Future.
createFuture.liftPromise = function Future$liftPromise(f){
/**
* Turn a function which returns a Promise into a function which returns a Future.
*
* @sig liftPromise :: (x... -> a) -> x... -> Future[Error, a]
*
* @param {Function} f The function to wrap.
*
* @return {Function} A function which returns a Future.
*/
Future.liftPromise = function Future$liftPromise(f){
check$liftPromise(f);
return function Future$liftPromise$lifted(){
const xs = arguments;
return new Future(function Future$liftPromise$fork(rej, res){
return f(...xs).then(res, rej);
return new FutureClass(function Future$liftPromise$fork(rej, res){
const m = f(...xs);
check$liftPromise$f(m, f, xs);
return m.then(res, rej);
});

@@ -223,4 +302,4 @@ };

//Create a Future which rejects witth the given value.
createFuture.reject = function Future$reject(x){
return new Future(function Future$reject$fork(rej){
Future.reject = function Future$reject(x){
return new FutureClass(function Future$reject$fork(rej){
rej(x);

@@ -231,4 +310,5 @@ });

//Create a Future which resolves after the given time with the given value.
createFuture.after = curry(function Future$after(n, x){
return new Future(function Future$after$fork(rej, res){
Future.after = curry(function Future$after(n, x){
check$after(n);
return new FutureClass(function Future$after$fork(rej, res){
setTimeout(res, n, x);

@@ -240,4 +320,5 @@ })

//or rejects with the exception thrown by the given function.
createFuture.try = function Future$try(f){
return new Future(function Future$try$fork(rej, res){
Future.try = function Future$try(f){
check$try(f);
return new FutureClass(function Future$try$fork(rej, res){
try{

@@ -252,5 +333,57 @@ res(f());

/**
* Allow one-off wrapping of a function that requires a node-style callback.
*
* @sig fromNode :: ((err, a) -> Void) -> Future[Error, a]
*
* @param {Function} f The operation expected to eventaully call the callback.
*
* @return {Future}
*
* @example
*
* node(done => MySql.connect(done))
* .fork(console.error, console.log)
*
*/
Future.node = function Future$node(f){
check$node(f);
return new FutureClass(function Future$node$fork(rej, res){
f((a, b) => a ? rej(a) : res(b));
});
};
/**
* Race two Futures against eachother.
*
* Creates a new Future which resolves or rejects with the resolution or
* rejection value of the first Future to settle.
*
* @param {Future} m1 The first Future.
* @param {Future} m2 The second Future.
*
* @return {Future}
*
* @example
*
* race(
* Future(rej => setTimeout(rej, 8000, new Error('Request timed out'))),
* fromNode(done => request('http://example.com', done))
* )
*
*/
Future.race = curry(function Future$race(m1, m2){
check$race$m1(m1);
check$race$m2(m2);
return new FutureClass(function Future$race$fork(rej, res){
let settled = false;
const once = f => a => settled || (settled = true, f(a));
m1._f(once(rej), once(res));
m2._f(once(rej), once(res));
});
});
//Export Future factory.
return createFuture;
return Future;
}));

2

package.json
{
"name": "fluture",
"version": "0.3.1",
"version": "0.4.0",
"description": "A complete Fantasy Land compatible Future library",

@@ -5,0 +5,0 @@ "main": "fluture.js",

@@ -7,2 +7,13 @@ # Fluture

## Usage
```js
Future.node(done => fs.readFile('package.json', 'utf8', done))
.chain(x => Future.try(() => JSON.parse(x)))
.map(x => x.name)
.fork(console.error, console.log)
//> "fluture"
```
## Motivation

@@ -15,2 +26,120 @@

## Documentation
### Future
A (monadic) container which represents an eventual value. A lot like Promise but
more principled in that it follows the Fantasy Land algebraic JavaScript
specification.
```js
const eventualThing = Future((reject, resolve) => {
setTimeout(resolve, 500, 'world');
});
eventualThing.fork(console.error, thing => console.log(`Hello ${thing}!`));
//> "Hello world!"
```
----
#### `of :: b -> Future a b`
A constructor that creates a Future containing the given value.
```js
const eventualThing = Future.of('world');
eventualThing.fork(console.error, thing => console.log(`Hello ${thing}!`));
//> "Hello world!"
```
#### `after :: Number -> b -> Future a b`
A constructor that creates a Future containing the given value after n milliseconds.
```js
const eventualThing = Future.after(500, 'world');
eventualThing.fork(console.error, thing => console.log(`Hello ${thing}!`));
//> "Hello world!"
```
#### `try :: (Void -> !a | b) -> Future a b`
A constructor that creates a Future which resolves with the result of calling
the given function, or rejects with the error thrown by the given function.
```js
const data = {foo: 'bar'}
Future.try(() => data.foo.bar.baz).fork(console.error, console.log)
//> [TypeError: Cannot read property 'baz' of undefined]
```
#### `node :: ((a, b -> Void) -> Void) -> Future a b`
A constructor that creates a Future which rejects with the first argument given
to the function, or resolves with the second if the first is not present.
This is a convenience for NodeJS users who wish to easily obtain a Future from
a node style callback API.
```js
Future.node(done => fs.readFile('package.json', 'utf8', done))
.fork(console.error, console.log)
//> "{...}"
```
----
#### `map :: Future a b ~> (b -> c) -> Future a c`
Map over the value inside the Future. If the Future is rejected, mapping is not
performed.
```js
Future.of(1).map(x => x + 1).fork(console.error, console.log);
//> 2
```
#### `chain :: Future a b ~> (b -> Future a c) -> Future a c`
FlatMap over the value inside the Future. If the Future is rejected, chaining is
not performed.
```js
Future.of(1).chain(x => Future.of(x + 1)).fork(console.error, console.log);
//> 2
```
#### `ap :: Future a (b -> c) ~> Future a b -> Future a c`
Apply the value in the Future to the value in the given Future. If the Future is
rejected, applying is not performed.
```js
Future.of(x => x + 1).ap(Future.of(1)).fork(console.error, console.log);
//> 2
```
----
#### `race :: Future a b -> Future a b -> Future a b`
Race two Futures against eachother. Creates a new Future which resolves or
rejects with the resolution or rejection value of the first Future to settle.
```js
Future.race(Future.after(100, 'hello'), Future.after(50, 'bye'))
.fork(console.error, console.log)
//> "bye"
const first = futures => futures.reduce(Future.race);
first([
Future.after(100, 'hello'),
Future.after(50, 'bye'),
Future(rej => setTimeout(rej, 25, 'nope'))
])
.fork(console.error, console.log)
//> [Error nope]
```
## Road map

@@ -28,8 +157,18 @@

* [ ] Implement Future.or
* [ ] Implement Future.race
* [x] Implement Future.race
* [ ] Implement Future.parallel
* [ ] Create documentation
* [x] Create documentation
* [ ] Wiki: Comparison between Future libs
* [ ] Wiki: Comparison Future and Promise
* [ ] Add test coverage
* [ ] A transpiled ES5 version if demand arises
## Benchmarks
Simply run `node ./bench/<file>` to see how a specific method compares to
implementations in `data.task`, `ramda-fantasy.Future` and `Promise`*.
\* Promise is not included in all benchmarks because it tends to make the
process run out of memory.
## The name

@@ -36,0 +175,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