Mediator.js
Version 0.9.7
A light utility class to help implement the Mediator pattern for easy eventing
Mediator is a simple class that allows you to register, unregister, and call
subscriber methods to help event-based, asyncronous programming. Its purpose
is to make the usage of WebSockets, Ajax calls, DOM events, or any other
asynchronous operations easy to maintain and test.
Mediator has no dependencies on any other libraries.
1.12kb, minifed and gzipped
Why?
My specific use case: bind elements easily for WebSocket callbacks. But, you
may find usage in it for all kinds of things: as an event management system,
to decouple calls between javascript functions, Ajax request callbacks, and
more. There's an excellent online book that talks about Mediators more in detail
by Addy Osmani.
Usage
Using in Node
The package is in NPM as mediator-js
. Include it in your project like so:
var Mediator = require("mediator-js").Mediator,
mediator = new Mediator();
mediator.subscribe("wat", function(){ console.log(arguments); });
mediator.publish("wat", 7, "hi", { one: 1 });
Using in the Browser
Mediator.js is compatible with browser module-loading solutions, including but
not limited to Browserify, Almond.js, Require.js, and others.
Note: if using AMD / Almond module loading, use the NPM package name:
require("mediator-js").Mediator
<script src="/js/Mediator.min.js"></script>
<script>
var Mediator = require("mediator-js").Mediator,
mediator = new Mediator();
mediator.subscribe("wat", function(){ console.log(arguments); });
mediator.publish("wat", 7, "hi", { one: 1 });
</script>
API
You can register events with the mediator two ways using channels. You can add
a predicate to perform more complex matching. Instantiate a new mediator, and
then you can being subscribing, removing, and publishing.
To use it in the browser, include mediator.min.js
from the root here, or the
unminified version at lib/mediator.js.
Subscription signature:
var mediator = new Mediator();
mediator.subscribe(channel, callback, <options>, <context>);
mediator.publish(channel, <data, data, ... >)
mediator.remove(channel, <identifier>)
Additionally, on
and bind
are aliased to subscribe
, and trigger
and
emit
are bound to publish
. off
is an alias for remove
. You can use
once
to subscribe to an event that should only be fired once.
Subscriber signature:
function(<data, data ...>, channel);
The channel is always returned as the last argument to subscriber functions.
Mediator.subscribe options (all are optional; default is empty):
{
predicate: function(*args){ ... }
priority: 0|1|...
calls: 1|2|...
}
Predicates return a boolean and are run using whatever args are passed in by the
publishing class. If the boolean is true, the subscriber is run.
Priority marks the order in which a subscriber is called.
calls
allows you to specify how many times the subscriber is called before it
is automatically removed. This is decremented each time it is called until it
reaches 0 and is removed. If it has a predicate and the predicate does not match,
calls is not decremented.
A Subscriber object is returned when calling Mediator.subscribe. It allows you
to update options on a given subscriber, or to reference it by an id for easy
removal later.
{
id,
fn,
options,
context,
channel,
update(options){ ...}
}
Examples:
var mediator = new Mediator();
mediator.subscribe("message", function(data){ alert(data); });
mediator.publish("message", "Hello, world");
var predicate = function(data){ return data.From === "Jack" };
mediator.subscribe("channel", function(data){ alert(data.Message); }, { predicate: predicate });
mediator.publish("channel", { Message: "Hey!", From: "Jack" });
mediator.publish("channel", { Message: "Hey!", From: "Audrey" });
You can remove events by passing in a channel, or a channel and the
function to remove or subscriber id. If you only pass in a channel,
all subscribers are removed.
mediator.remove("channel");
mediator.remove("channel", MethodFN);
You can call the registered functions with the Publish method, which accepts
an args array:
mediator.publish("channel", "argument", "another one", { etc: true });
You can namespace your subscribing / removing / publishing as such:
mediator.subscribe("application:chat:receiveMessage", function(data){ ... });
mediator.publish("application:chat:receiveMessage", "Jack Lawson", "Hey");
You can update Subscriber priority:
var sub = mediator.subscribe("application:chat", function(data){ ... });
var sub2 = mediator.subscribe("application:chat", function(data){ ... });
mediator.getChannel("application:chat").setPriority(sub2.id, 0);
You can update Subscriber callback, context, and/or options:
sub.update({ fn: ..., context: { }, options: { ... });
You can stop the chain of execution by calling channel.stopPropagation():
mediator.subscribe("application:chat", function(data, channel){
alert("Don't send messages to yourself!");
channel.stopPropagation();
}, options: {
predicate: function(data){ return data.From == data.To },
priority: 0
});
Changelog
Version 0.9.7
- Fixed bug where subscribers that failed predicates were decrementing calls.
Version 0.9.6
- Fixed AMD-style export; export constructor, not instance
Version 0.9.5
- Fixed issue with requring from node
Version 0.9.4
- Fixed issue with auto-removing subscribers after a maximum amount of calls
Version 0.9.3
- Make AMD name match npm package name
mediator-js
. (Previously used
Mediator.js
.)
Version 0.9.1
- Fixed AMD /
define
syntax - Exposed
Mediator.version
Version 0.9.0
- Reversed order of recursion: now calls parents instead of children channels
- Lowercase methods
- Aliases:
on
and bind
are aliased to subscribe
, and trigger
and
emit
are bound to publish
. off
is an alias for remove
. - Moved tests to mocha from jasmine
- Supports AMD, requirejs, and browser loading
- Lots of cleanup around extra variables, and jslinted
- Published to NPM under "mediator-js"
- Added travis-ci build
Version 0.6.1
- Cleaned up some typos
- Save pointer to channel within subscription
- Save namespace in channel
- Fixed bugs in SetPriority
Version 0.6.0
- Added ability to stop the chain of calls using c.stopPropagation()
Version 0.5.0
- Added ability to access and update subscribing objects
- Subscribers now have a unique ID and can be queried by id or by function
- Subscriber class can have its function, context, or options updated
- Subscriber priority can be updated post-addition
- Channels made public by Mediator.GetChannel
- Added a little performance test
Version 0.4.2
- Added Priority to calls, allowing you to set callback index
Version 0.4.1
Version 0.4.0
- Predicate no longer acts as a channel and is moved to an options object
at the end of the subcription call.
- Signatures changed; context moved to the end of subscriptions
- Namespacing for subscription binding
License
This class and its accompanying README and are
MIT licensed.
In Closing
Have fun, and please submit suggestions and improvements! You can leave any
issues here, or contact me at (@ajacksified).