Updated build artifacts

This commit is contained in:
Jim Cowart 2012-03-01 03:42:33 -05:00
parent e59d3ab07a
commit be9ca57c46
11 changed files with 342 additions and 392 deletions

View file

@ -10,39 +10,7 @@ var DEFAULT_EXCHANGE = "/",
DEFAULT_PRIORITY = 50,
DEFAULT_DISPOSEAFTER = 0,
SYSTEM_EXCHANGE = "postal",
NO_OP = function() { },
parsePublishArgs = function(args) {
var parsed = { envelope: { } }, env;
switch(args.length) {
case 3:
if(typeof args[1] === "Object" && typeof args[2] === "Object") {
parsed.envelope.exchange = DEFAULT_EXCHANGE;
parsed.envelope.topic = args[0];
parsed.payload = args[1];
env = parsed.envelope;
parsed.envelope = _.extend(env, args[2]);
}
else {
parsed.envelope.exchange = args[0];
parsed.envelope.topic = args[1];
parsed.payload = args[2];
}
break;
case 4:
parsed.envelope.exchange = args[0];
parsed.envelope.topic = args[1];
parsed.payload = args[2];
env = parsed.envelope;
parsed.envelope = _.extend(env, args[3]);
break;
default:
parsed.envelope.exchange = DEFAULT_EXCHANGE;
parsed.envelope.topic = args[0];
parsed.payload = args[1];
break;
}
return parsed;
};
NO_OP = function() { };
var DistinctPredicate = function() {
var previous;
@ -73,12 +41,11 @@ ChannelDefinition.prototype = {
},
publish: function(data, envelope) {
var env = _.extend({
exchange: this.exchange,
timeStamp: new Date(),
topic: this.topic
}, envelope);
postal.configuration.bus.publish(data, env);
var env = envelope || {};
env.exchange = this.exchange;
env.timeStamp = new Date();
env.topic = this.topic;
postal.configuration.bus.publish(env, data);
}
};
@ -87,12 +54,15 @@ var SubscriptionDefinition = function(exchange, topic, callback) {
this.topic = topic;
this.callback = callback;
this.priority = DEFAULT_PRIORITY;
this.constraints = [];
this.constraints = new Array(0);
this.maxCalls = DEFAULT_DISPOSEAFTER;
this.onHandled = NO_OP;
this.context = null;
postal.publish(SYSTEM_EXCHANGE, "subscription.created",
postal.publish({
exchange: SYSTEM_EXCHANGE,
topic: "subscription.created"
},
{
event: "subscription.created",
exchange: exchange,
@ -103,7 +73,10 @@ var SubscriptionDefinition = function(exchange, topic, callback) {
SubscriptionDefinition.prototype = {
unsubscribe: function() {
postal.configuration.bus.unsubscribe(this);
postal.publish(SYSTEM_EXCHANGE, "subscription.removed",
postal.publish({
exchange: SYSTEM_EXCHANGE,
topic: "subscription.removed"
},
{
event: "subscription.removed",
exchange: this.exchange,
@ -215,7 +188,10 @@ var bindingsResolver = {
if(this.cache[topic] && this.cache[topic][binding]) {
return true;
}
var rgx = new RegExp("^" + this.regexify(binding) + "$"), // match from start to end of string
// binding.replace(/\./g,"\\.") // escape actual periods
// .replace(/\*/g, ".*") // asterisks match any value
// .replace(/#/g, "[A-Z,a-z,0-9]*"); // hash matches any alpha-numeric 'word'
var rgx = new RegExp("^" + binding.replace(/\./g,"\\.").replace(/\*/g, ".*").replace(/#/g, "[A-Z,a-z,0-9]*") + "$"),
result = rgx.test(topic);
if(result) {
if(!this.cache[topic]) {
@ -224,12 +200,6 @@ var bindingsResolver = {
this.cache[topic][binding] = true;
}
return result;
},
regexify: function(binding) {
return binding.replace(/\./g,"\\.") // escape actual periods
.replace(/\*/g, ".*") // asterisks match any value
.replace(/#/g, "[A-Z,a-z,0-9]*"); // hash matches any alpha-numeric 'word'
}
};
@ -237,10 +207,12 @@ var localBus = {
subscriptions: {},
wireTaps: [],
wireTaps: new Array(0),
publish: function(data, envelope) {
this.notifyTaps(data, envelope);
publish: function(envelope, data) {
_.each(this.wireTaps,function(tap) {
tap(envelope, data);
});
_.each(this.subscriptions[envelope.exchange], function(topic) {
_.each(topic, function(binding){
@ -257,10 +229,15 @@ var localBus = {
},
subscribe: function(subDef) {
var idx, found, fn, exch, subs;
var idx, found, fn, exch = this.subscriptions[subDef.exchange], subs;
exch = this.subscriptions[subDef.exchange] = this.subscriptions[subDef.exchange] || {};
subs = this.subscriptions[subDef.exchange][subDef.topic] = this.subscriptions[subDef.exchange][subDef.topic] || [];
if(!exch) {
exch = this.subscriptions[subDef.exchange] = {};
}
subs = this.subscriptions[subDef.exchange][subDef.topic]
if(!subs) {
subs = this.subscriptions[subDef.exchange][subDef.topic] = new Array(0);
}
idx = subs.length - 1;
//if(!_.any(subs, function(cfg) { return cfg === subDef; })) {
@ -277,12 +254,6 @@ var localBus = {
//}
},
notifyTaps: function(data, envelope) {
_.each(this.wireTaps,function(tap) {
tap(data, envelope);
});
},
unsubscribe: function(config) {
if(this.subscriptions[config.exchange][config.topic]) {
var len = this.subscriptions[config.exchange][config.topic].length,
@ -308,30 +279,42 @@ var localBus = {
}
};
var publishPicker = {
"2" : function(envelope, payload) {
if(!envelope.exchange) {
envelope.exchange = DEFAULT_EXCHANGE;
}
postal.configuration.bus.publish(envelope, payload);
},
"3" : function(exchange, topic, payload) {
postal.configuration.bus.publish({ exchange: exchange, topic: topic }, payload);
}
};
var postal = {
configuration: {
bus: localBus,
resolver: bindingsResolver
},
channel: function(exchange, topic) {
var exch = topic ? exchange : DEFAULT_EXCHANGE,
tpc = topic || exchange;
channel: function(options) {
var exch = options.exchange || DEFAULT_EXCHANGE,
tpc = options.topic;
return new ChannelDefinition(exch, tpc);
},
subscribe: function(exchange, topic, callback) {
var callbk = callback || topic,
tpc = callback ? topic : exchange,
exch = callback ? exchange : DEFAULT_EXCHANGE;
var channel = this.channel(exch, tpc);
return channel.subscribe(callbk);
subscribe: function(options) {
var callback = options.callback,
topic = options.topic,
exchange = options.exchange || DEFAULT_EXCHANGE;
return new ChannelDefinition(exchange, topic).subscribe(callback);
},
publish: function(exchange, topic, payload, envelopeOptions) {
var parsedArgs = parsePublishArgs([].slice.call(arguments,0));
var channel = this.channel(parsedArgs.envelope.exchange, parsedArgs.envelope.topic);
channel.publish(parsedArgs.payload, parsedArgs.envelope);
publish: function() {
var len = arguments.length;
if(publishPicker[len]) {
publishPicker[len].apply(this, arguments);
}
},
addWireTap: function(callback) {
@ -339,21 +322,28 @@ var postal = {
},
bindExchanges: function(sources, destinations) {
var subscriptions = [];
var subscriptions;
if(!_.isArray(sources)) {
sources = [sources];
}
if(!_.isArray(destinations)) {
destinations = [destinations];
}
subscriptions = new Array(sources.length * destinations.length);
_.each(sources, function(source){
var sourceTopic = source.topic || "*";
_.each(destinations, function(destination) {
var destExchange = destination.exchange || DEFAULT_EXCHANGE;
subscriptions.push(
postal.subscribe(source.exchange || DEFAULT_EXCHANGE, source.topic || "*", function(msg, env) {
var destTopic = _.isFunction(destination.topic) ? destination.topic(env.topic) : destination.topic || env.topic;
postal.publish(destExchange, destTopic, msg);
postal.subscribe({
exchange: source.exchange || DEFAULT_EXCHANGE,
topic: source.topic || "*",
callback : function(msg, env) {
var newEnv = env;
newEnv.topic = _.isFunction(destination.topic) ? destination.topic(env.topic) : destination.topic || env.topic;
newEnv.exchange = destExchange;
postal.publish(newEnv, msg);
}
})
);
});

View file

@ -10,39 +10,7 @@ var DEFAULT_EXCHANGE = "/",
DEFAULT_PRIORITY = 50,
DEFAULT_DISPOSEAFTER = 0,
SYSTEM_EXCHANGE = "postal",
NO_OP = function() { },
parsePublishArgs = function(args) {
var parsed = { envelope: { } }, env;
switch(args.length) {
case 3:
if(typeof args[1] === "Object" && typeof args[2] === "Object") {
parsed.envelope.exchange = DEFAULT_EXCHANGE;
parsed.envelope.topic = args[0];
parsed.payload = args[1];
env = parsed.envelope;
parsed.envelope = _.extend(env, args[2]);
}
else {
parsed.envelope.exchange = args[0];
parsed.envelope.topic = args[1];
parsed.payload = args[2];
}
break;
case 4:
parsed.envelope.exchange = args[0];
parsed.envelope.topic = args[1];
parsed.payload = args[2];
env = parsed.envelope;
parsed.envelope = _.extend(env, args[3]);
break;
default:
parsed.envelope.exchange = DEFAULT_EXCHANGE;
parsed.envelope.topic = args[0];
parsed.payload = args[1];
break;
}
return parsed;
};
NO_OP = function() { };
var DistinctPredicate = function() {
var previous;
@ -73,12 +41,11 @@ ChannelDefinition.prototype = {
},
publish: function(data, envelope) {
var env = _.extend({
exchange: this.exchange,
timeStamp: new Date(),
topic: this.topic
}, envelope);
postal.configuration.bus.publish(data, env);
var env = envelope || {};
env.exchange = this.exchange;
env.timeStamp = new Date();
env.topic = this.topic;
postal.configuration.bus.publish(env, data);
}
};
@ -87,12 +54,15 @@ var SubscriptionDefinition = function(exchange, topic, callback) {
this.topic = topic;
this.callback = callback;
this.priority = DEFAULT_PRIORITY;
this.constraints = [];
this.constraints = new Array(0);
this.maxCalls = DEFAULT_DISPOSEAFTER;
this.onHandled = NO_OP;
this.context = null;
postal.publish(SYSTEM_EXCHANGE, "subscription.created",
postal.publish({
exchange: SYSTEM_EXCHANGE,
topic: "subscription.created"
},
{
event: "subscription.created",
exchange: exchange,
@ -103,7 +73,10 @@ var SubscriptionDefinition = function(exchange, topic, callback) {
SubscriptionDefinition.prototype = {
unsubscribe: function() {
postal.configuration.bus.unsubscribe(this);
postal.publish(SYSTEM_EXCHANGE, "subscription.removed",
postal.publish({
exchange: SYSTEM_EXCHANGE,
topic: "subscription.removed"
},
{
event: "subscription.removed",
exchange: this.exchange,
@ -215,7 +188,10 @@ var bindingsResolver = {
if(this.cache[topic] && this.cache[topic][binding]) {
return true;
}
var rgx = new RegExp("^" + this.regexify(binding) + "$"), // match from start to end of string
// binding.replace(/\./g,"\\.") // escape actual periods
// .replace(/\*/g, ".*") // asterisks match any value
// .replace(/#/g, "[A-Z,a-z,0-9]*"); // hash matches any alpha-numeric 'word'
var rgx = new RegExp("^" + binding.replace(/\./g,"\\.").replace(/\*/g, ".*").replace(/#/g, "[A-Z,a-z,0-9]*") + "$"),
result = rgx.test(topic);
if(result) {
if(!this.cache[topic]) {
@ -224,12 +200,6 @@ var bindingsResolver = {
this.cache[topic][binding] = true;
}
return result;
},
regexify: function(binding) {
return binding.replace(/\./g,"\\.") // escape actual periods
.replace(/\*/g, ".*") // asterisks match any value
.replace(/#/g, "[A-Z,a-z,0-9]*"); // hash matches any alpha-numeric 'word'
}
};
@ -237,10 +207,12 @@ var localBus = {
subscriptions: {},
wireTaps: [],
wireTaps: new Array(0),
publish: function(data, envelope) {
this.notifyTaps(data, envelope);
publish: function(envelope, data) {
_.each(this.wireTaps,function(tap) {
tap(envelope, data);
});
_.each(this.subscriptions[envelope.exchange], function(topic) {
_.each(topic, function(binding){
@ -257,10 +229,15 @@ var localBus = {
},
subscribe: function(subDef) {
var idx, found, fn, exch, subs;
var idx, found, fn, exch = this.subscriptions[subDef.exchange], subs;
exch = this.subscriptions[subDef.exchange] = this.subscriptions[subDef.exchange] || {};
subs = this.subscriptions[subDef.exchange][subDef.topic] = this.subscriptions[subDef.exchange][subDef.topic] || [];
if(!exch) {
exch = this.subscriptions[subDef.exchange] = {};
}
subs = this.subscriptions[subDef.exchange][subDef.topic]
if(!subs) {
subs = this.subscriptions[subDef.exchange][subDef.topic] = new Array(0);
}
idx = subs.length - 1;
//if(!_.any(subs, function(cfg) { return cfg === subDef; })) {
@ -277,12 +254,6 @@ var localBus = {
//}
},
notifyTaps: function(data, envelope) {
_.each(this.wireTaps,function(tap) {
tap(data, envelope);
});
},
unsubscribe: function(config) {
if(this.subscriptions[config.exchange][config.topic]) {
var len = this.subscriptions[config.exchange][config.topic].length,
@ -308,30 +279,42 @@ var localBus = {
}
};
var publishPicker = {
"2" : function(envelope, payload) {
if(!envelope.exchange) {
envelope.exchange = DEFAULT_EXCHANGE;
}
postal.configuration.bus.publish(envelope, payload);
},
"3" : function(exchange, topic, payload) {
postal.configuration.bus.publish({ exchange: exchange, topic: topic }, payload);
}
};
var postal = {
configuration: {
bus: localBus,
resolver: bindingsResolver
},
channel: function(exchange, topic) {
var exch = topic ? exchange : DEFAULT_EXCHANGE,
tpc = topic || exchange;
channel: function(options) {
var exch = options.exchange || DEFAULT_EXCHANGE,
tpc = options.topic;
return new ChannelDefinition(exch, tpc);
},
subscribe: function(exchange, topic, callback) {
var callbk = callback || topic,
tpc = callback ? topic : exchange,
exch = callback ? exchange : DEFAULT_EXCHANGE;
var channel = this.channel(exch, tpc);
return channel.subscribe(callbk);
subscribe: function(options) {
var callback = options.callback,
topic = options.topic,
exchange = options.exchange || DEFAULT_EXCHANGE;
return new ChannelDefinition(exchange, topic).subscribe(callback);
},
publish: function(exchange, topic, payload, envelopeOptions) {
var parsedArgs = parsePublishArgs([].slice.call(arguments,0));
var channel = this.channel(parsedArgs.envelope.exchange, parsedArgs.envelope.topic);
channel.publish(parsedArgs.payload, parsedArgs.envelope);
publish: function() {
var len = arguments.length;
if(publishPicker[len]) {
publishPicker[len].apply(this, arguments);
}
},
addWireTap: function(callback) {
@ -339,21 +322,28 @@ var postal = {
},
bindExchanges: function(sources, destinations) {
var subscriptions = [];
var subscriptions;
if(!_.isArray(sources)) {
sources = [sources];
}
if(!_.isArray(destinations)) {
destinations = [destinations];
}
subscriptions = new Array(sources.length * destinations.length);
_.each(sources, function(source){
var sourceTopic = source.topic || "*";
_.each(destinations, function(destination) {
var destExchange = destination.exchange || DEFAULT_EXCHANGE;
subscriptions.push(
postal.subscribe(source.exchange || DEFAULT_EXCHANGE, source.topic || "*", function(msg, env) {
var destTopic = _.isFunction(destination.topic) ? destination.topic(env.topic) : destination.topic || env.topic;
postal.publish(destExchange, destTopic, msg);
postal.subscribe({
exchange: source.exchange || DEFAULT_EXCHANGE,
topic: source.topic || "*",
callback : function(msg, env) {
var newEnv = env;
newEnv.topic = _.isFunction(destination.topic) ? destination.topic(env.topic) : destination.topic || env.topic;
newEnv.exchange = destExchange;
postal.publish(newEnv, msg);
}
})
);
});

View file

@ -10,39 +10,7 @@ var DEFAULT_EXCHANGE = "/",
DEFAULT_PRIORITY = 50,
DEFAULT_DISPOSEAFTER = 0,
SYSTEM_EXCHANGE = "postal",
NO_OP = function() { },
parsePublishArgs = function(args) {
var parsed = { envelope: { } }, env;
switch(args.length) {
case 3:
if(typeof args[1] === "Object" && typeof args[2] === "Object") {
parsed.envelope.exchange = DEFAULT_EXCHANGE;
parsed.envelope.topic = args[0];
parsed.payload = args[1];
env = parsed.envelope;
parsed.envelope = _.extend(env, args[2]);
}
else {
parsed.envelope.exchange = args[0];
parsed.envelope.topic = args[1];
parsed.payload = args[2];
}
break;
case 4:
parsed.envelope.exchange = args[0];
parsed.envelope.topic = args[1];
parsed.payload = args[2];
env = parsed.envelope;
parsed.envelope = _.extend(env, args[3]);
break;
default:
parsed.envelope.exchange = DEFAULT_EXCHANGE;
parsed.envelope.topic = args[0];
parsed.payload = args[1];
break;
}
return parsed;
};
NO_OP = function() { };
var DistinctPredicate = function() {
var previous;
@ -73,12 +41,11 @@ ChannelDefinition.prototype = {
},
publish: function(data, envelope) {
var env = _.extend({
exchange: this.exchange,
timeStamp: new Date(),
topic: this.topic
}, envelope);
postal.configuration.bus.publish(data, env);
var env = envelope || {};
env.exchange = this.exchange;
env.timeStamp = new Date();
env.topic = this.topic;
postal.configuration.bus.publish(env, data);
}
};
@ -87,12 +54,15 @@ var SubscriptionDefinition = function(exchange, topic, callback) {
this.topic = topic;
this.callback = callback;
this.priority = DEFAULT_PRIORITY;
this.constraints = [];
this.constraints = new Array(0);
this.maxCalls = DEFAULT_DISPOSEAFTER;
this.onHandled = NO_OP;
this.context = null;
postal.publish(SYSTEM_EXCHANGE, "subscription.created",
postal.publish({
exchange: SYSTEM_EXCHANGE,
topic: "subscription.created"
},
{
event: "subscription.created",
exchange: exchange,
@ -103,7 +73,10 @@ var SubscriptionDefinition = function(exchange, topic, callback) {
SubscriptionDefinition.prototype = {
unsubscribe: function() {
postal.configuration.bus.unsubscribe(this);
postal.publish(SYSTEM_EXCHANGE, "subscription.removed",
postal.publish({
exchange: SYSTEM_EXCHANGE,
topic: "subscription.removed"
},
{
event: "subscription.removed",
exchange: this.exchange,
@ -215,7 +188,10 @@ var bindingsResolver = {
if(this.cache[topic] && this.cache[topic][binding]) {
return true;
}
var rgx = new RegExp("^" + this.regexify(binding) + "$"), // match from start to end of string
// binding.replace(/\./g,"\\.") // escape actual periods
// .replace(/\*/g, ".*") // asterisks match any value
// .replace(/#/g, "[A-Z,a-z,0-9]*"); // hash matches any alpha-numeric 'word'
var rgx = new RegExp("^" + binding.replace(/\./g,"\\.").replace(/\*/g, ".*").replace(/#/g, "[A-Z,a-z,0-9]*") + "$"),
result = rgx.test(topic);
if(result) {
if(!this.cache[topic]) {
@ -224,12 +200,6 @@ var bindingsResolver = {
this.cache[topic][binding] = true;
}
return result;
},
regexify: function(binding) {
return binding.replace(/\./g,"\\.") // escape actual periods
.replace(/\*/g, ".*") // asterisks match any value
.replace(/#/g, "[A-Z,a-z,0-9]*"); // hash matches any alpha-numeric 'word'
}
};
@ -237,10 +207,12 @@ var localBus = {
subscriptions: {},
wireTaps: [],
wireTaps: new Array(0),
publish: function(data, envelope) {
this.notifyTaps(data, envelope);
publish: function(envelope, data) {
_.each(this.wireTaps,function(tap) {
tap(envelope, data);
});
_.each(this.subscriptions[envelope.exchange], function(topic) {
_.each(topic, function(binding){
@ -257,10 +229,15 @@ var localBus = {
},
subscribe: function(subDef) {
var idx, found, fn, exch, subs;
var idx, found, fn, exch = this.subscriptions[subDef.exchange], subs;
exch = this.subscriptions[subDef.exchange] = this.subscriptions[subDef.exchange] || {};
subs = this.subscriptions[subDef.exchange][subDef.topic] = this.subscriptions[subDef.exchange][subDef.topic] || [];
if(!exch) {
exch = this.subscriptions[subDef.exchange] = {};
}
subs = this.subscriptions[subDef.exchange][subDef.topic]
if(!subs) {
subs = this.subscriptions[subDef.exchange][subDef.topic] = new Array(0);
}
idx = subs.length - 1;
//if(!_.any(subs, function(cfg) { return cfg === subDef; })) {
@ -277,12 +254,6 @@ var localBus = {
//}
},
notifyTaps: function(data, envelope) {
_.each(this.wireTaps,function(tap) {
tap(data, envelope);
});
},
unsubscribe: function(config) {
if(this.subscriptions[config.exchange][config.topic]) {
var len = this.subscriptions[config.exchange][config.topic].length,
@ -308,30 +279,42 @@ var localBus = {
}
};
var publishPicker = {
"2" : function(envelope, payload) {
if(!envelope.exchange) {
envelope.exchange = DEFAULT_EXCHANGE;
}
postal.configuration.bus.publish(envelope, payload);
},
"3" : function(exchange, topic, payload) {
postal.configuration.bus.publish({ exchange: exchange, topic: topic }, payload);
}
};
var postal = {
configuration: {
bus: localBus,
resolver: bindingsResolver
},
channel: function(exchange, topic) {
var exch = topic ? exchange : DEFAULT_EXCHANGE,
tpc = topic || exchange;
channel: function(options) {
var exch = options.exchange || DEFAULT_EXCHANGE,
tpc = options.topic;
return new ChannelDefinition(exch, tpc);
},
subscribe: function(exchange, topic, callback) {
var callbk = callback || topic,
tpc = callback ? topic : exchange,
exch = callback ? exchange : DEFAULT_EXCHANGE;
var channel = this.channel(exch, tpc);
return channel.subscribe(callbk);
subscribe: function(options) {
var callback = options.callback,
topic = options.topic,
exchange = options.exchange || DEFAULT_EXCHANGE;
return new ChannelDefinition(exchange, topic).subscribe(callback);
},
publish: function(exchange, topic, payload, envelopeOptions) {
var parsedArgs = parsePublishArgs([].slice.call(arguments,0));
var channel = this.channel(parsedArgs.envelope.exchange, parsedArgs.envelope.topic);
channel.publish(parsedArgs.payload, parsedArgs.envelope);
publish: function() {
var len = arguments.length;
if(publishPicker[len]) {
publishPicker[len].apply(this, arguments);
}
},
addWireTap: function(callback) {
@ -339,21 +322,28 @@ var postal = {
},
bindExchanges: function(sources, destinations) {
var subscriptions = [];
var subscriptions;
if(!_.isArray(sources)) {
sources = [sources];
}
if(!_.isArray(destinations)) {
destinations = [destinations];
}
subscriptions = new Array(sources.length * destinations.length);
_.each(sources, function(source){
var sourceTopic = source.topic || "*";
_.each(destinations, function(destination) {
var destExchange = destination.exchange || DEFAULT_EXCHANGE;
subscriptions.push(
postal.subscribe(source.exchange || DEFAULT_EXCHANGE, source.topic || "*", function(msg, env) {
var destTopic = _.isFunction(destination.topic) ? destination.topic(env.topic) : destination.topic || env.topic;
postal.publish(destExchange, destTopic, msg);
postal.subscribe({
exchange: source.exchange || DEFAULT_EXCHANGE,
topic: source.topic || "*",
callback : function(msg, env) {
var newEnv = env;
newEnv.topic = _.isFunction(destination.topic) ? destination.topic(env.topic) : destination.topic || env.topic;
newEnv.exchange = destExchange;
postal.publish(newEnv, msg);
}
})
);
});

Binary file not shown.

View file

@ -1 +1 @@
define(["underscore"],function(a){var b="/",c=50,d=0,e="postal",f=function(){},g=function(c){var d={envelope:{}},e;switch(c.length){case 3:typeof c[1]=="Object"&&typeof c[2]=="Object"?(d.envelope.exchange=b,d.envelope.topic=c[0],d.payload=c[1],e=d.envelope,d.envelope=a.extend(e,c[2])):(d.envelope.exchange=c[0],d.envelope.topic=c[1],d.payload=c[2]);break;case 4:d.envelope.exchange=c[0],d.envelope.topic=c[1],d.payload=c[2],e=d.envelope,d.envelope=a.extend(e,c[3]);break;default:d.envelope.exchange=b,d.envelope.topic=c[0],d.payload=c[1]}return d},h=function(){var b;return function(c){var d=!1;return a.isString(c)?(d=c===b,b=c):(d=a.isEqual(c,b),b=a.clone(c)),!d}},i=function(a,b){this.exchange=a,this.topic=b};i.prototype={subscribe:function(a){var b=new j(this.exchange,this.topic,a);return m.configuration.bus.subscribe(b),b},publish:function(b,c){var d=a.extend({exchange:this.exchange,timeStamp:new Date,topic:this.topic},c);m.configuration.bus.publish(b,d)}};var j=function(a,b,g){this.exchange=a,this.topic=b,this.callback=g,this.priority=c,this.constraints=[],this.maxCalls=d,this.onHandled=f,this.context=null,m.publish(e,"subscription.created",{event:"subscription.created",exchange:a,topic:b})};j.prototype={unsubscribe:function(){m.configuration.bus.unsubscribe(this),m.publish(e,"subscription.removed",{event:"subscription.removed",exchange:this.exchange,topic:this.topic})},defer:function(){var a=this.callback;return this.callback=function(b){setTimeout(a,0,b)},this},disposeAfter:function(b){if(a.isNaN(b)||b<=0)throw"The value provided to disposeAfter (maxCalls) must be a number greater than zero.";var c=this.onHandled,d=a.after(b,a.bind(function(){this.unsubscribe(this)},this));return this.onHandled=function(){c.apply(this.context,arguments),d()},this},ignoreDuplicates:function(){return this.withConstraint(new h),this},whenHandledThenExecute:function(b){if(!a.isFunction(b))throw"Value provided to 'whenHandledThenExecute' must be a function";return this.onHandled=b,this},withConstraint:function(b){if(!a.isFunction(b))throw"Predicate constraint must be a function";return this.constraints.push(b),this},withConstraints:function(b){var c=this;return a.isArray(b)&&a.each(b,function(a){c.withConstraint(a)}),c},withContext:function(a){return this.context=a,this},withDebounce:function(b){if(a.isNaN(b))throw"Milliseconds must be a number";var c=this.callback;return this.callback=a.debounce(c,b),this},withDelay:function(b){if(a.isNaN(b))throw"Milliseconds must be a number";var c=this.callback;return this.callback=function(a){setTimeout(c,b,a)},this},withPriority:function(b){if(a.isNaN(b))throw"Priority must be a number";return this.priority=b,this},withThrottle:function(b){if(a.isNaN(b))throw"Milliseconds must be a number";var c=this.callback;return this.callback=a.throttle(c,b),this}};var k={cache:{},compare:function(a,b){if(this.cache[b]&&this.cache[b][a])return!0;var c=new RegExp("^"+this.regexify(a)+"$"),d=c.test(b);return d&&(this.cache[b]||(this.cache[b]={}),this.cache[b][a]=!0),d},regexify:function(a){return a.replace(/\./g,"\\.").replace(/\*/g,".*").replace(/#/g,"[A-Z,a-z,0-9]*")}},l={subscriptions:{},wireTaps:[],publish:function(b,c){this.notifyTaps(b,c),a.each(this.subscriptions[c.exchange],function(d){a.each(d,function(d){m.configuration.resolver.compare(d.topic,c.topic)&&a.all(d.constraints,function(a){return a(b)})&&typeof d.callback=="function"&&(d.callback.apply(d.context,[b,c]),d.onHandled())})})},subscribe:function(a){var b,c,d,e,f;e=this.subscriptions[a.exchange]=this.subscriptions[a.exchange]||{},f=this.subscriptions[a.exchange][a.topic]=this.subscriptions[a.exchange][a.topic]||[],b=f.length-1;for(;b>=0;b--)if(f[b].priority<=a.priority){f.splice(b+1,0,a),c=!0;break}c||f.unshift(a)},notifyTaps:function(b,c){a.each(this.wireTaps,function(a){a(b,c)})},unsubscribe:function(a){if(this.subscriptions[a.exchange][a.topic]){var b=this.subscriptions[a.exchange][a.topic].length,c=0;for(;c<b;c++)if(this.subscriptions[a.exchange][a.topic][c]===a){this.subscriptions[a.exchange][a.topic].splice(c,1);break}}},addWireTap:function(a){var b=this;return b.wireTaps.push(a),function(){var c=b.wireTaps.indexOf(a);c!==-1&&b.wireTaps.splice(c,1)}}},m={configuration:{bus:l,resolver:k},channel:function(a,c){var d=c?a:b,e=c||a;return new i(d,e)},subscribe:function(a,c,d){var e=d||c,f=d?c:a,g=d?a:b,h=this.channel(g,f);return h.subscribe(e)},publish:function(a,b,c,d){var e=g([].slice.call(arguments,0)),f=this.channel(e.envelope.exchange,e.envelope.topic);f.publish(e.payload,e.envelope)},addWireTap:function(a){return this.configuration.bus.addWireTap(a)},bindExchanges:function(c,d){var e=[];return a.isArray(c)||(c=[c]),a.isArray(d)||(d=[d]),a.each(c,function(c){var f=c.topic||"*";a.each(d,function(d){var f=d.exchange||b;e.push(m.subscribe(c.exchange||b,c.topic||"*",function(b,c){var e=a.isFunction(d.topic)?d.topic(c.topic):d.topic||c.topic;m.publish(f,e,b)}))})}),e}};return m})
define(["underscore"],function(a){var b="/",c=50,d=0,e="postal",f=function(){},g=function(){var b;return function(c){var d=!1;return a.isString(c)?(d=c===b,b=c):(d=a.isEqual(c,b),b=a.clone(c)),!d}},h=function(a,b){this.exchange=a,this.topic=b};h.prototype={subscribe:function(a){var b=new i(this.exchange,this.topic,a);return m.configuration.bus.subscribe(b),b},publish:function(a,b){var c=b||{};c.exchange=this.exchange,c.timeStamp=new Date,c.topic=this.topic,m.configuration.bus.publish(c,a)}};var i=function(a,b,g){this.exchange=a,this.topic=b,this.callback=g,this.priority=c,this.constraints=new Array(0),this.maxCalls=d,this.onHandled=f,this.context=null,m.publish({exchange:e,topic:"subscription.created"},{event:"subscription.created",exchange:a,topic:b})};i.prototype={unsubscribe:function(){m.configuration.bus.unsubscribe(this),m.publish({exchange:e,topic:"subscription.removed"},{event:"subscription.removed",exchange:this.exchange,topic:this.topic})},defer:function(){var a=this.callback;return this.callback=function(b){setTimeout(a,0,b)},this},disposeAfter:function(b){if(a.isNaN(b)||b<=0)throw"The value provided to disposeAfter (maxCalls) must be a number greater than zero.";var c=this.onHandled,d=a.after(b,a.bind(function(){this.unsubscribe(this)},this));return this.onHandled=function(){c.apply(this.context,arguments),d()},this},ignoreDuplicates:function(){return this.withConstraint(new g),this},whenHandledThenExecute:function(b){if(!a.isFunction(b))throw"Value provided to 'whenHandledThenExecute' must be a function";return this.onHandled=b,this},withConstraint:function(b){if(!a.isFunction(b))throw"Predicate constraint must be a function";return this.constraints.push(b),this},withConstraints:function(b){var c=this;return a.isArray(b)&&a.each(b,function(a){c.withConstraint(a)}),c},withContext:function(a){return this.context=a,this},withDebounce:function(b){if(a.isNaN(b))throw"Milliseconds must be a number";var c=this.callback;return this.callback=a.debounce(c,b),this},withDelay:function(b){if(a.isNaN(b))throw"Milliseconds must be a number";var c=this.callback;return this.callback=function(a){setTimeout(c,b,a)},this},withPriority:function(b){if(a.isNaN(b))throw"Priority must be a number";return this.priority=b,this},withThrottle:function(b){if(a.isNaN(b))throw"Milliseconds must be a number";var c=this.callback;return this.callback=a.throttle(c,b),this}};var j={cache:{},compare:function(a,b){if(this.cache[b]&&this.cache[b][a])return!0;var c=new RegExp("^"+a.replace(/\./g,"\\.").replace(/\*/g,".*").replace(/#/g,"[A-Z,a-z,0-9]*")+"$"),d=c.test(b);return d&&(this.cache[b]||(this.cache[b]={}),this.cache[b][a]=!0),d}},k={subscriptions:{},wireTaps:new Array(0),publish:function(b,c){a.each(this.wireTaps,function(a){a(b,c)}),a.each(this.subscriptions[b.exchange],function(d){a.each(d,function(d){m.configuration.resolver.compare(d.topic,b.topic)&&a.all(d.constraints,function(a){return a(c)})&&typeof d.callback=="function"&&(d.callback.apply(d.context,[c,b]),d.onHandled())})})},subscribe:function(a){var b,c,d,e=this.subscriptions[a.exchange],f;e||(e=this.subscriptions[a.exchange]={}),f=this.subscriptions[a.exchange][a.topic],f||(f=this.subscriptions[a.exchange][a.topic]=new Array(0)),b=f.length-1;for(;b>=0;b--)if(f[b].priority<=a.priority){f.splice(b+1,0,a),c=!0;break}c||f.unshift(a)},unsubscribe:function(a){if(this.subscriptions[a.exchange][a.topic]){var b=this.subscriptions[a.exchange][a.topic].length,c=0;for(;c<b;c++)if(this.subscriptions[a.exchange][a.topic][c]===a){this.subscriptions[a.exchange][a.topic].splice(c,1);break}}},addWireTap:function(a){var b=this;return b.wireTaps.push(a),function(){var c=b.wireTaps.indexOf(a);c!==-1&&b.wireTaps.splice(c,1)}}},l={2:function(a,c){a.exchange||(a.exchange=b),m.configuration.bus.publish(a,c)},3:function(a,b,c){m.configuration.bus.publish({exchange:a,topic:b},c)}},m={configuration:{bus:k,resolver:j},channel:function(a){var c=a.exchange||b,d=a.topic;return new h(c,d)},subscribe:function(a){var c=a.callback,d=a.topic,e=a.exchange||b;return(new h(e,d)).subscribe(c)},publish:function(){var a=arguments.length;l[a]&&l[a].apply(this,arguments)},addWireTap:function(a){return this.configuration.bus.addWireTap(a)},bindExchanges:function(c,d){var e;return a.isArray(c)||(c=[c]),a.isArray(d)||(d=[d]),e=new Array(c.length*d.length),a.each(c,function(c){var f=c.topic||"*";a.each(d,function(d){var f=d.exchange||b;e.push(m.subscribe({exchange:c.exchange||b,topic:c.topic||"*",callback:function(b,c){var e=c;e.topic=a.isFunction(d.topic)?d.topic(c.topic):d.topic||c.topic,e.exchange=f,m.publish(e,b)}}))})}),e}};return m})

View file

@ -10,39 +10,7 @@ var DEFAULT_EXCHANGE = "/",
DEFAULT_PRIORITY = 50,
DEFAULT_DISPOSEAFTER = 0,
SYSTEM_EXCHANGE = "postal",
NO_OP = function() { },
parsePublishArgs = function(args) {
var parsed = { envelope: { } }, env;
switch(args.length) {
case 3:
if(typeof args[1] === "Object" && typeof args[2] === "Object") {
parsed.envelope.exchange = DEFAULT_EXCHANGE;
parsed.envelope.topic = args[0];
parsed.payload = args[1];
env = parsed.envelope;
parsed.envelope = _.extend(env, args[2]);
}
else {
parsed.envelope.exchange = args[0];
parsed.envelope.topic = args[1];
parsed.payload = args[2];
}
break;
case 4:
parsed.envelope.exchange = args[0];
parsed.envelope.topic = args[1];
parsed.payload = args[2];
env = parsed.envelope;
parsed.envelope = _.extend(env, args[3]);
break;
default:
parsed.envelope.exchange = DEFAULT_EXCHANGE;
parsed.envelope.topic = args[0];
parsed.payload = args[1];
break;
}
return parsed;
};
NO_OP = function() { };
var DistinctPredicate = function() {
var previous;
@ -73,12 +41,11 @@ ChannelDefinition.prototype = {
},
publish: function(data, envelope) {
var env = _.extend({
exchange: this.exchange,
timeStamp: new Date(),
topic: this.topic
}, envelope);
postal.configuration.bus.publish(data, env);
var env = envelope || {};
env.exchange = this.exchange;
env.timeStamp = new Date();
env.topic = this.topic;
postal.configuration.bus.publish(env, data);
}
};
@ -87,12 +54,15 @@ var SubscriptionDefinition = function(exchange, topic, callback) {
this.topic = topic;
this.callback = callback;
this.priority = DEFAULT_PRIORITY;
this.constraints = [];
this.constraints = new Array(0);
this.maxCalls = DEFAULT_DISPOSEAFTER;
this.onHandled = NO_OP;
this.context = null;
postal.publish(SYSTEM_EXCHANGE, "subscription.created",
postal.publish({
exchange: SYSTEM_EXCHANGE,
topic: "subscription.created"
},
{
event: "subscription.created",
exchange: exchange,
@ -103,7 +73,10 @@ var SubscriptionDefinition = function(exchange, topic, callback) {
SubscriptionDefinition.prototype = {
unsubscribe: function() {
postal.configuration.bus.unsubscribe(this);
postal.publish(SYSTEM_EXCHANGE, "subscription.removed",
postal.publish({
exchange: SYSTEM_EXCHANGE,
topic: "subscription.removed"
},
{
event: "subscription.removed",
exchange: this.exchange,
@ -215,7 +188,10 @@ var bindingsResolver = {
if(this.cache[topic] && this.cache[topic][binding]) {
return true;
}
var rgx = new RegExp("^" + this.regexify(binding) + "$"), // match from start to end of string
// binding.replace(/\./g,"\\.") // escape actual periods
// .replace(/\*/g, ".*") // asterisks match any value
// .replace(/#/g, "[A-Z,a-z,0-9]*"); // hash matches any alpha-numeric 'word'
var rgx = new RegExp("^" + binding.replace(/\./g,"\\.").replace(/\*/g, ".*").replace(/#/g, "[A-Z,a-z,0-9]*") + "$"),
result = rgx.test(topic);
if(result) {
if(!this.cache[topic]) {
@ -224,12 +200,6 @@ var bindingsResolver = {
this.cache[topic][binding] = true;
}
return result;
},
regexify: function(binding) {
return binding.replace(/\./g,"\\.") // escape actual periods
.replace(/\*/g, ".*") // asterisks match any value
.replace(/#/g, "[A-Z,a-z,0-9]*"); // hash matches any alpha-numeric 'word'
}
};
@ -237,10 +207,12 @@ var localBus = {
subscriptions: {},
wireTaps: [],
wireTaps: new Array(0),
publish: function(data, envelope) {
this.notifyTaps(data, envelope);
publish: function(envelope, data) {
_.each(this.wireTaps,function(tap) {
tap(envelope, data);
});
_.each(this.subscriptions[envelope.exchange], function(topic) {
_.each(topic, function(binding){
@ -257,10 +229,15 @@ var localBus = {
},
subscribe: function(subDef) {
var idx, found, fn, exch, subs;
var idx, found, fn, exch = this.subscriptions[subDef.exchange], subs;
exch = this.subscriptions[subDef.exchange] = this.subscriptions[subDef.exchange] || {};
subs = this.subscriptions[subDef.exchange][subDef.topic] = this.subscriptions[subDef.exchange][subDef.topic] || [];
if(!exch) {
exch = this.subscriptions[subDef.exchange] = {};
}
subs = this.subscriptions[subDef.exchange][subDef.topic]
if(!subs) {
subs = this.subscriptions[subDef.exchange][subDef.topic] = new Array(0);
}
idx = subs.length - 1;
//if(!_.any(subs, function(cfg) { return cfg === subDef; })) {
@ -277,12 +254,6 @@ var localBus = {
//}
},
notifyTaps: function(data, envelope) {
_.each(this.wireTaps,function(tap) {
tap(data, envelope);
});
},
unsubscribe: function(config) {
if(this.subscriptions[config.exchange][config.topic]) {
var len = this.subscriptions[config.exchange][config.topic].length,
@ -308,30 +279,42 @@ var localBus = {
}
};
var publishPicker = {
"2" : function(envelope, payload) {
if(!envelope.exchange) {
envelope.exchange = DEFAULT_EXCHANGE;
}
postal.configuration.bus.publish(envelope, payload);
},
"3" : function(exchange, topic, payload) {
postal.configuration.bus.publish({ exchange: exchange, topic: topic }, payload);
}
};
var postal = {
configuration: {
bus: localBus,
resolver: bindingsResolver
},
channel: function(exchange, topic) {
var exch = topic ? exchange : DEFAULT_EXCHANGE,
tpc = topic || exchange;
channel: function(options) {
var exch = options.exchange || DEFAULT_EXCHANGE,
tpc = options.topic;
return new ChannelDefinition(exch, tpc);
},
subscribe: function(exchange, topic, callback) {
var callbk = callback || topic,
tpc = callback ? topic : exchange,
exch = callback ? exchange : DEFAULT_EXCHANGE;
var channel = this.channel(exch, tpc);
return channel.subscribe(callbk);
subscribe: function(options) {
var callback = options.callback,
topic = options.topic,
exchange = options.exchange || DEFAULT_EXCHANGE;
return new ChannelDefinition(exchange, topic).subscribe(callback);
},
publish: function(exchange, topic, payload, envelopeOptions) {
var parsedArgs = parsePublishArgs([].slice.call(arguments,0));
var channel = this.channel(parsedArgs.envelope.exchange, parsedArgs.envelope.topic);
channel.publish(parsedArgs.payload, parsedArgs.envelope);
publish: function() {
var len = arguments.length;
if(publishPicker[len]) {
publishPicker[len].apply(this, arguments);
}
},
addWireTap: function(callback) {
@ -339,21 +322,28 @@ var postal = {
},
bindExchanges: function(sources, destinations) {
var subscriptions = [];
var subscriptions;
if(!_.isArray(sources)) {
sources = [sources];
}
if(!_.isArray(destinations)) {
destinations = [destinations];
}
subscriptions = new Array(sources.length * destinations.length);
_.each(sources, function(source){
var sourceTopic = source.topic || "*";
_.each(destinations, function(destination) {
var destExchange = destination.exchange || DEFAULT_EXCHANGE;
subscriptions.push(
postal.subscribe(source.exchange || DEFAULT_EXCHANGE, source.topic || "*", function(msg, env) {
var destTopic = _.isFunction(destination.topic) ? destination.topic(env.topic) : destination.topic || env.topic;
postal.publish(destExchange, destTopic, msg);
postal.subscribe({
exchange: source.exchange || DEFAULT_EXCHANGE,
topic: source.topic || "*",
callback : function(msg, env) {
var newEnv = env;
newEnv.topic = _.isFunction(destination.topic) ? destination.topic(env.topic) : destination.topic || env.topic;
newEnv.exchange = destExchange;
postal.publish(newEnv, msg);
}
})
);
});

View file

@ -1 +1 @@
(function(a,b){var c="/",d=50,e=0,f="postal",g=function(){},h=function(a){var b={envelope:{}},d;switch(a.length){case 3:typeof a[1]=="Object"&&typeof a[2]=="Object"?(b.envelope.exchange=c,b.envelope.topic=a[0],b.payload=a[1],d=b.envelope,b.envelope=_.extend(d,a[2])):(b.envelope.exchange=a[0],b.envelope.topic=a[1],b.payload=a[2]);break;case 4:b.envelope.exchange=a[0],b.envelope.topic=a[1],b.payload=a[2],d=b.envelope,b.envelope=_.extend(d,a[3]);break;default:b.envelope.exchange=c,b.envelope.topic=a[0],b.payload=a[1]}return b},i=function(){var a;return function(b){var c=!1;return _.isString(b)?(c=b===a,a=b):(c=_.isEqual(b,a),a=_.clone(b)),!c}},j=function(a,b){this.exchange=a,this.topic=b};j.prototype={subscribe:function(a){var b=new k(this.exchange,this.topic,a);return n.configuration.bus.subscribe(b),b},publish:function(a,b){var c=_.extend({exchange:this.exchange,timeStamp:new Date,topic:this.topic},b);n.configuration.bus.publish(a,c)}};var k=function(a,b,c){this.exchange=a,this.topic=b,this.callback=c,this.priority=d,this.constraints=[],this.maxCalls=e,this.onHandled=g,this.context=null,n.publish(f,"subscription.created",{event:"subscription.created",exchange:a,topic:b})};k.prototype={unsubscribe:function(){n.configuration.bus.unsubscribe(this),n.publish(f,"subscription.removed",{event:"subscription.removed",exchange:this.exchange,topic:this.topic})},defer:function(){var a=this.callback;return this.callback=function(b){setTimeout(a,0,b)},this},disposeAfter:function(a){if(_.isNaN(a)||a<=0)throw"The value provided to disposeAfter (maxCalls) must be a number greater than zero.";var b=this.onHandled,c=_.after(a,_.bind(function(){this.unsubscribe(this)},this));return this.onHandled=function(){b.apply(this.context,arguments),c()},this},ignoreDuplicates:function(){return this.withConstraint(new i),this},whenHandledThenExecute:function(a){if(!_.isFunction(a))throw"Value provided to 'whenHandledThenExecute' must be a function";return this.onHandled=a,this},withConstraint:function(a){if(!_.isFunction(a))throw"Predicate constraint must be a function";return this.constraints.push(a),this},withConstraints:function(a){var b=this;return _.isArray(a)&&_.each(a,function(a){b.withConstraint(a)}),b},withContext:function(a){return this.context=a,this},withDebounce:function(a){if(_.isNaN(a))throw"Milliseconds must be a number";var b=this.callback;return this.callback=_.debounce(b,a),this},withDelay:function(a){if(_.isNaN(a))throw"Milliseconds must be a number";var b=this.callback;return this.callback=function(c){setTimeout(b,a,c)},this},withPriority:function(a){if(_.isNaN(a))throw"Priority must be a number";return this.priority=a,this},withThrottle:function(a){if(_.isNaN(a))throw"Milliseconds must be a number";var b=this.callback;return this.callback=_.throttle(b,a),this}};var l={cache:{},compare:function(a,b){if(this.cache[b]&&this.cache[b][a])return!0;var c=new RegExp("^"+this.regexify(a)+"$"),d=c.test(b);return d&&(this.cache[b]||(this.cache[b]={}),this.cache[b][a]=!0),d},regexify:function(a){return a.replace(/\./g,"\\.").replace(/\*/g,".*").replace(/#/g,"[A-Z,a-z,0-9]*")}},m={subscriptions:{},wireTaps:[],publish:function(a,b){this.notifyTaps(a,b),_.each(this.subscriptions[b.exchange],function(c){_.each(c,function(c){n.configuration.resolver.compare(c.topic,b.topic)&&_.all(c.constraints,function(b){return b(a)})&&typeof c.callback=="function"&&(c.callback.apply(c.context,[a,b]),c.onHandled())})})},subscribe:function(a){var b,c,d,e,f;e=this.subscriptions[a.exchange]=this.subscriptions[a.exchange]||{},f=this.subscriptions[a.exchange][a.topic]=this.subscriptions[a.exchange][a.topic]||[],b=f.length-1;for(;b>=0;b--)if(f[b].priority<=a.priority){f.splice(b+1,0,a),c=!0;break}c||f.unshift(a)},notifyTaps:function(a,b){_.each(this.wireTaps,function(c){c(a,b)})},unsubscribe:function(a){if(this.subscriptions[a.exchange][a.topic]){var b=this.subscriptions[a.exchange][a.topic].length,c=0;for(;c<b;c++)if(this.subscriptions[a.exchange][a.topic][c]===a){this.subscriptions[a.exchange][a.topic].splice(c,1);break}}},addWireTap:function(a){var b=this;return b.wireTaps.push(a),function(){var c=b.wireTaps.indexOf(a);c!==-1&&b.wireTaps.splice(c,1)}}},n={configuration:{bus:m,resolver:l},channel:function(a,b){var d=b?a:c,e=b||a;return new j(d,e)},subscribe:function(a,b,d){var e=d||b,f=d?b:a,g=d?a:c,h=this.channel(g,f);return h.subscribe(e)},publish:function(a,b,c,d){var e=h([].slice.call(arguments,0)),f=this.channel(e.envelope.exchange,e.envelope.topic);f.publish(e.payload,e.envelope)},addWireTap:function(a){return this.configuration.bus.addWireTap(a)},bindExchanges:function(a,b){var d=[];return _.isArray(a)||(a=[a]),_.isArray(b)||(b=[b]),_.each(a,function(a){var e=a.topic||"*";_.each(b,function(b){var e=b.exchange||c;d.push(n.subscribe(a.exchange||c,a.topic||"*",function(a,c){var d=_.isFunction(b.topic)?b.topic(c.topic):b.topic||c.topic;n.publish(e,d,a)}))})}),d}};a.postal=n})(window)
(function(a,b){var c="/",d=50,e=0,f="postal",g=function(){},h=function(){var a;return function(b){var c=!1;return _.isString(b)?(c=b===a,a=b):(c=_.isEqual(b,a),a=_.clone(b)),!c}},i=function(a,b){this.exchange=a,this.topic=b};i.prototype={subscribe:function(a){var b=new j(this.exchange,this.topic,a);return n.configuration.bus.subscribe(b),b},publish:function(a,b){var c=b||{};c.exchange=this.exchange,c.timeStamp=new Date,c.topic=this.topic,n.configuration.bus.publish(c,a)}};var j=function(a,b,c){this.exchange=a,this.topic=b,this.callback=c,this.priority=d,this.constraints=new Array(0),this.maxCalls=e,this.onHandled=g,this.context=null,n.publish({exchange:f,topic:"subscription.created"},{event:"subscription.created",exchange:a,topic:b})};j.prototype={unsubscribe:function(){n.configuration.bus.unsubscribe(this),n.publish({exchange:f,topic:"subscription.removed"},{event:"subscription.removed",exchange:this.exchange,topic:this.topic})},defer:function(){var a=this.callback;return this.callback=function(b){setTimeout(a,0,b)},this},disposeAfter:function(a){if(_.isNaN(a)||a<=0)throw"The value provided to disposeAfter (maxCalls) must be a number greater than zero.";var b=this.onHandled,c=_.after(a,_.bind(function(){this.unsubscribe(this)},this));return this.onHandled=function(){b.apply(this.context,arguments),c()},this},ignoreDuplicates:function(){return this.withConstraint(new h),this},whenHandledThenExecute:function(a){if(!_.isFunction(a))throw"Value provided to 'whenHandledThenExecute' must be a function";return this.onHandled=a,this},withConstraint:function(a){if(!_.isFunction(a))throw"Predicate constraint must be a function";return this.constraints.push(a),this},withConstraints:function(a){var b=this;return _.isArray(a)&&_.each(a,function(a){b.withConstraint(a)}),b},withContext:function(a){return this.context=a,this},withDebounce:function(a){if(_.isNaN(a))throw"Milliseconds must be a number";var b=this.callback;return this.callback=_.debounce(b,a),this},withDelay:function(a){if(_.isNaN(a))throw"Milliseconds must be a number";var b=this.callback;return this.callback=function(c){setTimeout(b,a,c)},this},withPriority:function(a){if(_.isNaN(a))throw"Priority must be a number";return this.priority=a,this},withThrottle:function(a){if(_.isNaN(a))throw"Milliseconds must be a number";var b=this.callback;return this.callback=_.throttle(b,a),this}};var k={cache:{},compare:function(a,b){if(this.cache[b]&&this.cache[b][a])return!0;var c=new RegExp("^"+a.replace(/\./g,"\\.").replace(/\*/g,".*").replace(/#/g,"[A-Z,a-z,0-9]*")+"$"),d=c.test(b);return d&&(this.cache[b]||(this.cache[b]={}),this.cache[b][a]=!0),d}},l={subscriptions:{},wireTaps:new Array(0),publish:function(a,b){_.each(this.wireTaps,function(c){c(a,b)}),_.each(this.subscriptions[a.exchange],function(c){_.each(c,function(c){n.configuration.resolver.compare(c.topic,a.topic)&&_.all(c.constraints,function(a){return a(b)})&&typeof c.callback=="function"&&(c.callback.apply(c.context,[b,a]),c.onHandled())})})},subscribe:function(a){var b,c,d,e=this.subscriptions[a.exchange],f;e||(e=this.subscriptions[a.exchange]={}),f=this.subscriptions[a.exchange][a.topic],f||(f=this.subscriptions[a.exchange][a.topic]=new Array(0)),b=f.length-1;for(;b>=0;b--)if(f[b].priority<=a.priority){f.splice(b+1,0,a),c=!0;break}c||f.unshift(a)},unsubscribe:function(a){if(this.subscriptions[a.exchange][a.topic]){var b=this.subscriptions[a.exchange][a.topic].length,c=0;for(;c<b;c++)if(this.subscriptions[a.exchange][a.topic][c]===a){this.subscriptions[a.exchange][a.topic].splice(c,1);break}}},addWireTap:function(a){var b=this;return b.wireTaps.push(a),function(){var c=b.wireTaps.indexOf(a);c!==-1&&b.wireTaps.splice(c,1)}}},m={2:function(a,b){a.exchange||(a.exchange=c),n.configuration.bus.publish(a,b)},3:function(a,b,c){n.configuration.bus.publish({exchange:a,topic:b},c)}},n={configuration:{bus:l,resolver:k},channel:function(a){var b=a.exchange||c,d=a.topic;return new i(b,d)},subscribe:function(a){var b=a.callback,d=a.topic,e=a.exchange||c;return(new i(e,d)).subscribe(b)},publish:function(){var a=arguments.length;m[a]&&m[a].apply(this,arguments)},addWireTap:function(a){return this.configuration.bus.addWireTap(a)},bindExchanges:function(a,b){var d;return _.isArray(a)||(a=[a]),_.isArray(b)||(b=[b]),d=new Array(a.length*b.length),_.each(a,function(a){var e=a.topic||"*";_.each(b,function(b){var e=b.exchange||c;d.push(n.subscribe({exchange:a.exchange||c,topic:a.topic||"*",callback:function(a,c){var d=c;d.topic=_.isFunction(b.topic)?b.topic(c.topic):b.topic||c.topic,d.exchange=e,n.publish(d,a)}}))})}),d}};a.postal=n})(window)

View file

@ -10,39 +10,7 @@ var DEFAULT_EXCHANGE = "/",
DEFAULT_PRIORITY = 50,
DEFAULT_DISPOSEAFTER = 0,
SYSTEM_EXCHANGE = "postal",
NO_OP = function() { },
parsePublishArgs = function(args) {
var parsed = { envelope: { } }, env;
switch(args.length) {
case 3:
if(typeof args[1] === "Object" && typeof args[2] === "Object") {
parsed.envelope.exchange = DEFAULT_EXCHANGE;
parsed.envelope.topic = args[0];
parsed.payload = args[1];
env = parsed.envelope;
parsed.envelope = _.extend(env, args[2]);
}
else {
parsed.envelope.exchange = args[0];
parsed.envelope.topic = args[1];
parsed.payload = args[2];
}
break;
case 4:
parsed.envelope.exchange = args[0];
parsed.envelope.topic = args[1];
parsed.payload = args[2];
env = parsed.envelope;
parsed.envelope = _.extend(env, args[3]);
break;
default:
parsed.envelope.exchange = DEFAULT_EXCHANGE;
parsed.envelope.topic = args[0];
parsed.payload = args[1];
break;
}
return parsed;
};
NO_OP = function() { };
var DistinctPredicate = function() {
var previous;
@ -73,12 +41,11 @@ ChannelDefinition.prototype = {
},
publish: function(data, envelope) {
var env = _.extend({
exchange: this.exchange,
timeStamp: new Date(),
topic: this.topic
}, envelope);
postal.configuration.bus.publish(data, env);
var env = envelope || {};
env.exchange = this.exchange;
env.timeStamp = new Date();
env.topic = this.topic;
postal.configuration.bus.publish(env, data);
}
};
@ -87,12 +54,15 @@ var SubscriptionDefinition = function(exchange, topic, callback) {
this.topic = topic;
this.callback = callback;
this.priority = DEFAULT_PRIORITY;
this.constraints = [];
this.constraints = new Array(0);
this.maxCalls = DEFAULT_DISPOSEAFTER;
this.onHandled = NO_OP;
this.context = null;
postal.publish(SYSTEM_EXCHANGE, "subscription.created",
postal.publish({
exchange: SYSTEM_EXCHANGE,
topic: "subscription.created"
},
{
event: "subscription.created",
exchange: exchange,
@ -103,7 +73,10 @@ var SubscriptionDefinition = function(exchange, topic, callback) {
SubscriptionDefinition.prototype = {
unsubscribe: function() {
postal.configuration.bus.unsubscribe(this);
postal.publish(SYSTEM_EXCHANGE, "subscription.removed",
postal.publish({
exchange: SYSTEM_EXCHANGE,
topic: "subscription.removed"
},
{
event: "subscription.removed",
exchange: this.exchange,
@ -215,7 +188,10 @@ var bindingsResolver = {
if(this.cache[topic] && this.cache[topic][binding]) {
return true;
}
var rgx = new RegExp("^" + this.regexify(binding) + "$"), // match from start to end of string
// binding.replace(/\./g,"\\.") // escape actual periods
// .replace(/\*/g, ".*") // asterisks match any value
// .replace(/#/g, "[A-Z,a-z,0-9]*"); // hash matches any alpha-numeric 'word'
var rgx = new RegExp("^" + binding.replace(/\./g,"\\.").replace(/\*/g, ".*").replace(/#/g, "[A-Z,a-z,0-9]*") + "$"),
result = rgx.test(topic);
if(result) {
if(!this.cache[topic]) {
@ -224,12 +200,6 @@ var bindingsResolver = {
this.cache[topic][binding] = true;
}
return result;
},
regexify: function(binding) {
return binding.replace(/\./g,"\\.") // escape actual periods
.replace(/\*/g, ".*") // asterisks match any value
.replace(/#/g, "[A-Z,a-z,0-9]*"); // hash matches any alpha-numeric 'word'
}
};
@ -237,10 +207,12 @@ var localBus = {
subscriptions: {},
wireTaps: [],
wireTaps: new Array(0),
publish: function(data, envelope) {
this.notifyTaps(data, envelope);
publish: function(envelope, data) {
_.each(this.wireTaps,function(tap) {
tap(envelope, data);
});
_.each(this.subscriptions[envelope.exchange], function(topic) {
_.each(topic, function(binding){
@ -257,10 +229,15 @@ var localBus = {
},
subscribe: function(subDef) {
var idx, found, fn, exch, subs;
var idx, found, fn, exch = this.subscriptions[subDef.exchange], subs;
exch = this.subscriptions[subDef.exchange] = this.subscriptions[subDef.exchange] || {};
subs = this.subscriptions[subDef.exchange][subDef.topic] = this.subscriptions[subDef.exchange][subDef.topic] || [];
if(!exch) {
exch = this.subscriptions[subDef.exchange] = {};
}
subs = this.subscriptions[subDef.exchange][subDef.topic]
if(!subs) {
subs = this.subscriptions[subDef.exchange][subDef.topic] = new Array(0);
}
idx = subs.length - 1;
//if(!_.any(subs, function(cfg) { return cfg === subDef; })) {
@ -277,12 +254,6 @@ var localBus = {
//}
},
notifyTaps: function(data, envelope) {
_.each(this.wireTaps,function(tap) {
tap(data, envelope);
});
},
unsubscribe: function(config) {
if(this.subscriptions[config.exchange][config.topic]) {
var len = this.subscriptions[config.exchange][config.topic].length,
@ -308,30 +279,42 @@ var localBus = {
}
};
var publishPicker = {
"2" : function(envelope, payload) {
if(!envelope.exchange) {
envelope.exchange = DEFAULT_EXCHANGE;
}
postal.configuration.bus.publish(envelope, payload);
},
"3" : function(exchange, topic, payload) {
postal.configuration.bus.publish({ exchange: exchange, topic: topic }, payload);
}
};
var postal = {
configuration: {
bus: localBus,
resolver: bindingsResolver
},
channel: function(exchange, topic) {
var exch = topic ? exchange : DEFAULT_EXCHANGE,
tpc = topic || exchange;
channel: function(options) {
var exch = options.exchange || DEFAULT_EXCHANGE,
tpc = options.topic;
return new ChannelDefinition(exch, tpc);
},
subscribe: function(exchange, topic, callback) {
var callbk = callback || topic,
tpc = callback ? topic : exchange,
exch = callback ? exchange : DEFAULT_EXCHANGE;
var channel = this.channel(exch, tpc);
return channel.subscribe(callbk);
subscribe: function(options) {
var callback = options.callback,
topic = options.topic,
exchange = options.exchange || DEFAULT_EXCHANGE;
return new ChannelDefinition(exchange, topic).subscribe(callback);
},
publish: function(exchange, topic, payload, envelopeOptions) {
var parsedArgs = parsePublishArgs([].slice.call(arguments,0));
var channel = this.channel(parsedArgs.envelope.exchange, parsedArgs.envelope.topic);
channel.publish(parsedArgs.payload, parsedArgs.envelope);
publish: function() {
var len = arguments.length;
if(publishPicker[len]) {
publishPicker[len].apply(this, arguments);
}
},
addWireTap: function(callback) {
@ -339,21 +322,28 @@ var postal = {
},
bindExchanges: function(sources, destinations) {
var subscriptions = [];
var subscriptions;
if(!_.isArray(sources)) {
sources = [sources];
}
if(!_.isArray(destinations)) {
destinations = [destinations];
}
subscriptions = new Array(sources.length * destinations.length);
_.each(sources, function(source){
var sourceTopic = source.topic || "*";
_.each(destinations, function(destination) {
var destExchange = destination.exchange || DEFAULT_EXCHANGE;
subscriptions.push(
postal.subscribe(source.exchange || DEFAULT_EXCHANGE, source.topic || "*", function(msg, env) {
var destTopic = _.isFunction(destination.topic) ? destination.topic(env.topic) : destination.topic || env.topic;
postal.publish(destExchange, destTopic, msg);
postal.subscribe({
exchange: source.exchange || DEFAULT_EXCHANGE,
topic: source.topic || "*",
callback : function(msg, env) {
var newEnv = env;
newEnv.topic = _.isFunction(destination.topic) ? destination.topic(env.topic) : destination.topic || env.topic;
newEnv.exchange = destExchange;
postal.publish(newEnv, msg);
}
})
);
});