<commit_before>import React from 'react';

import store from './store';
import logger, { formatBranchArgs } from './lib/log';

function subscribe({ local, paths }) {

  return Component => {

    const rootPath = [ 'subscriptions' ].concat( local ? [ 'local', Component.name ] : 'global' );

    return class Subscriber extends React.Component {

      subscription = null

      constructor( props ) {
        super( props );
        this.state = {};
      }

      componentWillMount = () => {
        this.subscriptions = paths.map( path => 
          store.subscribeTo( rootPath.concat( path ), this.onChange.bind( path ) )
        );
      }

      componentWillUnmount = () => this.subscriptions.forEach( store.unsubscribe )

      onChange = ( path, state ) => {
        /* eslint-disable no-console */
        const branch = formatBranchArgs( rootPath.concat( path ) );
        logger( `\uD83C\uDF00 <${Component.name || 'StatelessFunction'}> is re-rendering based on changes on branch: ${branch}` );
        this.setState({ [path]: state && state.toJS ? state.toJS() : state });
      }

      merge = ( path, val ) => {
        if ( typeof val !== 'object' ) {
          return this.replace( path, val );
        } else {
          const fullPath = rootPath.concat( path );
          const state = store.getState( fullPath );
          return store.setState( fullPath, state.mergeDeep( val ) );
        }
      }

      replace = ( path, val ) => store.setState( rootPath.concat( path ), val )

      methods = () => paths.reduce(( memo, path ) => ({
        ...memo,
        [path]: {
          get: () => this.state[ path ],
          set: val => this.merge( path, val ),
          replace: val => this.replace( path, val )
        }
      }), {})

      render = () => (
        <Component 
          { ...this.props } 
          { ...this.methods() }
        />
      )
    };
  };
}

export function local( ...paths ) {
  return subscribe({ local: true, paths });
}

export function global( ...paths ) {
  return subscribe({ local: false, paths });
}
<commit_msg>don't namespace global state so it's easier to access directly<commit_after>import React from 'react';

import store from './store';
import logger, { formatBranchArgs } from './lib/log';

function subscribe({ local, paths }) {

  return Component => {

    const rootPath = local ? [ 'local', Component.name ] : [];

    return class Subscriber extends React.Component {

      subscription = null

      constructor( props ) {
        super( props );
        this.state = {};
      }

      componentWillMount = () => {
        this.subscriptions = paths.map( path => 
          store.subscribeTo( rootPath.concat( path ), this.onChange.bind( path ) )
        );
      }

      componentWillUnmount = () => this.subscriptions.forEach( store.unsubscribe )

      onChange = ( path, state ) => {
        /* eslint-disable no-console */
        const branch = formatBranchArgs( rootPath.concat( path ) );
        logger( `\uD83C\uDF00 <${Component.name || 'StatelessFunction'}> is re-rendering based on changes on branch: ${branch}` );
        this.setState({ [path]: state && state.toJS ? state.toJS() : state });
      }

      merge = ( path, val ) => {
        if ( typeof val !== 'object' ) {
          return this.replace( path, val );
        } else {
          const fullPath = rootPath.concat( path );
          const state = store.getState( fullPath );
          return store.setState( fullPath, state.mergeDeep( val ) );
        }
      }

      replace = ( path, val ) => store.setState( rootPath.concat( path ), val )

      methods = () => paths.reduce(( memo, path ) => ({
        ...memo,
        [path]: {
          get: () => this.state[ path ],
          set: val => this.merge( path, val ),
          replace: val => this.replace( path, val )
        }
      }), {})

      render = () => (
        <Component 
          { ...this.props } 
          { ...this.methods() }
        />
      )
    };
  };
}

export function local( ...paths ) {
  return subscribe({ local: true, paths });
}

export function global( ...paths ) {
  return subscribe({ local: false, paths });
}

{'fraction_non_alphanumeric': 0.15423362916766611, 'fraction_numerical': 0.001918925401775006, 'mean_word_length': 2.0327272727272727, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 33, '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': '6912635', 'n_tokens_mistral': 1198, 'n_tokens_neox': 1173, 'n_words': 310}