Messaging is a powerful development pattern that makes decoupling components and providing internal APIs incredibly easy. The primary goal of msngr is to provide a high quality, asynchronous method of consuming and emitting messages that work in both node and the web browser.
Snag a copy of msngr
Install via npm or bower by running
npm install msngr or
bower install msngr
Grab a copy of the
msngr.min.js files directly from this repo
Reference msngr directly from cdnjs
// I can call a function when I receive a specific message!;// I can emit messages of any type and I can chain them together.;// I can notify and even return values when a message is finished being processed;// Even better, I can return a result asynchronously!;// I can emit and persist a message so future handlers can receive it;// See?;// I can even guarantee a handler is called only once;;// Did I mention I'm completely asynchronous?;console; // This will print before everything in this example
Anatomy of a message
Messages can be comprised of a topic, category and subcategory with topic being the only required piece all of which are specified in the main msngr function
msngr(topic, category, subcategory). This allows for a large range of message consumption from the very general to the highly specific.
Consuming and emitting
When consuming or emitting a message you can choose to match just the topic, the topic and category or the topic, category and subcategory. This allows for a great amount of specificity when choosing what your handler can take care of (is it generic in that it can handle anything? should it only handle specific categories? subcategories?). Take a look at this example:
// Handler that receives all profile save attempts;// Handler that only received profile saves in json;// Handler that only received profile saves in xml;;;
The example above demonstrates that the handler will only fire when the specified criteria of a registered
on handler is satisfied.
A mechanism for middleware exists that creates a global or localized affect. This allows for payload transformation to occur prior to any messages and their payloads being delivered to handlers. A middleware needs to be registered via
msngr.middleware(key, fn, force) where the
key is the name of the middleware, the
fn is the middleware itself and
force is a boolean that specifies whether the middleware should execute on all messages or not (if
msngr().use(key) needs to be called on a message to have it applied).
Persist, once and drop
Messages can also have a payload that is persistent. This is incredibly handy when doing initialization. You can specify a message when something is initialized and persist the message (even with an empty payload) so that handlers registered before or after said initialization are still called. This is done through
msngr().persist() and can be ended through
There is also a
msngr().once() that works just like
msngr().on() except it is guaranteed to execute only once. In a similar vein you can drop
msngr().on() registered handles either one at a time through
msngr().drop(fn) or all at once for a specific message via
msngr.is(obj) function is an attempt to make it as intuitive and straight-forward as possible. Simply call
msngr.is(obj) providing whatever you want to check as the parameter (you can also pass in multiple parameters to check them all in an AND fashion) then call one of the following properties on the returned object:
msngrarguments; // checks for arguments objectmsngrboolean; // checks for booleanmsngrstring; // check for stringmsngrdate; // checks for datemsngrarray; // checks for arraymsngrnumber; // checks for numbermsngrobject; // checks for objectmsngrfunction; // checks for functionmsngrsymbol; // checks for symbolmsngrthere; // checks to see if the obj existsmsngrempty; // checks to see if an object, array or string is empty (including null and undefined)msngrhtmlElement; // checks to see if it's an HTML ElementmsngrnodeList; // checks to see if it's an HTML NodeList
So if you want to create an asynchronous process many developers turn to
setTimeout(fn, 0); but that's actually rather slow to execute in web browsers (typically values less than 10ms or so are ignored and even 0ms isn't guaranteed to execute immediately). Using
setImmediate(fn) is a far better choice but it's almost exclusively available in node and IE. This is where
msngr.immediate(fn) comes in. There is a way to simulate
setImmediate(fn) when it doesn't exist in a web browser so
msngr.immediate(fn) will use whatever the fastest solution that exists on the platform it is running on to execute something asynchronously.
msngr.parallel(methods, callback) / msngr.series(methods, callback)
Handling asynchronous behaviors can be difficult and there are many libraries (async.js) and techniques (promises, async & await) for handling such issues. But sometimes you just need a simple way to take multiple methods and combine them. Msngr uses this capability internally for handling message delegation and processing of middleware so these two methods are the public version of the very same API.
const props = ;msngr;msngr;
For questions, news, and whatever else that doesn't fit in GitHub issues you can follow me @KrisSiegel
Copyright © 2014-2019 Kris Siegel