<commit_before>import { createElement, Component } from 'react';

const PAGINATION = {
  TYPE: {
    OFFSET_AND_LIMIT: 'offsetAndLimit'
  },
  MODE: {
    INFINITE: 'infinite'
  },
  PRESET: {
    infiniteOffsetAndLimit: (initialSize, nextSize = initialSize) => ({
      type: PAGINATION.TYPE.OFFSET_AND_LIMIT,
      mode: PAGINATION.MODE.INFINITE,
      getNextPage: ({ limit, offset }) => {
        if (offset === null) {
          return { offset: 0, limit: initialSize };
        }
        return { offset: offset + limit, limit: nextSize };
      }
    })
  }
};

class Retriever {
  constructor({ type, name, getter, getProps, publishData, publishError }) {
    this.type = type;
    this.name = name;
    this.getter = getter;
    this.getProps = getProps;
    this.publishData = publishData;
    this.publishError = publishError;
  }

  get() {
    const promise = this.getter(this.getProps());
    if (!promise || !promise.then) {
      throw new Error(`${this.type} for ${this.name} did not return a promise!`);
    }
    return promise.then(this.publishData, this.publishError);
  }

  // eslint-disable-next-line class-methods-use-this
  mergeProps(props) {
    return props;
  }

  // eslint-disable-next-line class-methods-use-this
  onDestroy() {}
}

class ResolveRetriever extends Retriever {
  constructor(args) {
    super({ type: 'resolve', ...args });
  }
}

class ObserveRetriever extends Retriever {
  constructor(args) {
    super({ type: 'observe', ...args });

    this.subscription = null;
  }

  get() {
    const observable = this.getter(this.getProps());
    if (!observable || !observable) {
      throw new Error(`${this.type} for ${this.name} did not expose a subscribe function`);
    }
    this.subscription = observable.subscribe(this.publishData, this.publishError);
    return Promise.resolve();
  }

  onDestroy() {
    if (this.subscription && this.subscription.unsubscribe) {
      this.subscription.unsubscribe();
    }
  }
}

const mergePaginateProps = (props, name, obj) => ({
  ...props,
  paginate: {
    ...props.paginate,
    [name]: obj
  }
});

class PaginatedInfiniteOffsetAndLimitResolveRetriever extends Retriever {
  constructor({ pagerConfig, ...args }) {
    super({ type: 'resolve paginated', ...args });
    this.pagerConfig = pagerConfig;

    this.pagers = [];

    this.queueNext();
  }

  get() {
    const props = this.getProps();
    return Promise.all(this.pagers.map((pager) => this.getter(props, pager))).then(
      (lists) => this.publishData(lists.reduce((mem, list) => [...mem, ...list], [])),
      this.publishError
    );
  }

  queueNext() {
    const prevPager = this.pagers[this.pagers.length - 1] || { limit: null, offset: null };
    const nextPager = this.pagerConfig.getNextPage(prevPager);
    this.pagers.push(nextPager);
  }

  mergeProps(props) {
    return mergePaginateProps(props, this.name, {
      getNext: () => {
        this.queueNext();
        return this.get();
      }
    });
  }
}

class PaginatedInfiniteOffsetAndLimitObserveRetriever extends Retriever {
  constructor({ pagerConfig, ...args }) {
    super({ type: 'observe paginated', ...args });
    this.pagerConfig = pagerConfig;

    this.pagerSubscriptions = [];

    this.queueNext();
  }

  get() {
    const props = this.getProps();
    const tryToPublish = () => {
      const result = [];
      for (let i = 0; i < this.pagerSubscriptions.length; i++) {
        const p = this.pagerSubscriptions[i];
        if (!p.data) {
          return;
        }
        result.push(...p.data);
      }
      this.publishData(result);
    };
    this.pagerSubscriptions = this.pagerSubscriptions.map((p) => {
      if (!p.subscription) {
        p.subscription = this.getter(props, p.pager).subscribe(
          (data) => { p.data = data; tryToPublish(); },
          this.publishError
        );
      }
      return p;
    });
    return Promise.resolve();
  }

  queueNext() {
    const pagers = this.pagerSubscriptions.map((p) => p.pager);
    const prevPager = pagers[pagers.length - 1] || { limit: null, offset: null };
    const nextPager = this.pagerConfig.getNextPage(prevPager);
    const p = {
      pager: nextPager,
      subscription: null,
      data: null,
      error: null
    };
    this.pagerSubscriptions.push(p);
  }

  mergeProps(props) {
    return mergePaginateProps(props, this.name, {
      getNext: () => {
        this.queueNext();<commit_msg>feat(with-data) Extract method for readability<commit_after>import { createElement, Component } from 'react';

const PAGINATION = {
  TYPE: {
    OFFSET_AND_LIMIT: 'offsetAndLimit'
  },
  MODE: {
    INFINITE: 'infinite'
  },
  PRESET: {
    infiniteOffsetAndLimit: (initialSize, nextSize = initialSize) => ({
      type: PAGINATION.TYPE.OFFSET_AND_LIMIT,
      mode: PAGINATION.MODE.INFINITE,
      getNextPage: ({ limit, offset }) => {
        if (offset === null) {
          return { offset: 0, limit: initialSize };
        }
        return { offset: offset + limit, limit: nextSize };
      }
    })
  }
};

class Retriever {
  constructor({ type, name, getter, getProps, publishData, publishError }) {
    this.type = type;
    this.name = name;
    this.getter = getter;
    this.getProps = getProps;
    this.publishData = publishData;
    this.publishError = publishError;
  }

  get() {
    const promise = this.getter(this.getProps());
    if (!promise || !promise.then) {
      throw new Error(`${this.type} for ${this.name} did not return a promise!`);
    }
    return promise.then(this.publishData, this.publishError);
  }

  // eslint-disable-next-line class-methods-use-this
  mergeProps(props) {
    return props;
  }

  // eslint-disable-next-line class-methods-use-this
  onDestroy() {}
}

class ResolveRetriever extends Retriever {
  constructor(args) {
    super({ type: 'resolve', ...args });
  }
}

class ObserveRetriever extends Retriever {
  constructor(args) {
    super({ type: 'observe', ...args });

    this.subscription = null;
  }

  get() {
    const observable = this.getter(this.getProps());
    if (!observable || !observable) {
      throw new Error(`${this.type} for ${this.name} did not expose a subscribe function`);
    }
    this.subscription = observable.subscribe(this.publishData, this.publishError);
    return Promise.resolve();
  }

  onDestroy() {
    if (this.subscription && this.subscription.unsubscribe) {
      this.subscription.unsubscribe();
    }
  }
}

const mergePaginateProps = (props, name, obj) => ({
  ...props,
  paginate: {
    ...props.paginate,
    [name]: obj
  }
});

class PaginatedInfiniteOffsetAndLimitResolveRetriever extends Retriever {
  constructor({ pagerConfig, ...args }) {
    super({ type: 'resolve paginated', ...args });
    this.pagerConfig = pagerConfig;

    this.pagers = [];

    this.queueNext();
  }

  get() {
    const props = this.getProps();
    return Promise.all(this.pagers.map((pager) => this.getter(props, pager))).then(
      (lists) => this.publishData(lists.reduce((mem, list) => [...mem, ...list], [])),
      this.publishError
    );
  }

  queueNext() {
    const prevPager = this.pagers[this.pagers.length - 1] || { limit: null, offset: null };
    const nextPager = this.pagerConfig.getNextPage(prevPager);
    this.pagers.push(nextPager);
  }

  mergeProps(props) {
    return mergePaginateProps(props, this.name, {
      getNext: () => {
        this.queueNext();
        return this.get();
      }
    });
  }
}

class PaginatedInfiniteOffsetAndLimitObserveRetriever extends Retriever {
  constructor({ pagerConfig, ...args }) {
    super({ type: 'observe paginated', ...args });
    this.pagerConfig = pagerConfig;

    this.pagerSubscriptions = [];

    this.queueNext();
  }

  get() {
    const props = this.getProps();
    this.pagerSubscriptions = this.pagerSubscriptions.map((p) => {
      if (!p.subscription) {
        p.subscription = this.getter(props, p.pager).subscribe(
          (data) => { p.data = data; this.tryToPublish(); },
          this.publishError
        );
      }
      return p;
    });
    return Promise.resolve();
  }

  queueNext() {
    const pagers = this.pagerSubscriptions.map((p) => p.pager);
    const prevPager = pagers[pagers.length - 1] || { limit: null, offset: null };
    const nextPager = this.pagerConfig.getNextPage(prevPager);
    const p = {
      pager: nextPager,
      subscription: null,
      data: null,
      error: null
    };
    this.pagerSubscriptions.push(p);
  }

  tryToPublish() {
    const result = [];
    for (let i = 0; i < this.pagerSubscriptions.length; i++) {
      const p = this.pagerSubscriptions[i];
      if (!p.data) {
        return;
      }
      result.push(...p.data);
    }
    this.publishData(result);
  }

  mergeProps(props) {
    return mergePaginateProps(props, this.name, {
      getNext: () => {
        this.queueNext();
{'fraction_non_alphanumeric': 0.15061058344640435, 'fraction_numerical': 0.0009045680687471732, 'mean_word_length': 2.7352195945945947, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 26, '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': '1045682', 'n_tokens_mistral': 2906, 'n_tokens_neox': 2881, 'n_words': 572}