<commit_before>
import createPrivate from "namespace-proxy"
import AbstractHandler from "./resourceHandler/AbstractHandler"

const PRIVATE = createPrivate()

export default class RequestHandler {
  constructor(...resourceHandlers: AbstractHandler[]) {
    /**
     * @type {AbstractHandler[]}
     */
    PRIVATE(this).resourceHandlers = resourceHandlers

    /**
     * @type {function(
     *         this:RequestHandler,
     *         {resource: string, method: string, parameters: ?Object<string, (number|string)>, data: ?Object<string, *>},
     *         sender: *,
     *         sendResponse: function(*))
     *       }
     */
    PRIVATE(this).onMessage = this[PRIVATE.onMessage].bind(this);

    /**
     * @type {boolean}
     */
    PRIVATE(this).running = false
    
    Object.seal(this)
  }
  
  start() {
    if (PRIVATE(this).running) {
      throw new Error("The request handler is already running")
    }

    chrome.runtime.onMessage.addListener(PRIVATE(this).onmessage)
    PRIVATE(this).running = true
  }
  
  stop() {
    if (PRIVATE(this).running) {
      throw new Error("The request handler is already stopped")
    }

    chrome.runtime.onMessage.removeListener(PRIVATE(this).onmessage)
    PRIVATE(this).running = false
  }

  /**
   * Incoming message handler.
   *
   * @param message The received message.
   * @param sender Identifier of the sender of the received message, which is
   *        irrelevant due to constraints imposed by Chrome.
   * @param sendResponse The callback to use to send the response to the sender
   *        of the message.
   * @return Always {@code true}, indicating the message will be responded to
   *         asynchronically.
   */
  [PRIVATE.onMessage](
    message: {resource: string, method: string, parameters: ?Object<string, (number|string)>, data: ?Object<string, *>},<commit_msg>documentation, added input check for the request handler constructor<commit_after>
import createPrivate from "namespace-proxy"
import AbstractHandler from "./resourceHandler/AbstractHandler"

const PRIVATE = createPrivate()

/**
 * The request handler is REST API-like server that allows other views of the
 * extension to communicate with the background page by sending messages and
 * receiving replies.
 */
export default class RequestHandler {
  /**
   * Initializes the request handler.
   *
   * @param resourceHandlers The resource handlers that should be used to
   *        handle the incoming messages. There cannot be multiple resource
   *        handlers handling the same resource.
   */
  constructor(...resourceHandlers: AbstractHandler[]) {
    let handledResources = new Set()
    for (let handler of resourceHandlers) {
      let resourceName = handler.resourceName
      if (handledResources.has(resourceName)) {
        throw new Error("Obtained multiple resource handlers for handling " +
            `the ${resourceName} resource`)
      }
      handledResources.add(resourceName)
    }

    /**
     * The resource handlers that should be used to handle the incoming
     * messages.
     *
     * @type {AbstractHandler[]}
     */
    PRIVATE(this).resourceHandlers = resourceHandlers

    /**
     * The private {@code onMessage} method bound to this instance. The method
     * is used as an event listener for the incoming messages.
     *
     * @type {function(
     *         this:RequestHandler,
     *         {resource: string, method: string, parameters: ?Object<string, (number|string)>, data: ?Object<string, *>},
     *         sender: *,
     *         sendResponse: function(*))
     *       }
     */
    PRIVATE(this).onMessage = this[PRIVATE.onMessage].bind(this);

    /**
     * The state of the request handler.
     *
     * @type {boolean}
     */
    PRIVATE(this).running = false
    
    Object.seal(this)
  }

  /**
   * Starts the request handler, allowing it to handle incoming messages,
   * processing them and sending replies.
   */
  start() {
    if (PRIVATE(this).running) {
      throw new Error("The request handler is already running")
    }

    chrome.runtime.onMessage.addListener(PRIVATE(this).onmessage)
    PRIVATE(this).running = true
  }

  /**
   * Stops the request handler. This method should not be used under normal
   * circumstances, it is useful for debugging only.
   */
  stop() {
    if (PRIVATE(this).running) {
      throw new Error("The request handler is already stopped")
    }

    chrome.runtime.onMessage.removeListener(PRIVATE(this).onmessage)
    PRIVATE(this).running = false
  }

  /**
   * Incoming message handler.
   *
   * @param message The received message.
   * @param sender Identifier of the sender of the received message, which is
   *        irrelevant due to constraints imposed by Chrome.
   * @param sendResponse The callback to use to send the response to the sender
   *        of the message.
   * @return Always {@code true}, indicating the message will be responded to
   *         asynchronically.
   */
  [PRIVATE.onMessage](
    message: {resource: string, method: string, parameters: ?Object<string, (number|string)>, data: ?Object<string, *>},
{'fraction_non_alphanumeric': 0.10451260011721039, 'fraction_numerical': 0.0, 'mean_word_length': 2.855421686746988, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2360102', 'n_tokens_mistral': 1404, 'n_tokens_neox': 1369, 'n_words': 438}