Prechádzať zdrojové kódy

feat: make fetchAdvanced drop-in & make timeout optional (closes #30)

Sv443 1 rok pred
rodič
commit
50389676aa
3 zmenil súbory, kde vykonal 31 pridanie a 14 odobranie
  1. 5 0
      .changeset/smooth-suits-cheat.md
  2. 8 5
      README.md
  3. 18 9
      lib/misc.ts

+ 5 - 0
.changeset/smooth-suits-cheat.md

@@ -0,0 +1,5 @@
+---
+"@sv443-network/userutils": minor
+---
+
+`fetchAdvanced` is now a drop-in replacement and timeout can now optionally be disabled

+ 8 - 5
README.md

@@ -1059,14 +1059,15 @@ window.addEventListener("resize", debounce((event) => {
 ### fetchAdvanced()
 Usage:  
 ```ts
-fetchAdvanced(url: string, options?: {
+fetchAdvanced(input: string | Request | URL, options?: {
   timeout?: number,
   // any other options from fetch() except for signal
 }): Promise<Response>
 ```
   
-A wrapper around the native `fetch()` function that adds options like a timeout property.  
-The timeout will default to 10 seconds if left undefined.  
+A drop-in replacement for the native `fetch()` function that adds options like a timeout property.  
+The timeout will default to 10 seconds if left undefined. Set it to a negative number to disable the timeout.  
+Note that the `signal` option will be overwritten if passed.  
   
 <details><summary><b>Example - click to view</b></summary>
 
@@ -1077,10 +1078,12 @@ fetchAdvanced("https://jokeapi.dev/joke/Any?safe-mode", {
   timeout: 5000,
   // also accepts any other fetch options like headers:
   headers: {
-    "Accept": "application/json",
+    "Accept": "text/plain",
   },
 }).then(async (response) => {
-  console.log("Data:", await response.json());
+  console.log("Fetch data:", await response.text());
+}).catch((err) => {
+  console.error("Fetch error:", err);
 });
 ```
 

+ 18 - 9
lib/misc.ts

@@ -63,21 +63,30 @@ export function debounce<TFunc extends (...args: TArgs[]) => void, TArgs = any>(
 }
 
 /** Options for the `fetchAdvanced()` function */
-export type FetchAdvancedOpts = RequestInit & Partial<{
-  /** Timeout in milliseconds after which the fetch call will be canceled with an AbortController signal */
-  timeout: number;
-}>;
+export type FetchAdvancedOpts = Omit<
+  RequestInit & Partial<{
+    /** Timeout in milliseconds after which the fetch call will be canceled with an AbortController signal */
+    timeout: number;
+  }>,
+  "signal"
+>;
 
 /** Calls the fetch API with special options like a timeout */
-export async function fetchAdvanced(url: string, options: FetchAdvancedOpts = {}) {
+export async function fetchAdvanced(input: RequestInfo | URL, options: FetchAdvancedOpts = {}) {
   const { timeout = 10000 } = options;
 
-  const controller = new AbortController();
-  const id = setTimeout(() => controller.abort(), timeout);
+  let signalOpts: Partial<RequestInit> = {},
+    id: NodeJS.Timeout | undefined = undefined;
 
-  const res = await fetch(url, {
+  if(timeout >= 0) {
+    const controller = new AbortController();
+    id = setTimeout(() => controller.abort(), timeout);
+    signalOpts = { signal: controller.signal };
+  }
+
+  const res = await fetch(input, {
     ...options,
-    signal: controller.signal,
+    ...signalOpts,
   });
 
   clearTimeout(id);