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

type FlightPhaseSnapshot = {
  currentPhase: FlightPhase;
  previousPhase: FlightPhase | null;
  pendingTransition: FlightPhase | null;
  trends: FlightTrends | null;
  isTracking: boolean;
};

FlightPhase enum

enum FlightPhase {
  UNKNOWN        = "unknown",
  BOARDING       = "boarding",
  PUSH_BACK      = "push_back",
  TAXI           = "taxi",
  TAKE_OFF       = "take_off",
  REJECTED_TAKE_OFF = "rejected_take_off",
  CLIMB          = "climb",
  CRUISE         = "cruise",
  DESCENT        = "descent",
  APPROACH       = "approach",
  FINAL          = "final",
  LANDED         = "landed",
  GO_AROUND      = "go_around",
  TAXI_IN        = "taxi_in",
  ARRIVED        = "arrived",
  DEBOARDING     = "deboarding",
}
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.

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.