@gotake/gotake-sdk
Version:
SDK for interacting with GoTake blockchain contracts
125 lines (124 loc) • 4.01 kB
JavaScript
/**
* 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}`);
}
}