<commit_before>var react = require('react')
  , pellet = require('./pellet')
  , utils = require('./utils')
  , isolator = require('./isolator')
  , pipeline = require('./isomorphic/pipeline');

// options.context options.mode=MODE_HTML, options.dom =

var pelletRender = module.exports = {
  MODE_STRING: 'static',
  MODE_HTML: 'markup',
  MODE_DOM: 'dom',

  /**
   * Render the component for both the server and browser
   *
   * @param component
   * @param options (mode: targetEl:, context: or props:)
   * @param next
   */
  renderComponent: function(component, options, next) {
    if(typeof options == 'function') {
      next = options;
      options = {};
    } else if(!options) {
      options = {};
    }

    if(!component || !next) {
      throw new Error('the component and next are required')
    }

    // default the mode using the environment so if in browser use
    // DOM render else render full html with react-ids
    if(!options.mode) {
      if(process.env.BROWSER_ENV) {
        options.mode = pelletRender.MODE_DOM;
      } else {
        options.mode = pelletRender.MODE_HTML;
      }
    }

    var instrument = pellet.instrumentation.namespace('isorender.');
    var mesure = instrument.elapseTimer();
    instrument.increment('isorender.count');

    function renderReactComponent(component, ctx) {
      var result;

      try {
        if(options.mode == pelletRender.MODE_DOM && process.env.BROWSER_ENV) {
          if(!options.targetEl) {
            options.targetEl = document.getElementById('__PELLET__');
            if(!options.targetEl) {
              options.targetEl = document.body;
            }
          }

          react.unmountComponentAtNode(options.targetEl);
          mesure.mark('react_unmount');

          // only add touch events if the device support it
          if ('ontouchstart' in document.documentElement) {
            react.initializeTouchEvents(true);
          }

          result = react.render(component, options.targetEl);
        } else if(options.mode == pelletRender.MODE_STRING) {
          result = react.renderToStaticMarkup(component);
        } else if(options.mode == pelletRender.MODE_HTML) {
          result = react.renderToString(component);
        }

        mesure.mark('react_render');
      } catch(ex) {
        next(ex);
        pellet.instrumentation.increment('isorender.error');
        return;
      }

      next(null, result, ctx);

      // update the cache with the latest render markup (if needed)
      ctx.updateCache(result, function(err) {
        if(err) {
          pellet.instrumentation.increment('isorender.cacheUpdateError');
          console.error('Cannot update cache key', ctx.$.cacheKey, 'because:', err.message||err);
          return;
        }

        instrument.increment('isorender.cacheUpdate');
      });
    }

    function cacheHitFn(html, ctx) {
      pellet.instrumentation.increment('isorender.cacheHit');
      next(null, html, {toJSON:function() {return ctx;}});

      // we do not want to send 2 responses
      // so no op the next call
      next = utils.noop;
    }

    var componentWithContext;

    // get the serialize state if component has a onRoute function
    if (component._$construction) {<commit_msg>fix: for non pipeline renders we need to skip the caching layer<commit_after>var react = require('react')
  , pellet = require('./pellet')
  , utils = require('./utils')
  , isolator = require('./isolator')
  , pipeline = require('./isomorphic/pipeline');

// options.context options.mode=MODE_HTML, options.dom =

var pelletRender = module.exports = {
  MODE_STRING: 'static',
  MODE_HTML: 'markup',
  MODE_DOM: 'dom',

  /**
   * Render the component for both the server and browser
   *
   * @param component
   * @param options (mode: targetEl:, context: or props:)
   * @param next
   */
  renderComponent: function(component, options, next) {
    if(typeof options == 'function') {
      next = options;
      options = {};
    } else if(!options) {
      options = {};
    }

    if(!component || !next) {
      throw new Error('the component and next are required')
    }

    // default the mode using the environment so if in browser use
    // DOM render else render full html with react-ids
    if(!options.mode) {
      if(process.env.BROWSER_ENV) {
        options.mode = pelletRender.MODE_DOM;
      } else {
        options.mode = pelletRender.MODE_HTML;
      }
    }

    var instrument = pellet.instrumentation.namespace('isorender.');
    var mesure = instrument.elapseTimer();
    instrument.increment('isorender.count');

    function renderReactComponent(component, ctx) {
      var result;

      try {
        if(options.mode == pelletRender.MODE_DOM && process.env.BROWSER_ENV) {
          if(!options.targetEl) {
            options.targetEl = document.getElementById('__PELLET__');
            if(!options.targetEl) {
              options.targetEl = document.body;
            }
          }

          react.unmountComponentAtNode(options.targetEl);
          mesure.mark('react_unmount');

          // only add touch events if the device support it
          if ('ontouchstart' in document.documentElement) {
            react.initializeTouchEvents(true);
          }

          result = react.render(component, options.targetEl);
        } else if(options.mode == pelletRender.MODE_STRING) {
          result = react.renderToStaticMarkup(component);
        } else if(options.mode == pelletRender.MODE_HTML) {
          result = react.renderToString(component);
        }

        mesure.mark('react_render');
      } catch(ex) {
        next(ex);
        pellet.instrumentation.increment('isorender.error');
        return;
      }

      next(null, result, ctx);

      // update the cache with the latest render markup (if needed)
      // requires a pipeline else we can not cache pages
      if(ctx.updateCache) {
        ctx.updateCache(result, function (err) {
          if (err) {
            pellet.instrumentation.increment('isorender.cacheUpdateError');
            console.error('Cannot update cache key', ctx.$.cacheKey, 'because:', err.message || err);
            return;
          }

          instrument.increment('isorender.cacheUpdate');
        });
      }
    }

    function cacheHitFn(html, ctx) {
      pellet.instrumentation.increment('isorender.cacheHit');
      next(null, html, {toJSON:function() {return ctx;}});

      // we do not want to send 2 responses
      // so no op the next call
      next = utils.noop;
    }

    var componentWithContext;

    // get the serialize state if component has a onRoute function
    if (component._$construction) {
{'fraction_non_alphanumeric': 0.11965811965811966, 'fraction_numerical': 0.000299895036737142, 'mean_word_length': 2.4523809523809526, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, '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': '4687802', 'n_tokens_mistral': 1920, 'n_tokens_neox': 1863, 'n_words': 450}