LCOV - code coverage report
Current view: top level - dashql-app/src/utils - async_value.ts Coverage Total Hit
Test: DashQL 915828b Lines: 90.9 % 66 60
Test Date: 2026-11-06 19:30:32

            Line data    Source code
       1              : import { LoggableException } from "../platform/logger/logger.js";
       2              : 
       3            1 : const LOG_CTX = 'async_value';
       4              : 
       5              : type Resolver<Value> = (value: Value) => void;
       6              : type Rejecter<Error> = (value: Error) => void;
       7              : 
       8            1 : enum AsyncValueStatus {
       9            1 :     PENDING = 0,
      10            1 :     RESOLVED = 1,
      11            1 :     REJECTED = 2
      12            1 : }
      13              : 
      14            1 : export class AsyncValue<Value, Error> {
      15            1 :     protected status: AsyncValueStatus;
      16            1 :     protected resolvedValue: Value | null;
      17            1 :     protected rejectionError: Error | null;
      18              : 
      19            1 :     protected valuePromise: Promise<Value> | null;
      20            1 :     protected resolveFn: Resolver<Value> | null;
      21            1 :     protected rejectFn: Rejecter<Error> | null;
      22              : 
      23            1 :     constructor() {
      24            1 :         this.status = AsyncValueStatus.PENDING;
      25            1 :         this.resolvedValue = null;
      26            1 :         this.rejectionError = null;
      27            1 :         this.valuePromise = null;
      28            1 :         this.resolveFn = null;
      29            1 :         this.rejectFn = null;
      30            1 :     }
      31              : 
      32            1 :     public isResolved(): boolean {
      33            1 :         return this.status != AsyncValueStatus.PENDING;
      34            1 :     }
      35            1 :     public async getValue(): Promise<Value> {
      36            1 :         switch (this.status) {
      37            1 :             case AsyncValueStatus.RESOLVED:
      38            1 :                 return Promise.resolve(this.resolvedValue!);
      39            1 :             case AsyncValueStatus.REJECTED:
      40            1 :                 return Promise.reject(this.rejectionError!);
      41            1 :             case AsyncValueStatus.PENDING: {
      42            1 :                 if (this.valuePromise == null) {
      43            1 :                     this.valuePromise = new Promise<Value>((resolve, reject) => {
      44            1 :                         this.resolveFn = resolve;
      45            1 :                         this.rejectFn = reject
      46            1 :                     });
      47              :                 }
      48            1 :                 return this.valuePromise;
      49              :             }
      50            1 :         }
      51            1 :     }
      52            1 :     public getResolvedValue(): Value {
      53            1 :         switch (this.status) {
      54            1 :             case AsyncValueStatus.RESOLVED:
      55            1 :                 return this.resolvedValue!;
      56            0 :             case AsyncValueStatus.REJECTED:
      57            0 :                 throw this.rejectionError;
      58            0 :             case AsyncValueStatus.PENDING:
      59            0 :                 throw new Error("async value is not resolved");
      60            1 :         }
      61            1 :     }
      62            1 :     public resolve(value: Value) {
      63            1 :         if (this.status != AsyncValueStatus.PENDING) {
      64            0 :             throw new LoggableException("tried to resolve an async value that is not pending", {}, LOG_CTX);
      65              :         }
      66            1 :         this.resolvedValue = value;
      67            1 :         this.status = AsyncValueStatus.RESOLVED;
      68            1 :         if (this.resolveFn != null) {
      69            1 :             this.resolveFn(value);
      70              :         }
      71            1 :     }
      72            1 :     public reject(error: Error) {
      73            1 :         if (this.status != AsyncValueStatus.PENDING) {
      74            0 :             throw new LoggableException(`tried to reject an async value that is not pending with error: ${error}`, {}, LOG_CTX);
      75              :         }
      76            1 :         this.rejectionError = error;
      77            1 :         this.status = AsyncValueStatus.REJECTED;
      78            1 :         if (this.rejectFn != null) {
      79            1 :             this.rejectFn(error);
      80              :         }
      81            1 :     }
      82            1 : }
        

Generated by: LCOV version 2.0-1