diff --git a/CHANGELOG.md b/CHANGELOG.md
index d84e5f3..f1f11c9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,8 @@
# CHANGELOG
+## v3.4.0
+- Add static method `PubSub.noConflict()` to roll back the global `PubSub` identifier. Used in a normal browser global namespace environment to avoid conflicts, etc.
+
## v3.3.0
- If there is no subscriber for a topic, delete topic property when unsubscribing. Used to leave it as an empty array before.
- The result of `subscribers` and `subscribersByTopic` methods is just a copy of the original object or array accordingly.
diff --git a/README.md b/README.md
index 93431e3..6e62a91 100644
--- a/README.md
+++ b/README.md
@@ -30,35 +30,34 @@ $ npm install PubSub
$ bower install georapbox.pubsub.js
```
-## Changelog
-
-For API updates and breaking changes, check the [CHANGELOG](https://github.com/georapbox/PubSub/blob/master/CHANGELOG.md).
-
## API
* [PubSub](#PubSub)
* [new PubSub()](#new_PubSub_new)
- * [.subscribe(topic, callback, [once])](#PubSub+subscribe) ⇒ number
- * [.subscribeOnce(topic, callback)](#PubSub+subscribeOnce) ⇒ number
- * [.publish(topic, [data])](#PubSub+publish) ⇒ boolean
- * [.publishSync(topic, [data])](#PubSub+publishSync) ⇒ boolean
- * [.unsubscribe(topic)](#PubSub+unsubscribe) ⇒ boolean
\| string
- * [.unsubscribeAll()](#PubSub+unsubscribeAll) ⇒ [PubSub](#PubSub)
- * [.hasSubscribers([topic])](#PubSub+hasSubscribers) ⇒ boolean
- * [.subscribers()](#PubSub+subscribers) ⇒ object
- * [.subscribersByTopic(topic)](#PubSub+subscribersByTopic) ⇒ array
- * [.alias(aliasMap)](#PubSub+alias) ⇒ [PubSub](#PubSub)
+ * _instance_
+ * [.subscribe(topic, callback, [once])](#PubSub+subscribe) ⇒ number
+ * [.subscribeOnce(topic, callback)](#PubSub+subscribeOnce) ⇒ number
+ * [.publish(topic, [...data])](#PubSub+publish) ⇒ boolean
+ * [.publishSync(topic, [...data])](#PubSub+publishSync) ⇒ boolean
+ * [.unsubscribe(topic)](#PubSub+unsubscribe) ⇒ boolean
\| string
+ * [.unsubscribeAll()](#PubSub+unsubscribeAll) ⇒ [PubSub](#PubSub)
+ * [.hasSubscribers([topic])](#PubSub+hasSubscribers) ⇒ boolean
+ * [.subscribers()](#PubSub+subscribers) ⇒ object
+ * [.subscribersByTopic(topic)](#PubSub+subscribersByTopic) ⇒ array
+ * [.alias(aliasMap)](#PubSub+alias) ⇒ [PubSub](#PubSub)
+ * _static_
+ * [.noConflict()](#PubSub.noConflict) ⇒ [PubSub](#PubSub)
### new PubSub()
Creates a PubSub instance.
-### Methods
+## Instance Methods
-### .subscribe(topic, callback, [once]) ⇒ number
+### pubSub.subscribe(topic, callback, [once]) ⇒ number
Subscribe to events of interest with a specific topic name and a
callback function, to be executed when the topic/event is observed.
@@ -82,7 +81,7 @@ var onUserAdd = pubsub.subscribe('user_add', function (data, topic) {
```
-### .subscribeOnce(topic, callback) ⇒ number
+### pubSub.subscribeOnce(topic, callback) ⇒ number
Subscribe to events of interest setting a flag
indicating the event will be published only one time.
@@ -103,7 +102,7 @@ var onUserAdd = pubsub.subscribeOnce('user_add', function (data, topic) {
```
-### .publish(topic, [data]) ⇒ boolean
+### pubSub.publish(topic, [data]) ⇒ boolean
Publishes a topic **asynchronously**, passing the data to its subscribers.
Asynchronous publication helps in that the originator of the topics will not be blocked while consumers process them.
For synchronous topic publication check `publishSync`.
@@ -126,7 +125,7 @@ pubsub.publish('user_add', {
```
-### .publishSync(topic, [data]) ⇒ boolean
+### pubSub.publishSync(topic, [data]) ⇒ boolean
Publishes a topic **synchronously**, passing the data to its subscribers.
**Kind**: instance method of [PubSub](#PubSub)
@@ -147,7 +146,7 @@ pubsub.publishSync('user_add', {
```
-### .unsubscribe(topic) ⇒ boolean
\| string
+### pubSub.unsubscribe(topic) ⇒ boolean
\| string
Unsubscribes from a specific topic, based on the topic name,
or based on a tokenized reference to the subscription.
@@ -168,7 +167,7 @@ pubsub.unsubscribe(onUserAdd);
```
-### .unsubscribeAll() ⇒ [PubSub](#PubSub)
+### pubSub.unsubscribeAll() ⇒ [PubSub](#PubSub)
Clears all subscriptions whatsoever.
**Kind**: instance method of [PubSub](#PubSub)
@@ -184,7 +183,7 @@ pubsub.hasSubscribers(); // -> false
```
-### .hasSubscribers([topic]) ⇒ boolean
+### pubSub.hasSubscribers([topic]) ⇒ boolean
Checks if there are subscribers for a specific topic.
If `topic` is not provided, checks if there is at least one subscriber.
@@ -207,14 +206,13 @@ pubsub.hasSubscribers('message');
```
-### .subscribers() ⇒ object
+### pubSub.subscribers() ⇒ object
Gets all the subscribers as a set of key value pairs that
represent the topic's name and the event listener(s) bound.
-**NOTE**: Mutating the result of this method does not affect the real subscribers. This is for reference only.
-
**Kind**: instance method of [PubSub](#PubSub)
**Returns**: object
- A readonly object with all subscribers.
+**Note**: Mutating the result of this method does not affect the real subscribers. This is for reference only.
**Example**
```js
var pubsub = new PubSub();
@@ -228,13 +226,12 @@ pubsub.subscribers();
```
-### .subscribersByTopic(topic) ⇒ array
+### pubSub.subscribersByTopic(topic) ⇒ array
Gets subscribers for a specific topic.
-**NOTE**: Mutating the result of this method does not affect the real subscribers. This is for reference only.
-
**Kind**: instance method of [PubSub](#PubSub)
**Returns**: array
- A copy array of all subscribers for a topic if exist; otherwise an empty array
+**Note**: Mutating the result of this method does not affect the real subscribers. This is for reference only.
| Param | Type | Description |
| --- | --- | --- |
@@ -259,7 +256,7 @@ pubsub.subscribersByTopic('some_message_not_existing');
```
-### .alias(aliasMap) ⇒ [PubSub](#PubSub)
+### pubSub.alias(aliasMap) ⇒ [PubSub](#PubSub)
Creates aliases for public methods.
**Kind**: instance method of [PubSub](#PubSub)
@@ -281,6 +278,24 @@ var pubsub = new PubSub().alias({
});
```
+## Static methods
+
+
+
+### PubSub.noConflict() ⇒ [PubSub](#PubSub)
+Rolls back the global `PubSub` identifier and returns the current constructor function.
+This can be used to keep the global namespace clean, or it can be used to have multiple simultaneous libraries
+(including separate versions/copies of `PubSub`) in the same project without conflicts over the `PubSub` global identifier.
+
+**Kind**: static method of [PubSub](#PubSub)
+**Returns**: [PubSub](#PubSub)
- The PubSub constructor.
+**Note**: The `PubSub.noConflict()` static method only makes sense when used in a normal browser global namespace environment. It should not be used with CommonJS or AMD style modules.
+**Example**
+```js
+var EventEmitter = PubSub.noConflict();
+var emitter = new EventEmitter();
+```
+
## Minify source code
```sh
@@ -296,6 +311,10 @@ To run the tests:
$ npm test
```
+## Changelog
+
+For API updates and breaking changes, check the [CHANGELOG](https://github.com/georapbox/PubSub/blob/master/CHANGELOG.md).
+
## More about Publish/Subscribe pattern
- [The Observer Pattern - Addy Osmani](https://addyosmani.com/resources/essentialjsdesignpatterns/book/#observerpatternjavascript)
diff --git a/src/pubsub.js b/src/pubsub.js
index b12e5d1..115c311 100644
--- a/src/pubsub.js
+++ b/src/pubsub.js
@@ -2,7 +2,7 @@
* PubSub.js
* Javascript implementation of the Publish/Subscribe pattern.
*
- * @version 3.3.0
+ * @version 3.4.0
* @author George Raptis (georapbox.github.io)
* @homepage https://github.com/georapbox/PubSub#readme
* @repository https://github.com/georapbox/PubSub.git
@@ -16,11 +16,14 @@
} else if (typeof module !== 'undefined' && module.exports) {
module.exports = definition();
} else {
- context[name] = definition();
+ context[name] = definition(name, context);
}
-}('PubSub', this, function () {
+}('PubSub', this, function (name, context) {
'use strict';
+ var VERSION = '3.4.0';
+ var OLD_PUBLIC_API = (context || {})[name];
+
function forOwn(obj, callback, thisArg) {
var key;
@@ -408,5 +411,33 @@
return this;
};
+ /**
+ * Rolls back the global `PubSub` identifier and returns the current constructor function.
+ * This can be used to keep the global namespace clean, or it can be used to have multiple simultaneous libraries
+ * (including separate versions/copies of `PubSub`) in the same project without conflicts over the `PubSub` global identifier.
+ *
+ * @NOTE The `PubSub.noConflict()` static method only makes sense when used in a normal browser global namespace environment.
+ * It should not be used with CommonJS or AMD style modules.
+ *
+ * @memberof PubSub
+ * @return {PubSub} The PubSub constructor.
+ * @example
+ *
+ * var EventEmitter = PubSub.noConflict();
+ * var emitter = new EventEmitter();
+ */
+ PubSub.noConflict = function noConflict() {
+ if (context) {
+ context[name] = OLD_PUBLIC_API;
+ }
+ return PubSub;
+ };
+
+ /**
+ * PubSub version
+ * @type {String}
+ */
+ PubSub.version = VERSION;
+
return PubSub;
}));
diff --git a/tests/pubsub.specs.js b/tests/pubsub.specs.js
index 549a092..d616c94 100644
--- a/tests/pubsub.specs.js
+++ b/tests/pubsub.specs.js
@@ -327,3 +327,14 @@ describe('Ensure that listeners registered on the same topic are invoked in the
expect(arr).toEqual(['A', 'B', 'C']);
});
});
+
+// noConflict functionality
+describe('noConflict static method', function () {
+ it('should roll back the global PubSub identifier and return the current constructor function', function () {
+ var EventEmitter = PubSub.noConflict();
+ var emitter = new EventEmitter();
+
+ expect(PubSub).toBeUndefined();
+ expect(emitter instanceof EventEmitter).toBe(true);
+ });
+});