@jay-js/system
Version:
A powerful and flexible TypeScript library for UI, state management, lazy loading, routing and managing draggable elements in modern web applications.
141 lines • 4.57 kB
JavaScript
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());
});
};
/**
* In-flight requests map for deduplication
*/
const inflightRequests = new Map();
/**
* Execute fetch with deduplication
* If same key is already fetching, return existing promise
*
* @param key Query key
* @param fetcher Function to fetch data
* @param onFinally Callback to run when fetch completes
* @returns Promise with fetched data
*/
export function executeFetch(key, fetcher, onFinally) {
return __awaiter(this, void 0, void 0, function* () {
const existing = inflightRequests.get(key);
if (existing) {
return existing.promise;
}
const controller = new AbortController();
const promise = fetcher(controller.signal).finally(() => {
inflightRequests.delete(key);
onFinally === null || onFinally === void 0 ? void 0 : onFinally();
});
inflightRequests.set(key, { promise, controller });
return promise;
});
}
/**
* Cancel in-flight request for a key
*
* @param key Query key
*/
export function cancelFetch(key) {
const inflight = inflightRequests.get(key);
if (inflight) {
inflight.controller.abort();
inflightRequests.delete(key);
}
}
/**
* Execute fetch with retry logic
*
* @param fetcher Function to fetch data
* @param retry Number of retries or boolean
* @param retryDelay Delay between retries in ms or function
* @param signal AbortSignal to cancel request
* @returns Promise with fetched data
*/
export function executeWithRetry(fetcher, retry, retryDelay, signal) {
return __awaiter(this, void 0, void 0, function* () {
const maxAttempts = typeof retry === "boolean" ? (retry ? 3 : 0) : retry;
let attempt = 0;
let lastError = new Error("Unknown error");
while (attempt <= maxAttempts) {
try {
return yield fetcher(signal);
}
catch (error) {
lastError = error;
attempt++;
if (signal.aborted) {
throw new Error("Request aborted");
}
if (attempt > maxAttempts) {
break;
}
const delay = typeof retryDelay === "function" ? retryDelay(attempt) : retryDelay;
yield sleep(delay);
}
}
throw lastError;
});
}
/**
* Default retry delay with exponential backoff
*
* @param attempt Current attempt number
* @returns Delay in milliseconds
*/
export function defaultRetryDelay(attempt) {
return Math.min(1000 * Math.pow(2, attempt), 30000);
}
/**
* Sleep utility
*
* @param ms Milliseconds to sleep
* @returns Promise that resolves after delay
*/
function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
/**
* Setup window focus refetch listener
*
* @param callback Function to call when window gains focus
* @returns Cleanup function to remove listener
*/
export function setupFocusRefetch(callback) {
const handler = () => {
if (document.visibilityState === "visible") {
callback();
}
};
document.addEventListener("visibilitychange", handler);
return () => {
document.removeEventListener("visibilitychange", handler);
};
}
/**
* Setup reconnect refetch listener
*
* @param callback Function to call when network reconnects
* @returns Cleanup function to remove listener
*/
export function setupReconnectRefetch(callback) {
const handler = () => callback();
window.addEventListener("online", handler);
return () => {
window.removeEventListener("online", handler);
};
}
/**
* Resolve query key (static or reactive)
*
* @param key Query key
* @returns Resolved string key
*/
export function resolveQueryKey(key) {
return typeof key === "function" ? key() : key;
}
//# sourceMappingURL=utils.js.map