Covenant is a tight and performant Promises/A+ implementation written in Coffeescript. Covenant passes the Promises/A+ Test Suite (Version 1.1).


Covenant is a fully compliant Promises/A+ implementation written in Coffeescript. Covenant, its core class is a bare-bones implementation that passes the Promises/A+ Test Suite, as well as the present draft of version 1.1 of the test suite. Covenant's core is very performant and extremely lightweight.

{CovenantCore} = require('covenant')
# create a new promise, which can be figured using subsequent 
# subsequent calls to the fulfill, reject and resolve methods 
= new Core 
# the promise can be configured with a callback function, which 
# will be passed a resolution and rejection function, as well as 
# a reference to the promise itself. Also, `this` is set to reference 
# the promise. 
pDelay50ms = new Core (resolve, reject, promise) ->
  setTimeout -> (
    resolve('50 milliseconds have passed')50)
# fulfill the promise with a value 
# reject the promise with a reason 
# Wrap another promise or foreign "thennable" and adopt its state. 
# Otherwise, fulfill with the value or reject if unable to adopt. 
# Works with Promise/A+-conforming and many non-conforming promises. 
# schedule asynchronous handlers, as often as you like, before or after resolution 
# the handler may be a value, a function or a promise (an object having a function 
# property named "then." 
covenant.then onFulfilledonRejected
# A Covenant object with a single `then` method linked to the promise. 
# The promise can be passed to a client authorized to schedule callbacks 
# on the Core object, but will not be able to change its state. 

Promise, more full-featured extension of Covenant's core is included, although it is in pre-alpha form at this time. It provides: a nice collection of promise-generating operations, an aggregation function, some convenience functions and functions for securely sharing promise objects with clients for limited use.

{Promise} = require ('promise')
# Promise.pending(): construct a pending promise 
= Promise.pending()
  .anything(console.log) # => nothing yet! 
  .fulfill("I'm all done") # => I'm all done" 
# Promise.fulfilled(value): construct a promise fulfilled with value 
  .done(console.log) # => 43 
# Promise.rejected(reason): construct a promise rejected for reason 
Promise.rejected("naughty you")
  .fail(console.error) # => "naughty you" 
# Promise.fromNode(nodeOperation): construct a promise generating function based on node functions 
= Promise.fromNode(fs.readFile)
pReadFile = f('')
# construct a promise that fulfills after ms milliseconds 
# construct a promise that rejects for timeout unless resolved before ms milliseconds. 
# Promise.when(promiseOrValueList): Construct a promise from any number of values or promises, which fulfills with an 
# array of corresponding values if all promises are fulfilled, and rejects if ANY 
# example when promise is rejected 
# with raw values 
  .done console.log # => [1, 2, 3] 
# with pending promises, ultimately fulfilled 
= Promise.pending()
= Promise.when p2Promise.fulfilled(3)
q.done console.log # => nothing happens 
p.fulfill(1) # => [1,2,3] after a tick or two 
# with pending promises, one rejectedl 
Promise.when(Promise.pending()Promise.fulfilled(2)Promise.rejected("Error in 3")
  .fail(console.error) # => Error in 3 
= (Promise.when p1p2p3).fail(console.error) # => Error in 3 
# Promise.all(valueOrPromiseList): same as Promise.all Promise.when  
# p.done(callback): convenience function for p.then onFulfill, undefined 
# convenience function for p.then undefined, onReject
# p.always(callback): convenience function for p.then callback, callback 
# Note that the promise returned by p.always(callback) can resolve 
# differently, even when p has already resolved. 

Download it, clone it, or npm install wizardwerdna/covenant

Covenant has no dependencies, but does use process.nextTick, found in modern Browsers. If process.nextTick is not a function, Covenant falls back to setImmediate, and then to setTimeout. If you are using ancient browsers, it is highly recommended that you use a shim to implement (fake) nextTick and/or setImmediate.

I am indebted, in particular, to the work of Brian Cavalier, whose when.js, and avow.js libraries illuminate what can be done both in a full-featured and minimalist implementation.

  1. clone the respository
  2. npm install
  3. npm test
  4. npm run-script browserTest

The browser test will run the tests directly on Safari, Chrome, Firefox and phantomJS. Some configuration of karma.conf.js will be necessary if you haven't configured one or more of the browsers. phantomJS was installed when you ran npm install.

MIT License, Copyright (c) 2013 Andrew C. Greenberg (