93 lines
3.1 KiB
TypeScript
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 ?? "",
|
|
}));
|
|
}
|