All files / client/src/events registry.js

100% Statements 17/17
100% Branches 7/7
100% Functions 8/8
100% Lines 17/17

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 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99                              29x                   22x 1x   21x                 3x                 15x                 5x             66x                 3x 1x     2x 2x 6x 3x     2x               6x               3x  
/**
 * Handler Registry for Coherent.js Event Delegation
 *
 * Maps handler IDs to their corresponding functions and component context.
 * Handlers are identified by ID (from data-coherent-{event} attributes) rather
 * than by element reference, allowing them to survive DOM updates.
 */
 
/**
 * HandlerRegistry class
 * Stores handler functions with their associated component context
 */
export class HandlerRegistry {
  constructor() {
    /** @type {Map<string, {handler: Function, componentRef: object|null}>} */
    this.handlers = new Map();
  }
 
  /**
   * Register a handler with optional component context
   * @param {string} handlerId - Unique identifier for the handler
   * @param {Function} handler - The event handler function
   * @param {object|null} componentRef - Optional component reference with state/setState
   */
  register(handlerId, handler, componentRef = null) {
    if (typeof handler !== 'function') {
      throw new Error(`Handler must be a function, received: ${typeof handler}`);
    }
    this.handlers.set(handlerId, { handler, componentRef });
  }
 
  /**
   * Unregister a handler by ID
   * @param {string} handlerId - The handler ID to remove
   * @returns {boolean} True if handler was removed, false if not found
   */
  unregister(handlerId) {
    return this.handlers.delete(handlerId);
  }
 
  /**
   * Get a handler entry by ID
   * @param {string} handlerId - The handler ID to look up
   * @returns {{handler: Function, componentRef: object|null}|undefined} Handler entry or undefined
   */
  get(handlerId) {
    return this.handlers.get(handlerId);
  }
 
  /**
   * Check if a handler is registered
   * @param {string} handlerId - The handler ID to check
   * @returns {boolean} True if handler exists
   */
  has(handlerId) {
    return this.handlers.has(handlerId);
  }
 
  /**
   * Clear all registered handlers
   */
  clear() {
    this.handlers.clear();
  }
 
  /**
   * Get all handler IDs registered for a specific component
   * @param {object} componentRef - The component reference to search for
   * @returns {string[]} Array of handler IDs belonging to this component
   */
  getByComponent(componentRef) {
    if (!componentRef) {
      return [];
    }
 
    const handlerIds = [];
    for (const [handlerId, entry] of this.handlers) {
      if (entry.componentRef === componentRef) {
        handlerIds.push(handlerId);
      }
    }
    return handlerIds;
  }
 
  /**
   * Get the number of registered handlers
   * @returns {number} Count of registered handlers
   */
  get size() {
    return this.handlers.size;
  }
}
 
/**
 * Singleton handler registry instance
 * Use this for global event delegation
 */
export const handlerRegistry = new HandlerRegistry();