Skip to content

Commit

Permalink
6.0.0 (#66)
Browse files Browse the repository at this point in the history
Removed mache and net
Removed dedupe, collapsed logic inward
Removed documentation regarding removals

* Removed unnecessary params
Updated node versions for testing

* Wrapping changes for 6.0.0
  • Loading branch information
KrisSiegel authored Jul 28, 2017
1 parent 8ae7a30 commit daa81b6
Show file tree
Hide file tree
Showing 28 changed files with 185 additions and 1,931 deletions.
4 changes: 2 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
language: node_js
sudo: false
node_js:
- "8.1"
- "8.2"
- "8.0"
- "7.10"
- "7.0"
- "6.10"
- "6.11"
- "6.0"
- "5.12"
- "5.0"
Expand Down
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
# Changelog
This is a roll-up of all release notes in order of release

## [Release 6.0.0 - July 28, 2017](https://github.com/KrisSiegel/msngr.js/releases/tag/6.0.0)
This release is a re-focusing on what makes msngr.js great. It removes the mache cache, the global configuration object and the universal networking to focus only on messaging and processing of messages. Additional, internal refactoring was also done to further shrink the filesize to a gzipped size of roughly 3kb.

***Breaking changes***
- Removed `msngr.mache`
- Removed global config instance of mache
- Removed `msngr.net`
- Removed `msngr.deDupeArray`

***Misc changes***
- Refacored multiple files to consolidate logic and reduce file size further

## [Release 5.2.1 - June 15, 2017](https://github.com/KrisSiegel/msngr.js/releases/tag/5.2.1)
Mostly some house cleaning

Expand Down
3 changes: 0 additions & 3 deletions Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,10 @@ module.exports = (function(grunt) {
*/
var paths = [
"src/main.js",
"src/exceptional.js",
"src/validators/*.js",
"src/utils/*.js",
"src/mutators/*.js",
"src/messaging/*.js",
"src/mache/*.js",
"src/net/*.js",
"src/middlewares/*.js",
"src/module.exports.js",
"!**/*.aspec.js",
Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
The MIT License (MIT)

Copyright (c) 2014-2016 Kris Siegel
Copyright (c) 2014-2017 Kris Siegel

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
136 changes: 57 additions & 79 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

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.

There is a secondary goal in providing great, universal objects and functions that are useful in essentially every application. This includes type validation using ```msngr.is(obj)```, basic http requests with ```msngr.net(url)``` that work identically across platforms and a merge cache that includes transactions in ```msngr.mache()```. There are also utilities such as ```msngr.immediate(fn)``` that provide a faster-than-setTimeout way of creating your own asynchronous methods.

### Snag a copy of msngr
Install via npm or bower by running ```npm install msngr``` or ```bower install msngr```

Expand All @@ -14,30 +12,59 @@ Reference msngr directly [from cdnjs](https://cdnjs.com/libraries/msngr)
### Hello, World!
```javascript
// I can call a function when I receive a specific message!
msngr("Output").on(function (words) {
msngr("Output").on((words) => {
console.log(words); // Outputs 'Hello, World!', 'I'm chainable!' and 'Weee'
return 42;
});

// I can emit messages of any type. I can even chain almost anything.
// I can emit messages of any type and I can chain them together.
msngr("Output")
.emit("Hello, World!")
.emit("I'm chainable!")
.emit("Weee");

// I can emit and persist a message, too so future handlers can receive it

// I can notify and even return values when a message is finished being processed
msngr("Output")
.emit("Processing", (results) => {
console.log(results); // Prints [42]
});

// Even better, I can return a result asynchronously!
msngr("More")
.on((input, message, async) => {
const done = async();
done(42);
})
.emit("Processing", (results) => {
console.log(results); // Also prints [42]
});

// I can emit and persist a message so future handlers can receive it
msngr("Important", "Message").persist("I am persisted!");

// See?
msngr("Important", "Message").on(function (text) {
console.log(text); // Outputs 'I am persisted!'
msngr("Important", "Message").on((text) => {
console.log(text); // Outputs 'I am persisted!'

// Then I can remove the persisted data once I'm done with it
msngr("Important", "Message").cease();
});

// I can even guarantee a handler is called once
msngr("Once").once(function (str) {
console.log(str); // Only outputs 'Just once'
// I can even guarantee a handler is called only once
msngr("Once").once((str) => {
console.log(str); // Only outputs 'Just once'
});

msngr("Once").emit("Just once").emit("asdljadlka").emit("sadjkhada");

// Did I mention I'm completely asynchronous?
msngr("Async")
.on((text) => {
console.log(text);
})
.emit("This is async text");

console.log("This is sync text"); // This will print before everything in this example
```

### Anatomy of a message
Expand All @@ -48,17 +75,17 @@ When consuming or emitting a message you can choose to match just the topic, the

```javascript
// Handler that receives all profile save attempts
msngr("Profile", "Save").on(function (payload) {
msngr("Profile", "Save").on((payload) => {
console.log(payload);
});

// Handler that only received profile saves in json
msngr("Profile", "Save", "application/json").on(function (payload) {
msngr("Profile", "Save", "application/json").on((payload) => {
console.log("Save the json payload");
});

// Handler that only received profile saves in xml
msngr("Profile", "Save", "application/xml").on(function (payload) {
msngr("Profile", "Save", "application/xml").on((payload) => {
console.log("Save the xml payload");
});

Expand All @@ -72,14 +99,14 @@ The example above demonstrates that the handler will only fire when the specifie
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 ```false``` then ```msngr().use(key)``` needs to be called on a message to have it applied).

```javascript
msngr.middleware("uppercase", function (payload, message) {
msngr.middleware("uppercase", (payload, message) => {
if (msngr.is(payload).string) {
return payload.toUpperCase();
}
return payload;
}, true);

msngr("SayIt").on(function (payload) {
msngr("SayIt").on((payload) => {
console.log(payload); // Prints 'HELLO, WORLD!'
});

Expand Down Expand Up @@ -112,60 +139,11 @@ msngr.is(obj).htmlElement; // checks to see if it's an HTML Element
msngr.is(obj).nodeList; // checks to see if it's an HTML NodeList
```

### msngr.net()
There is basic http request functionality that allows the sending of the typical HTTP verbs (GET, POST, PUT, DELETE and OPTIONS) to a server. This is not meant to be comprehensive but provides an 90% solution which works, without a code change, in both node and the web browser. It also works as a handy URL parser! ```msngr.net(protocol, host, port)``` looks nice and neat but you can straight up send it a URL and it will parse and separate it into the ```protocol```, ```host``` and ```port```, all available as properties on the returned net object.

```javascript
var net = msngr.net("https://mywebsite.com");
console.log(net.protocol); // prints 'https'

net.get({
path: "/endpoint",
query: {
q: "my query"
}, function (err, result) {
console.log(result);
}
});
```

In the simple ```msngr().net()``` example above the query object is translated into proper query strings and sent to the "/endpoint". Simple, right? You can also provide a ```header``` object that will get sent as proper HTTP headers and a ```payload``` object that can contain whatever you're sending to the server.

### Mache Mache Mache!
What the hell is a 'mache'? It's a merge cache. Get it? Merge cache...mache...okay okay. So how does it work? It's a lot like a typical local cache in that it works via key value pairs but it includes some neat additions including each setting of a value is merged with the previous value if it exists, the ability to revert multiple sets and even transactions.

```javascript
var mache = msngr.mache();

mache.set("mykey", {
test: "mytest"
});

mache.set("mykey", {
test: "anothertest"
});

mache.get("mykey"); // returns { test: "anothertest" }

mache.revert("mykey");

mache.get("mykey"); // returns { test: "mytest" }
```

Mache transactions work similar to SQL transactions; when you want to start simply call ```.begin()``` on your mache instance, then get and set whatever you want. Once you're finished either call ```.rollback()``` to end the transaction and eliminate all changes done during that time or ```.commit()``` to commit all of the changes made. You can even create a mache instance with some configuration options to change the level of revisions to store outside of transactions along with emitting all changes through messages so as data changes your components can react to said changes.

```javascript
var mache = msngr.mache({
revisions: 10, // default is 3
emitChanges: true // emits on the msngr("msngr.mache", "change") message
});
```

### msngr.immediate()
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 10 or so are ignored and even 0 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.
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.

```javascript
msngr.immediate(function () {
msngr.immediate(() => {
console.log("Hey there!");
});

Expand All @@ -175,25 +153,25 @@ msngr.immediate(function () {
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.

```javascript
var props = { };
const props = { };
msngr.parallel([
function () { props.value1 = 42; },
function () { props.value2 = "forty two"; },
function () { props.value3 = true; },
], function () {
() => { props.value1 = 42; },
() => { props.value2 = "forty two"; },
() => { props.value3 = true; },
], () => {
console.log(props.value1); // Prints 42
console.log(props.value2); // Prints 'forty two'
console.log(props.value3); // Prints true
});

msngr.series([
function () { return "s" },
function () { return "e" },
function (async) { async()("r") },
function (async) { async()("i") },
function (async) { async()("e") },
function () { return "s" }
], function (results) {
() => { return "s" },
() => { return "e" },
(async) => { async()("r") },
(async) => { async()("i") },
(async) => { async()("e") },
() => { return "s" }
], (results) => {
console.log(results.join("")); // Prints "series"
});
```
Expand Down
2 changes: 1 addition & 1 deletion bower.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "msngr.js",
"main": "msngr.min.js",
"description": "msngr.js is an asynchronous messaging library, written in JavaScript, for node and browser use",
"version": "5.2.1",
"version": "6.0.0",
"homepage": "https://github.com/KrisSiegel/msngr.js",
"authors": [
"Kris Siegel"
Expand Down
Loading

0 comments on commit daa81b6

Please sign in to comment.