UNPKG

@types/highland

Version:
1,331 lines (1,227 loc) 63.2 kB
/// <reference types="node" /> // TODO export the top-level functions // TODO figure out curry arguments // TODO use externalised Readable/Writable (not node's) // Returns the type of a flattened stream. // Uses trick described in https://github.com/microsoft/TypeScript/pull/33050#issuecomment-552218239 // with string keys to support TS 2.8 type Flattened<R> = { value: R; stream: R extends Highland.Stream<infer U> ? Flattened<U> : never; array: R extends Array<infer U> ? Flattened<U> : never; }[R extends any[] ? "array" : R extends Highland.Stream<any> ? "stream" : "value"]; // Describes a constructor for a particular promise library interface PConstructor<T, P extends PromiseLike<T>> { new(executor: (resolve: (value: T | PromiseLike<T>) => void, reject: (reason?: any) => void) => void): P; } /** * Highland: the high-level streams library * * Highland may be freely distributed under the Apache 2.0 license. * https://github.com/caolan/highland * Copyright (c) Caolan McMahon */ interface HighlandStatic { /** * The Stream constructor, accepts an array of values or a generator function * as an optional argument. This is typically the entry point to the Highland * APIs, providing a convenient way of chaining calls together. * * **Arrays -** Streams created from Arrays will emit each value of the Array * and then emit a [nil](#nil) value to signal the end of the Stream. * * **Generators -** These are functions which provide values for the Stream. * They are lazy and can be infinite, they can also be asynchronous (for * example, making a HTTP request). You emit values on the Stream by calling * `push(err, val)`, much like a standard Node.js callback. Once it has been * called, the generator function will not be called again unless you call * `next()`. This call to `next()` will signal you've finished processing the * current data and allow for the generator function to be called again. If the * Stream is still being consumed the generator function will then be called * again. * * You can also redirect a generator Stream by passing a new source Stream * to read from to next. For example: `next(other_stream)` - then any subsequent * calls will be made to the new source. * * **Node Readable Stream -** Pass in a Node Readable Stream object to wrap * it with the Highland API. Reading from the resulting Highland Stream will * begin piping the data from the Node Stream to the Highland Stream. * * A stream constructed in this way relies on `Readable#pipe` to end the * Highland Stream once there is no more data. Not all Readable Streams do * this. For example, `IncomingMessage` will only emit `close` when the client * aborts communications and will *not* properly call `end`. In this case, you * can provide an optional `onFinished` function with the signature * `onFinished(readable, callback)` as the second argument. * * This function will be passed the Readable and a callback that should called * when the Readable ends. If the Readable ended from an error, the error * should be passed as the first argument to the callback. `onFinished` should * bind to whatever listener is necessary to detect the Readable's completion. * If the callback is called multiple times, only the first invocation counts. * If the callback is called *after* the Readable has already ended (e.g., the * `pipe` method already called `end`), it will be ignored. * * The `onFinished` function may optionally return one of the following: * * - A cleanup function that will be called when the stream ends. It should * unbind any listeners that were added. * - An object with the following optional properties: * - `onDestroy` - the cleanup function. * - `continueOnError` - Whether or not to continue the stream when an * error is passed to the callback. Set this to `true` if the Readable * may continue to emit values after errors. Default: `false`. * * See [this issue](https://github.com/caolan/highland/issues/490) for a * discussion on why Highland cannot reliably detect stream completion for * all implementations and why the `onFinished` function is required. * * **EventEmitter / jQuery Elements -** Pass in both an event name and an * event emitter as the two arguments to the constructor and the first * argument emitted to the event handler will be written to the new Stream. * * You can pass a mapping hint as the third argument, which specifies how * event arguments are pushed into the stream. If no mapping hint is provided, * only the first value emitted with the event to the will be pushed onto the * Stream. * * If `mappingHint` is a number, an array of that length will be pushed onto * the stream, containing exactly that many parameters from the event. If it's * an array, it's used as keys to map the arguments into an object which is * pushed to the tream. If it is a function, it's called with the event * arguments, and the returned value is pushed. * * **Promise -** Accepts an ES6 / jQuery style promise and returns a * Highland Stream which will emit a single value (or an error). In case you use * [bluebird cancellation](http://bluebirdjs.com/docs/api/cancellation.html) Highland Stream will be empty for a cancelled promise. * * **Iterator -** Accepts an ES6 style iterator that implements the [iterator protocol](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#The_.22iterator.22_protocol): * yields all the values from the iterator using its `next()` method and terminates when the * iterator's done value returns true. If the iterator's `next()` method throws, the exception will be emitted as an error, * and the stream will be ended with no further calls to `next()`. * * **Iterable -** Accepts an object that implements the [iterable protocol](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#The_.22iterable.22_protocol), * i.e., contains a method that returns an object that conforms to the iterator protocol. The stream will use the * iterator defined in the `Symbol.iterator` property of the iterable object to generate emitted values. * * @id _(source) * @section Stream Objects * @name _(source) * @param {Array | Function | Iterator | Iterable | Promise | Readable Stream | String} source - (optional) source to take values from from * @param {Function} onFinished - (optional) a function that detects when the readable completes. Second argument. Only valid if `source` is a Readable. * @param {EventEmitter | jQuery Element} eventEmitter - (optional) An event emitter. Second argument. Only valid if `source` is a String. * @param {Array | Function | Number} mappingHint - (optional) how to pass the * arguments to the callback. Only valid if `source` is a String. * @api public */ <R>(): Highland.Stream<R>; <R>(source: R[]): Highland.Stream<R>; <R>( source: (push: (err: Error | null, x?: R | Highland.Nil) => void, next: () => void) => void, ): Highland.Stream<R>; <R>(source: Highland.Stream<R>): Highland.Stream<R>; <R>(source: NodeJS.ReadableStream, onFinished?: Highland.OnFinished): Highland.Stream<R>; <R>(source: string, eventEmitter: NodeJS.EventEmitter, mappingHint?: Highland.MappingHint): Highland.Stream<R>; // moar (promise for everything?) <R>(source: PromiseLike<Highland.Stream<R>>): Highland.Stream<R>; <R>(source: PromiseLike<R>): Highland.Stream<R>; <R>(source: Iterable<R>): Highland.Stream<R>; <R>(source: Iterator<R>): Highland.Stream<R>; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // UTILS // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /** * Creates a stream that sends a single error then ends. * * @id fromError * @section Utils * @name _.fromError(err) * @param error - the error to send * @returns Stream * @api public * * _.fromError(new Error('Single Error')).toCallback(function (err, result) { * // err contains Error('Single Error') object * } */ fromError<R>(error: unknown): Highland.Stream<R>; /** * Returns true if `x` is the end of stream marker. * * @id isNil * @section Streams * @name _.isNil(x) * @param x - the object to test * @api public */ isNil<R>(x: R | Highland.Nil): x is Highland.Nil; /** * Returns true if `x` is a Highland Stream. * * @id isStream * @section Streams * @name _.isStream(x) * @param x - the object to test * @api public */ isStream(x: any): x is Highland.Stream<any>; isStreamError(x: any): x is Highland.Stream<any>; isStreamRedirect(x: any): x is Highland.Stream<any>; /** * Logs values to the console, a simple wrapper around `console.log` that * it suitable for passing to other functions by reference without having to * call `bind`. * * @id log * @section Utils * @name _.log(args..) * @api public */ log(x: any, ...args: any[]): void; /** * The end of stream marker. This is sent along the data channel of a Stream * to tell consumers that the Stream has ended. See the following map code for * an example of detecting the end of a Stream: * * @id nil * @section Streams * @name _.nil * @api public */ nil: Highland.Nil; /** * Creates a stream that sends a single value then ends. * * @id of * @section Utils * @name _.of(x) * @param x - the value to send * @returns Stream * @api public * * _.of(1).toArray(_.log); // => [1] */ of<R>(x: R): Highland.Stream<R>; /** * Wraps a node-style async function which accepts a callback, transforming * it to a function which accepts the same arguments minus the callback and * returns a Highland Stream instead. The wrapped function keeps its context, * so you can safely use it as a method without binding (see the second * example below). * * wrapCallback also accepts an optional mappingHint, which specifies how * callback arguments are pushed to the stream. This can be used to handle * non-standard callback protocols that pass back more than one value. * * mappingHint can be a function, number, or array. See the documentation on * EventEmitter Stream Objects for details on the mapping hint. If * mappingHint is a function, it will be called with all but the first * argument that is passed to the callback. The first is still assumed to be * the error argument. * * @id wrapCallback * @section Utils * @name _.wrapCallback(f) * @param {Function} f - the node-style function to wrap * @param {Array | Function | Number} [mappingHint] - how to pass the arguments to the callback * @api public */ wrapCallback(f: Function, mappingHint?: Highland.MappingHint): (...args: any[]) => Highland.Stream<any>; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // OBJECTS // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /** * Extends one object with the properties of another. **Note:** The * arguments are in the reverse order of other libraries such as * underscore. This is so it follows the convention of other functions in * this library and so you can more meaningfully partially apply it. * * @id extend * @section Objects * @name _.extend(a, b) * @param {Object} a - the properties to extend b with * @param {Object} b - the original object to extend * @api public */ extend(extensions: Object, target: Object): Object; extend(target: Object): (extensions: Object) => Object; /** * Returns a property from an object. * * @id get * @section Objects * @name _.get(prop, obj) * @param {String} prop - the property to return * @param {Object} obj - the object to read properties from * @api public */ get(prop: string, obj: Object): string; get(prop: string): (obj: Object) => Object; /** * Returns keys from an Object as a Stream. * * @id keys * @section Objects * @name _.keys(obj) * @param {Object} obj - the object to return keys from * @api public */ keys(obj: Object): Highland.Stream<string>; /** * Returns key/value pairs for an Object as a Stream. Reads properties * lazily, so if you don't read from all keys on an object, not * all properties will be read from (may have an effect where getters * are used). * * @id pairs * @section Objects * @name _.pairs(obj) * @param {Object} obj - the object to return key/value pairs from * @api public */ pairs(obj: Object): Highland.Stream<any[]>; pairs(obj: any[]): Highland.Stream<any[]>; /** * Updates a property on an object, returning the updated object. * * @id set * @section Objects * @name _.set(prop, value, obj) * @param {String} prop - the property to return * @param value - the value to set the property to * @param {Object} obj - the object to set properties on * @api public */ set(prop: string, val: any, obj: Object): Object; set(prop: string, val: any): (obj: Object) => Object; /** * Returns values from an Object as a Stream. Reads properties * lazily, so if you don't read from all keys on an object, not * all properties will be read from (may have an effect where getters * are used). * * @id values * @section Objects * @name _.values(obj) * @param {Object} obj - the object to return values from * @api public */ values(obj: Object): Highland.Stream<any>; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // FUNCTIONS // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /** * Creates a composite function, which is the application of function1 to * the results of function2. You can pass an arbitrary number of arguments * and have them composed. This means you can't partially apply the compose * function itself. * * @id compose * @name compose(fn1, fn2, ...) * @section Functions * @api public */ compose(...functions: Function[]): Function; /** * Transforms a function with specific arity (all arguments must be * defined) in a way that it can be called as a chain of functions until * the arguments list is saturated. * * This function is not itself curryable. * * @id curry * @name curry(fn, [*arguments]) * @section Functions * @param {Function} fn - the function to curry * @param args.. - any number of arguments to pre-apply to the function * @returns Function * @api public */ curry(fn: Function, ...args: any[]): Function; /** * Evaluates the function `fn` with the argument positions swapped. Only * works with functions that accept two arguments. * * @id flip * @name flip(fn, [x, y]) * @section Functions * @param {Function} f - function to flip argument application for * @param x - parameter to apply to the right hand side of f * @param y - parameter to apply to the left hand side of f * @api public */ flip(fn: Function, ...args: any[]): Function; /** * Same as `curry` but with a specific number of arguments. This can be * useful when functions do not explicitly define all its parameters. * * This function is not itself curryable. * * @id ncurry * @name ncurry(n, fn, [args...]) * @section Functions * @param {Number} n - the number of arguments to wait for before apply fn * @param {Function} fn - the function to curry * @param args... - any number of arguments to pre-apply to the function * @returns Function * @api public */ ncurry(n: number, fn: Function, ...args: any[]): Function; /** * Partially applies the function (regardless of whether it has had curry * called on it). This will always postpone execution until at least the next * call of the partially applied function. * * @id partial * @name partial(fn, args...) * @section Functions * @param {Function} fn - function to partial apply * @param args... - the arguments to apply to the function * @api public */ partial(fn: Function, ...args: any[]): Function; /** * The reversed version of compose. Where arguments are in the order of * application. * * @id seq * @name seq(fn1, fn2, ...) * @section Functions * @api public */ seq(...functions: Function[]): Function; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // OPERATORS // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /** * Add two values. Can be partially applied. * * @id add * @section Operators * @name _.add(a, b) * @api public */ add(a: number, b: number): number; add(a: number): (b: number) => number; /** * Perform logical negation on a value. If `x` is truthy then returns false, * otherwise returns true. * * @id not * @section Operators * @name _.not(x) * @param x - the value to negate * @api public * * _.not(true) // => false * _.not(false) // => true */ not<R>(x: any): boolean; } declare namespace Highland { // hacky unique // TODO do we need this? interface Nil { Highland_NIL: Nil; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /** * Used as an Error marker when writing to a Stream's incoming buffer */ // TODO is this public? class StreamError { constructor(err: Error); error: Error; } /** * Used as a Redirect marker when writing to a Stream's incoming buffer */ // TODO is this public? class StreamRedirect<R> { constructor(to: Stream<R>); to: Stream<R>; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /** * Actual Stream constructor wrapped the the main exported function */ interface Stream<R> extends NodeJS.EventEmitter { // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // STREAM OBJECTS // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /** * Destroys a stream by unlinking it from any consumers and sources. This will * stop all consumers from receiving events from this stream and removes this * stream as a consumer of any source stream. * * This function calls end() on the stream and unlinks it from any piped-to streams. * * @id pipe * @section Streams * @name Stream.destroy() * @api public */ destroy(): void; /** * Ends a Stream. This is the same as sending a [nil](#nil) value as data. * You shouldn't need to call this directly, rather it will be called by * any [Node Readable Streams](https://nodejs.org/api/stream.html#stream_class_stream_readable) * you pipe in. * * @id end * @section Streams * @name Stream.end() * @api public */ end(): void; /** * Pauses the stream. All Highland Streams start in the paused state. * * @id pause * @section Streams * @name Stream.pause() * @api public */ pause(): void; /** * Resumes a paused Stream. This will either read from the Stream's incoming * buffer or request more data from an upstream source. * * @id resume * @section Streams * @name Stream.resume() * @api public */ resume(): void; /** * Writes a value to the Stream. If the Stream is paused it will go into the * Stream's incoming buffer, otherwise it will be immediately processed and * sent to the Stream's consumers (if any). Returns false if the Stream is * paused, true otherwise. This lets Node's pipe method handle back-pressure. * * You shouldn't need to call this yourself, but it may be called by Node * functions which treat Highland Streams as a [Node Writable Stream](https://nodejs.org/api/stream.html#stream_class_stream_writable). * * @id write * @section Streams * @name Stream.write(x) * @param x - the value to write to the Stream * @api public */ write(x: R): boolean; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // TRANSFORMS // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /** * Adds a value to the end of a Stream. * * @id append * @section Streams * @name Stream.append(y) * @param y - the value to append to the Stream * @api public */ append(y: R): Stream<R>; /** * Takes one Stream and batches incoming data into arrays of given length * * @id batch * @section Transforms * @name Stream.batch(n) * @param {Number} n - length of the array to batch * @api public * * _([1, 2, 3, 4, 5]).batch(2) // => [1, 2], [3, 4], [5] */ batch(n: number): Stream<R[]>; /** * Takes one Stream and batches incoming data within a maximum time frame * into arrays of a maximum length. * * @id batchWithTimeOrCount * @section Transforms * @name Stream.batchWithTimeOrCount(ms, n) * @param {Number} ms - the maximum milliseconds to buffer a batch * @param {Number} n - the maximum length of the array to batch * @api public * * _(function (push) { * push(1); * push(2); * push(3); * setTimeout(push, 20, 4); * }).batchWithTimeOrCount(10, 2) * * // => [1, 2], [3], [4] */ batchWithTimeOrCount(ms: number, n: number): Stream<R[]>; /** * Groups all values into an Array and passes down the stream as a single * data event. This is a bit like doing [toArray](#toArray), but instead * of accepting a callback and causing a *thunk*, it passes the value on. * * @id collect * @section Streams * @name Stream.collect() * @api public */ collect(): Stream<R[]>; /** * Filters a Stream to drop all non-truthy values. * * @id compact * @section Streams * @name Stream.compact() * @api public */ compact(): Stream<NonNullable<R>>; /** * Consumes values from a Stream (once resumed) and returns a new Stream for * you to optionally push values onto using the provided push / next functions. * * This function forms the basis of many higher-level Stream operations. * It will not cause a paused stream to immediately resume, but behaves more * like a 'through' stream, handling values as they are read. * * @id consume * @section Streams * @name Stream.consume(f) * @param {Function} f - the function to handle errors and values * @api public */ consume<U>( f: ( err: Error, x: R | Highland.Nil, push: (err: Error | null, value?: U | Highland.Nil) => void, next: () => void, ) => void, ): Stream<U>; /** * Holds off pushing data events downstream until there has been no more * data for `ms` milliseconds. Sends the last value that occurred before * the delay, discarding all other values. * * @id debounce * @section Streams * @name Stream.debounce(ms) * @param {Number} ms - the milliseconds to wait before sending data * @api public */ debounce(ms: number): Stream<R>; /** * Creates a new Stream which applies a function to each value from the source * and re-emits the source value. Useful when you want to mutate the value or * perform side effects * * @id doto * @section Transforms * @name Stream.doto(f) * @param {Function} f - the function to apply * @api public * * var appended = _([[1], [2], [3], [4]]).doto(function (x) { * x.push(1); * }); * * _([1, 2, 3]).doto(console.log) * // 1 * // 2 * // 3 * // => 1, 2, 3 */ doto(f: (x: R) => void): Stream<R>; /** * Acts as the inverse of [`take(n)`](#take) - instead of returning the first `n` values, it ignores the * first `n` values and then emits the rest. `n` must be of type `Number`, if not the whole stream will * be returned. All errors (even ones emitted before the nth value) will be emitted. * * @id drop * @section Transforms * @name Stream.drop(n) * @param {Number} n - integer representing number of values to read from source * @api public * * _([1, 2, 3, 4]).drop(2) // => 3, 4 */ drop(n: number): Stream<R>; /** * Extracts errors from a Stream and applies them to an error handler * function. Returns a new Stream with the errors removed (unless the error * handler chooses to rethrow them using `push`). Errors can also be * transformed and put back onto the Stream as values. * * @id errors * @section Streams * @name Stream.errors(f) * @param {Function} f - the function to pass all errors to * @api public */ errors(f: (err: Error, push: (err: Error | null, x?: R) => void) => void): Stream<R>; /** * Creates a new Stream including only the values which pass a truth test. * * @id filter * @section Streams * @name Stream.filter(f) * @param f - the truth test function * @api public */ filter<S extends R>(f: (x: R) => x is S): Stream<S>; filter(f: (x: R) => boolean): Stream<R>; /** * A convenient form of filter, which returns the first object from a * Stream that passes the provided truth test * * @id find * @section Streams * @name Stream.find(f) * @param {Function} f - the truth test function which returns a Stream * @api public */ find(f: (x: R) => boolean): Stream<R>; /** * A convenient form of [where](#where), which returns the first object from a * Stream that matches a set of property values. findWhere is to [where](#where) as [find](#find) is to [filter](#filter). * * @id findWhere * @section Transforms * @name Stream.findWhere(props) * @param {Object} props - the properties to match against * @api public * * var docs = [ * {type: 'blogpost', title: 'foo'}, * {type: 'blogpost', title: 'bar'}, * {type: 'comment', title: 'foo'} * ]; * * _(docs).findWhere({type: 'blogpost'}) * // => {type: 'blogpost', title: 'foo'} * * // example with partial application * var firstBlogpost = _.findWhere({type: 'blogpost'}); * * firstBlogpost(docs) * // => {type: 'blogpost', title: 'foo'} */ findWhere(props: Partial<R>): Stream<R>; /** * A convenient form of reduce, which groups items based on a function or property name * * @id group * @section Streams * @name Stream.group(f) * @param {Function|String} f - the function or property name on which to group, * toString() is called on the result of a function. * @api public */ // TODO verify this group(f: (x: R) => string): Stream<{ [prop: string]: R[] }>; group(prop: string): Stream<{ [prop: string]: R[] }>; /** * Creates a new Stream with only the first value from the source. * * @id head * @section Streams * @name Stream.head() * @api public * * _([1, 2, 3, 4]).head() // => 1 */ head(): Stream<R>; /** * Creates a new Stream with the separator interspersed between the elements of the source. * * `intersperse` is effectively the inverse of [splitBy](#splitBy). * * @id intersperse * @section Transforms * @name Stream.intersperse(sep) * @param {R} separator - the value to intersperse between the source elements * @api public */ intersperse<U>(separator: U): Stream<R | U>; /** * Calls a named method on each object from the Stream - returning * a new stream with the result of those calls. * * @id invoke * @section Streams * @name Stream.invoke(method, args) * @param {String} method - the method name to call * @param {Array} args - the arguments to call the method with * @api public */ invoke<U>(method: string, args: any[]): Stream<U>; /** * Drops all values from the Stream apart from the last one (if any). * * @id last * @section Streams * @name Stream.last() * @api public */ last(): Stream<R>; /** * Creates a new Stream, which when read from, only returns the last * seen value from the source. The source stream does not experience * back-pressure. Useful if you're using a Stream to model a changing * property which you need to query periodically. * * @id latest * @section Streams * @name Stream.latest() * @api public */ latest(): Stream<R>; /** * Creates a new Stream of transformed values by applying a function to each * value from the source. The transformation function can be replaced with * a non-function value for convenience, and it will emit that value * for every data event on the source Stream. * * @id map * @section Streams * @name Stream.map(f) * @param f - the transformation function or value to map to * @api public */ map<U>(f: (x: R) => U): Stream<U>; /** * Retrieves copies of all elements in the collection, * with only the whitelisted keys. If one of the whitelisted * keys does not exist, it will be ignored. * * @id pick * @section Transforms * @name Stream.pick(properties) * @param {Array} properties - property names to white filter * @api public */ pick<Prop extends keyof R>(props: Prop[]): Stream<Pick<R, Prop>>; /** * Retrieves copies of all the elements in the collection * that satisfy a given predicate. Note: When using ES3, * only enumerable elements are selected. Both enumerable * and non-enumerable elements are selected when using ES5. * * @id pickBy * @section Transforms * @name Stream.pickBy(f) * @param {Function} f - the predicate function * @api public */ pickBy<Prop extends keyof R>(f: (key: Prop, value: R[Prop]) => boolean): Stream<Partial<R>>; /** * Retrieves values associated with a given property from all elements in * the collection. * * @id pluck * @section Streams * @name Stream.pluck(property) * @param {String} prop - the property to which values should be associated * @api public */ pluck<Prop extends keyof R>(prop: Prop): Stream<R[Prop]>; pluck<U>(prop: string): Stream<U>; /** * Limits number of values through the stream to a maximum of number of values * per window. Errors are not limited but allowed to pass through as soon as * they are read from the source. * * @id ratelimit * @section Transforms * @name Stream.ratelimit(num, ms) * @param {Number} num - the number of operations to perform per window * @param {Number} ms - the window of time to limit the operations in (in ms) * @api public * * _([1, 2, 3, 4, 5]).ratelimit(2, 100); * * // after 0ms => 1, 2 * // after 100ms => 1, 2, 3, 4 * // after 200ms => 1, 2, 3, 4, 5 */ ratelimit(num: number, ms: number): Stream<R>; /** * Boils down a Stream to a single value. The memo is the initial state * of the reduction, and each successive step of it should be returned by * the iterator function. The iterator is passed two arguments: * the memo and the next value. * * @id reduce * @section Streams * @name Stream.reduce(memo, iterator) * @param memo - the initial state of the reduction * @param {Function} iterator - the function which reduces the values * @api public */ reduce<U>(memo: U, iterator: (memo: U, x: R) => U): Stream<U>; /** * Same as [reduce](#reduce), but uses the first element as the initial * state instead of passing in a `memo` value. * * @id reduce1 * @section Streams * @name Stream.reduce1(iterator) * @param {Function} iterator - the function which reduces the values * @api public */ reduce1<U>(iterator: (memo: R | U, x: R) => U): Stream<U>; /** * The inverse of [filter](#filter). * * @id reject * @section Streams * @name Stream.reject(f) * @param {Function} f - the truth test function * @api public * * var odds = _([1, 2, 3, 4]).reject(function (x) { * return x % 2 === 0; * }); */ reject(f: (x: R) => boolean): Stream<R>; /** * Like [reduce](#reduce), but emits each intermediate value of the * reduction as it is calculated. * * @id scan * @section Streams * @name Stream.scan(memo, iterator) * @param memo - the initial state of the reduction * @param {Function} iterator - the function which reduces the values * @api public */ scan<U>(memo: U, iterator: (memo: U, x: R) => U): Stream<U>; /** * Same as [scan](#scan), but uses the first element as the initial * state instead of passing in a `memo` value. * * @id scan1 * @section Streams * @name Stream.scan1(iterator) * @param {Function} iterator - the function which reduces the values * @api public * * _([1, 2, 3, 4]).scan1(add) // => 1, 3, 6, 10 */ scan1<U>(iterator: (memo: R | U, x: R) => U): Stream<U>; /** * Creates a new Stream with the values from the source in the range of `start` (inclusive) to `end` (exclusive). * `start` and `end` must be of type `Number`, if `start` is not a `Number` it will default to `0` * and, likewise, `end` will default to `Infinity`: this could result in the whole stream being be * returned. * * @id slice * @section Transforms * @name Stream.slice(start, end) * @param {Number} start - integer representing index to start reading from source (inclusive) * @param {Number} end - integer representing index to stop reading from source (exclusive) * @api public */ slice(start: number, end: number): Stream<R>; /** * Collects all values together then emits each value individually but in sorted order. * The method for sorting the elements is ascending lexical. * * @id sort * @section Transforms * @name Stream.sort() * @api public * * var sorted = _(['b', 'z', 'g', 'r']).sort().toArray(_.log); * // => ['b', 'g', 'r', 'z'] */ sort(): Stream<R>; /** * Collects all values together then emits each value individually in sorted * order. The method for sorting the elements is defined by the comparator * function supplied as a parameter. * * The comparison function takes two arguments `a` and `b` and should return * * - a negative number if `a` should sort before `b`. * - a positive number if `a` should sort after `b`. * - zero if `a` and `b` may sort in any order (i.e., they are equal). * * This function must also define a [partial * order](https://en.wikipedia.org/wiki/Partially_ordered_set). If it does not, * the resulting ordering is undefined. * * @id sortBy * @section Transforms * @name Stream.sortBy(f) * @param {Function} f - the comparison function * @api public */ sortBy(f: (a: R, b: R) => number): Stream<R>; /** * [splitBy](#splitBy) over newlines. * * @id split * @section Transforms * @name Stream.split() * @api public */ split(this: Stream<string>): Stream<string>; /** * Splits the source Stream by a separator and emits the pieces in between, much like splitting a string. * * `splitBy` is effectively the inverse of [intersperse](#intersperse). * * @id splitBy * @section Transforms * @name Stream.splitBy(sep) * @param {String | RegExp} sep - the separator to split on * @api public */ splitBy(this: Stream<string>, sep: string | RegExp): Stream<string>; /** * Like the [errors](#errors) method, but emits a Stream end marker after * an Error is encountered. * * @id stopOnError * @section Streams * @name Stream.stopOnError(f) * @param {Function} f - the function to handle an error * @api public */ stopOnError(f: (err: Error) => void): Stream<R>; /** * Creates a new Stream with the first `n` values from the source. * * @id take * @section Streams * @name Stream.take(n) * @param {Number} n - integer representing number of values to read from source * @api public */ take(n: number): Stream<R>; /** * An alias for the [doto](#doto) method. * * @id tap * @section Transforms * @name Stream.tap(f) * @param {Function} f - the function to apply * @api public * * _([1, 2, 3]).tap(console.log) */ tap(f: (x: R) => void): Stream<R>; /** * Ensures that only one data event is push downstream (or into the buffer) * every `ms` milliseconds, any other values are dropped. * * @id throttle * @section Streams * @name Stream.throttle(ms) * @param {Number} ms - the minimum milliseconds between each value * @api public */ throttle(ms: number): Stream<R>; /** * Filters out all duplicate values from the stream and keeps only the first * occurence of each value, using === to define equality. * * @id uniq * @section Streams * @name Stream.uniq() * @api public */ uniq(): Stream<R>; /** * Filters out all duplicate values from the stream and keeps only the first * occurence of each value, using the provided function to define equality. * * @id uniqBy * @section Streams * @name Stream.uniqBy() * @api public */ uniqBy(f: (a: R, b: R) => boolean): Stream<R>; /** * A convenient form of filter, which returns all objects from a Stream * match a set of property values. * * @id where * @section Streams * @name Stream.where(props) * @param {Object} props - the properties to match against * @api public */ where(props: Partial<R>): Stream<R>; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // HIGHER-ORDER STREAMS // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /** * Concatenates a Stream to the end of this Stream. * * Be aware that in the top-level export, the args may be in the reverse * order to what you'd expect `_([a], [b]) => [b, a]`, as this follows the * convention of other top-level exported functions which do `x` to `y`. * * @id concat * @section Streams * @name Stream.concat(ys) * @param {Stream | Array} ys - the values to concatenate onto this Stream * @api public */ concat(ys: Stream<R>): Stream<R>; concat(ys: R[]): Stream<R>; /** * Filters using a predicate which returns a Stream. If you need to check * against an asynchronous data source when filtering a Stream, this can * be convenient. The Stream returned from the filter function should have * a Boolean as it's first value (all other values on the Stream will be * disregarded). * * @id flatFilter * @section Streams * @name Stream.flatFilter(f) * @param {Function} f - the truth test function which returns a Stream * @api public */ flatFilter(f: (x: R) => Stream<boolean>): Stream<R>; /** * Creates a new Stream of values by applying each item in a Stream to an * iterator function which must return a (possibly empty) Stream. Each * item on these result Streams are then emitted on a single output Stream. * * This transform is functionally equivalent to `.map(f).sequence()`. * * @id flatMap * @section Streams * @name Stream.flatMap(f) * @param {Function} f - the iterator function * @api public */ flatMap<U>(f: (x: R) => Stream<U>): Stream<U>; flatMap<U>(f: (x: R) => U): Stream<U>; /** * Recursively reads values from a Stream which may contain nested Streams * or Arrays. As values or errors are encountered, they are emitted on a * single output Stream. * * @id flatten * @section Streams * @name Stream.flatten() * @api public */ flatten<U extends Flattened<R>>(): Stream<U>; /** * Forks a stream, allowing you to add additional consumers with shared * back-pressure. A stream forked to multiple consumers will only pull values * from it's source as fast as the slowest consumer can handle them. * * @id fork * @section Streams * @name Stream.fork() * @api public */ fork(): Stream<R>; /** * Takes a Stream of Streams and merges their values and errors into a * single new Stream. The merged stream ends when all source streams have * ended. * * Note that no guarantee is made with respect to the order in which * values for each stream end up in the merged stream. Values in the * merged stream will, however, respect the order they were emitted from * their respective streams. * * @id merge * @section Streams * @name Stream.merge() * @api public * * var txt = _(['foo.txt', 'bar.txt']).map(readFile) * var md = _(['baz.md']).map(readFile) * * _([txt, md]).merge(); * // => contents of foo.txt, bar.txt and baz.txt in the order they were read */ merge<U>(this: Stream<Stream<U>>): Stream<U>; /** * Takes a Stream of Streams and merges their values and errors into a * single new Stream, limitting the number of unpaused streams that can * running at any one time. * * Note that no guarantee is made with respect to the order in which * values for each stream end up in the merged stream. Values in the * merged stream will, however, respect the order they were emitted from * their respective streams. * * @id mergeWithLimit * @section Higher-order Streams * @name Stream.mergeWithLimit(n) * @param {Number} n - the maximum number of streams to run in parallel * @api public * * var readFile = _.wrapCallback(fs.readFile); * * var txt = _(['foo.txt', 'bar.txt']).flatMap(readFile) * var md = _(['baz.md']).flatMap(readFile) * var js = _(['bosh.js']).flatMap(readFile) * * _([txt, md, js]).mergeWithLimit(2); * // => contents of foo.txt, bar.txt, baz.txt and bosh.js in the order * // they were read, but bosh.js is not read until either foo.txt and bar.txt * // has completely been read or baz.md has been read */ mergeWithLimit<U>(this: Stream<Stream<U>>, n: number): Stream<U>; /** * Observes a stream, allowing you to handle values as they are emitted, without * adding back-pressure or causing data to be pulled from the source. This can * be useful when you are performing two related queries on a stream where one * would block the other. Just be aware that a slow observer could fill up it's * buffer and cause memory issues. Where possible, you should use [fork](#fork). * * @id observe * @section Streams * @name Stream.observe() * @api public */ observe(): Stream<R>; /** * Switches source to an alternate Stream if the current Stream is empty. * * @id otherwise * @section Streams * @name Stream.otherwise(ys) * @param {Stream} ys - alternate stream to use if this stream is empty * @api public */ otherwise(ys: Stream<R>): Stream<R>; /** * Takes a Stream of Streams and reads from them in parallel, buffering * the results until they can be returned to the consumer in their original * order. * * @id parallel * @section Streams * @name Stream.parallel(n) * @param {Number} n - the maximum number of concurrent reads/buffers * @api public */ parallel<U>(this: Stream<Stream<U>>, n: number): Stream<U>; /** * Reads values from a Stream of Streams, emitting them on a Single output * Stream. This can be thought of as a flatten, just one level deep. Often * used for resolving asynchronous actions such as a HTTP request or reading * a file. * * @id sequence * @section Streams * @name Stream.sequence() * @api public */ sequence<U>(this: Stream<Stream<U>>): Stream<U>; sequence<U>(this: Stream<U[]>): Stream<U>; /** * An alias for the [sequence](#sequence) method. * *