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 */
29export 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 */
50export 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 */
82export 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}