···11# Wonka
2233-A fast push & pull stream library for Reason, loosely following the [callbag spec](https://github.com/callbag/callbag)
33+A tiny but capable push & pull stream library for TypeScript and Flow,
44+loosely following the [callbag spec](https://github.com/callbag/callbag)
4555-> **NOTE:** The `master` branch currently points to the v4 Release Candidate version!
66-> If you're looking for v3, [please check the `v3.2.2`](https://github.com/kitten/wonka/tree/v3.2.2)
66+> **NOTE:** The currently released version v6 is only compatible now with TypeScript, Flow, and JavaScript.
77+> If you're looking for Reason/OCaml/esy/dune support, please check v5, and if you're looking for the legacy version
88+> of this library check v4.
79810<br>
911<a href="https://npmjs.com/package/wonka">
···3335the [callbag spec](https://github.com/callbag/callbag). It exposes a set of helpers to create streams,
3436which are sources of multiple values, which allow you to create, transform
3537and consume event streams or iterable sets of data.
3636-3737-Wonka is written in [Reason](https://reasonml.github.io/), a dialect of OCaml, and can hence be used
3838-for native applications. It is also compiled using [BuckleScript](https://bucklescript.github.io) to plain
3939-JavaScript and has typings for [TypeScript](https://www.typescriptlang.org/) and [Flow](https://flow.org/).
4040-4141-This means that out of the box Wonka is usable in any project that use the following:
4242-4343-- Plain JavaScript
4444-- TypeScript
4545-- Flow
4646-- Reason/OCaml with BuckleScript
4747-- Reason/OCaml with `bs-native`
4848-- Reason/OCaml with Dune and Esy
49385039## [Documentation](https://wonka.kitten.sh/)
5140
+37-328
docs/api/operators.md
···15151616In combination with `interval` this can be used to group values in chunks regularly.
17171818-```reason
1919-Wonka.interval(50)
2020- |> Wonka.buffer(Wonka.interval(100))
2121- |> Wonka.take(2)
2222- |> Wonka.subscribe((. buffer) => {
2323- Js.Array.forEach(num => print_int(num), buffer);
2424- print_endline(";");
2525- });
2626-/* Prints 1 2; 2 3 to the console. */
2727-```
2828-2929-``` typescript
1818+```typescript
3019import { pipe, interval, buffer, take, subscribe } from 'wonka';
31203221pipe(
3322 interval(50),
3423 buffer(interval(100)),
3524 take(2),
3636- subscribe(buffer => {
3737- buffer.forEach(x => console.log(x));
2525+ subscribe((buffer) => {
2626+ buffer.forEach((x) => console.log(x));
3827 console.log(';');
3928 })
4029); // Prints 1 2; 2 3 to the console.
···44334534`combine` two sources together to a single source. The emitted value will be a combination of the two sources, with all values from the first source being emitted with the first value of the second source _before_ values of the second source are emitted.
46354747-```reason
4848-let sourceOne = Wonka.fromArray([|1, 2, 3|]);
4949-let sourceTwo = Wonka.fromArray([|4, 5, 6|]);
5050-5151-Wonka.combine(sourceOne)
5252- |> sourceTwo
5353- |> Wonka.subscribe((. (a, b)) => print_int(a + b));
5454-5555-/* Prints 56789 (1+4, 2+4, 3+4, 3+5, 3+6) to the console. */
5656-```
5757-5836```typescript
5937import { fromArray, pipe, combine, subscribe } from 'wonka';
6038···73517452`concat` will combine two sources together, subscribing to the next source after the previous source completes.
75537676-```reason
7777-let sourceOne = Wonka.fromArray([|1, 2, 3|]);
7878-let sourceTwo = Wonka.fromArray([|6, 5, 4|]);
7979-8080-Wonka.concat([|sourceOne, sourceTwo|])
8181- |> Wonka.subscribe((. x) => print_int(x));
8282-/* Prints 1 2 3 6 5 4 to the console. */
8383-```
8484-8554```typescript
8655import { fromArray, pipe, concat, subscribe } from 'wonka';
8756···90599160pipe(
9261 concat([sourceOne, sourceTwo]),
9393- subscribe(val => console.log(val))
6262+ subscribe((val) => console.log(val))
9463); // Prints 1 2 3 6 5 4 to the console.
9564```
9665···1017010271It's very similar to `concat`, but instead accepts a source of sources as an input.
10372104104-```reason
105105-let sourceOne = Wonka.fromArray([|1, 2, 3|]);
106106-let sourceTwo = Wonka.fromArray([|6, 5, 4|]);
107107-108108-Wonka.fromList([sourceOne, sourceTwo])
109109- |> Wonka.concatAll
110110- |> Wonka.subscribe((. x) => print_int(x));
111111-/* Prints 1 2 3 6 5 4 to the console. */
112112-```
113113-11473```typescript
11574import { pipe, fromArray, concatAll, subscribe } from 'wonka';
11675···12079pipe(
12180 fromArray([sourceOne, sourceTwo]),
12281 concatAll,
123123- subscribe(val => console.log(val))
8282+ subscribe((val) => console.log(val))
12483); // Prints 1 2 3 6 5 4 to the console.
12584```
12685···1288712988`concatMap` allows you to map values of an outer source to an inner source. The sink will not dispatch the `Pull` signal until the previous value has been emitted. This is in contrast to `mergeMap`, which will dispatch the `Pull` signal for new values even if the previous value has not yet been emitted.
13089131131-```reason
132132-let source = Wonka.fromArray([|1, 2, 3, 4, 5, 6|]);
133133-134134-source
135135-|> Wonka.concatMap((. _val) =>
136136- Wonka.delay(_val * 1000, Wonka.fromValue(_val))
137137- )
138138-|> Wonka.subscribe((. _val) => print_int(_val));
139139-140140-/* After 1s, 1 will be emitted. After an additional 2s, 2 will be emitted.
141141-After an additional 3s, 3 will be emitted. After an additional 4s, 4 will be emitted.
142142-After an additional 5s, 5 will be emitted. After an additional 6s, 6 will be emitted. */
143143-```
144144-14590```typescript
14691import { fromArray, pipe, concatMap, delay, fromValue, subscribe } from 'wonka';
14792···1499415095pipe(
15196 source,
152152- concatMap(val => {
153153- return pipe(
154154- fromValue(val),
155155- delay(val * 1000)
156156- );
9797+ concatMap((val) => {
9898+ return pipe(fromValue(val), delay(val * 1000));
15799 }),
158158- subscribe(val => console.log(val))
100100+ subscribe((val) => console.log(val))
159101);
160102```
161161-162103163104## delay
164105165106`delay` delays all emitted values of a source by the given amount of milliseconds.
166107167167-> _Note:_ This operator is only available in JavaScript environments, and will be excluded
168168-> when compiling natively.
169169-170170-```reason
171171-Wonka.fromList([1, 2])
172172- |> Wonka.delay(10)
173173- |> Wonka.subscribe((. x) => print_int(x));
174174-/* waits 10ms then prints 1, waits 10ms then prints 2, waits 10ms then ends */
175175-```
176176-177108```typescript
178109import { pipe, fromArray, delay, subscribe } from 'wonka';
179110···191122a given amount of milliseconds. Once this threshold of silence has been reached, the
192123last value that has been received will be emitted.
193124194194-> _Note:_ This operator is only available in JavaScript environments, and will be excluded
195195-> when compiling natively.
196196-197197-```reason
198198-let sourceA = Wonka.interval(10)
199199- |> Wonka.take(5);
200200-let sourceB = Wonka.fromValue(1);
201201-202202-Wonka.concat([|sourceA, sourceB|])
203203- |> Wonka.debounce((. _x) => 20)
204204- |> Wonka.subscribe((. x) => print_int(x));
205205-/* The five values from sourceA will be omitted */
206206-/* After these values and after 20ms `1` will be logged */
207207-```
208208-209125```typescript
210126import { pipe, interval, take, fromValue, concat, debounce, subscribe } from 'wonka';
211127···226142227143`filter` will remove values from a source by passing them through an iteratee that returns a `bool`.
228144229229-```reason
230230-let isEven = (. n) => n mod 2 === 0;
231231-232232-Wonka.fromArray([|1, 2, 3, 4, 5, 6|])
233233- |> Wonka.filter(isEven)
234234- |> Wonka.subscribe((. x) => print_int(x));
235235-/* Prints 246 to the console. */
236236-```
237237-238145```typescript
239146import { fromArray, filter, subscribe } from 'wonka';
240147241241-const isEven = n => n % 2 === 0;
148148+const isEven = (n) => n % 2 === 0;
242149243150pipe(
244151 fromArray([1, 2, 3, 4, 5, 6]),
245152 filter(isEven),
246246- subscribe(val => console.log(val))
153153+ subscribe((val) => console.log(val))
247154);
248155249156// Prints 246 to the console.
···253160254161`map` will transform values from a source by passing them through an iteratee that returns a new value.
255162256256-```reason
257257-let square = (. n) => n * n;
258258-259259-Wonka.fromArray([|1, 2, 3, 4, 5, 6|])
260260- |> Wonka.map(square)
261261- |> Wonka.subscribe((. x) => print_int(x));
262262-/* Prints 1 4 9 16 25 36 to the console. */
263263-```
264264-265163```typescript
266164import { fromArray, pipe, map, subscribe } from 'wonka';
267165268268-const square = n => n * n;
166166+const square = (n) => n * n;
269167270168pipe(
271169 fromArray([1, 2, 3, 4, 5, 6]),
272170 map(square),
273273- subscribe(val => console.log(val))
171171+ subscribe((val) => console.log(val))
274172);
275173276174// Prints 1 4 9 16 25 36 to the console.
···281179`merge` merges an array of sources together into a single source. It subscribes
282180to all sources that it's passed and emits all their values on the output source.
283181284284-```reason
285285-let sourceA = Wonka.fromArray([|1, 2, 3|]);
286286-let sourceB = Wonka.fromArray([|4, 5, 6|]);
287287-288288-Wonka.merge([|sourceA, sourceB|])
289289- |> Wonka.subscribe((. x) => print_int(x));
290290-/* Prints 1 2 3 4 5 6 to the console. */
291291-```
292292-293182```typescript
294183import { fromArray, pipe, merge, subscribe } from 'wonka';
295184···309198310199> _Note:_ This operator is also exported as `flatten` which is just an alias for `mergeAll`
311200312312-```reason
313313-let sourceA = Wonka.fromArray([|1, 2, 3|]);
314314-let sourceB = Wonka.fromArray([|4, 5, 6|]);
315315-316316-Wonka.fromList([sourceA, sourceB])
317317- |> Wonka.mergeAll
318318- |> Wonka.subscribe((. x) => print_int(x));
319319-/* Prints 1 2 3 4 5 6 to the console. */
320320-```
321321-322201```typescript
323202import { pipe, fromArray, mergeAll, subscribe } from 'wonka';
324203···328207pipe(
329208 fromArray([sourceOne, sourceTwo]),
330209 mergeAll,
331331- subscribe(val => console.log(val))
210210+ subscribe((val) => console.log(val))
332211); // Prints 1 2 3 4 5 6 to the console.
333212```
334213···341220Unlike `concatMap` all inner sources will be subscribed to at the same time
342221and all their values will be emitted on the output source as they come in.
343222344344-```reason
345345-Wonka.fromList([1, 2])
346346- |> Wonka.mergeMap((. value) =>
347347- Wonka.fromList([value - 1, value]))
348348- |> Wonka.subscribe((. x) => print_int(x));
349349-/* Prints 0 1 1 2 to the console. */
350350-```
351351-352223```typescript
353224import { pipe, fromArray, mergeMap, subscribe } from 'wonka';
354225355226pipe(
356227 fromArray([1, 2]),
357357- mergeMap(x => fromArray([x - 1, x])),
358358- subscribe(val => console.log(val))
228228+ mergeMap((x) => fromArray([x - 1, x])),
229229+ subscribe((val) => console.log(val))
359230); // Prints 0 1 1 2 to the console.
360231```
361232···363234364235Run a callback when the `End` signal has been sent to the sink by the source, whether by way of the talkback passing the `End` signal or the source being exhausted of values.
365236366366-```reason
367367-let promiseOne =
368368- Js.Promise.make((~resolve, ~reject as _) =>
369369- Js.Global.setTimeout(() => resolve(. "ResolveOne"), 1000) |> ignore
370370- );
371371-372372-let promiseTwo =
373373- Js.Promise.make((~resolve, ~reject as _) =>
374374- Js.Global.setTimeout(() => resolve(. "ResolveTwo"), 2000) |> ignore
375375- );
376376-377377-let sourceOne = Wonka.fromPromise(promiseOne);
378378-let sourceTwo = Wonka.fromPromise(promiseTwo);
379379-380380-Wonka.concat([|sourceOne, sourceTwo|])
381381- |> Wonka.onEnd((.) => print_endline("onEnd"))
382382- |> Wonka.subscribe((. x) => print_endline(x));
383383-384384-/* Logs ResolveOne after one second, then ResolveTwo after an additional second, then onEnd immediately. */
385385-```
386386-387237```typescript
388238import { fromPromise, pipe, concat, onEnd, subscribe } from 'wonka';
389239390390-const promiseOne = new Promise(resolve => {
240240+const promiseOne = new Promise((resolve) => {
391241 setTimeout(() => {
392242 resolve('ResolveOne');
393243 }, 1000);
394244});
395395-const promiseTwo = new Promise(resolve => {
245245+const promiseTwo = new Promise((resolve) => {
396246 setTimeout(() => {
397247 resolve('ResolveTwo');
398248 }, 2000);
···404254pipe(
405255 concat([sourceOne, sourceTwo]),
406256 onEnd(() => console.log('onEnd')),
407407- subscribe(val => console.log(val))
257257+ subscribe((val) => console.log(val))
408258);
409259410260// Logs ResolveOne after one second, then ResolveTwo after an additional second, then onEnd immediately.
···416266417267> _Note:_ This operator is also exported as `tap` which is just an alias for `onPush`
418268419419-```reason
420420-Wonka.fromArray([|1, 2, 3, 4, 5, 6|])
421421- |> Wonka.onPush((. x) => print_string({j|Push $x|j}))
422422- |> Wonka.subscribe((. x) => print_int(x));
423423-/* Prints Push 1 1 Push 2 2 Push 3 3 Push 4 4 Push 5 5 Push 6 6 to the console. */
424424-```
425425-426269```typescript
427270import { fromArray, pipe, onPush, subscribe } from 'wonka';
428271429272pipe(
430273 fromArray([1, 2, 3, 4, 5, 6]),
431431- onPush(val => console.log(`Push ${val}`)),
432432- subscribe(val => console.log(val))
274274+ onPush((val) => console.log(`Push ${val}`)),
275275+ subscribe((val) => console.log(val))
433276); // Prints Push 1 1 Push 2 2 Push 3 3 Push 4 4 Push 5 5 Push 6 6 to the console.
434277```
435278···437280438281Run a callback when the `Start` signal is sent to the sink by the source.
439282440440-```reason
441441-let promise =
442442- Js.Promise.make((~resolve, ~reject as _) =>
443443- Js.Global.setTimeout(() => resolve(. "Resolve"), 1000) |> ignore
444444- );
445445-446446-Wonka.fromPromise(promise)
447447- |> Wonka.onStart((.) => print_endline("onStart"))
448448- |> Wonka.subscribe((. _val) => print_endline(_val));
449449-/* Logs onStart to the console, pauses for one second to allow the timeout to finish,
450450-then logs "Resolve" to the console. */
451451-```
452452-453283```typescript
454284import { pipe, onStart, fromPromise, subscribe } from 'wonka';
455285456456-const promise = new Promise(resolve => {
286286+const promise = new Promise((resolve) => {
457287 setTimeout(() => {
458288 resolve('Resolve');
459289 }, 1000);
···462292pipe(
463293 fromPromise(promise),
464294 onStart(() => console.log('onStart')),
465465- subscribe(val => console.log(val))
295295+ subscribe((val) => console.log(val))
466296);
467297468298// Logs onStart to the console, pauses for one second to allow the timeout to finish,
···477307In combination with `interval` it can be used to get values from a noisy source
478308more regularly.
479309480480-```reason
481481-Wonka.interval(10)
482482- |> Wonka.sample(Wonka.interval(100))
483483- |> Wonka.take(2)
484484- |> Wonka.subscribe((. x) => print_int(x));
485485-/* Prints 10 20 to the console. */
486486-```
487487-488488-``` typescript
310310+```typescript
489311import { pipe, interval, sample, take, subscribe } from 'wonka';
490312491313pipe(
492314 interval(10),
493315 sample(interval(100)),
494316 take(2),
495495- subscribe(x => console.log(x))
317317+ subscribe((x) => console.log(x))
496318); // Prints 10 20 to the console.
497319```
498320···500322501323Accumulate emitted values of a source in a accumulator, similar to JavaScript `reduce`.
502324503503-```reason
504504-Wonka.fromArray([|1, 2, 3, 4, 5, 6|])
505505- |> Wonka.scan((. acc, x) => acc + x, 0)
506506- |> Wonka.subscribe((. x) => print_int(x));
507507-/* Prints 1 3 6 10 15 21 to the console. */
508508-```
509509-510325```typescript
511326import { fromArray, pipe, scan, subscribe } from 'wonka';
512327513328pipe(
514329 fromArray([1, 2, 3, 4, 5, 6]),
515330 scan((acc, val) => acc + val, 0),
516516- subscribe(val => console.log(val))
331331+ subscribe((val) => console.log(val))
517332);
518333519334// Prints 1 3 6 10 15 21 to the console.
···536351This is especially useful if you introduce side-effects to your sources,
537352for instance with `onStart`.
538353539539-```reason
540540-let source = Wonka.never
541541- |> Wonka.onStart((.) => print_endline("start"))
542542- |> Wonka.share;
543543-544544-/* Without share this would print "start" twice: */
545545-Wonka.publish(source);
546546-Wonka.publish(source);
547547-```
548548-549354```typescript
550355import { pipe, never, onStart, share, publish } from 'wonka';
551356···563368## skip
564369565370`skip` the specified number of emissions from the source.
566566-567567-```reason
568568-Wonka.fromArray([|1, 2, 3, 4, 5, 6|])
569569- |> Wonka.skip(2)
570570- |> Wonka.subscribe((. x) => print_int(x));
571571-/* Prints 3 4 5 6 to the console, since the first two emissions from the source were skipped.
572572-```
573371574372```typescript
575373import { fromArray, pipe, skip, subscribe } from 'wonka';
···577375pipe(
578376 fromArray([1, 2, 3, 4, 5, 6]),
579377 skip(2),
580580- subscribe(val => console.log(val))
378378+ subscribe((val) => console.log(val))
581379);
582380```
583381···585383586384Skip emissions from an outer source until an inner source (notifier) emits.
587385588588-```reason
589589-let source = Wonka.interval(100);
590590-let notifier = Wonka.interval(500);
591591-592592-source
593593- |> Wonka.skipUntil(notifier)
594594- |> Wonka.subscribe((. x) => print_int(x));
595595-596596-/* Skips all values emitted by source (0, 1, 2, 3) until notifier emits at 500ms.
597597-Then logs 4 5 6 7 8 9 10... to the console every 500ms. */
598598-```
599599-600386```typescript
601387import { interval, pipe, skipUntil, subscribe } from 'wonka';
602388···606392pipe(
607393 source,
608394 skipUntil(notifier),
609609- subscribe(val => console.log(val))
395395+ subscribe((val) => console.log(val))
610396);
611397612398// Skips all values emitted by source (0, 1, 2, 3) until notifier emits at 500ms.
···617403618404Skip values emitted from the source while they return `true` for the provided predicate function.
619405620620-```reason
621621-let source = Wonka.fromArray([|1, 2, 3, 4, 5, 6|]);
622622-623623-source
624624-|> Wonka.skipWhile((. _val) => _val < 5)
625625-|> Wonka.subscribe((. _val) => print_int(_val));
626626-627627-/* Prints 5 6 to the console, as 1 2 3 4 all return true for the predicate function. */
628628-```
629629-630406```typescript
631407import { fromArray, pipe, skipWhile, subscribe } from 'wonka';
632408633409pipe(
634410 fromArray([1, 2, 3, 4, 5, 6]),
635635- skipWhile(val => val < 5),
636636- subscribe(val => console.log(val))
411411+ skipWhile((val) => val < 5),
412412+ subscribe((val) => console.log(val))
637413);
638414639415// Prints 5 6 to the console, as 1 2 3 4 all return true for the predicate function.
···650426This is similar to `concatMap` but instead of waiting for the last inner source to complete
651427before emitting values from the next, `switchMap` just cancels the previous inner source.
652428653653-```reason
654654-Wonka.interval(50)
655655- |> Wonka.switchMap((. _value) =>
656656- Wonka.interval(40))
657657- |> Wonka.take(3)
658658- |> Wonka.subscribe((. x) => print_int(x));
659659-/* Prints 1 2 3 to the console. */
660660-/* The inner interval is cancelled after its first value every time */
661661-```
662662-663429```typescript
664430import { pipe, interval, switchMap, take, subscribe } from 'wonka';
665431666432pipe(
667433 interval(50),
668434 // The inner interval is cancelled after its first value every time
669669- switchMap(value => interval(40)),
435435+ switchMap((value) => interval(40)),
670436 take(3),
671671- subscribe(x => console.log(x))
437437+ subscribe((x) => console.log(x))
672438); // Prints 1 2 3 to the console
673439```
674440···680446681447It's very similar to `switchMap`, but instead accepts a source of sources.
682448683683-```reason
684684-Wonka.interval(50)
685685- |> Wonka.map((. _value) =>
686686- Wonka.interval(40))
687687- |> Wonka.switchAll
688688- |> Wonka.take(3)
689689- |> Wonka.subscribe((. x) => print_int(x));
690690-/* Prints 1 2 3 to the console. */
691691-```
692692-693449```typescript
694450import { pipe, interval, map, switchAll, take, subscribe } from 'wonka';
695451···698454 map(() => interval(40)),
699455 switchAll,
700456 take(3),
701701- subscribe(x => console.log(x))
457457+ subscribe((x) => console.log(x))
702458); // Prints 1 2 3 to the console
703459```
704460···710466711467`take` only a specified number of emissions from the source before completing. `take` is the opposite of `skip`.
712468713713-```reason
714714-Wonka.fromArray([|1, 2, 3, 4, 5, 6|])
715715- |> Wonka.take(3)
716716- |> Wonka.subscribe((. x) => print_int(x));
717717-/* Prints 1 2 3 to the console. */
718718-```
719719-720469```typescript
721470import { fromArray, pipe, take, subscribe } from 'wonka';
722471723472pipe(
724473 fromArray([1, 2, 3, 4, 5, 6]),
725474 take(3),
726726- subscribe(val => console.log(val))
475475+ subscribe((val) => console.log(val))
727476);
728477729478// Prints 1 2 3 to the console.
···733482734483`takeLast` will take only the last n emissions from the source.
735484736736-```reason
737737-Wonka.fromArray([|1, 2, 3, 4, 5, 6|]);
738738- |> Wonka.takeLast(3)
739739- |> Wonka.subscribe((. x) => print_int(x));
740740-/* Prints 4 5 6 to the console. */
741741-```
742742-743485```typescript
744486import { fromArray, pipe, takeLast, subscribe } from 'wonka';
745487746488pipe(
747489 fromArray([1, 2, 3, 4, 5, 6]),
748490 takeLast(3),
749749- subscribe(val => console.log(val))
491491+ subscribe((val) => console.log(val))
750492);
751493752494// Prints 4 5 6 to the console.
···756498757499Take emissions from an outer source until an inner source (notifier) emits.
758500759759-```reason
760760-let source = Wonka.interval(100);
761761-let notifier = Wonka.interval(500);
762762-763763-source
764764- |> Wonka.takeUntil(notifier)
765765- |> Wonka.subscribe((. x) => print_int(x));
766766-767767-/* Pauses 100ms, prints 0, pauses 100ms, prints 1, pauses 100ms, prints 2, pauses 100ms,
768768-prints 3, pauses 100, then completes (notifier emits). */
769769-```
770770-771501```typescript
772502import { interval, pipe, takeUntil, subscribe } from 'wonka';
773503···777507pipe(
778508 source,
779509 takeUntil(notifier),
780780- subscribe(val => console.log(val))
510510+ subscribe((val) => console.log(val))
781511);
782512783513// Pauses 100ms, prints 0, pauses 100ms, prints 1, pauses 100ms, prints 2, pauses 100ms,
···788518789519Take emissions from the stream while they return `true` for the provided predicate function. If the first emission does not return `true`, no values will be `Push`ed to the sink.
790520791791-```reason
792792-let source = Wonka.fromArray([|1, 2, 3, 4, 5, 6|]);
793793-794794-source
795795- |> Wonka.takeWhile((. x) => x < 5)
796796- |> Wonka.subscribe((. x) => print_int(x));
797797-798798-/* Prints 1 2 3 4 to the console. */
799799-```
800800-801521```typescript
802522import { pipe, fromArray, takeWhile, subscribe } from 'wonka';
803523···805525806526pipe(
807527 source,
808808- takeWhile(val => val < 5),
809809- subscribe(val => console.log(val))
528528+ takeWhile((val) => val < 5),
529529+ subscribe((val) => console.log(val))
810530);
811531812532// Prints 1 2 3 4 to the console.
···820540821541This is very similar to `debounce` but instead of waiting for leading time before a
822542value it waits for trailing time after a value.
823823-824824-> _Note:_ This operator is only available in JavaScript environments, and will be excluded
825825-> when compiling natively.
826826-827827-```reason
828828-Wonka.interval(10)
829829- |> Wonka.throttle((. _x) => 50)
830830- |> Wonka.take(2)
831831- |> Wonka.subscribe((. x) => print_int(x));
832832-/* Outputs 0 6 to the console. */
833833-```
834543835544```typescript
836545import { pipe, interval, throttle, take, subscribe } from 'wonka';
+7-93
docs/api/sinks.md
···991010`subscribe` accepts a callback function to execute when data is received from the source, in addition to the source itself.
11111212-```reason
1313-Wonka.fromArray([|1, 2, 3|])
1414- |> Wonka.subscribe((. x) => print_int(x));
1515-/* Prints 123 to the console. */
1616-```
1717-1812```typescript
1913import { pipe, fromArray, subscribe } from 'wonka';
2014···2721`subscribe` also returns a "subscription" type, which can be used to
2822unsubscribe from the source. This allows you to cancel a source and stop receiving
2923new incoming values.
3030-3131-```reason
3232-let subscription = source
3333- |> Wonka.subscribe((. x) => print_int(x));
3434-3535-subscription.unsubscribe();
3636-```
37243825```typescript
3926import { pipe, subscribe } from 'wonka';
···5138`forEach` works the same as `subscribe` but doesn't return a subscription.
5239It will just call the passed callback for each incoming value.
53405454-```reason
5555-Wonka.fromArray([|1, 2, 3|])
5656- |> Wonka.forEach((. x) => print_int(x));
5757-/* Returns unit; Prints 123 to the console. */
5858-```
5959-6041```typescript
6142import { pipe, fromArray, forEach } from 'wonka';
6243···7556In this example we're using [`onPush`](./operators.md#onpush) to pass a callback to react to incoming
7657values instead.
77587878-```reason
7979-Wonka.fromArray([|1, 2, 3|])
8080- |> Wonka.onPush((. x) => print_int(x))
8181- |> Wonka.publish;
8282-/* Prints 123 to the console. */
8383-```
8484-8559```typescript
8660import { pipe, fromArray, onPush, publish } from 'wonka';
8761···10478> _Note:_ If you're using this sink, make sure that your input source streams
10579> the values you're collecting partly or fully synchronously.
10680107107-```reason
108108-Wonka.fromArray([|1, 2, 3|])
109109- |> Wonka.map((. x) => x * 2)
110110- |> Wonka.toArray
111111-/* Returns [|2, 4, 6|] */
112112-```
113113-11481```typescript
11582import { pipe, fromArray, map, toArray } from 'wonka';
1168311784pipe(
11885 fromArray([1, 2, 3]),
119119- map(x => x * 2),
8686+ map((x) => x * 2),
12087 toArray
12188); // Returns [2, 4, 6]
12289```
···1259212693`toPromise` returns a promise, which resolves on the last value of a source.
12794128128-> _Note:_ This source is only available in JavaScript environments, and will be excluded
129129-> when compiling natively.
130130-131131-```reason
132132-Wonka.fromArray([|1, 2, 3|])
133133- |> Wonka.toPromise
134134- |> Js.Promise.then_(x => {
135135- print_int(x);
136136- Js.Promise.resolve(())
137137- })
138138-/* Prints 3 to the console. */
139139-```
140140-14195```typescript
14296import { pipe, fromArray, toPromise } from 'wonka';
14397144144-const promise = pipe(
145145- fromArray([1, 2, 3]),
146146- toPromise,
147147-);
9898+const promise = pipe(fromArray([1, 2, 3]), toPromise);
14899149149-promise.then(x => console.log(x));
100100+promise.then((x) => console.log(x));
150101// Prints 3 to the console.
151102```
152103···160111161112As per the specification, the Observable is annotated using `Symbol.observable`.
162113163163-> _Note:_ This sink is only available in JavaScript environments, and will be excluded
164164-> when compiling natively.
165165-166166-```reason
167167-let observable = Wonka.fromArray([|1, 2, 3|])
168168- |> Wonka.toObservable;
169169-170170-observable##subscribe([@bs] {
171171- as _;
172172- pub next = value => print_int(value);
173173- pub complete = () => ();
174174- pub error = _ => ();
175175-}); /* Prints 1 2 3 to the console. */
176176-```
177177-178114```typescript
179115import { pipe, fromArray, toObservable } from 'wonka';
180116181181-const observable = pipe(
182182- fromArray([1, 2, 3]),
183183- toObservable,
184184-);
117117+const observable = pipe(fromArray([1, 2, 3]), toObservable);
185118186119observable.subscribe({
187187- next: value => console.log(value),
120120+ next: (value) => console.log(value),
188121 complete: () => {},
189122 error: () => {},
190123}); // Prints 1 2 3 to the console.
···199132minimally, Callbags map to Wonka's sources very closely and `toCallbag` only creates a thin
200133wrapper which is mostly concerned with converting between the type signatures.
201134202202-> _Note:_ This sink is only available in JavaScript environments, and will be excluded
203203-> when compiling natively.
204204-205205-```reason
206206-/* This example uses the callbag-iterate package for illustrative purposes */
207207-[@bs.module] external callbagIterate:
208208- (. ('a => unit)) => (. Wonka.callbagT('a)) => unit = "callbag-iterate";
209209-210210-let callbag = Wonka.fromArray([|1, 2, 3|])
211211- |> Wonka.toCallbag;
212212-213213-callbagIterate(. value => {
214214- print_int(value);
215215-})(. callbag); /* Prints 1 2 3 to the console. */
216216-```
217217-218135```typescript
219136import { pipe, fromArray, toCallbag } from 'wonka';
220137221138// This example uses the callbag-iterate package for illustrative purposes
222139import callbagIterate from 'callbag-iterate';
223140224224-const callbag = pipe(
225225- fromArray([1, 2, 3]),
226226- toCallbag,
227227-);
141141+const callbag = pipe(fromArray([1, 2, 3]), toCallbag);
228142229229-callbagIterate(value => console.log(value))(callbag);
143143+callbagIterate((value) => console.log(value))(callbag);
230144// Prints 1 2 3 to the console.
231145```
+13-150
docs/api/sources.md
···991010`fromArray` transforms an array into a source, emitting each item synchronously.
11111212-```reason
1313-Wonka.fromArray([|1, 2, 3|]);
1414-```
1515-1612```typescript
1713import { fromArray } from 'wonka';
1814fromArray([1, 2, 3]);
1915```
20162121-## fromList
2222-2323-`fromList` transforms a list into a source, emitting each item synchronously.
2424-2525-> _Note:_ This operator is only useful in Reason / OCaml where lists are a builtin
2626-> data structure.
2727-2828-This is otherwise functionally the same as `fromArray`.
2929-3030-```reason
3131-Wonka.fromList([1, 2, 3]);
3232-```
3333-3417## fromValue
35183619`fromValue` takes a single value and creates a source that emits the value and
3720completes immediately afterwards.
38213939-```reason
4040-Wonka.fromValue("a value");
2222+```typescript
2323+import { fromValue } from 'wonka';
2424+fromValue(1);
4125```
42264327## make
···59436044In this example we create a source that waits for a promise to resolve and emits
6145values from the array of that promise.
6262-6363-```reason
6464-let waitForArray = () => Js.Promise.resolve([|1, 2, 3|]);
6565-6666-let source = Wonka.make((. observer) => {
6767- let (next, complete) = observer;
6868- let cancelled = ref(false);
6969- let promise = waitForArray();
7070-7171- Js.Promise.then_(arr => {
7272- if (!cancelled^) {
7373- Array.iter(next, arr);
7474- complete();
7575- }
7676- }, promise);
7777-7878- () => cancelled := true;
7979-});
8080-```
81468247```typescript
8348import { make } from 'wonka';
84498550const waitForArray = () => Promise.resolve([1, 2, 3]);
86518787-const source = make(observer => {
5252+const source = make((observer) => {
8853 const { next, complete } = observer;
8954 let cancelled = false;
90559191- waitForArray().then(arr => {
5656+ waitForArray().then((arr) => {
9257 if (!cancelled) {
9358 arr.forEach(next);
9459 complete();
···11176around but also have access to the observer functions to emit events away from
11277the source itself.
11378114114-```reason
115115-let subject = Wonka.makeSubject();
116116-let { source, next, complete } = subject;
117117-118118-/* This will push the values synchronously to any subscribers of source */
119119-next(1);
120120-next(2);
121121-next(complete);
122122-```
123123-12479```typescript
125125-import { makeSubject } from 'wonka'
8080+import { makeSubject } from 'wonka';
12681const subject = makeSubject();
12782const { source, next, complete } = subject;
12883···13792`fromDomEvent` will turn a DOM event into a Wonka source, emitting the DOM events
13893on the source whenever the DOM emits them on the passed element.
13994140140-> _Note:_ This source is only available in JavaScript environments, and will be excluded
141141-> when compiling natively.
142142-143143-```reason
144144-open Webapi.Dom;
145145-open Document;
146146-147147-let element = getElementById("root", document)->Belt.Option.getExn;
148148-149149-Wonka.fromDomEvent(element, "click")
150150- |> Wonka.subscribe((. click) => Js.log(click));
151151-```
152152-15395```typescript
15496import { pipe, fromDomEvent, subscribe } from 'wonka';
15597···15799158100pipe(
159101 fromDomEvent(element, 'click'),
160160- subscribe(e => console.log(e))
102102+ subscribe((e) => console.log(e))
161103);
162104```
163105···166108`fromPromise` transforms a promise into a source, emitting the promisified value on
167109the source once it resolves.
168110169169-> _Note:_ This source is only available in JavaScript environments, and will be excluded
170170-> when compiling natively.
171171-172172-```reason
173173-let promise = Js.Promise.make(1); /* Just an example promise */
174174-175175-Wonka.fromPromise(promise)
176176- |> Wonka.subscribe((. x) => Js.log(x));
177177-/* Prints 1 to the console. */
178178-```
179179-180111```typescript
181112import { pipe, fromPromise, subscribe } from 'wonka';
182113···184115185116pipe(
186117 fromPromise(promise),
187187- subscribe(e => console.log(e))
118118+ subscribe((e) => console.log(e))
188119); // Prints 1 to the console.
189120```
190121···193124`fromObservable` transforms a [spec-compliant JS Observable](https://github.com/tc39/proposal-observable) into a source.
194125The resulting source will behave exactly the same as the Observable that it was
195126passed, so it will start, end, and push values identically.
196196-197197-> _Note:_ This source is only available in JavaScript environments, and will be excluded
198198-> when compiling natively.
199127200128```typescript
201129import { pipe, fromObservable, subscribe } from 'wonka';
···207135208136pipe(
209137 fromObservable(observable),
210210- subscribe(e => console.log(e))
138138+ subscribe((e) => console.log(e))
211139); // Prints 1 2 3 to the console
212140```
213141214214-If you're using Reason in a JavaScript environment and you're interested in this
215215-operator, you may be using a library to create or get Observables.
216216-217217-Some libraries don't expose Observables with the same BuckleScript type signature
218218-that Wonka uses to type them. So while Wonka's `observableT` type is fairly
219219-lenient it may not work for you.
220220-221221-```reason
222222-type observableT('a) = {.
223223- [@bs.meth] "subscribe": observerT('a) => subscriptionT
224224-};
225225-```
226226-227227-To work around this you can create a function that casts your observable type
228228-to Wonka's `observableT`.
229229-230230-```reason
231231-type yourObservableType('a);
232232-external asObservable: yourObservableType('a) => Wonka.observableT('a) = "%identity";
233233-```
234234-235235-This snippet would create an `asObservable` function, which can type-cast your
236236-Observable type to `Wonka.observableT` and compiles away completely.
237237-238142## fromCallbag
239143240144`fromCallbag` transforms a [spec-compliant JS Callbag](https://github.com/callbag/callbag) into a source.
···243147minimally, Callbags map to Wonka's sources very closely and the `fromCallbag` wrapper
244148is very thin and mostly concerned with converting between the type signatures.
245149246246-> _Note:_ This source is only available in JavaScript environments, and will be excluded
247247-> when compiling natively.
248248-249249-```reason
250250-/* This example uses the callbag-from-iter package for illustrative purposes */
251251-[@bs.module] external callbagFromArray:
252252- array('a) => Wonka.callbagT('a) = "callbag-from-iter";
253253-254254-let callbag = callbagFromArray([|1, 2, 3|]);
255255-256256-Wonka.fromCallbag(callbag)
257257- |> Wonka.subscribe((. x) => Js.log(x));
258258-/* Prints 1 2 3 to the console. */
259259-```
260260-261150```typescript
262151import { pipe, fromCallbag, subscribe } from 'wonka';
263152···268157269158pipe(
270159 fromCallbag(callbag),
271271- subscribe(e => console.log(e))
160160+ subscribe((e) => console.log(e))
272161); // Prints 1 2 3 to the console.
273162```
274163···277166`interval` creates a source that emits values after the given amount of milliseconds.
278167Internally it uses `setInterval` to accomplish this.
279168280280-> _Note:_ This source is only available in JavaScript environments, and will be excluded
281281-> when compiling natively.
282282-283283-```reason
284284-Wonka.interval(50)
285285- |> Wonka.subscribe((. x) => Js.log(x));
286286-/* Prints 0 1 2... to the console. */
287287-/* The incrementing number is logged every 50ms */
288288-```
289289-290169```typescript
291170import { pipe, interval, subscribe } from 'wonka';
292171293172pipe(
294173 interval(50),
295295- subscribe(e => console.log(e))
174174+ subscribe((e) => console.log(e))
296175); // Prints 0 1 2... to the console.
297176// The incrementing number is logged every 50ms
298177```
···302181This is a source that doesn't emit any values when subscribed to and
303182immediately completes.
304183305305-```reason
306306-Wonka.empty
307307- |> Wonka.forEach((. value) => {
308308- /* This will never be called */
309309- ()
310310- });
311311-```
312312-313184```typescript
314185import { pipe, empty, forEach } from 'wonka';
315186316187pipe(
317188 empty,
318318- forEach(value => {
189189+ forEach((value) => {
319190 /* This will never be called */
320191 })
321192);
···326197This is source is similar to [`empty`](#empty).
327198It doesn't emit any values but also never completes.
328199329329-```reason
330330-Wonka.never
331331- |> Wonka.forEach((. value) => {
332332- /* This will never be called */
333333- ()
334334- });
335335-```
336336-337200```typescript
338201import { pipe, never, forEach } from 'wonka';
339202340203pipe(
341204 never,
342342- forEach(value => {
205205+ forEach((value) => {
343206 /* This will never be called */
344207 })
345208);
+27-27
docs/basics/architecture.md
···2222Because a sink has a start, incoming values, and an end, there are three
2323signals that a sink can receive: `Start`, `Push`, and `End`.
24242525-``` reason
2626-type signalT('a) =
2727- | Start
2828- | Push('a)
2929- | End;
2525+```typescript
2626+type Start = { tag: 0 }; // & [TalkbackFn]
2727+type Push<T> = { tag: 1 } & [T];
2828+type End = 0;
2929+3030+type Signal<T> = Start | Push<T> | End;
30313131-type sinkT('a) = (. signalT('a)) => unit;
3232+type Sink<T> = (signal: Signal<T>) => void;
3233```
33343435As shown, the sink is just a function accepting a signal as its argument.
35363637When the stream starts then the sink is called with `Start`,
3737-Then for every incoming, new value it's called with `Push('a)`,
3838+Then for every incoming, new value it's called with `Push<T>`,
3839and when the stream ends it's finally called with `End`.
39404041Since we want a source to send these values to the sink, the source is
4142also just a function and it accepts a sink as its argument.
42434343-``` reason
4444-type sourceT('a) = sinkT('a) => unit;
4444+```typescript
4545+type Source<T> = (sink: Sink<T>) => void;
4546```
46474748This is completely sufficient to represent simple "push" streams, where
···55565657The type signature of an operator with no other arguments is thus:
57585858-``` reason
5959-type operatorT('a, 'b) = sourceT('a) => sourceT('b);
5959+```typescript
6060+type Operator<In, Out> = (source: Source<In>) => Source<Out>;
6061/* which is the same as: */
6161-type operatorT('a, 'b) = (sourceT('a), sinkT('b)) => unit;
6262+type Operator<In, Out> = (source: Source<In>) => (sink: Sink<Out>) => void;
6263```
63646465## Adding Callbacks
···7677In Wonka, a sink's `Start` signal also carries a callback that is used to communicate
7778back to the source, making these "talkback signals" flow from the bottom to the top.
78797979-``` reason
8080-type talkbackT =
8181- | Pull
8282- | Close;
8080+```typescript
8181+const enum TalkbackKind {
8282+ Pull = 0,
8383+ Close = 1,
8484+}
83858484-type signalT('a) =
8585- | Start((. talkbackT) => unit)
8686- | Push('a)
8787- | End;
8686+type TalkbackFn = (signal: TalkbackKind) => void;
8787+type Start = { tag: 0 } & [TalkbackFn];
8888```
89899090-This is like the previous `signalT('a)` definition, but the `Start` signal has the
9090+This is like the previous `Signal<T>` definition, but the `Start` signal has the
9191callback definition now. The callback accepts one of two signals: `Pull` or `Close`.
92929393`Close` is a signal that will cancel the stream. It tells the source to stop sending
···117117In Wonka there's a separate type for subjects however, since this reduces the
118118complexity of its streams a lot:
119119120120-``` reason
121121-type subjectT('a) = {
122122- source: sourceT('a),
123123- next: 'a => unit,
124124- complete: unit => unit,
125125-};
120120+```reason
121121+interface Subject<T> {
122122+ next(value: T): void;
123123+ complete(): void;
124124+ source: Source<T>;
125125+}
126126```
127127128128Hence in Wonka a subject is simply a wrapper around a source and a `next` and `complete`
+6-15
docs/index.md
···21212222It also comes with many operators that users from [RxJS](https://github.com/ReactiveX/rxjs) will be used to.
23232424-## Compatibility
2424+## Reason Support
25252626-Wonka is written in [Reason](https://reasonml.github.io/), a dialect of OCaml, and can hence be used
2727-for native applications. It is also compiled using [BuckleScript](https://bucklescript.github.io) to plain
2828-JavaScript and has typings for [TypeScript](https://www.typescriptlang.org/) and [Flow](https://flow.org/).
2626+Wonka used to be written in [Reason](https://reasonml.github.io/),, a dialect of OCaml, and was usable
2727+for native development and compileable with [BuckleScript](https://bucklescript.github.io).
2828+Out of the box it supported usage with BuckleScript, `bs-native`, Dune, and Esy.
29293030-This means that out of the box Wonka is usable in any project that use the following:
3131-3232-- Plain JavaScript
3333-- TypeScript
3434-- Flow
3535-- Reason/OCaml with BuckleScript
3636-- Reason/OCaml with `bs-native`
3737-- Reason/OCaml with Dune and Esy
3838-3939-In summary, Wonka provides a consistent interface in and works across
4040-TypeScript/Flow/Reason/OCaml environments with full type safety.
3030+If you're looking for the legacy version that supported this, you may want to install v4 or v5 rather
3131+than v6 onwards, which converted the project to TypeScript.
41324233## About the docs
4334
+17
docs/migration.md
···66This page lists breaking changes and migration guides for
77various major releases of Wonka.
8899+## v6.0.0
1010+1111+In `v6.0.0` of Wonka, we've migrated fully to TypeScript.
1212+If you're using this project with Reason or OCaml before, we're sorry for
1313+the inconvenience. However, v4 and v5-rc will remain usable for these
1414+platforms and languages.
1515+1616+The internal API and data structures of Wonka haven't changed in `v6.0.0`
1717+compared to the prior releases and are based on `v4.0.14`. This means that
1818+from a TypeScript, Flow, and JS perspective, `v6.0.0` is backwards compatible
1919+and continues to function as before.
2020+2121+However, the `fromList` API has been removed so far, and we reserve ourselves
2222+room to make more breaking changes were behaviour before was broken.
2323+2424+We're also dropping IE11 support and are now bundling against an ES2015 target.
2525+926## v4.0.0
10271128In `v4.0.0` of Wonka, we've migrated to BuckleScript v7 and