result-core
Advanced tools
Comparing version 1.1.2 to 1.1.3
76
index.js
@@ -36,8 +36,8 @@ | ||
Result.prototype.write = function(value){ | ||
if (this.state == 'pending') { | ||
this.state = 'done' | ||
this.value = value | ||
this._onValue && run(this, this._onValue) | ||
} | ||
return this | ||
if (this.state == 'pending') { | ||
this.state = 'done' | ||
this.value = value | ||
this._onValue && run(this, this._onValue) | ||
} | ||
return this | ||
} | ||
@@ -53,8 +53,8 @@ | ||
Result.prototype.error = function(reason){ | ||
if (this.state == 'pending') { | ||
this.state = 'fail' | ||
this.value = reason | ||
this._onError && run(this, this._onError) | ||
} | ||
return this | ||
if (this.state == 'pending') { | ||
this.state = 'fail' | ||
this.value = reason | ||
this._onError && run(this, this._onError) | ||
} | ||
return this | ||
} | ||
@@ -71,6 +71,6 @@ | ||
function run(ctx, fns){ | ||
if (typeof fns == 'function') runFn(ctx, fns) | ||
else for (var i = 0, len = fns.length; i < len;) { | ||
runFn(ctx, fns[i++]) | ||
} | ||
if (typeof fns == 'function') runFn(ctx, fns) | ||
else for (var i = 0, len = fns.length; i < len;) { | ||
runFn(ctx, fns[i++]) | ||
} | ||
} | ||
@@ -99,4 +99,4 @@ | ||
function runFn(ctx, fn){ | ||
try { fn.call(ctx, ctx.value) } | ||
catch (e) { rethrow(e) } | ||
try { fn.call(ctx, ctx.value) } | ||
catch (e) { rethrow(e) } | ||
} | ||
@@ -113,20 +113,20 @@ | ||
Result.prototype.read = function(onValue, onError){ | ||
switch (this.state) { | ||
case 'pending': | ||
onValue && listen(this, '_onValue', onValue) | ||
listen(this, '_onError', onError || rethrow) | ||
break | ||
case 'done': | ||
onValue && runFn(this, onValue) | ||
break | ||
case 'fail': | ||
if (onError) runFn(this, onError) | ||
else rethrow(this.value) | ||
break | ||
} | ||
return this | ||
switch (this.state) { | ||
case 'pending': | ||
onValue && listen(this, '_onValue', onValue) | ||
listen(this, '_onError', onError || rethrow) | ||
break | ||
case 'done': | ||
onValue && runFn(this, onValue) | ||
break | ||
case 'fail': | ||
if (onError) runFn(this, onError) | ||
else rethrow(this.value) | ||
break | ||
} | ||
return this | ||
} | ||
function rethrow(error){ | ||
nextTick(function(){ throw error }) | ||
nextTick(function(){ throw error }) | ||
} | ||
@@ -144,6 +144,6 @@ | ||
function listen(obj, prop, fn){ | ||
var fns = obj[prop] | ||
if (!fns) obj[prop] = fn | ||
else if (typeof fns == 'function') obj[prop] = [fns, fn] | ||
else obj[prop].push(fn) | ||
} | ||
var fns = obj[prop] | ||
if (!fns) obj[prop] = fn | ||
else if (typeof fns == 'function') obj[prop] = [fns, fn] | ||
else obj[prop].push(fn) | ||
} |
{ | ||
"name": "result-core", | ||
"version": "1.1.2", | ||
"version": "1.1.3", | ||
"description": "minimal result reification", | ||
"keywords": ["result", "promise", "future"], | ||
"dependencies": { | ||
"inherit": "http://github.com/nathan7/inherit/tarball/f1a75b4844", | ||
"next-tick": "http://github.com/timoxley/next-tick/tarball/0.0.2", | ||
"inherit": "nathan7/inherit#f1a75b4844", | ||
"next-tick": "timoxley/next-tick#0.0.2", | ||
"result-type": "1.0.0" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git://github.com/jkroso/result-core.git" | ||
"devDependencies": { | ||
"serve": "jkroso/serve", | ||
"chai-spies": "*", | ||
"hydro-html": "*", | ||
"hydro-chai": "*", | ||
"hydro-bdd": "*", | ||
"hydro-dot": "*", | ||
"hydro": "*", | ||
"chai": "*", | ||
"jsmd": "*", | ||
"tryc": "*" | ||
}, | ||
"bugs": { | ||
"url": "https://github.com/jkroso/result-core/issues" | ||
}, | ||
"keywords": ["result", "computation", "promise", "future", "thenable", "reify"], | ||
"repository": "git://github.com/jkroso/result-core.git", | ||
"bugs": "https://github.com/jkroso/result-core/issues", | ||
"author": "Jake Rosoman", | ||
@@ -19,0 +26,0 @@ "license": "MIT", |
# result-core | ||
JavaScript doesn't allow you to spawn new threads. Nore does it allow you to park a thread progamatically. Instead it uses an "event loop", which functions as a sort of work queue. It allows you to request an operation and register a function to be called when its completed. This function is called a "callback" and it provides all the synchronisation we need to compose computations however it leaves our control flow model FUBAR. Normally we think of values and errors as propagating up and down an implicit call stack. When a child computation completes it is returned to its parent frame where it can be passed into other computation frames or simply ignored and allowed to propagate up the stack. Meanwhile, in the "event loop" model values/errors are passed in to the callbacks as arguments which means both that they never become available in the parent context and that they can't just be allowed to propagate. Also without callstack's our error objects are mostly garbage. | ||
JavaScript doesn't allow you to spawn new threads. Nore does it allow you to park a thread programmatically. Instead it uses an "event loop", which functions as a sort of work queue. It allows you to request an operation and register a function to be called when its completed. This function is called a "callback" and it provides all the synchronization we need to compose computations however it leaves our control flow model FUBAR. Normally we think of values and errors as propagating up and down an implicit call stack. When a child computation completes it is returned to its parent frame where it can be passed into other computation frames or simply ignored and allowed to propagate up the stack. Meanwhile, in the "event loop" model values/errors are passed in to the callbacks as arguments which means both that they never become available in the parent context and that they can't just be allowed to propagate. Also without callstack's our error objects are mostly garbage. | ||
Results are an attempt to re-build the call stack conceptual model back on top of the "event loop" model. The approach they take is to ask you to reify your asynchronous function calls with a Result instance. The intention of these is to model stack frames, in that they will eventually be either a successfully computed value or an error. Because these Result instances are runtime objects you can compose them together to recreate the computation tree that is normally implicit and maintained underneath the runtime. | ||
Results are an attempt to re-build the call stack conceptual model back on top of the "event loop" model. The approach they take is to ask you to reify your asynchronous function calls with a Result instance. The intention of these is to model stack frames, in that they will eventually be either a successfully computed value or an error. Because these Result instances are runtime objects you can compose them together to recreate the computation tree that is normally implicit and maintained underneath the runtime. | ||
This implementation does nothing to improve the stack traces of your errors but that feature could be added. | ||
This implementation does nothing to improve the stack traces of your errors but that feature could be added. | ||
## Installation | ||
_With [component](//github.com/component/component), [packin](//github.com/jkroso/packin) or [npm](//github.com/isaacs/npm)_ | ||
With your favorite package manager: | ||
$ {package mananger} install jkroso/result-core | ||
- [packin](//github.com/jkroso/packin): `packin add result-core` | ||
- [component](//github.com/component/component#installing-packages): `component install jkroso/result-core` | ||
- [npm](//npmjs.org/doc/cli/npm-install.html): `npm install result-core` | ||
@@ -26,5 +28,23 @@ then in your app: | ||
A class for creating concrete representations of function calls which can be manipulated programmatically at run-time. | ||
A class for creating concrete representations of function calls which can be manipulated programmatically at run-time. | ||
### Result.state | ||
The state of the result. Can be one of: | ||
- pending | ||
- done | ||
- fail | ||
All Results start of in a "pending" state and will transition either to "done" or "fail". | ||
```js | ||
new Result().state // => 'pending' | ||
``` | ||
### Result.value | ||
The value of the Result. If the Result has a state of "fail" then this value is an error. If its "pending" then reading its value is useless. You should use the read method unless you know what your doing and are handling each of the 3 possible states correctly. | ||
```js | ||
function add(a, b){ | ||
@@ -36,21 +56,39 @@ var result = new Result | ||
add(1, 2).read(function(n){ | ||
console.log('1 + 2 = %d', n) | ||
}) | ||
add(1, 2).value // => 3 | ||
``` | ||
### Result.write(value) | ||
### Result#write(value) | ||
give `this` its value | ||
give the Result its value and change its state to "done" | ||
### Result.error(reason) | ||
```js | ||
var one = new Result().write(1) | ||
one.state // => 'done' | ||
one.value // => 1 | ||
``` | ||
give `this` its reason for failure | ||
### Result#error(reason) | ||
### Result.read([onValue], [onError]) | ||
give the Result its error and change its state to "fail" | ||
```js | ||
var err = new Error('coz oops') | ||
var two = new Result().error(err) | ||
two.state // => 'fail' | ||
two.value // => err | ||
``` | ||
### Result#read([onValue], [onError]) | ||
access the result of `this` | ||
## Running the tests | ||
Just run `make`. It will install and start a development server so all you then need to do is point your browser to `localhost:3000/test`. Likewise to run the Koans. | ||
```js | ||
one.read(function(n){ | ||
n // => 1 | ||
}) // error handlers are optional | ||
two.read( | ||
null, // value handlers are also optional | ||
function(e){ | ||
e // => err | ||
}) | ||
``` |
GitHub dependency
Supply chain riskContains a dependency which resolves to a GitHub URL. Dependencies fetched from GitHub specifiers are not immutable can be used to inject untrusted code or reduce the likelihood of a reproducible install.
Found 2 instances in 1 package
No bug tracker
MaintenancePackage does not have a linked bug tracker in package.json.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
HTTP dependency
Supply chain riskContains a dependency which resolves to a remote HTTP URL which could be used to inject untrusted code and reduce overall package reliability.
Found 2 instances in 1 package
6737
122
93
10
2
1