<commit_before>import { FloodgateProps, FloodgateState } from "./types";
import "regenerator-runtime/runtime";
import * as React from "react";
import * as PropTypes from "prop-types";
import { generator } from "./functions";

const initGeneratorSymbol = Symbol.for("initGenerator");

class Floodgate extends React.Component<FloodgateProps, FloodgateState> {
  // types
  data: Array<any>;
  queue: Generator | null;
  state: FloodgateState;

  // static props
  static propTypes = {
    children: PropTypes.func,
    data: PropTypes.array.isRequired,
    initial: PropTypes.number,
    increment: PropTypes.number,
    saveStateOnUnmount: PropTypes.bool,
    exportState: PropTypes.func,
    onLoadNext: PropTypes.func,
    onLoadComplete: PropTypes.func,
    onReset: PropTypes.func
  };
  static defaultProps = {
    initial: 5,
    increment: 5,
    saveStateOnUnmount: true
  };

  // methods
  constructor(props: FloodgateProps) {
    super(props);
    const { data, increment, initial } = props;
    this.queue = null;
    this.data = data;
    this.state = {
      items: this.data,
      renderedItems: [],
      currentIndex: 0,
      allItemsRendered: false,
      prevProps: {
        data,
        increment,
        initial
      }
    };
    this[initGeneratorSymbol] = this[initGeneratorSymbol].bind(this);
    this.loadAll = this.loadAll.bind(this);
    this.loadNext = this.loadNext.bind(this);
    this.reset = this.reset.bind(this);
    this.saveState = this.saveState.bind(this);
    this[initGeneratorSymbol](
      this.state.items,
      this.props.increment,
      this.props.initial
    );
  }
  [initGeneratorSymbol](items, increment, initial) {
    this.queue = generator(items, increment, initial);
  }
  componentDidMount(): void {
    this.loadNext({ silent: true });
  }
  componentDidUpdate(prevProps, prevState): void {
    const { data, increment, initial } = this.props;
    if (this.props !== prevProps) {
      this[initGeneratorSymbol](
        data.slice(prevState.currentIndex, data.length),
        increment,
        increment
      );
      const items = data;
      this.setState(() => ({
        items,
        allItemsRendered: items.length === prevState.renderedItems.length
      }));
    }
  }
  componentWillUnmount(): void {
    // Prevent unwanted cacheing by setting saveStateOnUnmount to false
    this.props.saveStateOnUnmount && this.saveState();
  }
  reset({ callback }: { callback?: Function } = {}): void {
    this.queue = generator(this.data, this.props.increment, this.props.initial);
    this.setState(
      prevState => ({
        renderedItems: [],
        allItemsRendered: false
      }),
      () => {
        this.loadNext({ silent: true, callback });
        this.props.onReset && this.props.onReset(this.state);
      }
    );
  }
  loadAll(
    {
      callback,
      suppressWarning
    }: { callback?: Function, suppressWarning: boolean } = {
      suppressWarning: false
    }
  ): void {
    !this.state.allItemsRendered
      ? this.setState(
          prevState => {
            return {
              renderedItems: this.data,
              allItemsRendered: true
            };
          },
          () => {
            callback && callback(this.state);
            this.props.onLoadComplete && this.props.onLoadComplete(this.state);
          }<commit_msg>loadAll updates currentIndex, reset adds support for explicit initial value in generator re-init<commit_after>import { FloodgateProps, FloodgateState } from "./types";
import "regenerator-runtime/runtime";
import * as React from "react";
import * as PropTypes from "prop-types";
import { generator } from "./functions";

const initGeneratorSymbol = Symbol.for("initGenerator");

class Floodgate extends React.Component<FloodgateProps, FloodgateState> {
  // types
  data: Array<any>;
  queue: Generator | null;
  state: FloodgateState;

  // static props
  static propTypes = {
    children: PropTypes.func,
    data: PropTypes.array.isRequired,
    initial: PropTypes.number,
    increment: PropTypes.number,
    saveStateOnUnmount: PropTypes.bool,
    exportState: PropTypes.func,
    onLoadNext: PropTypes.func,
    onLoadComplete: PropTypes.func,
    onReset: PropTypes.func
  };
  static defaultProps = {
    initial: 5,
    increment: 5,
    saveStateOnUnmount: true
  };

  // methods
  constructor(props: FloodgateProps) {
    super(props);
    const { data, increment, initial } = props;
    this.queue = null;
    this.data = data;
    this.state = {
      items: this.data,
      renderedItems: [],
      currentIndex: 0,
      allItemsRendered: false,
      prevProps: {
        data,
        increment,
        initial
      }
    };
    this[initGeneratorSymbol] = this[initGeneratorSymbol].bind(this);
    this.loadAll = this.loadAll.bind(this);
    this.loadNext = this.loadNext.bind(this);
    this.reset = this.reset.bind(this);
    this.saveState = this.saveState.bind(this);
    this[initGeneratorSymbol](
      this.props.data,
      this.props.increment,
      this.props.initial
    );
  }
  [initGeneratorSymbol](data, increment, initial) {
    this.queue = generator(data, increment, initial);
  }
  componentDidMount(): void {
    this.loadNext({ silent: true });
  }
  componentDidUpdate(prevProps, prevState): void {
    const { data, increment } = this.props;
    if (this.props !== prevProps) {
      this[initGeneratorSymbol](
        data.slice(prevState.currentIndex, data.length),
        increment,
        increment
      );
      const items = data;
      this.setState(() => ({
        items,
        allItemsRendered: items.length === prevState.renderedItems.length
      }));
    }
  }
  componentWillUnmount(): void {
    // Prevent unwanted cacheing by setting saveStateOnUnmount to false
    this.props.saveStateOnUnmount && this.saveState();
  }
  reset({
    initial,
    callback
  }: { initial?: number, callback?: Function } = {}): void {
    this[initGeneratorSymbol](
      this.data,
      this.props.increment,
      typeof initial !== "undefined" ? initial : this.props.initial
    );

    this.setState(
      prevState => ({
        renderedItems: [],
        allItemsRendered: false,
        prevProps: {
          ...prevState.prevProps,
          initial: typeof initial !== "undefined" ? initial : this.props.initial
        }
      }),
      () => {
        this.loadNext({ silent: true, callback });
        this.props.onReset && this.props.onReset(this.state);
      }
    );
  }
  loadAll(
    {
      callback,
      suppressWarning
    }: { callback?: Function, suppressWarning: boolean } = {
      suppressWarning: false
    }
  ): void {
    !this.state.allItemsRendered
      ? this.setState(
          prevState => {
            return {
              renderedItems: this.data,
              currentIndex: this.data.length,
              allItemsRendered: true
            };
          },
          () => {
            callback && callback(this.state);
            this.props.onLoadComplete && this.props.onLoadComplete(this.state);
          }
{'fraction_non_alphanumeric': 0.12205840657782818, 'fraction_numerical': 0.0008505812305075135, 'mean_word_length': 2.531031031031031, 'pattern_counts': {'":': 0, '<': 7, '<?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': '3983879', 'n_tokens_mistral': 2040, 'n_tokens_neox': 2044, 'n_words': 420}