Skip to main content
Glama
websocket-manager.ts2.82 kB
import { Log, LogLevel } from "./types.js"; import { createClient, Client } from 'graphql-ws'; export interface LogSubscriptionOptions { onLog?: (log: Log) => void; onError?: (error: Error) => void; onComplete?: () => void; traceId?: string; includeDebug?: boolean; } export interface WebSocketSubscription { unsubscribe: () => void; } export class WebSocketManager { private wsEndpoint: string; private apiKey: string; private client: Client | null = null; private subscriptions: Map<string, () => void> = new Map(); constructor(endpoint: string, apiKey: string) { this.wsEndpoint = endpoint.replace('https:', 'wss:').replace('http:', 'ws:'); this.apiKey = apiKey; } private initClient(): Client { if (!this.client) { this.client = createClient({ url: this.wsEndpoint, connectionParams: { Authorization: `Bearer ${this.apiKey}` }, retryAttempts: Infinity, shouldRetry: () => true, retryWait: (retries) => new Promise((resolve) => setTimeout(resolve, Math.min(retries * 1000, 5000)) ), keepAlive: 10000, }); } return this.client; } async subscribeToLogs(options: LogSubscriptionOptions = {}): Promise<WebSocketSubscription> { const client = this.initClient(); const unsubscribe = client.subscribe( { query: ` subscription OnNewLog { logs { id message level timestamp traceId } } ` }, { next: (data: any) => { if (data.data?.logs) { const log: Log = { ...data.data.logs, timestamp: new Date(data.data.logs.timestamp) }; if (!options.traceId || log.traceId === options.traceId) { if (options.includeDebug || log.level !== LogLevel.DEBUG) { options.onLog?.(log); } } } }, error: (error: any) => { options.onError?.(error); }, complete: () => { options.onComplete?.(); } } ); const subscriptionId = Math.random().toString(36).substring(2, 15); this.subscriptions.set(subscriptionId, unsubscribe); return { unsubscribe: () => { const unsub = this.subscriptions.get(subscriptionId); if (unsub) { unsub(); this.subscriptions.delete(subscriptionId); } } }; } async disconnect(): Promise<void> { for (const [subscriptionId, unsubscribe] of this.subscriptions) { unsubscribe(); } this.subscriptions.clear(); if (this.client) { this.client.dispose(); this.client = null; } } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/superglue-ai/superglue'

If you have feedback or need assistance with the MCP directory API, please join our Discord server