DEV Community

Cover image for A Stream-Oriented App — built in public
Dario Mannu
Dario Mannu

Posted on • Edited on

A Stream-Oriented App — built in public

The exploration of Stream-Oriented Programming continues.

Now that we have a good UI library for that, a decent Collections Library, and the brand-new Observable Plugin System for streams, it's time to build a blueprint for some cutting-edge, futuristic webapps.

Principles

Two core principles drive this project

  • Everything is a stream (code)
  • Everything is a plugin (architecture)

Everything is a Stream

This is the core mantra of stream-oriented programming which wants all code made of monadic components split in two parts: reactive streams and declarative templates.

Reactive streams can be either functional (E.G.: RxJS) or imperative (E.G.: Callforwards) or something in between (E.G.: Signals).

Templates define bindings to the real world. RML (an async equivalent of HTML) is one that tells what should happen when a button is clicked or where should some data be pulled from.

Everything is a Plugin

We'll break every piece of functionality of our app down into modules/plugins.

All modules use the messagebus pattern, so they are loosely coupled, have no knowledge of each-other and only communicate via messages by listening, emitting and replying to them.

The entry point of our application loads the modules, kicks off the plugin system and emits a single message "INIT". Modules subscribe to it and the whole ecosystem starts up.


The Architecture

One module listens to INIT and that's the router. It matches the current route from the URL and emits a ROUTE message.

Then we have pages. They listen to events on the ROUTE topic, render a page (to a plain HTML string) and emit a RENDER event.
Lastly, there is a ui module that listens and actually render these in the HTML.

This is what every module exports, a function that takes topics and connects them.

export default ({ ROUTE, RENDER }: Protocol, config) => {

  ROUTE.pipe(
    match('/'),
    map(template),
  ).subscribe(RENDER);

};
Enter fullscreen mode Exit fullscreen mode

We'll come up with a good test coverage soon, but you may realise how well this lends itself to testing, due to all modules being loosely coupled.


Lights, Camera, Action!

Enough talk, let's see the juice.

This is what it looks like. Just two pages, enough for a start.

Click on "editor" to see the code, or check it out directly on Stackblitz and roast it.

Check the code, the architecture. What do you think? Drop a comment, a praise or an insult, as you see fit!

Finally, if you like what you've seen here please don't forget to leave a Star in Github ⭐ so we can continue evolving it!


Learn More

Top comments (0)