/** * @license * Copyright Google LLC * SPDX-License-Identifier: BSD-3-Clause */ /** * Incrementally parses a single JSON value from the given iterable of string * chunks. * * Yields a sequence of increasingly complete JSON values as more of the input * can be parsed. The final value yielded will be the same as running JSON.parse * on the entire input as a single string. If the input is not valid JSON, * throws an error in the same way that JSON.parse would, though the error * message is not guaranteed to be the same. * * When possible (i.e. with objects and arrays), the yielded JSON values will * be reused. This means that if you store a reference to a yielded value, it * will be updated in place as more of the input is parsed. * * As with JSON.parse, this throws if non-whitespace trailing content is found. * * For performance, it parses as much of the string that's synchronously * available before yielding. So the sequence of partially-complete values * that you'll see will vary based on how the input is grouped into stream * chunks. * * The following invariants will also be maintained: * * 1. Subsequent versions of a value will have the same type. i.e. we will * never yield a value as a string and then later replace it with an array * (unless the object has repeated keys, see invariant 7). * 2. true, false, null, and numbers are atomic, we don't yield them until * we have the entire value. * 3. Strings may be replaced with a longer string, with more characters (in * the JavaScript sense) appended. * 4. Arrays are modified only by appending new elements or * replacing/mutating the element currently at the end. * 5. Objects are only modified by either adding new properties, or * replacing/mutating the most recently added property, (except in the case * of repeated keys, see invariant 7). * 6. As a consequence of 1 and 5, we only add a property to an object once we * have the entire key and enough of the value to know that value's type. * 7. If an object has the same key multiple times, later values take * precedence over earlier ones, matching the behavior of JSON.parse. This * may result in changing the type of a value, and setting earlier keys * the object. */ export declare function parse(stream: AsyncIterable, options?: Options): AsyncIterableIterator; interface Options { /** * A callback that's called with each value once that value is complete. It * will also be given information about the path to each * completed value. * * The calls that jsonriver makes to a `completeCallback` are deterministic, * regardless of how the incoming JSON streams in. * * Formally, a value is complete when jsonriver will not mutate it again, nor * replace it with a different value, except for the unusual case of a * repeated key in an object (see invariant 7 in the parse() docs). * * For example, when parsing this JSON: * ```json * {"name": "Alex", "keys": [1, 20, 300]} * ``` * * The complete callback will be called six times, with the following values: * * ```js * "Alex" * 1 * 20 * 300 * [1, 20, 300] * {"name": "Alex", "keys": [1, 20, 300]} * ``` * * And the path segments would be: * * ```js * ['name'] // the 'keys' property on a toplevel object * ['keys', 0] // the 0th item in the array on the 'keys' prop * ['keys', 1] // the 1st item on that array * ['keys', 2] // the 2nd * ['keys'] // the 'keys' property is now complete * [] // finally, the toplevel value is complete * ``` */ completeCallback?: (value: JsonValue, path: Path) => void; } /** * The path of a complete value inside the toplevel parsed value. * * Note that Path values may be reused between calls to the complete callback. */ interface Path { /** * Constructs an array of the path to the most recently completed value. * * This method should be called synchronously when the completeCallback is * called, as the segments array is created lazily on demand based on the * parser's internal state. */ segments(): Array; } export type JsonValue = null | boolean | number | string | JsonValue[] | JsonObject; export type JsonObject = { [key: string]: JsonValue; }; export {};