Files
MajoorWaldi-ComfyUI-Majoor-…/ui/features/viewer/nodeStream/NodeStreamRegistry.ts
T

93 lines
3.1 KiB
TypeScript

/**
* NodeStreamRegistry - adapter registry for the Node Stream system.
*
* Each adapter declares which ComfyUI node class_types it can handle and how
* to extract viewable media from the node's output. The registry resolves the
* best adapter for a given node type at runtime.
*
* Adapters are matched in priority order (highest first). The first adapter
* whose `canHandle(classType, outputs)` returns true wins.
*
* The registry remains available for built-in compatibility coverage and
* debug inspection, but third-party adapter registration is not part of the
* active selection-only Node Stream public contract.
*/
/** @typedef {import("./adapters/BaseAdapter.js").NodeStreamAdapter} NodeStreamAdapter */
/** @type {NodeStreamAdapter[]} sorted by priority descending */
const _adapters: any[] = [];
/** Dirty flag - set when an adapter is added/removed so the sorted list is rebuilt. */
let _dirty = false;
function _ensureSorted() {
if (!_dirty) return;
_adapters.sort((a: any, b: any) => (b.priority ?? 0) - (a.priority ?? 0));
_dirty = false;
}
// -- Public API ----------------------------------------------------------------
/**
* Register a new adapter for internal compatibility/debug purposes.
* @param {NodeStreamAdapter} adapter
*/
export function registerAdapter(adapter: any): void {
if (!adapter?.name) {
console.warn("[NodeStream] Cannot register adapter without a name");
return;
}
// Replace existing adapter with the same name (hot-reload friendly)
const idx = _adapters.findIndex((a: any) => a.name === adapter.name);
if (idx >= 0) _adapters.splice(idx, 1);
_adapters.push(adapter);
_dirty = true;
console.debug(
`[NodeStream] Adapter registered: ${adapter.name} (priority ${adapter.priority ?? 0})`,
);
}
/**
* Remove an adapter by name.
* @param {string} name
*/
export function unregisterAdapter(name: string): void {
const idx = _adapters.findIndex((a: any) => a.name === name);
if (idx >= 0) {
_adapters.splice(idx, 1);
_dirty = true;
}
}
/**
* Find the best adapter in the compatibility registry.
* @param {string} classType ComfyUI node class_type (e.g. "SaveImage", "LayerColorCorrection")
* @param {object} outputs The outputs object from onNodeOutputsUpdated for this node
* @returns {NodeStreamAdapter | null}
*/
export function findAdapter(classType: string, outputs: any): any {
_ensureSorted();
for (const adapter of _adapters) {
try {
if (adapter.canHandle(classType, outputs)) return adapter;
} catch (e: any) {
console.debug?.(`[NodeStream] adapter.canHandle error (${adapter.name})`, e);
}
}
return null;
}
/**
* Return a snapshot of all registered adapters (for debug / UI listing).
* @returns {ReadonlyArray<{name: string, priority: number, description: string}>}
*/
export function listAdapters(): unknown[] {
_ensureSorted();
return _adapters.map((a: any) => ({
name: a.name,
priority: a.priority ?? 0,
description: a.description ?? "",
}));
}