/rx-rql

AB*C

Primary LanguageTypeScript


AB*C
[A --a--------]
[B -b-b-b-b-b-]
[C --------c--]
[= --ab-b-bc| ]

Reactive Query Language
NPM Bundlephobia MIT license

📖 Intro

Extract events from multiple streams using query commands

📦 Install

npm i rx-rql

It's quite small: just a couple of kBs!

⛱ Example

To create a Drag-n-Drop behavior you can select all mouse-move events, betweeen each mouse-down and mouse-up:

// Mouse DnD implemented using rx-rql
import { fromEvent } from 'rxjs';
import { query, some, mute } from 'rx-rql';

// get dom element to drag
const item = document.getElementById('item');
const updatePosition = p => {
  item.style.left = p.x + 'px';
  item.style.top = p.y + 'px';
};

// capture mouse down, up and move
const down$ = fromEvent(item, 'mousedown');
const move$ = fromEvent(document, 'mousemove');
const up$   = fromEvent(document, 'mouseup');

// (_down, move*, _up)*
// listen to a query & update element position
query(
  some(mute(down$), some(move$), mute(up$))
)
  .subscribe(updatePosition)

Try this example online

🔧 API

Query root

Your query should be wrapped in a query or $ function

query(A, B, C).subscribe(console.log);

It returns an Observable of query results!

A, B, C — single emission

To select a single event from a stream — just pass that stream to the query function or one of the operators:

// $ A
// A ---Hi-----
// = ---(H|)
const A = of('H', 'i');
query(A).subscribe(console.log); // > H

// $ AA
// A ---Hi-----
// = ---H(i|)
query(A, A).subscribe(console.log); // > H > i

// $ AB
// A --H-i-----
// B -W-o-r-l-d
// = --H(o|)
const A = of('H', 'i');
const B = of('W', 'o', 'r', 'l', 'd');
query(A, B).subscribe(console.log); // > H > o

_A — mute

Use mute(…) to query an event, but suppress its emission:

// $ A_B
// A --H-i-----
// B -W-o-r-l-d
// = --(H|)
const A = of('H', 'i');
const B = of('W', 'o', 'r', 'l', 'd');
query(A, mute(B)).subscribe(console.log); // > H > W

A* — some

Use some(…) to select as many events as possible:

// $ A*
// A Hi--------
// = Hi--------
const A = of('H', 'i');
query(some(A)).subscribe(console.log); // > H > i

This operator is not greedy, it will select events while it can. You may limit it with another event:

// A*B
// A 0-1-2-3-4
// B ---b-----
// = 0-1(b|)
const A = timer(0, 10);
const B = of('b').pipe( delay(35) );
query(some(A), B).subscribe(console.log); // > 0 > 1 > b

A? — maybe

Use maybe(…) to select 0 or 1 events:

// $ A?B
// A 0-1-2-3-4
// B ---b-----
// = 0--(b|)
const A = timer(0, 10);
const B = of('b').pipe( delay(35) );
query(maybe(A), B).subscribe(console.log); // > 0 > b

A{min,max} — many

Use many(min, max)(…) to select at least min and at most max events:

// $ A{1, 3}
// A 0-1-2-3-4
// B -------b-
// = 0-1-2--(b|)
const A = timer(0, 10);
const B = of('b').pipe( delay(45) );
query(many(1, 3)(A), B).subscribe(console.log); // > 0 > 1 > 2 > b

🤝 Want to contribute to this project?

That will be awesome!

Please create an issue before submiting a PR — we'll be able to discuss it first!

Thanks!

Enjoy 🙂