Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
lvivski committed Oct 9, 2013
0 parents commit d407313
Show file tree
Hide file tree
Showing 9 changed files with 221 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules
31 changes: 31 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
JS_COMPILER ?= ./node_modules/uglify-js/bin/uglifyjs
FILES = \
src/troth.js \
src/promise.js \

all: \
troth.js \
troth.min.js

troth.js: ${FILES}
@rm -f $@
@echo "(function(global){" > $@.tmp
@echo "'use strict'" >> $@.tmp
@cat $(filter %.js,$^) >> $@.tmp
@echo "}(this))" >> $@.tmp
@$(JS_COMPILER) $@.tmp -b indent-level=2 -o $@
@rm $@.tmp
@chmod a-w $@

troth.min.js: troth.js
@rm -f $@
@$(JS_COMPILER) $< -c -m -o $@ \
--source-map $@.map \
&& du -h $< $@

deps:
mkdir -p node_modules
npm install

clean:
rm -f troth*.js*
1 change: 1 addition & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require('./troth.js')
13 changes: 13 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"name": "troth",
"version": "0.0.1",
"dependencies": {
"subsequent": "*"
},
"scripts": {
"prepublish": "make -B"
},
"devDependencies": {
"uglify-js": "*"
}
}
83 changes: 83 additions & 0 deletions src/promise.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
function Promise(value) {
this.value = value
this.deferreds = []
}

Promise.SUCCESS = 'fulfill'
Promise.FAILURE = 'reject'
Promise.isPromise = function (obj) {
return obj && typeof obj.then === 'function'
}

Promise.prototype.isFulfilled = false
Promise.prototype.isRejected = false

Promise.prototype.then = function (onFulfill, onReject) {
var promise = new Promise,
deferred = defer(promise, onFulfill, onReject)

if (this.isFulfilled || this.isRejected) {
resolve(deferred, this.isFulfilled ? Promise.SUCCESS : Promise.FAILURE, this.value)
} else {
this.deferreds.push(deferred)
}

return promise
}

Promise.prototype.fulfill = function (value) {
if (this.isFulfilled || this.isRejected) return
this.isFulfilled = true

this.complete(Promise.SUCCESS, value)
}

Promise.prototype.reject = function (error) {
if (this.isFulfilled || this.isRejected) return
this.isRejected = true

this.complete(Promise.FAILURE, error)
}

Promise.prototype.complete = function (type, value) {
this.value = value
for (var i = 0; i < this.deferreds.length; ++i) {
resolve(this.deferreds[i], type, value)
}
this.deferreds = undefined
}

function resolve(deferred, type, value) {
nextTick(function () {
var fn = deferred[type],
promise = deferred.promise,
res
if (typeof fn === 'function') {
try {
res = fn(value)
} catch(e) {
promise.reject(e)
return
}
if (Promise.isPromise(res)) {
res.then(function (val) {
promise.fulfill(val)
}, function (err) {
promise.reject(err)
})
} else {
promise[type](res)
}
} else {
promise[type](value)
}
})
}

function defer(promise, fulfill, reject) {
return {
promise: promise,
fulfill: fulfill,
reject: reject
}
}
9 changes: 9 additions & 0 deletions src/troth.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
if (typeof define === 'function' && define.amd) {
define(Promise)
} else if (typeof module === 'object' && module.exports) {
module.exports = Promise
var nextTick = require('subsequent')
} else {
global.Troth = global.Promise = Promise
var nextTick = global.nextTick
}
80 changes: 80 additions & 0 deletions troth.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
(function(global) {
"use strict";
if (typeof define === "function" && define.amd) {
define(Promise);
} else if (typeof module === "object" && module.exports) {
module.exports = Promise;
var nextTick = require("subsequent");
} else {
global.Troth = global.Promise = Promise;
var nextTick = global.nextTick;
}
function Promise(value) {
this.value = value;
this.deferreds = [];
}
Promise.SUCCESS = "fulfill";
Promise.FAILURE = "reject";
Promise.isPromise = function(obj) {
return obj && typeof obj.then === "function";
};
Promise.prototype.isFulfilled = false;
Promise.prototype.isRejected = false;
Promise.prototype.then = function(onFulfill, onReject) {
var promise = new Promise(), deferred = defer(promise, onFulfill, onReject);
if (this.isFulfilled || this.isRejected) {
resolve(deferred, this.isFulfilled ? Promise.SUCCESS : Promise.FAILURE, this.value);
} else {
this.deferreds.push(deferred);
}
return promise;
};
Promise.prototype.fulfill = function(value) {
if (this.isFulfilled || this.isRejected) return;
this.isFulfilled = true;
this.complete(Promise.SUCCESS, value);
};
Promise.prototype.reject = function(error) {
if (this.isFulfilled || this.isRejected) return;
this.isRejected = true;
this.complete(Promise.FAILURE, error);
};
Promise.prototype.complete = function(type, value) {
this.value = value;
for (var i = 0; i < this.deferreds.length; ++i) {
resolve(this.deferreds[i], type, value);
}
this.deferreds = undefined;
};
function resolve(deferred, type, value) {
nextTick(function() {
var fn = deferred[type], promise = deferred.promise, res;
if (typeof fn === "function") {
try {
res = fn(value);
} catch (e) {
promise.reject(e);
return;
}
if (Promise.isPromise(res)) {
res.then(function(val) {
promise.fulfill(val);
}, function(err) {
promise.reject(err);
});
} else {
promise[type](res);
}
} else {
promise[type](value);
}
});
}
function defer(promise, fulfill, reject) {
return {
promise: promise,
fulfill: fulfill,
reject: reject
};
}
})(this);
2 changes: 2 additions & 0 deletions troth.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions troth.min.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit d407313

Please sign in to comment.