added channel & observers

This commit is contained in:
MrAlders0n
2026-05-27 19:27:48 -04:00
parent 134289af92
commit a0caf65a18
23 changed files with 1133 additions and 81 deletions
+40 -2
View File
@@ -1,5 +1,7 @@
import { API_BASE, DEFAULT_PAGE_SIZE } from "../lib/constants";
import type { CursorPage, PacketSummary, PacketDetail, IataCode } from "../types/api";
import type { CursorPage, PacketSummary, PacketDetail, IataCode, BrokerStatus } from "../types/api";
import type { ChannelSummary, ChannelMessage } from "../features/channels/types";
import type { ObserverSummary, Observer } from "../features/observers/types";
// typed fetch wrapper with query params
@@ -16,7 +18,7 @@ class ApiError extends Error {
}
async function request<T>(path: string, params?: Record<string, string | number | undefined>): Promise<T> {
const url = new URL(`${API_BASE}${path}`);
const url = new URL(`${API_BASE}${path}`, window.location.origin);
if (params) {
for (const [key, value] of Object.entries(params)) {
if (value !== undefined) {
@@ -57,4 +59,40 @@ export function getIatas(): Promise<IataCode[]> {
return request("/iatas");
}
export function getChannels(params?: { iata?: string; limit?: number }): Promise<ChannelSummary[]> {
return request("/channels", {
iata: params?.iata,
limit: params?.limit,
});
}
export function getChannelMessages(
channelId: number,
params?: { iata?: string; limit?: number },
): Promise<ChannelMessage[]> {
return request(`/channels/${channelId}/messages`, {
iata: params?.iata,
limit: params?.limit ?? DEFAULT_PAGE_SIZE,
});
}
export function getBrokers(): Promise<BrokerStatus[]> {
return request("/brokers");
}
export function getObservers(
params?: { iata?: string; type?: string; broker?: string; status?: string },
): Promise<ObserverSummary[]> {
return request("/observers", {
iata: params?.iata,
type: params?.type,
broker: params?.broker,
status: params?.status,
});
}
export function getObserver(observerId: string): Promise<Observer> {
return request(`/observers/${observerId}`);
}
export { ApiError };
+27 -1
View File
@@ -1,4 +1,4 @@
import type { SubscriptionFilter, WsServerMessage, WsPacketObservation, WsLagged } from "../types/ws";
import type { SubscriptionFilter, WsServerMessage, WsPacketObservation, WsLagged, WsChannelMessage, WsObserverStatus } from "../types/ws";
import {
WS_PING_INTERVAL_MS,
WS_RECONNECT_BASE_MS,
@@ -12,6 +12,8 @@ export type WsStatus = "connected" | "connecting" | "disconnected" | "error";
type PacketHandler = (data: WsPacketObservation["data"]) => void;
type LaggedHandler = (data: WsLagged) => void;
type ChannelMessageHandler = (data: WsChannelMessage["data"]) => void;
type ObserverStatusHandler = (data: WsObserverStatus["data"]) => void;
type StatusHandler = (status: WsStatus) => void;
export class WsManager {
@@ -28,6 +30,8 @@ export class WsManager {
private packetHandlers: PacketHandler[] = [];
private laggedHandlers: LaggedHandler[] = [];
private channelMessageHandlers: ChannelMessageHandler[] = [];
private observerStatusHandlers: ObserverStatusHandler[] = [];
private statusHandlers: StatusHandler[] = [];
constructor(url: string) {
@@ -56,6 +60,20 @@ export class WsManager {
};
}
onChannelMessage(handler: ChannelMessageHandler): () => void {
this.channelMessageHandlers.push(handler);
return () => {
this.channelMessageHandlers = this.channelMessageHandlers.filter((h) => h !== handler);
};
}
onObserverStatus(handler: ObserverStatusHandler): () => void {
this.observerStatusHandlers.push(handler);
return () => {
this.observerStatusHandlers = this.observerStatusHandlers.filter((h) => h !== handler);
};
}
onStatusChange(handler: StatusHandler): () => void {
this.statusHandlers.push(handler);
return () => {
@@ -148,6 +166,14 @@ export class WsManager {
for (const handler of this.packetHandlers) {
handler(msg.data);
}
} else if (msg.event === "channelMessage") {
for (const handler of this.channelMessageHandlers) {
handler(msg.data);
}
} else if (msg.event === "observerStatus") {
for (const handler of this.observerStatusHandlers) {
handler(msg.data);
}
}
break;