import { Build, Promised } from "./utils";

declare global {
  interface Generator<T = unknown, TReturn = any, TNext = unknown> {
    /**
     * Appends a value to the end of the sequence.
     * @param item The value to append to source.
     * @returns A new sequence that ends with element.
     */
    append<TItem>(item: TItem): Generator<T | TItem, TNext, TReturn>;
  }

  interface AsyncGenerator<T = unknown, TReturn = any, TNext = unknown> {
    /**
     * Appends a value to the end of the sequence.
     * @param item The value to append to source.
     * @returns A new sequence that ends with element.
     */
    append<TItem>(
      item: Promised<TItem>
    ): AsyncGenerator<T | TItem, TNext, TReturn>;
  }
}

Build(
  "append",
  function* (extra) {
    for (const item of this) {
      yield item;
    }

    yield extra;
  },
  async function* (extra) {
    for await (const item of this) {
      yield item;
    }

    yield await Promise.resolve(extra);
  }
);
