RealTime Apps in NodeJS (new library)

André Marques
5 min readJan 5, 2019

There are so many framework and libraries to develop a realtime app. The most famous in nodeJS are React, angular, vue, socket.io…

I am going to introduce to you an unique and powerful library that synchronizes the database objects with your HTML files and your JS Classes, and gives you control and speed in your project development.

There are 2 versions of the library, one for client side, and another for server side. They synchronize with each other by pure websocket. The server counterpart connects with mongodb.

We call short functions, such as data.update(field, value), and the library updates the database, and it also sends the updated part to the clients that need it. Before sending, it protects certain fields if they shouldn’t be seen by some users (depending on conditions).

Let’s Start

We type a skeleton for the database collection:

this.skeleton = { username: “”, score: 0, x: 0, y: 0, bullets: [] };this.type = "player";

we create or get the object:

var obj = Data.create("player");var obj = Data.get("player", id);

Now that we have the object,

we can call any method we want:

//example:obj.update("score", 5);var value = obj.get("score");

The methods are:

update(path, value)— changes, adds and removes fields and array elements

get(path)— retrieve any information, no matter if it’s nested (field1.field2.array1…) or powerful queries (later on).

link(obj2) — links the object to a second object, so you can call its methods in the second object: obj2.get(path)

execute(callback) — execute the function when the object is loaded from the database (or from the server, if we are in the client side)

setBinder(path, callback) — observe the path (such as “body.legs.right”), and when there is a change, it triggers the callback. On the callback we have access to: old obj, updated obj, and the element that was added or removed.

Displaying interactive information

by defining certain attributes in any element of the page, we are able to give them tremendous interactivity.

  1. data-exec=”…” — executes the function when the element is loaded.
  2. data-func=”…” — creates a func that is called by el.funcs.name();

inside of these, we are able to show or hide the element simply by: this.show(); / this.hide();

3. data-entangle=”…”

Display nested data in RealTime, simply:

this.innerHTML = this.retrieve(player, path);

retrieve(data, path, default) — the first argument is either the data Object, or a name string. A name? Let me show you.

Abstract Objects

Data.getN(name) give us an abstract entity which can be synced to any data Object. It has two methods: sync and unsync.

sync(data) or sync(type, id)

This abstract entity will be linked to a data Object in our client side which is updated by the server side Object. Finally, this server Object corresponds to a mongoDB document.

We use the abstract entity when for example we have one single tab, and depending on what profile we click, the tab shows different texts.

We are able to entangle it such as this:

data-entangle= ‘this.innerHTML = this.retrieve(“myTab”, “array.0.text”);’

We can also add up conditions and multiple retrieves:

if(this.retrieve(...)) this.style.textColor = this.retrieve(...);

Data protected from “bad” users — privacy

in the collection type file, we define rules:

this.rules = function(){

if(.....)
this.filter("*username");
}

filter(path) — we are able to filter nested objects. If we filter the field “nested1", the field “nested1.nested2” will also be reset to its skeleton default. But if we filter “nested1” first, we can make exceptions by overflowing the state of “nested2", like this:

this.filter("*nested1");
this.filter("nested1.=nested2");

Notice the * and =, they mean filtering and showing, respectively.

The same applies to update(path, value); but different meanings: * means delete an array element or a field, and = means replacing an object or array

Connecting parents with children by ids

While creating skeletons we can use _ surrounding the type name which represents an id of a children. for example:

this.skeleton = { username: “”, _bullet_s: [] };

Bullet is the type, the value may be an string or an array of strings.

We don’t necessary need to use _ to make reference to another data Object, but it has one purpose. I will show you:

Active + Fully Active Objects

When the users request this specific Object to be “fully active” its children will be downloaded from mongoDB to the server and stay there as long as the user needs their parent.

There are two states of the Data Object:

Active means every update in the data will be sent to its users.

Fully Active, every update plus children’s updates will be sent.

A perfect example of fully active are chat rooms or gaming lobbies. The Room Object and its children are considered as one but they are better kept separate in types for organizing and reference purposes.

Room → Players → Weapons → Bullets

Powerful query at get(path)

what if we want to retrieve information according to conditions? No problem! or sorting, getting different fields at once, iterating arrays, accessing reference children… No problem.

Here is how we do it:

Iterating — use ~

data.get("_bullet_types.~.quantity");result: [5, 220, 60, 30]

Accessing children by reference — use parenthesis or _ surrounding the type

data.get("gun(weapon)._creator_s.0.name");result: "John"

many fields at once — use {}

data.get("{username, friends(user).username}");result: ["Andre", "Friend1", "Friend2"]

identify fields — use = before field (and optional [name])

data.get("{=[mine]username, =friends(user).username}");result: { mine: "Andre", friends: [ "Friend1", "Friend2" ]}

Conditions and Sorting — #filter and #sort

data.get("{ rooms(room).@, #filter(get('type') === 5) }");result: rooms data which type is 5
data.get("{ rooms(room).@, #sort([>get('type')) }");result: rooms data ordered by type (growing)

Other Powerful tools:

  • Call Actions in the server in a secure and organized way
  • Easily integrated with website builders (such as www.webflow.com)
  • dynamic search URL (changes when an abstract entity is synchronized)
  • Events that are scheduled to be triggered, are saved in database and retrieved in a optimized way.
  • Searching the mongoDB is also very easy: Data.search(obj)
  • Element Repeater, repeats an element according to your array of ids (which are references to data Objects) Perfect for a “friends” page.
  • Many More

This is an ambitious project. We believe engineers and designers will have a powerful tool to create real time and complex applications and websites in a short period of time.

Although my library is not released yet, you can Join and talk to me in this facebook group and receive the news!

--

--