UNPKG

wonka

Version:

A tiny but capable push & pull stream library for TypeScript and Flow

1,348 lines (1,326 loc) 58.5 kB
/** * Talkback signal that sends instructions from a sink to a source. * * @remarks * This signal is issued via {@link TalkbackFn | talkback functions} that a {@link Sink} receives via * the {@link Start} signal, to tell a {@link Source} to either send a new value (pulling) or stop * sending values altogether (cancellation). */ declare enum TalkbackKind { /** Instructs the {@link Source} to send the next value. */ Pull = 0, /** Instructs the {@link Source} to stop sending values and cancels it. */ Close = 1, } /** * Talkback callback that sends instructions to a source. * * @remarks * This function sends a {@link TalkbackKind} signal to the source to instruct it to send a new value * (pulling) or to be cancelled and stop sending values altogether. */ type TalkbackFn = (signal: TalkbackKind) => void; /** * Callback that is called when a source is cancelled. * * @remarks * This is used, in particular, in the {@link make | make Source} and is a returned function that is * called when the {@link TalkbackKind.Close} signal is received by the source. */ type TeardownFn = () => void; /** * Tag enum that is used to on signals that are sent from a source to a sink. * * @remarks * This signal is issued by a {@link Source} and {@link Sink | Sinks} are called with it. The signals * carrying values ({@link Start} and {@link Push}) are sent as a unary `[T]` tuple tagged with * {@link Tag}. The {@link End} signal carries no value and is sent as a raw `0` value. * @see {@link Start} for the data structure of the start signal. * @see {@link Push} for the data structure of the push signal, carrying values. */ declare enum SignalKind { /** * Informs the {@link Sink} that it's being called by a {@link Source}. * * @remarks * This starts the stream of values and carries a {@link TalkbackFn | talkback function} with it * that is used by the {@link Sink} to communicate back to the {@link Source}. * @see {@link Start} for the data structure of the signal. */ Start = 0, /** * Informs the {@link Sink} of a new values that's incoming from the {@link Source}. * * @remarks * This informs the {@link Sink} of new values that are sent by the {@link Source}. * @see {@link Push} for the data structure of the signal. */ Push = 1, /** * Informs the {@link Sink} that the {@link Source} has ended and that it won't send more values. * * @remarks * This signal signifies that the stream has stopped and that no more values are expected. Some * sources don't have a set end or limit on how many values will be sent. This signal is not sent * when the {@link Source} is cancelled with a {@link TalkbackKind.Close | Close talkback signal}. */ End = 0, } /** * The tag property that's put on unary `[T]` tuple to turn them into signals carrying values. * * @internal */ interface Tag<T> { tag: T; } /** * Indicates the start of a stream to a {@link Sink}. * * @remarks * This signal is sent from a {@link Source} to a {@link Sink} at the start of a stream to inform it * that values can be pulled and/or will be sent. This signal carries a * {@link TalkbackFn | talkback function} that is used by the {@link Sink} to communicate back to the * {@link Source} as a callback. The talkback accepts {@link TalkbackKind.Pull | Pull} and * {@link TalkbackKind.Close | Close} signals. */ type Start<_T> = Tag<SignalKind.Start> & [TalkbackFn]; /** * Sends a new value to a {@link Sink}. * * @remarks * This signal is sent from a {@link Source} to a {@link Sink} to send a new value to it. This is * essentially the signal that wraps new values coming in, like an event. Values are carried on * unary tuples and can be accessed using `signal[0]`. */ type Push<T> = Tag<SignalKind.Push> & [T]; /** * Signals are sent from {@link Source | Sources} to {@link Sink | Sinks} to inform them of changes. * * @remarks * A {@link Source}, when consumed, sends a sequence of events to {@link Sink | Sinks}. In order, a * {@link SignalKind.Start | Start} signal will always be sent first, followed optionally by one or * more {@link SignalKind.Push | Push signals}, carrying values and representing the stream. A * {@link Source} will send the {@link SignalKind.End | End signal} when it runs out of values. The * End signal will be omitted if the Source is cancelled by a * {@link TalkbackKind.Close | Close signal}, sent back from the {@link Sink}. * @see {@link SignalKind} for the kinds signals sent by {@link Source | Sources}. * @see {@link Start} for the data structure of the start signal. * @see {@link Push} for the data structure of the push signal. */ type Signal<T> = Start<T> | Push<T> | SignalKind.End; /** * Callback function that is called by a {@link Source} with {@link Signal | Signals}. * * @remarks * A Sink is a function that is called repeatedly with signals from a {@link Source}. It represents * the receiver of the stream of signals/events coming from a {@link Source}. * @see {@link Signal} for the data structure of signals. */ type Sink<T> = (signal: Signal<T>) => void; /** Factory function that calls {@link Sink | Sinks} with {@link Signal | Signals} when invoked. * @remarks * A Source is a factory function that when invoked with a {@link Sink}, calls it with * {@link Signal | Signals} to create a stream of events, informing it of new values and the * potential end of the stream of values. The first signal a Source sends is always a * {@link Start | Start signal} that sends a talkback function to the {@link Sink}, so it may request * new values or cancel the source. * * @see {@link Signal} for the data structure of signals. * @see {@link Sink} for the data structure of sinks. */ type Source<T> = (sink: Sink<T>) => void; /** Transform function that accepts a {@link Source} and returns a new one. * @remarks * Wonka comes with several helper operators that transform a given {@link Source} into a new one, * potentially changing its outputs, or the outputs' timing. An "operator" in Wonka typically * accepts arguments and then returns this kind of function, so they can be chained and composed. * * @see {@link pipe | `pipe`} for the helper used to compose operators. */ type Operator<In, Out> = (a: Source<In>) => Source<Out>; /** Type utility to determine the type of a {@link Source}. */ type TypeOfSource<T> = T extends Source<infer U> ? U : never; /** Subscription object that can be used to cancel a {@link Source}. * @see {@link subscribe | subscribe sink} for a helper that returns this structure. */ interface Subscription { /** * Cancels a {@link Source} to stop the subscription from receiving new values. * * @see {@link TalkbackKind.Close | Close signal} This uses the {@link TalkbackFn | talkback function} to send a {@link TalkbackKind.Close | Close signal} * to the subscribed-to {@link Source} to stop it from sending new values. This cleans up the subscription * and ends it immediately. */ unsubscribe(): void; } /** An Observer represents sending signals manually to a {@link Sink}. * @remarks * The Observer is used whenever a utility allows for signals to be sent manually as a {@link Source} * would send them. * * @see {@link make | `make` source} for a helper that uses this structure. */ interface Observer<T> { /** Sends a new value to the receiving Sink. * @remarks * This creates a {@link Push | Push signal} that is sent to a {@link Sink}. */ next(value: T): void; /** Indicates to the receiving Sink that no more values will be sent. * @remarks * This creates an {@link SignalKind.End | End signal} that is sent to a {@link Sink}. The Observer * will accept no more values via {@link Observer.next | `next` calls} once this method has been * invoked. */ complete(): void; } /** Subjects combine a {@link Source} with the {@link Observer} that is used to send values on said Source. * @remarks * A Subject is used whenever an event hub-like structure is needed, as it both provides the * {@link Observer}'s methods to send signals, as well as the `source` to receive said signals. * * @see {@link makeSubject | `makeSubject` source} for a helper that creates this structure. */ interface Subject<T> extends Observer<T> { /** The {@link Source} that issues the signals as the {@link Observer} methods are called. */ source: Source<T>; } /** Async Iterable/Iterator after having converted a {@link Source}. * @see {@link toAsyncIterable} for a helper that creates this structure. */ interface SourceIterable<T> extends AsyncIterator<T>, AsyncIterable<T> {} /** Helper creating a Source from a factory function when it's subscribed to. * @param produce - A factory function returning a {@link Source}. * @returns A {@link Source} lazyily subscribing to the Source returned by the given factory * function. * * @remarks * At times it's necessary to create a {@link Source} lazily. The time of a {@link Source} being * created could be different from when it's subscribed to, and hence we may want to split the * creation and subscription time. This is especially useful when the Source we wrap is "hot" and * issues values as soon as it's created, which we may then not receive in a subscriber. * * @example An example of creating a {@link Source} that issues the timestamp of subscription. Here * we effectively use `lazy` with the simple {@link fromValue | `fromValue`} source, to quickly * create a Source that issues the time of its subscription, rather than the time of its creation * that it would otherwise issue without `lazy`. * * ```ts * lazy(() => fromValue(Date.now())); * ``` */ declare function lazy<T>(produce: () => Source<T>): Source<T>; /** Converts an AsyncIterable to a Source that pulls and issues values from it as requested. * * @see {@link fromIterable | `fromIterable`} for the non-async Iterable version of this helper, * which calls this helper automatically as needed. * * @param iterable - An {@link AsyncIterable | `AsyncIterable`}. * @returns A {@link Source} issuing values sourced from the Iterable. * * @remarks * `fromAsyncIterable` will create a {@link Source} that pulls and issues values from a given * {@link AsyncIterable}. This can be used in many interoperability situations, including to consume * an async generator function. * * When the {@link Sink} throws an exception when a new value is pushed, this helper will rethrow it * using {@link AsyncIterator.throw}, which allows an async generator to recover from the exception. * * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#the_async_iterator_and_async_iterable_protocols} * for the JS Iterable protocol. */ declare function fromAsyncIterable<T>(iterable: AsyncIterable<T> | AsyncIterator<T>): Source<T>; /** Converts an Iterable to a Source that pulls and issues values from it as requested. * @see {@link fromAsyncIterable | `fromAsyncIterable`} for the AsyncIterable version of this helper. * @param iterable - An {@link Iterable | `Iterable`} or an `AsyncIterable` * @returns A {@link Source} issuing values sourced from the Iterable. * * @remarks * `fromIterable` will create a {@link Source} that pulls and issues values from a given * {@link Iterable | JS Iterable}. As iterables are the common standard for any lazily iterated list * of values in JS it can be applied to many different JS data types, including a JS Generator * function. * * This Source will only call {@link Iterator.next} on the iterator when the subscribing {@link Sink} * has pulled a new value with the {@link TalkbackKind.Pull | Pull signal}. `fromIterable` can * therefore also be applied to "infinite" iterables, without a predefined end. * * This helper will call {@link fromAsyncIterable | `fromAsyncIterable`} automatically when the * passed object also implements the async iterator protocol. * * When the {@link Sink} throws an exception when a new value is pushed, this helper will rethrow it * using {@link Iterator.throw}, which allows a generator to recover from the exception. * * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#the_iterable_protocol} * for the JS Iterable protocol. */ declare function fromIterable<T>(iterable: Iterable<T> | AsyncIterable<T>): Source<T>; /** Creates a Source that issues a each value of a given array synchronously. * @see {@link fromIterable} which `fromArray` aliases. * @param array - The array whose values will be issued one by one. * @returns A {@link Source} issuing the array's values. * * @remarks * `fromArray` will create a {@link Source} that issues the values of a given JS array one by one. It * will issue values as they're pulled and is hence a "cold" source, not eagerly emitting values. It * will end and issue the {@link SignalKind.End | End signal} when the array is exhausted of values. * * @example * ```ts * fromArray([1, 2, 3]); * ``` */ declare const fromArray: <T>(array: T[]) => Source<T>; /** Creates a Source that issues a single value and ends immediately after. * @param value - The value that will be issued. * @returns A {@link Source} issuing the single value. * * @example * ```ts * fromValue('test'); * ``` */ declare function fromValue<T>(value: T): Source<T>; /** Creates a new Source from scratch from a passed `subscriber` function. * @param subscriber - A callback that is called when the {@link Source} is subscribed to. * @returns A {@link Source} created from the `subscriber` parameter. * * @remarks * `make` is used to create a new, arbitrary {@link Source} from scratch. It calls the passed * `subscriber` function when it's subscribed to. * * The `subscriber` function receives an {@link Observer}. You may call {@link Observer.next} to * issue values on the Source, and {@link Observer.complete} to end the Source. * * Your `subscribr` function must return a {@link TeardownFn | teardown function} which is only * called when your source is cancelled — not when you invoke `complete` yourself. As this creates a * "cold" source, every time this source is subscribed to, it will invoke the `subscriber` function * again and create a new source. * * @example * * ```ts * make(observer => { * const frame = requestAnimationFrame(() => { * observer.next('animate!'); * }); * return () => { * cancelAnimationFrame(frame); * }; * }); * ``` */ declare function make<T>(subscriber: (observer: Observer<T>) => TeardownFn): Source<T>; /** Creates a new Subject which can be used as an IO event hub. * @returns A new {@link Subject}. * * @remarks * `makeSubject` creates a new {@link Subject}. A Subject is a {@link Source} and an {@link Observer} * combined in one interface, as the Observer is used to send new signals to the Source. This means * that it's "hot" and hence all subscriptions to {@link Subject.source} share the same underlying * signals coming from {@link Subject.next} and {@link Subject.complete}. * * @example * ```ts * const subject = makeSubject(); * pipe(subject.source, subscribe(console.log)); * // This will log the string on the above subscription * subject.next('hello subject!'); * ``` */ declare function makeSubject<T>(): Subject<T>; /** A {@link Source} that immediately ends. * @remarks * `empty` is a {@link Source} that immediately issues an {@link SignalKind.End | End signal} when * it's subscribed to, ending immediately. * * @see {@link never | `never`} for a source that instead never ends. */ declare const empty: Source<any>; /** A {@link Source} without values that never ends. * @remarks * `never` is a {@link Source} that never issues any signals and neither sends values nor ends. * * @see {@link empty | `empty`} for a source that instead ends immediately. */ declare const never: Source<any>; /** Creates a Source that issues an incrementing integer in intervals. * @param ms - The interval in milliseconds. * @returns A {@link Source} issuing an incrementing count on each interval. * * @remarks * `interval` will create a {@link Source} that issues an incrementing counter each time the `ms` * interval expires. * * It'll only stop when it's cancelled by a {@link TalkbackKind.Close | Close signal}. * * @example * An example printing `0`, then `1`, and so on, in intervals of 50ms. * * ```ts * pipe(interval(50), subscribe(console.log)); * ``` */ declare function interval(ms: number): Source<number>; /** Converts DOM Events to a Source given an `HTMLElement` and an event's name. * @param element - The {@link HTMLElement} to listen to. * @param event - The DOM Event name to listen to. * @returns A {@link Source} issuing the {@link Event | DOM Events} as they're issued by the DOM. * * @remarks * `fromDomEvent` will create a {@link Source} that listens to the given element's events and issues * them as values on the source. This source will only stop when it's cancelled by a * {@link TalkbackKind.Close | Close signal}. * * @example * An example printing `'clicked!'` when the given `#root` element is clicked. * * ```ts * const element = document.getElementById('root'); * pipe( * fromDomEvent(element, 'click'), * subscribe(() => console.log('clicked!')) * ); * ``` */ declare function fromDomEvent(element: HTMLElement, event: string): Source<Event>; /** Converts a Promise to a Source that issues the resolving Promise's value and then ends. * @param promise - The promise that will be wrapped. * @returns A {@link Source} issuing the promise's value when it resolves. * * @remarks * `fromPromise` will create a {@link Source} that issues the {@link Promise}'s resolving value * asynchronously and ends immediately after resolving. * * This helper will not handle the promise's exceptions, and will cause uncaught errors if the * promise rejects without a value. * * @example * An example printing `'resolved!'` when the given promise resolves after a tick. * * ```ts * pipe(fromPromise(Promise.resolve('resolved!')), subscribe(console.log)); * ``` */ declare function fromPromise<T>(promise: Promise<T>): Source<T>; /** Buffers values and emits the array of bufferd values each time a `notifier` Source emits. * * @param notifier - A {@link Source} that releases the current buffer. * @returns An {@link Operator}. * * @remarks * `buffer` will buffer values from the input {@link Source}. When the passed `notifier` Source * emits, it will emit an array of all buffered values. * * This can be used to group values over time. A buffer will only be emitted when it contains any * values. * * @example * ```ts * pipe( * interval(50), * buffer(interval(100)), * subscribe(x => { * console.log(text); // logs: [0], [1, 2], [3, 4]... * }) * ); * ``` */ declare function buffer<S, T>(notifier: Source<S>): Operator<T, T[]>; /** Emits in order from the Sources returned by a mapping function per value of the Source. * * @param map - A function returning a {@link Source} per value. * @returns An {@link Operator}. * * @remarks * `concatMap` accepts a mapping function which must return a {@link Source} per value. * The output {@link Source} will emit values from each Source the function returned, in order, * queuing sources that aren't yet active. * * This can be used to issue multiple values per emission of an input {@link Source}, while keeping * the order of their outputs consistent. * * @example * ```ts * pipe( * fromArray([1, 2]), * concatMap(x => fromArray([x, x * 2])), * subscribe(x => { * console.log(text); // logs: 1, 2, 2, 4 * }) * ); * ``` */ declare function concatMap<In, Out>(map: (value: In) => Source<Out>): Operator<In, Out>; /** Flattens a Source emitting Sources into a single Source emitting the inner values in order. * * @see {@link concatMap} which this helper uses and instead accept a mapping function. * @param source - An {@link Source} emitting {@link Source | Sources}. * @returns A {@link Source} emitting values from the inner Sources. * * @remarks * `concatAll` accepts a {@link Source} emitting {@link Source | Sources}. * The output {@link Source} will emit values from each Source, in order, queuing sources that * aren't yet active. * * @example * ```ts * pipe( * fromArray([ * fromArray([1, 2]), * fromArray([3, 4]), * ]), * concatAll, * subscribe(x => { * console.log(text); // logs: 1, 2, 3, 4 * }) * ); * ``` */ declare function concatAll<T>(source: Source<Source<T>>): Source<T>; /** Emits values from the passed sources in order. * * @param sources - An array of {@link Source | Sources}. * @returns A {@link Source} emitting values from the input Sources. * * @remarks * `concat` accepts an array of {@link Source | Sources} and will emit values from them, starting * with the first one and continuing to the next only when the prior source ended. * * This can be used to issue combine sources while keeping the order of their values intact. * * @example * ```ts * pipe( * concat([ * fromArray([1, 2]), * fromArray([3, 4]), * ]), * subscribe(x => { * console.log(text); // logs: 1, 2, 3, 4 * }) * ); * ``` */ declare function concat<T>(sources: Source<T>[]): Source<T>; /** Filters out emitted values for which the passed predicate function returns `false`. * * @param predicate - A function returning a boolean per value. * @returns An {@link Operator}. * * @remarks * `filter` will omit values from the {@link Source} for which the passed `predicate` function * returns `false`. * * @example * ```ts * pipe( * fromArray([1, 2, 3]), * filter(x => x % 2 === 0), * subscribe(x => { * console.log(text); // logs: 2 * }) * ); * ``` */ declare function filter<In, Out extends In>(predicate: (value: In) => value is Out): Operator<In, Out>; declare function filter<T>(predicate: (value: T) => boolean): Operator<T, T>; /** Maps emitted values using the passed mapping function. * * @param map - A function returning transforming the {@link Source | Source's} values. * @returns An {@link Operator}. * * @remarks * `map` accepts a transform function and calls it on each emitted value. It then emits * the values returned by the transform function instead. * * @example * ```ts * pipe( * fromArray([1, 2, 3]), * map(x => x * 2), * subscribe(x => { * console.log(text); // logs: 2, 4, 6 * }) * ); * ``` */ declare function map<In, Out>(map: (value: In) => Out): Operator<In, Out>; /** Emits from the Sources returned by a mapping function per value of the Source. * * @param map - A function returning a {@link Source} per value. * @returns An {@link Operator}. * * @remarks * `mergeMap` accepts a mapping function which must return a {@link Source} per value. * The output {@link Source} will emit values from all {@link Source | Sources} the mapping function * returned. * * This can be used to issue multiple values per emission of an input {@link Source}, essentially * multiplexing all values to multiple Sources. * * @example * ```ts * pipe( * interval(50), * mergeMap(x => pipe( * fromValue(x), * delay(100) * )), * subscribe(x => { * console.log(text); // logs: 0, 1, 2... * }) * ); * ``` */ declare function mergeMap<In, Out>(map: (value: In) => Source<Out>): Operator<In, Out>; /** Flattens a Source emitting Sources into a single Source emitting the inner values. * * @see {@link mergeMap} which this helper uses and instead accept a mapping function. * @param source - An {@link Source} emitting {@link Source | Sources}. * @returns A {@link Source} emitting values from the inner Sources. * * @remarks * `mergeAll` accepts a {@link Source} which must emit {@link Source | Sources}. It will subscribe * to each incoming source immediately and start passing its emitted values through. * * @example * ```ts * pipe( * fromArray([ * interval(50), * interval(100), * ]), * mergeAll, * subscribe(x => { * console.log(text); // logs: 0, 0, 1, 2, 1, 3, 4, 2 * }) * ); * ``` */ declare function mergeAll<T>(source: Source<Source<T>>): Source<T>; /** Emits values from the passed sources simultaneously. * * @param sources - An array of {@link Source | Sources}. * @returns A {@link Source} emitting values from the input Sources. * * @remarks * `merge` accepts an array of {@link Source | Sources} and will subscribe to all of them, passing * through all their emitted values simultaneously. * * This can be used to interleave the values of multiple sources. * * @example * ```ts * pipe( * merge([ * interval(50), * interval(100), * ]), * subscribe(x => { * console.log(text); // logs: 0, 0, 1, 2, 1, 3, 4, 2 * }) * ); * ``` */ declare function merge<T>(sources: Source<T>[]): Source<T>; /** Calls the passed callback function when the Source ends or is closed. * * @param callback - A function that is called when the {@link Source} ends. * @returns An {@link Operator}. * * @remarks * `onEnd` accepts a callback which is called when the {@link Source} either ends * or is closed. * * This operator can be used to add side-effects to a Source. * * @example * ```ts * pipe( * fromArray([1, 2, 3]), * take(1), * onEnd(() => { * console.log('end'); * }), * publish * ); * ``` */ declare function onEnd<T>(callback: () => void): Operator<T, T>; /** Calls the passed callback function when the Source emits a value. * * @param callback - A function that is called with each value the {@link Source} emits. * @returns An {@link Operator}. * * @remarks * `onPush` accepts a callback which is called for every emitted value of * the {@link Source}. * * This operator can be used to add side-effects to a Source. * * @example * ```ts * pipe( * fromArray([1, 2, 3]), * onPush(value => { * console.log(value); // logs: 1, 2, 3 * }), * publish * ); * ``` */ declare function onPush<T>(callback: (value: T) => void): Operator<T, T>; /** Calls the passed callback function when the Source starts. * * @param callback - A function that is called when the {@link Source} is started. * @returns An {@link Operator}. * * @remarks * `onPush` accepts a callback which is called for every emitted value of * the {@link Source}. * * This operator can be used to add side-effects to a Source. * Specifically, it's useful to add a side-effect for a Source that triggers only once * the {@link Source} is used and started. * * @example * ```ts * pipe( * fromArray([1, 2, 3]), * onStart(() => { * console.log('start'); * }), * publish * ); * ``` */ declare function onStart<T>(callback: () => void): Operator<T, T>; /** Emits the last value the {@link Source} emitted, whenever the notifier Source emits a value. * * @param notifier - A {@link Source} that triggers the last value to be emitted. * @returns An {@link Operator}. * * @remarks * `sample` will store the latest value the {@link Source} emitted. Every time the `notifier` Source * emits, it will emit the latest value. * * This is a back pressure operator that can be used to omit values from a {@link Source} coming in * too frequently. * * {@link Source | Sources} emitting `undefined` are undefined behaviour and these values will be * ignored. * * @example * ```ts * pipe( * interval(50), * sample(interval(100)), * subscribe(x => { * console.log(text); // logs: 0, 2, 4... * }) * ); * ``` */ declare function sample<S, T>(notifier: Source<S>): Operator<T, T>; /** Maps emitted values using the passed reducer function. * * @param reducer - A function called with the last value by the `reducer` and the emitted value. * @param seed - The initial value that is passed to the `reducer`. * @returns An {@link Operator}. * * @remarks * `scan` accepts a reducer function and a seed value. The reducer will be called initially with the * seed value and the first emitted value. The {@link Source} will then emit the value returned by * the reducer function. Subsequently, the `reducer` is called with the last value the `reducer` * returned and the emitted value. * * This operator is similar to `Array.prototype.reduce`, but instead is called over time and emits * each value of the reducer. * * @example * ```ts * pipe( * fromArray([1, 2, 3]), * scan((acc, x) => acc + x, 0), * subscribe(x => { * console.log(text); // logs: 1, 3, 6 * }) * ); * ``` */ declare function scan<In, Out>(reducer: (acc: Out, value: In) => Out, seed: Out): Operator<In, Out>; /** Shares one underlying subscription to the Source between all Sinks. * * @param source - A {@link Source} that should be shared. * @returns A shared {@link Source}. * * @remarks * `share` accepts a {@link Source} and returns one. It will emit all values as normal, however, it * will share one subscription to the input source. This allows side-effects on the input * {@link Source} to only be triggerd once. */ declare function share<T>(source: Source<T>): Source<T>; /** Omits `wait` amount of values from the Source and then runs as usual. * * @param wait - The number of values to be omitted. * @returns An {@link Operator}. * * @remarks * `skip` will skip `wait` number of emitted values, then issue all values as normal afterwards. * This essentially skips a given number of values on the input {@link Source}. * * @example * ```ts * pipe( * fromArray([1, 2, 3]), * skip(2), * subscribe(x => { * console.log(text); // logs: 3 * }) * ); * ``` */ declare function skip<T>(wait: number): Operator<T, T>; /** Omits values from an input Source until a notifier Source emits a value. * * @param notifier - A {@link Source} that starts the operator's sent values. * @returns An {@link Operator}. * * @remarks * `skipUntil` will omit all values from the input {@link Source} until the `notifier` * Source emits a value of its own. It'll then start passing values from the Source through. * * @example * ```ts * pipe( * interval(50), * skipUntil(interval(150)), * subscribe(x => { * console.log(text); // logs: 2, 3... * }) * ); * ``` */ declare function skipUntil<S, T>(notifier: Source<S>): Operator<T, T>; /** Omits values from an input Source until a predicate function returns `false`. * * @param predicate - A function returning a boolean per value. * @returns An {@link Operator}. * * @remarks * `skipWhile` will omit all values from the input {@link Source} until the `predicate` * function returns `false`. When the `predicate` function returns `false`, the Source's values will * be passed through. * * @example * ```ts * pipe( * fromArray([1, 2, 3]), * skipWhile(x => x < 2), * subscribe(x => { * console.log(text); // logs: 2, 3 * }) * ); * ``` */ declare function skipWhile<T>(predicate: (value: T) => boolean): Operator<T, T>; /** Emits from the latest Source returned by a mapping function per value of the Source. * * @param map - A function returning a {@link Source} per value. * @returns An {@link Operator}. * * @remarks * `switchMap` accepts a mapping function which must return a {@link Source} per value. * The output {@link Source} will emit values from the latest Source the mapping function * returned. If a value is emitted while the last returned Source is still active, the prior Source * will be closed. * * This can be used to issue multiple values per emission of an input {@link Source}, while only * letting one of these sub-Sources be active at a time. * * @example * ```ts * pipe( * interval(100), * switchMap(() => interval(50)), * subscribe(x => { * console.log(text); // logs: 0, 0, 0... * }) * ); * ``` */ declare function switchMap<In, Out>(map: (value: In) => Source<Out>): Operator<In, Out>; /** Flattens a Source emitting Sources into a single Source emitting the inner values. * * @see {@link switchMap} which this helper uses and instead accept a mapping function. * @param source - An {@link Source} emitting {@link Source | Sources}. * @returns A {@link Source} emitting values from the inner Sources. * * @remarks * `switchAll` accepts a {@link Source} which must emit {@link Source | Sources}. Each time it * receives a {@link Source} it will close its prior subscription and subscribe to the new Source * instead, passing through its values. * * @example * ```ts * pipe( * interval(100), * map(() => interval(50)), * switchAll, * subscribe(x => { * console.log(text); // logs: 0, 0, 0... * }) * ); * ``` */ declare function switchAll<T>(source: Source<Source<T>>): Source<T>; /** Emits `max` values from the Source and then ends. * * @param max - The maximum number of values emitted. * @returns An {@link Operator}. * * @remarks * `take` will issue all values as normal until the `max` number of emitted values has been reached. * It will then end and close the {@link Source}. * * @example * ```ts * pipe( * fromArray([1, 2, 3]), * take(2), * subscribe(x => { * console.log(text); // logs: 1, 2 * }) * ); * ``` */ declare function take<T>(max: number): Operator<T, T>; /** Buffers the `max` last values of the Source and emits them once the Source ends. * * @param max - The maximum number of values buffered. * @returns An {@link Operator}. * * @remarks * `takeLast` will buffer values from the input {@link Source} up until the given `max` number. It * will only emit values stored in the buffer once the {@link Source} ends. * * All values in the buffer are emitted like the {@link fromArray | `fromArray`} source would * synchronously. * * @example * ```ts * pipe( * fromArray([1, 2, 3]), * takeLast(1), * subscribe(x => { * console.log(text); // logs: 3 * }) * ); * ``` */ declare function takeLast<T>(max: number): Operator<T, T>; /** Takes values from an input Source until a notifier Source emits a value. * * @param notifier - A {@link Source} that stops the operator's sent values. * @returns An {@link Operator}. * * @remarks * `takeUntil` will issue all values as normal from the input {@link Source} until the `notifier` * Source emits a value of its own. It'll then close the {@link Source}. * * @example * ```ts * pipe( * interval(50), * takeUntil(interval(150)), * subscribe(x => { * console.log(text); // logs: 0, 1 * }) * ); * ``` */ declare function takeUntil<S, T>(notifier: Source<S>): Operator<T, T>; /** Takes values from an input Source until a predicate function returns `false`. * * @param predicate - A function returning a boolean per value. * @param addOne - Lets an additional input value pass on. * @returns An {@link Operator}. * * @remarks * `takeWhile` will issue all values as normal from the input {@link Source} until the `predicate` * function returns `false`. When the `predicate` function returns `false`, the current value is * omitted and the {@link Source} is closed. * * If `addOne` is set to `true`, the value for which the `predicate` first returned `false` is * issued and passed on as well instead of being omitted. * * @example * ```ts * pipe( * fromArray([1, 2, 3]), * takeWhile(x => x < 2), * subscribe(x => { * console.log(text); // logs: 1 * }) * ); * ``` */ declare function takeWhile<T>(predicate: (value: T) => boolean, addOne?: boolean): Operator<T, T>; /** Debounces a Source by omitting values until a given timeframe has passed. * * @param timing - A function returning a debounce time (ms) per emitted value. * @returns An {@link Operator}. * * @remarks * `debounce` accepts a mapping function that can be used to return a time (in ms) per emitted * value. All emitted values issued by the {@link Source} during the returned time will be omitted * until the time has passed. * * Debouncing means that the returned {@link Source} will wait for a minimum time of silence until a * value is let through. * * This is a back pressure operator that can be used to omit values from a {@link Source} coming in * too frequently. * * @example * ```ts * pipe( * interval(50), * debounce(() => 100), * subscribe(x => { * console.log(text); // never logs any value * }) * ); * ``` */ declare function debounce<T>(timing: (value: T) => number): Operator<T, T>; /** Delays each signal emitted by a Source by given time (ms). * * @param wait - A time (in ms) by which each {@link SignalKind | signal} is delayed. * @returns An {@link Operator}. * * @remarks * `delay` accepts a time (in ms) by which each {@link SignalKind | signal} will be delayed by. * This will create a timeout per received signal and delay the emitted values accordingly. * * Since the operator only calls `setTimeout` per signal, it relies on the timeout implementation to * be ordered. Otherwise, signals will arrive in the wrong order at the sink. */ declare function delay<T>(wait: number): Operator<T, T>; /** Throttles a Source by omitting values that are emitted before a given timeout. * * @param timing - A function returning a throttle time (ms) per emitted value. * @returns An {@link Operator}. * * @remarks * `throttle` accepts a mapping function that can be used to return a time (in ms) per emitted * value. During the returned timeframe all values issued by the {@link Source} will be omitted and * dropped. * * This is a back pressure operator that can be used to omit values from a {@link Source} coming in * too frequently. * * @example * ```ts * pipe( * interval(50), * throttle(() => 100), * subscribe(x => { * // omits every second value: 0, 2, 4... * console.log(text); * }) * ); * ``` */ declare function throttle<T>(timing: (value: T) => number): Operator<T, T>; /** Creates a subscription to a given source and invokes a `subscriber` callback for each value. * @param subscriber - A callback function called for each issued value. * @returns A function accepting a {@link Source} and returning a {@link Subscription}. * * @remarks * `subscribe` accepts a `subscriber` callback and returns a function accepting a {@link Source}. * When a source is passed to the returned funtion, the subscription will start and `subscriber` * will be called for each new value the Source issues. This will also return a {@link Subscription} * object that can cancel the ongoing {@link Source} early. * * @example * ```ts * const subscription = pipe( * fromValue('test'), * subscribe(text => { * console.log(text); // 'test' * }) * ); * ``` */ declare function subscribe<T>(subscriber: (value: T) => void): (source: Source<T>) => Subscription; /** Creates a subscription to a given source and invokes a `subscriber` callback for each value. * @see {@link subscribe} which this helper aliases without returnin a {@link Subscription}. * @param subscriber - A callback function called for each issued value. * @returns A function accepting a {@link Source}. * * @remarks * `forEach` accepts a `subscriber` callback and returns a function accepting a {@link Source}. * When a source is passed to the returned funtion, the subscription will start and `subscriber` * will be called for each new value the Source issues. Unlike `subscribe` it will not return a * Subscription object and can't be cancelled early. * * @example * ```ts * pipe( * fromValue('test'), * forEach(text => { * console.log(text); // 'test' * }) * ); // undefined * ``` */ declare function forEach<T>(subscriber: (value: T) => void): (source: Source<T>) => void; /** Creates a subscription to a given source and invokes a `subscriber` callback for each value. * @see {@link subscribe} which this helper aliases without accepting parameters or returning a * {@link Subscription | Subscription}. * * @param source - A {@link Source}. * * @remarks * `publish` accepts a {@link Source} and subscribes to it, starting its values. The resulting * values cannot be observed and the subscription can't be cancelled, as this helper is purely * intended to start side-effects. * * @example * ```ts * pipe( * lazy(() => { * console.log('test'); // this is called * return fromValue(123); // this is never used * }), * publish * ); // undefined * ``` */ declare function publish<T>(source: Source<T>): void; /** Converts a Source to an AsyncIterable that pulls and issues values from the Source. * * @param source - A {@link Source}. * @returns An {@link AsyncIterable | `AsyncIterable`} issuing values from the Source. * * @remarks * `toAsyncIterable` will create an {@link AsyncIterable} that pulls and issues values from a given * {@link Source}. This can be used in many interoperability situations, to provide an iterable when * a consumer requires it. * * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#the_async_iterator_and_async_iterable_protocols} * for the JS Iterable protocol. * * @example * ```ts * const iterable = toAsyncIterable(fromArray([1, 2, 3])); * for await (const value of iterable) { * console.log(value); // outputs: 1, 2, 3 * } * ``` */ declare const toAsyncIterable: <T>(source: Source<T>) => SourceIterable<T>; /** Subscribes to a given source and collects all synchronous values into an array. * @param source - A {@link Source}. * @returns An array of values collected from the {@link Source}. * * @remarks * `toArray` accepts a {@link Source} and returns an array of all synchronously issued values from * this Source. It will issue {@link TalkbackKind.Pull | Pull signals} after every value it receives * and expects the Source to recursively issue values. * * Any asynchronously issued values will not be * added to the array and a {@link TalkbackKind.Close | Close signal} is issued by the sink before * returning the array. * * @example * ```ts * toArray(fromArray([1, 2, 3])); // [1, 2, 3] * ``` */ declare function toArray<T>(source: Source<T>): T[]; /** Subscribes to a given source and returns a Promise that will resolve with the last value the * source issues. * * @param source - A {@link Source}. * @returns A {@link Promise} resolving to the last value of the {@link Source}. * * @remarks * `toPromise` will subscribe to the passed {@link Source} and resolve to the last value of it once * it receives the last value, as signaled by the {@link SignalKind.End | End signal}. * * To keep its implementation simple, padding sources that don't issue any values to `toPromise` is * undefined behaviour and `toPromise` will issue `undefined` in that case. * * The returned {@link Promise} delays its value by a microtick, using `Promise.resolve`. * * @example * ```ts * toPromise(fromValue('test')); // resolves: 'test' * ``` */ declare function toPromise<T>(source: Source<T>): Promise<T>; type TypeOfSourceArray<T extends readonly [...any[]]> = T extends [infer Head, ...infer Tail] ? [TypeOfSource<Head>, ...TypeOfSourceArray<Tail>] : []; /** Combines the latest values of several sources into a Source issuing either tuple or dictionary * values. * * @param sources - Either an array or dictionary object of Sources. * @returns A {@link Source} issuing a zipped value whenever any input Source updates. * * @remarks * `zip` combines several {@link Source | Sources}. The resulting Source will issue its first value * once all input Sources have at least issued one value, and will subsequently issue a new value * each time any of the Sources emits a new value. * * Depending on whether an array or dictionary object of Sources is passed to `zip`, its emitted * values will be arrays or dictionary objects of the Sources' values. * * @example * An example of passing a dictionary object to `zip`. If an array is passed, the resulting * values will output arrays of the sources' values instead. * * ```ts * pipe( * zip({ * x: fromValue(1), * y: fromArray([2, 3]), * }), * subscribe(result => { * // logs { x: 1, y: 2 } then { x: 1, y: 3 } * console.log(result); * }) * ); * ``` */ interface zip { <Sources extends readonly [...Source<any>[]]>(sources: [...Sources]): Source<TypeOfSourceArray<Sources>>; <Sources extends { [prop: string]: Source<any>; }>(sources: Sources): Source<{ [Property in keyof Sources]: TypeOfSource<Sources[Property]>; }>; } declare function zip<T>(sources: Source<T>[] | Record<string, Source<T>>): Source<T[] | Record<string, T>>; /** Combines the latest values of all passed sources into a Source issuing tuple values. * * @see {@link zip | `zip`} which this helper wraps and uses. * @param sources - A variadic list of {@link Source} parameters. * @returns A {@link Source} issuing a zipped value whenever any input Source updates. * * @remarks * `combine` takes one or more {@link Source | Sources} as arguments. Once all input Sources have at * least issued one value it will issue an array of all of the Sources' values. Subsequently, it * will issue a new array value whenever any of the Sources update. * * @example * * ```ts * pipe( * combine(fromValue(1), fromValue(2)), * subscribe(result => { * console.log(result); // logs [1, 2] * }) * ); * ``` */ declare function combine<Sources extends Source<any>[]>(...sources: Sources): Source<TypeOfSourceArray<Sources>>; declare global { interface SymbolConstructor { readonly observable: symbol; } } /** A definition of the ES Observable Subscription type that is returned by * {@link Observable.subscribe} * * @remarks * The Subscription in ES Observables is a handle that is held while the Observable is actively * streaming values. As such, it's used to indicate with {@link ObservableSubscription.closed} * whether it's active, and {@link ObservableSubscription.unsubscribe} may be used to cancel the * ongoing subscription and end the {@link Observable} early. * * @see {@link https://github.com/tc39/proposal-observable} for the ES Observable specification. */ interface ObservableSubscription { /** A boolean flag indicating whether the subscription is closed. * @remarks * When `true`, the subscription will not issue new values to the {@link ObservableObserver} and * has terminated. No new values are expected. * * @readonly */ closed: boolean; /** Cancels the subscription. * @remarks * This cancels the ongoing subscription and the {@link ObservableObserver}'s callbacks will * subsequently not be called at all. The subscription will be terminated and become inactive. */ unsubscribe(): void; } /** A definition of the ES Observable Observer type that is used to receive data from an * {@link Observable}. * * @remarks * The Observer in ES Observables is supplied to {@link Observable.subscribe} to receive events from * an {@link Observable} as it issues them. * * @see {@link https://github.com/tc39/proposal-observable#observer} for the ES Observable * specification of an Observer. */ interface ObservableObserver<T> { /** Callback for the Observable issuing new values. * @param value - The value that the {@link Observable} is sending. */ next(value: T): void; /** Callback for the Observable encountering an error, terminating it. * @param error - The error that the {@link Observable} has encountered. */ error?(error: any): void; /** Callback for the Observable ending, after all values have been issued. */ complete?(): void; } /** A looser definition of ES Observable-like types that is used for interoperability. * @remarks * The Observable is often used by multiple libraries supporting or creating streams to provide * interoperability for push-based streams. When converting from an Observable to a {@link Source}, * this looser type is accepted as an input. * * @see {@link https://github.com/tc39/proposal-observable} for the ES Observable specification. * @see {@link Observable} for the full ES Observable type. */ interface ObservableLike<T> { /** * Subscribes to new signals from an {@link Observable} via callbacks. * @param observer - An object containing callbacks for the various events of an Observable. * @returns Subscription handle of type {@link ObservableSubscription}. * * @see {@link ObservableObserver} for the callbacks in an object that are called as Observables * issue events. */ subscribe(observer: ObservableObserver<T>): { unsubscribe(): void; }; /** The well-known symbol specifying the default ES Observable for an object. */ [Symbol.observable]?(): Observable<T>; } /** An ES Observable type that is a de-facto standard for push-based data sources across the JS * ecosystem. * * @remarks * The Observable is often used by multiple libraries supporting or creating streams to provide * interoperability for push-based streams. As Wonka's {@link Source | Sources} are similar in * functionality to Observables, it provides utilities to cleanly convert to and from Observables. * * @see {@link https://github.com/tc39/proposal-observable} for the ES Observable specification. */ interface Observable<T> { /** Subscribes to new signals from an {@link Observable} via callbacks. * @param observer - An object containing callbacks for the various events of an Observable. * @returns Subscription handle of type {@link ObservableSubscription}. * * @see {@link ObservableObserver} for the callbacks in an object that are called as Observables * issue events. */ subscribe(observer: Observa