houser-js-utils
Version:
A comprehensive collection of TypeScript utility functions for common development tasks including array manipulation, string processing, date handling, random number generation, validation, and much more.
247 lines (246 loc) • 7.64 kB
JavaScript
const NetworkUtils = {
/**
* Adds a listener for network status changes (online/offline).
* @param callback - Callback invoked with `true` if online, `false` if offline.
* @returns Function to remove the listener.
* @example
* ```typescript
* const remove = NetworkUtils.addNetworkStatusListener((online) => console.log('Online:', online));
* // ...later
* remove();
* ```
*/
addNetworkStatusListener: (callback) => {
const handleOnline = () => callback(true);
const handleOffline = () => callback(false);
window.addEventListener("online", handleOnline);
window.addEventListener("offline", handleOffline);
return () => {
window.removeEventListener("online", handleOnline);
window.removeEventListener("offline", handleOffline);
};
},
/**
* Makes a fetch request with Bearer token authentication.
* @param url - The URL to fetch.
* @param token - The authentication token.
* @param options - Additional fetch options.
* @returns The fetch response.
* @example
* ```typescript
* const res = await NetworkUtils.fetchWithAuth('/api', 'token123');
* ```
*/
fetchWithAuth: async (url, token, options = {}) => {
return fetch(url, {
...options,
headers: {
...options.headers,
Authorization: `Bearer ${token}`
}
});
},
/**
* Makes a fetch request with caching in localStorage.
* @param url - The URL to fetch.
* @param options - Fetch options.
* @param cacheTime - Cache time in milliseconds (default 5 minutes).
* @returns The fetch response (from cache or network).
* @example
* ```typescript
* const res = await NetworkUtils.fetchWithCache('/api/data');
* ```
*/
fetchWithCache: async (url, options = {}, cacheTime = 5 * 60 * 1e3) => {
const cacheKey = `fetch-cache-${url}`;
const cached = localStorage.getItem(cacheKey);
if (cached) {
const { data: data2, timestamp } = JSON.parse(cached);
if (Date.now() - timestamp < cacheTime) {
return new Response(data2);
}
}
const response = await fetch(url, options);
const data = await response.clone().text();
localStorage.setItem(
cacheKey,
JSON.stringify({
data,
timestamp: Date.now()
})
);
return response;
},
/**
* Makes a fetch request and parses the response as JSON, with error handling.
* @template T
* @param url - The URL to fetch.
* @param options - Fetch options.
* @returns The parsed response data.
* @throws {Error} If the response is not OK.
* @example
* ```typescript
* const data = await NetworkUtils.fetchJson<{foo: string}>('/api/data');
* ```
*/
fetchJson: async (url, options = {}) => {
const response = await fetch(url, {
...options,
headers: {
"Content-Type": "application/json",
...options.headers
}
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.json();
},
/**
* Makes a fetch request and tracks download progress.
* @param url - The URL to fetch.
* @param options - Fetch options.
* @param onProgress - Progress callback (0-100).
* @returns The fetch response.
* @example
* ```typescript
* await NetworkUtils.fetchWithProgress('/file', {}, (progress) => console.log('Progress:', progress));
* ```
*/
fetchWithProgress: async (url, options = {}, onProgress) => {
const response = await fetch(url, options);
const contentLength = response.headers.get("content-length");
const total = contentLength ? parseInt(contentLength, 10) : 0;
let loaded = 0;
const reader = response.body?.getReader();
if (!reader || !response.body) return response;
const stream = new ReadableStream({
start(controller) {
function push() {
reader.read().then(({ done, value }) => {
if (done) {
controller.close();
return;
}
loaded += value.length;
if (total && onProgress) {
onProgress(loaded / total * 100);
}
controller.enqueue(value);
push();
});
}
push();
}
});
return new Response(stream, {
headers: response.headers,
status: response.status,
statusText: response.statusText
});
},
/**
* Makes a fetch request with retry logic on failure.
* @param url - The URL to fetch.
* @param options - Fetch options.
* @param retries - Number of retries (default 3).
* @param delay - Delay between retries in milliseconds (default 1000).
* @returns The fetch response.
* @throws {Error} If all retries fail.
* @example
* ```typescript
* const res = await NetworkUtils.fetchWithRetry('/api', {}, 5, 500);
* ```
*/
fetchWithRetry: async (url, options = {}, retries = 3, delay = 1e3) => {
let lastError;
for (let i = 0; i < retries; i++) {
try {
return await fetch(url, options);
} catch (error) {
lastError = error;
if (i < retries - 1) {
await new Promise((resolve) => setTimeout(resolve, delay));
}
}
}
throw lastError;
},
/**
* Makes a fetch request with a timeout.
* @param url - The URL to fetch.
* @param options - Fetch options.
* @param timeout - Request timeout in milliseconds (default 5000).
* @returns The fetch response.
* @throws {Error} If the request times out.
* @example
* ```typescript
* const res = await NetworkUtils.fetchWithTimeout('/api', {}, 2000);
* ```
*/
fetchWithTimeout: async (url, options = {}, timeout = 5e3) => {
const controller = new AbortController();
const { signal } = controller;
const timeoutId = setTimeout(() => controller.abort(), timeout);
try {
const response = await fetch(url, { ...options, signal });
clearTimeout(timeoutId);
return response;
} catch (error) {
clearTimeout(timeoutId);
if (error instanceof Error && error.name === "AbortError") {
throw new Error("Request timeout");
}
throw error;
}
},
/**
* Gets the current network speed (downlink) in Mbps, if available.
* @returns The network speed in Mbps, or null if not available.
* @example
* ```typescript
* const speed = NetworkUtils.getNetworkSpeed();
* console.log('Speed:', speed);
* ```
*/
getNetworkSpeed: () => {
if (typeof navigator !== "undefined" && "connection" in navigator) {
const connection = navigator.connection;
return connection ? connection.downlink + " Mbps" : null;
}
return null;
},
/**
* Gets the current network type (e.g., 'wifi', '4g'), if available.
* @returns The network type, or null if not available.
* @example
* ```typescript
* const type = NetworkUtils.getNetworkType();
* console.log('Type:', type);
* ```
*/
getNetworkType: () => {
if (typeof navigator !== "undefined" && "connection" in navigator) {
const connection = navigator.connection;
return connection ? connection.effectiveType : null;
}
return null;
},
/**
* Checks if the network is currently online.
* @returns True if the network is online, false otherwise.
* @example
* ```typescript
* if (NetworkUtils.isOnline()) {
* // Do something when online
* }
* ```
*/
isOnline: () => {
return typeof navigator !== "undefined" && navigator.onLine;
}
};
export {
NetworkUtils
};
//# sourceMappingURL=NetworkUtils.mjs.map