UNPKG

@gotake/gotake-sdk

Version:

SDK for interacting with GoTake blockchain contracts

125 lines (124 loc) 4.01 kB
/** * Status tracker for video processing */ import { EventEmitter } from './eventEmitter.js'; import { VideoStatus } from '../types.js'; export class StatusTracker { constructor() { this.videoStatuses = new Map(); this.activePolls = new Map(); this.emitter = new EventEmitter(); } /** * Get StatusTracker singleton instance */ static getInstance() { if (!StatusTracker.instance) { StatusTracker.instance = new StatusTracker(); } return StatusTracker.instance; } /** * Update status of a video * @param videoId Video ID * @param status New status information */ updateStatus(videoId, status) { const currentStatus = this.videoStatuses.get(videoId) || { id: videoId, status: VideoStatus.UPLOADING, updated_at: new Date().toISOString() }; const newStatus = { ...currentStatus, ...status, updated_at: new Date().toISOString() }; this.videoStatuses.set(videoId, newStatus); this.emitter.emit(`status:${videoId}`, newStatus); } /** * Get current status of a video * @param videoId Video ID * @returns Status information or undefined if not found */ getStatus(videoId) { return this.videoStatuses.get(videoId); } /** * Subscribe to status updates for a video * @param videoId Video ID * @param callback Function to call when status changes * @returns Subscription object */ subscribe(videoId, callback) { // Send current status immediately if available const currentStatus = this.getStatus(videoId); if (currentStatus) { setTimeout(() => callback(currentStatus), 0); } // Subscribe to future updates return this.emitter.on(`status:${videoId}`, callback); } /** * Start polling for status updates * @param videoId Video ID * @param statusFetcher Function to fetch the latest status * @param options Polling options * @returns Poll controller */ startPolling(videoId, statusFetcher, options) { // Clear any existing poll for this video this.stopPolling(videoId); const interval = options.interval || 5000; // Default: 5 seconds // Define poll function const poll = async () => { try { const status = await statusFetcher(); this.updateStatus(videoId, status); // Call callback options.callback(status); // Check stop condition if (options.stopCondition && options.stopCondition(status)) { this.stopPolling(videoId); return; } // Schedule next poll const timeoutId = setTimeout(poll, interval); this.activePolls.set(videoId, timeoutId); } catch (error) { console.error(`Error polling status for video ${videoId}:`, error); // Try again after interval const timeoutId = setTimeout(poll, interval); this.activePolls.set(videoId, timeoutId); } }; // Start polling poll(); // Return controller return { stop: () => this.stopPolling(videoId) }; } /** * Stop polling for a video * @param videoId Video ID */ stopPolling(videoId) { const timeoutId = this.activePolls.get(videoId); if (timeoutId) { clearTimeout(timeoutId); this.activePolls.delete(videoId); } } /** * Clear all data for a video * @param videoId Video ID */ clearVideo(videoId) { this.stopPolling(videoId); this.videoStatuses.delete(videoId); this.emitter.removeAllListeners(`status:${videoId}`); } }