Skip to main content
useTrackingSession is the recommended entry point for tracking-aware plugins. It wraps the lower-level useFlightManager and adds derived state: isTracking, isPaused, elapsedTime (ticking locally every second), phase, and crash recovery handling. Use this hook when your plugin needs to know whether a flight is active or wants to show elapsed time. Fall back to useFlightManager only when you need the raw CurrentFlight object without derived fields, or want to avoid the extra effect for the elapsed timer.

Import

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

Signature

function useTrackingSession(): UseTrackingSessionReturn

type UseTrackingSessionReturn = {
  isTracking: boolean;
  isPaused: boolean;
  currentFlight: CurrentFlight | null;
  pendingRecovery: RecoverableFlight | null;
  elapsedTime: number;
  phase: FlightPhase;
  startFlight: (
    plan: FlightPlan,
    options?: { skipPreflightWarnings?: boolean; forceStart?: boolean }
  ) => Promise<StartFlightResult>;
  pauseFlight: () => Promise<boolean>;
  resumeFlight: () => Promise<boolean>;
  endFlight: (
    status?: "completed" | "diverted" | "crashed" | "cancelled"
  ) => Promise<{ success: boolean; error?: string }>;
  recoverFlight: () => Promise<boolean>;
  dismissRecovery: () => Promise<boolean>;
  isLoading: boolean;
};

Return value

FieldTypeDescription
isTrackingbooleantrue when a flight is active or paused
isPausedbooleantrue when the active flight is paused
currentFlightCurrentFlight | nullFull flight state object, or null when idle
pendingRecoveryRecoverableFlight | nullA previous flight that can be recovered, if one exists
elapsedTimenumberElapsed flight time in milliseconds, updating every second
phaseFlightPhaseCurrent flight phase (defaults to FlightPhase.BOARDING when idle)
startFlightFunctionStart a new flight; accepts optional start options
pauseFlight() => Promise<boolean>Pause the active flight
resumeFlight() => Promise<boolean>Resume a paused flight
endFlight(status?) => Promise<{ success, error? }>End the active flight
recoverFlight() => Promise<boolean>Recover a previously interrupted flight
dismissRecovery() => Promise<boolean>Dismiss the pending recovery prompt
isLoadingbooleantrue during the initial REST hydration

RecoverableFlight

When Stratos detects a flight was interrupted (e.g. the app crashed mid-flight), pendingRecovery is populated with a lean summary of that flight:
type RecoverableFlight = {
  id: string;
  callsign: string | null;
  departureIcao: string | null;
  arrivalIcao: string | null;
  aircraftIcao: string | null;
  latitude: number | null;
  longitude: number | null;
  altitude: number | null;
  heading: number | null;
  groundSpeed: number | null;
  startedAt: number | null;
  elapsedMs: number;
  status: string;
  phase: string | null;
};

Usage

Basic tracking display

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

export function TrackingStatus() {
  const { isTracking, isPaused, phase, elapsedTime } = useTrackingSession();

  const formatTime = (ms: number) => {
    const h = Math.floor(ms / 3_600_000);
    const m = Math.floor((ms % 3_600_000) / 60_000);
    const s = Math.floor((ms % 60_000) / 1_000);
    return `${h}:${String(m).padStart(2, "0")}:${String(s).padStart(2, "0")}`;
  };

  if (!isTracking) return <p>No active flight</p>;

  return (
    <div>
      <p>Phase: {phase}</p>
      <p>Elapsed: {formatTime(elapsedTime)}</p>
      <p>{isPaused ? "Paused" : "Active"}</p>
    </div>
  );
}

Start a flight with options

const { startFlight } = useTrackingSession();

const result = await startFlight(
  {
    source: "simbrief",
    sourceId: "12345678",
    callsign: "QFA001",
    departureIcao: "YSSY",
    arrivalIcao: "EGLL",
    route: ["SY", "LL"],
    aircraftIcao: "A388",
  },
  { skipPreflightWarnings: false, forceStart: false },
);

if (result.vaConfirmation) {
  // Show VA confirmation dialog before the flight is fully registered
  console.log(result.vaConfirmation);
}

Recovery handling

const { pendingRecovery, recoverFlight, dismissRecovery } = useTrackingSession();

if (pendingRecovery) {
  return (
    <div>
      <p>Interrupted flight found: {pendingRecovery.callsign}</p>
      <button onClick={recoverFlight}>Recover</button>
      <button onClick={dismissRecovery}>Dismiss</button>
    </div>
  );
}

Notes

  • elapsedTime is computed locally via a 1-second setInterval so it ticks smoothly between server broadcasts (which occur every ~15 seconds).
  • The hook uses staleTime: Infinity and refetches on socket reconnect to catch flights started before the UI loaded.
  • The TanStack Query cache key is ["tracking-session", "state"] — this is the same key used across the shell and all plugins, ensuring consistent state with no duplicate requests.