Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.skyvexsoftware.com/llms.txt

Use this file to discover all available pages before exploring further.

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: PendingPhaseTransition | null;
  trends: FlightTrends | null;
  isTracking: boolean;
};

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:
type PendingPhaseTransition = {
  phase: FlightPhase;
  elapsed: number;   // milliseconds spent waiting
  required: number;  // milliseconds required before transition
};

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. 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.