mirror of
https://github.com/block/buzz.git
synced 2026-08-18 06:50:31 +02:00
Signed-off-by: Tyler Longwell <109685178+tlongwell-block@users.noreply.github.com> Co-authored-by: Dawn <c6237ef84fa537c78dcee78efd2d4e59f728859c7f194da42ac51ededfa0be05@sprout-oss.stage.blox.sqprod.co>
96 lines
2.5 KiB
TypeScript
96 lines
2.5 KiB
TypeScript
import type { RelayEvent } from "@/shared/api/types";
|
|
|
|
/**
|
|
* Observable connection state for the relay singleton.
|
|
*
|
|
* - `idle` — never tried to connect yet (post-init, pre-workspace).
|
|
* - `connecting` — initial socket + AUTH handshake in flight.
|
|
* - `connected` — socket open and AUTH'd.
|
|
* - `reconnecting` — socket dropped, waiting for the backoff timer.
|
|
* - `stalled` — socket is *open* per the WS layer but no inbound frames
|
|
* for a long time (half-open / Warp split-brain). We
|
|
* surface this so the UI can warn even though tungstenite
|
|
* hasn't reported anything wrong yet.
|
|
* - `disconnected` — final/terminal disconnect (auth rejected, workspace
|
|
* switch, etc.) — no auto-reconnect scheduled.
|
|
*/
|
|
export type ConnectionState =
|
|
| "idle"
|
|
| "connecting"
|
|
| "connected"
|
|
| "reconnecting"
|
|
| "stalled"
|
|
| "disconnected";
|
|
|
|
/** True when the UI should surface a "connection lost" indicator. */
|
|
export function isRelayConnectionDegraded(state: ConnectionState): boolean {
|
|
return (
|
|
state === "reconnecting" || state === "stalled" || state === "disconnected"
|
|
);
|
|
}
|
|
|
|
export type RelaySubscriptionFilter = {
|
|
kinds: number[];
|
|
limit: number;
|
|
authors?: string[];
|
|
since?: number;
|
|
until?: number;
|
|
} & Partial<Record<`#${string}`, string[]>>;
|
|
|
|
type HistorySubscription = {
|
|
mode: "history";
|
|
events: RelayEvent[];
|
|
resolve: (events: RelayEvent[]) => void;
|
|
reject: (error: Error) => void;
|
|
timeout: number;
|
|
};
|
|
|
|
type LiveSubscription = {
|
|
mode: "live";
|
|
filter: RelaySubscriptionFilter;
|
|
onEvent: (event: RelayEvent) => void;
|
|
resolveReady?: () => void;
|
|
lastSeenCreatedAt?: number;
|
|
};
|
|
|
|
export type PendingEvent = {
|
|
event: RelayEvent;
|
|
resolve: (event: RelayEvent) => void;
|
|
reject: (error: Error) => void;
|
|
timeout: number;
|
|
};
|
|
|
|
export type RelaySubscription = HistorySubscription | LiveSubscription;
|
|
|
|
export function sortEvents(events: RelayEvent[]) {
|
|
return [...events].sort((left, right) => left.created_at - right.created_at);
|
|
}
|
|
|
|
export function getTextPayload(message: unknown) {
|
|
if (typeof message === "string") {
|
|
return message;
|
|
}
|
|
|
|
if (
|
|
typeof message === "object" &&
|
|
message !== null &&
|
|
"type" in message &&
|
|
message.type === "Text" &&
|
|
"data" in message &&
|
|
typeof message.data === "string"
|
|
) {
|
|
return message.data;
|
|
}
|
|
|
|
if (
|
|
typeof message === "object" &&
|
|
message !== null &&
|
|
"Text" in message &&
|
|
typeof message.Text === "string"
|
|
) {
|
|
return message.Text;
|
|
}
|
|
|
|
return null;
|
|
}
|