Skip to main content
useFlightPhase subscribes to flight phase changes via Socket.io and keeps the TanStack Query cache in sync. It only re-renders when the phase actually changes — not on every simulator data tick. On mount it hydrates from GET /api/simulator/flight-phase/snapshot, then listens for flight:phase Socket.io events.

Import

import { useFlightPhase } from "@skyvexsoftware/stratos-sdk";

Signature

function useFlightPhase<TSelected = FlightPhaseSnapshot>(
  options?: UseFlightPhaseOptions<TSelected>
): UseFlightPhaseReturn<TSelected>

type UseFlightPhaseOptions<TSelected = FlightPhaseSnapshot> = {
  select?: (snapshot: FlightPhaseSnapshot) => TSelected;
};

type UseFlightPhaseReturn<TSelected = FlightPhaseSnapshot> = {
  data: TSelected;
  isLoading: boolean;
};

Parameters

ParameterTypeDescription
options.select(snapshot: FlightPhaseSnapshot) => TSelectedSelector function. The component only re-renders when the selected value changes.

FlightPhaseSnapshot

See FlightPhaseSnapshot for the full shape.

PendingPhaseTransition

When the flight state manager is about to transition to a new phase (waiting for the debounce timer to expire), this object describes the pending change. See PendingPhaseTransition for the full shape.

FlightPhase enum

See FlightPhase for all values. The typical progression is:
BOARDING → PUSH_BACK → TAXI → TAKE_OFF → CLIMB → CRUISE
→ DESCENT → APPROACH → FINAL → LANDED → TAXI_IN → ARRIVED → DEBOARDING
Special phases (GO_AROUND, REJECTED_TAKE_OFF) can interrupt this sequence. The ARRIVED to DEBOARDING transition is triggered when all engines are off (using the composite engine*On fields from FlightData, which check N1/RPM thresholds). DEBOARDING is sticky — once entered, it does not transition to another phase.

Usage

import { useFlightPhase, FlightPhase } from "@skyvexsoftware/stratos-sdk";

export function PhaseBadge() {
  const { data, isLoading } = useFlightPhase();

  if (isLoading) return <span>Loading...</span>;

  return <span>{data?.currentPhase ?? FlightPhase.UNKNOWN}</span>;
}

Selector pattern

Subscribe only to the current phase string — the component will not re-render on trends or pendingTransition changes:
const { data: phase } = useFlightPhase({
  select: (s) => s.currentPhase,
});

const isCruising = phase === FlightPhase.CRUISE;

Detecting phase transitions

const { data } = useFlightPhase();

useEffect(() => {
  if (data?.currentPhase === FlightPhase.LANDED) {
    console.log("Aircraft has landed");
  }
}, [data?.currentPhase]);

Notes

  • The hook uses staleTime: Infinity — Socket.io pushes are the sole update mechanism after the initial REST hydration. There is no polling.
  • Phase transitions have built-in debounce delays in the flight state manager to prevent rapid flapping.
  • If you need the full tracking session state (isTracking, elapsedTime, etc.), use useTrackingSession instead.