Skip to content

devhimanshuu/asyncflowstate

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

62 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
AsyncFlowState Logo

AsyncFlowState

The industry-standard engine for predictable async UI behavior.

Eliminate boilerplate and bugs in async interactions. Built for React, Vue, Svelte, Angular, Solid — works everywhere.

Documentation Tests License: MIT NPM Version


The Problem

Every modern application has async user actions: clicking buttons, submitting forms, saving data, deleting items, uploading files, or making payments.

Each of these actions follows the same lifecycle: idle → loading → success → error → retry

But in real projects, this logic is re-written thousands of times. This leads to:

  • Double submission bugs (user clicks twice)
  • Inconsistent loading UX (spinners everywhere, or nowhere)
  • Error handling chaos (forgotten catch blocks, messy transitions)
  • Boilerplate fatigue (writing setIsLoading(true) on every function)

What AsyncFlowState Solves

AsyncFlowState provides a standard, reusable engine to control async UI behavior correctly and consistently. It is not a data-fetching library (like React Query) or a state manager (like Redux); it is a behavior orchestrator.

  • Double submissions? Prevented by default.
  • Optimistic UI? One line of config, with Deep-Diff Rollbacks.
  • Global Undo? Purgatory delays destructive actions dynamically.
  • Worker Offloading? Push intense ops to a background thread instantly (flow.worker()).
  • Ghost Queues? Spam clicking handled via background queues seamlessly.
  • Dead Letter Queue (DLQ)? Failed operations automatically pooled for replay.
  • Feature Convergence? cross-tab sync, AI Skeletons, and Predictive Prefetching built right in.

Why AsyncFlowState?

vs. Manual State Management

  • 90% less boilerplate
  • Zero double-submission bugs
  • Enterprise-grade error resilience (DLQ, Retries, Circuit Breakers)

vs. React Query / SWR

  • Designed for actions, not data fetching
  • Works with any async function (API, WebSockets, LocalStorage, LLMs)
  • Powerful composition (pipe, chain, raceFlows)

vs. Redux / Zustand

  • Focused on behavior orchestration, not pure global state
  • Time-Travel debugger with exportState() directly built-in
  • Works flawlessly alongside your existing state manager

The Difference (Before vs After)

Here is a common scenario: Submitting a form and handling the API response.

Before (Manual State Management)

const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);

const handleSubmit = async (data) => {
  setLoading(true);
  setError(null);
  try {
    await api.save(data);
    alert("Saved!");
  } catch (err) {
    setError(err);
  } finally {
    setLoading(false);
  }
};

return (
  <button onClick={handleSubmit} disabled={loading}>
    {loading ? "Saving..." : "Save"}
  </button>
);

After (With AsyncFlowState)

const flow = useFlow(api.save, {
  onSuccess: () => alert("Saved!"),
});

return (
  <button {...flow.button()}>{flow.loading ? "Saving..." : "Save"}</button>
);

See more patterns? Check out our Full Comparison Guide.


Package Ecosystem

AsyncFlowState is built as a modular system:

Package Version Description NPM
@asyncflowstate/core 2.0.2 Framework-agnostic logic engine npm
@asyncflowstate/react 2.0.2 React hooks & accessibility-first helpers npm
@asyncflowstate/next 2.0.2 Next.js Server Actions & SSR integration npm
@asyncflowstate/vue 2.0.2 Vue 3 composables & provide/inject config npm
@asyncflowstate/svelte 2.0.2 Svelte stores with $ auto-subscription npm
@asyncflowstate/angular 2.0.2 Angular Observable/BehaviorSubject bindings npm
@asyncflowstate/solid 2.0.2 SolidJS fine-grained reactive signals npm

Quick Start

1. Installation

AsyncFlowState consists of a core engine and native adapters for each framework.

Framework Command
React npm install @asyncflowstate/react @asyncflowstate/core
Next.js npm install @asyncflowstate/next @asyncflowstate/react @asyncflowstate/core
Vue 3 npm install @asyncflowstate/vue @asyncflowstate/core
Svelte npm install @asyncflowstate/svelte @asyncflowstate/core
Angular npm install @asyncflowstate/angular @asyncflowstate/core
SolidJS npm install @asyncflowstate/solid @asyncflowstate/core

2. Basic Usage (React)

import { useFlow } from "@asyncflowstate/react";

function SaveButton() {
  const flow = useFlow(async (data) => {
    return await api.save(data);
  });

  return (
    <button {...flow.button()}>
      {flow.loading ? "Saving..." : "Save Changes"}
    </button>
  );
}

3. Server Actions (Next.js)

"use client";

import { useServerActionFlow } from "@asyncflowstate/next";
import { saveUserAction } from "./actions";

function ProfileForm() {
  const flow = useServerActionFlow(saveUserAction);

  return (
    <form action={flow.execute}>
      <input name="name" />
      <button type="submit" disabled={flow.loading}>
        {flow.loading ? "Saving..." : "Save"}
      </button>
    </form>
  );
}

3. Sequential Workflows

import { useFlowSequence } from "@asyncflowstate/react";

const steps = [
  { name: "Step 1", flow: flow1 },
  { name: "Step 2", flow: flow2, mapInput: (prev) => prev.id },
];

const sequence = useFlowSequence(steps);
// sequence.execute() runs them in order

3. Form Handling (Native Zod/Valibot)

import { z } from "zod";

const schema = z.object({
  username: z.string().min(3),
  email: z.string().email(),
});

function ProfileForm() {
  const flow = useFlow(updateProfile);

  return (
    <form {...flow.form({ schema, extractFormData: true })}>
      <input name="username" />
      {flow.fieldErrors.username && <span>{flow.fieldErrors.username}</span>}

      <input name="email" />
      {flow.fieldErrors.email && <span>{flow.fieldErrors.email}</span>}

      <button type="submit" disabled={flow.loading}>
        Submit
      </button>
      {flow.error && <p ref={flow.errorRef}>{flow.error.message}</p>}
    </form>
  );
}

4. Global Configuration

import { FlowProvider } from "@asyncflowstate/react";

function App() {
  return (
    <FlowProvider
      config={{
        onError: (err) => toast.error(err.message),
        retry: { maxAttempts: 3, backoff: "exponential" },
      }}
    >
      <YourApp />
    </FlowProvider>
  );
}

5. Vue 3

pnpm add @asyncflowstate/vue @asyncflowstate/core
<script setup lang="ts">
import { useFlow } from "@asyncflowstate/vue";

const { loading, data, execute, button } = useFlow(async (id: string) =>
  api.fetchUser(id),
);
</script>

<template>
  <button v-bind="button()">
    {{ loading ? "Loading..." : "Fetch User" }}
  </button>
</template>

6. Svelte

pnpm add @asyncflowstate/svelte @asyncflowstate/core
<script>
import { createFlow } from '@asyncflowstate/svelte';
const flow = createFlow(async (id) => api.fetchUser(id));
</script>

<button on:click={() => flow.execute('user-123')} disabled={$flow.loading}>
  {$flow.loading ? 'Loading...' : 'Fetch User'}
</button>

7. Angular

pnpm add @asyncflowstate/angular @asyncflowstate/core
import { createFlow } from "@asyncflowstate/angular";

@Component({
  template: `
    <ng-container *ngIf="userFlow.state$ | async as state">
      <button (click)="userFlow.execute('user-123')" [disabled]="state.loading">
        {{ state.loading ? "Loading..." : "Fetch User" }}
      </button>
    </ng-container>
  `,
})
export class UserComponent implements OnDestroy {
  userFlow = createFlow(async (id: string) => api.fetchUser(id));
  ngOnDestroy() {
    this.userFlow.destroy();
  }
}

8. SolidJS

pnpm add @asyncflowstate/solid @asyncflowstate/core
import { createFlow } from "@asyncflowstate/solid";

function UserCard() {
  const flow = createFlow(async (id: string) => api.fetchUser(id));
  return (
    <button onClick={() => flow.execute("user-123")} disabled={flow.loading()}>
      {flow.loading() ? "Loading..." : "Fetch User"}
    </button>
  );
}

Key Features

  • Global Config: Set default options app-wide with FlowProvider.
  • Declarative Chaining: Orchestrate complex workflows with triggerOn and signals instead of manual useEffect.
  • Streaming Support: Native support for LLM/AI streaming using AsyncIterable or ReadableStream.
  • Parallel & Sequential: Orchestrate multiple flows with aggregate state via FlowParallel and FlowSequence.
  • Declarative Polling: Built-in support for auto-refreshing actions with conditional stop logic.
  • Smart Persistence: Survive page refreshes and resume interrupted operations (file uploads, forms, etc.).
  • Persistent Circuit Breaker: Prevent cascading failures with cross-session state persistence.
  • Visual Sequence Trace: Real-time Timeline/Gantt view of all async activity with FlowDebugger.
  • Form Recovery: Automatically re-focus fields and restore validation errors after a page refresh.
  • Global Notifications: Centralized success/error handling for all flows via FlowNotificationProvider.
  • Core Engine: Lightweight runtime logic that works anywhere (Vanilla JS, Node, etc.).

Learn More


Contributing

We love contributions! Whether you're fixing a bug, improving documentation, or suggesting a new feature, your help is welcome.

  1. Check for Issues: Look at our Issue Tracker to see if your idea or bug is already being addressed.
  2. Follow the Guide: Read our Contributing Guide for local setup, development workflows, and coding standards.
  3. Submit a PR: When you're ready, use our Pull Request Template to ensure your contribution meets our quality standards.

Security Policy

We take the security of AsyncFlowState seriously. If you find a potential vulnerability, please do not open a public issue. Instead, follow the instructions in our Security Policy to report it responsibly.


Code of Conduct

To ensure a welcoming, diverse, and inclusive community, we adhere to the Contributor Covenant Code of Conduct. By participating in this project, you agree to abide by its terms.


License

MIT © AsyncFlowState Contributors


"Stop rewriting the same async logic. Start building features."

AsyncFlowState solves async UI behavior once, correctly, and everywhere.

About

A high-performance orchestration engine for asynchronous UI states. Standardize idle → loading → success → error lifecycles across your entire stack. Built-in protection against race conditions, native Zod integration, and cross-session form persistence. Stop managing states, start defining flows

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors