Comparing version 1.4.2 to 1.5.0
{ | ||
"name": "PubSubJS", | ||
"version": "1.4.2", | ||
"version": "1.5.0", | ||
"main": "src/pubsub.js", | ||
@@ -5,0 +5,0 @@ "ignore": [ |
@@ -28,10 +28,7 @@ # Contributing to PubSubJS | ||
Syntax: | ||
And in case we didn't emphasize it enough: we love tests! | ||
* Tabs, not spaces | ||
* PubSubJS is linted with jslint, with these settings: `/*jslint white:true, plusplus:true, stupid:true*/` | ||
* No trailing whitespace. Blank lines should not have any space. | ||
* Follow the conventions you see used in the source already. | ||
## Syntax | ||
And in case we didn't emphasize it enough: we love tests! | ||
Install [Editor Config](http://editorconfig.org) for your text editor, this will ensure that the correct formatting is applied for each file type. | ||
@@ -63,2 +60,2 @@ ## Development | ||
$ npm test | ||
``` | ||
``` |
@@ -34,2 +34,13 @@ /*jslint white:true*/ | ||
} | ||
}, | ||
concat: { | ||
options: { | ||
// overrides the default linefeed separator | ||
separator: '' | ||
}, | ||
jquery: { | ||
src: ['wrappers/jquery/pubsub.js.pre.txt', 'src/pubsub.js', 'wrappers/jquery/pubsub.js.post.txt'], | ||
dest: 'jquery.pubsub.js' | ||
} | ||
} | ||
@@ -40,2 +51,3 @@ }); | ||
grunt.loadNpmTasks('grunt-jslint'); | ||
grunt.loadNpmTasks('grunt-contrib-concat'); | ||
@@ -47,4 +59,7 @@ // override the built-in lint task with jslint | ||
// build jQuery version | ||
grunt.registerTask('jquery', 'concat:jquery'); | ||
// Default task. | ||
grunt.registerTask('default', 'test'); | ||
}; |
{ | ||
"name": "pubsub-js", | ||
"version": "1.4.2", | ||
"version": "1.5.0", | ||
"description": "Dependency free publish/subscribe library", | ||
@@ -11,3 +11,3 @@ "main": "./src/pubsub.js", | ||
"scripts": { | ||
"test": "grunt test" | ||
"test": "$(npm bin)/grunt test" | ||
}, | ||
@@ -32,7 +32,9 @@ "repository": { | ||
"devDependencies": { | ||
"buster": "0.6.x", | ||
"grunt": "0.4.0", | ||
"grunt-jslint": "0.2.5", | ||
"grunt-buster": "0.1.2" | ||
"grunt-buster": "0.1.2", | ||
"grunt-contrib-concat": "0.5.0", | ||
"buster": "0.7.13", | ||
"grunt": "~0.4.4", | ||
"grunt-cli": "~0.1.13" | ||
} | ||
} |
@@ -5,10 +5,14 @@ # PubSubJS | ||
PubSubJS is a dependency free [publish/subscribe](http://en.wikipedia.org/wiki/Publish/subscribe) library for [JavaScript](https://developer.mozilla.org/en/JavaScript). | ||
PubSubJS is a [topic-based](http://en.wikipedia.org/wiki/Publish–subscribe_pattern#Message_filtering) [publish/subscribe](http://en.wikipedia.org/wiki/Publish/subscribe) library written in JavaScript. | ||
PubSubJS has synchronisation decoupling, so messages are delivered asynchronously. This helps keep your program predictable as the originator of messages will not be blocked while consumers process messages. | ||
PubSubJS has synchronisation decoupling, so topics are published asynchronously. This helps keep your program predictable as the originator of topics will not be blocked while consumers process them. | ||
For the adventurous, PubSubJS also supports synchronous message publication. This can give a speedup in some environments (browsers, not all), but can also lead to some very difficult to reason about programs, when one message triggers publication of another message in the same execution chain. | ||
For the adventurous, PubSubJS also supports synchronous topic publication. This can give a speedup in some environments (browsers, not all), but can also lead to some very difficult to reason about programs, where one topic triggers publication of another topic in the same execution chain. | ||
For benchmarks, see [A Comparison of JS Publish/Subscribe Approaches](http://jsperf.com/pubsubjs-vs-jquery-custom-events/51) | ||
#### Single process | ||
PubSubJS is designed to be used within a **single process**, and is not a good candidate for multi-process applications (like [Node.js – Cluster](http://nodejs.org/api/cluster.html) with many sub-processes). If your Node.js app is a single process app, you're good. If it is (or is going to be) a multi-process app, you're probably better off using [redis Pub/Sub](http://redis.io/topics/pubsub) or similar | ||
## Key features | ||
@@ -37,3 +41,3 @@ | ||
```javascript | ||
// create a function to receive messages | ||
// create a function to subscribe to topics | ||
var mySubscriber = function( msg, data ){ | ||
@@ -43,15 +47,15 @@ console.log( msg, data ); | ||
// add the function to the list of subscribers for a particular message | ||
// add the function to the list of subscribers for a particular topic | ||
// we're keeping the returned token, in order to be able to unsubscribe | ||
// from the message later on | ||
var token = PubSub.subscribe( 'MY MESSAGE', mySubscriber ); | ||
// from the topic later on | ||
var token = PubSub.subscribe( 'MY TOPIC', mySubscriber ); | ||
// publish a message asyncronously | ||
PubSub.publish( 'MY MESSAGE', 'hello world!' ); | ||
// publish a topic asyncronously | ||
PubSub.publish( 'MY TOPIC', 'hello world!' ); | ||
// publish a message syncronously, which is faster in some environments, | ||
// but will get confusing when one message triggers new messages in the | ||
// publish a topic syncronously, which is faster in some environments, | ||
// but will get confusing when one topic triggers new topics in the | ||
// same execution chain | ||
// USE WITH CAUTION, HERE BE DRAGONS!!! | ||
PubSub.publishSync( 'MY MESSAGE', 'hello world!' ); | ||
PubSub.publishSync( 'MY TOPIC', 'hello world!' ); | ||
``` | ||
@@ -62,3 +66,3 @@ | ||
```javascript | ||
// create a function to receive the message | ||
// create a function to receive the topic | ||
var mySubscriber = function( msg, data ){ | ||
@@ -68,8 +72,8 @@ console.log( msg, data ); | ||
// add the function to the list of subscribers to a particular message | ||
// add the function to the list of subscribers to a particular topic | ||
// we're keeping the returned token, in order to be able to unsubscribe | ||
// from the message later on | ||
var token = PubSub.subscribe( 'MY MESSAGE', mySubscriber ); | ||
// from the topic later on | ||
var token = PubSub.subscribe( 'MY TOPIC', mySubscriber ); | ||
// unsubscribe from further messages | ||
// unsubscribe this subscriber from this topic | ||
PubSub.unsubscribe( token ); | ||
@@ -81,3 +85,3 @@ ``` | ||
```javascript | ||
// create a function to receive the message | ||
// create a function to receive the topic | ||
var mySubscriber = function( msg, data ){ | ||
@@ -87,15 +91,29 @@ console.log( msg, data ); | ||
// add the function to the list of subscribers to a particular message | ||
// we're keeping the returned token, in order to be able to unsubscribe | ||
// from the message later on | ||
var token = PubSub.subscribe( 'MY MESSAGE', mySubscriber ); | ||
// unsubscribe mySubscriber from ALL further messages | ||
// unsubscribe mySubscriber from ALL topics | ||
PubSub.unsubscribe( mySubscriber ); | ||
``` | ||
### Clear all subscriptions for a topic | ||
```javascript | ||
PubSub.subscribe('a', myFunc1); | ||
PubSub.subscribe('a.b', myFunc2); | ||
PubSub.subscribe('a.b.c', myFunc3); | ||
PubSub.unsubscribe('a.b'); | ||
// no further notications for 'a.b' and 'a.b.c' topics | ||
// notifications for 'a' will still get published | ||
``` | ||
### Clear all subscriptions | ||
```javascript | ||
PubSub.clearAllSubscriptions(); | ||
// all subscriptions are removed | ||
``` | ||
### Hierarchical addressing | ||
```javascript | ||
// create a subscriber to receive all messages from a hierarchy of topics | ||
// create a subscriber to receive all topics from a hierarchy of topics | ||
var myToplevelSubscriber = function( msg, data ){ | ||
@@ -108,3 +126,3 @@ console.log( 'top level: ', msg, data ); | ||
// create a subscriber to receive only leaf message from hierarchy op topics | ||
// create a subscriber to receive only leaf topic from hierarchy op topics | ||
var mySpecificSubscriber = function( msg, data ){ | ||
@@ -130,4 +148,3 @@ console.log('specific: ', msg, data ); | ||
Use "constants" for topics and not string literals. PubSubJS uses strings as topics, and will happily try to deliver | ||
your messages with ANY topic. So, save yourself from frustrating debugging by letting the JavaScript engine complain | ||
Use "constants" for topics and not string literals. PubSubJS uses strings as topics, and will happily try to deliver your topics with ANY topic. So, save yourself from frustrating debugging by letting the JavaScript engine complain | ||
when you make typos. | ||
@@ -168,6 +185,10 @@ | ||
By default PubSubJS can be used in any browser or CommonJS environment, including [node](http://nodejs.org). Additionally, PubSubJS can be built specifically for jQuery. | ||
By default PubSubJS can be used in any browser or CommonJS environment, including [node](http://nodejs.org). Additionally, PubSubJS can be built specifically for jQuery using Rake. | ||
$ rake jquery | ||
or using Grunt | ||
$ grunt jquery | ||
Produces jquery.pubsub.js | ||
@@ -208,6 +229,5 @@ | ||
* Build script to create the following wrappers | ||
* Ender.js wrapper | ||
* Better and more extensive usage examples | ||
## More about Publish/Subscribe | ||
@@ -238,2 +258,2 @@ | ||
* http://radio.uxder.com/ — oriented towards 'channels', free of dependencies | ||
* https://github.com/pmelander/Subtopic - supports vanilla, underscore, jQuery and is even available in NuGet | ||
* https://github.com/pmelander/Subtopic - supports vanilla, underscore, jQuery and is even available in NuGet |
/* | ||
Copyright (c) 2010,2011,2012,2013 Morgan Roderick http://roderick.dk | ||
Copyright (c) 2010,2011,2012,2013,2014 Morgan Roderick http://roderick.dk | ||
License: MIT - http://mrgnrdrck.mit-license.org | ||
@@ -16,22 +16,22 @@ | ||
*/ | ||
(function(root, factory){ | ||
(function (root, factory){ | ||
'use strict'; | ||
// CommonJS | ||
if (typeof exports === 'object' && module){ | ||
module.exports = factory(); | ||
if (typeof define === 'function' && define.amd){ | ||
// AMD. Register as an anonymous module. | ||
define(['exports'], factory); | ||
// AMD | ||
} else if (typeof define === 'function' && define.amd){ | ||
define(factory); | ||
// Browser | ||
} else { | ||
root.PubSub = factory(); | ||
} | ||
}( ( typeof window === 'object' && window ) || this, function(){ | ||
} else if (typeof exports === 'object'){ | ||
// CommonJS | ||
factory(exports); | ||
} else { | ||
// Browser globals | ||
factory((root.PubSub = {})); | ||
} | ||
}(( typeof window === 'object' && window ) || this, function (PubSub){ | ||
'use strict'; | ||
var PubSub = {}, | ||
messages = {}, | ||
var messages = {}, | ||
lastUid = -1; | ||
@@ -181,13 +181,39 @@ | ||
/** | ||
* PubSub.unsubscribe( tokenOrFunction ) -> String | Boolean | ||
* - tokenOrFunction (String|Function): The token of the function to unsubscribe or func passed in on subscribe | ||
* Unsubscribes a specific subscriber from a specific message using the unique token | ||
* or if using Function as argument, it will remove all subscriptions with that function | ||
**/ | ||
PubSub.unsubscribe = function( tokenOrFunction ){ | ||
var isToken = typeof tokenOrFunction === 'string', | ||
/* Public: Clears all subscriptions | ||
*/ | ||
PubSub.clearAllSubscriptions = function clearSubscriptions(){ | ||
messages = {}; | ||
}; | ||
/* Public: removes subscriptions. | ||
* When passed a token, removes a specific subscription. | ||
* When passed a function, removes all subscriptions for that function | ||
* When passed a topic, removes all subscriptions for that topic (hierarchy) | ||
* | ||
* value - A token, function or topic to unsubscribe. | ||
* | ||
* Examples | ||
* | ||
* // Example 1 - unsubscribing with a token | ||
* var token = PubSub.subscribe('mytopic', myFunc); | ||
* PubSub.unsubscribe(token); | ||
* | ||
* // Example 2 - unsubscribing with a function | ||
* PubSub.unsubscribe(myFunc); | ||
* | ||
* // Example 3 - unsubscribing a topic | ||
* PubSub.unsubscribe('mytopic'); | ||
*/ | ||
PubSub.unsubscribe = function(value){ | ||
var isTopic = typeof value === 'string' && messages.hasOwnProperty(value), | ||
isToken = !isTopic && typeof value === 'string', | ||
isFunction = typeof value === 'function', | ||
result = false, | ||
m, message, t, token; | ||
if (isTopic){ | ||
delete messages[value]; | ||
return; | ||
} | ||
for ( m in messages ){ | ||
@@ -197,10 +223,10 @@ if ( messages.hasOwnProperty( m ) ){ | ||
if ( isToken && message[tokenOrFunction] ){ | ||
delete message[tokenOrFunction]; | ||
result = tokenOrFunction; | ||
if ( isToken && message[value] ){ | ||
delete message[value]; | ||
result = value; | ||
// tokens are unique, so we can just stop here | ||
break; | ||
} else if (!isToken) { | ||
} else if (isFunction) { | ||
for ( t in message ){ | ||
if (message.hasOwnProperty(t) && message[t] === tokenOrFunction){ | ||
if (message.hasOwnProperty(t) && message[t] === value){ | ||
delete message[t]; | ||
@@ -216,4 +242,2 @@ result = true; | ||
}; | ||
return PubSub; | ||
})); |
@@ -76,2 +76,58 @@ /*jslint white:true, stupid:true*/ | ||
'with topic argument, must clear all exactly matched subscriptions': function(){ | ||
var topic = TestHelper.getUniqueString(), | ||
spy1 = sinon.spy(), | ||
spy2 = sinon.spy(); | ||
PubSub.subscribe(topic, spy1); | ||
PubSub.subscribe(topic, spy2); | ||
PubSub.unsubscribe(topic); | ||
PubSub.publishSync(topic, TestHelper.getUniqueString()); | ||
refute(spy1.called); | ||
refute(spy2.called); | ||
}, | ||
'with topic argument, must only clear matched subscriptions': function(){ | ||
var topic1 = TestHelper.getUniqueString(), | ||
topic2 = TestHelper.getUniqueString(), | ||
spy1 = sinon.spy(), | ||
spy2 = sinon.spy(); | ||
PubSub.subscribe(topic1, spy1); | ||
PubSub.subscribe(topic2, spy2); | ||
PubSub.unsubscribe(topic1); | ||
PubSub.publishSync(topic1, TestHelper.getUniqueString()); | ||
PubSub.publishSync(topic2, TestHelper.getUniqueString()); | ||
refute(spy1.called); | ||
assert(spy2.called); | ||
}, | ||
'with topic argument, must clear all matched hierarchical subscriptions': function(){ | ||
var topic = TestHelper.getUniqueString(), | ||
topicA = topic + '.a', | ||
topicB = topic + '.a.b', | ||
topicC = topic + '.a.b.c', | ||
spyA = sinon.spy(), | ||
spyB = sinon.spy(), | ||
spyC = sinon.spy(); | ||
PubSub.subscribe(topicA, spyA); | ||
PubSub.subscribe(topicB, spyB); | ||
PubSub.subscribe(topicC, spyC); | ||
PubSub.unsubscribe(topicB); | ||
PubSub.publishSync(topicA, TestHelper.getUniqueString()); | ||
assert(spyA.called); | ||
refute(spyB.called); | ||
refute(spyC.called); | ||
}, | ||
'must not throw exception when unsubscribing as part of publishing' : function(){ | ||
@@ -78,0 +134,0 @@ refute.exception(function(){ |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
303892
30
8839
248
6