In the previous post we explored API to select events from streams using RegExp-like syntax, e.g.:
const D = fromEvent(element, 'mousedown');
const M = fromEvent(document, 'mousemove');
const U = fromEvent(document, 'mouseup');
exec(
'DM*U' // <- regular expression
, { D, M, U } // <- streams that will be used
)
.pipe(ā¦)
.subscribe(console.log);
In this post we'll review it's functional API counterpart:
query(D, some(M), U) // select some Ms between Ds and Us
.pipe(ā¦)
.subscribe(console.log)
But first, we'll recap the thought process. If you're already familiar with the idea ā hop here
tl;dr: package @ https://github.com/erql/rx-rql š¦
š” Recap the idea
Imagine we need to implement a drag-n-drop behavior.
For that, we have three event streams: mousemove$
, mousedown$
, mouseup$
. So we want to capture mousemove$
events after mousedown$
emitted and before mouseup$
.
Let's draw a marble diagram of the event streams we have:
mousedown$ --o------------
mousemove$ -o-o-o-o-o-o-o-
mouseup$ ------------o--
o
stands for event on the stream. -
is a separator to represent passing timeFor better readability let's substitute all the o
s to respective letters of the streams:
mousedown$ --d------------
mousemove$ -m-m-m-m-m-m-m-
mouseup$ ------------u--
Now that we have distinct event names, we can simplify our diagram to a single line of events:
events$ -mdm-m-m-m-mum-
Let's remove the time -
signs as well, we don't them:
events$ mdmmmmmum
Okay, to rephrase our task in terms of the new diagram: we need to capture the m
events between d
and u
emissions.
š¤
Hmm...
"we need
m
s betweend
andu
"...
Sounds familiar...
Ah! If that was a string, we could easily do it with a regular expression:
/dm*u/.exec('mdmmmum')
Would give us the needed dmmmu
without trailing mouse-move m
events...
Right?
If only we had a library to select events from streams with regexes...
š Solution
query(D, some(M), U)
.pipe(ā¦)
.subscribe(console.log)
Rx-RQL š¦ package provides following API to make such selections:
-
query(ā¦)
ā root of your selection -
A
ā select 1 emission from the stream -
some(A)
ā select 0 to ā emissions from A -
maybe(A)
ā select 0 or 1 emission from A -
many(n,m)(A)
ā select from n to m emissions from A -
mute(A)
ā select emission from A & mute it
And you can group them as you like:
-
some(A, some(B), mute(C))
ā select as many emissions from: select as many Bs as possible between emissions from A and muted C
Here's how to create a simple drag-n-drop behavior using this package:
And here's a Mr. Potato-Head DnD š„ ā a more sophisticated example based on this amazing article by @dailydevtips1 ! Thx, Chris š
š Outro
Thank you for reading this article! Stay reactive and have a nice day š
If you enjoyed reading ā please, indicate that with ā¤ļø š¦ š buttons
And in case you're not yet following me here and on twitter ā then you've probably missed my recent experiments: Rx + Proxy, Rx Autorun, React + Rx
![]()
![]()
Kos Palchyk šš©@kddsky
š Here's an example of MIXING #RxJS with #React
1ļøā£ root ā React
2ļøā£ count-down ā Rx
3ļøā£ leaf display ā React
š stackblitz.com/edit/react-rxj⦠š
cc @Joseptec @voliva_v it's the concept I mentioned yesterday. WDYT?
#ļøā£ #js #ts #javascript #typescript #webdev #fe #FrontEnd #coding18:21 PM - 06 Oct 2020
Now I'd love to hear your thoughts! š
Top comments (3)
Look very cool. I will try it out.
Thanks! š
Be cautious: although it's well covered with tests, it's still very experimental!
If community would find this library useful, I'm thinking it could be extended with:
query(A, many(B).pipe(ā¦), C)
that would be applied to particular group outputAnyhow, please ping me back here or on github if you have additional thoughts or ideas. Thx!
I think it would be interesting to create predefined example to solve some common scenarios. Things like Drag and Drop, Hotkeys etc. I can see many possibilities here.