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.9.8 to 0.9.9

426

lib/mediator.js

@@ -19,3 +19,3 @@ /*jslint bitwise: true, nomen: true, plusplus: true, white: true */

if(typeof define === 'function' && define.amd) {
if (typeof define === 'function' && define.amd) {
// AMD

@@ -53,4 +53,4 @@ define('mediator-js', [], function() {

function Subscriber(fn, options, context){
if(!(this instanceof Subscriber)) {
function Subscriber(fn, options, context) {
if (!(this instanceof Subscriber)) {
return new Subscriber(fn, options, context);

@@ -66,22 +66,19 @@ }

Subscriber.prototype = {
// Mediator.update on a subscriber instance can update its function,context,
// or options object. It takes in an object and looks for fn, context, or
// options keys.
update: function(options){
if(options){
this.fn = options.fn || this.fn;
this.context = options.context || this.context;
this.options = options.options || this.options;
if(this.channel && this.options && this.options.priority !== undefined) {
this.channel.setPriority(this.id, this.options.priority);
}
// Mediator.update on a subscriber instance can update its function,context,
// or options object. It takes in an object and looks for fn, context, or
// options keys.
Subscriber.prototype.update = function(options) {
if (options) {
this.fn = options.fn || this.fn;
this.context = options.context || this.context;
this.options = options.options || this.options;
if (this.channel && this.options && this.options.priority !== undefined) {
this.channel.setPriority(this.id, this.options.priority);
}
}
};
}
function Channel(namespace, parent){
if(!(this instanceof Channel)) {
function Channel(namespace, parent) {
if (!(this instanceof Channel)) {
return new Channel(namespace);

@@ -102,97 +99,95 @@ }

// through the Mediator instance.
Channel.prototype.addSubscriber = function(fn, options, context) {
var subscriber = new Subscriber(fn, options, context);
Channel.prototype = {
addSubscriber: function(fn, options, context){
var subscriber = new Subscriber(fn, options, context);
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;
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;
if (options.priority < 0) { options.priority = 0; }
if (options.priority >= this._subscribers.length) { options.priority = this._subscribers.length-1; }
if(options.priority < 0){ options.priority = 0; }
if(options.priority >= this._subscribers.length){ options.priority = this._subscribers.length-1; }
this._subscribers.splice(options.priority, 0, subscriber);
}else{
this._subscribers.push(subscriber);
}
this._subscribers.splice(options.priority, 0, subscriber);
}else{
this._subscribers.push(subscriber);
}
subscriber.channel = this;
subscriber.channel = this;
return subscriber;
}
return subscriber;
},
// The channel instance is passed as an argument to the mediator subscriber,
// and further subscriber propagation can be called with
// channel.StopPropagation().
Channel.prototype.stopPropagation = function() {
this.stopped = true;
}
// The channel instance is passed as an argument to the mediator subscriber,
// and further subscriber propagation can be called with
// channel.StopPropagation().
stopPropagation: function(){
this.stopped = true;
},
Channel.prototype.getSubscriber = function(identifier) {
var x = 0,
y = this._subscribers.length;
getSubscriber: function(identifier){
var x = 0,
y = this._subscribers.length;
for(x, y; x < y; x++){
if(this._subscribers[x].id === identifier || this._subscribers[x].fn === identifier){
return this._subscribers[x];
}
for(x, y; x < y; x++) {
if (this._subscribers[x].id === identifier || this._subscribers[x].fn === identifier) {
return this._subscribers[x];
}
},
}
}
// Channel.setPriority is useful in updating the order in which Subscribers
// are called, and takes an identifier (subscriber id or named function) and
// an array index. It will not search recursively through subchannels.
// Channel.setPriority is useful in updating the order in which Subscribers
// are called, and takes an identifier (subscriber id or named function) and
// an array index. It will not search recursively through subchannels.
setPriority: function(identifier, priority){
var oldIndex = 0,
x = 0,
sub, firstHalf, lastHalf, y;
Channel.prototype.setPriority = function(identifier, priority) {
var oldIndex = 0,
x = 0,
sub, firstHalf, lastHalf, y;
for(x = 0, y = this._subscribers.length; x < y; x++){
if(this._subscribers[x].id === identifier || this._subscribers[x].fn === identifier){
break;
}
oldIndex ++;
for(x = 0, y = this._subscribers.length; x < y; x++) {
if (this._subscribers[x].id === identifier || this._subscribers[x].fn === identifier) {
break;
}
oldIndex ++;
}
sub = this._subscribers[oldIndex];
firstHalf = this._subscribers.slice(0, oldIndex);
lastHalf = this._subscribers.slice(oldIndex+1);
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 = firstHalf.concat(lastHalf);
this._subscribers.splice(priority, 0, sub);
}
addChannel: function(channel){
this._channels[channel] = new Channel((this.namespace ? this.namespace + ':' : '') + channel, this);
},
Channel.prototype.addChannel = function(channel) {
this._channels[channel] = new Channel((this.namespace ? this.namespace + ':' : '') + channel, this);
}
hasChannel: function(channel){
return this._channels.hasOwnProperty(channel);
},
Channel.prototype.hasChannel = function(channel) {
return this._channels.hasOwnProperty(channel);
}
returnChannel: function(channel){
return this._channels[channel];
},
Channel.prototype.returnChannel = function(channel) {
return this._channels[channel];
}
removeSubscriber: function(identifier){
var x = this._subscribers.length - 1;
Channel.prototype.removeSubscriber = function(identifier) {
var x = this._subscribers.length - 1;
// If we don't pass in an id, we're clearing all
if(!identifier){
this._subscribers = [];
return;
}
// If we don't pass in an id, we're clearing all
if (!identifier) {
this._subscribers = [];
return;
}
// 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);
}
// 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);
}
},
}
}

@@ -202,61 +197,60 @@ // This will publish arbitrary arguments to a subscriber and then to parent

publish: function(data){
var x = 0,
y = this._subscribers.length,
shouldCall = false,
subscriber, l,
subsBefore,subsAfter;
Channel.prototype.publish = function(data) {
var x = 0,
y = this._subscribers.length,
shouldCall = false,
subscriber, l,
subsBefore,subsAfter;
// Priority is preserved in the _subscribers index.
for(x, y; x < y; x++) {
// By default set the flag to false
shouldCall = false;
subscriber = this._subscribers[x];
// Priority is preserved in the _subscribers index.
for(x, y; x < y; x++) {
// By default set the flag to false
shouldCall = false;
subscriber = this._subscribers[x];
if(!this.stopped){
subsBefore = this._subscribers.length;
if(subscriber.options !== undefined && typeof subscriber.options.predicate === "function"){
if(subscriber.options.predicate.apply(subscriber.context, data)){
// The predicate matches, the callback function should be called
shouldCall = true;
}
}else{
// There is no predicate to match, the callback should always be called
if (!this.stopped) {
subsBefore = this._subscribers.length;
if (subscriber.options !== undefined && typeof subscriber.options.predicate === "function") {
if (subscriber.options.predicate.apply(subscriber.context, data)) {
// The predicate matches, the callback function should be called
shouldCall = true;
}
}else{
// There is no predicate to match, the callback should always be called
shouldCall = true;
}
}
// Check if the callback should be called
if(shouldCall) {
// Check if the subscriber has options and if this include the calls options
if (subscriber.options && subscriber.options.calls !== undefined){
// Decrease the number of calls left by one
subscriber.options.calls--;
// Once the number of calls left reaches zero or less we need to remove the subscriber
if(subscriber.options.calls < 1){
this.removeSubscriber(subscriber.id);
}
// Check if the callback should be called
if (shouldCall) {
// Check if the subscriber has options and if this include the calls options
if (subscriber.options && subscriber.options.calls !== undefined) {
// Decrease the number of calls left by one
subscriber.options.calls--;
// Once the number of calls left reaches zero or less we need to remove the subscriber
if (subscriber.options.calls < 1) {
this.removeSubscriber(subscriber.id);
}
// Now we call the callback, if this in turns publishes to the same channel it will no longer
// cause the callback to be called as we just removed it as a subscriber
subscriber.fn.apply(subscriber.context, data);
}
// Now we call the callback, if this in turns publishes to the same channel it will no longer
// cause the callback to be called as we just removed it as a subscriber
subscriber.fn.apply(subscriber.context, data);
subsAfter = this._subscribers.length;
y = subsAfter;
if (subsAfter === subsBefore - 1){
x--;
}
subsAfter = this._subscribers.length;
y = subsAfter;
if (subsAfter === subsBefore - 1) {
x--;
}
}
}
if(this._parent){
this._parent.publish(data);
}
this.stopped = false;
if (this._parent) {
this._parent.publish(data);
}
};
this.stopped = false;
}
function Mediator() {
if(!(this instanceof Mediator)) {
if (!(this instanceof Mediator)) {
return new Mediator();

@@ -271,108 +265,104 @@ }

Mediator.prototype = {
// Returns a channel instance based on namespace, for example
// application:chat:message:received. If readOnly is true we
// will refrain from creating non existing channels.
Mediator.prototype.getChannel = function(namespace, readOnly) {
var channel = this._channels,
namespaceHierarchy = namespace.split(':'),
x = 0,
y = namespaceHierarchy.length;
// Returns a channel instance based on namespace, for example
// application:chat:message:received. If readOnly is true we
// will refrain from creating non existing channels.
if (namespace === '') {
return channel;
}
getChannel: function(namespace, readOnly){
var channel = this._channels,
namespaceHierarchy = namespace.split(':'),
x = 0,
y = namespaceHierarchy.length;
if (namespaceHierarchy.length > 0) {
for(x, y; x < y; x++) {
if(namespace === ''){
return channel;
}
if(namespaceHierarchy.length > 0){
for(x, y; x < y; x++){
if(!channel.hasChannel(namespaceHierarchy[x])){
if (readOnly) {
break;
} else {
channel.addChannel(namespaceHierarchy[x]);
}
if (!channel.hasChannel(namespaceHierarchy[x])) {
if (readOnly) {
break;
} else {
channel.addChannel(namespaceHierarchy[x]);
}
}
channel = channel.returnChannel(namespaceHierarchy[x]);
}
channel = channel.returnChannel(namespaceHierarchy[x]);
}
}
return channel;
},
return channel;
}
// Pass in a channel namespace, function to be called, options, and context
// to call the function in to Subscribe. It will create a channel if one
// does not exist. Options can include a predicate to determine if it
// should be called (based on the data published to it) and a priority
// index.
// Pass in a channel namespace, function to be called, options, and context
// to call the function in to Subscribe. It will create a channel if one
// does not exist. Options can include a predicate to determine if it
// should be called (based on the data published to it) and a priority
// index.
subscribe: function(channelName, fn, options, context){
var channel = this.getChannel(channelName || "", false);
Mediator.prototype.subscribe = function(channelName, fn, options, context) {
var channel = this.getChannel(channelName || "", false);
options = options || {};
context = context || {};
options = options || {};
context = context || {};
return channel.addSubscriber(fn, options, context);
},
return channel.addSubscriber(fn, options, context);
}
// Pass in a channel namespace, function to be called, options, and context
// to call the function in to Subscribe. It will create a channel if one
// does not exist. Options can include a predicate to determine if it
// should be called (based on the data published to it) and a priority
// index.
// Pass in a channel namespace, function to be called, options, and context
// to call the function in to Subscribe. It will create a channel if one
// does not exist. Options can include a predicate to determine if it
// should be called (based on the data published to it) and a priority
// index.
once: function(channelName, fn, options, context){
options = options || {};
options.calls = 1;
Mediator.prototype.once = function(channelName, fn, options, context) {
options = options || {};
options.calls = 1;
return this.subscribe(channelName, fn, options, context);
},
return this.subscribe(channelName, fn, options, context);
}
// Returns a subscriber for a given subscriber id / named function and
// channel namespace
// Returns a subscriber for a given subscriber id / named function and
// channel namespace
getSubscriber: function(identifier, channelName){
var channel = this.getChannel(channelName || "", true);
// We have to check if channel within the hierarchy exists and if it is
// an exact match for the requested channel
if (channel.namespace !== channelName) {
return null;
}
Mediator.prototype.getSubscriber = function(identifier, channelName) {
var channel = this.getChannel(channelName || "", true);
// We have to check if channel within the hierarchy exists and if it is
// an exact match for the requested channel
if (channel.namespace !== channelName) {
return null;
}
return channel.getSubscriber(identifier);
},
return channel.getSubscriber(identifier);
}
// Remove a subscriber from a given channel namespace recursively based on
// a passed-in subscriber id or named function.
// Remove a subscriber from a given channel namespace recursively based on
// a passed-in subscriber id or named function.
remove: function(channelName, identifier){
var channel = this.getChannel(channelName || "", true);
if (channel.namespace !== channelName) {
return false;
}
Mediator.prototype.remove = function(channelName, identifier) {
var channel = this.getChannel(channelName || "", true);
if (channel.namespace !== channelName) {
return false;
}
channel.removeSubscriber(identifier);
},
channel.removeSubscriber(identifier);
}
// Publishes arbitrary data to a given channel namespace. Channels are
// called recursively downwards; a post to application:chat will post to
// application:chat:receive and application:chat:derp:test:beta:bananas.
// Called using Mediator.publish("application:chat", [ args ]);
// Publishes arbitrary data to a given channel namespace. Channels are
// called recursively downwards; a post to application:chat will post to
// application:chat:receive and application:chat:derp:test:beta:bananas.
// Called using Mediator.publish("application:chat", [ args ]);
publish: function(channelName){
var channel = this.getChannel(channelName || "", true);
if (channel.namespace !== channelName) {
return null;
}
Mediator.prototype.publish = function(channelName) {
var channel = this.getChannel(channelName || "", true);
if (channel.namespace !== channelName) {
return null;
}
var args = Array.prototype.slice.call(arguments, 1);
var args = Array.prototype.slice.call(arguments, 1);
args.push(channel);
args.push(channel);
channel.publish(args);
}
};
channel.publish(args);
}

@@ -379,0 +369,0 @@ // Alias some common names for easy interop

{
"name": "mediator-js",
"version": "0.9.8",
"version": "0.9.9",
"description": "Flexible event management. Implementation of the mediator pattern.",

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

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