All files / client/src/hooks use-simulation.ts

100% Statements 5/5
50% Branches 1/2
100% Functions 1/1
100% Lines 5/5

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                                                                                                                11x 11x         11x     11x                         11x              
import { useRef } from "react";
import { useSimulationControls, UseSimulationControlsParams, SimulationStatus } from "./use-simulation-controls";
import { useSimulationLifecycle } from "./use-simulation-lifecycle";
 
// re-export types removed (unused exports per knip)
 
// The hook accepts the same parameters as `useSimulationControls` plus a few
// extras that are required by the lifecycle automation.  A parent may also
// provide an optional `startSimulationRef` so it can invoke the start action
// before the hook itself is instantiated (used by the page when wiring up
// the compilation hook).
type UseSimulationParams = UseSimulationControlsParams & {
  startSimulationRef?: React.MutableRefObject<(() => void) | null>;
  // forwarded to lifecycle hook
  code: string;
  clearOutputs?: () => void;
  handlePause?: () => void;
  handleResume?: () => void;
  handleReset?: () => void;
  hasCompilationErrors?: boolean;
};
 
interface UseSimulationResult {
  // state values (mirrors useSimulationControls)
  simulationStatus: SimulationStatus;
  setSimulationStatus: React.Dispatch<React.SetStateAction<SimulationStatus>>;
  hasCompiledOnce: boolean;
  setHasCompiledOnce: React.Dispatch<React.SetStateAction<boolean>>;
  simulationTimeout: number;
  setSimulationTimeout: React.Dispatch<React.SetStateAction<number>>;
 
  // mutations returned by the underlying controls hook (for tests/inspection)
  startMutation: ReturnType<typeof useSimulationControls>["startMutation"];
  stopMutation: ReturnType<typeof useSimulationControls>["stopMutation"];
  pauseMutation: ReturnType<typeof useSimulationControls>["pauseMutation"];
  resumeMutation: ReturnType<typeof useSimulationControls>["resumeMutation"];
 
  // action helpers (same names as before to minimise page changes)
  handleStart: () => void;
  handleStop: () => void;
  handlePause: () => void;
  handleResume: () => void;
  handleReset: () => void;
 
  // allow external callers (eg. useCompilation) to start the sim directly
  startSimulation: () => void;
 
  // lifecycle helper: caller can suppress the auto-stop behaviour once
  suppressAutoStopOnce: () => void;
 
  // ref that will be populated with the "real" start function
  startSimulationRef: React.MutableRefObject<(() => void) | null>;
}
 
export function useSimulation(params: UseSimulationParams): UseSimulationResult {
  // honour an external ref if supplied; otherwise create our own
  const internalRef = useRef<(() => void) | null>(null);
  const startSimulationRef = params.startSimulationRef ?? internalRef;
 
  // delegate to the existing controls hook; this preserves all existing
  // behaviour including stop/start/pause/resume/reset.  we still spread the
  // ref so the underlying hook can populate it for callers.
  const controls = useSimulationControls({ ...params, startSimulationRef });
 
  // plug in lifecycle automation
  const { suppressAutoStopOnce } = useSimulationLifecycle({
    code: params.code,
    simulationStatus: controls.simulationStatus,
    setSimulationStatus: controls.setSimulationStatus,
    sendMessage: params.sendMessage,
    resetPinUI: params.resetPinUI,
    clearOutputs: params.clearOutputs,
    handlePause: controls.handlePause,
    handleResume: controls.handleResume,
    handleReset: controls.handleReset,
    hasCompilationErrors: params.hasCompilationErrors,
  });
 
  return {
    ...controls,
    suppressAutoStopOnce,
    startSimulationRef,
    startSimulation: controls.handleStart,
  };
}