40 lines
1.3 KiB
TypeScript
40 lines
1.3 KiB
TypeScript
export type OutputHandler<T = unknown> = (payload: T) => void | Promise<void>;
|
|
export interface OutputHost extends HTMLElement {
|
|
__wrnexusOutputHandlers?: Map<string, Set<OutputHandler>>;
|
|
}
|
|
|
|
export function registerOutputHandler<T>(
|
|
host: OutputHost,
|
|
name: string,
|
|
handler: OutputHandler<T>,
|
|
): () => void {
|
|
const registry = (host.__wrnexusOutputHandlers ??= new Map());
|
|
const handlers = registry.get(name) ?? new Set();
|
|
handlers.add(handler as OutputHandler);
|
|
registry.set(name, handlers);
|
|
return () => {
|
|
handlers.delete(handler as OutputHandler);
|
|
if (!handlers.size) registry.delete(name);
|
|
};
|
|
}
|
|
|
|
export async function invokeOutput<T>(host: OutputHost, name: string, payload?: T): Promise<void> {
|
|
const handlers = host.__wrnexusOutputHandlers?.get(name);
|
|
if (handlers?.size) {
|
|
for (const handler of handlers) await handler(payload);
|
|
return;
|
|
}
|
|
// Compatibility path for legacy listeners outside a hydrated WRN parent.
|
|
host.dispatchEvent(new CustomEvent(name, { detail: payload }));
|
|
host.dispatchEvent(new CustomEvent(`wrnexus:${name}`, { detail: payload }));
|
|
}
|
|
|
|
export function createOutputProxy<T extends Record<string, (...args: any[]) => void>>(
|
|
host: OutputHost,
|
|
): T {
|
|
return new Proxy({} as T, {
|
|
get: (_target, property) => (payload?: unknown) =>
|
|
invokeOutput(host, String(property), payload),
|
|
});
|
|
}
|