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 🙏

© 2026 – Pkg Stats / Ryan Hefner

alien-resources

v0.1.3

Published

Async signal bridge for alien-signals — reactive resources with loading/error states and automatic cancellation

Readme

alien-resources

Async signal bridge for alien-signals. Wraps async fetchers into reactive signals with loading/error states and automatic cancellation.

Install

npm install alien-resources alien-signals

alien-signals is a peer dependency.

Usage

import { signal, effect } from "alien-signals"
import { createResource } from "alien-resources"

const userId = signal("user-1")

// Resource tracks a fetcher — refetches when dependencies change
const profile = createResource(async (abort) => {
  const res = await fetch(`/api/users/${userId()}`, { signal: abort })
  return res.json()
})

// Read data, loading, and error reactively
effect(() => {
  if (profile.loading()) console.log("Loading...")
  else if (profile.error()) console.log("Error:", profile.error())
  else console.log("Data:", profile())
})

// Change dependency — automatically refetches (cancels in-flight request)
userId("user-2")

API

createResource(fetcher, options?)

Creates a reactive resource that tracks an async fetcher.

Parameters:

  • fetcher: (abort: AbortSignal) => Promise<T> — Async function that produces data. Receives an AbortSignal for cancellation. Any alien-signals signals read in the synchronous preamble (before the first await) become reactive dependencies.
  • options.initialValue?: T — Initial data value (default: undefined).

Returns: Resource<T>

| Member | Type | Description | |--------|------|-------------| | resource() | T \| undefined | Read current data. undefined while loading (unless initialValue set). | | resource.loading() | boolean | Whether a fetch is in progress. | | resource.error() | Error \| null | Error from last fetch, or null. | | resource.refetch() | void | Manually trigger a re-fetch. | | resource.mutate(value) | void | Optimistically set data (overwritten on next fetch). | | resource.dispose() | void | Stop tracking, cancel in-flight fetches. |

How It Works

  1. The fetcher runs inside an effect() tracking context.
  2. Any signals read during the fetcher's synchronous portion (before the first await) become dependencies.
  3. When dependencies change, the effect re-runs — aborting any in-flight request via AbortController and starting a new fetch.
  4. A monotonic fetch ID ensures only the latest fetch writes to the data/loading/error signals (stale responses are discarded).

Examples

Initial value

const data = createResource(
  async () => fetchExpensiveData(),
  { initialValue: [] }
)
// data() returns [] immediately, then the fetched result

Manual refetch

const feed = createResource(async () => fetchFeed())

// Poll every 30 seconds
setInterval(() => feed.refetch(), 30_000)

Optimistic update

const todos = createResource(async () => fetchTodos())

function addTodo(todo: Todo) {
  // Show immediately
  todos.mutate([...todos()!, todo])
  // Persist (refetch will overwrite with server state)
  postTodo(todo).then(() => todos.refetch())
}

Cleanup

const resource = createResource(async (abort) => {
  const res = await fetch(url, { signal: abort })
  return res.json()
})

// When done — stops tracking dependencies, cancels in-flight fetch
resource.dispose()

Credits & Inspiration

  • alien-signals by Johnson Chu — the reactive engine this package builds on. Fastest signals implementation, proven by Vue 3.6 adoption.
  • SolidJS by Ryan Carniato — pioneered createResource (Solid 1.x) and createAsync (Solid 2.0) for bridging async data into reactive graphs. The loading/error/refetch/mutate pattern originates here.
  • Angularresource() (Angular 17+) provides a similar async-to-signal bridge with .value(), .isLoading(), .error().
  • TanStack Query — popularized the loading/error/refetch pattern for async data in React. Not signal-based, but the UX conventions (stale-while-revalidate, optimistic updates) influenced this API.

Compatibility

This package is not API-compatible with SolidJS createResource or Angular resource(). It follows alien-signals conventions (callable accessors: resource() not resource.value, .loading() not .loading). SolidJS returns [data, { loading, error, refetch, mutate }] (tuple); this returns a single callable with signal sub-properties. The concepts are the same; the ergonomics match the alien-signals ecosystem.

See Also

  • alien-projections — Incremental reactive collection transforms for alien-signals. createProjection(source, { key, map, filter, sort }) only re-maps changed entries. The companion package for derived collections.
  • @silvery/signals — The Silvery TUI framework includes alien-resources and alien-projections as part of its @silvery/signals package, adding React integration (useSignal), deep stores (createStore), and model factories on top.

License

MIT