@attio/fetchable

中文文档
0.0.1-experimental.9发布于 2025/12/04TypeScriptESM + CJS零依赖近 30 天下载 5.7万

fetchable is a library for explicitly handling errors and loading in Typescript and JavaScript.

原始使用文档
文档目录5 节
  1. Installation
  2. Concepts
  3. Primitive states
  4. Higher order states
  5. Transformations

Fetchable

fetchable is a library for explicitly handling errors and loading in Typescript and JavaScript.

Installation

> npm install @attio/fetchable

Concepts

Primitive states

There are three primitive states in fetchable.

✅ Complete

A Complete<V> is a simple JavaScript object which represents any kind of intact data.

import {complete} from "@attio/fetchable"

const completeNumber = complete(1) // Returns a Complete<1>

console.log(completeNumber.value) // 1
console.log(completeNumber.state) // "complete"

❌ Errored

An Errored<E> is another JavaScript object which represents something that went wrong.

import {errored} from "@attio/fetchable"

const erroredThing = errored("Oops") // Returns an Errored<"Oops">

console.log(erroredThing.error) // "Oops"
console.log(erroredThing.state) // "errored"

⏳ Pending

A Pending is another JavaScript object which represents some process which is in progress.

import {pending} from "@attio/fetchable"

const pendingThing = pending() // Returns a Pending

console.log(pendingThing.state) // "pending"

Higher order states

The fun comes when we start to mix up the three primitive states.

Result: Complete or Errored

A Result<V, E> is an object which is either a Complete<V> or an Errored<E>. It represents the outcome of a process which might succeed or fail.

import {isComplete} from "@attio/fetchable"

const result = doSynchronousThingWhichMightError() // Returns Result<number, "Oops">

if (isComplete(result)) {
    console.log(result.value) // number
} else {
    console.log(result.error) // "Oops"
}

Loadable: Complete or Pending

A Loadable<V> is an object which is either a Complete<V> or a Pending. It represents the outcome of an asynchronous process which cannot fail.

import {isComplete} from "@attio/fetchable"

const loadable = getStatusOfLongRunningProcess() // Returns Loadable<number>

if (isComplete(loadable)) {
    console.log(loadable.value) // number
}

Fetchable: Complete or Pending or Errored

A Fetchable<V, E> is an object which is either a Complete<V>, Errored<E> or Pending. It represents the outcome of an asynchronous process which can fail.

Fetchable is most often seen in declarative front-end code where we don't want to expose promises.

import {isComplete, isErrored} from "@attio/fetchable"

const fetchable = getStatusOfLongRunningProcessWhichMightFail() // Returns Fetchable<number, "Oops">

if (isComplete(fetchable)) {
    console.log(fetchable.value) // number
} else if (isErrored(fetchable)) {
    console.log(fetchable.error) // "Oops"
}

AsyncResult

An AsyncResult<V, E> is a promise of a Result<V, E>. Complete<V>, Errored<E> or Pending. It is most often seen in imperative code where we use promises for asynchronous processes.

import {isComplete, isErrored} from "@attio/fetchable"

const asyncResult = runAsyncProcessWhichMightFail() // Returns AsyncResult<number, "Oops">

asyncResult.then(result => {
    if (isComplete(result)) {
        console.log(result.value) // number
    } else if (isErrored(result)) {
        console.log(result.error) // "Oops"
    }
})

Transformations

fetchable provides functional utilities for working with these objects without explicitly checking which state they're in.

map

import {map} from "@attio/fetchable"

const fetchable = getStatusOfLongRunningProcessWhichMightFail() // Returns Fetchable<number, "Oops">

// Increments the fetchable if it's complete. 
// Returns Fetchable<number, "Oops">
const incrementedFetchable = map(fetchable, (number) => number + 1)

bind

import {map} from "@attio/fetchable"

const fetchable = getStatusOfLongRunningProcessWhichMightFail() // Returns Fetchable<number, "Oops">

// Increments the fetchable if it's complete and not zero.
// Returns Fetchable<number, "Oops" | "Unexpected zero">
const incrementedFetchable = bind(fetchable, (number) =>
    number === 0 ? errored("Unexpected zero") : complete(number + 1)
)

combine

Arrays

import {combine} from "@attio/fetchable"

const fetchable1 = getStatusOfLongRunningProcessWhichMightFail() // Returns Fetchable<number, "Oops">
const fetchable2 = doSynchronousThingWhichMightError() // Returns Result<string, "Eek">

// If both fetchables are complete then their values will be returned in a complete array.
// Returns Fetchable<[number, string], "Oops" | "Eek">
const combinedFetchable = combine([fetchable1, fetchable2])

Objects

import {combine} from "@attio/fetchable"

const fetchableA = getStatusOfLongRunningProcessWhichMightFail() // Returns Fetchable<number, "Oops">
const fetchableB = doSynchronousThingWhichMightError() // Returns Result<string, "Eek">

// If both fetchables are complete then their values will be returned in a new object.
// Returns Fetchable<{a: number, b: string}, "Oops" | "Eek">
const combinedFetchable = combine({a: fetchable1, b: fetchable2})

combineAsync

Like Promise.all for AsyncResults. It takes multiple AsyncResults and resolves when they all resolve with Completes or when one resolves with an Errored.

Arrays

import {combineAsync} from "@attio/fetchable"

const asyncResult1 = runAsyncProcessWhichMightFail() // Returns AsyncResult<number, "Oops">
const asyncResult2 = runAnotherAsyncProcessWhichMightFail() // Returns AsyncResult<string, "Eek">

// Returns Result<[number, string], "Oops" | "Eek">
const combinedResult = await combineAsync([asyncResult1, asyncResult2])

Objects

import {combine} from "@attio/fetchable"

const asyncResultA = runAsyncProcessWhichMightFail() // Returns AsyncResult<number, "Oops">
const asyncResultB = runAnotherAsyncProcessWhichMightFail() // Returns AsyncResult<string, "Eek">

// If both fetchables are complete then their values will be returned in a new object.
// Returns Result<{a: number, b: string}, "Oops" | "Eek">
const combinedResult = await combineAsync({a: asyncResultA, b: asyncResultB})

版本与发布记录

@attio/fetchable 共发布 8 个版本,首次发布于 2025/03/13;过去 12 个月发布了 3 个版本。

版本发布日期距今
0.0.1-experimental.9latest2025/12/0411 个月前
0.0.1-experimental.82025/12/0211 个月前
0.0.1-experimental.72025/12/0211 个月前
0.0.1-experimental.62025/09/021.2 年前
0.0.1-experimental.52025/04/211.5 年前
0.0.1-experimental.42025/03/141.7 年前

关于 @attio/fetchable 的常见问题

@attio/fetchable 是什么?

fetchable is a library for explicitly handling errors and loading in Typescript and JavaScript.

如何安装 @attio/fetchable?

在项目目录运行 npm install @attio/fetchable,或使用 pnpm add / yarn add / bun add。

@attio/fetchable 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@attio/fetchable 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@attio/fetchable 可以商用吗?

@attio/fetchable 使用 未声明 许可。package.json 没有声明许可证。没有许可证的代码默认保留全部权利,商用前请联系作者或查看仓库中的 LICENSE 文件。以上为概括,不构成法律意见,请以许可原文为准。

@attio/fetchable 的下载量有多少?

根据 npm 官方下载统计,@attio/fetchable 在 2026/10/07 – 2026/11/05 这 30 天内被下载 57,183 次,日均约 1,906 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@attio/fetchable 还在维护吗?

最新版本 0.0.1-experimental.9 发布于 2025/12/04(11 个月前);至今共发布 8 个版本,其中过去 12 个月发布了 3 个;首次发布于 2025/03/13。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。