Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

mediator-js

Package Overview
Dependencies
Maintainers
1
Versions
12
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

mediator-js - npm Package Compare versions

Comparing version 0.10.1 to 0.11.0

145

lib/mediator.js
/*jslint bitwise: true, nomen: true, plusplus: true, white: true */
/*!
* Mediator.js Library v0.10.1
* Mediator.js Library v0.11.0
* https://github.com/ajacksified/Mediator.js

@@ -78,2 +78,7 @@ *

// A Mediator channel holds a list of sub-channels and subscribers to be fired
// when Mediator.publish is called on the Mediator instance. It also contains
// some methods to manipulate its lists of data; only setPriority and
// StopPropagation are meant to be used. The other methods should be accessed
// through the Mediator instance.

@@ -92,26 +97,32 @@ function Channel(namespace, parent) {

// A Mediator channel holds a list of sub-channels and subscribers to be fired
// when Mediator.publish is called on the Mediator instance. It also contains
// some methods to manipulate its lists of data; only setPriority and
// StopPropagation are meant to be used. The other methods should be accessed
// through the Mediator instance.
Channel.prototype.addSubscriber = function(fn, options, context) {
var subscriber = new Subscriber(fn, options, context);
// Sort function for sorting the channels based on their priority. The sort will
// place the channel with the highest priority in the first place of the array,
// all other channels will be added in descending order. i.g. a channel with a
// priority of 9 will be placed before a channel with a priority of 3
Channel.prototype.channelPrioritySort = function(a, b) {
if (a.options.priority > b.options.priority) {
return -1;
} else if (a.options.priority < b.options.priority) {
return 1;
}
return 0;
};
if (options && options.priority !== undefined) {
// Cheap hack to either parse as an int or turn it into 0. Runs faster
// in many browsers than parseInt with the benefit that it won't
// return a NaN.
options.priority = options.priority >> 0;
Channel.prototype.addSubscriber = function(fn, options, context){
// Make sure there is always an options object
if (!options) {
options = { priority: 0 };
}
if (options.priority < 0) { options.priority = 0; }
if (options.priority >= this._subscribers.length) { options.priority = this._subscribers.length-1; }
// Cheap hack to either parse as an int or turn it into 0. Runs faster
// in many browsers than parseInt with the benefit that it won't
// return a NaN.
options.priority = options.priority | 0;
this._subscribers.splice(options.priority, 0, subscriber);
}else{
this._subscribers.push(subscriber);
}
var subscriber = new Subscriber(fn, options, context);
subscriber.channel = this;
this._subscribers.push(subscriber);
this._subscribers.sort(this.channelPrioritySort);
return subscriber;

@@ -143,19 +154,13 @@ }

Channel.prototype.setPriority = function(identifier, priority) {
var oldIndex = 0,
x = 0,
sub, firstHalf, lastHalf, y;
var x = 0,
y = this._subscribers.length;
for(x = 0, y = this._subscribers.length; x < y; x++) {
if (this._subscribers[x].id === identifier || this._subscribers[x].fn === identifier) {
for(; x<y; x++) {
if (this._subscribers[x].id === identifier || this._subscribers[x].fn === identifier){
this._subscribers[x].priority = priority;
break;
}
oldIndex ++;
}
sub = this._subscribers[oldIndex];
firstHalf = this._subscribers.slice(0, oldIndex);
lastHalf = this._subscribers.slice(oldIndex+1);
this._subscribers = firstHalf.concat(lastHalf);
this._subscribers.splice(priority, 0, sub);
this._subscribers.sort(this.channelPrioritySort);
}

@@ -175,6 +180,28 @@

Channel.prototype.removeSubscriber = function(identifier) {
Channel.prototype.removeSubscriber = function(identifier, autoCleanup) {
var x = this._subscribers.length - 1;
autoCleanup = (typeof autoCleanup === 'undefined') ? true : autoCleanup;
// If we don't pass in an id, we're clearing all
if(!identifier){
this._subscribers = [];
} else {
// Going backwards makes splicing a whole lot easier.
for(x; x >= 0; x--) {
if(this._subscribers[x].fn === identifier || this._subscribers[x].id === identifier){
this._subscribers[x].channel = null;
this._subscribers.splice(x,1);
}
}
}
// Check if we should attempt to automatically clean up the channel
if (autoCleanup) {
this.autoCleanChannel();
}
var x = this._subscribers.length - 1;
// If we don't pass in an id, we're clearing all
if (!identifier) {

@@ -194,5 +221,47 @@ this._subscribers = [];

// This will publish arbitrary arguments to a subscriber and then to parent
// channels.
Channel.prototype.autoCleanChannel = function() {
// First make sure there are no more subscribers, if there are we
// can stop processing the channel any further
if (this._subscribers.length !== 0) {
return;
}
// Next we need to make sure there are no more sub-channels that
// have this channel as its parent channel. We try to iterate over the
// properties of _channels and as soon as we find a property we've
// set we will stop processing the channel any further
for (var key in this._channels) {
if (this._channels.hasOwnProperty(key)) {
return;
}
}
// The last check before we can remove the channel is to see if it
// has a parent. If there is no parent we don't want to remove this
// channel
if (this._parent != null) {
// We need the ID by which this channel is known to its parent, it should
// be the last part of the namespace. We need split the namespace up and
// take its last element to pass along to the removeChannel method
var path = this.namespace.split(':'),
channelName = path[path.length - 1];
// The parent of the current channel to remove this channel
this._parent.removeChannel(channelName);
}
}
Channel.prototype.removeChannel = function(channelName) {
if (this.hasChannel(channelName)) {
this._channels[channelName] = null;
delete this._channels[channelName];
// After removing a sub-channel we can check if that makes this channel
// suitable for auto clean up
this.autoCleanChannel();
}
};
// This will publish arbitrary arguments to a subscriber and then to parent
// channels.
Channel.prototype.publish = function(data) {

@@ -341,4 +410,5 @@ var x = 0,

Mediator.prototype.remove = function(channelName, identifier) {
Mediator.prototype.remove = function(channelName, identifier, autoClean) {
var channel = this.getChannel(channelName || "", true);
if (channel.namespace !== channelName) {

@@ -348,5 +418,6 @@ return false;

channel.removeSubscriber(identifier);
channel.removeSubscriber(identifier, autoClean);
}
// Publishes arbitrary data to a given channel namespace. Channels are

@@ -353,0 +424,0 @@ // called recursively downwards; a post to application:chat will post to

/*!
* Mediator.js Library v0.10.1
* Mediator.js Library v0.11.0
* https://github.com/ajacksified/Mediator.js

@@ -13,2 +13,2 @@ *

*/
!function(t,s){"use strict";"function"==typeof define&&define.amd?define([],function(){return t.Mediator=s(),t.Mediator}):"undefined"!=typeof exports?exports.Mediator=s():t.Mediator=s()}(this,function(){"use strict";function t(s,i,e){if(!(this instanceof t))return new t(s,i,e);var r;this.id=(r=function(){return(65536*(1+Math.random())|0).toString(16).substring(1)})()+r()+"-"+r()+"-"+r()+"-"+r()+"-"+r()+r()+r(),this.fn=s,this.options=i,this.context=e,this.channel=null}function s(t,i){if(!(this instanceof s))return new s(t);this.namespace=t||"",this._subscribers=[],this._channels={},this._parent=i,this.stopped=!1}function i(){if(!(this instanceof i))return new i;this._channels=new s("")}return t.prototype.update=function(t){t&&(this.fn=t.fn||this.fn,this.context=t.context||this.context,this.options=t.options||this.options,this.channel&&this.options&&void 0!==this.options.priority&&this.channel.setPriority(this.id,this.options.priority))},s.prototype.addSubscriber=function(s,i,e){var r=new t(s,i,e);return i&&void 0!==i.priority?(i.priority=i.priority>>0,i.priority<0&&(i.priority=0),i.priority>=this._subscribers.length&&(i.priority=this._subscribers.length-1),this._subscribers.splice(i.priority,0,r)):this._subscribers.push(r),r.channel=this,r},s.prototype.stopPropagation=function(){this.stopped=!0},s.prototype.getSubscriber=function(t){for(var s=0,i=this._subscribers.length;s<i;s++)if(this._subscribers[s].id===t||this._subscribers[s].fn===t)return this._subscribers[s]},s.prototype.setPriority=function(t,s){var i,e,r,n,o=0,p=0;for(p=0,n=this._subscribers.length;p<n&&(this._subscribers[p].id!==t&&this._subscribers[p].fn!==t);p++)o++;i=this._subscribers[o],e=this._subscribers.slice(0,o),r=this._subscribers.slice(o+1),this._subscribers=e.concat(r),this._subscribers.splice(s,0,i)},s.prototype.addChannel=function(t){this._channels[t]=new s((this.namespace?this.namespace+":":"")+t,this)},s.prototype.hasChannel=function(t){return this._channels.hasOwnProperty(t)},s.prototype.returnChannel=function(t){return this._channels[t]},s.prototype.removeSubscriber=function(t){var s=this._subscribers.length-1;if(t)for(;s>=0;s--)this._subscribers[s].fn!==t&&this._subscribers[s].id!==t||(this._subscribers[s].channel=null,this._subscribers.splice(s,1));else this._subscribers=[]},s.prototype.publish=function(t){for(var s,i,e,r=0,n=this._subscribers.length,o=!1;r<n;r++)o=!1,s=this._subscribers[r],this.stopped||(i=this._subscribers.length,void 0!==s.options&&"function"==typeof s.options.predicate?s.options.predicate.apply(s.context,t)&&(o=!0):o=!0),o&&(s.options&&void 0!==s.options.calls&&(s.options.calls--,s.options.calls<1&&this.removeSubscriber(s.id)),s.fn.apply(s.context,t),n=e=this._subscribers.length,e===i-1&&r--);this._parent&&this._parent.publish(t),this.stopped=!1},i.prototype.getChannel=function(t,s){var i=this._channels,e=t.split(":"),r=0,n=e.length;if(""===t)return i;if(e.length>0)for(;r<n;r++){if(!i.hasChannel(e[r])){if(s)break;i.addChannel(e[r])}i=i.returnChannel(e[r])}return i},i.prototype.subscribe=function(t,s,i,e){return i=i||{},e=e||{},this.getChannel(t||"",!1).addSubscriber(s,i,e)},i.prototype.once=function(t,s,i,e){return(i=i||{}).calls=1,this.subscribe(t,s,i,e)},i.prototype.getSubscriber=function(t,s){var i=this.getChannel(s||"",!0);return i.namespace!==s?null:i.getSubscriber(t)},i.prototype.remove=function(t,s){var i=this.getChannel(t||"",!0);if(i.namespace!==t)return!1;i.removeSubscriber(s)},i.prototype.publish=function(t){var s=this.getChannel(t||"",!1);if(s.namespace!==t)return null;var i=Array.prototype.slice.call(arguments,1);i.push(s),s.publish(i)},i.prototype.on=i.prototype.subscribe,i.prototype.bind=i.prototype.subscribe,i.prototype.emit=i.prototype.publish,i.prototype.trigger=i.prototype.publish,i.prototype.off=i.prototype.remove,i.Channel=s,i.Subscriber=t,i.version="0.10.1",i});
!function(t,s){"use strict";"function"==typeof define&&define.amd?define([],function(){return t.Mediator=s(),t.Mediator}):"undefined"!=typeof exports?exports.Mediator=s():t.Mediator=s()}(this,function(){"use strict";function t(s,i,e){if(!(this instanceof t))return new t(s,i,e);var n;this.id=(n=function(){return(65536*(1+Math.random())|0).toString(16).substring(1)})()+n()+"-"+n()+"-"+n()+"-"+n()+"-"+n()+n()+n(),this.fn=s,this.options=i,this.context=e,this.channel=null}function s(t,i){if(!(this instanceof s))return new s(t);this.namespace=t||"",this._subscribers=[],this._channels={},this._parent=i,this.stopped=!1}function i(){if(!(this instanceof i))return new i;this._channels=new s("")}return t.prototype.update=function(t){t&&(this.fn=t.fn||this.fn,this.context=t.context||this.context,this.options=t.options||this.options,this.channel&&this.options&&void 0!==this.options.priority&&this.channel.setPriority(this.id,this.options.priority))},s.prototype.channelPrioritySort=function(t,s){return t.options.priority>s.options.priority?-1:t.options.priority<s.options.priority?1:0},s.prototype.addSubscriber=function(s,i,e){i||(i={priority:0}),i.priority=0|i.priority;var n=new t(s,i,e);return n.channel=this,this._subscribers.push(n),this._subscribers.sort(this.channelPrioritySort),n},s.prototype.stopPropagation=function(){this.stopped=!0},s.prototype.getSubscriber=function(t){for(var s=0,i=this._subscribers.length;s<i;s++)if(this._subscribers[s].id===t||this._subscribers[s].fn===t)return this._subscribers[s]},s.prototype.setPriority=function(t,s){for(var i=0,e=this._subscribers.length;i<e;i++)if(this._subscribers[i].id===t||this._subscribers[i].fn===t){this._subscribers[i].priority=s;break}this._subscribers.sort(this.channelPrioritySort)},s.prototype.addChannel=function(t){this._channels[t]=new s((this.namespace?this.namespace+":":"")+t,this)},s.prototype.hasChannel=function(t){return this._channels.hasOwnProperty(t)},s.prototype.returnChannel=function(t){return this._channels[t]},s.prototype.removeSubscriber=function(t,s){var i=this._subscribers.length-1;if(s=void 0===s||s,t)for(;i>=0;i--)this._subscribers[i].fn!==t&&this._subscribers[i].id!==t||(this._subscribers[i].channel=null,this._subscribers.splice(i,1));else this._subscribers=[];s&&this.autoCleanChannel();i=this._subscribers.length-1;if(t)for(;i>=0;i--)this._subscribers[i].fn!==t&&this._subscribers[i].id!==t||(this._subscribers[i].channel=null,this._subscribers.splice(i,1));else this._subscribers=[]},s.prototype.autoCleanChannel=function(){if(0===this._subscribers.length){for(var t in this._channels)if(this._channels.hasOwnProperty(t))return;if(null!=this._parent){var s=this.namespace.split(":"),i=s[s.length-1];this._parent.removeChannel(i)}}},s.prototype.removeChannel=function(t){this.hasChannel(t)&&(this._channels[t]=null,delete this._channels[t],this.autoCleanChannel())},s.prototype.publish=function(t){for(var s,i,e,n=0,r=this._subscribers.length,o=!1;n<r;n++)o=!1,s=this._subscribers[n],this.stopped||(i=this._subscribers.length,void 0!==s.options&&"function"==typeof s.options.predicate?s.options.predicate.apply(s.context,t)&&(o=!0):o=!0),o&&(s.options&&void 0!==s.options.calls&&(s.options.calls--,s.options.calls<1&&this.removeSubscriber(s.id)),s.fn.apply(s.context,t),r=e=this._subscribers.length,e===i-1&&n--);this._parent&&this._parent.publish(t),this.stopped=!1},i.prototype.getChannel=function(t,s){var i=this._channels,e=t.split(":"),n=0,r=e.length;if(""===t)return i;if(e.length>0)for(;n<r;n++){if(!i.hasChannel(e[n])){if(s)break;i.addChannel(e[n])}i=i.returnChannel(e[n])}return i},i.prototype.subscribe=function(t,s,i,e){return i=i||{},e=e||{},this.getChannel(t||"",!1).addSubscriber(s,i,e)},i.prototype.once=function(t,s,i,e){return(i=i||{}).calls=1,this.subscribe(t,s,i,e)},i.prototype.getSubscriber=function(t,s){var i=this.getChannel(s||"",!0);return i.namespace!==s?null:i.getSubscriber(t)},i.prototype.remove=function(t,s,i){var e=this.getChannel(t||"",!0);if(e.namespace!==t)return!1;e.removeSubscriber(s,i)},i.prototype.publish=function(t){var s=this.getChannel(t||"",!1);if(s.namespace!==t)return null;var i=Array.prototype.slice.call(arguments,1);i.push(s),s.publish(i)},i.prototype.on=i.prototype.subscribe,i.prototype.bind=i.prototype.subscribe,i.prototype.emit=i.prototype.publish,i.prototype.trigger=i.prototype.publish,i.prototype.off=i.prototype.remove,i.Channel=s,i.Subscriber=t,i.version="0.10.1",i});
{
"name": "mediator-js",
"version": "0.10.1",
"version": "0.11.0",
"description": "Flexible event management. Implementation of the mediator pattern.",

@@ -5,0 +5,0 @@ "author": "Jack Lawson <jlawson@olivinelabs.com>",

@@ -5,3 +5,3 @@ Mediator.js

Version 0.9.8
Version 0.11.0

@@ -209,2 +209,15 @@ * [View the documentation](http://thejacklawson.com/Mediator.js/)

__Version 0.11.0__
* Accepted PRs that:
* [Make channel priority more sane](https://github.com/ajacksified/Mediator.js/pull/37)
* [Add automatic cleanup of channels](https://github.com/ajacksified/Mediator.js/pull/35)
(note - this was changed to opt-out, with the minor version bump.)
__Version 0.10.1__
* Accepted a PR that fixed some AMD require issues, and allowed upwards-
recursing events to fire on events even where the most-specific event
is not fired (a listener on "application:chat:message" will fire on an event
like "application:chat:message:jack", even if there's no matching listenener
on "jack".) https://github.com/ajacksified/Mediator.js/pull/45
__Version 0.9.8__

@@ -211,0 +224,0 @@ * Accepted a ton of PRs from [tbusser](https://github.com/tbusser) that fixed

@@ -70,11 +70,10 @@ var Mediator = require("../index").Mediator,

spy2 = sinon.spy(),
spy3 = sinon.spy();
spy3 = sinon.spy(),
idA = channel.addSubscriber(spy, { priority: 1}).id,
idB = channel.addSubscriber(spy2).id,
idC = channel.addSubscriber(spy3, { priority: 3 }).id;
channel.addSubscriber(spy);
channel.addSubscriber(spy2);
channel.addSubscriber(spy3, { priority: 1 });
expect(channel._subscribers[0].fn).to.equal(spy);
expect(channel._subscribers[1].fn).to.equal(spy3);
expect(channel._subscribers[2].fn).to.equal(spy2);
expect(channel._subscribers[0].id).to.equal(idC);
expect(channel._subscribers[1].id).to.equal(idA);
expect(channel._subscribers[2].id).to.equal(idB);
});

@@ -91,4 +90,4 @@

expect(channel._subscribers[0].fn).to.equal(spy);
expect(channel._subscribers[1].fn).to.equal(spy3);
expect(channel._subscribers[0].fn).to.equal(spy3);
expect(channel._subscribers[1].fn).to.equal(spy);
expect(channel._subscribers[2].fn).to.equal(spy2);

@@ -100,14 +99,22 @@ });

spy2 = sinon.spy(),
spy3 = sinon.spy();
spy3 = sinon.spy(),
idA = channel.addSubscriber(spy, { num: 1 }).id,
idB = channel.addSubscriber(spy2, { num: 2 }).id,
idC = channel.addSubscriber(spy3, { num: 3 }).id;
var sub = channel.addSubscriber(spy, { num: 1 });
channel.addSubscriber(spy2, { num: 2 });
channel.addSubscriber(spy3, { num: 3 });
channel.setPriority(idA, 2);
channel.setPriority(sub.id, 2);
expect(channel._subscribers[0].id).to.equal(idA);
expect(channel._subscribers[1].id).to.equal(idB);
expect(channel._subscribers[2].id).to.equal(idC);
expect(channel._subscribers[0].fn).to.equal(spy2);
expect(channel._subscribers[1].fn).to.equal(spy3);
expect(channel._subscribers[2].fn).to.equal(spy);
});
it("should keep the priorities as initially set (issue #15)", function() {
var spy = sinon.spy(),
spy2 = sinon.spy(),
idA = channel.addSubscriber(spy, {priority: 9}).id,
idB = channel.addSubscriber(spy, {priority: 1}).id;
expect(channel._subscribers[0].id).to.equal(idA);
expect(channel._subscribers[1].id).to.equal(idB);
});

@@ -190,3 +197,3 @@ });

spy3 = sinon.spy();
channel.addSubscriber(spy);

@@ -197,3 +204,3 @@ var sub2 = channel.addSubscriber(spy2);

expect(channel._subscribers.length).to.equal(3);
channel.removeSubscriber(sub2.id);

@@ -227,2 +234,79 @@ expect(channel._subscribers.length).to.equal(2);

});
describe("autoCleanChannel", function() {
it("should utomatically clean channels when the parameter is not specified", function() {
var spy = sinon.spy();
channel.addChannel('sub1');
var subChannel = channel.returnChannel('sub1'),
subscriber = subChannel.addSubscriber(spy);
subChannel.removeSubscriber(subscriber.id);
expect(channel._channels['sub1']).to.be.undefined;
});
it("should NOT automatically clean channels when the parameter is false", function() {
var spy = sinon.spy();
channel.addChannel('sub1');
var subChannel = channel.returnChannel('sub1'),
subscriber = subChannel.addSubscriber(spy);
subChannel.removeSubscriber(subscriber.id, false);
expect(channel._channels['sub1']).to.not.be.undefined;
});
it("should automatically clean channels when the parameter is true", function() {
var spy = sinon.spy();
channel.addChannel('sub1');
var subChannel = channel.returnChannel('sub1'),
subscriber = subChannel.addSubscriber(spy);
subChannel.removeSubscriber(subscriber.id, true);
expect(channel._channels['sub1']).to.be.undefined;
});
it("should automatically clean channels and empty parent channels", function() {
var spy = sinon.spy();
channel.addChannel('sub1');
var subChannel = channel.returnChannel('sub1');
subChannel.addChannel('sub2');
var subChannel2 = subChannel.returnChannel('sub2'),
subscriber = subChannel2.addSubscriber(spy);
subChannel2.removeSubscriber(subscriber.id, true);
expect(subChannel._channels['sub2']).to.be.undefined;
expect(channel._channels['sub1']).to.be.undefined;
});
it("should NOT automatically clean channels when there are still other subscribers", function() {
var spy = sinon.spy(),
spy2 = sinon.spy();
channel.addChannel('sub1');
var subChannel = channel.returnChannel('sub1'),
subscriber = subChannel.addSubscriber(spy),
subscriber2 = subChannel.addSubscriber(spy2);
subChannel.removeSubscriber(subscriber.id, true);
expect(channel._channels['sub1']).to.not.be.undefined;
});
it("should NOT automatically clean channels when the channel has sub-channels", function() {
var spy = sinon.spy();
channel.addChannel('sub1');
var subChannel = channel.returnChannel('sub1'),
subscriber = subChannel.addSubscriber(spy);
subChannel.addChannel('sub2');
subChannel.removeSubscriber(subscriber.id, true);
expect(channel._channels['sub1']).to.not.be.undefined;
expect(subChannel._channels['sub2']).to.not.be.undefined;
});
});
});

@@ -277,3 +361,3 @@

});
it("should call all matching subscribers with context", function(){

@@ -288,3 +372,3 @@ var spy = sinon.spy(),

});
it("should call subscribers in predefined priority", function(){

@@ -291,0 +375,0 @@ var sub1 = function(){

@@ -271,3 +271,3 @@ var Mediator = require("../index").Mediator,

sub2.update({ options: { priority: 0 } });
sub2.update({ options: { priority: 1 } });

@@ -274,0 +274,0 @@ expect(mediator.getChannel("test")._subscribers[0].id).to.equal(sub2.id);

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc