diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8928f27..13c91cc 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,40 @@
# CHANGELOG
+## v3.0.0
+
+### Breaking changes
+
+The default API method aliases are deprecated and removed from v3.0.0 onwards. However there is a new method `alias` introduced, that allows to create your own aliases. Therefore, if you already use those aliases in a project you can use the `alias` method to provide your own.
+
+Below is a map of the default aliases that existed prior to version 3.0.0:
+
+| Original method | Alias method |
+| --------------- | ------------- |
+| `subscribe` | `on` |
+| `subscribeOnce` | `once` |
+| `publishSync` | `triggerSync` |
+| `unsubscribe` | `off` |
+| `hasSubscribers` | `has` |
+
+To create your own aliases:
+
+```js
+var pubsub = new PubSub().alias({
+ subscribe: 'on',
+ subscribeOnce: 'once',
+ publish: 'trigger',
+ publishSync: 'triggerSync',
+ unsubscribe: 'off',
+ hasSubscribers: 'has'
+});
+```
+
+### Other updates
+
+- Add public method `unsubscribeAll` to clear all subscriptions whatsoever.
+- Add public method `alias` to create your own method aliases. (See above)
+- Provide source-map for the minified library.
+
## v2.1.0
- Add support for publishing events synchronously using `publishSync` method.
- Add public method `hasSubscribers` to check if there are subscribers for a specific topic.
diff --git a/Gruntfile.js b/Gruntfile.js
index 8472e67..c4d8cb1 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -6,6 +6,7 @@ module.exports = function (grunt) {
uglify: {
options: {
+ sourceMap: 'dist/',
banner: '/**\n' +
' * <%= pkg.name %>\n' +
' * <%= pkg.description %>\n' +
diff --git a/README.md b/README.md
index db52ff1..c80633d 100644
--- a/README.md
+++ b/README.md
@@ -25,6 +25,10 @@ $ 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)
@@ -35,6 +39,8 @@ $ bower install georapbox.pubsub.js
* [.publishSync(topic, [data])](#PubSub+publishSync) ⇒ boolean
* [.unsubscribe(topic)](#PubSub+unsubscribe) ⇒ boolean
| string
* [.hasSubscribers(topic)](#PubSub+hasSubscribers) ⇒ Boolean
+ * [.unsubscribeAll()](#PubSub+unsubscribeAll) ⇒ [PubSub](#PubSub)
+ * [.alias(aliasMap)](#PubSub+alias) ⇒ [PubSub](#PubSub)
@@ -177,15 +183,45 @@ pubsub.on('message', function (data) {
pubsub.hasSubscribers('message');
// -> true
```
+
+
+### pubSub.unsubscribeAll() ⇒ [PubSub](#PubSub)
+Clears all subscriptions whatsoever.
+
+**Kind**: instance method of [PubSub](#PubSub)
+**Returns**: [PubSub](#PubSub)
- The PubSub instance.
+**this**: {PubSub}
+**Example**
+```js
+var pubsub = new PubSub();
+...
+...
+pubsub.unsubscribeAll();
+```
+
+### pubSub.alias(aliasMap) ⇒ [PubSub](#PubSub)
+Creates aliases for public methods.
-### Methods aliases
-- `on` - `subscribe`
-- `once` - `subscribeOnce`
-- `trigger` - `publish`
-- `triggerSync` - `publishSync`
-- `off` - `unsubscribe`
-- `has` - `hasSubscribers`
+**Kind**: instance method of [PubSub](#PubSub)
+**Returns**: [PubSub](#PubSub)
- The PubSub instance.
+**this**: {PubSub}
+
+| Param | Type | Description |
+| --- | --- | --- |
+| aliasMap | object
| A plain object that maps the public methods to their aliases. |
+
+**Example**
+```js
+var pubsub = new PubSub().alias({
+ subscribe: 'on',
+ subscribeOnce: 'once',
+ publish: 'trigger',
+ publishSync: 'triggerSync',
+ unsubscribe: 'off',
+ hasSubscribers: 'has'
+});
+```
## Minify
diff --git a/dist/pubsub.min.js b/dist/pubsub.min.js
index 3fe5b66..e1e9513 100644
--- a/dist/pubsub.min.js
+++ b/dist/pubsub.min.js
@@ -2,10 +2,12 @@
* PubSub
* Javascript implementation of the Publish/Subscribe pattern.
*
- * @version 2.1.0
+ * @version 3.0.0
* @author George Raptis (georapbox.github.io)
* @homepage https://github.com/georapbox/PubSub#readme
* @repository git+https://github.com/georapbox/PubSub.git
* @license MIT
*/
-!function(a,b,c){"use strict";"function"==typeof define&&define.amd?define(c):"undefined"!=typeof module&&module.exports?module.exports=c():b[a]=c()}("PubSub",this,function(){"use strict";function a(a){return function(){return this[a].apply(this,arguments)}}function b(a,b,c){for(var d,e,f=a.topics[b],g=f?f.length:0;g;)g-=1,e=f[g].token,d=f[g],d.callback(c,{name:b,token:e}),d.once===!0&&a.unsubscribe(e)}function c(a,c,d,e){return!!a.topics[c]&&(e?b(a,c,d):setTimeout(function(){b(a,c,d)},0),!0)}function d(){this.topics={},this.subUid=-1}return d.prototype.subscribe=function(a,b,c){var d=this.subUid+=1,e={};if("function"!=typeof b)throw new TypeError("When subscribing for an event, a callback function must be defined.");return this.topics[a]||(this.topics[a]=[]),e.token=d,e.callback=b,e.once=!!c,this.topics[a].push(e),d},d.prototype.subscribeOnce=function(a,b){return this.subscribe(a,b,!0)},d.prototype.publish=function(a,b){return c(this,a,b,!1)},d.prototype.publishSync=function(a,b){return c(this,a,b,!0)},d.prototype.unsubscribe=function(a){var b,c,d=!1;for(b in this.topics)if(Object.hasOwnProperty.call(this.topics,b)&&this.topics[b]){for(c=this.topics[b].length;c;){if(c-=1,this.topics[b][c].token===a)return this.topics[b].splice(c,1),a;b===a&&(this.topics[b].splice(c,1),d=!0)}if(d===!0)return a}return!1},d.prototype.hasSubscribers=function(a){var b=this.topics;return!!(Object.hasOwnProperty.call(b,a)&&b[a].length>0)},d.prototype.on=a("subscribe"),d.prototype.once=a("subscribeOnce"),d.prototype.trigger=a("publish"),d.prototype.triggerSync=a("publishSync"),d.prototype.off=a("unsubscribe"),d.prototype.has=a("hasSubscribers"),d});
\ No newline at end of file
+
+!function(a,b,c){"use strict";"function"==typeof define&&define.amd?define(c):"undefined"!=typeof module&&module.exports?module.exports=c():b[a]=c()}("PubSub",this,function(){"use strict";function a(a){return function(){return this[a].apply(this,arguments)}}function b(a,b,c){for(var d,e,f=a.topics[b],g=f?f.length:0;g;)g-=1,e=f[g].token,d=f[g],d.callback(c,{name:b,token:e}),d.once===!0&&a.unsubscribe(e)}function c(a,c,d,e){return!!a.topics[c]&&(e?b(a,c,d):setTimeout(function(){b(a,c,d)},0),!0)}function d(){return this.topics={},this.subUid=-1,this}return d.prototype.subscribe=function(a,b,c){var d=this.subUid+=1,e={};if("function"!=typeof b)throw new TypeError("When subscribing for an event, a callback function must be defined.");return this.topics[a]||(this.topics[a]=[]),e.token=d,e.callback=b,e.once=!!c,this.topics[a].push(e),d},d.prototype.subscribeOnce=function(a,b){return this.subscribe(a,b,!0)},d.prototype.publish=function(a,b){return c(this,a,b,!1)},d.prototype.publishSync=function(a,b){return c(this,a,b,!0)},d.prototype.unsubscribe=function(a){var b,c,d=!1;for(b in this.topics)if(Object.hasOwnProperty.call(this.topics,b)&&this.topics[b]){for(c=this.topics[b].length;c;){if(c-=1,this.topics[b][c].token===a)return this.topics[b].splice(c,1),a;b===a&&(this.topics[b].splice(c,1),d=!0)}if(d===!0)return a}return!1},d.prototype.hasSubscribers=function(a){var b=this.topics;return!!(Object.hasOwnProperty.call(b,a)&&b[a].length>0)},d.prototype.unsubscribeAll=function(){var a;for(a in this.topics)Object.hasOwnProperty.call(this.topics,a)&&(this.topics[a]=[]);return this},d.prototype.alias=function(b){var c;for(c in b)Object.hasOwnProperty.call(b,c)&&d.prototype[c]&&(d.prototype[b[c]]=a(c));return this},d});
+//# sourceMappingURL=pubsub.min.js.map
\ No newline at end of file
diff --git a/dist/pubsub.min.js.map b/dist/pubsub.min.js.map
new file mode 100644
index 0000000..ee119ce
--- /dev/null
+++ b/dist/pubsub.min.js.map
@@ -0,0 +1 @@
+{"version":3,"sources":["../src/pubsub.js"],"names":["name","context","definition","define","amd","module","exports","this","alias","fn","apply","arguments","deliverTopic","instance","topic","data","currentSubscriber","token","subscribers","topics","len","length","callback","once","unsubscribe","publish","sync","setTimeout","PubSub","subUid","prototype","subscribe","obj","TypeError","push","subscribeOnce","publishSync","prop","tf","Object","hasOwnProperty","call","splice","hasSubscribers","unsubscribeAll","aliasMap"],"mappings":";;;;;;;;;;;CAUC,SAAUA,EAAMC,EAASC,GACxB,YACsB,mBAAXC,SAAyBA,OAAOC,IACzCD,OAAOD,GACoB,mBAAXG,SAA0BA,OAAOC,QACjDD,OAAOC,QAAUJ,IAEjBD,EAAQD,GAAQE,KAElB,SAAUK,KAAM,WAChB,YAEA,SAASC,GAAMC,GACb,MAAO,YACL,MAAOF,MAAKE,GAAIC,MAAMH,KAAMI,YAIhC,QAASC,GAAaC,EAAUC,EAAOC,GAKrC,IAJA,GAEEC,GAAmBC,EAFjBC,EAAcL,EAASM,OAAOL,GAChCM,EAAMF,EAAcA,EAAYG,OAAS,EAGpCD,GACLA,GAAO,EACPH,EAAQC,EAAYE,GAAKH,MACzBD,EAAoBE,EAAYE,GAEhCJ,EAAkBM,SAASP,GACzBf,KAAMc,EACNG,MAAOA,IAKLD,EAAkBO,QAAS,GAC7BV,EAASW,YAAYP,GAK3B,QAASQ,GAAQZ,EAAUC,EAAOC,EAAMW,GACtC,QAAKb,EAASM,OAAOL,KAIrBY,EAAOd,EAAaC,EAAUC,EAAOC,GAAQY,WAAW,WACtDf,EAAaC,EAAUC,EAAOC,IAC7B,IAEI,GAOT,QAASa,KAGP,MAFArB,MAAKY,UACLZ,KAAKsB,QAAS,EACPtB,KAkPT,MA1NAqB,GAAOE,UAAUC,UAAY,SAAUjB,EAAOQ,EAAUC,GACtD,GAAIN,GAAQV,KAAKsB,QAAU,EACzBG,IAEF,IAAwB,kBAAbV,GACT,KAAM,IAAIW,WAAU,sEAatB,OAVK1B,MAAKY,OAAOL,KACfP,KAAKY,OAAOL,OAGdkB,EAAIf,MAAQA,EACZe,EAAIV,SAAWA,EACfU,EAAIT,OAASA,EAEbhB,KAAKY,OAAOL,GAAOoB,KAAKF,GAEjBf,GAqBTW,EAAOE,UAAUK,cAAgB,SAAUrB,EAAOQ,GAChD,MAAOf,MAAKwB,UAAUjB,EAAOQ,GAAU,IAmBzCM,EAAOE,UAAUL,QAAU,SAAUX,EAAOC,GAC1C,MAAOU,GAAQlB,KAAMO,EAAOC,GAAM,IAmBpCa,EAAOE,UAAUM,YAAc,SAAUtB,EAAOC,GAC9C,MAAOU,GAAQlB,KAAMO,EAAOC,GAAM,IAmBpCa,EAAOE,UAAUN,YAAc,SAAUV,GACvC,GACEuB,GAAMjB,EADJkB,GAAK,CAGT,KAAKD,IAAQ9B,MAAKY,OAChB,GAAIoB,OAAOC,eAAeC,KAAKlC,KAAKY,OAAQkB,IACtC9B,KAAKY,OAAOkB,GAAO,CAGrB,IAFAjB,EAAMb,KAAKY,OAAOkB,GAAMhB,OAEjBD,GAAK,CAIV,GAHAA,GAAO,EAGHb,KAAKY,OAAOkB,GAAMjB,GAAKH,QAAUH,EAEnC,MADAP,MAAKY,OAAOkB,GAAMK,OAAOtB,EAAK,GACvBN,CAILuB,KAASvB,IACXP,KAAKY,OAAOkB,GAAMK,OAAOtB,EAAK,GAC9BkB,GAAK,GAIT,GAAIA,KAAO,EACT,MAAOxB,GAMf,OAAO,GAoBTc,EAAOE,UAAUa,eAAiB,SAAU7B,GAC1C,GAAIK,GAASZ,KAAKY,MAElB,UAAIoB,OAAOC,eAAeC,KAAKtB,EAAQL,IAAUK,EAAOL,GAAOO,OAAS,IAoB1EO,EAAOE,UAAUc,eAAiB,WAChC,GAAIP,EAEJ,KAAKA,IAAQ9B,MAAKY,OACZoB,OAAOC,eAAeC,KAAKlC,KAAKY,OAAQkB,KAC1C9B,KAAKY,OAAOkB,MAIhB,OAAO9B,OAqBTqB,EAAOE,UAAUtB,MAAQ,SAAUqC,GACjC,GAAIR,EAEJ,KAAKA,IAAQQ,GACPN,OAAOC,eAAeC,KAAKI,EAAUR,IACnCT,EAAOE,UAAUO,KACnBT,EAAOE,UAAUe,EAASR,IAAS7B,EAAM6B,GAK/C,OAAO9B,OAGFqB","file":"pubsub.min.js"}
\ No newline at end of file
diff --git a/package.json b/package.json
index 6791e87..0139db2 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "PubSub",
- "version": "2.1.0",
+ "version": "3.0.0",
"description": "Javascript implementation of the Publish/Subscribe pattern.",
"main": "src/pubsub.js",
"scripts": {
diff --git a/src/pubsub.js b/src/pubsub.js
index 8fbb2d3..b6929d6 100644
--- a/src/pubsub.js
+++ b/src/pubsub.js
@@ -2,7 +2,7 @@
* PubSub.js
* Javascript implementation of the Publish/Subscribe pattern.
*
- * @version 2.1.0
+ * @version 3.0.0
* @author George Raptis (georapbox.github.io)
* @homepage https://github.com/georapbox/PubSub#readme
* @repository git+https://github.com/georapbox/PubSub.git
@@ -68,6 +68,7 @@
function PubSub() {
this.topics = {}; // Storage for topics that can be broadcast or listened to.
this.subUid = -1; // A topic identifier.
+ return this;
}
/**
@@ -252,13 +253,62 @@
return false;
};
- // Alias for public methods.
- PubSub.prototype.on = alias('subscribe');
- PubSub.prototype.once = alias('subscribeOnce');
- PubSub.prototype.trigger = alias('publish');
- PubSub.prototype.triggerSync = alias('publishSync');
- PubSub.prototype.off = alias('unsubscribe');
- PubSub.prototype.has = alias('hasSubscribers');
+ /**
+ * Clears all subscriptions whatsoever.
+ *
+ * @memberof PubSub
+ * @this {PubSub}
+ * @return {PubSub} The PubSub instance.
+ * @example
+ *
+ * var pubsub = new PubSub();
+ * ...
+ * ...
+ * pubsub.unsubscribeAll();
+ */
+ PubSub.prototype.unsubscribeAll = function () {
+ var prop;
+
+ for (prop in this.topics) {
+ if (Object.hasOwnProperty.call(this.topics, prop)) {
+ this.topics[prop] = [];
+ }
+ }
+
+ return this;
+ };
+
+ /**
+ * Creates aliases for public methods.
+ *
+ * @memberof PubSub
+ * @this {PubSub}
+ * @param {object} aliasMap A plain object that maps the public methods to their aliases.
+ * @return {PubSub} The PubSub instance.
+ * @example
+ *
+ * var pubsub = new PubSub().alias({
+ * subscribe: 'on',
+ * subscribeOnce: 'once',
+ * publish: 'trigger',
+ * publishSync: 'triggerSync',
+ * unsubscribe: 'off',
+ * hasSubscribers: 'has'
+ * });
+ */
+ PubSub.prototype.alias = function (aliasMap) {
+ var prop;
+
+ for (prop in aliasMap) {
+ if (Object.hasOwnProperty.call(aliasMap, prop)) {
+ if (PubSub.prototype[prop]) {
+ PubSub.prototype[aliasMap[prop]] = alias(prop);
+ }
+ }
+ }
+
+ return this;
+ };
return PubSub;
}));
diff --git a/tests/pubsub.specs.js b/tests/pubsub.specs.js
index a2d6bc6..753a053 100644
--- a/tests/pubsub.specs.js
+++ b/tests/pubsub.specs.js
@@ -104,3 +104,39 @@ describe('Check if there are subscribers for a specific topic.', function () {
expect(ps.hasSubscribers('message')).toBe(false);
});
});
+
+// Clear all subscriptions at once.
+describe('Clears all subscriptions at once', function () {
+ it('Should unsubscribe from all subscriptions', function () {
+ var ps = new PubSub();
+ var listener = function listener() {}
+
+ // Subscribe to some events
+ ps.subscribe('eventA', listener);
+ ps.subscribe('eventB', listener);
+ ps.subscribe('eventC', listener);
+ ps.subscribeOnce('eventA', listener);
+ ps.subscribeOnce('eventB', listener);
+ ps.subscribeOnce('eventC', listener);
+
+ // Unsubscribe from all
+ ps.unsubscribeAll();
+
+ expect(ps.hasSubscribers('eventA')).toBe(false);
+ expect(ps.hasSubscribers('eventB')).toBe(false);
+ expect(ps.hasSubscribers('eventC')).toBe(false);
+ });
+});
+
+// Alias methods
+describe('Public methods alias', function () {
+ it('Should create aliases "on" and "off" for "subscribe" and "unsubscribe" methods respectively', function () {
+ var ps = new PubSub().alias({
+ subscribe: 'on',
+ unsubscribe: 'off'
+ });
+
+ expect(PubSub.prototype.on).not.toBeUndefined();
+ expect(PubSub.prototype.off).not.toBeUndefined();
+ });
+});