/* eslint-disable @typescript-eslint/no-unused-vars */ /* eslint-disable @typescript-eslint/unbound-method */ import type { IActivityHandler } from "@vertigis/workflow"; /** An interface that defines the inputs of the activity. */ interface RequestCheckerInputs {} /** An interface that defines the outputs of the activity. */ interface RequestCheckerOutputs { /** * @description True if there is still any pending request. */ result: boolean; } /** * @displayName RequestChecker * @category EBTA Utilities * @description Check if there is any pending HTTP request */ export default class RequestCheckerActivity implements IActivityHandler { // Track ongoing XMLHttpRequests private static activeXHRs: XMLHttpRequest[] = []; // Track ongoing Fetch requests private static activeFetches: Promise[] = []; constructor() { // Monkey patch XMLHttpRequest to track active requests const xhrProto = XMLHttpRequest.prototype as any; const originalOpen = xhrProto.open; const originalAbort = xhrProto.abort; xhrProto.open = function ( this: XMLHttpRequest, method: string, url: string, async?: boolean, username?: string | null, password?: string | null ): void { RequestCheckerActivity.activeXHRs.push(this); this.addEventListener("loadend", () => { const index = RequestCheckerActivity.activeXHRs.indexOf(this); if (index > -1) { RequestCheckerActivity.activeXHRs.splice(index, 1); } }); return originalOpen.call(this, method, url, async, username, password); }; xhrProto.abort = function (this: XMLHttpRequest): void { const index = RequestCheckerActivity.activeXHRs.indexOf(this); if (index > -1) { RequestCheckerActivity.activeXHRs.splice(index, 1); } return originalAbort.call(this); }; // Monkey patch global fetch to track active promises const originalFetch = window.fetch.bind(window); (window as any).fetch = (...args: Parameters) => { const fetchPromise = originalFetch(...args); RequestCheckerActivity.activeFetches.push(fetchPromise); void fetchPromise .then(() => { const index = RequestCheckerActivity.activeFetches.indexOf(fetchPromise); if (index > -1) { RequestCheckerActivity.activeFetches.splice(index, 1); } }) .catch(() => { const index = RequestCheckerActivity.activeFetches.indexOf(fetchPromise); if (index > -1) { RequestCheckerActivity.activeFetches.splice(index, 1); } }); return fetchPromise; }; } execute(inputs: RequestCheckerInputs): RequestCheckerOutputs { // Check both XMLHttpRequests and Fetch requests const hasPendingXHR = RequestCheckerActivity.activeXHRs.length > 0; const hasPendingFetch = RequestCheckerActivity.activeFetches.length > 0; return { result: hasPendingXHR || hasPendingFetch, }; } }