Skip to content

Commit

Permalink
Adds component tracking and pins components
Browse files Browse the repository at this point in the history
Switches querystring components

node-querystring is stable enough and contains needed features without having to maintain yet another querystring module

Signed-off-by: Christopher Rogers <chrissrogers@gmail.com>
  • Loading branch information
chrissrogers committed May 7, 2014
1 parent e3660ee commit 9f67942
Show file tree
Hide file tree
Showing 45 changed files with 2,163 additions and 21 deletions.
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ node_modules
npm-debug.log

build
components

test/server/pid.txt

Expand Down
39 changes: 19 additions & 20 deletions component.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "recurly",
"repo": "recurly/recurly-js",
"repository": "recurly/recurly-js",
"description": "Official Recurly JavaScript client for the browser.",
"version": "3.0.0-beta",
"keywords": [
Expand All @@ -10,23 +10,23 @@
"main": "lib/index.js",
"dependencies": {
"danmilon/object.keys-shim": "*",
"chrissrogers/querystring": "*",
"component/emitter": "*",
"component/indexof": "*",
"component/event": "*",
"component/clone": "*",
"component/bind": "*",
"component/each": "*",
"component/find": "*",
"component/json": "*",
"component/type": "*",
"component/map": "*",
"yields/merge": "*",
"learnboost/jsonp": "*",
"visionmedia/debug": "*",
"chrissrogers/promise": "*",
"kewah/mixin": "*",
"pluma/par": "*"
"visionmedia/node-querystring": "0.6.6",
"component/emitter": "1.1.2",
"component/indexof": "0.0.3",
"component/event": "0.1.3",
"component/clone": "0.2.2",
"component/bind": "0.0.1",
"component/each": "0.2.3",
"component/find": "0.0.1",
"component/json": "0.0.2",
"component/type": "1.0.0",
"component/map": "0.0.1",
"yields/merge": "1.0.0",
"learnboost/jsonp": "0.0.4",
"visionmedia/debug": "0.8.1",
"chrissrogers/promise": "5.0.0-p1",
"kewah/mixin": "0.1.0",
"pluma/par": "0.3.0"
},
"scripts": [
"lib/index.js",
Expand All @@ -45,6 +45,5 @@
"lib/mixins/pricing/promise.js",
"lib/mixins/pricing/calculations.js",
"lib/mixins/pricing/attach.js"
],
"remotes": []
]
}
17 changes: 17 additions & 0 deletions components/chrissrogers-promise/component.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"name": "promise",
"repo": "chrissrogers/promise",
"description": "Bare bones Promises/A+ implementation",
"version": "5.0.0-p0",
"keywords": [],
"dependencies": {
"johntron/asap": "*"
},
"development": {},
"license": "MIT",
"scripts": [
"index.js",
"core.js"
],
"twitter": "@ForbesLindesay"
}
105 changes: 105 additions & 0 deletions components/chrissrogers-promise/core.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
'use strict';

var asap = require('asap')

module.exports = Promise
function Promise(fn) {
if (typeof this !== 'object') throw new TypeError('Promises must be constructed via new')
if (typeof fn !== 'function') throw new TypeError('not a function')
var state = null
var value = null
var deferreds = []
var self = this

this.then = function(onFulfilled, onRejected) {
return new self.constructor(function(resolve, reject) {
handle(new Handler(onFulfilled, onRejected, resolve, reject))
})
}

function handle(deferred) {
if (state === null) {
deferreds.push(deferred)
return
}
asap(function() {
var cb = state ? deferred.onFulfilled : deferred.onRejected
if (cb === null) {
(state ? deferred.resolve : deferred.reject)(value)
return
}
var ret
try {
ret = cb(value)
}
catch (e) {
deferred.reject(e)
return
}
deferred.resolve(ret)
})
}

function resolve(newValue) {
try { //Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure
if (newValue === self) throw new TypeError('A promise cannot be resolved with itself.')
if (newValue && (typeof newValue === 'object' || typeof newValue === 'function')) {
var then = newValue.then
if (typeof then === 'function') {
doResolve(then.bind(newValue), resolve, reject)
return
}
}
state = true
value = newValue
finale()
} catch (e) { reject(e) }
}

function reject(newValue) {
state = false
value = newValue
finale()
}

function finale() {
for (var i = 0, len = deferreds.length; i < len; i++)
handle(deferreds[i])
deferreds = null
}

doResolve(fn, resolve, reject)
}


function Handler(onFulfilled, onRejected, resolve, reject){
this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null
this.onRejected = typeof onRejected === 'function' ? onRejected : null
this.resolve = resolve
this.reject = reject
}

/**
* Take a potentially misbehaving resolver function and make sure
* onFulfilled and onRejected are only called once.
*
* Makes no guarantees about asynchrony.
*/
function doResolve(fn, onFulfilled, onRejected) {
var done = false;
try {
fn(function (value) {
if (done) return
done = true
onFulfilled(value)
}, function (reason) {
if (done) return
done = true
onRejected(reason)
})
} catch (ex) {
if (done) return
done = true
onRejected(ex)
}
}
180 changes: 180 additions & 0 deletions components/chrissrogers-promise/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
'use strict';

//This file contains then/promise specific extensions to the core promise API

var Promise = require('./core.js')
var asap = require('asap')

module.exports = Promise

/* Static Functions */

function ValuePromise(value) {
this.then = function (onFulfilled) {
if (typeof onFulfilled !== 'function') return this
return new Promise(function (resolve, reject) {
asap(function () {
try {
resolve(onFulfilled(value))
} catch (ex) {
reject(ex);
}
})
})
}
}
ValuePromise.prototype = Object.create(Promise.prototype)

var TRUE = new ValuePromise(true)
var FALSE = new ValuePromise(false)
var NULL = new ValuePromise(null)
var UNDEFINED = new ValuePromise(undefined)
var ZERO = new ValuePromise(0)
var EMPTYSTRING = new ValuePromise('')

Promise.resolve = function (value) {
if (value instanceof Promise) return value

if (value === null) return NULL
if (value === undefined) return UNDEFINED
if (value === true) return TRUE
if (value === false) return FALSE
if (value === 0) return ZERO
if (value === '') return EMPTYSTRING

if (typeof value === 'object' || typeof value === 'function') {
try {
var then = value.then
if (typeof then === 'function') {
return new Promise(then.bind(value))
}
} catch (ex) {
return new Promise(function (resolve, reject) {
reject(ex)
})
}
}

return new ValuePromise(value)
}

Promise.from = Promise.cast = function (value) {
var err = new Error('Promise.from and Promise.cast are deprecated, use Promise.resolve instead')
err.name = 'Warning'
console.warn(err.stack)
return Promise.resolve(value)
}

Promise.denodeify = function (fn, argumentCount) {
argumentCount = argumentCount || Infinity
return function () {
var self = this
var args = Array.prototype.slice.call(arguments)
return new Promise(function (resolve, reject) {
while (args.length && args.length > argumentCount) {
args.pop()
}
args.push(function (err, res) {
if (err) reject(err)
else resolve(res)
})
fn.apply(self, args)
})
}
}
Promise.nodeify = function (fn) {
return function () {
var args = Array.prototype.slice.call(arguments)
var callback = typeof args[args.length - 1] === 'function' ? args.pop() : null
try {
return fn.apply(this, arguments).nodeify(callback)
} catch (ex) {
if (callback === null || typeof callback == 'undefined') {
return new Promise(function (resolve, reject) { reject(ex) })
} else {
asap(function () {
callback(ex)
})
}
}
}
}

Promise.all = function () {
var calledWithArray = arguments.length === 1 && Array.isArray(arguments[0])
var args = Array.prototype.slice.call(calledWithArray ? arguments[0] : arguments)

if (!calledWithArray) {
var err = new Error('Promise.all should be called with a single array, calling it with multiple arguments is deprecated')
err.name = 'Warning'
console.warn(err.stack)
}

return new Promise(function (resolve, reject) {
if (args.length === 0) return resolve([])
var remaining = args.length
function res(i, val) {
try {
if (val && (typeof val === 'object' || typeof val === 'function')) {
var then = val.then
if (typeof then === 'function') {
then.call(val, function (val) { res(i, val) }, reject)
return
}
}
args[i] = val
if (--remaining === 0) {
resolve(args);
}
} catch (ex) {
reject(ex)
}
}
for (var i = 0; i < args.length; i++) {
res(i, args[i])
}
})
}

Promise.reject = function (value) {
return new Promise(function (resolve, reject) {
reject(value);
});
}

Promise.race = function (values) {
return new Promise(function (resolve, reject) {
values.forEach(function(value){
Promise.resolve(value).then(resolve, reject);
})
});
}

/* Prototype Methods */

Promise.prototype.done = function (onFulfilled, onRejected) {
var self = arguments.length ? this.then.apply(this, arguments) : this
self.then(null, function (err) {
asap(function () {
throw err
})
})
}

Promise.prototype.nodeify = function (callback) {
if (typeof callback != 'function') return this

this.then(function (value) {
asap(function () {
callback(null, value)
})
}, function (err) {
asap(function () {
callback(err)
})
})
}

Promise.prototype['catch'] = function (onRejected) {
return this.then(null, onRejected);
}
14 changes: 14 additions & 0 deletions components/component-bind/component.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"name": "bind",
"version": "0.0.1",
"description": "function binding utility",
"keywords": [
"bind",
"utility"
],
"dependencies": {},
"scripts": [
"index.js"
],
"repo": "https://raw.githubusercontent.com/component/bind"
}
Loading

0 comments on commit 9f67942

Please sign in to comment.