A “source” in Wonka is a provider of data. It provides data to a “sink” when the “sink” requests it. This is called a pull signal and for synchronous sources no time will pass between the sink pulling a new value and a source sending it. For asynchronous sources, the source may either ignore pull signals and just push values or send one some time after the pull signal.
fromArray
fromArray transforms an array into a source, emitting each item synchronously.
reasonWonka.fromArray([|1, 2, 3|]);
typescriptimport { fromArray } from 'wonka';fromArray([1, 2, 3]);
fromList
fromList transforms a list into a source, emitting each item synchronously.
Note: This operator is only useful in Reason / OCaml where lists are a builtin data structure.
This is otherwise functionally the same as fromArray.
reasonWonka.fromList([1, 2, 3]);
fromValue
fromValue takes a single value and creates a source that emits the value and
completes immediately afterwards.
reasonWonka.fromValue("a value");
make
make can be used to create an arbitrary source. It allows you to make a source
from any other data.
It accepts a function that receives an “observer” and should return a teardown
function. It’s very similar to creating an Observable in zen-observable.
The function you pass to make is called lazily when a sink subscribes to the
source you’re creating. The first argument observer is a tuple with two methods:
next(value)emits a value on the sinkcomplete()ends the source and completes the sink
The subscriber function also needs to return a teardown function. This function
is called when either complete() is called and the source ends, or if the source
is being cancelled, since the sink unsubscribed.
In this example we create a source that waits for a promise to resolve and emits values from the array of that promise.
reasonlet waitForArray = () => Js.Promise.resolve([|1, 2, 3|]);let source = Wonka.make((. observer) => {let (next, complete) = observer;let cancelled = ref(false);let promise = waitForArray();Js.Promise.then_(arr => {if (!cancelled^) {Array.iter(next, arr);complete();}}, promise);() => cancelled := true;});
typescriptimport { make } from 'wonka';const waitForArray = () => Promise.resolve([1, 2, 3]);const source = make(observer => {const { next, complete } = observer;let cancelled = false;waitForArray().then(arr => {if (!cancelled) {arr.forEach(next);complete();}});return () => {cancelled = true;};});
makeSubject
makeSubject can be used to create a subject. This is similar to make without
having to define a source function. Instead a subject is a tuple of a source and
the observer’s next and complete functions combined.
A subject can be very useful as a full event emitter. It allows you to pass a source around but also have access to the observer functions to emit events away from the source itself.
reasonlet subject = Wonka.makeSubject();let { source, next, complete } = subject;/* This will push the values synchronously to any subscribers of source */next(1);next(2);next(complete);
typescriptimport { makeSubject } from 'wonka'const subject = Wonka.makeSubject();const { source, next, complete } = subject;/* This will push the values synchronously to any subscribers of source */next(1);next(2);next(complete);
fromDomEvent
fromDomEvent will turn a DOM event into a Wonka source, emitting the DOM events
on the source whenever the DOM emits them on the passed element.
Note: This source is only available in JavaScript environments, and will be excluded when compiling natively.
reasonopen Webapi.Dom;open Document;let element = getElementById("root", document)->Belt.Option.getExn;Wonka.fromDomEvent(element, "click")|> Wonka.subscribe((. click) => Js.log(click));
typescriptimport { pipe, fromDomEvent, subscribe } from 'wonka';const element = document.getElementById('root');pipe(fromDomEvent(element, 'click'),subscribe(e => console.log(e)));
fromPromise
fromPromise transforms a promise into a source, emitting the promisified value on
the source once it resolves.
Note: This source is only available in JavaScript environments, and will be excluded when compiling natively.
reasonlet promise = Js.Promise.make(1); /* Just an example promise */Wonka.fromPromise(promise)|> Wonka.subscribe((. x) => Js.log(x));/* Prints 1 to the console. */
typescriptimport { pipe, fromPromise, subscribe } from 'wonka';const promise = Promise.resolve(1); // Just an example promisepipe(fromPromise(promise),subscribe(e => console.log(e))); // Prints 1 to the console.
fromObservable
fromObservable transforms a spec-compliant JS Observable into a source.
The resulting source will behave exactly the same as the Observable that it was
passed, so it will start, end, and push values identically.
Note: This source is only available in JavaScript environments, and will be excluded when compiling natively.
typescriptimport { pipe, fromObservable, subscribe } from 'wonka';// This example uses zen-observable for illustrative purposesimport Observable from 'zen-observable';const observable = Observable.from([1, 2, 3]);pipe(fromObservable(observable),subscribe(e => console.log(e))); // Prints 1 2 3 to the console
If you’re using Reason in a JavaScript environment and you’re interested in this operator, you may be using a library to create or get Observables.
Some libraries don’t expose Observables with the same BuckleScript type signature
that Wonka uses to type them. So while Wonka’s observableT type is fairly
lenient it may not work for you.
reasontype observableT('a) = {.[@bs.meth] "subscribe": observerT('a) => subscriptionT};
To work around this you can create a function that casts your observable type
to Wonka’s observableT.
reasontype yourObservableType('a);external asObservable: yourObservableType('a) => Wonka.observableT('a) = "%identity";
This snippet would create an asObservable function, which can type-cast your
Observable type to Wonka.observableT and compiles away completely.
fromCallbag
fromCallbag transforms a spec-compliant JS Callbag into a source.
Since Wonka’s sources are very similar to callbags and only diverge from the specification
minimally, Callbags map to Wonka’s sources very closely and the fromCallbag wrapper
is very thin and mostly concerned with converting between the type signatures.
Note: This source is only available in JavaScript environments, and will be excluded when compiling natively.
reason/* This example uses the callbag-from-iter package for illustrative purposes */[@bs.module] external callbagFromArray:array('a) => Wonka.callbagT('a) = "callbag-from-iter";let callbag = callbagFromArray([|1, 2, 3|]);Wonka.fromCallbag(callbag)|> Wonka.subscribe((. x) => Js.log(x));/* Prints 1 2 3 to the console. */
typescriptimport { pipe, fromCallbag, subscribe } from 'wonka';// This example uses the callbag-from-iter package for illustrative purposesimport callbagFromArray from 'callbag-from-iter';const callbag = callbagFromArray([1, 2, 3]);pipe(fromCallbag(callbag),subscribe(e => console.log(e))); // Prints 1 2 3 to the console.
interval
interval creates a source that emits values after the given amount of milliseconds.
Internally it uses setInterval to accomplish this.
Note: This source is only available in JavaScript environments, and will be excluded when compiling natively.
reasonWonka.interval(50)|> Wonka.subscribe((. x) => Js.log(x));/* Prints 0 1 2... to the console. *//* The incrementing number is logged every 50ms */
typescriptimport { pipe, interval, subscribe } from 'wonka';pipe(interval(50),subscribe(e => console.log(e))); // Prints 0 1 2... to the console.// The incrementing number is logged every 50ms
empty
This is a source that doesn’t emit any values when subscribed to and immediately completes.
reasonWonka.empty|> Wonka.forEach((. value) => {/* This will never be called */()});
typescriptimport { pipe, empty, forEach } from 'wonka';pipe(empty,forEach(value => {/* This will never be called */}));
never
This is source is similar to empty.
It doesn’t emit any values but also never completes.
reasonWonka.never|> Wonka.forEach((. value) => {/* This will never be called */()});
typescriptimport { pipe, never, forEach } from 'wonka';pipe(never,forEach(value => {/* This will never be called */}));