Skip to main content
This page covers all Socket.io-based hooks exported from the SDK. The primary hook for most plugins is useSimData. The lower-level hooks (useSocket, useSimulatorData, etc.) are available when you need direct event access.

Import

import {
  useSimData,
  useSocket,
  useSimulatorData,
  useProtocolUrl,
  useNotifications,
  useSystemMetrics,
} from "@skyvexsoftware/stratos-sdk";

useSimData

TanStack Query + Socket.io hook for real-time simulator data. Hydrates from GET /api/simulator/snapshot on mount, then subscribes to simulator:data and simulator:status events via Socket.io. Performance: Simulator data arrives at 10–20 Hz. Updates are buffered and flushed via requestAnimationFrame, aligning cache writes to the browser’s ~60 fps paint cycle. Multiple components share a single TanStack Query cache entry — there is no duplicate subscription overhead.

Signature

function useSimData<TSelected = SimDataSnapshot>(
  options?: UseSimDataOptions<TSelected>
): UseSimDataReturn<TSelected>

type UseSimDataOptions<TSelected = SimDataSnapshot> = {
  select?: (snapshot: SimDataSnapshot) => TSelected;
};

type UseSimDataReturn<TSelected = SimDataSnapshot> = {
  data: TSelected;
  isLoading: boolean;
};

Parameters

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

SimDataSnapshot

type SimDataSnapshot = {
  data: FlightData | null;
  isConnected: boolean;
  simulatorType: SimulatorType;
};
FlightData contains all simulator variables: position, speed, altitude, heading, engine data, fuel, weather, flaps, gear, and more. Import the type from @skyvexsoftware/stratos-sdk for the full definition.

Usage

// Full snapshot — re-renders on any field change
const { data, isLoading } = useSimData();

if (!isLoading && data?.isConnected) {
  console.log(data.data?.altitude);
}
// Position selector — re-renders only when lat/lon/heading change
const { data: pos } = useSimData({
  select: (s) => ({
    lat: s?.data?.latitude ?? 0,
    lon: s?.data?.longitude ?? 0,
    hdg: s?.data?.heading ?? 0,
  }),
});
// Single scalar — re-renders only when altitude changes
const { data: altitude } = useSimData({
  select: (s) => s?.data?.altitude ?? 0,
});

useSocket

Core Socket.io connection hook. Uses a singleton SocketManager — all consumers share a single underlying socket. The socket connects when the first subscriber mounts and disconnects one second after the last subscriber unmounts.

Signature

function useSocket(): UseSocketReturn

type UseSocketReturn = {
  socket: Socket | null;
  isConnected: boolean;
  connectionState: ConnectionState;  // "disconnected" | "connecting" | "connected" | "error"
  clientId: string | null;
  connect: () => void;
  disconnect: () => void;
  subscribe: (eventType: string) => void;
  unsubscribe: (eventType: string) => void;
};

Usage

function ConnectionStatus() {
  const { isConnected, connectionState } = useSocket();

  return <span>{connectionState}</span>;
}

useSimulatorData

Raw event streaming hook. Calls your callbacks directly on each simulator:data and simulator:status event. Prefer useSimData unless you need the raw payload or must bypass TanStack Query caching.

Signature

function useSimulatorData(
  onData?: (payload: SimulatorDataPayload) => void,
  onStatus?: (payload: SimulatorStatusPayload) => void,
): {
  isConnected: boolean;
  latestData: SimulatorDataPayload | null;
  simulatorStatus: SimulatorStatusPayload | null;
}

Usage

const logger = usePluginLogger();

const { latestData, isConnected } = useSimulatorData(
  (payload) => logger.debug("SimData", "Received data", payload),
  (status) => logger.info("SimData", "Status changed", status),
);

useProtocolUrl

Receives deep link events dispatched when the OS opens a stratos:// URL while the app is running.

Signature

function useProtocolUrl(
  onProtocolUrl?: (payload: ProtocolUrlPayload) => void,
): ProtocolUrlPayload | null

Usage

const latestUrl = useProtocolUrl((payload) => {
  console.log("Received protocol URL:", payload.url);
});

useNotifications

Accumulates shell notification events for the duration of the component’s lifetime.

Signature

function useNotifications(
  onNotification?: (payload: NotificationPayload) => void,
): {
  notifications: NotificationPayload[];
  clearNotifications: () => void;
}

Usage

const { notifications, clearNotifications } = useNotifications();

return (
  <ul>
    {notifications.map((n, i) => <li key={i}>{n.message}</li>)}
  </ul>
);

useSystemMetrics

Streams system metrics (CPU, memory, etc.) from the shell process.

Signature

function useSystemMetrics(
  onMetrics?: (payload: SystemMetricsPayload) => void,
): {
  isConnected: boolean;
  metrics: SystemMetricsPayload | null;
}

Usage

const { metrics } = useSystemMetrics();

return <span>CPU: {metrics?.cpu ?? 0}%</span>;