Comparing version 0.8.11 to 0.9.0-rc1
@@ -1,450 +0,541 @@ | ||
/* | ||
postal | ||
Author: Jim Cowart (http://freshbrewedcode.com/jimcowart) | ||
License: Dual licensed MIT (http://www.opensource.org/licenses/mit-license) & GPL (http://www.opensource.org/licenses/gpl-license) | ||
Version 0.8.11 | ||
/** | ||
* postal - Pub/Sub library providing wildcard subscriptions, complex message handling, etc. Works server and client-side. | ||
* Author: Jim Cowart (http://freshbrewedcode.com/jimcowart) | ||
* Version: v0.9.0-rc1 | ||
* Url: http://github.com/postaljs/postal.js | ||
* License(s): MIT, GPL | ||
*/ | ||
/*jshint -W098 */ | ||
(function ( root, factory ) { | ||
if ( typeof module === "object" && module.exports ) { | ||
// Node, or CommonJS-Like environments | ||
module.exports = function ( _ ) { | ||
_ = _ || require( "underscore" ); | ||
return factory( _ ); | ||
}; | ||
} else if ( typeof define === "function" && define.amd ) { | ||
// AMD. Register as an anonymous module. | ||
define( ["underscore"], function ( _ ) { | ||
return factory( _, root ); | ||
} ); | ||
} else { | ||
// Browser globals | ||
root.postal = factory( root._, root ); | ||
} | ||
}( this, function ( _, global, undefined ) { | ||
var postal; | ||
/*jshint -W098 */ | ||
var ConsecutiveDistinctPredicate = function () { | ||
var previous; | ||
return function ( data ) { | ||
var eq = false; | ||
if ( _.isString( data ) ) { | ||
eq = data === previous; | ||
previous = data; | ||
} | ||
else { | ||
eq = _.isEqual( data, previous ); | ||
previous = _.clone( data ); | ||
} | ||
return !eq; | ||
}; | ||
}; | ||
/*jshint -W098 */ | ||
var DistinctPredicate = function () { | ||
var previous = []; | ||
return function ( data ) { | ||
var isDistinct = !_.any( previous, function ( p ) { | ||
if ( _.isObject( data ) || _.isArray( data ) ) { | ||
return _.isEqual( data, p ); | ||
} | ||
return data === p; | ||
} ); | ||
if ( isDistinct ) { | ||
previous.push( data ); | ||
} | ||
return isDistinct; | ||
}; | ||
}; | ||
/* global postal, SubscriptionDefinition */ | ||
var ChannelDefinition = function ( channelName ) { | ||
this.channel = channelName || postal.configuration.DEFAULT_CHANNEL; | ||
}; | ||
ChannelDefinition.prototype.subscribe = function () { | ||
return arguments.length === 1 ? | ||
new SubscriptionDefinition( this.channel, arguments[0].topic, arguments[0].callback ) : | ||
new SubscriptionDefinition( this.channel, arguments[0], arguments[1] ); | ||
}; | ||
ChannelDefinition.prototype.publish = function () { | ||
var envelope = arguments.length === 1 ? | ||
( Object.prototype.toString.call( arguments[0] ) === "[object String]" ? | ||
{ topic : arguments[0] } : | ||
arguments[0] ) : | ||
{ topic : arguments[0], data : arguments[1] }; | ||
envelope.channel = this.channel; | ||
return postal.configuration.bus.publish( envelope ); | ||
}; | ||
/* global postal */ | ||
/*jshint -W117 */ | ||
var SubscriptionDefinition = function ( channel, topic, callback ) { | ||
this.channel = channel; | ||
this.topic = topic; | ||
this.callback = callback; | ||
this.constraints = []; | ||
this.context = null; | ||
postal.configuration.bus.publish( { | ||
channel : postal.configuration.SYSTEM_CHANNEL, | ||
topic : "subscription.created", | ||
data : { | ||
event : "subscription.created", | ||
channel : channel, | ||
topic : topic | ||
} | ||
} ); | ||
postal.configuration.bus.subscribe( this ); | ||
}; | ||
SubscriptionDefinition.prototype = { | ||
unsubscribe : function () { | ||
if ( !this.inactive ) { | ||
this.inactive = true; | ||
postal.configuration.bus.unsubscribe( this ); | ||
postal.configuration.bus.publish( { | ||
channel : postal.configuration.SYSTEM_CHANNEL, | ||
topic : "subscription.removed", | ||
data : { | ||
event : "subscription.removed", | ||
channel : this.channel, | ||
topic : this.topic | ||
} | ||
} ); | ||
} | ||
}, | ||
defer : function () { | ||
var self = this; | ||
var fn = this.callback; | ||
this.callback = function ( data, env ) { | ||
setTimeout( function () { | ||
fn.call( self.context, data, env ); | ||
}, 0 ); | ||
}; | ||
return this; | ||
}, | ||
disposeAfter : function ( maxCalls ) { | ||
if ( _.isNaN( maxCalls ) || maxCalls <= 0 ) { | ||
throw "The value provided to disposeAfter (maxCalls) must be a number greater than zero."; | ||
} | ||
var self = this; | ||
var fn = this.callback; | ||
var dispose = _.after( maxCalls, _.bind( function () { | ||
this.unsubscribe(); | ||
}, this ) ); | ||
this.callback = function () { | ||
fn.apply( self.context, arguments ); | ||
dispose(); | ||
}; | ||
return this; | ||
}, | ||
distinctUntilChanged : function () { | ||
this.withConstraint( new ConsecutiveDistinctPredicate() ); | ||
return this; | ||
}, | ||
distinct : function () { | ||
this.withConstraint( new DistinctPredicate() ); | ||
return this; | ||
}, | ||
once : function () { | ||
this.disposeAfter( 1 ); | ||
return this; | ||
}, | ||
withConstraint : function ( predicate ) { | ||
if ( !_.isFunction( predicate ) ) { | ||
throw "Predicate constraint must be a function"; | ||
} | ||
this.constraints.push( predicate ); | ||
return this; | ||
}, | ||
withConstraints : function ( predicates ) { | ||
var self = this; | ||
if ( _.isArray( predicates ) ) { | ||
_.each( predicates, function ( predicate ) { | ||
self.withConstraint( predicate ); | ||
} ); | ||
} | ||
return self; | ||
}, | ||
withContext : function ( context ) { | ||
this.context = context; | ||
return this; | ||
}, | ||
withDebounce : function ( milliseconds, immediate ) { | ||
if ( _.isNaN( milliseconds ) ) { | ||
throw "Milliseconds must be a number"; | ||
} | ||
var fn = this.callback; | ||
this.callback = _.debounce( fn, milliseconds, !!immediate ); | ||
return this; | ||
}, | ||
withDelay : function ( milliseconds ) { | ||
if ( _.isNaN( milliseconds ) ) { | ||
throw "Milliseconds must be a number"; | ||
} | ||
var self = this; | ||
var fn = this.callback; | ||
this.callback = function ( data, env ) { | ||
setTimeout( function () { | ||
fn.call( self.context, data, env ); | ||
}, milliseconds ); | ||
}; | ||
return this; | ||
}, | ||
withThrottle : function ( milliseconds ) { | ||
if ( _.isNaN( milliseconds ) ) { | ||
throw "Milliseconds must be a number"; | ||
} | ||
var fn = this.callback; | ||
this.callback = _.throttle( fn, milliseconds ); | ||
return this; | ||
}, | ||
subscribe : function ( callback ) { | ||
this.callback = callback; | ||
return this; | ||
} | ||
}; | ||
/*jshint -W098 */ | ||
var bindingsResolver = { | ||
cache : {}, | ||
regex : {}, | ||
compare : function ( binding, topic ) { | ||
var pattern, rgx, prevSegment, result = ( this.cache[ topic ] && this.cache[ topic ][ binding ] ); | ||
if ( typeof result !== "undefined" ) { | ||
return result; | ||
} | ||
if ( !( rgx = this.regex[ binding ] )) { | ||
pattern = "^" + _.map( binding.split( "." ),function ( segment ) { | ||
var res = ""; | ||
if ( !!prevSegment ) { | ||
res = prevSegment !== "#" ? "\\.\\b" : "\\b"; | ||
} | ||
if ( segment === "#" ) { | ||
res += "[\\s\\S]*"; | ||
} else if ( segment === "*" ) { | ||
res += "[^.]+"; | ||
} else { | ||
res += segment; | ||
} | ||
prevSegment = segment; | ||
return res; | ||
} ).join( "" ) + "$"; | ||
rgx = this.regex[ binding ] = new RegExp( pattern ); | ||
} | ||
this.cache[ topic ] = this.cache[ topic ] || {}; | ||
this.cache[ topic ][ binding ] = result = rgx.test( topic ); | ||
return result; | ||
}, | ||
reset : function () { | ||
this.cache = {}; | ||
this.regex = {}; | ||
} | ||
}; | ||
/* global postal */ | ||
var fireSub = function ( subDef, envelope ) { | ||
if ( !subDef.inactive && postal.configuration.resolver.compare( subDef.topic, envelope.topic ) ) { | ||
if ( _.all( subDef.constraints, function ( constraint ) { | ||
return constraint.call( subDef.context, envelope.data, envelope ); | ||
} ) ) { | ||
if ( typeof subDef.callback === "function" ) { | ||
subDef.callback.call( subDef.context, envelope.data, envelope ); | ||
} | ||
} | ||
} | ||
}; | ||
var pubInProgress = 0; | ||
var unSubQueue = []; | ||
var clearUnSubQueue = function () { | ||
while ( unSubQueue.length ) { | ||
localBus.unsubscribe(unSubQueue.shift()); | ||
} | ||
}; | ||
var localBus = { | ||
addWireTap : function ( callback ) { | ||
var self = this; | ||
self.wireTaps.push( callback ); | ||
return function () { | ||
var idx = self.wireTaps.indexOf( callback ); | ||
if ( idx !== -1 ) { | ||
self.wireTaps.splice( idx, 1 ); | ||
} | ||
}; | ||
}, | ||
publish : function ( envelope ) { | ||
++pubInProgress; | ||
envelope.timeStamp = new Date(); | ||
_.each( this.wireTaps, function ( tap ) { | ||
tap( envelope.data, envelope ); | ||
} ); | ||
if ( this.subscriptions[envelope.channel] ) { | ||
_.each( this.subscriptions[envelope.channel], function ( subscribers ) { | ||
var idx = 0, len = subscribers.length, subDef; | ||
while ( idx < len ) { | ||
if ( subDef = subscribers[idx++] ) { | ||
fireSub( subDef, envelope ); | ||
} | ||
} | ||
} ); | ||
} | ||
if ( --pubInProgress === 0 ) { | ||
clearUnSubQueue(); | ||
} | ||
return envelope; | ||
}, | ||
reset : function () { | ||
if ( this.subscriptions ) { | ||
_.each( this.subscriptions, function ( channel ) { | ||
_.each( channel, function ( topic ) { | ||
while ( topic.length ) { | ||
topic.pop().unsubscribe(); | ||
} | ||
} ); | ||
} ); | ||
this.subscriptions = {}; | ||
} | ||
}, | ||
subscribe : function ( subDef ) { | ||
var channel = this.subscriptions[subDef.channel], subs; | ||
if ( !channel ) { | ||
channel = this.subscriptions[subDef.channel] = {}; | ||
} | ||
subs = this.subscriptions[subDef.channel][subDef.topic]; | ||
if ( !subs ) { | ||
subs = this.subscriptions[subDef.channel][subDef.topic] = []; | ||
} | ||
subs.push( subDef ); | ||
return subDef; | ||
}, | ||
subscriptions : {}, | ||
wireTaps : [], | ||
unsubscribe : function ( config ) { | ||
if ( pubInProgress ) { | ||
unSubQueue.push( config ); | ||
return; | ||
} | ||
if ( this.subscriptions[config.channel][config.topic] ) { | ||
var len = this.subscriptions[config.channel][config.topic].length, | ||
idx = 0; | ||
while ( idx < len ) { | ||
if ( this.subscriptions[config.channel][config.topic][idx] === config ) { | ||
this.subscriptions[config.channel][config.topic].splice( idx, 1 ); | ||
break; | ||
} | ||
idx += 1; | ||
} | ||
} | ||
} | ||
}; | ||
/* global localBus, bindingsResolver, ChannelDefinition, SubscriptionDefinition, postal */ | ||
/*jshint -W020 */ | ||
postal = { | ||
configuration : { | ||
bus : localBus, | ||
resolver : bindingsResolver, | ||
DEFAULT_CHANNEL : "/", | ||
SYSTEM_CHANNEL : "postal" | ||
}, | ||
ChannelDefinition : ChannelDefinition, | ||
SubscriptionDefinition : SubscriptionDefinition, | ||
channel : function ( channelName ) { | ||
return new ChannelDefinition( channelName ); | ||
}, | ||
subscribe : function ( options ) { | ||
return new SubscriptionDefinition( options.channel || postal.configuration.DEFAULT_CHANNEL, options.topic, options.callback ); | ||
}, | ||
publish : function ( envelope ) { | ||
envelope.channel = envelope.channel || postal.configuration.DEFAULT_CHANNEL; | ||
return postal.configuration.bus.publish( envelope ); | ||
}, | ||
addWireTap : function ( callback ) { | ||
return this.configuration.bus.addWireTap( callback ); | ||
}, | ||
linkChannels : function ( sources, destinations ) { | ||
var result = []; | ||
sources = !_.isArray( sources ) ? [ sources ] : sources; | ||
destinations = !_.isArray( destinations ) ? [destinations] : destinations; | ||
_.each( sources, function ( source ) { | ||
var sourceTopic = source.topic || "#"; | ||
_.each( destinations, function ( destination ) { | ||
var destChannel = destination.channel || postal.configuration.DEFAULT_CHANNEL; | ||
result.push( | ||
postal.subscribe( { | ||
channel : source.channel || postal.configuration.DEFAULT_CHANNEL, | ||
topic : sourceTopic, | ||
callback : function ( data, env ) { | ||
var newEnv = _.clone( env ); | ||
newEnv.topic = _.isFunction( destination.topic ) ? destination.topic( env.topic ) : destination.topic || env.topic; | ||
newEnv.channel = destChannel; | ||
newEnv.data = data; | ||
postal.publish( newEnv ); | ||
} | ||
} ) | ||
); | ||
} ); | ||
} ); | ||
return result; | ||
}, | ||
utils : { | ||
getSubscribersFor : function () { | ||
var channel = arguments[ 0 ], | ||
tpc = arguments[ 1 ]; | ||
if ( arguments.length === 1 ) { | ||
channel = arguments[ 0 ].channel || postal.configuration.DEFAULT_CHANNEL; | ||
tpc = arguments[ 0 ].topic; | ||
} | ||
if ( postal.configuration.bus.subscriptions[ channel ] && | ||
Object.prototype.hasOwnProperty.call( postal.configuration.bus.subscriptions[ channel ], tpc ) ) { | ||
return postal.configuration.bus.subscriptions[ channel ][ tpc ]; | ||
} | ||
return []; | ||
}, | ||
reset : function () { | ||
postal.configuration.bus.reset(); | ||
postal.configuration.resolver.reset(); | ||
} | ||
} | ||
}; | ||
localBus.subscriptions[postal.configuration.SYSTEM_CHANNEL] = {}; | ||
/*jshint -W106 */ | ||
if ( global && Object.prototype.hasOwnProperty.call( global, "__postalReady__" ) && _.isArray( global.__postalReady__ ) ) { | ||
while(global.__postalReady__.length) { | ||
global.__postalReady__.shift().onReady(postal); | ||
} | ||
} | ||
/*jshint +W106 */ | ||
return postal; | ||
} )); | ||
(function (root, factory) { | ||
if (typeof module === "object" && module.exports) { | ||
// Node, or CommonJS-Like environments | ||
module.exports = factory(require("underscore"), this); | ||
} else if (typeof define === "function" && define.amd) { | ||
// AMD. Register as an anonymous module. | ||
define(["underscore"], function (_) { | ||
return factory(_, root); | ||
}); | ||
} else { | ||
// Browser globals | ||
root.postal = factory(root._, root); | ||
} | ||
}(this, function (_, global, undefined) { | ||
var _postal; | ||
var prevPostal = global.postal; | ||
var Conduit = function (options) { | ||
if (typeof options.target !== "function") { | ||
throw new Error("You can only make functions into Conduits."); | ||
} | ||
var _steps = { | ||
pre: options.pre || [], | ||
post: options.post || [], | ||
all: [] | ||
}; | ||
var _defaultContext = options.context; | ||
var _targetStep = { | ||
isTarget: true, | ||
fn: function (next) { | ||
var args = Array.prototype.slice.call(arguments, 1); | ||
options.target.apply(_defaultContext, args); | ||
next.apply(this, args); | ||
} | ||
}; | ||
var _genPipeline = function () { | ||
_steps.all = _steps.pre.concat([_targetStep].concat(_steps.post)); | ||
}; | ||
_genPipeline(); | ||
var conduit = function () { | ||
var idx = 0; | ||
var next = function next() { | ||
var args = Array.prototype.slice.call(arguments, 0); | ||
var thisIdx = idx; | ||
var step; | ||
idx += 1; | ||
if (thisIdx < _steps.all.length) { | ||
step = _steps.all[thisIdx]; | ||
step.fn.apply(step.context || _defaultContext, [next].concat(args)); | ||
} | ||
}; | ||
next.apply(this, arguments); | ||
}; | ||
conduit.steps = function () { | ||
return _steps.all; | ||
}; | ||
conduit.context = function (ctx) { | ||
if (arguments.length === 0) { | ||
return _defaultContext; | ||
} else { | ||
_defaultContext = ctx; | ||
} | ||
}; | ||
conduit.before = function (step, options) { | ||
step = typeof step === "function" ? { | ||
fn: step | ||
} : step; | ||
options = options || {}; | ||
if (options.prepend) { | ||
_steps.pre.unshift(step); | ||
} else { | ||
_steps.pre.push(step); | ||
} | ||
_genPipeline(); | ||
}; | ||
conduit.after = function (step, options) { | ||
step = typeof step === "function" ? { | ||
fn: step | ||
} : step; | ||
options = options || {}; | ||
if (options.prepend) { | ||
_steps.post.unshift(step); | ||
} else { | ||
_steps.post.push(step); | ||
} | ||
_genPipeline(); | ||
}; | ||
conduit.clear = function () { | ||
_steps = { | ||
pre: [], | ||
post: [], | ||
all: [] | ||
}; | ||
}; | ||
return conduit; | ||
}; | ||
var ChannelDefinition = function (channelName) { | ||
this.channel = channelName || _postal.configuration.DEFAULT_CHANNEL; | ||
this.initialize(); | ||
}; | ||
ChannelDefinition.prototype.initialize = function () {}; | ||
ChannelDefinition.prototype.subscribe = function () { | ||
return _postal.subscribe({ | ||
channel: this.channel, | ||
topic: (arguments.length === 1 ? arguments[0].topic : arguments[0]), | ||
callback: (arguments.length === 1 ? arguments[0].callback : arguments[1]) | ||
}); | ||
}; | ||
ChannelDefinition.prototype.publish = function () { | ||
var envelope = arguments.length === 1 ? (Object.prototype.toString.call(arguments[0]) === "[object String]" ? { | ||
topic: arguments[0] | ||
} : arguments[0]) : { | ||
topic: arguments[0], | ||
data: arguments[1] | ||
}; | ||
envelope.channel = this.channel; | ||
_postal.publish(envelope); | ||
}; | ||
var SubscriptionDefinition = function (channel, topic, callback) { | ||
if (arguments.length !== 3) { | ||
throw new Error("You must provide a channel, topic and callback when creating a SubscriptionDefinition instance."); | ||
} | ||
if (topic.length === 0) { | ||
throw new Error("Topics cannot be empty"); | ||
} | ||
this.channel = channel; | ||
this.topic = topic; | ||
this.subscribe(callback); | ||
}; | ||
SubscriptionDefinition.prototype = { | ||
unsubscribe: function () { | ||
if (!this.inactive) { | ||
this.inactive = true; | ||
_postal.unsubscribe(this); | ||
} | ||
}, | ||
subscribe: function (callback) { | ||
this.callback = callback; | ||
return this; | ||
}, | ||
withContext: function (context) { | ||
this.context = context; | ||
return this; | ||
} | ||
}; | ||
var ConsecutiveDistinctPredicate = function () { | ||
var previous; | ||
return function (data) { | ||
var eq = false; | ||
if (_.isString(data)) { | ||
eq = data === previous; | ||
previous = data; | ||
} | ||
else { | ||
eq = _.isEqual(data, previous); | ||
previous = _.clone(data); | ||
} | ||
return !eq; | ||
}; | ||
}; | ||
var DistinctPredicate = function () { | ||
var previous = []; | ||
return function (data) { | ||
var isDistinct = !_.any(previous, function (p) { | ||
if (_.isObject(data) || _.isArray(data)) { | ||
return _.isEqual(data, p); | ||
} | ||
return data === p; | ||
}); | ||
if (isDistinct) { | ||
previous.push(data); | ||
} | ||
return isDistinct; | ||
}; | ||
}; | ||
var strats = { | ||
withDelay: function (ms) { | ||
if (_.isNaN(ms)) { | ||
throw "Milliseconds must be a number"; | ||
} | ||
return { | ||
name: "withDelay", | ||
fn: function (next, data, envelope) { | ||
setTimeout(function () { | ||
next(data, envelope); | ||
}, ms); | ||
} | ||
}; | ||
}, | ||
defer: function () { | ||
return this.withDelay(0); | ||
}, | ||
stopAfter: function (maxCalls, callback) { | ||
if (_.isNaN(maxCalls) || maxCalls <= 0) { | ||
throw "The value provided to disposeAfter (maxCalls) must be a number greater than zero."; | ||
} | ||
var dispose = _.after(maxCalls, callback); | ||
return { | ||
name: "stopAfter", | ||
fn: function (next, data, envelope) { | ||
dispose(); | ||
next(data, envelope); | ||
} | ||
}; | ||
}, | ||
withThrottle: function (ms) { | ||
if (_.isNaN(ms)) { | ||
throw "Milliseconds must be a number"; | ||
} | ||
return { | ||
name: "withThrottle", | ||
fn: _.throttle(function (next, data, envelope) { | ||
next(data, envelope); | ||
}, ms) | ||
}; | ||
}, | ||
withDebounce: function (ms, immediate) { | ||
if (_.isNaN(ms)) { | ||
throw "Milliseconds must be a number"; | ||
} | ||
return { | ||
name: "debounce", | ||
fn: _.debounce(function (next, data, envelope) { | ||
next(data, envelope); | ||
}, ms, !! immediate) | ||
}; | ||
}, | ||
withConstraint: function (pred) { | ||
if (!_.isFunction(pred)) { | ||
throw "Predicate constraint must be a function"; | ||
} | ||
return { | ||
name: "withConstraint", | ||
fn: function (next, data, envelope) { | ||
if (pred.call(this, data, envelope)) { | ||
next.call(this, data, envelope); | ||
} | ||
} | ||
}; | ||
}, | ||
distinct: function (options) { | ||
options = options || {}; | ||
var accessor = function (args) { | ||
return args[0]; | ||
}; | ||
var check = options.all ? new DistinctPredicate(accessor) : new ConsecutiveDistinctPredicate(accessor); | ||
return { | ||
name: "distinct", | ||
fn: function (next, data, envelope) { | ||
if (check(data)) { | ||
next(data, envelope); | ||
} | ||
} | ||
}; | ||
} | ||
}; | ||
SubscriptionDefinition.prototype.defer = function () { | ||
this.callback.before(strats.defer()); | ||
return this; | ||
}; | ||
SubscriptionDefinition.prototype.disposeAfter = function (maxCalls) { | ||
var self = this; | ||
self.callback.before(strats.stopAfter(maxCalls, function () { | ||
self.unsubscribe.call(self); | ||
})); | ||
return self; | ||
}; | ||
SubscriptionDefinition.prototype.distinctUntilChanged = function () { | ||
this.callback.before(strats.distinct()); | ||
return this; | ||
}; | ||
SubscriptionDefinition.prototype.distinct = function () { | ||
this.callback.before(strats.distinct({ | ||
all: true | ||
})); | ||
return this; | ||
}; | ||
SubscriptionDefinition.prototype.once = function () { | ||
this.disposeAfter(1); | ||
return this; | ||
}; | ||
SubscriptionDefinition.prototype.withConstraint = function (predicate) { | ||
this.callback.before(strats.withConstraint(predicate)); | ||
return this; | ||
}; | ||
SubscriptionDefinition.prototype.withConstraints = function (preds) { | ||
while (preds.length) { | ||
this.callback.before(strats.withConstraint(preds.shift())); | ||
} | ||
return this; | ||
}; | ||
SubscriptionDefinition.prototype.withDebounce = function (milliseconds, immediate) { | ||
this.callback.before(strats.withDebounce(milliseconds, immediate)); | ||
return this; | ||
}; | ||
SubscriptionDefinition.prototype.withDelay = function (milliseconds) { | ||
this.callback.before(strats.withDelay(milliseconds)); | ||
return this; | ||
}; | ||
SubscriptionDefinition.prototype.withThrottle = function (milliseconds) { | ||
this.callback.before(strats.withThrottle(milliseconds)); | ||
return this; | ||
}; | ||
SubscriptionDefinition.prototype.subscribe = function (callback) { | ||
this.callback = new Conduit({ | ||
target: callback, | ||
context: this | ||
}); | ||
return this; | ||
}; | ||
SubscriptionDefinition.prototype.withContext = function (context) { | ||
this.callback.context(context); | ||
return this; | ||
}; | ||
SubscriptionDefinition.prototype.after = function () { | ||
this.callback.after.apply(this, arguments); | ||
}; | ||
SubscriptionDefinition.prototype.before = function () { | ||
this.callback.before.apply(this, arguments); | ||
}; | ||
ChannelDefinition.prototype.initialize = function () { | ||
var oldPub = this.publish; | ||
this.publish = new Conduit({ | ||
target: oldPub, | ||
context: this | ||
}); | ||
}; | ||
var bindingsResolver = { | ||
cache: {}, | ||
regex: {}, | ||
compare: function (binding, topic) { | ||
var pattern, rgx, prevSegment, result = (this.cache[topic] && this.cache[topic][binding]); | ||
if (typeof result !== "undefined") { | ||
return result; | ||
} | ||
if (!(rgx = this.regex[binding])) { | ||
pattern = "^" + _.map(binding.split("."), function (segment) { | ||
var res = ""; | ||
if ( !! prevSegment) { | ||
res = prevSegment !== "#" ? "\\.\\b" : "\\b"; | ||
} | ||
if (segment === "#") { | ||
res += "[\\s\\S]*"; | ||
} else if (segment === "*") { | ||
res += "[^.]+"; | ||
} else { | ||
res += segment; | ||
} | ||
prevSegment = segment; | ||
return res; | ||
}).join("") + "$"; | ||
rgx = this.regex[binding] = new RegExp(pattern); | ||
} | ||
this.cache[topic] = this.cache[topic] || {}; | ||
this.cache[topic][binding] = result = rgx.test(topic); | ||
return result; | ||
}, | ||
reset: function () { | ||
this.cache = {}; | ||
this.regex = {}; | ||
} | ||
}; | ||
var fireSub = function (subDef, envelope) { | ||
if (!subDef.inactive && _postal.configuration.resolver.compare(subDef.topic, envelope.topic)) { | ||
subDef.callback.call(subDef.context || this, envelope.data, envelope); | ||
} | ||
}; | ||
var pubInProgress = 0; | ||
var unSubQueue = []; | ||
var clearUnSubQueue = function () { | ||
while (unSubQueue.length) { | ||
_postal.unsubscribe(unSubQueue.shift()); | ||
} | ||
}; | ||
_postal = { | ||
configuration: { | ||
resolver: bindingsResolver, | ||
DEFAULT_CHANNEL: "/", | ||
SYSTEM_CHANNEL: "postal" | ||
}, | ||
subscriptions: {}, | ||
wireTaps: [], | ||
ChannelDefinition: ChannelDefinition, | ||
SubscriptionDefinition: SubscriptionDefinition, | ||
channel: function (channelName) { | ||
return new ChannelDefinition(channelName); | ||
}, | ||
subscribe: function (options) { | ||
var subDef = new SubscriptionDefinition(options.channel || this.configuration.DEFAULT_CHANNEL, options.topic, options.callback); | ||
var channel = this.subscriptions[subDef.channel]; | ||
var subs; | ||
this.publish({ | ||
channel: this.configuration.SYSTEM_CHANNEL, | ||
topic: "subscription.created", | ||
data: { | ||
event: "subscription.created", | ||
channel: subDef.channel, | ||
topic: subDef.topic | ||
} | ||
}); | ||
if (!channel) { | ||
channel = this.subscriptions[subDef.channel] = {}; | ||
} | ||
subs = this.subscriptions[subDef.channel][subDef.topic]; | ||
if (!subs) { | ||
subs = this.subscriptions[subDef.channel][subDef.topic] = []; | ||
} | ||
subs.push(subDef); | ||
return subDef; | ||
}, | ||
publish: function (envelope) { | ||
++pubInProgress; | ||
envelope.channel = envelope.channel || this.configuration.DEFAULT_CHANNEL; | ||
envelope.timeStamp = new Date(); | ||
_.each(this.wireTaps, function (tap) { | ||
tap(envelope.data, envelope); | ||
}); | ||
if (this.subscriptions[envelope.channel]) { | ||
_.each(this.subscriptions[envelope.channel], function (subscribers) { | ||
var idx = 0, | ||
len = subscribers.length, | ||
subDef; | ||
while (idx < len) { | ||
if (subDef = subscribers[idx++]) { | ||
fireSub(subDef, envelope); | ||
} | ||
} | ||
}); | ||
} | ||
if (--pubInProgress === 0) { | ||
clearUnSubQueue(); | ||
} | ||
}, | ||
unsubscribe: function (subDef) { | ||
if (pubInProgress) { | ||
unSubQueue.push(subDef); | ||
return; | ||
} | ||
if (this.subscriptions[subDef.channel] && this.subscriptions[subDef.channel][subDef.topic]) { | ||
var len = this.subscriptions[subDef.channel][subDef.topic].length, | ||
idx = 0; | ||
while (idx < len) { | ||
if (this.subscriptions[subDef.channel][subDef.topic][idx] === subDef) { | ||
this.subscriptions[subDef.channel][subDef.topic].splice(idx, 1); | ||
break; | ||
} | ||
idx += 1; | ||
} | ||
} | ||
this.publish({ | ||
channel: this.configuration.SYSTEM_CHANNEL, | ||
topic: "subscription.removed", | ||
data: { | ||
event: "subscription.removed", | ||
channel: subDef.channel, | ||
topic: subDef.topic | ||
} | ||
}); | ||
}, | ||
addWireTap: function (callback) { | ||
var self = this; | ||
self.wireTaps.push(callback); | ||
return function () { | ||
var idx = self.wireTaps.indexOf(callback); | ||
if (idx !== -1) { | ||
self.wireTaps.splice(idx, 1); | ||
} | ||
}; | ||
}, | ||
noConflict: function () { | ||
if (typeof window === "undefined" || (typeof window !== "undefined" && typeof define === "function" && define.amd)) { | ||
throw new Error("noConflict can only be used in browser clients which aren't using AMD modules"); | ||
} | ||
global.postal = prevPostal; | ||
return this; | ||
}, | ||
getSubscribersFor: function () { | ||
var channel = arguments[0], | ||
tpc = arguments[1]; | ||
if (arguments.length === 1) { | ||
channel = arguments[0].channel || this.configuration.DEFAULT_CHANNEL; | ||
tpc = arguments[0].topic; | ||
} | ||
if (this.subscriptions[channel] && Object.prototype.hasOwnProperty.call(this.subscriptions[channel], tpc)) { | ||
return this.subscriptions[channel][tpc]; | ||
} | ||
return []; | ||
}, | ||
reset: function () { | ||
if (this.subscriptions) { | ||
_.each(this.subscriptions, function (channel) { | ||
_.each(channel, function (topic) { | ||
while (topic.length) { | ||
topic.pop().unsubscribe(); | ||
} | ||
}); | ||
}); | ||
this.subscriptions = {}; | ||
} | ||
this.configuration.resolver.reset(); | ||
} | ||
}; | ||
_postal.subscriptions[_postal.configuration.SYSTEM_CHANNEL] = {}; | ||
_postal.linkChannels = function (sources, destinations) { | ||
var result = [], | ||
self = this; | ||
sources = !_.isArray(sources) ? [sources] : sources; | ||
destinations = !_.isArray(destinations) ? [destinations] : destinations; | ||
_.each(sources, function (source) { | ||
var sourceTopic = source.topic || "#"; | ||
_.each(destinations, function (destination) { | ||
var destChannel = destination.channel || self.configuration.DEFAULT_CHANNEL; | ||
result.push( | ||
self.subscribe({ | ||
channel: source.channel || self.configuration.DEFAULT_CHANNEL, | ||
topic: sourceTopic, | ||
callback: function (data, env) { | ||
var newEnv = _.clone(env); | ||
newEnv.topic = _.isFunction(destination.topic) ? destination.topic(env.topic) : destination.topic || env.topic; | ||
newEnv.channel = destChannel; | ||
newEnv.data = data; | ||
self.publish(newEnv); | ||
} | ||
})); | ||
}); | ||
}); | ||
return result; | ||
}; | ||
if (global && Object.prototype.hasOwnProperty.call(global, "__postalReady__") && _.isArray(global.__postalReady__)) { | ||
while (global.__postalReady__.length) { | ||
global.__postalReady__.shift().onReady(_postal); | ||
} | ||
} | ||
return _postal; | ||
})); |
@@ -1,7 +0,8 @@ | ||
/* | ||
postal | ||
Author: Jim Cowart (http://freshbrewedcode.com/jimcowart) | ||
License: Dual licensed MIT (http://www.opensource.org/licenses/mit-license) & GPL (http://www.opensource.org/licenses/gpl-license) | ||
Version 0.8.11 | ||
/** | ||
* postal - Pub/Sub library providing wildcard subscriptions, complex message handling, etc. Works server and client-side. | ||
* Author: Jim Cowart (http://freshbrewedcode.com/jimcowart) | ||
* Version: v0.9.0-rc1 | ||
* Url: http://github.com/postaljs/postal.js | ||
* License(s): MIT, GPL | ||
*/ | ||
(function(t,n){"object"==typeof module&&module.exports?module.exports=function(t){return t=t||require("underscore"),n(t)}:"function"==typeof define&&define.amd?define(["underscore"],function(i){return n(i,t)}):t.postal=n(t._,t)})(this,function(t,n){var i,s=function(){var n;return function(i){var s=!1;return t.isString(i)?(s=i===n,n=i):(s=t.isEqual(i,n),n=t.clone(i)),!s}},c=function(){var n=[];return function(i){var s=!t.any(n,function(n){return t.isObject(i)||t.isArray(i)?t.isEqual(i,n):i===n});return s&&n.push(i),s}},e=function(t){this.channel=t||i.configuration.DEFAULT_CHANNEL};e.prototype.subscribe=function(){return 1===arguments.length?new r(this.channel,arguments[0].topic,arguments[0].callback):new r(this.channel,arguments[0],arguments[1])},e.prototype.publish=function(){var t=1===arguments.length?"[object String]"===Object.prototype.toString.call(arguments[0])?{topic:arguments[0]}:arguments[0]:{topic:arguments[0],data:arguments[1]};return t.channel=this.channel,i.configuration.bus.publish(t)};var r=function(t,n,s){this.channel=t,this.topic=n,this.callback=s,this.constraints=[],this.context=null,i.configuration.bus.publish({channel:i.configuration.SYSTEM_CHANNEL,topic:"subscription.created",data:{event:"subscription.created",channel:t,topic:n}}),i.configuration.bus.subscribe(this)};r.prototype={unsubscribe:function(){this.inactive||(this.inactive=!0,i.configuration.bus.unsubscribe(this),i.configuration.bus.publish({channel:i.configuration.SYSTEM_CHANNEL,topic:"subscription.removed",data:{event:"subscription.removed",channel:this.channel,topic:this.topic}}))},defer:function(){var t=this,n=this.callback;return this.callback=function(i,s){setTimeout(function(){n.call(t.context,i,s)},0)},this},disposeAfter:function(n){if(t.isNaN(n)||0>=n)throw"The value provided to disposeAfter (maxCalls) must be a number greater than zero.";var i=this,s=this.callback,c=t.after(n,t.bind(function(){this.unsubscribe()},this));return this.callback=function(){s.apply(i.context,arguments),c()},this},distinctUntilChanged:function(){return this.withConstraint(new s),this},distinct:function(){return this.withConstraint(new c),this},once:function(){return this.disposeAfter(1),this},withConstraint:function(n){if(!t.isFunction(n))throw"Predicate constraint must be a function";return this.constraints.push(n),this},withConstraints:function(n){var i=this;return t.isArray(n)&&t.each(n,function(t){i.withConstraint(t)}),i},withContext:function(t){return this.context=t,this},withDebounce:function(n,i){if(t.isNaN(n))throw"Milliseconds must be a number";var s=this.callback;return this.callback=t.debounce(s,n,!!i),this},withDelay:function(n){if(t.isNaN(n))throw"Milliseconds must be a number";var i=this,s=this.callback;return this.callback=function(t,c){setTimeout(function(){s.call(i.context,t,c)},n)},this},withThrottle:function(n){if(t.isNaN(n))throw"Milliseconds must be a number";var i=this.callback;return this.callback=t.throttle(i,n),this},subscribe:function(t){return this.callback=t,this}};var o={cache:{},regex:{},compare:function(n,i){var s,c,e,r=this.cache[i]&&this.cache[i][n];return r!==undefined?r:((c=this.regex[n])||(s="^"+t.map(n.split("."),function(t){var n="";return e&&(n="#"!==e?"\\.\\b":"\\b"),n+="#"===t?"[\\s\\S]*":"*"===t?"[^.]+":t,e=t,n}).join("")+"$",c=this.regex[n]=RegExp(s)),this.cache[i]=this.cache[i]||{},this.cache[i][n]=r=c.test(i),r)},reset:function(){this.cache={},this.regex={}}},a=function(n,s){!n.inactive&&i.configuration.resolver.compare(n.topic,s.topic)&&t.all(n.constraints,function(t){return t.call(n.context,s.data,s)})&&"function"==typeof n.callback&&n.callback.call(n.context,s.data,s)},u=0,h=[],l=function(){for(;h.length;)f.unsubscribe(h.shift())},f={addWireTap:function(t){var n=this;return n.wireTaps.push(t),function(){var i=n.wireTaps.indexOf(t);-1!==i&&n.wireTaps.splice(i,1)}},publish:function(n){return++u,n.timeStamp=new Date,t.each(this.wireTaps,function(t){t(n.data,n)}),this.subscriptions[n.channel]&&t.each(this.subscriptions[n.channel],function(t){for(var i,s=0,c=t.length;c>s;)(i=t[s++])&&a(i,n)}),0===--u&&l(),n},reset:function(){this.subscriptions&&(t.each(this.subscriptions,function(n){t.each(n,function(t){for(;t.length;)t.pop().unsubscribe()})}),this.subscriptions={})},subscribe:function(t){var n,i=this.subscriptions[t.channel];return i||(i=this.subscriptions[t.channel]={}),n=this.subscriptions[t.channel][t.topic],n||(n=this.subscriptions[t.channel][t.topic]=[]),n.push(t),t},subscriptions:{},wireTaps:[],unsubscribe:function(t){if(u)return h.push(t),undefined;if(this.subscriptions[t.channel][t.topic])for(var n=this.subscriptions[t.channel][t.topic].length,i=0;n>i;){if(this.subscriptions[t.channel][t.topic][i]===t){this.subscriptions[t.channel][t.topic].splice(i,1);break}i+=1}}};if(i={configuration:{bus:f,resolver:o,DEFAULT_CHANNEL:"/",SYSTEM_CHANNEL:"postal"},ChannelDefinition:e,SubscriptionDefinition:r,channel:function(t){return new e(t)},subscribe:function(t){return new r(t.channel||i.configuration.DEFAULT_CHANNEL,t.topic,t.callback)},publish:function(t){return t.channel=t.channel||i.configuration.DEFAULT_CHANNEL,i.configuration.bus.publish(t)},addWireTap:function(t){return this.configuration.bus.addWireTap(t)},linkChannels:function(n,s){var c=[];return n=t.isArray(n)?n:[n],s=t.isArray(s)?s:[s],t.each(n,function(n){var e=n.topic||"#";t.each(s,function(s){var r=s.channel||i.configuration.DEFAULT_CHANNEL;c.push(i.subscribe({channel:n.channel||i.configuration.DEFAULT_CHANNEL,topic:e,callback:function(n,c){var e=t.clone(c);e.topic=t.isFunction(s.topic)?s.topic(c.topic):s.topic||c.topic,e.channel=r,e.data=n,i.publish(e)}}))})}),c},utils:{getSubscribersFor:function(){var t=arguments[0],n=arguments[1];return 1===arguments.length&&(t=arguments[0].channel||i.configuration.DEFAULT_CHANNEL,n=arguments[0].topic),i.configuration.bus.subscriptions[t]&&Object.prototype.hasOwnProperty.call(i.configuration.bus.subscriptions[t],n)?i.configuration.bus.subscriptions[t][n]:[]},reset:function(){i.configuration.bus.reset(),i.configuration.resolver.reset()}}},f.subscriptions[i.configuration.SYSTEM_CHANNEL]={},n&&Object.prototype.hasOwnProperty.call(n,"__postalReady__")&&t.isArray(n.__postalReady__))for(;n.__postalReady__.length;)n.__postalReady__.shift().onReady(i);return i}); | ||
(function(t,n){"object"==typeof module&&module.exports?module.exports=n(require("underscore"),this):"function"==typeof define&&define.amd?define(["underscore"],function(i){return n(i,t)}):t.postal=n(t._,t)})(this,function(t,n){var i,e=n.postal,o=function(t){if("function"!=typeof t.target)throw new Error("You can only make functions into Conduits.");var n={pre:t.pre||[],post:t.post||[],all:[]},i=t.context,e={isTarget:!0,fn:function(n){var e=Array.prototype.slice.call(arguments,1);t.target.apply(i,e),n.apply(this,e)}},o=function(){n.all=n.pre.concat([e].concat(n.post))};o();var r=function(){var t=0,e=function o(){var e,r=Array.prototype.slice.call(arguments,0),c=t;t+=1,c<n.all.length&&(e=n.all[c],e.fn.apply(e.context||i,[o].concat(r)))};e.apply(this,arguments)};return r.steps=function(){return n.all},r.context=function(t){return 0===arguments.length?i:void(i=t)},r.before=function(t,i){t="function"==typeof t?{fn:t}:t,i=i||{},i.prepend?n.pre.unshift(t):n.pre.push(t),o()},r.after=function(t,i){t="function"==typeof t?{fn:t}:t,i=i||{},i.prepend?n.post.unshift(t):n.post.push(t),o()},r.clear=function(){n={pre:[],post:[],all:[]}},r},r=function(t){this.channel=t||i.configuration.DEFAULT_CHANNEL,this.initialize()};r.prototype.initialize=function(){},r.prototype.subscribe=function(){return i.subscribe({channel:this.channel,topic:1===arguments.length?arguments[0].topic:arguments[0],callback:1===arguments.length?arguments[0].callback:arguments[1]})},r.prototype.publish=function(){var t=1===arguments.length?"[object String]"===Object.prototype.toString.call(arguments[0])?{topic:arguments[0]}:arguments[0]:{topic:arguments[0],data:arguments[1]};t.channel=this.channel,i.publish(t)};var c=function(t,n,i){if(3!==arguments.length)throw new Error("You must provide a channel, topic and callback when creating a SubscriptionDefinition instance.");if(0===n.length)throw new Error("Topics cannot be empty");this.channel=t,this.topic=n,this.subscribe(i)};c.prototype={unsubscribe:function(){this.inactive||(this.inactive=!0,i.unsubscribe(this))},subscribe:function(t){return this.callback=t,this},withContext:function(t){return this.context=t,this}};var s=function(){var n;return function(i){var e=!1;return t.isString(i)?(e=i===n,n=i):(e=t.isEqual(i,n),n=t.clone(i)),!e}},a=function(){var n=[];return function(i){var e=!t.any(n,function(n){return t.isObject(i)||t.isArray(i)?t.isEqual(i,n):i===n});return e&&n.push(i),e}},u={withDelay:function(n){if(t.isNaN(n))throw"Milliseconds must be a number";return{name:"withDelay",fn:function(t,i,e){setTimeout(function(){t(i,e)},n)}}},defer:function(){return this.withDelay(0)},stopAfter:function(n,i){if(t.isNaN(n)||0>=n)throw"The value provided to disposeAfter (maxCalls) must be a number greater than zero.";var e=t.after(n,i);return{name:"stopAfter",fn:function(t,n,i){e(),t(n,i)}}},withThrottle:function(n){if(t.isNaN(n))throw"Milliseconds must be a number";return{name:"withThrottle",fn:t.throttle(function(t,n,i){t(n,i)},n)}},withDebounce:function(n,i){if(t.isNaN(n))throw"Milliseconds must be a number";return{name:"debounce",fn:t.debounce(function(t,n,i){t(n,i)},n,!!i)}},withConstraint:function(n){if(!t.isFunction(n))throw"Predicate constraint must be a function";return{name:"withConstraint",fn:function(t,i,e){n.call(this,i,e)&&t.call(this,i,e)}}},distinct:function(t){t=t||{};var n=function(t){return t[0]},i=t.all?new a(n):new s(n);return{name:"distinct",fn:function(t,n,e){i(n)&&t(n,e)}}}};c.prototype.defer=function(){return this.callback.before(u.defer()),this},c.prototype.disposeAfter=function(t){var n=this;return n.callback.before(u.stopAfter(t,function(){n.unsubscribe.call(n)})),n},c.prototype.distinctUntilChanged=function(){return this.callback.before(u.distinct()),this},c.prototype.distinct=function(){return this.callback.before(u.distinct({all:!0})),this},c.prototype.once=function(){return this.disposeAfter(1),this},c.prototype.withConstraint=function(t){return this.callback.before(u.withConstraint(t)),this},c.prototype.withConstraints=function(t){for(;t.length;)this.callback.before(u.withConstraint(t.shift()));return this},c.prototype.withDebounce=function(t,n){return this.callback.before(u.withDebounce(t,n)),this},c.prototype.withDelay=function(t){return this.callback.before(u.withDelay(t)),this},c.prototype.withThrottle=function(t){return this.callback.before(u.withThrottle(t)),this},c.prototype.subscribe=function(t){return this.callback=new o({target:t,context:this}),this},c.prototype.withContext=function(t){return this.callback.context(t),this},c.prototype.after=function(){this.callback.after.apply(this,arguments)},c.prototype.before=function(){this.callback.before.apply(this,arguments)},r.prototype.initialize=function(){var t=this.publish;this.publish=new o({target:t,context:this})};var h={cache:{},regex:{},compare:function(n,i){var e,o,r,c=this.cache[i]&&this.cache[i][n];return"undefined"!=typeof c?c:((o=this.regex[n])||(e="^"+t.map(n.split("."),function(t){var n="";return r&&(n="#"!==r?"\\.\\b":"\\b"),n+="#"===t?"[\\s\\S]*":"*"===t?"[^.]+":t,r=t,n}).join("")+"$",o=this.regex[n]=new RegExp(e)),this.cache[i]=this.cache[i]||{},this.cache[i][n]=c=o.test(i),c)},reset:function(){this.cache={},this.regex={}}},p=function(t,n){!t.inactive&&i.configuration.resolver.compare(t.topic,n.topic)&&t.callback.call(t.context||this,n.data,n)},l=0,f=[],b=function(){for(;f.length;)i.unsubscribe(f.shift())};if(i={configuration:{resolver:h,DEFAULT_CHANNEL:"/",SYSTEM_CHANNEL:"postal"},subscriptions:{},wireTaps:[],ChannelDefinition:r,SubscriptionDefinition:c,channel:function(t){return new r(t)},subscribe:function(t){var n,i=new c(t.channel||this.configuration.DEFAULT_CHANNEL,t.topic,t.callback),e=this.subscriptions[i.channel];return this.publish({channel:this.configuration.SYSTEM_CHANNEL,topic:"subscription.created",data:{event:"subscription.created",channel:i.channel,topic:i.topic}}),e||(e=this.subscriptions[i.channel]={}),n=this.subscriptions[i.channel][i.topic],n||(n=this.subscriptions[i.channel][i.topic]=[]),n.push(i),i},publish:function(n){++l,n.channel=n.channel||this.configuration.DEFAULT_CHANNEL,n.timeStamp=new Date,t.each(this.wireTaps,function(t){t(n.data,n)}),this.subscriptions[n.channel]&&t.each(this.subscriptions[n.channel],function(t){for(var i,e=0,o=t.length;o>e;)(i=t[e++])&&p(i,n)}),0===--l&&b()},unsubscribe:function(t){if(l)return void f.push(t);if(this.subscriptions[t.channel]&&this.subscriptions[t.channel][t.topic])for(var n=this.subscriptions[t.channel][t.topic].length,i=0;n>i;){if(this.subscriptions[t.channel][t.topic][i]===t){this.subscriptions[t.channel][t.topic].splice(i,1);break}i+=1}this.publish({channel:this.configuration.SYSTEM_CHANNEL,topic:"subscription.removed",data:{event:"subscription.removed",channel:t.channel,topic:t.topic}})},addWireTap:function(t){var n=this;return n.wireTaps.push(t),function(){var i=n.wireTaps.indexOf(t);-1!==i&&n.wireTaps.splice(i,1)}},noConflict:function(){if("undefined"==typeof window||"undefined"!=typeof window&&"function"==typeof define&&define.amd)throw new Error("noConflict can only be used in browser clients which aren't using AMD modules");return n.postal=e,this},getSubscribersFor:function(){var t=arguments[0],n=arguments[1];return 1===arguments.length&&(t=arguments[0].channel||this.configuration.DEFAULT_CHANNEL,n=arguments[0].topic),this.subscriptions[t]&&Object.prototype.hasOwnProperty.call(this.subscriptions[t],n)?this.subscriptions[t][n]:[]},reset:function(){this.subscriptions&&(t.each(this.subscriptions,function(n){t.each(n,function(t){for(;t.length;)t.pop().unsubscribe()})}),this.subscriptions={}),this.configuration.resolver.reset()}},i.subscriptions[i.configuration.SYSTEM_CHANNEL]={},i.linkChannels=function(n,i){var e=[],o=this;return n=t.isArray(n)?n:[n],i=t.isArray(i)?i:[i],t.each(n,function(n){var r=n.topic||"#";t.each(i,function(i){var c=i.channel||o.configuration.DEFAULT_CHANNEL;e.push(o.subscribe({channel:n.channel||o.configuration.DEFAULT_CHANNEL,topic:r,callback:function(n,e){var r=t.clone(e);r.topic=t.isFunction(i.topic)?i.topic(e.topic):i.topic||e.topic,r.channel=c,r.data=n,o.publish(r)}}))})}),e},n&&Object.prototype.hasOwnProperty.call(n,"__postalReady__")&&t.isArray(n.__postalReady__))for(;n.__postalReady__.length;)n.__postalReady__.shift().onReady(i);return i}); |
121
package.json
{ | ||
"name" : "postal", | ||
"description" : "Pub/Sub library providing wildcard subscriptions, complex message handling, etc. Works server and client-side.", | ||
"version" : "0.8.11", | ||
"homepage" : "http://github.com/postaljs/postal.js", | ||
"repository" : { | ||
"type" : "git", | ||
"url" : "git://github.com/postaljs/postal.js.git" | ||
"name": "postal", | ||
"description": "Pub/Sub library providing wildcard subscriptions, complex message handling, etc. Works server and client-side.", | ||
"version": "0.9.0-rc1", | ||
"homepage": "http://github.com/postaljs/postal.js", | ||
"repository": { | ||
"type": "git", | ||
"url": "git://github.com/postaljs/postal.js.git" | ||
}, | ||
"author" : "Jim Cowart (http://freshbrewedcode.com/jimcowart)", | ||
"author": "Jim Cowart (http://freshbrewedcode.com/jimcowart)", | ||
"contributors": [ | ||
{ | ||
"name" : "Jim Cowart", | ||
"email" : "WhyNotJustComment@OnMyBlog.com", | ||
"url" : "http://freshbrewedcode.com/jimcowart" | ||
"name": "Jim Cowart", | ||
"email": "WhyNotJustComment@OnMyBlog.com", | ||
"url": "http://freshbrewedcode.com/jimcowart" | ||
}, | ||
{ | ||
"name" : "Alex Robson", | ||
"email" : "WhyNotJustComment@OnMyBlog.com", | ||
"url" : "http://freshbrewedcode.com/alexrobson" | ||
"name": "Alex Robson", | ||
"email": "WhyNotJustComment@OnMyBlog.com", | ||
"url": "http://freshbrewedcode.com/alexrobson" | ||
}, | ||
{ | ||
"name" : "Nicholas Cloud", | ||
"email" : "WhyNotJustComment@OnMyBlog.com", | ||
"url" : "http://nicholascloud.com" | ||
"name": "Nicholas Cloud", | ||
"email": "WhyNotJustComment@OnMyBlog.com", | ||
"url": "http://nicholascloud.com" | ||
}, | ||
{ | ||
"name" : "Doug Neiner", | ||
"email" : "WhyNotJustComment@OnMyBlog.com", | ||
"url" : "http://dougneiner.com" | ||
"name": "Doug Neiner", | ||
"email": "WhyNotJustComment@OnMyBlog.com", | ||
"url": "http://dougneiner.com" | ||
}, | ||
{ | ||
"name" : "Jonathan Creamer", | ||
"email" : "WhyNotJustComment@OnMyBlog.com", | ||
"url" : "http://freshbrewedcode.com/jonathancreamer" | ||
"name": "Jonathan Creamer", | ||
"email": "WhyNotJustComment@OnMyBlog.com", | ||
"url": "http://freshbrewedcode.com/jonathancreamer" | ||
}, | ||
{ | ||
"name" : "Elijah Manor", | ||
"email" : "WhyNotJustComment@OnMyBlog.com", | ||
"url" : "http://www.elijahmanor.com" | ||
"name": "Elijah Manor", | ||
"email": "WhyNotJustComment@OnMyBlog.com", | ||
"url": "http://www.elijahmanor.com" | ||
}, | ||
{ | ||
"name" : "Ger Hobbelt", | ||
"email" : "ger@hobbelt.com", | ||
"url" : "http://hebbut.net/" | ||
"name": "Ger Hobbelt", | ||
"email": "ger@hobbelt.com", | ||
"url": "http://hebbut.net/" | ||
}, | ||
{ | ||
"name" : "Christian Haas", | ||
"url" : "http://github.com/dertseha" | ||
"name": "Christian Haas", | ||
"url": "http://github.com/dertseha" | ||
} | ||
@@ -64,26 +64,51 @@ ], | ||
], | ||
"bugs" : { | ||
"email" : "PleaseJustUseTheIssuesPage@github.com", | ||
"url" : "http://github.com/postaljs/postal.js/issues" | ||
"bugs": { | ||
"email": "PleaseJustUseTheIssuesPage@github.com", | ||
"url": "http://github.com/postaljs/postal.js/issues" | ||
}, | ||
"directories" : { "lib" : "lib" }, | ||
"main" : "lib/postal.js", | ||
"engines" : { | ||
"node" : ">=0.4.0" | ||
"directories": { | ||
"lib": "lib" | ||
}, | ||
"dependencies" : { | ||
"underscore" : ">=1.1.7" | ||
"main": "lib/postal.js", | ||
"engines": { | ||
"node": ">=0.4.0" | ||
}, | ||
"bundleDependencies" : [ "underscore" ], | ||
"devDependencies" : {}, | ||
"licenses" : [ | ||
"dependencies": { | ||
"underscore": "~1.5.2" | ||
}, | ||
"bundleDependencies": [ | ||
"underscore" | ||
], | ||
"devDependencies": { | ||
"bower": "~1.2.8", | ||
"gulp-util": "~2.2.9", | ||
"gulp": "~3.3.1", | ||
"gulp-imports": "~0.0.1", | ||
"gulp-header": "~1.0.2", | ||
"gulp-hint-not": "~0.0.3", | ||
"gulp-uglify": "~0.1.0", | ||
"gulp-rename": "~0.2.1", | ||
"gulp-plato": "~0.1.0", | ||
"gulp-beautify": "~1.0.3", | ||
"tiny-lr": "0.0.5", | ||
"express": "~3.4.7", | ||
"gulp-rimraf": "0.0.8", | ||
"open": "~0.0.4", | ||
"expect.js": "~0.2.0" | ||
}, | ||
"licenses": [ | ||
{ | ||
"type" : "MIT", | ||
"url" : "http://www.opensource.org/licenses/mit-license.php" | ||
"type": "MIT", | ||
"url": "http://www.opensource.org/licenses/mit-license.php" | ||
}, | ||
{ | ||
"type" : "GPL", | ||
"url" : "http://www.opensource.org/licenses/gpl-3.0.html" | ||
"type": "GPL", | ||
"url": "http://www.opensource.org/licenses/gpl-3.0.html" | ||
} | ||
] | ||
], | ||
"scripts": { | ||
"test": "mocha ./spec/*.js", | ||
"build": "gulp", | ||
"start": "gulp server" | ||
} | ||
} |
# Postal.js | ||
## Version 0.8.11 (Dual Licensed [MIT](http://www.opensource.org/licenses/mit-license) & [GPL](http://www.opensource.org/licenses/gpl-license)) | ||
## Version 0.9.0-rc1 (Dual Licensed [MIT](http://www.opensource.org/licenses/mit-license) & [GPL](http://www.opensource.org/licenses/gpl-license)) | ||
*(Note: this is the first release candidate for v0.9.0)* | ||
@@ -121,3 +122,3 @@ ## What is it? | ||
## More References | ||
Please visit the [postal.js wiki](https://github.com/postaljs/postal.js/wiki) for API documentation, discussion of concepts and links to blogs/articles on postal.js. | ||
Please visit the [postal.js wiki](https://github.com/postaljs/postal.js/wiki) for API documentation, discussion of concepts and links to blogs/articles on postal.js. Just bear in mind that the wiki won't be updated for v0.9.0 until a release is final. | ||
@@ -129,3 +130,2 @@ ## How can I extend it? | ||
* Write a custom federation plugin, to federate instances of postal across a transport of your choice. | ||
* You can write an entirely new bus implementation if you wanted. The postal `subscribe`, `publish` and `addWiretap` calls all simply wrap a concrete implementation provided by the `postal.configuration.bus` object. For example, if you wanted a bus that stored message history in local storage and pushed a dump of past messages to a new subscriber, you'd simply write your implementation and then swap the default one out by calling: `postal.configuration.bus = myWayBetterBusImplementation`. | ||
* You can also change how the `bindingResolver` matches subscriptions to message topics being published. You may not care for the AMQP-style bindings functionality. No problem! Write your own resolver object that implements a `compare` and `reset` method and swap the core version out with your implementation by calling: `postal.configuration.resolver = myWayBetterResolver`. | ||
@@ -135,2 +135,16 @@ | ||
## Build, Dependencies, etc. | ||
* postal depends on [underscore.js](http://underscorejs.org/) | ||
* postal uses [gulp.js](http://gulpjs.com/) for building, running tests and examples. | ||
* To build | ||
* run `npm install` (to install all deps) | ||
* run `npm run build` - then check the lib folder for the output | ||
* To run tests & examples | ||
* To run node-based tests: `npm run test` | ||
* To run browser-based tests & examples: | ||
* run `npm start` | ||
* navigate in your browser to <http://localhost:3080/> | ||
## Can I contribute? | ||
@@ -144,3 +158,3 @@ Please - by all means! While I hope the API is relatively stable, I'm open to pull requests. (Hint - if you want a feature implemented, a pull request gives it a much higher probability of being included than simply asking me.) As I said, pull requests are most certainly welcome - but please include tests for your additions. Otherwise, it will disappear into the ether. | ||
* The `SubscriptionDefinition` object will be given the ability to pause (skip) responding to subscriptions | ||
* We'll be working on experimental "lightweight" builds of postal, providing a basic SubscriptionDefinition prototype, but removing the more advanced options if you don't need them. Reduced size builds would be offered alongside full builds, giving you page-weight-sensitive options. | ||
* We'll be working on experimental "underscore-free" builds of postal, providing ES5 method shims so that you don't have to pull in underscore/lodash just to run postal. | ||
* What else would you like to see? |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Native code
Supply chain riskContains native code (e.g., compiled binaries or shared libraries). Including native code can obscure malicious behavior.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
Mixed license
License(Experimental) Package contains multiple licenses.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1563555
77
16956
156
15
1
3
2
- Removedunderscore@1.13.7(transitive)
Updatedunderscore@~1.5.2