UNPKG

@multiplayer-app/session-recorder-node

Version:
231 lines (206 loc) 5.46 kB
import { MULTIPLAYER_BASE_API_URL } from '../config' import { ISession } from '../types' export interface ApiServiceConfig { apiKey?: string apiBaseUrl?: string continuousRecording?: boolean } export interface StartSessionRequest { name?: string resourceAttributes?: Record<string, any> sessionAttributes?: Record<string, any> tags?: { key?: string value: string }[] } export interface StopSessionRequest { sessionAttributes?: { email?: string comment?: string }, } export class ApiService { private config: ApiServiceConfig constructor() { this.config = { apiBaseUrl: MULTIPLAYER_BASE_API_URL, } } /** * Initialize the API service * @param config - API service configuration * @param config.apiKey - API key for authentication * @param config.apiBaseUrl - Base URL for API endpoints (preferred) * @param config.continuousRecording - Whether continuous recording is enabled */ public init(config: ApiServiceConfig) { const { apiBaseUrl: _apiBaseUrl, ...restConfig } = config const apiBaseUrl = _apiBaseUrl || MULTIPLAYER_BASE_API_URL this.config = { ...this.config, ...restConfig, apiBaseUrl, } } /** * Update the API service configuration * @param config - Partial configuration to update */ public updateConfigs(config: Partial<ApiServiceConfig>) { const { apiBaseUrl: _apiBaseUrl, ...restConfig } = config const apiBaseUrl = _apiBaseUrl || MULTIPLAYER_BASE_API_URL this.config = { ...this.config, ...restConfig, apiBaseUrl, } } /** * Get the current API base URL * @returns The current API base URL */ public getApiBaseUrl(): string { return this.config.apiBaseUrl || MULTIPLAYER_BASE_API_URL } /** * Start a new debug session * @param requestBody - Session start request data * @param signal - Optional AbortSignal for request cancellation */ async startSession( requestBody: StartSessionRequest, signal?: AbortSignal, ): Promise<ISession> { return this.makeRequest( '/debug-sessions/start', 'POST', requestBody, signal, ) } /** * Stop an active debug session * @param sessionId - ID of the session to stop * @param requestBody - Session stop request data */ async stopSession( sessionId: string, requestBody: StopSessionRequest, ): Promise<any> { return this.makeRequest( `/debug-sessions/${sessionId}/stop`, 'PATCH', requestBody, ) } /** * Cancel an active session * @param sessionId - ID of the session to cancel */ async cancelSession(sessionId: string): Promise<any> { return this.makeRequest( `/debug-sessions/${sessionId}/cancel`, 'DELETE', ) } /** * Start a new session * @param requestBody - Session start request data * @param signal - Optional AbortSignal for request cancellation */ async startContinuousSession( requestBody: StartSessionRequest, signal?: AbortSignal, ): Promise<any> { return this.makeRequest( '/continuous-debug-sessions/start', 'POST', requestBody, signal, ) } /** * Save a continuous session * @param sessionId - ID of the session to save * @param requestBody - Session save request data * @param signal - Optional AbortSignal for request cancellation */ async saveContinuousSession( sessionId: string, requestBody: StartSessionRequest, signal?: AbortSignal, ): Promise<any> { return this.makeRequest( `/continuous-debug-sessions/${sessionId}/save`, 'POST', requestBody, signal, ) } /** * Cancel an active debug session * @param sessionId - ID of the session to cancel */ async stopContinuousSession(sessionId: string): Promise<any> { return this.makeRequest( `/continuous-debug-sessions/${sessionId}/cancel`, 'DELETE', ) } /** * Check debug session should be started remotely */ async checkRemoteSession( requestBody: StartSessionRequest, signal?: AbortSignal, ): Promise<{ state: 'START' | 'STOP' }> { return this.makeRequest( '/remote-debug-session/check', 'POST', requestBody, signal, ) } /** * Make a request to the session API * @param path - API endpoint path (relative to the base URL) * @param method - HTTP method (GET, POST, PATCH, etc.) * @param body - request payload * @param signal - AbortSignal to set request's signal */ private async makeRequest( path: string, method: string, body?: any, signal?: AbortSignal, ): Promise<any> { const url = `${this.config.apiBaseUrl}/v0/radar${path}` const params = { method, body: body ? JSON.stringify(body) : null, headers: { 'Content-Type': 'application/json', ...(this.config.apiKey && { 'X-Api-Key': this.config.apiKey }), }, } try { const response = await fetch(url, { ...params, credentials: 'include', signal, }) if (!response.ok) { throw new Error('Network response was not ok: ' + response.statusText) } if (response.status === 204) { return null } return await response.json() } catch (error: any) { if (error?.name === 'AbortError') { throw new Error('Request aborted') } } } }