Move toju-app into own its folder

This commit is contained in:
2026-03-29 23:30:37 +02:00
parent 0467a7b612
commit 8162e0444a
287 changed files with 42 additions and 34 deletions

View File

@@ -0,0 +1,172 @@
import { Observable, of } from 'rxjs';
import type { SignalingMessage } from '../../../shared-kernel';
import { DEFAULT_DISPLAY_NAME, SIGNALING_TYPE_IDENTIFY } from '../realtime.constants';
import { IdentifyCredentials } from '../realtime.types';
import { ConnectedSignalingManager, ServerSignalingCoordinator } from './server-signaling-coordinator';
import { WebRTCLogger } from '../logging/webrtc-logger';
interface SignalingTransportHandlerDependencies<TMessage> {
signalingCoordinator: ServerSignalingCoordinator<TMessage>;
logger: WebRTCLogger;
getLocalPeerId(): string;
}
export class SignalingTransportHandler<TMessage> {
private lastIdentifyCredentials: IdentifyCredentials | null = null;
constructor(
private readonly dependencies: SignalingTransportHandlerDependencies<TMessage>
) {}
getIdentifyCredentials(): IdentifyCredentials | null {
return this.lastIdentifyCredentials;
}
getIdentifyOderId(): string {
return this.lastIdentifyCredentials?.oderId || this.dependencies.getLocalPeerId();
}
getIdentifyDisplayName(): string {
return this.lastIdentifyCredentials?.displayName || DEFAULT_DISPLAY_NAME;
}
getConnectedSignalingManagers(): ConnectedSignalingManager[] {
return this.dependencies.signalingCoordinator.getConnectedSignalingManagers();
}
getCurrentSignalingUrl(activeServerId: string | null): string | null {
if (activeServerId) {
const activeServerSignalUrl = this.dependencies.signalingCoordinator.getServerSignalUrl(activeServerId);
if (activeServerSignalUrl) {
return activeServerSignalUrl;
}
}
return this.getConnectedSignalingManagers()[0]?.signalUrl ?? null;
}
connectToSignalingServer(serverUrl: string): Observable<boolean> {
const manager = this.dependencies.signalingCoordinator.ensureSignalingManager(serverUrl);
if (manager.isSocketOpen()) {
return of(true);
}
return manager.connect(serverUrl);
}
isSignalingConnectedTo(serverUrl: string): boolean {
return this.dependencies.signalingCoordinator.isSignalingConnectedTo(serverUrl);
}
async ensureSignalingConnected(timeoutMs?: number): Promise<boolean> {
return await this.dependencies.signalingCoordinator.ensureAnySignalingConnected(timeoutMs);
}
sendSignalingMessage(message: Omit<SignalingMessage, 'from' | 'timestamp'>): void {
const targetPeerId = message.to;
if (targetPeerId) {
const targetSignalUrl = this.dependencies.signalingCoordinator.getPeerSignalUrl(targetPeerId);
if (targetSignalUrl) {
const targetManager = this.dependencies.signalingCoordinator.ensureSignalingManager(targetSignalUrl);
targetManager.sendSignalingMessage(message, this.dependencies.getLocalPeerId());
return;
}
}
const connectedManagers = this.getConnectedSignalingManagers();
if (connectedManagers.length === 0) {
this.dependencies.logger.error('[signaling] No active signaling connection for outbound message', new Error('No signaling manager available'), {
type: message.type
});
return;
}
for (const { manager } of connectedManagers) {
manager.sendSignalingMessage(message, this.dependencies.getLocalPeerId());
}
}
sendRawMessage(message: Record<string, unknown>): void {
const targetPeerId = typeof message['targetUserId'] === 'string' ? message['targetUserId'] : null;
if (targetPeerId) {
const targetSignalUrl = this.dependencies.signalingCoordinator.getPeerSignalUrl(targetPeerId);
if (targetSignalUrl && this.sendRawMessageToSignalUrl(targetSignalUrl, message)) {
return;
}
}
const serverId = typeof message['serverId'] === 'string' ? message['serverId'] : null;
if (serverId) {
const serverSignalUrl = this.dependencies.signalingCoordinator.getServerSignalUrl(serverId);
if (serverSignalUrl && this.sendRawMessageToSignalUrl(serverSignalUrl, message)) {
return;
}
}
const connectedManagers = this.getConnectedSignalingManagers();
if (connectedManagers.length === 0) {
this.dependencies.logger.error('[signaling] No active signaling connection for outbound message', new Error('No signaling manager available'), {
type: typeof message['type'] === 'string' ? message['type'] : 'unknown'
});
return;
}
for (const { manager } of connectedManagers) {
manager.sendRawMessage(message);
}
}
sendRawMessageToSignalUrl(signalUrl: string, message: Record<string, unknown>): boolean {
const manager = this.dependencies.signalingCoordinator.getSignalingManager(signalUrl);
if (!manager) {
return false;
}
manager.sendRawMessage(message);
return true;
}
identify(oderId: string, displayName: string, signalUrl?: string): void {
const normalizedDisplayName = displayName.trim() || DEFAULT_DISPLAY_NAME;
this.lastIdentifyCredentials = {
oderId,
displayName: normalizedDisplayName
};
const identifyMessage = {
type: SIGNALING_TYPE_IDENTIFY,
oderId,
displayName: normalizedDisplayName
};
if (signalUrl) {
this.sendRawMessageToSignalUrl(signalUrl, identifyMessage);
return;
}
const connectedManagers = this.getConnectedSignalingManagers();
if (connectedManagers.length === 0) {
return;
}
for (const { manager } of connectedManagers) {
manager.sendRawMessage(identifyMessage);
}
}
}