npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@paquitosoft/fetcher

v1.3.0

Published

A simple and [small](https://bundlephobia.com/package/@paquitosoft/fetcher) (_typed_) library on top of [**fetch**](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) that is more user friendly.

Downloads

30

Readme

Fetcher

A simple and small (typed) library on top of fetch that is more user friendly.

NPM version Gzip size CircleCI status GitHub license

Sections:

Please head to the API Docs for detailed information.

Installation

npm install @paquitosoft/fetcher

How to use it

The module exports four API functions tailored for the main HTTP Methods (GET, POST, PUT, DELETE) and also another one to tailor your request (and use other HTTP methods).

Sending a GET request

import { get } from '@paquitosoft/fetcher';

async function loadProducts() {
  const products = await get('https://fakestoreapi.com/products');
  console.log({ products });
}

// Loading and cache products for 10 minutes
async function loadAndCacheProducts() {
  const products = await get('https://fakestoreapi.com/products', {
    ttl: 10 * 60 // value is seconds
  });
  console.log({ products });
}

Sending a POST request

import { post } from '@paquitosoft/fetcher';

async function saveProduct() {
  const newProduct = {
    title: 'test product',
    price: 13.5,
    description: 'lorem ipsum set',
    image: 'https://i.pravatar.cc',
    category: 'electronic'
  };
  const persistedProduct = await post('https://fakestoreapi.com/products', newProduct);
  console.log({ persistedProduct });
}

Caching

By default fetcher uses an in-memory cache so you can avoid hitting the server for long-lived resources. This is controlled by the ttl (seconds) parameter for GET requests.

You can also provide your own custom cache manager to store values in other locations such local-storage or IndexedDB. For such situations, you would create a class/object which implements the CacheManager interface.

import { setCacheManager, get } from '@paquitosoft/fetcher';

// Define a custom cache manager
const localStorageCacheManager = {
  set(key, value, options = { ttl: 0 }) {
    const cacheEntry = {
      expires: Date.now() + ((options?.ttl || 0) * 1000),
      value
    };
    localStorage.setItem(key, JSON.stringify(cacheEntry));
  },

  get(key) {
    const cacheEntryRaw = localStorage.getItem(key);

    if (!cacheEntry) return undefined;

    const now = Date.now();
    const cacheEntry = JSON.parse(cacheEntryRaw);
    if (cacheEntry && now < cacheEntry.expires) {
      return cacheEntry.value;
    } else {
      localStorage.removeItem(key);
      return undefined;
    }
  }
};

// Tell Fetcher to use this custom manager
setCacheManager(localStorageCacheManager);

// Now fetched data will be persisted in browser's local storage
async function loadAndCacheProducts() {
  const products = await get('https://fakestoreapi.com/products', {
    ttl: 10 * 60
  });
  console.log({ products });
}

Middlewares

There might be scenarios where you would like to apply some logic before or after every request. You can achieve this by using middlewares. You would create middleware functions and register them in the fetcher module by calling the addMiddleware function.

Before request middlewares

These are just functions that receive the request meta-data and must return that meta-data with your needed modifications.

Here is an example of a middleware to add some sort of auth token to every request.

import { addMiddleware, removeMiddleware, get } from '@paquitosoft/fetcher';

// Define your middleware
function authMiddleware({ method, url, fetchOptions, ttl, body, cache }) {
  const authToken = localStorage.getItem('auth-token');
  const headers = {
    ...fetchOptions.headers,
    'Authorization': `Bearer ${authToken}`
  };
  return {
    fetchOptions: {
      ...fetchOptions,
      headers
    }
  };
}

// Tell fetcher you want to use it
addMiddleware('before', authMiddleware);

// This request would send the auth header
const shopCart = await get('https://fakestoreapi.com/carts/5');

// If you ever need to remove the middleware, you can do it like this
removeMiddleware(authMiddleware);

After request middlewares

In you ever need to modify the response from the server before it gets to your consumer, you can use an after middleware which receives the data fetched from the server (processed) and can return whatever it wants.

Here is an example where we modify the response if user is in a certain A/B experiment:

import { addMiddleware, get } from '@paquitosoft/fetcher';

// Define your middleware
function updateProductsMetaData(serverData: products) {
  const isProductsListingUrl = /\/products$/.test(url);

  if (isProductsListingUrl) {
    const isUserInExperiment = (localStorage.getItem('user-ab-engaged-experiments') || '')
      .split(',').includes('exp_001');

    if (isUserInExperiment) {
      return products.map(product => ({
        ...product,
        labels: ['NEW']
      }));
    }
  }
}

// Tell fetcher you want to use it
addMiddleware('before', updateProductsMetaData);

// Products will include the 'labels' attribute if user is in the experiment
const products = await get('https://fakestoreapi.com/products');