@juspay/neurolink
Version:
Universal AI Development Platform with working MCP integration, multi-provider support, voice (TTS/STT/realtime), and professional CLI. 58+ external MCP servers discoverable, multimodal file processing, RAG pipelines. Build, test, and deploy AI applicatio
348 lines (347 loc) • 11.6 kB
TypeScript
/**
* Processor Registry
*
* Central registry for file processors with priority-based selection.
* Uses singleton pattern to ensure a single source of truth for processor registration.
*
* All 16 BaseFileProcessor-based processors are auto-registered on first access
* via getProcessorRegistry(). Legacy processors (CSV, Image, PDF, PPTX) that use
* static methods and don't extend BaseFileProcessor are excluded — they continue
* to be routed via the switch/case in FileDetector.processFile().
*
* Key features:
* - Priority-based processor selection (lower number = higher priority)
* - Confidence scoring for match quality
* - Alias support for alternative processor names
* - Auto-detection and processing of files
* - Testing utilities (clear, resetInstance)
*
* @module processors/registry/ProcessorRegistry
*
* @example
* ```typescript
* import { ProcessorRegistry, getProcessorRegistry, PROCESSOR_PRIORITIES } from "./registry/index.js";
*
* const registry = await getProcessorRegistry();
*
* // Register a processor
* registry.register({
* name: "image",
* priority: PROCESSOR_PRIORITIES.IMAGE,
* processor: new ImageProcessor(),
* isSupported: (mimetype, filename) => mimetype.startsWith("image/"),
* description: "Processes images for AI vision",
* });
*
* // Find and use a processor
* const match = registry.findProcessor("image/jpeg", "photo.jpg");
* if (match) {
* const result = await match.processor.processFile(fileInfo);
* }
*
* // Auto-process a file
* const result = await registry.processFile(fileInfo);
* ```
*/
import type { FileInfo, ProcessorFileProcessingResult, ProcessedFileBase, ProcessOptions, ProcessorMatch, RegistryOptions, RegistryProcessResult, ProcessorRegistration } from "../../types/index.js";
/**
* Central registry for file processors.
* Uses singleton pattern and priority-based selection.
*
* Priority system: Lower number = higher priority
* - 5: SVG (before image, processed as text since AI providers often don't support SVG format)
* - 10: Image (AI vision)
* - 20: PDF (document)
* - 30: CSV (tabular data)
* - ...
* - 130: Config files
*
* @example
* ```typescript
* // Get singleton instance
* const registry = ProcessorRegistry.getInstance();
*
* // Register processors
* registry.register({
* name: "pdf",
* priority: 20,
* processor: pdfProcessor,
* isSupported: isPdfFile,
* });
*
* // Find best processor for a file
* const match = registry.findProcessor("application/pdf", "document.pdf");
* ```
*/
export declare class ProcessorRegistry {
/** Singleton instance */
private static instance;
/** Map of processor name (lowercase) to registration */
private processors;
/** Map of alias (lowercase) to canonical name (lowercase) */
private aliases;
/** Flag indicating if default processors have been initialized */
private initialized;
/**
* Private constructor for singleton pattern.
* Use getInstance() to get the registry instance.
*/
private constructor();
/**
* Get the singleton registry instance.
*
* @returns The ProcessorRegistry singleton
*
* @example
* ```typescript
* const registry = ProcessorRegistry.getInstance();
* ```
*/
static getInstance(): ProcessorRegistry;
/**
* Reset the singleton instance.
* Useful for testing to ensure a clean state.
*
* @example
* ```typescript
* // In test setup/teardown
* ProcessorRegistry.resetInstance();
* ```
*/
static resetInstance(): void;
/**
* Register a file processor.
*
* @typeParam T - The type of processed result
* @param registration - Processor registration details
* @param options - Registration options (allowDuplicates, overwriteExisting)
* @throws Error if processor with same name exists and overwrite not allowed
*
* @example
* ```typescript
* registry.register({
* name: "image",
* priority: 10,
* processor: imageProcessor,
* isSupported: (mimetype, filename) => mimetype.startsWith("image/"),
* description: "Processes images for AI vision",
* aliases: ["img", "picture"],
* });
* ```
*/
register<T extends ProcessedFileBase>(registration: ProcessorRegistration<T>, options?: RegistryOptions): void;
/**
* Unregister a processor by name.
*
* @param name - Name of the processor to unregister
* @returns true if processor was found and removed, false otherwise
*
* @example
* ```typescript
* const removed = registry.unregister("custom-image");
* ```
*/
unregister(name: string): boolean;
/**
* Remove all aliases pointing to a processor.
*
* @param normalizedName - Lowercase processor name
*/
private removeAliasesForProcessor;
/**
* Find the best matching processor for a file.
* Uses priority-based selection when multiple processors match.
*
* @param mimetype - MIME type of the file
* @param filename - Filename (for extension-based detection)
* @returns Best matching processor or null if none found
*
* @example
* ```typescript
* const match = registry.findProcessor("image/jpeg", "photo.jpg");
* if (match) {
* console.log(`Using ${match.name} processor`);
* const result = await match.processor.processFile(fileInfo);
* }
* ```
*/
findProcessor(mimetype: string, filename: string): ProcessorMatch | null;
/**
* Find all matching processors sorted by priority and confidence.
*
* @param mimetype - MIME type of the file
* @param filename - Filename (for extension-based detection)
* @returns Array of matching processors, sorted by priority (ascending) then confidence (descending)
*
* @example
* ```typescript
* const matches = registry.findAllProcessors("text/plain", "data.txt");
* console.log(`Found ${matches.length} processors that can handle this file`);
*
* for (const match of matches) {
* console.log(`${match.name}: priority=${match.priority}, confidence=${match.confidence}%`);
* }
* ```
*/
findAllProcessors(mimetype: string, filename: string): ProcessorMatch[];
/**
* Get a specific processor by name or alias.
*
* @param name - Processor name or alias
* @returns Processor registration or undefined if not found
*
* @example
* ```typescript
* const pdfProcessor = registry.getProcessor("pdf");
* // Also works with aliases
* const imageProcessor = registry.getProcessor("img");
* ```
*/
getProcessor(name: string): ProcessorRegistration | undefined;
/**
* List all registered processors.
*
* @returns Array of all processor registrations
*
* @example
* ```typescript
* const processors = registry.listProcessors();
* console.log("Registered processors:");
* for (const proc of processors) {
* console.log(` ${proc.name} (priority: ${proc.priority})`);
* }
* ```
*/
listProcessors(): ProcessorRegistration[];
/**
* Check if a processor is registered.
*
* @param name - Processor name or alias to check
* @returns true if processor is registered
*
* @example
* ```typescript
* if (registry.hasProcessor("pdf")) {
* console.log("PDF processor is available");
* }
* ```
*/
hasProcessor(name: string): boolean;
/**
* Get list of supported file types/processor names.
*
* @returns Array of processor names
*
* @example
* ```typescript
* const supportedTypes = registry.getSupportedTypes();
* console.log(`Supported: ${supportedTypes.join(", ")}`);
* ```
*/
getSupportedTypes(): string[];
/**
* Auto-detect and process a file using the best matching processor.
*
* @param fileInfo - File information including content/URL
* @param options - Processing options (auth headers, timeout, retry config)
* @returns Processing result or null if no processor found
*
* @example
* ```typescript
* const result = await registry.processFile(fileInfo, {
* authHeaders: { Authorization: "Bearer token" },
* timeout: 60000,
* });
*
* if (result?.success) {
* console.log("Processed:", result.data.filename);
* }
* ```
*/
processFile(fileInfo: FileInfo, options?: ProcessOptions): Promise<ProcessorFileProcessingResult<ProcessedFileBase> | null>;
/**
* Process a file with detailed result including error information.
* Returns structured result with either data or error details.
*
* @param fileInfo - File information including content/URL
* @param options - Processing options
* @returns Result with type, data, and optional error information
*
* @example
* ```typescript
* const result = await registry.processWithResult(fileInfo);
*
* if (result.error) {
* console.error(result.error.message);
* console.log("Suggestion:", result.error.suggestion);
* console.log("Supported types:", result.error.supportedTypes.join(", "));
* } else {
* console.log(`Processed as ${result.type}:`, result.data);
* }
* ```
*/
processWithResult(fileInfo: FileInfo, options?: ProcessOptions): Promise<RegistryProcessResult>;
/**
* Clear all registrations.
* Useful for testing to reset state between tests.
*
* @example
* ```typescript
* // In test teardown
* registry.clear();
* ```
*/
clear(): void;
/**
* Check if the registry has been initialized with default processors.
*
* @returns true if initialized
*/
isInitialized(): boolean;
/**
* Mark the registry as initialized.
* Called after default processors have been registered.
*/
markInitialized(): void;
/**
* Calculate confidence score for a processor match.
*
* @param mimetype - MIME type of the file
* @param filename - Filename
* @param reg - Processor registration
* @returns Confidence score (0-100)
*/
private calculateConfidence;
/**
* Get a helpful suggestion based on the file type.
*
* @param mimetype - MIME type of the file
* @param extension - File extension
* @returns Suggestion string for the user
*/
private getSuggestionForFile;
}
/**
* Get the ProcessorRegistry singleton instance.
* On first call, auto-initializes with all 16 default processors.
* Convenience function for shorter imports.
*
* @returns The ProcessorRegistry singleton (auto-initialized with default processors)
*
* @example
* ```typescript
* import { getProcessorRegistry } from "./registry/index.js";
*
* const registry = await getProcessorRegistry();
* const match = registry.findProcessor("image/svg+xml", "icon.svg");
* ```
*/
export declare const getProcessorRegistry: () => Promise<ProcessorRegistry>;
/**
* Get the ProcessorRegistry singleton instance synchronously (without auto-initialization).
* Use this when you know the registry is already initialized, or when you only
* need the raw registry instance (e.g., for manual registration in tests).
*
* @returns The ProcessorRegistry singleton (may be empty if not yet initialized)
*/
export declare const getProcessorRegistrySync: () => ProcessorRegistry;