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

@asyncflowstate/core

v3.0.0

Published

Framework-agnostic core for AsyncFlowState. A tiny, powerful engine to orchestrate complex async UI behaviors, retries, and optimistic updates.

Readme


Installation

npm install @asyncflowstate/core
# or
pnpm add @asyncflowstate/core

Quick Start

import { Flow } from "@asyncflowstate/core";

// 1. Create a flow for any async action
const saveFlow = new Flow(async (data) => {
  const response = await fetch("/api/save", {
    method: "POST",
    body: JSON.stringify(data),
  });
  return response.json();
});

// 2. Subscribe to state changes
saveFlow.subscribe((state) => {
  console.log("Status:", state.status); // 'idle' | 'loading' | 'success' | 'error'
  console.log("Data:", state.data);
  console.log("Error:", state.error);
});

// 3. Execute the flow
await saveFlow.execute({ name: "John" });

Key Features

Concurrency Strategies

Control what happens when execute() is called while an action is already running.

  • keep (default): Ignore the new request.
  • restart: Abort the current request and start the new one.
const flow = new Flow(fetchData, { concurrency: "restart" });

Perception & UX Polish

Prevent UI flashes by ensuring loading states show for a appropriate amount of time.

  • delay: Wait before switching to loading status (prevents flicker for fast actions).
  • minDuration: Stay in loading state for at least this long once switched.
const flow = new Flow(saveData, {
  loading: {
    delay: 200, // Only show spinner if > 200ms
    minDuration: 500, // If shown, keep for at least 500ms
  },
});

Resilience (Retry)

Built-in retry logic with fixed, linear, or exponential backoff.

const flow = new Flow(flakeyAction, {
  retry: {
    maxAttempts: 3,
    delay: 1000,
    backoff: "exponential",
  },
});

Optimistic UI

Update the state immediately before the action completes.

const flow = new Flow(updateName, {
  optimisticResult: "New Name",
});

flow.execute();
console.log(flow.data); // "New Name" (instantly)

Progress Tracking

Manually report progress for long-running tasks.

const flow = new Flow(async () => {
  flow.setProgress(50); // halfway done
});

console.log(flow.progress); // 50

Polling

Automatically re-execute the action at a fixed interval.

const flow = new Flow(fetchPrice, {
  polling: {
    interval: 5000, // Every 5 seconds
    stopIf: (data) => data.isClosed, // Stop when condition met
    stopOnError: true,
  },
});

flow.execute(); // Starts execution and subsequent polls

Preconditions

Prevent execution based on custom logic.

const flow = new Flow(saveData, {
  precondition: () => isAuthenticated(),
  onBlocked: () => redirectToLogin(),
});

FlowSequence

Run multiple flows in order with shared state.

import { FlowSequence } from "@asyncflowstate/core";

const sequence = new FlowSequence([
  { name: "Auth", flow: loginFlow },
  { name: "Fetch", flow: dataFlow, mapInput: (auth) => auth.token },
]);

await sequence.execute();

FlowParallel

Execute multiple flows in parallel with aggregate state. Supports all, allSettled, and race strategies.

import { FlowParallel } from "@asyncflowstate/core";

const parallel = new FlowParallel([widget1Flow, widget2Flow], "all");
await parallel.execute();
console.log(parallel.state.progress); // Average progress of all flows

Streaming Support (LLM/AI)

Native support for AsyncIterable and ReadableStream. The flow status switches to 'streaming' until completion.

const flow = new Flow(async (prompt) => {
  const response = await ai.stream(prompt);
  return response.body; // ReadableStream
});

flow.subscribe((state) => {
  if (state.status === "streaming") {
    processChunk(state.data);
  }
});

Persistent Circuit Breaker

Prevents cascading failures by "tripping" the circuit after thresholds are met. State is persisted to localStorage.

const flow = new Flow(flakeyAPI, {
  circuitBreaker: {
    failureThreshold: 5,
    resetTimeout: 30000,
  },
  circuitBreakerKey: "user-api-circuit",
});

Declarative Chaining (Signals)

Use signals to chain flows without manual useEffect or complex orchestration.

const saveFlow = new Flow(saveUser);
const emailFlow = new Flow(sendEmail, {
  triggerOn: [saveFlow.signals.success],
});

Event System (Debugger Support)

Subscribe to global events for monitoring or logging.

const cleanup = Flow.onEvent((event) => {
  console.log(
    `${event.flowName} [${event.flowId}]: ${event.type}`,
    event.state,
  );
});

New in v3.0

  • Flow DNA: Self-healing async state that learns from environment patterns and user behavior.
  • Ambient Intelligence: Non-intrusive monitoring that predicts and optimizes background flows.
  • Flow Choreography: Declarative coordination of complex, multi-stage async workflows.
  • Speculative Execution: Run flows before users even click, based on high-confidence intent prediction.
  • Emotional UX: Adaptive UI transitions and skeleton states that respond to user sentiment and system load.
  • Flow Mesh: Cross-tab and cross-device orchestration with leader election and shared state.
  • Collaborative Flows: Sync async state in real-time across multiple users and browser sessions.
  • Temporal Replay: Time-travel through any async flow state with full state restoration.
  • Edge-First Flows: Optimized for Cloudflare Workers, Vercel Edge, and Deno with automatic failover.
  • Telemetry Dashboard: Real-time visualization of all flow health, latency, and throughput.

API Reference

Flow<TData, TError, TArgs>

Constructor

new Flow(action, options?)

Properties

  • status: 'idle' | 'loading' | 'streaming' | 'success' | 'error'
  • data: TData | null
  • error: TError | null
  • progress: number (0-100)
  • isLoading: boolean (Returns false if currently in loading.delay period)
  • state: The full state snapshot.

Methods

  • execute(...args: TArgs): Promise<TData | undefined>
  • cancel(): void
  • reset(): void
  • setProgress(value: number): void
  • subscribe(listener: (state) => void): () => void

License

MIT © AsyncFlowState Contributors