/** * Copyright (c) 2021 OpenLens Authors * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ export type Falsey = false | 0 | "" | null | undefined; /** * Create a new type safe empty Iterable * @returns An `Iterable` that yields 0 items */ export function* newEmpty(): Iterable { return; } /** * Creates a new `Iterable` that yields at most n items from src. * Does not modify `src` which can be used later. * @param src An initial iterator * @param n The maximum number of elements to take from src. Yields up to the floor of `n` and 0 items if n < 0 */ export function* take(src: Iterable, n: number): Iterable { outer: for (let i = 0; i < n; i += 1) { for (const item of src) { yield item; continue outer; } // if we are here that means that `src` has been exhausted. Don't bother trying again. break outer; } } /** * Creates a new iterator that iterates (lazily) over its input and yields the * result of `fn` for each item. * @param src A type that can be iterated over * @param fn The function that is called for each value */ export function* map(src: Iterable, fn: (from: T) => U): Iterable { for (const from of src) { yield fn(from); } } /** * The single layer flattening of an iterator, discarding `Falsey` values. * @param src A type that can be iterated over * @param fn The function that returns either an iterable over items that should be filtered out or a `Falsey` value indicating that it should be ignored */ export function* filterFlatMap(src: Iterable, fn: (from: T) => Iterable | Falsey): Iterable { for (const from of src) { if (!from) { continue; } const mapping = fn(from); if (!mapping) { continue; } for (const mapped of mapping) { if (mapped) { yield mapped; } } } } /** * Returns a new iterator that yields the items that each call to `fn` would produce * @param src A type that can be iterated over * @param fn A function that returns an iterator */ export function* flatMap(src: Iterable, fn: (from: T) => Iterable): Iterable { for (const from of src) { yield* fn(from); } } /** * Creates a new iterator that iterates (lazily) over its input and yields the * items that return a `truthy` value from `fn`. * @param src A type that can be iterated over * @param fn The function that is called for each value */ export function* filter(src: Iterable, fn: (from: T) => any): Iterable { for (const from of src) { if (fn(from)) { yield from; } } } /** * Creates a new iterator that iterates (lazily) over its input and yields the * result of `fn` when it is `truthy` * @param src A type that can be iterated over * @param fn The function that is called for each value */ export function* filterMap(src: Iterable, fn: (from: T) => U | Falsey): Iterable { for (const from of src) { const res = fn(from); if (res) { yield res; } } } /** * Creates a new iterator that iterates (lazily) over its input and yields the * result of `fn` when it is not null or undefined * @param src A type that can be iterated over * @param fn The function that is called for each value */ export function* filterMapStrict(src: Iterable, fn: (from: T) => U | null | undefined): Iterable { for (const from of src) { const res = fn(from); if (res != null) { yield res; } } }