All files / kernel-ui/src/hooks useStatusPolling.ts

100% Statements 19/19
100% Branches 7/7
100% Functions 5/5
100% Lines 19/19

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                                3x         12x 12x         12x 9x 12x 1x   11x 11x       10x 1x   7x   4x       9x 3x     9x   9x 2x       12x    
import { stringify } from '@metamask/kernel-utils';
import type { KernelStatus } from '@metamask/ocap-kernel';
import { hasProperty } from '@metamask/utils';
import { useEffect, useRef, useState } from 'react';
 
import type { StreamState } from './useStream.ts';
import { logger } from '../services/logger.ts';
 
/**
 * Hook to start polling for kernel status
 *
 * @param callKernelMethod - Function to send a message to the kernel
 * @param isRequestInProgress - Ref to track if a request is in progress
 * @param interval - Polling interval in milliseconds
 * @returns The kernel status
 */
export const useStatusPolling = (
  callKernelMethod: StreamState['callKernelMethod'],
  isRequestInProgress: React.RefObject<boolean>,
  interval: number = 1000,
): KernelStatus | undefined => {
  const pollingRef = useRef<NodeJS.Timeout>();
  const [status, setStatus] = useState<KernelStatus>();
 
  /**
   * Effect to start polling for kernel status.
   */
  useEffect(() => {
    const fetchStatus = async (): Promise<void> => {
      if (!callKernelMethod || isRequestInProgress.current) {
        return;
      }
      try {
        const result = await callKernelMethod({
          method: 'getStatus',
          params: [],
        });
        if (hasProperty(result, 'error')) {
          throw new Error(stringify(result.error, 0));
        }
        setStatus(result);
      } catch (error) {
        logger.error('Failed to fetch status:', error);
      }
    };
 
    pollingRef.current = setInterval(() => {
      fetchStatus().catch(logger.error);
    }, interval);
 
    fetchStatus().catch(logger.error);
 
    return () => {
      clearInterval(pollingRef.current);
    };
  }, [callKernelMethod, interval, isRequestInProgress]);
 
  return status;
};