UNPKG

@globalleaderboards/sdk

Version:

Official SDK for GlobalLeaderboards.net - Add competitive leaderboards to any application

1,191 lines (1,184 loc) 35.3 kB
/** * Configuration options for the GlobalLeaderboards SDK */ interface GlobalLeaderboardsConfig { /** API key for authentication */ apiKey: string; /** Default leaderboard ID for simplified submit() calls */ defaultLeaderboardId?: string; /** Base URL for the API (default: https://api.globalleaderboards.net) */ baseUrl?: string; /** WebSocket URL (default: wss://api.globalleaderboards.net) */ wsUrl?: string; /** Request timeout in milliseconds (default: 30000) */ timeout?: number; /** Enable automatic retry on failure (default: true) */ autoRetry?: boolean; /** Maximum number of retry attempts (default: 3) */ maxRetries?: number; } /** * Score submission request */ interface SubmitScoreRequest { /** Leaderboard ID */ leaderboard_id: string; /** User ID (ULID format) */ user_id: string; /** Display name for the user */ user_name: string; /** Score value */ score: number; /** Optional metadata to store with the score */ metadata?: Record<string, unknown>; } /** * Score submission response */ interface SubmitScoreResponse { /** Operation performed (insert, update, no_change) */ operation: 'insert' | 'update' | 'no_change'; /** User's new rank on the leaderboard */ rank: number; /** Previous score if update operation */ previous_score?: number; /** Score improvement if update operation */ improvement?: number; } /** * Queued score submission response */ interface QueuedSubmitResponse extends SubmitScoreResponse { /** Indicates this submission was queued */ queued: true; /** Unique queue ID */ queueId: string; /** Position in queue */ queuePosition: number; } /** * Flexible score submission format */ type FlexibleScoreSubmission = [userId: string, score: number] | [userId: string, score: number, leaderboardId: string] | { userId: string; score: number; leaderboardId?: string; userName?: string; metadata?: Record<string, unknown>; }; /** * Bulk score submission request */ interface BulkSubmitScoreRequest { /** Array of scores to submit */ scores: SubmitScoreRequest[]; } /** * Single score result in bulk response */ interface BulkScoreResult extends SubmitScoreResponse { /** Leaderboard ID */ leaderboard_id: string; /** User ID */ user_id: string; } /** * Bulk score submission response */ interface BulkSubmitScoreResponse { /** Individual results for each score */ results: BulkScoreResult[]; /** Summary statistics */ summary: { /** Total scores submitted */ total: number; /** Successful submissions */ successful: number; /** Failed submissions */ failed: number; }; } /** * Extended leaderboard entry with leaderboard info */ interface UserScoreEntry extends LeaderboardEntry { /** Leaderboard ID */ leaderboard_id: string; /** Leaderboard name */ leaderboard_name: string; } /** * User scores response */ interface UserScoresResponse { /** User's scores across leaderboards */ data: UserScoreEntry[]; /** Pagination information */ pagination: { page: number; limit: number; total: number; pages: number; }; /** User summary */ user: { /** User ID */ id: string; /** Total number of scores */ total_scores: number; /** Best rank achieved */ best_rank: number; }; } /** * Leaderboard entry */ interface LeaderboardEntry { /** User ID */ user_id: string; /** User display name */ user_name: string; /** Score value */ score: number; /** Rank position */ rank: number; /** Timestamp when score was submitted */ timestamp: string; /** Optional metadata stored with the score */ metadata?: Record<string, unknown>; } /** * Leaderboard data */ interface LeaderboardData { /** Leaderboard ID */ id: string; /** Leaderboard name */ name: string; /** Total number of entries */ total_entries: number; /** Last update timestamp */ last_updated?: string; } /** * Leaderboard entries response - matches OpenAPI LeaderboardEntriesResponse */ interface LeaderboardEntriesResponse { /** Leaderboard entries */ data: LeaderboardEntry[]; /** Pagination information */ pagination: { page: number; limit: number; total: number; pages: number; }; /** Leaderboard information */ leaderboard: LeaderboardData; } /** * WebSocket message types - matches OpenAPI spec */ type WebSocketMessageType = 'subscribe' | 'unsubscribe' | 'ping' | 'pong' | 'leaderboard_update' | 'user_rank_update' | 'error' | 'connection_info' | 'update' | 'score_submission'; /** * Base WebSocket message */ interface WebSocketMessage { type: WebSocketMessageType; } /** * Subscribe message */ interface SubscribeMessage extends WebSocketMessage { type: 'subscribe'; leaderboard_id: string; user_id?: string; } /** * Unsubscribe message */ interface UnsubscribeMessage extends WebSocketMessage { type: 'unsubscribe'; leaderboard_id: string; } /** * Mutation types for leaderboard changes */ type MutationType = 'new_entry' | 'rank_change' | 'score_update' | 'username_change' | 'removed'; /** * Base mutation interface */ interface BaseMutation { type: MutationType; userId: string; } /** * New entry mutation */ interface NewEntryMutation extends BaseMutation { type: 'new_entry'; newRank: number; score: number; userName: string; } /** * Rank change mutation */ interface RankChangeMutation extends BaseMutation { type: 'rank_change'; previousRank: number; newRank: number; score: number; } /** * Score update mutation */ interface ScoreUpdateMutation extends BaseMutation { type: 'score_update'; previousScore: number; newScore: number; previousRank: number; newRank: number; } /** * Username change mutation */ interface UsernameChangeMutation extends BaseMutation { type: 'username_change'; previousUsername: string; newUsername: string; rank: number; } /** * Removed mutation */ interface RemovedMutation extends BaseMutation { type: 'removed'; previousRank: number; score: number; } /** * Union type for all mutations */ type LeaderboardMutation = NewEntryMutation | RankChangeMutation | ScoreUpdateMutation | UsernameChangeMutation | RemovedMutation; /** * Update trigger information */ interface UpdateTrigger { type: 'score_submission' | 'bulk_submission' | 'admin_action' | 'leaderboard_reset'; submissions?: Array<{ userId: string; userName: string; score: number; previousScore?: number; timestamp: string; }>; } /** * Leaderboard update message with full state and mutations */ interface LeaderboardUpdateMessage extends WebSocketMessage { type: 'leaderboard_update'; id: string; timestamp: string; payload: { leaderboardId: string; updateType: 'score_update' | 'full_refresh' | 'bulk_update'; leaderboard: { entries: LeaderboardEntry[]; totalEntries: number; displayedEntries: number; }; mutations: LeaderboardMutation[]; trigger: UpdateTrigger; sequence: number; }; } /** * User rank update message */ interface UserRankUpdateMessage extends WebSocketMessage { type: 'user_rank_update'; data: { leaderboard_id: string; user_id: string; old_rank: number; new_rank: number; score: number; }; } /** * Error message */ interface ErrorMessage extends WebSocketMessage { type: 'error'; error: { code: string; message: string; details?: Record<string, unknown>; }; } /** * Connection info message */ interface ConnectionInfoMessage extends WebSocketMessage { type: 'connection_info'; payload?: { connectionId: string; maxConnections: number; currentConnections: number; rateLimit?: { requestsPerMinute: number; burstSize: number; }; }; } /** * API error response */ interface ApiErrorResponse { error: { code: string; message: string; details?: Record<string, unknown>; }; timestamp: string; requestId?: string; } /** * API info response */ interface ApiInfoResponse { /** API name */ name: string; /** Package version */ version: string; /** API version */ apiVersion: string; /** Environment */ environment: 'development' | 'staging' | 'production'; /** Current timestamp */ timestamp: string; /** Available endpoints */ endpoints: { health: { basic: string; detailed: string; }; public: { description: string; scores: string; leaderboards: string; websocket: string; }; dashboard: { description: string; auth: string; accounts: string; apps: string; leaderboards: string; analytics: string; }; admin: { description: string; auth: string; accounts: string; apps: string; analytics: string; }; }; /** Documentation URL */ documentation: string; /** Support email */ support: string; } /** * Basic health check response */ interface HealthResponse { /** Health status */ status: 'healthy' | 'unhealthy'; /** API version */ version: string; /** Current timestamp */ timestamp: string; } /** * Detailed health check response */ interface DetailedHealthResponse extends HealthResponse { /** Individual service statuses */ services: { /** Database health */ database: { status: 'healthy' | 'unhealthy'; latency?: number; }; /** Cache health */ cache: { status: 'healthy' | 'unhealthy'; latency?: number; }; /** Storage health */ storage: { status: 'healthy' | 'unhealthy'; latency?: number; }; }; /** System information */ system: { /** Memory usage in MB */ memoryUsage: number; /** Uptime in seconds */ uptime: number; /** Environment */ environment: string; }; } /** * SDK error class */ declare class GlobalLeaderboardsError extends Error { code: string; statusCode?: number | undefined; details?: Record<string, unknown> | undefined; constructor(message: string, code: string, statusCode?: number | undefined, details?: Record<string, unknown> | undefined); } /** * WebSocket event handlers */ interface WebSocketHandlers { /** Called when connection is established */ onConnect?: () => void; /** Called when connection is closed */ onDisconnect?: (code: number, reason: string) => void; /** Called when an error occurs */ onError?: (error: Error) => void; /** Called when leaderboard is updated */ onLeaderboardUpdate?: (data: LeaderboardUpdateMessage['payload']) => void; /** Called when user rank changes */ onUserRankUpdate?: (data: UserRankUpdateMessage['data']) => void; /** Called for any message */ onMessage?: (message: WebSocketMessage) => void; /** Called when starting a reconnection attempt */ onReconnecting?: (attempt: number, maxAttempts: number, nextDelay: number) => void; } /** * Offline queue operation */ interface QueuedOperation { /** Unique queue ID */ queueId: string; /** Operation method */ method: 'submit' | 'submitBulk'; /** Operation parameters */ params: { userId?: string; score?: number; leaderboardId?: string; userName?: string; metadata?: Record<string, unknown>; scores?: SubmitScoreRequest[]; }; /** Timestamp when queued */ timestamp: number; /** Number of retry attempts */ retryCount?: number; } /** * Queue event types */ type QueueEventType = 'queue:added' | 'queue:processed' | 'queue:failed' | 'queue:progress'; /** * Queue event handler */ interface QueueEventHandler { (event: QueueEventType, data: unknown): void; } /** * Server-Sent Events client for real-time leaderboard updates */ /** * SSE event types */ type SSEEventType = 'connected' | 'leaderboard_update' | 'heartbeat' | 'error'; /** * Enhanced SSE leaderboard update event data - matches WebSocket format */ interface SSELeaderboardUpdateEvent { leaderboardId: string; updateType: 'score_update' | 'full_refresh' | 'bulk_update'; leaderboard: { entries: LeaderboardEntry[]; totalEntries: number; displayedEntries: number; }; mutations: LeaderboardMutation[]; trigger: UpdateTrigger; sequence: number; } /** * Event handlers for SSE */ interface SSEEventHandlers { onConnect?: () => void; onDisconnect?: () => void; onError?: (error: GlobalLeaderboardsError) => void; onLeaderboardUpdate?: (data: SSELeaderboardUpdateEvent) => void; onHeartbeat?: (data: { connectionId: string; serverTime: string; }) => void; onMessage?: (message: any) => void; } /** * SSE connection options */ interface SSEConnectionOptions { userId?: string; includeMetadata?: boolean; topN?: number; } /** * LeaderboardSSE client for Server-Sent Events * * @example * ```typescript * const sse = new LeaderboardSSE(config) * * const connection = sse.connect('leaderboard-id', { * onLeaderboardUpdate: (data) => { * console.log('Leaderboard updated:', data.topScores) * }, * onUserRankUpdate: (data) => { * console.log('User rank changed:', data) * } * }) * * // Later... * connection.close() * ``` */ declare class LeaderboardSSE { private config; private connections; private reconnectAttempts; private reconnectTimers; /** * Create a new LeaderboardSSE client * * @param config - Configuration with API key and base URL */ constructor(config: Required<GlobalLeaderboardsConfig>); /** * Connect to a leaderboard's SSE stream * * @param leaderboardId - The leaderboard to connect to * @param handlers - Event handlers for different SSE events * @param options - Connection options * @returns Connection object with close method */ connect(leaderboardId: string, handlers: SSEEventHandlers, options?: SSEConnectionOptions): { close: () => void; }; /** * Disconnect from a specific leaderboard * * @param leaderboardId - The leaderboard to disconnect from */ disconnect(leaderboardId: string): void; /** * Disconnect from all leaderboards */ disconnectAll(): void; /** * Check if connected to a specific leaderboard * * @param leaderboardId - The leaderboard to check * @returns Whether connected to the leaderboard */ isConnected(leaderboardId: string): boolean; /** * Get connection status for all leaderboards * * @returns Map of leaderboard IDs to connection states */ getConnectionStatus(): Map<string, 'connecting' | 'open' | 'closed'>; /** * Attempt to reconnect to a leaderboard * * @param leaderboardId - The leaderboard to reconnect to * @param handlers - Event handlers * @param options - Connection options */ private attemptReconnection; } /** * WebSocket client for real-time leaderboard updates * * WebSocket connections now work through the main API domain with full * Cloudflare proxy protection. Both WebSocket and SSE are supported options * for real-time updates. * * @see LeaderboardSSE - Alternative method using Server-Sent Events */ declare class LeaderboardWebSocket { private readonly wsUrl; private readonly apiKey; private readonly options; private ws; private reconnectAttempts; private reconnectTimer; private pingInterval; private subscribedLeaderboards; private handlers; private isConnecting; private shouldReconnect; private permanentError; private isOnline; private networkListenersBound; constructor(wsUrl: string, apiKey: string, options?: { maxReconnectAttempts?: number; reconnectDelay?: number; pingInterval?: number; }); /** * Connect to the WebSocket server */ connect(leaderboardId?: string, userId?: string): void; /** * Disconnect from the WebSocket server */ disconnect(): void; /** * Subscribe to a leaderboard */ subscribe(leaderboardId: string, userId?: string): void; /** * Unsubscribe from a leaderboard */ unsubscribe(leaderboardId: string): void; /** * Set event handlers */ on(handlers: Partial<WebSocketHandlers>): void; /** * Get connection state */ get isConnected(): boolean; /** * Get subscribed leaderboards */ get subscriptions(): string[]; /** * Get permanent error if connection was terminated due to a permanent error */ get permanentConnectionError(): GlobalLeaderboardsError | null; private setupEventHandlers; private handleMessage; private send; private transformToServerFormat; private startPingInterval; private stopPingInterval; private scheduleReconnect; private handleError; private cleanup; /** * Set up network status listeners */ private setupNetworkListeners; /** * Manually trigger a reconnection attempt * Useful for application-level retry logic */ reconnect(): void; } declare global { interface Chrome { storage: { sync: { get(keys: string | string[], callback: (result: Record<string, unknown>) => void): void; set(items: Record<string, unknown>, callback?: () => void): void; remove(keys: string | string[], callback?: () => void): void; }; }; runtime: { lastError?: { message: string; }; }; } const chrome: Chrome | undefined; } /** * Offline queue for managing API operations when offline * * Features: * - Automatic persistence using chrome.storage.sync * - Intelligent batching of submit operations * - FIFO processing order * - Event-based notifications * - Automatic cleanup of expired items */ declare class OfflineQueue { private queue; private processing; private storageKey; private storage; private eventHandlers; private readonly MAX_QUEUE_SIZE; private readonly QUEUE_TTL_MS; private readonly MAX_BATCH_SIZE; constructor(apiKey: string); /** * Add an operation to the queue */ enqueue(operation: Omit<QueuedOperation, 'queueId' | 'timestamp' | 'retryCount'>): Promise<QueuedSubmitResponse>; /** * Check if queue has items */ hasItems(): boolean; /** * Get queue size */ size(): number; /** * Check if currently processing */ isProcessing(): boolean; /** * Get all queued operations */ getQueue(): QueuedOperation[]; /** * Group operations by leaderboard for intelligent batching */ batchOperations(): Map<string, QueuedOperation[]>; /** * Mark operations as processed and remove from queue */ removeProcessed(queueIds: string[]): Promise<void>; /** * Clear the entire queue */ clear(): Promise<void>; /** * Mark operation as failed and increment retry count */ markFailed(queueId: string, permanent?: boolean): Promise<void>; /** * Set processing state */ setProcessing(processing: boolean): void; /** * Register event handler */ on(event: QueueEventType, handler: QueueEventHandler): void; /** * Unregister event handler */ off(event: QueueEventType, handler: QueueEventHandler): void; /** * Emit event * @internal */ emit(event: QueueEventType, data: unknown): void; /** * Load queue from storage */ private loadQueue; /** * Persist queue to storage */ private persistQueue; /** * Clean expired items from queue */ private cleanExpiredItems; /** * Simple hash function for API key */ private hashApiKey; } /** * GlobalLeaderboards SDK client for interacting with the GlobalLeaderboards.net API * * @example * ```typescript * const leaderboard = new GlobalLeaderboards('your-api-key') * ``` */ declare class GlobalLeaderboards { private readonly config; private wsClient; private sseClient; private offlineQueue; private isOnline; readonly version: string; /** * Create a new GlobalLeaderboards SDK instance * * @param apiKey - Your API key from GlobalLeaderboards.net * @param config - Optional configuration options * @param config.defaultLeaderboardId - Default leaderboard ID for simplified submit() calls * @param config.baseUrl - API base URL (default: https://api.globalleaderboards.net) * @param config.wsUrl - WebSocket URL (default: wss://api.globalleaderboards.net) * @param config.timeout - Request timeout in ms (default: 30000) * @param config.autoRetry - Enable automatic retry (default: true) * @param config.maxRetries - Maximum retry attempts (default: 3) * * @example * ```typescript * const leaderboard = new GlobalLeaderboards('your-api-key', { * timeout: 60000 * }) * ``` */ constructor(apiKey: string, config?: Partial<GlobalLeaderboardsConfig>); /** * Submit a score to a leaderboard with validation * * Supports three signature variations: * - `submit(userId, score)` - Uses default leaderboard ID * - `submit(userId, score, leaderboardId)` - Specify leaderboard * - `submit(userId, score, options)` - Full options object * * When offline or queue not empty, submissions are queued and processed when online. * * @param userId - Unique user identifier * @param score - Score value (must be >= 0) * @param leaderboardIdOrOptions - Leaderboard ID string or options object * @returns Score submission response or queued response * @throws {GlobalLeaderboardsError} If validation fails * * @example * ```typescript * // Using default leaderboard * await leaderboard.submit('user-123', 1500) * * // Specify leaderboard * await leaderboard.submit('user-123', 1500, 'leaderboard-456') * * // Full options * await leaderboard.submit('user-123', 1500, { * leaderboardId: 'leaderboard-456', * userName: 'PlayerOne', * metadata: { level: 5 } * }) * ``` */ submit(userId: string, score: number, leaderboardIdOrOptions?: string | { leaderboardId?: string; userName?: string; metadata?: Record<string, unknown>; }): Promise<SubmitScoreResponse | QueuedSubmitResponse>; /** * Get paginated leaderboard entries * * @param leaderboardId - Leaderboard ID to retrieve * @param options - Query options * @param options.page - Page number (default: 1) * @param options.limit - Results per page (default: 20, max: 100) * @param options.aroundUser - Center results around specific user ID * @returns Leaderboard entries with pagination info * @throws {GlobalLeaderboardsError} If API returns an error * * @example * ```typescript * const data = await leaderboard.getLeaderboard('leaderboard-456', { * page: 1, * limit: 10, * aroundUser: 'user-123' * }) * ``` */ getLeaderboard(leaderboardId: string, options?: { page?: number; limit?: number; aroundUser?: string; }): Promise<LeaderboardEntriesResponse>; /** * Submit multiple scores in bulk for better performance * * Accepts mixed formats for flexibility: * - `[userId, score]` - Uses default leaderboard * - `[userId, score, leaderboardId]` - Specify leaderboard * - Full object with all options * * @param submissions - Array of score submissions in various formats (max 100) * @returns Bulk submission response with individual results and summary * @throws {GlobalLeaderboardsError} If validation fails or API returns an error * * @example * ```typescript * const results = await leaderboard.submitBulk([ * ['user-123', 1000], // Uses default leaderboard * ['user-456', 2000, 'leaderboard-789'], // Specific leaderboard * { // Full options * userId: 'user-789', * score: 3000, * leaderboardId: 'leaderboard-789', * userName: 'TopPlayer', * metadata: { level: 10 } * } * ]) * ``` */ submitBulk(submissions: FlexibleScoreSubmission[]): Promise<BulkSubmitScoreResponse>; /** * Get all scores for a user across leaderboards * * @param userId - User ID to get scores for * @param options - Query options * @param options.page - Page number (default: 1) * @param options.limit - Results per page (default: 20) * @returns User scores with pagination and summary stats * @throws {GlobalLeaderboardsError} If API returns an error * * @example * ```typescript * const userScores = await leaderboard.getUserScores('user-123', { * page: 1, * limit: 50 * }) * ``` */ getUserScores(userId: string, options?: { page?: number; limit?: number; }): Promise<UserScoresResponse>; /** * Connect to WebSocket for real-time leaderboard updates * * WebSocket connections now work through the main API domain with full * Cloudflare proxy protection. Both WebSocket and SSE are supported options * for real-time updates. Choose based on your specific needs: * - WebSocket: Lower latency, binary support, bidirectional potential * - SSE: Simpler implementation, automatic reconnection, better firewall compatibility * * @param handlers - Event handlers for WebSocket events * @param handlers.onConnect - Called when connection is established * @param handlers.onDisconnect - Called when connection is closed * @param handlers.onError - Called on errors * @param handlers.onLeaderboardUpdate - Called when leaderboard data changes * @param handlers.onUserRankUpdate - Called when user's rank changes * @param handlers.onMessage - Called for any WebSocket message * @param options - Connection options * @param options.leaderboardId - Initial leaderboard to subscribe to * @param options.userId - User ID for personalized updates * @param options.maxReconnectAttempts - Max reconnection attempts * @param options.reconnectDelay - Delay between reconnection attempts in ms * @returns WebSocket client instance * * @example * ```typescript * const ws = leaderboard.connectWebSocket({ * onConnect: () => console.log('Connected'), * onLeaderboardUpdate: (data) => console.log('Update:', data) * }, { * leaderboardId: 'leaderboard-456' * }) * ``` * * @see connectSSE - Recommended alternative for real-time updates */ connectWebSocket(handlers: WebSocketHandlers, options?: { leaderboardId?: string; userId?: string; maxReconnectAttempts?: number; reconnectDelay?: number; }): LeaderboardWebSocket; /** * Disconnect from WebSocket * * @example * ```typescript * leaderboard.disconnectWebSocket() * ``` */ disconnectWebSocket(): void; /** * Connect to Server-Sent Events (SSE) for real-time leaderboard updates * * This is the recommended method for real-time updates. SSE provides: * - Simpler implementation compared to WebSocket * - Automatic reconnection with exponential backoff * - Better firewall and proxy compatibility * - Lower resource usage * - Built-in heartbeat for connection health * * @param leaderboardId - Leaderboard to connect to * @param handlers - Event handlers for SSE events * @param handlers.onConnect - Called when connection is established * @param handlers.onDisconnect - Called when connection is closed * @param handlers.onError - Called on errors * @param handlers.onLeaderboardUpdate - Called when leaderboard data changes * @param handlers.onUserRankUpdate - Called when user's rank changes * @param handlers.onHeartbeat - Called on heartbeat (optional) * @param handlers.onMessage - Raw message handler (optional) * @param options - Connection options * @param options.userId - User ID for personalized updates * @param options.includeMetadata - Include metadata in updates (default: true) * @param options.topN - Number of top scores to include in refresh events (default: 10) * @returns SSE connection object with close method * * @example * ```typescript * const connection = leaderboard.connectSSE('leaderboard-123', { * onLeaderboardUpdate: (data) => { * console.log('Top scores:', data.topScores) * }, * onUserRankUpdate: (data) => { * console.log('Rank changed:', data) * } * }) * * // Later... * connection.close() * ``` */ connectSSE(leaderboardId: string, handlers: SSEEventHandlers, options?: SSEConnectionOptions): { close: () => void; }; /** * Disconnect from all SSE connections * * @example * ```typescript * leaderboard.disconnectSSE() * ``` */ disconnectSSE(): void; /** * Generate a new ULID (Universally Unique Lexicographically Sortable Identifier) * * @returns A new ULID string * * @example * ```typescript * const id = leaderboard.generateId() * // Returns: '01ARZ3NDEKTSV4RRFFQ69G5FAV' * ``` */ generateId(): string; /** * Get API information and available endpoints * * @returns API info including version, endpoints, and documentation URL * @throws {GlobalLeaderboardsError} If API returns an error * * @remarks No authentication required for this endpoint * * @example * ```typescript * const info = await leaderboard.getApiInfo() * console.log('API Version:', info.version) * ``` */ getApiInfo(): Promise<ApiInfoResponse>; /** * Perform a basic health check on the API * * @returns Health status with version and timestamp * @throws {GlobalLeaderboardsError} If health check fails * * @remarks No authentication required for this endpoint * * @example * ```typescript * const health = await leaderboard.health() * if (health.status === 'healthy') { * console.log('API is healthy') * } * ``` */ health(): Promise<HealthResponse>; /** * Perform a detailed health check with individual service statuses * * @returns Detailed health info including database, cache, and storage status * @throws {GlobalLeaderboardsError} If health check fails * * @remarks No authentication required for this endpoint * * @example * ```typescript * const health = await leaderboard.healthDetailed() * console.log('Database:', health.services.database.status) * console.log('Cache:', health.services.cache.status) * ``` */ healthDetailed(): Promise<DetailedHealthResponse>; /** * Make an authenticated API request with automatic retry * * @private * @param method - HTTP method * @param path - API endpoint path * @param body - Request body (optional) * @param retryCount - Current retry attempt (internal use) * @returns API response * @throws {GlobalLeaderboardsError} If request fails */ private request; /** * Check if an error is retryable * * @private * @param error - Error to check * @returns True if error is retryable (5xx, 429, 408, timeout) */ private shouldRetry; /** * Set up network detection and automatic queue processing * @private */ private setupNetworkDetection; /** * Process the offline queue * @private */ private processOfflineQueue; /** * Register event handler for queue events * * @param event - Event type to listen for * @param handler - Handler function * * @example * ```typescript * leaderboard.on('queue:processed', (data) => { * console.log('Queue item processed:', data) * }) * ``` */ on(event: QueueEventType, handler: QueueEventHandler): void; /** * Unregister event handler * * @param event - Event type * @param handler - Handler function to remove */ off(event: QueueEventType, handler: QueueEventHandler): void; /** * Get current offline queue status * * @returns Queue information including size and processing state */ getQueueStatus(): { size: number; processing: boolean; items: Array<{ queueId: string; method: string; timestamp: number; }>; }; /** * Manually trigger offline queue processing * * @returns Promise that resolves when processing is complete */ processQueue(): Promise<void>; } export { type ApiErrorResponse, type ApiInfoResponse, type BaseMutation, type BulkScoreResult, type BulkSubmitScoreRequest, type BulkSubmitScoreResponse, type ConnectionInfoMessage, type DetailedHealthResponse, type ErrorMessage, type FlexibleScoreSubmission, GlobalLeaderboards, type GlobalLeaderboardsConfig, GlobalLeaderboardsError, type HealthResponse, type LeaderboardData, type LeaderboardEntriesResponse, type LeaderboardEntry, type LeaderboardMutation, LeaderboardSSE, type LeaderboardUpdateMessage, LeaderboardWebSocket, type MutationType, type NewEntryMutation, OfflineQueue, type QueueEventHandler, type QueueEventType, type QueuedOperation, type QueuedSubmitResponse, type RankChangeMutation, type RemovedMutation, type SSEConnectionOptions, type SSEEventHandlers, type SSEEventType, type SSELeaderboardUpdateEvent, type ScoreUpdateMutation, type SubmitScoreRequest, type SubmitScoreResponse, type SubscribeMessage, type UnsubscribeMessage, type UpdateTrigger, type UserRankUpdateMessage, type UserScoreEntry, type UserScoresResponse, type UsernameChangeMutation, type WebSocketHandlers, type WebSocketMessage, type WebSocketMessageType };