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

wrap-request

v7.0.7

Published

a request wrapper for asynchronous operations

Downloads

240

Readme

wrap-request

a request wrapper for asynchronous operations

basic usage

const wrappedXhr = wrapRequest((config) => fetch('...'));

const { loading, fetched, error } = wrappedXhr;

const result = await wrappedXhr.request({ id: 1 });

pattern matching

based on the tc39-proposal for pattern matching you can display all states that your wrap-requests might enter.

const wrappedXhr = wrapRequest((config) => fetch('...'));

wrappedXhr.match({
    loading: () => 'Loading...',
    error: (e) => e.message,
    empty: () => 'No data.',
    fetched: (res) => res.data,
    default: () => 'Nothing to display'
});

react example

const MyComponent = () => {
    return wrappedXhr.match({
        loading: () => 'Loading...',
        error: (e) => e.message,
        empty: () => 'No data.',
        fetched: (res) => res.data,
        default: () => 'Nothing to display'
    });
};

default data

especially when dealing with lists it comes in handy to set a default value. from v7.0.0 on, when not setting defaultData, all of your data will be undefined by default when directly accessing it.

const wrappedXhr = wrapRequest(() => fetch('...'), { defaultData: [] });

pipe

sometimes it is useful, to directly pipe the result and keep a copy of the original data in the wrapper.

const wrappedXhr = wrapRequest(() => fetch('...'), {
    defaultData: []
}).pipe((res) => res.slice(0, 15));

const result = await wrappedXhr.request();

console.log(result); // capped list containing 15 items
console.log(wrappedXhr.$); // same as result
console.log(wrappedXhr.source); // list containing all items

you can also chain or use pipes as often as you like:

const wrappedXhr = wrapRequest(async () => [1, 2, 3, 4, 5], {
    defaultData: []
}).pipe((res) => res.map((num) => num.toString()));

await wrappedXhr.request();

const pipe1 = wrappedXhr.pipe((res) => res.slice(0, 2)); // [ '1', '2' ]
const pipe2 = pipe1.pipe((res) => res.slice(0, 1)); // [ '1' ]
const pipe3 = pipe2.pipe((res) => res[0]); // '1'

reset

Reset all wrapper-values to its initial state.

const wrappedXhr = wrapRequest(() => fetch('...'), {
    defaultData: []
});

await wrappedXhr.request();

wrappedXhr.reset();

metadata

You can save any metadata on the wrapper to store further informations.

const wrappedXhr = wrapRequest(() => fetch('...'), {
    metadata: (res) => ({
        fullName: `${res.firstname} ${res.lastname}`
    })
});

await wrappedXhr.request();

console.log(wrappedXhr.metadata);

streaming

The nature of promises is to resolve data only once. In some cases you need to update resolve multiple times f.e. when working with websockets. Enter streaming.

import websocket from 'my-websocket-lib';

const streamWr = wrapRequest.stream<{}, { id: string }>((update, resolve, params) => {
    websocket.on('update', updatedData => update(JSON.parse(updatedData)));
    websocket.on('close', () => resolve({}));
    websocket.connect(params.id);
});

streamWr.on('update', (data) => console.log('update', data));
streamWr.on('resolve', (data) => console.log('resolve', data));
streamWr.request({ id: 'ABCD1234HIJK' });

When working with mobx-wrap-request, all observable-values are updated when calling update / resolve that means when rendering data, you may not need events but receive streamlined updates in your component.

react hook

There is an implementation for working with react-hooks inside your components. react-wrap-request

mobx dependency

wrap-request used to have a direct dependency on mobx. this was removed in 3.0.0 please use mobx-wrap-request for further support.

pitfalls

typescript

please avoid setting your own generics when using wrapRequest. The problem here is, if you don't set all of the generics, chances are high that automatic type-inference will break.

❌ don't:

wrapRequest<MyArray[]>(() => [], { defaultData: [] });

✅ do:

wrapRequest(() => [] as MyArray[], { defaultData: [] });

If you really need to override all the generics, better make sure to set all of them:

wrapRequest<MyArray[], any, MyArray[], any, never[]>(() => []);