All files / components KoconutPrimitive.ts

100% Statements 27/27
100% Branches 11/11
100% Functions 9/9
100% Lines 26/26

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 1761x   1x                 1x               968x 968x         974x 974x           1845x     1845x                                                   1845x 948x 948x 40x   1845x 1798x 1494x 1494x   1798x 1798x         4x 4x                                                     1708x 1696x                                                                 1x                                                               1x 1x      
`use strict`;
 
import {
  KoconutYieldable,
  KoconutOpener,
  KoconutSequence,
  Sequence,
  Selector,
  Processor,
} from '../module';
 
export class KoconutPrimitive<DataType> implements KoconutYieldable<DataType> {
  protected data: DataType | null;
  protected prevYieldable?: KoconutYieldable<any>;
  protected processor?: () => Promise<DataType>;
 
  protected setPrevYieldable(
    prevYieldable: KoconutYieldable<any>,
  ): KoconutOpener<DataType> {
    this.prevYieldable = prevYieldable;
    return this as any as KoconutOpener<DataType>;
  }
  protected setProcessor(
    processor: () => Promise<DataType>,
  ): KoconutOpener<DataType> {
    this.processor = processor;
    return this as any as KoconutOpener<DataType>;
  }
 
  protected async validate(data: DataType | null) {}
 
  constructor(data: DataType | null = null) {
    this.data = data;
  }
 
  protected isValidated = false;
 
  // Processor
  /**
   * Processes all the chained objects ane returns ```Promise<void>```.
   *
   * @since 1.0.10
   *
   * @category Processor
   *
   * @example
   * ```typescript
   * import { KoconutArray } from 'koconut'
   *
   * const mainProcess = async () => {
   *   const koconutNumbers = KoconutArray.of(1,2,3,4,5)
   *
   *   await koconutNumbers
   *               .forEach(console.log)
   *               .process()
   *   // ↑ 1 2 3 4 5
   * }
   * mainProcess()
   * ```
   */
  async process(): Promise<void> {
    if (this.prevYieldable != null) {
      this.data = await this.prevYieldable.yield();
      if (!(this instanceof KoconutSequence) && this.data instanceof Sequence)
        await this.data.done();
    }
    if (this.processor != null) this.data = await this.processor();
    if (!this.isValidated) {
      await this.validate(this.data);
      this.isValidated = true;
    }
    delete this.prevYieldable;
    delete this.processor;
  }
 
  // No Comment -- All the classes inheriting this.
  async retrieve(): Promise<KoconutPrimitive<DataType>> {
    await this.process();
    return this;
  }
 
  /**
   * Processes all the chained objects and return the result.
   *
   * @since 1.0.10
   *
   * @category Processor
   *
   * @example
   * ``` typescript
   * import { KoconutArray } from 'koconut'
   *
   * const mainProcess = async () => {
   *   const koconutNumbers = KoconutArray.of(1,2,3,4,5)
   *
   *   const firstNumber = await koconutNumbers
   *                                       .first()
   *                                       .yield()
   *   console.log(firstNumber)
   *   // ↑ 1
   * }
   * mainProcess()
   * ```
   */
  async yield(): Promise<DataType> {
    await this.process();
    return this.data!;
  }
 
  /**
   * Processes all the chained objects and calls the specified function
   * ```block``` with the result value as its argument and returns the final result
   * of the ```block```.
   *
   * @param {SingleInputSingleOutCallback} block A callback function that accepts an argument. The method calls the `block` and returns its result.
   *
   * @since 1.0.10
   *
   * @category Processor
   *
   * @example
   * ``` typescript
   * import { KoconutArray } from 'koconut'
   *
   * const mainProcess = async () => {
   *   const koconutNumbers = KoconutArray.of(1,2,3,4,5)
   *
   *   const firstNumberPlus2 = await koconutNumbers
   *                           .first()
   *                           .let(result => result + 2)
   *   console.log(firstNumber)
   *   // ↑ 3
   * }
   * mainProcess()
   * ```
   */
  async let<ReturnType>(
    block: Selector<DataType, ReturnType>,
  ): Promise<ReturnType> {
    return await block(await this.yield());
  }
 
  /**
   * Processes all the chained objects and calls the specified function
   * ```block``` with the result value as its argument and returns the original result.
   * @param {Processor} block A callback function that accepts an argument.
   *
   * @since 1.0.10
   *
   * @category Processor
   *
   * @example
   * ```typescript
   * import { KoconutArray } from 'koconut'
   *
   * const mainProcess = async () => {
   *   const koconutNumbers = KoconutArray.of(1,2,3,4,5)
   *
   *   const moreNumbers = await koconutNumbers
   *                           .also(result => {
   *                               result.push(6)
   *                               result.push(7)
   *                               result.push(8)
   *                           })
   *   console.log(moreNumbers)
   *   // ↑ [1, 2, 3, 4, 5, 6, 7, 8]
   * }
   * mainProcess()
   * ```
   */
  async also(block: Processor<DataType>): Promise<DataType | null> {
    await block(await this.yield());
    return this.data;
  }
}