<commit_before>package de.tu_berlin.formic.datatype.tree

import akka.pattern._
import akka.util.Timeout
import de.tu_berlin.formic.common.datatype.FormicDataType.LocalOperationMessage
import de.tu_berlin.formic.common.datatype.client.DataTypeInitiator
import de.tu_berlin.formic.common.datatype.{DataTypeName, FormicDataType, OperationContext}
import de.tu_berlin.formic.common.message.{OperationMessage, UpdateRequest, UpdateResponse}
import de.tu_berlin.formic.common.{DataTypeInstanceId, OperationId}
import upickle.default._

import scala.concurrent.{ExecutionContext, Future}
import scala.concurrent.duration._
import scala.scalajs.js.annotation.JSExport

/**
  * @author <NAME>
  */
class FormicTree[T](_callback: () => Unit,
                    initiator: DataTypeInitiator,
                    dataTypeInstanceId: DataTypeInstanceId,
                    dataTypeName: DataTypeName)
                   (implicit val writer: Writer[T], val reader: Reader[T])
  extends FormicDataType(_callback, dataTypeName, dataTypeInstanceId = dataTypeInstanceId, initiator = initiator) {

  //TODO I suppose getDataAsJson within the TreeClientDataType is quite slow, optimize
  implicit val timeout: Timeout = 3.seconds

  implicit val valueTreeNodeReader = new ValueTreeNodeReader[T]()

  @JSExport
  def insert(value: T, path: AccessPath): Unit = {
    actor ! LocalOperationMessage(
      OperationMessage(null, dataTypeInstanceId, dataTypeName, List(
        TreeInsertOperation(path, ValueTreeNode(value), OperationId(), OperationContext(), null)
      ))
    )
  }

  @JSExport
  def remove(path: AccessPath): Unit = {
    actor ! LocalOperationMessage(
      OperationMessage(null, dataTypeInstanceId, dataTypeName, List(
        TreeDeleteOperation(path, OperationId(), OperationContext(), null)
      ))
    )
  }

  @JSExport
  def getSubTree(path: AccessPath)(implicit ec: ExecutionContext): Future[TreeNode] = {
    ask(actor, UpdateRequest(null, dataTypeInstanceId)).
      mapTo[UpdateResponse].
      map(rep => {
        rep.data
      }).
      map(data => {
        if(data == "") EmptyTreeNode
        else read[ValueTreeNode](data)
      }).
      map(tree => tree.getNode(path))
  }

  def getTree()(implicit ec: ExecutionContext): Future[TreeNode] = {
    ask(actor, UpdateRequest(null, dataTypeInstanceId)).
      mapTo[UpdateResponse].
      map(rep => {
        rep.data
      }).
      map(data => {
        if(data == "") EmptyTreeNode
        else read[ValueTreeNode](data)
      })
  }
}
<commit_msg>add missing JSExport<commit_after>package de.tu_berlin.formic.datatype.tree

import akka.pattern._
import akka.util.Timeout
import de.tu_berlin.formic.common.datatype.FormicDataType.LocalOperationMessage
import de.tu_berlin.formic.common.datatype.client.DataTypeInitiator
import de.tu_berlin.formic.common.datatype.{DataTypeName, FormicDataType, OperationContext}
import de.tu_berlin.formic.common.message.{OperationMessage, UpdateRequest, UpdateResponse}
import de.tu_berlin.formic.common.{DataTypeInstanceId, OperationId}
import upickle.default._

import scala.concurrent.{ExecutionContext, Future}
import scala.concurrent.duration._
import scala.scalajs.js.annotation.JSExport

/**
  * @author <NAME>
  */
class FormicTree[T](_callback: () => Unit,
                    initiator: DataTypeInitiator,
                    dataTypeInstanceId: DataTypeInstanceId,
                    dataTypeName: DataTypeName)
                   (implicit val writer: Writer[T], val reader: Reader[T])
  extends FormicDataType(_callback, dataTypeName, dataTypeInstanceId = dataTypeInstanceId, initiator = initiator) {

  //TODO I suppose getDataAsJson within the TreeClientDataType is quite slow, optimize
  implicit val timeout: Timeout = 3.seconds

  implicit val valueTreeNodeReader = new ValueTreeNodeReader[T]()

  @JSExport
  def insert(value: T, path: AccessPath): Unit = {
    actor ! LocalOperationMessage(
      OperationMessage(null, dataTypeInstanceId, dataTypeName, List(
        TreeInsertOperation(path, ValueTreeNode(value), OperationId(), OperationContext(), null)
      ))
    )
  }

  @JSExport
  def remove(path: AccessPath): Unit = {
    actor ! LocalOperationMessage(
      OperationMessage(null, dataTypeInstanceId, dataTypeName, List(
        TreeDeleteOperation(path, OperationId(), OperationContext(), null)
      ))
    )
  }

  @JSExport
  def getSubTree(path: AccessPath)(implicit ec: ExecutionContext): Future[TreeNode] = {
    ask(actor, UpdateRequest(null, dataTypeInstanceId)).
      mapTo[UpdateResponse].
      map(rep => {
        rep.data
      }).
      map(data => {
        if(data == "") EmptyTreeNode
        else read[ValueTreeNode](data)
      }).
      map(tree => tree.getNode(path))
  }

  @JSExport
  def getTree()(implicit ec: ExecutionContext): Future[TreeNode] = {
    ask(actor, UpdateRequest(null, dataTypeInstanceId)).
      mapTo[UpdateResponse].
      map(rep => {
        rep.data
      }).
      map(data => {
        if(data == "") EmptyTreeNode
        else read[ValueTreeNode](data)
      })
  }
}

{'fraction_non_alphanumeric': 0.10839091806515301, 'fraction_numerical': 0.0003948667324777887, 'mean_word_length': 3.572202166064982, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 17, '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': '1696344', 'n_tokens_mistral': 1503, 'n_tokens_neox': 1492, 'n_words': 293}