All files / src/primitives lisAsync.ts

100% Statements 36/36
100% Branches 9/9
100% Functions 3/3
100% Lines 36/36

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 561x                     1x 6x 6x 6x 6x   1x 1x   5x     5x 1x 1x 5x   5x 2x 2x   2x 1x 1x 1x 1x 2x   5x 1x 1x 1x 1x   5x   5x 6x 1x 1x 1x 1x 6x 6x  
import LISWorker from './lis.worker.ts?worker';
 
/**
 * Finds the LIS of a sequence asynchronously in a Web Worker.
 *
 * This is the recommended approach for extremely large arrays to avoid blocking the main UI thread.
 *
 * @param seq The sequence of numbers. Must be a TypedArray for zero-copy transfer.
 * @returns A Promise that resolves with the array of LIS indices.
 * @throws An error if the worker computation fails or times out.
 */
export function longestIncreasingSubsequenceAsync(
  seq: Int32Array | Uint32Array | Float32Array | Float64Array
): Promise<number[]> {
  return new Promise((resolve, reject) => {
    if (!seq || seq.length === 0) {
      // Handle empty input gracefully without creating a worker.
      return resolve([]);
    }
 
    const worker = new LISWorker();
 
    // Set a timeout to prevent hanging workers.
    const timeout = setTimeout(() => {
      worker.terminate();
      reject(new Error('Worker timeout: LIS computation took too long.'));
    }, 30000); // 30-second timeout
 
    worker.onmessage = (event: MessageEvent<number[] | { error: string }>) => {
      clearTimeout(timeout);
      worker.terminate();
      
      if (event.data && typeof event.data === 'object' && 'error' in event.data) {
        reject(new Error(event.data.error));
      } else {
        resolve(event.data as number[]);
      }
    };
 
    worker.onerror = (error: ErrorEvent) => {
      clearTimeout(timeout);
      worker.terminate();
      reject(new Error(`Worker error: ${error.message}`));
    };
 
    try {
      // Post the sequence to the worker with a transferable object.
      worker.postMessage(seq, [seq.buffer]);
    } catch (error) {
      clearTimeout(timeout);
      worker.terminate();
      reject(error);
    }
  });
}