| 1 | /** |
| 2 | * The `NonEmptyIterable` module provides a type-level representation of any |
| 3 | * JavaScript `Iterable` that is known to contain at least one element. A |
| 4 | * `NonEmptyIterable<A>` can be consumed anywhere an `Iterable<A>` is expected, |
| 5 | * while also carrying the guarantee that reading the first element is safe. |
| 6 | * |
| 7 | * @since 2.0.0 |
| 8 | */ |
| 9 | |
| 10 | /** |
| 11 | * Defines the type-level symbol used to brand the `NonEmptyIterable` type. |
| 12 | * |
| 13 | * **When to use** |
| 14 | * |
| 15 | * Use as the property key for the type-level brand that marks an `Iterable` as |
| 16 | * non-empty. |
| 17 | * |
| 18 | * **Details** |
| 19 | * |
| 20 | * `NonEmptyIterable<A>` includes `readonly [nonEmpty]: A`, which makes it |
| 21 | * distinct from a plain `Iterable<A>` at compile time while preserving the |
| 22 | * normal iteration shape. |
| 23 | * |
| 24 | * @see {@link NonEmptyIterable} for the branded iterable type that uses this symbol |
| 25 | * |
| 26 | * @category symbols |
| 27 | * @since 2.0.0 |
| 28 | */ |
| 29 | export declare const nonEmpty: unique symbol |
| 30 | |
| 31 | /** |
| 32 | * Represents an iterable that is guaranteed to contain at least one element. |
| 33 | * |
| 34 | * **When to use** |
| 35 | * |
| 36 | * Use to require an iterable input that must provide at least one element. |
| 37 | * |
| 38 | * **Details** |
| 39 | * |
| 40 | * `NonEmptyIterable<A>` extends the standard `Iterable<A>` interface with a type-level |
| 41 | * guarantee of non-emptiness. This allows for safe operations that would otherwise |
| 42 | * require runtime checks or could throw exceptions. |
| 43 | * |
| 44 | * The type is branded with a unique symbol to ensure type safety while maintaining |
| 45 | * full compatibility with JavaScript's iteration protocol. |
| 46 | * |
| 47 | * @category models |
| 48 | * @since 2.0.0 |
| 49 | */ |
| 50 | export interface NonEmptyIterable<out A> extends Iterable<A> { |
| 51 | readonly [nonEmpty]: A |
| 52 | } |
| 53 | |
| 54 | /** |
| 55 | * Extracts the first element and remaining elements from a non-empty iterable safely. |
| 56 | * |
| 57 | * **When to use** |
| 58 | * |
| 59 | * Use to split a non-empty iterable into its first element and an iterator for |
| 60 | * the remaining elements. |
| 61 | * |
| 62 | * **Details** |
| 63 | * |
| 64 | * This function provides a safe way to deconstruct a `NonEmptyIterable` into its |
| 65 | * head (first element) and tail (remaining elements as an iterator). Since the |
| 66 | * iterable is guaranteed to be non-empty, the first element is always available. |
| 67 | * |
| 68 | * **Example** (Extracting first and remaining elements) |
| 69 | * |
| 70 | * ```ts import.meta.vitest |
| 71 | * import { Chunk, NonEmptyIterable } from "effect" |
| 72 | * |
| 73 | * const [first, rest] = NonEmptyIterable.unprepend(Chunk.make(1, 2, 3)) |
| 74 | * |
| 75 | * first // => 1 |
| 76 | * globalThis.Array.from({ [Symbol.iterator]: () => rest }) // => [2, 3] |
| 77 | * ``` |
| 78 | * |
| 79 | * @category getters |
| 80 | * @since 2.0.0 |
| 81 | */ |
| 82 | export const unprepend = <A>(self: NonEmptyIterable<A>): [firstElement: A, remainingElements: Iterator<A>] => { |
| 83 | const iterator = self[Symbol.iterator]() |
| 84 | const next = iterator.next() |
| 85 | if (next.done) { |
| 86 | throw new Error( |
| 87 | "BUG: NonEmptyIterator should not be empty - please report an issue at https://github.com/Effect-TS/effect/issues" |
| 88 | ) |
| 89 | } |
| 90 | return [next.value, iterator] |
| 91 | } |