UNPKG

filecoin-pin

Version:

Bridge IPFS content to Filecoin Onchain Cloud using familiar tools

150 lines 4.91 kB
/** * Multi-operation spinner flow manager * * Manages a spinner that can track multiple parallel operations, automatically * updating the spinner message as operations are added, updated, or completed. * * Usage: * const flow = createSpinnerFlow(spinner) * flow.addOperation('upload', 'Uploading file...') * flow.addOperation('validate', 'Validating...') * flow.updateOperation('upload', 'Uploading file... 50%') * flow.completeOperation('upload', 'Upload complete', { type: 'success', details: {...} }) * flow.completeOperation('validate', 'Validation complete', { type: 'success' }) */ import pc from 'picocolors'; import { log } from './cli-logger.js'; /** * Multi-operation spinner flow manager */ export class MultiOperationSpinner { operations = new Map(); spinner; spinnerRunning = false; constructor(spinner) { this.spinner = spinner; } /** * Get the combined message for all active operations */ getCombinedMessage() { return Array.from(this.operations.values()) .filter((msg) => msg !== '') .join(' & '); } /** * Update the spinner message * Handles starting the spinner if needed, or updating if already running */ updateSpinner() { const message = this.getCombinedMessage(); if (message === '') { // No operations - nothing to do, but don't stop spinner // (spinner might be running for other reasons) return; } if (this.spinnerRunning) { // Spinner running, update message this.spinner?.message(message); } else { // Spinner not running, start it this.spinner?.start(message); this.spinnerRunning = true; } } /** * Add or update an operation * @param id - Unique identifier for the operation * @param message - Message to display for this operation */ addOperation(id, message) { this.operations.set(id, message); this.updateSpinner(); } /** * Update an existing operation's message * @param id - Operation identifier * @param message - New message */ updateOperation(id, message) { if (!this.operations.has(id)) { // Operation doesn't exist, treat as add this.addOperation(id, message); return; } this.operations.set(id, message); this.updateSpinner(); } /** * Mark that the spinner was started externally * Use this when you start the spinner outside of the flow manager */ markSpinnerStarted() { this.spinnerRunning = true; } /** * Mark that the spinner was stopped externally * Use this when you stop the spinner outside of the flow manager */ markSpinnerStopped() { this.spinnerRunning = false; } /** * Complete an operation * @param id - Operation identifier * @param message - Completion message * @param options - Completion options (status type and optional details) */ completeOperation(id, message, options = {}) { if (!this.operations.has(id)) { // Operation doesn't exist, nothing to complete return; } const { type = 'success', details } = options; // Remove from active operations this.operations.delete(id); // Format completion message with status indicator const statusIcon = this.getStatusIcon(type); const completionMessage = `${statusIcon} ${message}`; // Stop spinner with completion message this.spinner?.stop(completionMessage); this.spinnerRunning = false; // Display details section if provided if (details != null) { log.spinnerSection(details.title, details.content); } // Restart spinner if there are remaining operations const remainingMessage = this.getCombinedMessage(); if (remainingMessage !== '') { this.spinner?.start(remainingMessage); this.spinnerRunning = true; } } /** * Get the icon for a status type */ getStatusIcon(type) { switch (type) { case 'success': return pc.green('✓'); case 'warning': return pc.yellow('⚠'); case 'error': return pc.red('✗'); case 'info': return pc.blue('ℹ'); default: return pc.green('✓'); } } } /** * Create a new multi-operation spinner flow * @param spinner - The spinner instance to manage * @returns A MultiOperationSpinner instance */ export function createSpinnerFlow(spinner) { return new MultiOperationSpinner(spinner); } //# sourceMappingURL=multi-operation-spinner.js.map