All files / webview messageBus.ts

100% Statements 23/23
91.66% Branches 11/12
100% Functions 4/4
100% Lines 21/21

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49                8x 8x     32x 32x 21x 21x 16x 18x           18x 8x 8x                 18x 18x 18x 17x 17x   18x 18x 9x 9x 9x        
export interface WebviewMessageMap {
  update: { type: 'update'; content?: string; baseUri?: string; fileType?: string };
  toggleMode: { type: 'toggleMode' };
  [key: string]: { type: string; [k: string]: unknown };
}
 
type MessageHandler<T = { type: string; [k: string]: unknown }> = (data: T) => void;
 
const listeners = new Map<string, Set<MessageHandler<any>>>();
let initialized = false;
 
function handleRawMessage(event: MessageEvent) {
  const msg = event.data;
  if (!msg || typeof msg.type !== 'string') return;
  const handlers = listeners.get(msg.type);
  if (handlers) {
    for (const handler of handlers) {
      handler(msg);
    }
  }
}
 
function ensureInit() {
  if (initialized) return;
  initialized = true;
  window.addEventListener('message', handleRawMessage);
}
 
export function subscribe<K extends keyof WebviewMessageMap>(
  type: K,
  handler: MessageHandler<WebviewMessageMap[K]>
): () => void;
export function subscribe(type: string, handler: MessageHandler): () => void;
export function subscribe(type: string, handler: MessageHandler<any>): () => void {
  ensureInit();
  let set = listeners.get(type);
  if (!set) {
    set = new Set();
    listeners.set(type, set);
  }
  set.add(handler);
  return () => {
    set!.delete(handler);
    Eif (set!.size === 0) {
      listeners.delete(type);
    }
  };
}