Files

63 lines
2.2 KiB
JavaScript

// Shared registry of live Region Box (PromptChain_RegionBox) nodes.
//
// region-box.js populates this as Region Box nodes mount/unmount; main.js reads
// it so each PromptChain node's menubar can gate the "pop the Region Box into a
// panel" button (enabled only when a Region Box exists) and so the panel knows
// which node to dock. A single shared module instead of a window global keeps it
// deterministic regardless of which extension file the loader runs first.
//
// Twin of pose-registry.js — separate so the two panels gate independently.
// Event-driven: subscribers are notified on add/remove (never polled).
const nodes = new Set();
const listeners = new Set();
let lastActive = null;
function notify() {
for (const cb of listeners) {
try { cb(); } catch (e) { console.error("[PromptChain] region-box-registry listener error", e); }
}
}
export const regionBoxRegistry = {
// Called by region-box.js on mount.
add(node) {
nodes.add(node);
lastActive = node;
notify();
},
// Called by region-box.js on teardown.
remove(node) {
const had = nodes.delete(node);
if (lastActive === node) lastActive = null;
if (had) notify();
},
// Called when a Region Box canvas is interacted with, so "which node does the
// panel dock" follows the one you last touched. Quiet by design — switching
// focus shouldn't yank an already-open panel onto a different node.
touch(node) {
if (nodes.has(node)) lastActive = node;
},
// The canvas finished mounting (enterDock now exists). add() fired its notify
// earlier; re-notify so an already-open panel can dock now.
signalReady(node) {
if (nodes.has(node)) notify();
},
all() {
return [...nodes];
},
// The node a freshly-opened panel should host: last-interacted if still alive,
// else any live one.
getActive() {
if (lastActive && lastActive._pcrAlive && nodes.has(lastActive)) return lastActive;
for (const n of nodes) if (n._pcrAlive) return n;
return null;
},
get count() { return nodes.size; },
// Returns an unsubscribe fn. Fires on add/remove (gating + open-panel refresh).
subscribe(cb) {
listeners.add(cb);
return () => listeners.delete(cb);
},
};