You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+45-27Lines changed: 45 additions & 27 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -8,16 +8,6 @@
8
8
9
9
Rimmel is a powerful, fast and lightweight JavaScript UI library for creating web applications using reactive streams.
10
10
11
-
It implements [RML](https://github.com/ReactiveHTML/reactive-markup), the Reactive Markup which makes your HTML work with streams in a seamless way.
12
-
13
-
## Getting started
14
-
If you are new to reactive streams, there is a [3m crash-course](https://medium.com/@fourtyeighthours/the-mostly-inaccurate-crash-course-for-reactive-ui-development-w-rxjs-ddbb7e5e526e) tailored for UI development with Rimmel, arguably the simplest RxJS introduction around to get you started.
15
-
16
-
If you are new to the reactive and functional programming paradigms, this [interactive tutorial](https://reactivex.io/learnrx/) may be an especially useful introduction.
17
-
18
-
If you come from Angular, check out [this page](./docs/migrating/angular.md)<br>
19
-
If you come from React, check out [this page](./docs/migrating/react.md)<br>
20
-
21
11
## Hello World 👋🌏🏖️😎
22
12
Let's jump straight in. The "Hello World" for reactive user interfaces is the classic click counter: one button, you click it, ze counts it.
23
13
@@ -28,20 +18,41 @@ Let's jump straight in. The "Hello World" for reactive user interfaces is the cl
28
18
The click event from the `<button>` above is plugged into `counter` — a simple stream of events to numbers —
29
19
and the output is plugged into the `<span>` element at the end.
30
20
31
-
No need for anything else. No need to attach, connect, disconnect, clean up or anything. Rimmel does it all for you in pure JavaScript/TypeScript without any "dark magic".
21
+
```js
22
+
constcount=newBehaviorSubject(0).pipe(
23
+
scan(x=>x+1)
24
+
);
25
+
26
+
document.body.innerHTML= rml`
27
+
<button onclick="${count}">
28
+
click me (${count})
29
+
</button>
30
+
`;
31
+
```
32
32
33
-
You've probably never seen anything like this before, so just go and try it:
33
+
No need for anything else. No need to attach, connect, disconnect, clean up or anything. Rimmel does it all for you in pure JavaScript/TypeScript.
34
+
35
+
You've probably never seen anything like this before, so just go and play with it:
34
36
35
37
[](https://stackblitz.com/edit/rimmel-click-counter)
36
38
39
+
## Getting started
40
+
OK, let's take one step back, just in case.
41
+
42
+
If you are new to reactive streams, there is a [3m crash-course](https://medium.com/@fourtyeighthours/the-mostly-inaccurate-crash-course-for-reactive-ui-development-w-rxjs-ddbb7e5e526e) tailored for UI development with Rimmel, arguably the simplest RxJS introduction around to get you started.
43
+
44
+
If you are new to the reactive and functional programming paradigms, this [interactive tutorial](https://reactivex.io/learnrx/) may be an especially useful introduction.
45
+
46
+
If you come from Angular, check out [this page](./docs/migrating/angular.md)<br>
47
+
If you come from React, check out [this page](./docs/migrating/react.md)<br>
37
48
38
49
## Stream Oriented
39
50
Most JavaScript UI libraries and frameworks are designed for the imperative programming paradigm.
40
51
Occasionally they may also support some aspects of reactive or functional programming, too.
41
52
Third-party adapters or utility libraries can also be used to translate between each paradigm but the reality is that the imperative paradigm is their main focus and everything else was just an afterthought, severely limited, inconvenient or plain awkward to use in practice.
42
53
43
54
Rimmel was designed to make reactive streams just work.
44
-
In the Stream Oriented paradigm you begin creating reactive streams for all your state and behaviour, then use declarative templates (e.g.: RML) to bind them to the real world. This helps writing an extremely high quality code that's also very easy to maintain.
55
+
In the Stream Oriented paradigm you begin creating reactive streams for all your state and behaviour, then use declarative templates (e.g.: [RML](https://github.com/ReactiveHTML/reactive-markup)) to bind them to the real world. This helps writing an extremely high quality code that's also very easy to maintain.
45
56
46
57
### Everything is a Stream ☄️
47
58
This is the key concept of the paradigm. Instead of creating variables, classes, object and methods that perform mutations, you create streams. A stream is optional data-in, optional processing, optional data-out. Can be sync or async and combine other streams.
What you do instead, is you define all your application logic as streams, then you connect both ends of them to your HTML (Rimmel will know when to connect the input or the output from the context):
61
72
62
73
```javascript
63
-
//Stream Oriented
64
-
conststream=<your stream here>;
74
+
//A stream-oriented component
75
+
conststream=/*<your stream definition> */;
65
76
66
77
consttemplate= rml`
67
78
<button onclick="${stream}">click me</button>
68
79
Total clicks: <b>${stream}</b>
69
80
`;
70
81
```
71
82
83
+
# A simple way to manage a complex world
84
+
UI is complex: API calls that might not come back, touch events coming in thousands, user actions, sensor data. They can come in any order and you'd normally have to handle all that.
85
+
86
+
Stream-Oriented Programming makes complicated UI development an order of magnitude simpler to deal with, once you've learnt how to use streams. This is the promise.
87
+
88
+
What follows is some of the key aspects of Rimmel that make it so much simpler to deal with.
89
+
90
+
72
91
## No Virtual DOM 🚀
73
92
The concept of Virtual DOM originates from the assumption that the DOM is slow, which might appear to be the case if a framework makes a large number of unnecessary, uncontrolled updates, also known as "re-renders".
74
93
In that case it may be computationally cheaper to just run those outside of the DOM.
@@ -164,13 +183,12 @@ Finally, we have two sinks where the data ends up; one as the innerHTML of the <
164
183
## State doesn't exist. It's a Stream ✴️
165
184
"State", as the word itself suggests, is something static, so it doesn't belong to the dynamic, interactive, reactive webapps we make every day.
166
185
167
-
The rationale is that "state", as represented by plain old values such as numbers, strings and objects that are stored somewhere in memory is something you almost never need to read. Not now, not in 2 seconds, not in 45 minutes, not tomorrow. You only need those when certain events happen, in order to respond.
186
+
The rationale is that "state", as represented by plain old values such as numbers, strings and objects that are stored somewhere in memory is something you almost never need to read. Not now, not in 2 seconds, not in 45 minutes, not tomorrow.
168
187
169
-
After that, everything should go quiet, including your CPU, to keep your laptop cool until the next UI event occurs.
188
+
> You only need "state" when certain events happen, in order to respond.
170
189
171
-
This is, in summary, the _discrete functional/reactive_ paradigm behind Observables and RxJS (as opposed to the functional-reactive paradigm in general in which state is more like a continuous flow of data over time).
190
+
After that, everything should go quiet, including your CPU, to keep your laptop cool until the next UI event occurs.
172
191
173
-
Event-driven reactivity as modelled by Observables is therefore the perfect way to describe state as it changes through the lifetime of an application at the occurrence of various discrete UI events.
@@ -637,10 +655,13 @@ These are perfect cases to create Custom Sinks implementing relevant design patt
637
655
638
656
<br>
639
657
658
+
Here is [an example](https://stackblitz.com/edit/rimmel-table-powersink) code with a custom sink that uses low-level DOM operations to append rows and columns to a table.
659
+
640
660
## Memory management 🧠
641
-
If you come from some other libraries or frameworks, including "vanilla RxJS", you know you're somewhat responsible of cleaning up memory. The indiscriminate use of Observable subscriptions without proper cleanup can cause memory leaks in certain scenarios.
661
+
If you come from some other libraries or frameworks, including "vanilla RxJS", but especially Angular, then you know you are responsible for cleaning up memory.
662
+
Certain improper uses of Observable subscriptions in mixed-imperative programming and without proper cleanup cause memory leaks in certain scenarios.
642
663
643
-
Using Observables with Rimmel is trivial. All DOM subscriptions and event listeners are handled by the library behind the scenes, registered when a component is mounted and unregistered when it's removed.
664
+
Using Observables with Rimmel is trivial. All DOM event listeners and subscriptions are handled by the library behind the scenes, registered when a component is mounted and unregistered when it's removed.
644
665
645
666
<br>
646
667
@@ -651,20 +672,19 @@ A `BehaviorSubject` receives a special treatment from Rimmel in that its initial
651
672
652
673
```javascript
653
674
import { BehaviorSubject, switchMap } from 'rxjs';
@@ -705,9 +725,7 @@ Rimmel is closely following the above standardisation initiatives and aims to al
705
725
706
726
# Examples, examples, examples 🛟
707
727
708
-
There are several collections on Stackblitz that can get you started, give you inspiration or show you advanced design patterns.
709
-
710
-
There are several collections on Stackblitz that can get you started, give you inspiration or show you advanced design patterns.
728
+
There are several collections on Stackblitz with over 200 examples that can get you started, give you inspiration or show you advanced design patterns.
711
729
712
730
[The Basics](https://stackblitz.com/@dariomannu/collections/rimmel-js-getting-started) 🧺 A good place to start off. Simple examples for simple tasks.
0 commit comments