anydrop/shared/src/protocol.ts
ordinarthur 9d6e4da4ae
Some checks failed
Build & Deploy / build-and-deploy (push) Failing after 8s
feat: initial commit with full deployment setup
Includes React PWA frontend, WebSocket signaling server, shared types,
K8s manifests, Gitea CI/CD workflow, nginx config, and Dockerfiles.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-14 10:30:45 +02:00

138 lines
2.6 KiB
TypeScript

// ── Client → Server messages ──
export interface HelloMessage {
type: "hello";
joinCode?: string;
}
export interface CreatePublicRoomMessage {
type: "create-public-room";
}
export interface SignalMessage {
type: "signal";
to: string;
data: unknown;
}
export interface LeaveMessage {
type: "leave";
}
export type ClientMessage =
| HelloMessage
| CreatePublicRoomMessage
| SignalMessage
| LeaveMessage;
// ── Server → Client messages ──
export interface PeerInfo {
peerId: string;
displayName: string;
}
export interface WelcomeMessage {
type: "welcome";
peerId: string;
displayName: string;
roomId: string;
peers: PeerInfo[];
}
export interface PublicRoomCreatedMessage {
type: "public-room-created";
code: string;
url: string;
expiresAt: string;
}
export interface PeerJoinedMessage {
type: "peer-joined";
peerId: string;
displayName: string;
}
export interface PeerLeftMessage {
type: "peer-left";
peerId: string;
}
export interface SignalRelayMessage {
type: "signal";
from: string;
data: unknown;
}
export type ErrorCode = "room-not-found" | "room-expired" | "rate-limit";
export interface ErrorMessage {
type: "error";
code: ErrorCode;
message: string;
}
export type ServerMessage =
| WelcomeMessage
| PublicRoomCreatedMessage
| PeerJoinedMessage
| PeerLeftMessage
| SignalRelayMessage
| ErrorMessage;
// ── Data channel messages (peer-to-peer) ──
export interface FileMetaMessage {
type: "file-meta";
id: string;
name: string;
size: number;
mime: string;
}
export interface FileEndMessage {
type: "file-end";
id: string;
}
export interface TextMessage {
type: "text";
id: string;
content: string;
}
export interface TransferRequestMessage {
type: "transfer-request";
files: { id: string; name: string; size: number; mime: string }[];
text?: string;
}
export interface TransferResponseMessage {
type: "transfer-response";
accepted: boolean;
}
export type DataChannelMessage =
| FileMetaMessage
| FileEndMessage
| TextMessage
| TransferRequestMessage
| TransferResponseMessage;
// ── Constants ──
export const CHUNK_SIZE = 16 * 1024; // 16 KB
export const MAX_BUFFER = 1024 * 1024; // 1 MB backpressure threshold
export const SHORT_CODE_ALPHABET = "abcdefghjkmnpqrstuvwxyz23456789";
export const SHORT_CODE_LENGTH = 3;
export const SHORT_CODE_MAX_LENGTH = 4;
export const SHORT_CODE_MAX_RETRIES = 5;
export const PUBLIC_ROOM_TTL_MS = 10 * 60 * 1000; // 10 minutes
export const ICE_SERVERS: RTCIceServer[] = [
{ urls: "stun:stun.l.google.com:19302" },
{ urls: "stun:stun1.l.google.com:19302" },
];