misc.ts 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. import type { FetchAdvancedOpts } from "./types";
  2. /**
  3. * Automatically appends an `s` to the passed `word`, if `num` is not equal to 1
  4. * @param word A word in singular form, to auto-convert to plural
  5. * @param num If this is an array or NodeList, the amount of items is used
  6. */
  7. export function autoPlural(word: string, num: number | unknown[] | NodeList) {
  8. if(Array.isArray(num) || num instanceof NodeList)
  9. num = num.length;
  10. return `${word}${num === 1 ? "" : "s"}`;
  11. }
  12. /** Pauses async execution for the specified time in ms */
  13. export function pauseFor(time: number) {
  14. return new Promise((res) => {
  15. setTimeout(res, time);
  16. });
  17. }
  18. /**
  19. * Calls the passed `func` after the specified `timeout` in ms.
  20. * Any subsequent calls to this function will reset the timer and discard previous calls.
  21. */
  22. export function debounce<TFunc extends (...args: TArgs[]) => void, TArgs = any>(func: TFunc, timeout = 300) { // eslint-disable-line @typescript-eslint/no-explicit-any
  23. let timer: number | undefined;
  24. return function(...args: TArgs[]) {
  25. clearTimeout(timer);
  26. timer = setTimeout(() => func.apply(this, args), timeout) as unknown as number;
  27. };
  28. }
  29. /** Calls the fetch API with special options like a timeout */
  30. export async function fetchAdvanced(url: string, options: FetchAdvancedOpts = {}) {
  31. const { timeout = 10000 } = options;
  32. const controller = new AbortController();
  33. const id = setTimeout(() => controller.abort(), timeout);
  34. const res = await fetch(url, {
  35. ...options,
  36. signal: controller.signal,
  37. });
  38. clearTimeout(id);
  39. return res;
  40. }