diff --git a/README.md b/README.md
index b5005c8..7ee9f12 100644
--- a/README.md
+++ b/README.md
@@ -22,13 +22,16 @@ JavaScript:
```javascript
// The world's simplest subscription
-var channel = postal.channel("Name.Changed");
+// doesn't specify a channel name, so it defaults to "/" (DEFAULT_CHANNEL)
+var channel = postal.channel( { topic: "Name.Changed" } );
// subscribe
-var subscription = channel.subscribe(function(data) { $("#example1").html("Name: " + data.name); });
+var subscription = channel.subscribe( function( data, envelope ) {
+ $( "#example1" ).html( "Name: " + data.name );
+});
// And someone publishes a first name change:
-channel.publish({ name: "Dr. Who" });
+channel.publish( { name: "Dr. Who" } );
subscription.unsubscribe();
```
@@ -37,14 +40,14 @@ subscription.unsubscribe();
The `#` symbol represents "one word" in a topic (i.e - the text between two periods of a topic). By subscribing to `"#.Changed"`, the binding will match `Name.Changed` & `Location.Changed` but *not* for `Changed.Companion`
```javascript
-var hashChannel = postal.channel("#.Changed"),
- chgSubscription = hashChannel.subscribe(function(data) {
- $('
' + data.type + " Changed: " + data.value + '').appendTo("#example2");
+var hashChannel = postal.channel( { topic: "#.Changed" } ),
+ chgSubscription = hashChannel.subscribe( function( data ) {
+ $( '' + data.type + " Changed: " + data.value + '' ).appendTo( "#example2" );
});
-postal.channel("Name.Changed")
- .publish({ type: "Name", value:"John Smith" });
-postal.channel("Location.Changed")
- .publish({ type: "Location", value: "Early 20th Century England" });
+postal.channel( { topic: "Name.Changed" } )
+ .publish( { type: "Name", value:"John Smith" } );
+postal.channel( "Location.Changed" )
+ .publish( { type: "Location", value: "Early 20th Century England" } );
chgSubscription.unsubscribe();
```
@@ -53,40 +56,38 @@ chgSubscription.unsubscribe();
The `*` symbol represents any number of characters/words in a topic string. By subscribing to ``"DrWho.*.Changed"``, the binding will match `DrWho.NinthDoctor.Companion.Changed` & `DrWho.Location.Changed` but *not* `Changed`
```javascript
-var starChannel = postal.channel("DrWho.*.Changed"),
- starSubscription = starChannel.subscribe(function(data) {
- $('' + data.type + " Changed: " + data.value + '').appendTo("#example3");
+var starChannel = postal.channel( { channel: "Doctor.Who", topic: "DrWho.*.Changed" } ),
+ starSubscription = starChannel.subscribe( function( data ) {
+ $( '' + data.type + " Changed: " + data.value + '' ).appendTo( "#example3" );
});
-postal.channel("DrWho.NinthDoctor.Companion.Changed")
- .publish({ type: "Name", value:"Rose" });
-postal.channel("DrWho.TenthDoctor.Companion.Changed")
- .publish({ type: "Name", value:"Martha" });
-postal.channel("DrWho.Eleventh.Companion.Changed")
- .publish({ type: "Name", value:"Amy" });
-postal.channel("DrWho.Location.Changed")
- .publish({ type: "Location", value: "The Library" });
-postal.channel("TheMaster.DrumBeat.Changed")
- .publish({ type: "DrumBeat", value: "This won't trigger any subscriptions" });
-postal.channel("Changed")
- .publish({ type: "Useless", value: "This won't trigger any subscriptions either" });
+// demonstrating how we're re-using the channel delcared above to publish, but overriding the topic in the second argument
+starChannel.publish( { type: "Name", value:"Rose" }, { topic: "DrWho.NinthDoctor.Companion.Changed" } );
+starChannel.publish( { type: "Name", value:"Martha" }, { topic: "DrWho.TenthDoctor.Companion.Changed" } );
+starChannel.publish( { type: "Name", value:"Amy" }, { topic: "DrWho.Eleventh.Companion.Changed" } );
+starChannel.publish( { type: "Location", value: "The Library" }, { topic: "DrWho.Location.Changed" } );
+starChannel.publish( { type: "DrumBeat", value: "This won't trigger any subscriptions" }, { topic: "TheMaster.DrumBeat.Changed" } );
+starChannel.publish( { type: "Useless", value: "This won't trigger any subscriptions either" }, { topic: "Changed" } );
+
starSubscription.unsubscribe();
```
### Applying ignoreDuplicates to a subscription
```javascript
-var dupChannel = postal.channel("WeepingAngel.*"),
- dupSubscription = dupChannel.subscribe(function(data) {
- $('' + data.value + '').appendTo("#example4");
+var dupChannel = postal.channel( { topic: "WeepingAngel.*" } ),
+ dupSubscription = dupChannel.subscribe( function( data ) {
+ $( '' + data.value + '' ).appendTo( "#example4" );
}).ignoreDuplicates();
-postal.channel("WeepingAngel.DontBlink")
- .publish({ value:"Don't Blink" });
-postal.channel("WeepingAngel.DontBlink")
- .publish({ value:"Don't Blink" });
-postal.channel("WeepingAngel.DontEvenBlink")
- .publish({ value:"Don't Even Blink" });
-postal.channel("WeepingAngel.DontBlink")
- .publish({ value:"Don't Close Your Eyes" });
+// demonstrating multiple channels per topic being used
+// You can do it this way if you like, but the example above has nicer syntax (and less overhead)
+postal.channel( { topic: "WeepingAngel.DontBlink" } )
+ .publish( { value:"Don't Blink" } );
+postal.channel( { topic: "WeepingAngel.DontBlink" } )
+ .publish( { value:"Don't Blink" } );
+postal.channel( { topic: "WeepingAngel.DontEvenBlink" } )
+ .publish( { value:"Don't Even Blink" } );
+postal.channel( { topic: "WeepingAngel.DontBlink" } )
+ .publish( { value:"Don't Close Your Eyes" } );
dupSubscription.unsubscribe();
```
@@ -104,7 +105,5 @@ Please - by all means! While I hope the API is relatively stable, I'm open to p
## Roadmap for the Future
Here's where Postal is headed:
-* The original proof-of-concept version of postal supported the ability to capture messages and replay them. This functionality will be added soon.
-* The ability to 'join' two (or more) subscriptions, so that the original subscription will only fire once the second "joined" subscription has also fired. Think of it as a message-based version of a compound promise.
* I haven't yet thoroughly tested Postal on Node.js - that is high on my list as well.
* What else would you like to see?
\ No newline at end of file
diff --git a/build-all.sh b/build-all.sh
index 98f53cb..fb02833 100755
--- a/build-all.sh
+++ b/build-all.sh
@@ -2,12 +2,14 @@
anvil -b build-browser-standard.json
anvil -b build-browser-standard-diags.json
-anvil -b build-browser-amd.json
-anvil -b build-browser-amd-diags.json
-anvil -b build-node.json
-anvil -b build-node-diags.json
-cp ./lib/browser/amd/postal.js ./example/amd/js/libs/postal/
-cp ./lib/browser/amd/postal.diagnostics.js ./example/amd/js/libs/postal/
+cp ./lib/browser/standard/postal.js ./example/amd/js/libs/postal/
+cp ./lib/browser/standard/postal.diagnostics.js ./example/amd/js/libs/postal/
cp ./lib/browser/standard/postal.js ./example/standard/js/
-cp ./lib/browser/standard/postal.diagnostics.js ./example/standard/js/
\ No newline at end of file
+cp ./lib/browser/standard/postal.diagnostics.js ./example/standard/js/
+
+mv ./lib/browser/standard/postal.node.js ./lib/node/postal.js
+rm ./lib/browser/standard/postal.node*
+
+mv ./lib/browser/standard/postal.diagnostics.node.js ./lib/node/postal.diagnostics.js
+rm ./lib/browser/standard/postal.diagnostics.node*
\ No newline at end of file
diff --git a/build-browser-amd-diags.json b/build-browser-amd-diags.json
deleted file mode 100644
index 42430de..0000000
--- a/build-browser-amd-diags.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "source": "src/diags",
- "output": "lib/browser/amd",
- "lint": {},
- "uglify": {},
- "gzip": {},
- "extensions": { "uglify": "min", "gzip": "gz" },
- "wrap": {
- "prefix": "define(['postal', 'underscore'], function(postal, _) {",
- "suffix": "});"
- }
-}
\ No newline at end of file
diff --git a/build-browser-amd.json b/build-browser-amd.json
deleted file mode 100644
index 6817679..0000000
--- a/build-browser-amd.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "source": "src/main",
- "output": "lib/browser/amd",
- "lint": {},
- "uglify": {},
- "gzip": {},
- "extensions": { "uglify": "min", "gzip": "gz" },
- "wrap": {
- "prefix": "define(['underscore'], function(_) {",
- "suffix": "return postal; });"
- }
-}
\ No newline at end of file
diff --git a/build-browser-standard.json b/build-browser-standard.json
index cb413ca..63711c5 100644
--- a/build-browser-standard.json
+++ b/build-browser-standard.json
@@ -4,9 +4,5 @@
"lint": {},
"uglify": {},
"gzip": {},
- "extensions": { "uglify": "min", "gzip": "gz" },
- "wrap": {
- "prefix": "(function(global, undefined) {",
- "suffix": "global.postal = postal; })(window);"
- }
+ "extensions": { "uglify": "min", "gzip": "gz" }
}
\ No newline at end of file
diff --git a/build-node-diags.json b/build-node-diags.json
index 5085ed7..20f1560 100644
--- a/build-node-diags.json
+++ b/build-node-diags.json
@@ -1,9 +1,5 @@
{
"source": "src/diags",
"output": "lib/node",
- "lint": {},
- "wrap": {
- "prefix": "module.exports = function(postal) {",
- "suffix": "};"
- }
+ "lint": {}
}
\ No newline at end of file
diff --git a/build-node.json b/build-node.json
index 7b4d7b4..c7f9289 100644
--- a/build-node.json
+++ b/build-node.json
@@ -1,9 +1,5 @@
{
"source": "src/main",
"output": "lib/node",
- "lint": {},
- "wrap": {
- "prefix": "var _ = require('underscore');",
- "suffix": "module.exports = postal;"
- }
+ "lint": {}
}
\ No newline at end of file
diff --git a/example/amd/js/libs/postal/postal.diagnostics.js b/example/amd/js/libs/postal/postal.diagnostics.js
index 9f9ee66..5defd32 100644
--- a/example/amd/js/libs/postal/postal.diagnostics.js
+++ b/example/amd/js/libs/postal/postal.diagnostics.js
@@ -1,20 +1,33 @@
-define(['postal', 'underscore'], function(postal, _) {
-postal.addWireTap(function(data, envelope) {
- var all = _.extend(envelope, { data: data });
- if(!JSON) {
- throw "This browser or environment does not provide JSON support";
- }
- try {
- console.log(JSON.stringify(all));
- }
- catch(exception) {
- try {
- all.data = "ERROR: " + exception.message;
- console.log(JSON.stringify(all));
- }
- catch(ex) {
- console.log("Unable to parse data to JSON: " + exception);
- }
- }
-});
-});
\ No newline at end of file
+(function(root, doc, factory) {
+ if (typeof define === "function" && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(["postal", "underscore"], function(postal, _) {
+ return factory(postal, _, root, doc);
+ });
+ } else {
+ // Browser globals
+ factory(root.postal, root._, root, doc);
+ }
+}(this, document, function(postal, _, global, document, undefined) {
+
+ // this returns a callback that, if invoked, removes the wireTap
+ return postal.addWireTap(function(data, envelope) {
+ var all = _.extend(envelope, { data: data });
+ if(!JSON) {
+ throw "This browser or environment does not provide JSON support";
+ }
+ try {
+ console.log(JSON.stringify(all));
+ }
+ catch(exception) {
+ try {
+ all.data = "ERROR: " + exception.message;
+ console.log(JSON.stringify(all));
+ }
+ catch(ex) {
+ console.log("Unable to parse data to JSON: " + exception);
+ }
+ }
+ });
+
+}));
\ No newline at end of file
diff --git a/example/amd/js/libs/postal/postal.js b/example/amd/js/libs/postal/postal.js
index f8037cc..7fe0a44 100644
--- a/example/amd/js/libs/postal/postal.js
+++ b/example/amd/js/libs/postal/postal.js
@@ -1,4 +1,3 @@
-define(['underscore'], function(_) {
/*
postal.js
Author: Jim Cowart
@@ -6,6 +5,18 @@ define(['underscore'], function(_) {
Version 0.4.0
*/
+(function(root, doc, factory) {
+ if (typeof define === "function" && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(["underscore"], function(_) {
+ return factory(_, root, doc);
+ });
+ } else {
+ // Browser globals
+ factory(root._, root, doc);
+ }
+}(this, document, function(_, global, document, undefined) {
+
var DEFAULT_CHANNEL = "/",
DEFAULT_PRIORITY = 50,
DEFAULT_DISPOSEAFTER = 0,
@@ -34,8 +45,14 @@ var ChannelDefinition = function(channelName, defaultTopic) {
};
ChannelDefinition.prototype = {
- subscribe: function(callback) {
- return new SubscriptionDefinition(this.channel, this.topic, callback);
+ subscribe: function() {
+ var len = arguments.length;
+ if(len === 1) {
+ return new SubscriptionDefinition(this.channel, this.topic, arguments[0]);
+ }
+ else if (len === 2) {
+ return new SubscriptionDefinition(this.channel, arguments[0], arguments[1]);
+ }
},
publish: function(data, envelope) {
@@ -43,142 +60,140 @@ ChannelDefinition.prototype = {
env.channel = this.channel;
env.timeStamp = new Date();
env.topic = env.topic || this.topic;
- postal.configuration.bus.publish(env, data);
+ postal.configuration.bus.publish(data, env);
}
};
var SubscriptionDefinition = function(channel, topic, callback) {
- this.channel = channel;
- this.topic = topic;
- this.callback = callback;
- this.priority = DEFAULT_PRIORITY;
- this.constraints = new Array(0);
- this.maxCalls = DEFAULT_DISPOSEAFTER;
- this.onHandled = NO_OP;
- this.context = null;
+ this.channel = channel;
+ this.topic = topic;
+ this.callback = callback;
+ this.priority = DEFAULT_PRIORITY;
+ this.constraints = new Array(0);
+ this.maxCalls = DEFAULT_DISPOSEAFTER;
+ this.onHandled = NO_OP;
+ this.context = null;
+ postal.publish({
+ event: "subscription.created",
+ channel: channel,
+ topic: topic
+ },{
+ channel: SYSTEM_CHANNEL,
+ topic: "subscription.created"
+ });
postal.configuration.bus.subscribe(this);
- postal.publish({
- channel: SYSTEM_CHANNEL,
- topic: "subscription.created"
- },
- {
- event: "subscription.created",
- channel: channel,
- topic: topic
- });
};
SubscriptionDefinition.prototype = {
- unsubscribe: function() {
- postal.configuration.bus.unsubscribe(this);
- postal.publish({
- channel: SYSTEM_CHANNEL,
- topic: "subscription.removed"
- },
- {
- event: "subscription.removed",
- channel: this.channel,
- topic: this.topic
- });
- },
+ unsubscribe: function() {
+ postal.configuration.bus.unsubscribe(this);
+ postal.publish({
+ event: "subscription.removed",
+ channel: this.channel,
+ topic: this.topic
+ },{
+ channel: SYSTEM_CHANNEL,
+ topic: "subscription.removed"
+ });
+ },
- defer: function() {
- var fn = this.callback;
- this.callback = function(data) {
- setTimeout(fn,0,data);
- };
- return this;
- },
+ defer: function() {
+ var fn = this.callback;
+ this.callback = function(data) {
+ setTimeout(fn,0,data);
+ };
+ return this;
+ },
- disposeAfter: function(maxCalls) {
- if(_.isNaN(maxCalls) || maxCalls <= 0) {
- throw "The value provided to disposeAfter (maxCalls) must be a number greater than zero.";
- }
+ disposeAfter: function(maxCalls) {
+ if(_.isNaN(maxCalls) || maxCalls <= 0) {
+ throw "The value provided to disposeAfter (maxCalls) must be a number greater than zero.";
+ }
- var fn = this.onHandled;
- var dispose = _.after(maxCalls, _.bind(function() {
- this.unsubscribe(this);
- }, this));
+ var fn = this.onHandled;
+ var dispose = _.after(maxCalls, _.bind(function() {
+ this.unsubscribe(this);
+ }, this));
- this.onHandled = function() {
- fn.apply(this.context, arguments);
- dispose();
- };
- return this;
- },
+ this.onHandled = function() {
+ fn.apply(this.context, arguments);
+ dispose();
+ };
+ return this;
+ },
- ignoreDuplicates: function() {
- this.withConstraint(new DistinctPredicate());
- return this;
- },
+ ignoreDuplicates: function() {
+ this.withConstraint(new DistinctPredicate());
+ return this;
+ },
- whenHandledThenExecute: function(callback) {
- if(! _.isFunction(callback)) {
- throw "Value provided to 'whenHandledThenExecute' must be a function";
- }
- this.onHandled = callback;
- return this;
- },
+ whenHandledThenExecute: function(callback) {
+ if(! _.isFunction(callback)) {
+ throw "Value provided to 'whenHandledThenExecute' must be a function";
+ }
+ this.onHandled = callback;
+ return this;
+ },
- withConstraint: function(predicate) {
- if(! _.isFunction(predicate)) {
- throw "Predicate constraint must be a function";
- }
- this.constraints.push(predicate);
- 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;
- },
+ 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;
- },
+ withContext: function(context) {
+ this.context = context;
+ return this;
+ },
- withDebounce: function(milliseconds) {
- if(_.isNaN(milliseconds)) {
- throw "Milliseconds must be a number";
- }
- var fn = this.callback;
- this.callback = _.debounce(fn, milliseconds);
- return this;
- },
+ withDebounce: function(milliseconds) {
+ if(_.isNaN(milliseconds)) {
+ throw "Milliseconds must be a number";
+ }
+ var fn = this.callback;
+ this.callback = _.debounce(fn, milliseconds);
+ return this;
+ },
- withDelay: function(milliseconds) {
- if(_.isNaN(milliseconds)) {
- throw "Milliseconds must be a number";
- }
- var fn = this.callback;
- this.callback = function(data) {
- setTimeout(fn, milliseconds, data);
- };
- return this;
- },
+ withDelay: function(milliseconds) {
+ if(_.isNaN(milliseconds)) {
+ throw "Milliseconds must be a number";
+ }
+ var fn = this.callback;
+ this.callback = function(data) {
+ setTimeout(fn, milliseconds, data);
+ };
+ return this;
+ },
- withPriority: function(priority) {
- if(_.isNaN(priority)) {
- throw "Priority must be a number";
- }
- this.priority = priority;
- return this;
- },
+ withPriority: function(priority) {
+ if(_.isNaN(priority)) {
+ throw "Priority must be a number";
+ }
+ this.priority = priority;
+ 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;
- }
+ withThrottle: function(milliseconds) {
+ if(_.isNaN(milliseconds)) {
+ throw "Milliseconds must be a number";
+ }
+ var fn = this.callback;
+ this.callback = _.throttle(fn, milliseconds);
+ return this;
+ }
};
var bindingsResolver = {
@@ -209,9 +224,9 @@ var localBus = {
wireTaps: new Array(0),
- publish: function(envelope, data) {
+ publish: function(data, envelope) {
_.each(this.wireTaps,function(tap) {
- tap(envelope, data);
+ tap(data, envelope);
});
_.each(this.subscriptions[envelope.channel], function(topic) {
@@ -279,14 +294,14 @@ var localBus = {
};
var publishPicker = {
- "2" : function(envelope, payload) {
+ "2" : function(data, envelope) {
if(!envelope.channel) {
envelope.channel = DEFAULT_CHANNEL;
}
- postal.configuration.bus.publish(envelope, payload);
+ postal.configuration.bus.publish(data, envelope);
},
"3" : function(channel, topic, payload) {
- postal.configuration.bus.publish({ channel: channel, topic: topic }, payload);
+ postal.configuration.bus.publish(payload, { channel: channel, topic: topic });
}
};
@@ -343,7 +358,7 @@ var postal = {
var newEnv = env;
newEnv.topic = _.isFunction(destination.topic) ? destination.topic(env.topic) : destination.topic || env.topic;
newEnv.channel = destChannel;
- postal.publish(newEnv, msg);
+ postal.publish(msg, newEnv);
}
})
);
@@ -352,5 +367,8 @@ var postal = {
return result;
}
};
-
-return postal; });
\ No newline at end of file
+
+
+ global.postal = postal;
+ return postal;
+}));
\ No newline at end of file
diff --git a/example/standard/js/postal.diagnostics.js b/example/standard/js/postal.diagnostics.js
index f1d0516..5defd32 100644
--- a/example/standard/js/postal.diagnostics.js
+++ b/example/standard/js/postal.diagnostics.js
@@ -1,18 +1,33 @@
-postal.addWireTap(function(data, envelope) {
- var all = _.extend(envelope, { data: data });
- if(!JSON) {
- throw "This browser or environment does not provide JSON support";
- }
- try {
- console.log(JSON.stringify(all));
- }
- catch(exception) {
- try {
- all.data = "ERROR: " + exception.message;
- console.log(JSON.stringify(all));
- }
- catch(ex) {
- console.log("Unable to parse data to JSON: " + exception);
- }
- }
-});
\ No newline at end of file
+(function(root, doc, factory) {
+ if (typeof define === "function" && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(["postal", "underscore"], function(postal, _) {
+ return factory(postal, _, root, doc);
+ });
+ } else {
+ // Browser globals
+ factory(root.postal, root._, root, doc);
+ }
+}(this, document, function(postal, _, global, document, undefined) {
+
+ // this returns a callback that, if invoked, removes the wireTap
+ return postal.addWireTap(function(data, envelope) {
+ var all = _.extend(envelope, { data: data });
+ if(!JSON) {
+ throw "This browser or environment does not provide JSON support";
+ }
+ try {
+ console.log(JSON.stringify(all));
+ }
+ catch(exception) {
+ try {
+ all.data = "ERROR: " + exception.message;
+ console.log(JSON.stringify(all));
+ }
+ catch(ex) {
+ console.log("Unable to parse data to JSON: " + exception);
+ }
+ }
+ });
+
+}));
\ No newline at end of file
diff --git a/example/standard/js/postal.js b/example/standard/js/postal.js
index 66cd36a..7fe0a44 100644
--- a/example/standard/js/postal.js
+++ b/example/standard/js/postal.js
@@ -1,4 +1,3 @@
-(function(global, undefined) {
/*
postal.js
Author: Jim Cowart
@@ -6,6 +5,18 @@
Version 0.4.0
*/
+(function(root, doc, factory) {
+ if (typeof define === "function" && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(["underscore"], function(_) {
+ return factory(_, root, doc);
+ });
+ } else {
+ // Browser globals
+ factory(root._, root, doc);
+ }
+}(this, document, function(_, global, document, undefined) {
+
var DEFAULT_CHANNEL = "/",
DEFAULT_PRIORITY = 50,
DEFAULT_DISPOSEAFTER = 0,
@@ -34,8 +45,14 @@ var ChannelDefinition = function(channelName, defaultTopic) {
};
ChannelDefinition.prototype = {
- subscribe: function(callback) {
- return new SubscriptionDefinition(this.channel, this.topic, callback);
+ subscribe: function() {
+ var len = arguments.length;
+ if(len === 1) {
+ return new SubscriptionDefinition(this.channel, this.topic, arguments[0]);
+ }
+ else if (len === 2) {
+ return new SubscriptionDefinition(this.channel, arguments[0], arguments[1]);
+ }
},
publish: function(data, envelope) {
@@ -43,142 +60,140 @@ ChannelDefinition.prototype = {
env.channel = this.channel;
env.timeStamp = new Date();
env.topic = env.topic || this.topic;
- postal.configuration.bus.publish(env, data);
+ postal.configuration.bus.publish(data, env);
}
};
var SubscriptionDefinition = function(channel, topic, callback) {
- this.channel = channel;
- this.topic = topic;
- this.callback = callback;
- this.priority = DEFAULT_PRIORITY;
- this.constraints = new Array(0);
- this.maxCalls = DEFAULT_DISPOSEAFTER;
- this.onHandled = NO_OP;
- this.context = null;
+ this.channel = channel;
+ this.topic = topic;
+ this.callback = callback;
+ this.priority = DEFAULT_PRIORITY;
+ this.constraints = new Array(0);
+ this.maxCalls = DEFAULT_DISPOSEAFTER;
+ this.onHandled = NO_OP;
+ this.context = null;
+ postal.publish({
+ event: "subscription.created",
+ channel: channel,
+ topic: topic
+ },{
+ channel: SYSTEM_CHANNEL,
+ topic: "subscription.created"
+ });
postal.configuration.bus.subscribe(this);
- postal.publish({
- channel: SYSTEM_CHANNEL,
- topic: "subscription.created"
- },
- {
- event: "subscription.created",
- channel: channel,
- topic: topic
- });
};
SubscriptionDefinition.prototype = {
- unsubscribe: function() {
- postal.configuration.bus.unsubscribe(this);
- postal.publish({
- channel: SYSTEM_CHANNEL,
- topic: "subscription.removed"
- },
- {
- event: "subscription.removed",
- channel: this.channel,
- topic: this.topic
- });
- },
+ unsubscribe: function() {
+ postal.configuration.bus.unsubscribe(this);
+ postal.publish({
+ event: "subscription.removed",
+ channel: this.channel,
+ topic: this.topic
+ },{
+ channel: SYSTEM_CHANNEL,
+ topic: "subscription.removed"
+ });
+ },
- defer: function() {
- var fn = this.callback;
- this.callback = function(data) {
- setTimeout(fn,0,data);
- };
- return this;
- },
+ defer: function() {
+ var fn = this.callback;
+ this.callback = function(data) {
+ setTimeout(fn,0,data);
+ };
+ return this;
+ },
- disposeAfter: function(maxCalls) {
- if(_.isNaN(maxCalls) || maxCalls <= 0) {
- throw "The value provided to disposeAfter (maxCalls) must be a number greater than zero.";
- }
+ disposeAfter: function(maxCalls) {
+ if(_.isNaN(maxCalls) || maxCalls <= 0) {
+ throw "The value provided to disposeAfter (maxCalls) must be a number greater than zero.";
+ }
- var fn = this.onHandled;
- var dispose = _.after(maxCalls, _.bind(function() {
- this.unsubscribe(this);
- }, this));
+ var fn = this.onHandled;
+ var dispose = _.after(maxCalls, _.bind(function() {
+ this.unsubscribe(this);
+ }, this));
- this.onHandled = function() {
- fn.apply(this.context, arguments);
- dispose();
- };
- return this;
- },
+ this.onHandled = function() {
+ fn.apply(this.context, arguments);
+ dispose();
+ };
+ return this;
+ },
- ignoreDuplicates: function() {
- this.withConstraint(new DistinctPredicate());
- return this;
- },
+ ignoreDuplicates: function() {
+ this.withConstraint(new DistinctPredicate());
+ return this;
+ },
- whenHandledThenExecute: function(callback) {
- if(! _.isFunction(callback)) {
- throw "Value provided to 'whenHandledThenExecute' must be a function";
- }
- this.onHandled = callback;
- return this;
- },
+ whenHandledThenExecute: function(callback) {
+ if(! _.isFunction(callback)) {
+ throw "Value provided to 'whenHandledThenExecute' must be a function";
+ }
+ this.onHandled = callback;
+ return this;
+ },
- withConstraint: function(predicate) {
- if(! _.isFunction(predicate)) {
- throw "Predicate constraint must be a function";
- }
- this.constraints.push(predicate);
- 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;
- },
+ 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;
- },
+ withContext: function(context) {
+ this.context = context;
+ return this;
+ },
- withDebounce: function(milliseconds) {
- if(_.isNaN(milliseconds)) {
- throw "Milliseconds must be a number";
- }
- var fn = this.callback;
- this.callback = _.debounce(fn, milliseconds);
- return this;
- },
+ withDebounce: function(milliseconds) {
+ if(_.isNaN(milliseconds)) {
+ throw "Milliseconds must be a number";
+ }
+ var fn = this.callback;
+ this.callback = _.debounce(fn, milliseconds);
+ return this;
+ },
- withDelay: function(milliseconds) {
- if(_.isNaN(milliseconds)) {
- throw "Milliseconds must be a number";
- }
- var fn = this.callback;
- this.callback = function(data) {
- setTimeout(fn, milliseconds, data);
- };
- return this;
- },
+ withDelay: function(milliseconds) {
+ if(_.isNaN(milliseconds)) {
+ throw "Milliseconds must be a number";
+ }
+ var fn = this.callback;
+ this.callback = function(data) {
+ setTimeout(fn, milliseconds, data);
+ };
+ return this;
+ },
- withPriority: function(priority) {
- if(_.isNaN(priority)) {
- throw "Priority must be a number";
- }
- this.priority = priority;
- return this;
- },
+ withPriority: function(priority) {
+ if(_.isNaN(priority)) {
+ throw "Priority must be a number";
+ }
+ this.priority = priority;
+ 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;
- }
+ withThrottle: function(milliseconds) {
+ if(_.isNaN(milliseconds)) {
+ throw "Milliseconds must be a number";
+ }
+ var fn = this.callback;
+ this.callback = _.throttle(fn, milliseconds);
+ return this;
+ }
};
var bindingsResolver = {
@@ -209,9 +224,9 @@ var localBus = {
wireTaps: new Array(0),
- publish: function(envelope, data) {
+ publish: function(data, envelope) {
_.each(this.wireTaps,function(tap) {
- tap(envelope, data);
+ tap(data, envelope);
});
_.each(this.subscriptions[envelope.channel], function(topic) {
@@ -279,14 +294,14 @@ var localBus = {
};
var publishPicker = {
- "2" : function(envelope, payload) {
+ "2" : function(data, envelope) {
if(!envelope.channel) {
envelope.channel = DEFAULT_CHANNEL;
}
- postal.configuration.bus.publish(envelope, payload);
+ postal.configuration.bus.publish(data, envelope);
},
"3" : function(channel, topic, payload) {
- postal.configuration.bus.publish({ channel: channel, topic: topic }, payload);
+ postal.configuration.bus.publish(payload, { channel: channel, topic: topic });
}
};
@@ -343,7 +358,7 @@ var postal = {
var newEnv = env;
newEnv.topic = _.isFunction(destination.topic) ? destination.topic(env.topic) : destination.topic || env.topic;
newEnv.channel = destChannel;
- postal.publish(newEnv, msg);
+ postal.publish(msg, newEnv);
}
})
);
@@ -352,5 +367,8 @@ var postal = {
return result;
}
};
-
-global.postal = postal; })(window);
\ No newline at end of file
+
+
+ global.postal = postal;
+ return postal;
+}));
\ No newline at end of file
diff --git a/lib/browser/amd/postal.diagnostics.js b/lib/browser/amd/postal.diagnostics.js
deleted file mode 100644
index 9f9ee66..0000000
--- a/lib/browser/amd/postal.diagnostics.js
+++ /dev/null
@@ -1,20 +0,0 @@
-define(['postal', 'underscore'], function(postal, _) {
-postal.addWireTap(function(data, envelope) {
- var all = _.extend(envelope, { data: data });
- if(!JSON) {
- throw "This browser or environment does not provide JSON support";
- }
- try {
- console.log(JSON.stringify(all));
- }
- catch(exception) {
- try {
- all.data = "ERROR: " + exception.message;
- console.log(JSON.stringify(all));
- }
- catch(ex) {
- console.log("Unable to parse data to JSON: " + exception);
- }
- }
-});
-});
\ No newline at end of file
diff --git a/lib/browser/amd/postal.diagnostics.min.gz.js b/lib/browser/amd/postal.diagnostics.min.gz.js
deleted file mode 100644
index be522d3..0000000
Binary files a/lib/browser/amd/postal.diagnostics.min.gz.js and /dev/null differ
diff --git a/lib/browser/amd/postal.diagnostics.min.js b/lib/browser/amd/postal.diagnostics.min.js
deleted file mode 100644
index 674a524..0000000
--- a/lib/browser/amd/postal.diagnostics.min.js
+++ /dev/null
@@ -1 +0,0 @@
-define(["postal","underscore"],function(a,b){a.addWireTap(function(a,c){var d=b.extend(c,{data:a});if(!JSON)throw"This browser or environment does not provide JSON support";try{console.log(JSON.stringify(d))}catch(e){try{d.data="ERROR: "+e.message,console.log(JSON.stringify(d))}catch(f){console.log("Unable to parse data to JSON: "+e)}}})})
\ No newline at end of file
diff --git a/lib/browser/amd/postal.js b/lib/browser/amd/postal.js
deleted file mode 100644
index f8037cc..0000000
--- a/lib/browser/amd/postal.js
+++ /dev/null
@@ -1,356 +0,0 @@
-define(['underscore'], function(_) {
-/*
- postal.js
- Author: Jim Cowart
- License: Dual licensed MIT (http://www.opensource.org/licenses/mit-license) & GPL (http://www.opensource.org/licenses/gpl-license)
- Version 0.4.0
-*/
-
-var DEFAULT_CHANNEL = "/",
- DEFAULT_PRIORITY = 50,
- DEFAULT_DISPOSEAFTER = 0,
- SYSTEM_CHANNEL = "postal",
- NO_OP = function() { };
-
-var DistinctPredicate = 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 ChannelDefinition = function(channelName, defaultTopic) {
- this.channel = channelName;
- this.topic = defaultTopic || "";
-};
-
-ChannelDefinition.prototype = {
- subscribe: function(callback) {
- return new SubscriptionDefinition(this.channel, this.topic, callback);
- },
-
- publish: function(data, envelope) {
- var env = envelope || {};
- env.channel = this.channel;
- env.timeStamp = new Date();
- env.topic = env.topic || this.topic;
- postal.configuration.bus.publish(env, data);
- }
-};
-
-var SubscriptionDefinition = function(channel, topic, callback) {
- this.channel = channel;
- this.topic = topic;
- this.callback = callback;
- this.priority = DEFAULT_PRIORITY;
- this.constraints = new Array(0);
- this.maxCalls = DEFAULT_DISPOSEAFTER;
- this.onHandled = NO_OP;
- this.context = null;
-
- postal.configuration.bus.subscribe(this);
-
- postal.publish({
- channel: SYSTEM_CHANNEL,
- topic: "subscription.created"
- },
- {
- event: "subscription.created",
- channel: channel,
- topic: topic
- });
-};
-
-SubscriptionDefinition.prototype = {
- unsubscribe: function() {
- postal.configuration.bus.unsubscribe(this);
- postal.publish({
- channel: SYSTEM_CHANNEL,
- topic: "subscription.removed"
- },
- {
- event: "subscription.removed",
- channel: this.channel,
- topic: this.topic
- });
- },
-
- defer: function() {
- var fn = this.callback;
- this.callback = function(data) {
- setTimeout(fn,0,data);
- };
- 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 fn = this.onHandled;
- var dispose = _.after(maxCalls, _.bind(function() {
- this.unsubscribe(this);
- }, this));
-
- this.onHandled = function() {
- fn.apply(this.context, arguments);
- dispose();
- };
- return this;
- },
-
- ignoreDuplicates: function() {
- this.withConstraint(new DistinctPredicate());
- return this;
- },
-
- whenHandledThenExecute: function(callback) {
- if(! _.isFunction(callback)) {
- throw "Value provided to 'whenHandledThenExecute' must be a function";
- }
- this.onHandled = callback;
- 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) {
- if(_.isNaN(milliseconds)) {
- throw "Milliseconds must be a number";
- }
- var fn = this.callback;
- this.callback = _.debounce(fn, milliseconds);
- return this;
- },
-
- withDelay: function(milliseconds) {
- if(_.isNaN(milliseconds)) {
- throw "Milliseconds must be a number";
- }
- var fn = this.callback;
- this.callback = function(data) {
- setTimeout(fn, milliseconds, data);
- };
- return this;
- },
-
- withPriority: function(priority) {
- if(_.isNaN(priority)) {
- throw "Priority must be a number";
- }
- this.priority = priority;
- 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;
- }
-};
-
-var bindingsResolver = {
- cache: { },
-
- compare: function(binding, topic) {
- if(this.cache[topic] && this.cache[topic][binding]) {
- return true;
- }
- // 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]) {
- this.cache[topic] = {};
- }
- this.cache[topic][binding] = true;
- }
- return result;
- }
-};
-
-var localBus = {
-
- subscriptions: {},
-
- wireTaps: new Array(0),
-
- publish: function(envelope, data) {
- _.each(this.wireTaps,function(tap) {
- tap(envelope, data);
- });
-
- _.each(this.subscriptions[envelope.channel], function(topic) {
- _.each(topic, function(binding){
- if(postal.configuration.resolver.compare(binding.topic, envelope.topic)) {
- if(_.all(binding.constraints, function(constraint) { return constraint(data); })) {
- if(typeof binding.callback === 'function') {
- binding.callback.apply(binding.context, [data, envelope]);
- binding.onHandled();
- }
- }
- }
- });
- });
- },
-
- subscribe: function(subDef) {
- var idx, found, fn, 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] = new Array(0);
- }
-
- idx = subs.length - 1;
- for(; idx >= 0; idx--) {
- if(subs[idx].priority <= subDef.priority) {
- subs.splice(idx + 1, 0, subDef);
- found = true;
- break;
- }
- }
- if(!found) {
- subs.unshift(subDef);
- }
- return subDef;
- },
-
- unsubscribe: function(config) {
- if(this.subscriptions[config.channel][config.topic]) {
- var len = this.subscriptions[config.channel][config.topic].length,
- idx = 0;
- for ( ; idx < len; idx++ ) {
- if (this.subscriptions[config.channel][config.topic][idx] === config) {
- this.subscriptions[config.channel][config.topic].splice( idx, 1 );
- break;
- }
- }
- }
- },
-
- 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);
- }
- };
- }
-};
-
-var publishPicker = {
- "2" : function(envelope, payload) {
- if(!envelope.channel) {
- envelope.channel = DEFAULT_CHANNEL;
- }
- postal.configuration.bus.publish(envelope, payload);
- },
- "3" : function(channel, topic, payload) {
- postal.configuration.bus.publish({ channel: channel, topic: topic }, payload);
- }
-};
-
-// save some setup time, albeit tiny
-localBus.subscriptions[SYSTEM_CHANNEL] = {};
-
-var postal = {
- configuration: {
- bus: localBus,
- resolver: bindingsResolver
- },
-
- channel: function(options) {
- var channel = options.channel || DEFAULT_CHANNEL,
- tpc = options.topic;
- return new ChannelDefinition(channel, tpc);
- },
-
- subscribe: function(options) {
- var callback = options.callback,
- topic = options.topic,
- channel = options.channel || DEFAULT_CHANNEL;
- return new SubscriptionDefinition(channel, topic, callback);
- },
-
- publish: function() {
- var len = arguments.length;
- if(publishPicker[len]) {
- publishPicker[len].apply(this, arguments);
- }
- },
-
- addWireTap: function(callback) {
- return this.configuration.bus.addWireTap(callback);
- },
-
- linkChannels: function(sources, destinations) {
- var result = [];
- if(!_.isArray(sources)) {
- sources = [sources];
- }
- if(!_.isArray(destinations)) {
- destinations = [destinations];
- }
- _.each(sources, function(source){
- var sourceTopic = source.topic || "*";
- _.each(destinations, function(destination) {
- var destChannel = destination.channel || DEFAULT_CHANNEL;
- result.push(
- postal.subscribe({
- channel: source.channel || DEFAULT_CHANNEL,
- topic: source.topic || "*",
- callback : function(msg, env) {
- var newEnv = env;
- newEnv.topic = _.isFunction(destination.topic) ? destination.topic(env.topic) : destination.topic || env.topic;
- newEnv.channel = destChannel;
- postal.publish(newEnv, msg);
- }
- })
- );
- });
- });
- return result;
- }
-};
-
-return postal; });
\ No newline at end of file
diff --git a/lib/browser/amd/postal.min.gz.js b/lib/browser/amd/postal.min.gz.js
deleted file mode 100644
index 6f0e3e1..0000000
Binary files a/lib/browser/amd/postal.min.gz.js and /dev/null differ
diff --git a/lib/browser/amd/postal.min.js b/lib/browser/amd/postal.min.js
deleted file mode 100644
index 5022587..0000000
--- a/lib/browser/amd/postal.min.js
+++ /dev/null
@@ -1 +0,0 @@
-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.channel=a,this.topic=b||""};h.prototype={subscribe:function(a){return new i(this.channel,this.topic,a)},publish:function(a,b){var c=b||{};c.channel=this.channel,c.timeStamp=new Date,c.topic=c.topic||this.topic,m.configuration.bus.publish(c,a)}};var i=function(a,b,g){this.channel=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.configuration.bus.subscribe(this),m.publish({channel:e,topic:"subscription.created"},{event:"subscription.created",channel:a,topic:b})};i.prototype={unsubscribe:function(){m.configuration.bus.unsubscribe(this),m.publish({channel:e,topic:"subscription.removed"},{event:"subscription.removed",channel:this.channel,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.channel],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.channel],f;e||(e=this.subscriptions[a.channel]={}),f=this.subscriptions[a.channel][a.topic],f||(f=this.subscriptions[a.channel][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}return c||f.unshift(a),a},unsubscribe:function(a){if(this.subscriptions[a.channel][a.topic]){var b=this.subscriptions[a.channel][a.topic].length,c=0;for(;c=0;b--)if(f[b].priority<=a.priority){f.splice(b+1,0,a),c=!0;break}return c||f.unshift(a),a},unsubscribe:function(a){if(this.subscriptions[a.channel][a.topic]){var b=this.subscriptions[a.channel][a.topic].length,c=0;for(;c=0;b--)if(f[b].priority<=a.priority){f.splice(b+1,0,a),c=!0;break}return c||f.unshift(a),a},unsubscribe:function(a){if(this.subscriptions[a.channel][a.topic]){var b=this.subscriptions[a.channel][a.topic].length,c=0;for(;c