What is a Source ?
We've seen how to create Observables, but how can we simply emit some values ?
Definition of a Source
Let's write the interface of a Source:
interface ISource<GValue> {
readonly emit: IObserver<GValue>;
readonly subscribe: IObservable<GValue>;
}
A Source is simply a tuple composed of an Observer and an Observable.
Usually, they are tied together by a predefined algorithm.
Kind of Sources
@lirx/core
comes with a list of predefined Sources, each having a specific usage.
This part is more difficult than the others, do not focus too much on the details. You may take a quick look at this section and jump directly to the conclusion if required.
The MulticastSource
A MulticastSource is used to emit one value to multiple Observers.
While plain Observables are unicast (each subscribed Observer owns an independent execution of the Observable), MulticastSource are multicast.
Internally to the MulticastSource, subscribe does not invoke a new execution that delivers values. It simply registers the given Observer in a list of Observers, similarly to how addListener usually works in other libraries and languages.
You can create a MulticastSource with the function createMulticastSource.
Here's a simple example demonstrating its usage .
const source = createMulticastSource<number>();
source.subscribe((value: string) => {
console.log('value - A:', value);
});
source.subscribe((value: string) => {
console.log('value - B:', value);
});
source.emit(1);
source.emit(2);
Output:
value - A: 1
value - B: 1
value - A: 2
value - B: 2
If we already have an Observable and want to "convert" it to a MulticastSource (share its values), we can use the ObservablePipe shareObservablePipe:
const subscribe = pipe$$(interval(1000), [
scan$$$<void, number>(count => (count + 1), 0),
share$$$<number>(),
]);
The ReplaySource
A ReplaySource caches all the received values and emit them each time we subscribe to it.
This is the perfect candidate if we have to replay the values sent by an Observable.
We can create one using the function createReplaySource, but usually we'll end up using the shortcut createMulticastReplaySource, or the ObservablePipe shareObservablePipeWithMulticastReplaySource.
The ReplayLastSource
A ReplayLastSource is like a ReplaySource, but it only caches the last received value.
This is the perfect candidate if we have to keep only the last emitted value.
We can create one using the function createReplayLastSource, but like the previous one, we'll usually end up using the shortcut createMulticastReplayLastSource, or the ObservablePipe shareObservablePipeWithMulticastReplayLastSource.
let$$
Sources are a perfect bridge when we have to manually emit some values.
In 99% cases we'll use the shortcut let$$ to create a MulticastReplayLastSource represented as a tuple. It will act like a regular variable, but having the faculties of an Observable.
const [$firsName, firstName$] = let$$('Valentin');
const [$lastName, lastName$] = let$$(); // it's possible to omit the value, in this case, the Observable is uninitialized
const fullName$ = string$$`${firstName$} ${lastName$}`;
fullName$((value) => {
console.log(value);
});
lastName$('Richard');
// OUT => Valentin Richard
firstName$('Bob');
// OUT => Bob Richard
This is an elegant manner to create dynamic variables.