<commit_before>
import {Watcher} from "../reactors/watcher";
import rootLogger from "../logger";
const logger = rootLogger.child({name: "fetchers"});

import * as actions from "../actions";

import {Fetcher, FetchReason} from "../fetchers/types";
import {IStore} from "../types";
import DashboardFetcher from "../fetchers/dashboard-fetcher";
import CollectionsFetcher from "../fetchers/collections-fetcher";
import LibraryFetcher from "../fetchers/library-fetcher";

import GameFetcher from "../fetchers/game-fetcher";
import CollectionFetcher from "../fetchers/collection-fetcher";

const staticFetchers = {
  "dashboard": DashboardFetcher,
  "collections": CollectionsFetcher,
  "library": LibraryFetcher,
};

const pathFetchers = {
  "games": GameFetcher,
  "collections": CollectionFetcher,
};

let currentFetchers: any = {};
let waitingFor: {
  [key: string]: NodeJS.Timer;
} = {};

export async function queueFetch (store: IStore, tabId: string, reason: FetchReason) {
  if (waitingFor[tabId]) {
    clearTimeout(waitingFor[tabId]);
  }

  waitingFor[tabId] = setTimeout(() => {
    delete waitingFor[tabId];
    logger.info(tabId, reason, ", reloading.");

    const fetcherClass = getFetcherClass(store, tabId);
    if (!fetcherClass) {
      return;
    }

    const fetcher = new fetcherClass();
    currentFetchers[tabId] = fetcher;
    fetcher.hook(store, tabId, reason);
    fetcher.start();
    fetcher.emitter.on("done", () => {
      delete currentFetchers[tabId];
    });
  }, 50);
}

function getFetcherClass(store: IStore, tabId: string): typeof Fetcher {
  let staticFetcher = staticFetchers[tabId];
  if (staticFetcher) {
    return staticFetcher;
  }

  const path = store.getState().session.navigation.tabData[tabId].path;
  if (path) {
    const pathBase = path.substr(0, path.indexOf("/"));
    const pathFetcher = pathFetchers[pathBase];
    if (pathFetcher) {
      return pathFetcher;
    }
  }

  return null;
}

export default function (watcher: Watcher) {
  // changing tabs? it's a fetching
  watcher.on(actions.tabChanged, async (store, action) => {
    queueFetch(store, action.payload.id, "tab-changed");
  });

  // tab navigated to something else? let's fetch
  watcher.on(actions.tabEvolved, async (store, action) => {
    queueFetch(store, action.payload.id, "tab-evolved");
  });
<commit_msg>Try different strategies<commit_after>
import {Watcher} from "../reactors/watcher";
import rootLogger from "../logger";
const logger = rootLogger.child({name: "fetchers"});

import * as actions from "../actions";

import {Fetcher, FetchReason} from "../fetchers/types";
import {IStore} from "../types";
import DashboardFetcher from "../fetchers/dashboard-fetcher";
import CollectionsFetcher from "../fetchers/collections-fetcher";
import LibraryFetcher from "../fetchers/library-fetcher";

import GameFetcher from "../fetchers/game-fetcher";
import CollectionFetcher from "../fetchers/collection-fetcher";

const staticFetchers = {
  "dashboard": DashboardFetcher,
  "collections": CollectionsFetcher,
  "library": LibraryFetcher,
};

const pathFetchers = {
  "games": GameFetcher,
  "collections": CollectionFetcher,
};

let fetching: {
  [key: string]: boolean;
} = {};

let nextFetchReason: {
  [key: string]: FetchReason;
} = {};

export async function queueFetch (store: IStore, tabId: string, reason: FetchReason) {
  if (fetching[tabId]) {
    nextFetchReason[tabId] = reason;
    return;
  }

  fetching[tabId] = true;

  const fetcherClass = getFetcherClass(store, tabId);
  if (!fetcherClass) {
    return;
  }

  const fetcher = new fetcherClass();
  fetcher.hook(store, tabId, reason);

  fetcher.emitter.on("done", () => {
    delete fetching[tabId];

    const nextReason = nextFetchReason[tabId];
    if (nextReason) {
      delete nextFetchReason[tabId];
      queueFetch(store, tabId, nextReason);
    }
  });

  fetcher.start();
}

function getFetcherClass(store: IStore, tabId: string): typeof Fetcher {
  let staticFetcher = staticFetchers[tabId];
  if (staticFetcher) {
    return staticFetcher;
  }

  const path = store.getState().session.navigation.tabData[tabId].path;
  if (path) {
    const pathBase = path.substr(0, path.indexOf("/"));
    const pathFetcher = pathFetchers[pathBase];
    if (pathFetcher) {
      return pathFetcher;
    }
  }

  return null;
}

export default function (watcher: Watcher) {
  // changing tabs? it's a fetching
  watcher.on(actions.tabChanged, async (store, action) => {
    queueFetch(store, action.payload.id, "tab-changed");
  });

  // tab navigated to something else? let's fetch
  watcher.on(actions.tabEvolved, async (store, action) => {
    queueFetch(store, action.payload.id, "tab-evolved");
  });

{'fraction_non_alphanumeric': 0.1451063829787234, 'fraction_numerical': 0.000851063829787234, 'mean_word_length': 4.148959474260679, 'pattern_counts': {'":': 10, '<': 3, '<?xml version=': 0, '>': 10, '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': '4530924', 'n_tokens_mistral': 1508, 'n_tokens_neox': 1531, 'n_words': 354}