UNPKG

@hoangsonw/fast-fetch

Version:

A smarter fetch() wrapper with auto-retry, deduplication, and minimal boilerplate.

125 lines (120 loc) 4.65 kB
import { fastFetch } from "@hoangsonw/fast-fetch"; fastFetch("https://pokeapi.co/api/v2/pokemon/ditto", { retries: 2, retryDelay: 2000, deduplicate: true, shouldRetry: (errorOrResponse, attempt) => { console.log(`Retry attempt #${attempt}`); // If it's a Response object (failed request) if (errorOrResponse instanceof Response) { return errorOrResponse.status >= 500; // Retry on 5xx errors } // If it's a network or other error return true; }, }) .then((res) => res.json()) .then((data) => { console.log("FastFetch data:", data); }) .catch((err) => { console.error("FastFetch error:", err); }); // Should output something like: // [FastFetch] Starting request for: https://pokeapi.co/api/v2/pokemon/ditto // [FastFetch] Attempt #1 for: https://pokeapi.co/api/v2/pokemon/ditto // [FastFetch] Stored in-flight request with signature: {"url":"https://pokeapi.co/api/v2/pokemon/ditto","method":"GET","headers":{},"body":null} // [FastFetch] Request succeeded on attempt #1 // [FastFetch] Removed in-flight record for signature: {"url":"https://pokeapi.co/api/v2/pokemon/ditto","method":"GET","headers":{},"body":null} // FastFetch data: { // abilities: [ // { ability: [Object], is_hidden: false, slot: 1 }, // { ability: [Object], is_hidden: true, slot: 3 } // ], // base_experience: 101, // cries: { // latest: 'https://raw.githubusercontent.com/PokeAPI/cries/main/cries/pokemon/latest/132.ogg', // legacy: 'https://raw.githubusercontent.com/PokeAPI/cries/main/cries/pokemon/legacy/132.ogg' // }, // forms: [ // { // name: 'ditto', // url: 'https://pokeapi.co/api/v2/pokemon-form/132/' // } // ], // game_indices: [ // { game_index: 76, version: [Object] }, // { game_index: 76, version: [Object] }, // { game_index: 76, version: [Object] }, // { game_index: 132, version: [Object] }, // { game_index: 132, version: [Object] }, // { game_index: 132, version: [Object] }, // { game_index: 132, version: [Object] }, // { game_index: 132, version: [Object] }, // { game_index: 132, version: [Object] }, // { game_index: 132, version: [Object] }, // { game_index: 132, version: [Object] }, // { game_index: 132, version: [Object] }, // { game_index: 132, version: [Object] }, // { game_index: 132, version: [Object] }, // { game_index: 132, version: [Object] }, // { game_index: 132, version: [Object] }, // { game_index: 132, version: [Object] }, // { game_index: 132, version: [Object] }, // { game_index: 132, version: [Object] }, // { game_index: 132, version: [Object] } // ], // height: 3, // held_items: [ // { item: [Object], version_details: [Array] }, // { item: [Object], version_details: [Array] } // ], // id: 132, // is_default: true, // location_area_encounters: 'https://pokeapi.co/api/v2/pokemon/132/encounters', // moves: [ { move: [Object], version_group_details: [Array] } ], // name: 'ditto', // order: 214, // past_abilities: [], // past_types: [], // species: { // name: 'ditto', // url: 'https://pokeapi.co/api/v2/pokemon-species/132/' // }, // sprites: { // back_default: 'https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/back/132.png', // back_female: null, // back_shiny: 'https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/back/shiny/132.png', // back_shiny_female: null, // front_default: 'https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/132.png', // front_female: null, // front_shiny: 'https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/shiny/132.png', // front_shiny_female: null, // other: { // dream_world: [Object], // home: [Object], // 'official-artwork': [Object], // showdown: [Object] // }, // versions: { // 'generation-i': [Object], // 'generation-ii': [Object], // 'generation-iii': [Object], // 'generation-iv': [Object], // 'generation-v': [Object], // 'generation-vi': [Object], // 'generation-vii': [Object], // 'generation-viii': [Object] // } // }, // stats: [ // { base_stat: 48, effort: 1, stat: [Object] }, // { base_stat: 48, effort: 0, stat: [Object] }, // { base_stat: 48, effort: 0, stat: [Object] }, // { base_stat: 48, effort: 0, stat: [Object] }, // { base_stat: 48, effort: 0, stat: [Object] }, // { base_stat: 48, effort: 0, stat: [Object] } // ], // types: [ { slot: 1, type: [Object] } ], // weight: 40 // }