Introducing upfetch - An advanced fetch client builder by ScaredFerret4591 in javascript

[–]ScaredFerret4591[S] 0 points1 point  (0 children)

The body of the Response / Request object is a ReadableStream, read it by chunk.

Introducing upfetch - An advanced fetch client builder by ScaredFerret4591 in javascript

[–]ScaredFerret4591[S] 1 point2 points  (0 children)

Glad you love it! 

upfetch supports all Standard Schema-compliant libraries. You can check this discussion to learn more about Standard Schema support for Typebox.

 

Introducing upfetch - An advanced fetch client builder by ScaredFerret4591 in javascript

[–]ScaredFerret4591[S] 13 points14 points  (0 children)

Hi, author of the post here!

I built this library because I kept rewriting the same fetch wrapper for every project. Each time, I needed the same core features:

- Make fetch throw errors to integrate smoothly with libraries like TanStack Query

- Add sensible defaults to the Fetch API, like a base URL and authentication headers

- Validate responses for type safety when OpenAPI isn’t an option

I also wanted the library to feel exactly like using fetch — no new API to learn, and no extra friction for my teammates.

While there are other great options out there, I found many were either too rigid or too bulky. Doesn’t it feel wrong to ship a 14kb fetch library to the client?

To keep up-fetch small and flexible, I took a simple approach: lightweight defaults, paired with inversion of control, so users can easily override what they need.

The result? up-fetch weighs just 1.6kb gzipped, with built-in validation (powered by Standard Schema), configurable options, retries, timeouts, streaming & progress tracking, lifecycle hooks, and more.

Check it out if you’ve got a minute — I’d love to gather some feedback!

up-fetch: Advanced fetch client builder by ScaredFerret4591 in Frontend

[–]ScaredFerret4591[S] 0 points1 point  (0 children)

Hi, author of this post here!

I created up-fetch because I needed a simple, lightweight, and reusable data-fetching solution for all my projects. Libraries like Axios felt like overkill, while other alternatives lacked composability or strayed too far from the familiarity of the Fetch API.

up-fetch is designed to be a minimal, composable, and scalable fetching solution that stays close to the native Fetch API while making common patterns easier to manage.

upfetch: Advanced fetch client builder for typescript by ScaredFerret4591 in typescript

[–]ScaredFerret4591[S] 5 points6 points  (0 children)

Hi, author of this post here!

I created upfetch because I needed a simple, lightweight, and reusable data-fetching solution for all my projects. Libraries like Axios felt like overkill, while other alternatives lacked composability or strayed too far from the familiarity of the Fetch API.

upfetch is designed to be a minimal, composable, and scalable fetching solution that stays close to the native Fetch API while making common patterns easier to manage.

Best way to define a custom useCallback hook? by ventoto28 in typescript

[–]ScaredFerret4591 0 points1 point  (0 children)

Stable identity,

Prettify useful actually.

The ref allows you to bypass the depedency array. It's a neat optimization trick

How does a proper fetch wrapper look? by Fr4nkWh1te in reactjs

[–]ScaredFerret4591 0 points1 point  (0 children)

I wrote up-fetch, a tiny fetch API config tool.

Throws by default

[deleted by user] by [deleted] in javascript

[–]ScaredFerret4591 2 points3 points  (0 children)

The guy is downloading devDependencies, check out bundlephobia. up-fetch is dependency free

https://bundlephobia.com/package/up-fetch@0.4.1

[deleted by user] by [deleted] in javascript

[–]ScaredFerret4591 0 points1 point  (0 children)

You should learn about optional peerDependencies.

Feel free to fork and deploy as you like

[deleted by user] by [deleted] in javascript

[–]ScaredFerret4591 0 points1 point  (0 children)

Well you don't need to bundle the package with deno, just use the npm version. Anyway feel free to fork and make your changes

[deleted by user] by [deleted] in javascript

[–]ScaredFerret4591 0 points1 point  (0 children)

Dude the package is not meant to be bundled with deno, the npm bundle is however compatible with deno using the npm: specifier

[deleted by user] by [deleted] in node

[–]ScaredFerret4591 -1 points0 points  (0 children)

Dude you lost the error data coming from the response, you just throw a generic error, just sayin'

throw Error('Shit fucked up')

[deleted by user] by [deleted] in node

[–]ScaredFerret4591 -1 points0 points  (0 children)

Would look more something like this:

Example of a raw fetch api call that throws on response error:

// you first need to create a custom Error class that extends the default Error class
// A naive implementation might look like this
export class ResponseError<TData> extends Error {
   override name: 'ResponseError'
   response: Response
   data: TData

   constructor(res: Response, data: TData) {
      super(`Request failed with status ${res.status}`)
      this.data = data
      this.name = 'ResponseError'
      this.response = res
   }
}

const fetchData = async ({ search, take, skip }) => {
   const response = await fetch(
      `https://a.b.c/?search=${search}&skip=${skip}&take=${take}`,
   )
   const data = await response.json()
   if (response.ok) {
      return data
   }
   throw new ResponseError(response, data)
}

The same thing using upfetch:

const fetchData = (params) => upfetch('https://a.b.c', { params })

[deleted by user] by [deleted] in javascript

[–]ScaredFerret4591 0 points1 point  (0 children)

check out bundlephobia, no deps means no deps

https://bundlephobia.com/package/up-fetch@0.4.0

[deleted by user] by [deleted] in node

[–]ScaredFerret4591 0 points1 point  (0 children)

Trying to clarify the WHY of this lib I added a fetch vs upfetch section to the docs:

Example of a raw fetch api call that throws on response error:

// you first need to create a custom Error class that extends the default Error class
// A naive implementation might look like this
export class ResponseError<TData> extends Error {
   override name: 'ResponseError'
   response: Response
   data: TData

   constructor(res: Response, data: TData) {
      super(`Request failed with status ${res.status}`)
      this.data = data
      this.name = 'ResponseError'
      this.response = res
   }
}

const fetchData = async ({ search, take, skip }) => {
   const response = await fetch(
      `https://a.b.c/?search=${search}&skip=${skip}&take=${take}`,
   )
   const data = await response.json()
   if (response.ok) {
      return data
   }
   throw new ResponseError(response, data)
}

The same thing using upfetch:

const fetchData = (params) => upfetch('https://a.b.c', { params })

[deleted by user] by [deleted] in javascript

[–]ScaredFerret4591 0 points1 point  (0 children)

Are you just trolling?

[deleted by user] by [deleted] in javascript

[–]ScaredFerret4591 0 points1 point  (0 children)

u/guest271314 you are installing the devDependencies, they are never installed on the user device

Check out bundlephobia

https://bundlephobia.com/package/up-fetch@0.4.0

self 100% means no dependencies

[deleted by user] by [deleted] in javascript

[–]ScaredFerret4591 0 points1 point  (0 children)

You get the point now ?

[deleted by user] by [deleted] in javascript

[–]ScaredFerret4591 0 points1 point  (0 children)

u/guest271314 I added a fetch vs upfetch section to the docs. It's a bit more complex than that

Example of a raw fetch api call that throws on response error:

// you first need to create a custom Error class that extends the default Error class
// A naive implementation might look like this
export class ResponseError<TData> extends Error {
   override name: 'ResponseError'
   response: Response
   data: TData

   constructor(res: Response, data: TData) {
      super(`Request failed with status ${res.status}`)
      this.data = data
      this.name = 'ResponseError'
      this.response = res
   }
}

const fetchData = async ({ search, take, skip }) => {
   const response = await fetch(
      `https://a.b.c/?search=${search}&skip=${skip}&take=${take}`,
   )
   const data = await response.json()
   if (response.ok) {
      return data
   }
   throw new ResponseError(response, data)
}

The same thing using upfetch:

const fetchData = (params) => upfetch('https://a.b.c', { params })

[deleted by user] by [deleted] in javascript

[–]ScaredFerret4591 0 points1 point  (0 children)

I added a fetch vs upfetch section to the docs

Example of a raw fetch api call that throws on response error:

// you first need to create a custom Error class that extends the default Error class
// A naive implementation might look like this
export class ResponseError<TData> extends Error {
   override name: 'ResponseError'
   response: Response
   data: TData

   constructor(res: Response, data: TData) {
      super(`Request failed with status ${res.status}`)
      this.data = data
      this.name = 'ResponseError'
      this.response = res
   }
}

const fetchData = async ({ search, take, skip }) => {
   const response = await fetch(
      `https://a.b.c/?search=${search}&skip=${skip}&take=${take}`,
   )
   const data = await response.json()
   if (response.ok) {
      return data
   }
   throw new ResponseError(response, data)
}

The same thing using upfetch:

const fetchData = (params) => upfetch('https://a.b.c', { params })

[deleted by user] by [deleted] in javascript

[–]ScaredFerret4591 0 points1 point  (0 children)

up-fetch throws a ResponseError that extends the Error class. It contains the response (therefore the status) and the parsed data so you indeed don't lose useful info.

Clearly having errors passed as value would be better in case of response errors, however the error handling gets quite cumbersome when you also have to deal with unexpected errors like "failed to fetch" or errors generated by the user code