<commit_before>/*
  Connects to the Cerebral debugger
  - Triggers events with information from function tree execution
  - Stores data related to time travel, if activated
*/
class Devtools {
  constructor(options = {}) {
    this.VERSION = 'v1'
    this.storeMutations = options.storeMutations === undefined ? true : options.storeMutations
    this.backlog = []
    this.mutations = []
    this.latestExecutionId = null
    this.executionCount = 0
    this.initialModelString = null
    this.isConnected = false
    this.controller = null
    this.originalRunTreeFunction = null
  }
  /*
    To remember state Cerebral stores the initial model as stringified
    object. Since the model is mutable this is necessary. The debugger
    passes the execution id of the signal that was double clicked. This
    execution id is searched backwards in the array of mutations done.
    This is necessary as multiple mutations can be done on the same execution.
    Then all mutations are replayed to the model and all the components
    will be rerendered using the "flush" event and "force" flag.

    It will also replace the "runTree" method of the controller to
    prevent any new signals firing off when in "remember state"
  */
  remember(executionId) {
    this.controller.model.state = JSON.parse(this.initialModelString)
    let lastMutationIndex

    if (executionId === this.latestExecutionId) {
      this.controller.runTree = this.originalRunTreeFunction
      lastMutationIndex = this.mutations.length - 1
    } else {
      for (lastMutationIndex = this.mutations.length - 1; lastMutationIndex >= 0; lastMutationIndex--) {
        if (this.mutations[lastMutationIndex].executionId === executionId) {
          break
        }
      }

      this.controller.runTree = (name) => {
        console.warn(`The signal "${name}" fired while debugger is remembering state, it was ignored`)
      }
    }

    for (let x = 0; x <= lastMutationIndex; x++) {
      const mutation = JSON.parse(this.mutations[x].data)

      this.controller.model[mutation.method](...mutation.args)
    }

    this.controller.emit('flush', {}, true)
  }
  /*
    The debugger might be ready or it might not. The initial communication
    with the debugger requires a "ping" -> "pong" to identify that it
    is ready to receive messages.
    1. Debugger is open when app loads
      - Devtools sends "ping"
      - Debugger sends "pong"
      - Devtools sends "init"
    2. Debugger is opened after app load
      - Debugger sends "ping"
      - Devtools sends "init"
  */
  init(controller) {
    const initialModel = controller.model.get()
    this.controller = controller
    this.originalRunTreeFunction = controller.runTree

    if (this.storeMutations) {
      this.initialModelString = JSON.stringify(initialModel)
    }

    window.addEventListener('cerebral2.debugger.remember', (event) => {
      if (!this.storeMutations) {
        console.warn('Cerebral Devtools - You tried to time travel, but you have turned of storing of mutations')
      }
      this.remember(event.detail)
    })
    window.addEventListener('cerebral2.debugger.pong', () => {
      // When debugger responds to a ping
      this.isConnected = true
      this.sendInitial(initialModel)
    })
    window.addEventListener('cerebral2.debugger.ping', () => {
      // When debugger activates
      this.isConnected = true
      this.sendInitial(initialModel)
    })

    const event = new window.CustomEvent('cerebral2.client.message', {
      detail: JSON.stringify({type: 'ping'})
    })
    window.dispatchEvent(event)

    this.watchExecution()
  }
  /*
    Watches function tree for execution of signals. This is passed to
    debugger to prevent time travelling when executing. It also tracks
    latest executed signal for "remember" to know when signals can be
    called again
  */<commit_msg>feat(devtools): should reset state when receiving reset event<commit_after>/*
  Connects to the Cerebral debugger
  - Triggers events with information from function tree execution
  - Stores data related to time travel, if activated
*/
class Devtools {
  constructor(options = {}) {
    this.VERSION = 'v1'
    this.storeMutations = options.storeMutations === undefined ? true : options.storeMutations
    this.backlog = []
    this.mutations = []
    this.latestExecutionId = null
    this.executionCount = 0
    this.initialModelString = null
    this.isConnected = false
    this.controller = null
    this.originalRunTreeFunction = null
  }
  /*
    To remember state Cerebral stores the initial model as stringified
    object. Since the model is mutable this is necessary. The debugger
    passes the execution id of the signal that was double clicked. This
    execution id is searched backwards in the array of mutations done.
    This is necessary as multiple mutations can be done on the same execution.
    Then all mutations are replayed to the model and all the components
    will be rerendered using the "flush" event and "force" flag.

    It will also replace the "runTree" method of the controller to
    prevent any new signals firing off when in "remember state"
  */
  remember(executionId) {
    this.controller.model.state = JSON.parse(this.initialModelString)
    let lastMutationIndex

    if (executionId === this.latestExecutionId) {
      this.controller.runTree = this.originalRunTreeFunction
      lastMutationIndex = this.mutations.length - 1
    } else {
      for (lastMutationIndex = this.mutations.length - 1; lastMutationIndex >= 0; lastMutationIndex--) {
        if (this.mutations[lastMutationIndex].executionId === executionId) {
          break
        }
      }

      this.controller.runTree = (name) => {
        console.warn(`The signal "${name}" fired while debugger is remembering state, it was ignored`)
      }
    }

    for (let x = 0; x <= lastMutationIndex; x++) {
      const mutation = JSON.parse(this.mutations[x].data)

      this.controller.model[mutation.method](...mutation.args)
    }

    this.controller.emit('flush', {}, true)
  }
  /*

  */
  reset() {
    this.controller.model.state = JSON.parse(this.initialModelString)
    this.backlog = []
    this.mutations = []
    this.controller.emit('flush', {}, true)
  }
  /*
    The debugger might be ready or it might not. The initial communication
    with the debugger requires a "ping" -> "pong" to identify that it
    is ready to receive messages.
    1. Debugger is open when app loads
      - Devtools sends "ping"
      - Debugger sends "pong"
      - Devtools sends "init"
    2. Debugger is opened after app load
      - Debugger sends "ping"
      - Devtools sends "init"
  */
  init(controller) {
    const initialModel = controller.model.get()
    this.controller = controller
    this.originalRunTreeFunction = controller.runTree

    if (this.storeMutations) {
      this.initialModelString = JSON.stringify(initialModel)
    }

    window.addEventListener('cerebral2.debugger.remember', (event) => {
      if (!this.storeMutations) {
        console.warn('Cerebral Devtools - You tried to time travel, but you have turned of storing of mutations')
      }
      this.remember(event.detail)
    })
    window.addEventListener('cerebral2.debugger.reset', (event) => {
      this.reset()
    })
    window.addEventListener('cerebral2.debugger.pong', () => {
      // When debugger responds to a ping
      this.isConnected = true
      this.sendInitial(initialModel)
    })
    window.addEventListener('cerebral2.debugger.ping', () => {
      // When debugger activates
      this.isConnected = true
      this.sendInitial(initialModel)
    })

    const event = new window.CustomEvent('cerebral2.client.message', {
      detail: JSON.stringify({type: 'ping'})
    })
    window.dispatchEvent(event)

    this.watchExecution()
  }
  /*
    Watches function tree for execution of signals. This is passed to
    debugger to prevent time travelling when executing. It also tracks
    latest executed signal for "remember" to know when signals can be
    called again
  */
{'fraction_non_alphanumeric': 0.09210526315789473, 'fraction_numerical': 0.003103277060575968, 'mean_word_length': 2.9437102300538425, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 16, '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': '5178478', 'n_tokens_mistral': 2283, 'n_tokens_neox': 2200, 'n_words': 711}