Files
svelte-mud/src/lib/connection/ConnectionManager.ts

191 lines
5.1 KiB
TypeScript
Raw Normal View History

2025-04-22 17:21:44 +02:00
import { writable, get } from 'svelte/store';
import { MudConnection } from './MudConnection';
import type { GmcpHandler } from '$lib/gmcp/GmcpHandler';
import { connectionStatus } from '$lib/stores/mudStore';
// Store for active MUD connections (persistent across tab switches)
export const activeConnections = writable<{ [key: string]: MudConnection }>({});
/**
* ConnectionManager - Singleton service to manage MUD connections
* This ensures connections stay alive even when components are unmounted during tab switches
*/
export class ConnectionManager {
private static instance: ConnectionManager;
// Private constructor for singleton pattern
private constructor() {
console.log('ConnectionManager initialized');
}
/**
* Get the singleton instance of ConnectionManager
*/
public static getInstance(): ConnectionManager {
if (!ConnectionManager.instance) {
ConnectionManager.instance = new ConnectionManager();
}
return ConnectionManager.instance;
}
/**
* Get an existing connection without creating a new one
*/
public getExistingConnection(profileId: string): MudConnection | null {
const connections = get(activeConnections);
return connections[profileId] || null;
}
/**
* Create a new connection or return an existing one
*/
public getConnection(profileId: string, options: {
host: string;
port: number;
useSSL?: boolean;
gmcpHandler?: GmcpHandler;
}): MudConnection {
// Get current connections
const connections = get(activeConnections);
// Check if a connection already exists for this profile
if (connections[profileId]) {
console.log(`Returning existing connection for profile ${profileId}`);
return connections[profileId];
}
// Create a new connection
console.log(`Creating new connection for profile ${profileId}`);
const connection = new MudConnection({
host: options.host,
port: options.port,
useSSL: options.useSSL,
gmcpHandler: options.gmcpHandler
});
// Set up event handlers
this.setupConnectionEvents(connection, profileId);
// Store the connection
activeConnections.update(connections => ({
...connections,
[profileId]: connection
}));
// Return the connection
return connection;
}
/**
* Connect to a MUD server
*/
public connect(profileId: string, options: {
host: string;
port: number;
useSSL?: boolean;
gmcpHandler?: GmcpHandler;
}): void {
const connection = this.getConnection(profileId, options);
// Update connection status
connectionStatus.update(statuses => ({
...statuses,
[profileId]: 'connecting'
}));
// Connect
connection.connect();
}
/**
* Disconnect from a MUD server
*/
public disconnect(profileId: string): void {
const connections = get(activeConnections);
if (connections[profileId]) {
connections[profileId].disconnect();
// Update connection status
connectionStatus.update(statuses => ({
...statuses,
[profileId]: 'disconnected'
}));
}
}
/**
* Send text to a MUD server
*/
public send(profileId: string, text: string): void {
const connections = get(activeConnections);
if (connections[profileId]) {
connections[profileId].send(text);
}
}
/**
* Close a connection and remove it
*/
public closeConnection(profileId: string): void {
const connections = get(activeConnections);
if (connections[profileId]) {
// Disconnect first
connections[profileId].disconnect();
// Then remove from store
activeConnections.update(connections => {
const newConnections = { ...connections };
delete newConnections[profileId];
return newConnections;
});
// Update connection status
connectionStatus.update(statuses => {
const newStatuses = { ...statuses };
delete newStatuses[profileId];
return newStatuses;
});
}
}
/**
* Set up event handlers for a connection
*/
private setupConnectionEvents(connection: MudConnection, profileId: string): void {
// Handle connection established
connection.on('connected', () => {
console.log(`ConnectionManager: Connection established for profile ${profileId}`);
// Update connection status
connectionStatus.update(statuses => ({
...statuses,
[profileId]: 'connected'
}));
});
// Handle connection closed
connection.on('disconnected', () => {
console.log(`ConnectionManager: Connection closed for profile ${profileId}`);
// Update connection status
connectionStatus.update(statuses => ({
...statuses,
[profileId]: 'disconnected'
}));
});
// Handle connection error
connection.on('error', (error) => {
console.error(`ConnectionManager: Connection error for profile ${profileId}:`, error);
// Update connection status
connectionStatus.update(statuses => ({
...statuses,
[profileId]: 'error'
}));
});
}
}