UNPKG

dbl-utils

Version:

Utilities for dbl, adba and others projects

93 lines (92 loc) 3.46 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); const js_md5_1 = require("js-md5"); /** * A queue to manage fetch requests with unique identification. * * Useful to deduplicate concurrent network calls to the same URL. * * @example * ```ts * const queue = new FetchQueue(fetch); * const [a, b] = await Promise.all([ * queue.addRequest('https://example.com/data'), * queue.addRequest('https://example.com/data') * ]); * // only one HTTP request is performed * ``` */ class FetchQueue { /** * * @param {Function} fetchFn - A fetch function (e.g., node-fetch or window.fetch). */ constructor(fetchFn) { this.queue = {}; this.isRunning = false; this.fetchFn = fetchFn; } /** * Adds a fetch request to the queue. * @param {string} url - The URL to fetch. * @param {RequestInit} [options] - Optional fetch options. * @returns {Promise<any>} - A promise that resolves with the fetch response. */ addRequest(url, options) { const hash = this.createHash(url, options); if (this.queue[hash]) { return new Promise((resolve, reject) => { this.queue[hash].resolve.push(resolve); this.queue[hash].reject.push(reject); }); } return new Promise((resolve, reject) => { this.queue[hash] = { url, options, resolve: [resolve], reject: [reject] }; this.runQueue(); }); } /** * Runs the queue of fetch requests. */ runQueue() { return __awaiter(this, void 0, void 0, function* () { if (this.isRunning) return; this.isRunning = true; while (Object.keys(this.queue).length > 0) { const hash = Object.keys(this.queue)[0]; const { url, options, resolve, reject } = this.queue[hash]; try { const response = yield this.fetchFn(url, options); resolve.forEach(r => r(response)); delete this.queue[hash]; } catch (error) { reject.forEach(r => r(error)); delete this.queue[hash]; } } this.isRunning = false; }); } /** * Creates a hash to uniquely identify a request. * @param {string} url - The URL to fetch. * @param {RequestInit} [options] - Optional fetch options. * @returns {string} - A hash representing the unique request. */ createHash(url, options) { const optionsString = JSON.stringify(options || {}); return (0, js_md5_1.md5)(url + optionsString); } } exports.default = FetchQueue;