<commit_before>const { Map, List } = require('immutable')

const Store = () => {
  let store = Map({})
  let relationships = Map({})

  function _isRelationshipValid(relationship) {
    const [...props] = relationship.keys()
    const shape = ['field', 'mustReference', 'mustEmbed']
    const valid = shape.filter(prop => props.indexOf(prop) >= 0)
    
    return (valid.length === 2 && relationship.get('field'))
  }

  function _parseRelationship(relationship) {
    let pathFrom, pathTo, fieldFrom, fieldTo, type
    
    pathFrom = relationship.get('field').split('.')
    fieldFrom = pathFrom.pop()
    if (relationship.get('mustEmbed')) {
      type = "embed"
      pathTo = relationship.get('mustEmbed').split('.')
    } else {
      type = "reference"
      pathTo = relationship.get('mustReference').split('.')
    }
    fieldTo = pathTo.pop()
    
    return { type, pathFrom, fieldFrom, pathTo, fieldTo }
  }

  function _transform(grave, newState) {
    // First, change Grave store to state
    let newStore = store.set(grave, newState)
    if (relationships.has(grave)) {
      relationships.get(grave).forEach(relationship => {
        if (_isRelationshipValid(relationship)) {
          const rel = _parseRelationship(relationship)
          if (rel.type === 'embed') {
            // Dive into the origin collection...
            newStore = newStore.updateIn([grave, ...rel.pathFrom], collection => {
              // If collection isn't a list, return itself
              if (!List.isList(collection)) {
                return collection
              }
              // Maps collection
              return collection.map(documentFrom => {
                if (Map.isMap(documentFrom.get(rel.fieldFrom))) {
                  return documentFrom
                }
                // Return the document if there's a match
                const match = newStore.getIn(rel.pathTo).find(documentTo => {
                  return documentTo.get(rel.fieldTo) === documentFrom.get(rel.fieldFrom)
                })
                // If there's a match, embed the result in the field
                return match ? documentFrom.set(rel.fieldFrom, match) : documentFrom
              })
            })
          }
        }
      })
    }
    return newStore
  }
  
  function setGraveState(grave, newState) {
    store = _transform(grave, newState)
  }

  function getGraveState(grave) {
    return store.get(grave)
  }

  function setGraveRelationships(grave, graveRelationships) {
    relationships = relationships.set(grave, graveRelationships)
  }

  function getGraveRelationships(grave) {
    return relationships.get(grave)
  }
  
  function createGraveStateGetter(grave) {<commit_msg>Separating embed and reference transforms into different functions<commit_after>const { Map, List } = require('immutable')

const Store = () => {
  let store = Map({})
  let relationships = Map({})

  function _isRelationshipValid(relationship) {
    const [...props] = relationship.keys()
    const shape = ['field', 'mustReference', 'mustEmbed']
    const valid = shape.filter(prop => props.indexOf(prop) >= 0)
    
    return (valid.length === 2 && relationship.get('field'))
  }

  function _parseRelationship(relationship) {
    let pathFrom, pathTo, fieldFrom, fieldTo, type
    
    pathFrom = relationship.get('field').split('.')
    fieldFrom = pathFrom.pop()
    if (relationship.get('mustEmbed')) {
      type = "embed"
      pathTo = relationship.get('mustEmbed').split('.')
    } else {
      type = "reference"
      pathTo = relationship.get('mustReference').split('.')
    }
    fieldTo = pathTo.pop()
    
    return { type, pathFrom, fieldFrom, pathTo, fieldTo }
  }

  function _transformEmbed(grave, data, params) {
    // Dive into the origin collection...
    return data.updateIn([grave, ...params.pathFrom], collection => {
      // If collection isn't a list, return itself
      if (!List.isList(collection)) {
        return collection
      }
      // Maps collection
      return collection.map(documentFrom => {
        if (Map.isMap(documentFrom.get(params.fieldFrom))) {
          return documentFrom
        }
        // Return the document if, params there's a match
        const match = data.getIn(params.pathTo).find(documentTo => {
          return documentTo.get(params.fieldTo) === documentFrom.get(params.fieldFrom)
        })
        // If there's a match, embed the result in the field
        return match ? documentFrom.set(params.fieldFrom, match) : documentFrom
      })
    })
  }

  function _transformReference(grave, data, params) {
    
  }
  
  function _transform(grave, newState) {
    // First, change Grave store to state
    let newStore = store.set(grave, newState)
    if (relationships.has(grave)) {
      relationships.get(grave).forEach(relationship => {
        if (_isRelationshipValid(relationship)) {
          const rel = _parseRelationship(relationship)
          if (rel.type === 'embed') {
            newStore = _transformEmbed(grave, newStore, rel)
          } else {
            newStore = _transformReference(grave, newStore, rel)
          }
        }
      })
    }
    return newStore
  }
  
  function setGraveState(grave, newState) {
    store = _transform(grave, newState)
  }

  function getGraveState(grave) {
    return store.get(grave)
  }

  function setGraveRelationships(grave, graveRelationships) {
    relationships = relationships.set(grave, graveRelationships)
  }

  function getGraveRelationships(grave) {
    return relationships.get(grave)
  }
  
  function createGraveStateGetter(grave) {
{'fraction_non_alphanumeric': 0.12059402397566649, 'fraction_numerical': 0.0007156915369475756, 'mean_word_length': 2.55146124523507, 'pattern_counts': {'":': 0, '<': 3, '<?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': '449734', 'n_tokens_mistral': 1633, 'n_tokens_neox': 1549, 'n_words': 357}