<commit_before>import FontFaceObserver from "fontfaceobserver-es";

import {
  BodyMethod,
  LoadItem,
  LoadedValue,
  LoadedXMLValue,
  LoaderKey,
  LoaderValue,
} from "./types.js";

const isSafari = navigator && navigator.userAgent.indexOf("Safari") > -1;

/**
 * AsyncPreloader: assets preloader using ES2017 async/await and fetch.
 *
 * It exports an instance of itself as default so you can:
 *
 * ```js
 * import Preloader from "async-preloader";
 *
 * await Preloader.loadItems([]);
 * ```
 *
 * to use directly as a singleton or
 *
 * ```js
 * import { AsyncPreloader as Preloader } from "async-preloader";
 *
 * const preloader = new Preloader();
 * await preloader.loadItems([]);
 * ```
 * if you need more than one instance.
 */
class AsyncPreloader {
  // Properties
  /**
   * Object that contains the loaded items
   */
  public items: Map<string, LoadedValue> = new Map();

  /**
   * Default body method to be called on the Response from fetch if no body option is specified on the LoadItem
   */
  public defaultBodyMethod: BodyMethod = "blob";

  /**
   * Default loader to use if no loader key is specified in the [[LoadItem]] or if the extension doesn't match any of the [[AsyncPreloader.loaders]] extensions
   */
  public defaultLoader: LoaderKey = LoaderKey.Text;

  /**
   * Loader types and the extensions they handle
   *
   * Allows the omission of the loader key in a [[LoadItem.loader]] for some generic extensions
   */
  private static loaders: Map<LoaderKey, LoaderValue> = new Map()
    .set(LoaderKey.Text, { extensions: ["txt"] })
    .set(LoaderKey.Json, { extensions: ["json"] })
    .set(LoaderKey.Image, { extensions: ["jpeg", "jpg", "gif", "png", "webp"] })
    .set(LoaderKey.Video, { extensions: ["webm", "ogg", "mp4"] })
    .set(LoaderKey.Audio, { extensions: ["webm", "ogg", "mp3", "wav", "flac"] })
    .set(LoaderKey.Xml, {
      extensions: ["xml", "svg", "html"],
      mimeType: {
        xml: "text/xml",
        svg: "image/svg+xml",
        html: "text/html",
      },
      defaultMimeType: "text/xml",
    })
    .set(LoaderKey.Font, {
      extensions: ["woff2", "woff", "ttf", "otf", "eot"],
    });

  /**
   * DOMParser instance for the XML loader
   */
  private static domParser = new DOMParser();

  // API
  /**
   * Load the specified manifest (array of items)
   *
   * @param {LoadItem[]} items Items to load
   * @returns {Promise<LoadedValue[]>} Resolve when all items are loaded, reject for any error
   */
  public loadItems = async (items: LoadItem[]): Promise<LoadedValue[]> => {
    return await Promise.all(items.map(this.loadItem));
  };

  /**
   * Load a single item
   *
   * @param {LoadItem} item Item to load
   * @returns {Promise<LoadedValue>} Resolve when item is loaded, reject for any error
   */
  public loadItem = async (item: LoadItem): Promise<LoadedValue> => {
    const extension: string = AsyncPreloader.getFileExtension(item.src);
    const loaderKey: LoaderKey =
      item.loader || AsyncPreloader.getLoaderKey(extension);

    const loadedItem: LoadedValue = await this[`load` + loaderKey](item);

    this.items.set((item.id || item.src) as string, loadedItem);
<commit_msg>fix: enhance node support by checking for navigator and DOMParser<commit_after>import FontFaceObserver from "fontfaceobserver-es";

import {
  BodyMethod,
  LoadItem,
  LoadedValue,
  LoadedXMLValue,
  LoaderKey,
  LoaderValue,
} from "./types.js";

const isSafari =
  typeof navigator !== "undefined" &&
  navigator &&
  navigator.userAgent.indexOf("Safari") > -1;

/**
 * AsyncPreloader: assets preloader using ES2017 async/await and fetch.
 *
 * It exports an instance of itself as default so you can:
 *
 * ```js
 * import Preloader from "async-preloader";
 *
 * await Preloader.loadItems([]);
 * ```
 *
 * to use directly as a singleton or
 *
 * ```js
 * import { AsyncPreloader as Preloader } from "async-preloader";
 *
 * const preloader = new Preloader();
 * await preloader.loadItems([]);
 * ```
 * if you need more than one instance.
 */
class AsyncPreloader {
  // Properties
  /**
   * Object that contains the loaded items
   */
  public items: Map<string, LoadedValue> = new Map();

  /**
   * Default body method to be called on the Response from fetch if no body option is specified on the LoadItem
   */
  public defaultBodyMethod: BodyMethod = "blob";

  /**
   * Default loader to use if no loader key is specified in the [[LoadItem]] or if the extension doesn't match any of the [[AsyncPreloader.loaders]] extensions
   */
  public defaultLoader: LoaderKey = LoaderKey.Text;

  /**
   * Loader types and the extensions they handle
   *
   * Allows the omission of the loader key in a [[LoadItem.loader]] for some generic extensions
   */
  private static loaders: Map<LoaderKey, LoaderValue> = new Map()
    .set(LoaderKey.Text, { extensions: ["txt"] })
    .set(LoaderKey.Json, { extensions: ["json"] })
    .set(LoaderKey.Image, { extensions: ["jpeg", "jpg", "gif", "png", "webp"] })
    .set(LoaderKey.Video, { extensions: ["webm", "ogg", "mp4"] })
    .set(LoaderKey.Audio, { extensions: ["webm", "ogg", "mp3", "wav", "flac"] })
    .set(LoaderKey.Xml, {
      extensions: ["xml", "svg", "html"],
      mimeType: {
        xml: "text/xml",
        svg: "image/svg+xml",
        html: "text/html",
      },
      defaultMimeType: "text/xml",
    })
    .set(LoaderKey.Font, {
      extensions: ["woff2", "woff", "ttf", "otf", "eot"],
    });

  /**
   * DOMParser instance for the XML loader
   */
  private static domParser =
    typeof DOMParser !== "undefined" && new DOMParser();

  // API
  /**
   * Load the specified manifest (array of items)
   *
   * @param {LoadItem[]} items Items to load
   * @returns {Promise<LoadedValue[]>} Resolve when all items are loaded, reject for any error
   */
  public loadItems = async (items: LoadItem[]): Promise<LoadedValue[]> => {
    return await Promise.all(items.map(this.loadItem));
  };

  /**
   * Load a single item
   *
   * @param {LoadItem} item Item to load
   * @returns {Promise<LoadedValue>} Resolve when item is loaded, reject for any error
   */
  public loadItem = async (item: LoadItem): Promise<LoadedValue> => {
    const extension: string = AsyncPreloader.getFileExtension(item.src);
    const loaderKey: LoaderKey =
      item.loader || AsyncPreloader.getLoaderKey(extension);

    const loadedItem: LoadedValue = await this[`load` + loaderKey](item);

    this.items.set((item.id || item.src) as string, loadedItem);

{'fraction_non_alphanumeric': 0.14235040098704504, 'fraction_numerical': 0.0024676125848241827, 'mean_word_length': 3.3699460916442048, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 10}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5644290', 'n_tokens_mistral': 2041, 'n_tokens_neox': 2016, 'n_words': 625}