<commit_before>import { ITabInstances, ITabData, ITabDataSave } from "../../types";
import { actions } from "../../actions";
import reducer from "../reducer";

import rootLogger from "../../logger";
const logger = rootLogger.child({ name: "reducers/tab-data" });

import { omit, each } from "underscore";

import staticTabData from "../../constants/static-tab-data";

const initialState: ITabInstances = {};

for (const tab of Object.keys(staticTabData)) {
  const page = staticTabData[tab];
  initialState[tab] = {
    history: [page],
    currentIndex: 0,
    data: {},
    sleepy: true,
  };
}

const emptyObj = {} as any;

let deepFields = ["users", "games", "collections", "web", "toast"];

function merge(
  a: ITabData,
  b: ITabData,
  { shallow }: { shallow: boolean }
): ITabData {
  if (shallow) {
    return { ...a, ...b };
  }

  const res = {
    ...a,
    ...b,
  };
  for (const df of deepFields) {
    res[df] = {
      ...(a[df] || emptyObj),
      ...(b[df] || emptyObj),
    };
  }
  return res;
}

export default reducer<ITabInstances>(initialState, on => {
  on(actions.tabDataFetched, (state, action) => {
    const { tab, data, shallow } = action.payload;
    const oldInstance = state[tab];
    if (!oldInstance) {
      // ignore fresh data for closed tabs
      logger.debug(`tabDataFetched, ignoring fresh data for ${tab}`);
      return state;
    }

    let newData = merge(oldInstance.data, data, { shallow });

    return {
      ...state,
      [tab]: {
        ...oldInstance,
        data: newData,
      },
    };
  });

  on(actions.evolveTab, (state, action) => {
    const { tab, data = emptyObj } = action.payload;
    let { url, resource, replace } = action.payload;

    const oldInstance = state[tab];
    if (!oldInstance) {
      // ignore fresh data for closed tabs
      return state;
    }

    let { history, currentIndex } = oldInstance;
    if (history[currentIndex].url === url) {
      replace = true;
    }

    if (/^collections\//.test(resource)) {
      url = `itch://${resource}`;
    }

    if (!resource) {
      // keep the resource in case it's not specified
      resource = history[currentIndex].resource;
    }
    if (replace) {<commit_msg>Mark tabs as non-sleepy after their first tabDataFetched<commit_after>import { ITabInstances, ITabData, ITabDataSave } from "../../types";
import { actions } from "../../actions";
import reducer from "../reducer";

import rootLogger from "../../logger";
const logger = rootLogger.child({ name: "reducers/tab-data" });

import { omit, each } from "underscore";

import staticTabData from "../../constants/static-tab-data";

const initialState: ITabInstances = {};

for (const tab of Object.keys(staticTabData)) {
  const page = staticTabData[tab];
  initialState[tab] = {
    history: [page],
    currentIndex: 0,
    data: {},
    sleepy: true,
  };
}

const emptyObj = {} as any;

let deepFields = ["users", "games", "collections", "web", "toast"];

function merge(
  a: ITabData,
  b: ITabData,
  { shallow }: { shallow: boolean }
): ITabData {
  if (shallow) {
    return { ...a, ...b };
  }

  const res = {
    ...a,
    ...b,
  };
  for (const df of deepFields) {
    res[df] = {
      ...(a[df] || emptyObj),
      ...(b[df] || emptyObj),
    };
  }
  return res;
}

export default reducer<ITabInstances>(initialState, on => {
  on(actions.tabDataFetched, (state, action) => {
    const { tab, data, shallow } = action.payload;
    const oldInstance = state[tab];
    if (!oldInstance) {
      // ignore fresh data for closed tabs
      logger.debug(`tabDataFetched, ignoring fresh data for ${tab}`);
      return state;
    }

    let newData = merge(oldInstance.data, data, { shallow });

    return {
      ...state,
      [tab]: {
        ...omit(oldInstance, "sleepy"),
        data: newData,
      },
    };
  });

  on(actions.evolveTab, (state, action) => {
    const { tab, data = emptyObj } = action.payload;
    let { url, resource, replace } = action.payload;

    const oldInstance = state[tab];
    if (!oldInstance) {
      // ignore fresh data for closed tabs
      return state;
    }

    let { history, currentIndex } = oldInstance;
    if (history[currentIndex].url === url) {
      replace = true;
    }

    if (/^collections\//.test(resource)) {
      url = `itch://${resource}`;
    }

    if (!resource) {
      // keep the resource in case it's not specified
      resource = history[currentIndex].resource;
    }
    if (replace) {
{'fraction_non_alphanumeric': 0.16506374412883024, 'fraction_numerical': 0.00044732721986132855, 'mean_word_length': 2.5776, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 11, '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': '2633370', 'n_tokens_mistral': 1457, 'n_tokens_neox': 1434, 'n_words': 384}