<commit_before>import _ from 'lodash'
import { createElement, Component } from 'react'
import createReactContext from 'create-react-context'

import bitsObserver from './bitsObserver'
import createDb from '../db'
import { createBatchMemoizer } from '../cache-util'

const createDatavanContext = config => {
  const { calcChangedBits, getObservedBits } = bitsObserver(config)
  const { Provider, Consumer } = createReactContext(null, calcChangedBits)

  class VanProvider extends Component {
    constructor(props) {
      super(props)
      // TODO may pass upper provider db instead of config here
      let db = props.db || createDb(config)
      if (props.initDb) db = props.initDb(db)
      this.state = db
    }
    componentDidMount() {
      this.unsubscribe = this.state.subscribe(change => this.setState(change))
    }
    componentWillUnmount() {
      this.unsubscribe()
    }
    render() {
      return createElement(Provider, { value: this.state }, this.props.children)
    }
  }

  /* eslint-disable react/no-multi-comp */
  class VanConsumer extends Component {
    // state = { setState: this.setState } // eslint-disable-line react/no-unused-state

    // eslint-disable-next-line
    UNSAFE_componentWillReceiveProps(nextProps) {
      if (this.props.observe !== nextProps.observe) {
        this.observedBits = getObservedBits(nextProps.observe)
      }
    }

    observedBits = getObservedBits(this.props.observe)

    memoizer = createBatchMemoizer({
      onSuccess: () => this.setState({ cacheAt: Date.now() }), // eslint-disable-line react/no-unused-state
    })

    render() {
      const { props } = this
      return createElement(
        Consumer,
        {
          ...props,
          observedBits: this.observedBits,
        },
        db => props.children(this.memoizer.newBatch(db))
      )
    }
  }

  Object.assign(VanConsumer, {
    Provider: VanProvider,
    config,

    hoc: (propKeys, mapFunc) => {
      if (!mapFunc) return BaseComponent => BaseComponent
      propKeys = _.uniq(_.compact(propKeys))

      return BaseComponent => props =>
        createElement(VanConsumer, props, db => {
          const dataProps = db.memoize(mapFunc, _.pick(props, propKeys), props)
          return createElement(BaseComponent, { ...props, db, ...dataProps })
        })
    },
  })

  return VanConsumer
}

export default createDatavanContext<commit_msg>fix: hoc still pass db if no propKeys or mapFunc<commit_after>import _ from 'lodash'
import { createElement, Component } from 'react'
import createReactContext from 'create-react-context'

import bitsObserver from './bitsObserver'
import createDb from '../db'
import { createBatchMemoizer } from '../cache-util'

const createDatavanContext = config => {
  const { calcChangedBits, getObservedBits } = bitsObserver(config)
  const { Provider, Consumer } = createReactContext(null, calcChangedBits)

  class VanProvider extends Component {
    constructor(props) {
      super(props)
      // TODO may pass upper provider db instead of config here
      let db = props.db || createDb(config)
      if (props.initDb) db = props.initDb(db)
      this.state = db
    }
    componentDidMount() {
      this.unsubscribe = this.state.subscribe(change => this.setState(change))
    }
    componentWillUnmount() {
      this.unsubscribe()
    }
    render() {
      return createElement(Provider, { value: this.state }, this.props.children)
    }
  }

  /* eslint-disable react/no-multi-comp */
  class VanConsumer extends Component {
    // state = { setState: this.setState } // eslint-disable-line react/no-unused-state

    // eslint-disable-next-line
    UNSAFE_componentWillReceiveProps(nextProps) {
      if (this.props.observe !== nextProps.observe) {
        this.observedBits = getObservedBits(nextProps.observe)
      }
    }

    observedBits = getObservedBits(this.props.observe)

    memoizer = createBatchMemoizer({
      onSuccess: () => this.setState({ cacheAt: Date.now() }), // eslint-disable-line react/no-unused-state
    })

    render() {
      const { props } = this
      return createElement(
        Consumer,
        {
          ...props,
          observedBits: this.observedBits,
        },
        db => props.children(this.memoizer.newBatch(db))
      )
    }
  }

  Object.assign(VanConsumer, {
    Provider: VanProvider,
    config,

    hoc: (propKeys, mapFunc) => {
      propKeys = _.uniq(_.compact(propKeys))
      return BaseComponent => props =>
        createElement(VanConsumer, props, db => {
          const dataProps = mapFunc && db.memoize(mapFunc, _.pick(props, propKeys), props)
          return createElement(BaseComponent, { ...props, db, ...dataProps })
        })
    },
  })

  return VanConsumer
}

export default createDatavanContext
{'fraction_non_alphanumeric': 0.11868316208848816, 'fraction_numerical': 0.0, 'mean_word_length': 2.8190552441953565, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 20, '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': '5551016', 'n_tokens_mistral': 1415, 'n_tokens_neox': 1386, 'n_words': 304}