All files / src/impl CompleteLater.impl.ts

100% Statements 16/16
100% Branches 2/2
100% Functions 1/1
100% Lines 16/16

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 3312x     12x                   12x 19x 18x 18x 18x   18x 18x 18x 10x   8x 8x 8x   18x 8x      
import { Consumer, Type as ConsumerType, fromType as fromTypeToConsumer } from "@jonloucks/concurrency-ts/auxiliary/Consumer";
import { OnCompletion } from "@jonloucks/concurrency-ts/api/OnCompletion";
import { RequiredType, OptionalType, Throwable } from "@jonloucks/concurrency-ts/api/Types";
import { onCompletionCheck } from "@jonloucks/concurrency-ts/auxiliary/Checks";
import { CompletionState } from "@jonloucks/concurrency-ts/api/Completion";
 
/**
 * Completes the given OnCompletion later by delegating to the provided delegate.
 * If the delegate throws, the OnCompletion is completed with FAILED state.
 *
 * @param onCompletion The OnCompletion to complete
 * @param delegate The delegate to which completion is delegated
 */
export function completeLater<T>(onCompletion: RequiredType<OnCompletion<T>>, delegate: RequiredType<ConsumerType<OnCompletion<T>>>): void {
  const validOnCompletion = onCompletionCheck(onCompletion); // only validate onCompletion here
  let state: CompletionState = 'PENDING';
  let thrown: OptionalType<Throwable<unknown>> = undefined;
  let delegated: boolean = false;
 
  try {
    const validDelegate: Consumer<OnCompletion<T>> = fromTypeToConsumer(delegate);
    validDelegate.consume(onCompletion); // ownership transferred
    delegated = true;
  } catch (caught) {
    thrown = caught;
    state = 'FAILED';
    throw thrown;
  } finally {
    if (!delegated) {
      validOnCompletion.onCompletion({ state, thrown });
    }
  }
}