<commit_before>package frontend.webui

import java.nio.ByteBuffer

import scala.concurrent.Future
import scala.scalajs.js
import scala.scalajs.js.JSApp

import org.scalajs.dom
import org.scalajs.dom.raw.ErrorEvent
import org.scalajs.dom.raw.Event
import org.scalajs.dom.raw.MessageEvent
import org.scalajs.dom.raw.WebSocket

import frontend.webui.protocol.Response
import protocol.ConnectionFailure
import protocol.ConnectionSuccessful

object Main extends JSApp {

  implicit class AsDynamic[A](private val a: A) extends AnyVal {
    def jsg: js.Dynamic = a.asInstanceOf[js.Dynamic]
  }

  val ServerAddress = "localhost:9999"

  /** The socket to the server */
  private var ws: WebSocket = _
  /** The ID of the client which is assigned by the server after authentication. */
  private var id: String = _

  override def main(): Unit = {
    authenticate()
  }

  def authenticate() = {
    val ws = new WebSocket(websocketUri("auth-web"))
    ws.binaryType = "arraybuffer"
    ws.onopen = (e: Event) ⇒ {
      dom.console.log("Connection for server authentication opened")
    }
    ws.onerror = (e: ErrorEvent) ⇒ {
      dom.console.error(s"Couldn't create connection to server: $e")
    }
    ws.onmessage = (e: MessageEvent) ⇒ {
      import boopickle.Default._
      val bytes = toByteBuffer(e.data)
      Unpickle[Response].fromBytes(bytes) match {
        case ConnectionSuccessful(id) ⇒
          dom.console.info(s"Server assigned id `$id`.")
          this.id = id

          import scala.scalajs.concurrent.JSExecutionContext.Implicits.queue
          Future(setupWS())

        case ConnectionFailure ⇒
          dom.console.error("Connection failure")
          // TODO what to do here?

        case msg ⇒
          dom.console.error(s"Unexpected message arrived: $msg")
      }
      ws.close()
    }
  }

  def setupWS() = {
    ws = new WebSocket(websocketUri("kb"))
    ws.binaryType = "arraybuffer"
    ws.onopen = (e: Event) ⇒ {
      dom.console.info("Connection for server communication opened")
    }
    ws.onerror = (e: ErrorEvent) ⇒ {
      dom.console.error(s"Couldn't create connection to server: $e")
    }
    ws.onmessage = (e: MessageEvent) ⇒ {
      import boopickle.Default._
      val bytes = toByteBuffer(e.data)
      handleResponse(Unpickle[Response].fromBytes(bytes))
    }
    ws.onclose = (e: Event) ⇒ {
      dom.console.info(s"websocket for server communication closed")
    }
    dom.window.jsg.onerror = js.Any.fromFunction5((msg: Event, file: String, line: Int, col: Int, error: Any) ⇒ {
      // TODO See https://github.com/stacktracejs/stacktrace.js for a browser independent solution to log errors
      dom.console.error(error.jsg.stack)
    })
  }

  def handleResponse(response: Response) = response match {
    case _ ⇒
  }

  private def websocketUri(path: String): String = {
    val wsProtocol = if (dom.document.location.protocol == "https:") "wss" else "ws"
    s"$wsProtocol://$ServerAddress/$path"
  }

  private def toByteBuffer(data: Any): ByteBuffer = {
    val ab = data.asInstanceOf[js.typedarray.ArrayBuffer]
    js.typedarray.TypedArrayBuffer.wrap(ab)
  }
}
<commit_msg>Better error messages in web ui<commit_after>package frontend.webui

import java.nio.ByteBuffer

import scala.concurrent.Future
import scala.scalajs.js
import scala.scalajs.js.JSApp
import scala.scalajs.js.JSON

import org.scalajs.dom
import org.scalajs.dom.raw.ErrorEvent
import org.scalajs.dom.raw.Event
import org.scalajs.dom.raw.MessageEvent
import org.scalajs.dom.raw.WebSocket

import frontend.webui.protocol.Response
import protocol.ConnectionFailure
import protocol.ConnectionSuccessful

object Main extends JSApp {

  implicit class AsDynamic[A](private val a: A) extends AnyVal {
    def jsg: js.Dynamic = a.asInstanceOf[js.Dynamic]
  }

  val ServerAddress = "localhost:9999"

  /** The socket to the server */
  private var ws: WebSocket = _
  /** The ID of the client which is assigned by the server after authentication. */
  private var id: String = _

  override def main(): Unit = {
    authenticate()
  }

  def authenticate() = {
    val ws = new WebSocket(websocketUri("auth-web"))
    ws.binaryType = "arraybuffer"
    ws.onopen = (e: Event) ⇒ {
      dom.console.info("Connection for server authentication opened")
    }
    ws.onerror = (e: ErrorEvent) ⇒ {
      dom.console.error(s"Couldn't create connection to server: ${JSON.stringify(e)}")
    }
    ws.onmessage = (e: MessageEvent) ⇒ {
      import boopickle.Default._
      val bytes = toByteBuffer(e.data)
      Unpickle[Response].fromBytes(bytes) match {
        case ConnectionSuccessful(id) ⇒
          dom.console.info(s"Server assigned id `$id`.")
          this.id = id

          import scala.scalajs.concurrent.JSExecutionContext.Implicits.queue
          Future(setupWS())

        case ConnectionFailure ⇒
          dom.console.error("Connection failure")
          // TODO what to do here?

        case msg ⇒
          dom.console.error(s"Unexpected message arrived: $msg")
      }
      ws.close()
    }
  }

  def setupWS() = {
    ws = new WebSocket(websocketUri("kb"))
    ws.binaryType = "arraybuffer"
    ws.onopen = (e: Event) ⇒ {
      dom.console.info("Connection for server communication opened")
    }
    ws.onerror = (e: ErrorEvent) ⇒ {
      dom.console.error(s"Couldn't create connection to server: ${JSON.stringify(e)}")
    }
    ws.onmessage = (e: MessageEvent) ⇒ {
      import boopickle.Default._
      val bytes = toByteBuffer(e.data)
      handleResponse(Unpickle[Response].fromBytes(bytes))
    }
    ws.onclose = (e: Event) ⇒ {
      dom.console.info(s"websocket for server communication closed")
    }
    dom.window.jsg.onerror = js.Any.fromFunction5((msg: Event, file: String, line: Int, col: Int, error: Any) ⇒ {
      // TODO See https://github.com/stacktracejs/stacktrace.js for a browser independent solution to log errors
      dom.console.error(error.jsg.stack)
    })
  }

  def handleResponse(response: Response) = response match {
    case _ ⇒
  }

  private def websocketUri(path: String): String = {
    val wsProtocol = if (dom.document.location.protocol == "https:") "wss" else "ws"
    s"$wsProtocol://$ServerAddress/$path"
  }

  private def toByteBuffer(data: Any): ByteBuffer = {
    val ab = data.asInstanceOf[js.typedarray.ArrayBuffer]
    js.typedarray.TypedArrayBuffer.wrap(ab)
  }
}

{'fraction_non_alphanumeric': 0.11800754242614708, 'fraction_numerical': 0.0015713387806411063, 'mean_word_length': 3.072296865003199, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 2, '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': '3130824', 'n_tokens_mistral': 2079, 'n_tokens_neox': 2033, 'n_words': 493}