@tahanabavi/typeaction
v1.0.0
Published
A lightweight React hook system for Next.js server actions with caching, retries, optimistic updates, and type safety.
Downloads
4
Maintainers
Readme
@tahanabavi/typeaction
A lightweight React utility for type-safe server actions. It simplifies working with async functions by providing useTransition-powered loading state, cache support, and type inference — all designed for modern React apps with Server Components and server actions.
Table of contents
- Why use this
- Features
- Install
- Quick start
- API reference
- Testing / Development
- Contributing
- Changelog
- License
- Maintainers & Support
Why use this
If you use Next.js Server Actions or any async functions in React, you often need boilerplate for:
- Loading state
- Caching results
- Reusing results across components
This package provides a minimal but extensible hook system for calling actions with isPending, mutate, and cache support.
Features
- ✅ Type-safe request/response with TypeScript inference
- ✅ Automatic loading state via
useTransition - ✅ Simple cache API (
invalidate,prefetch,getCache) - ✅ Works with Next.js Server Actions (
"use server") - ✅ Minimal, composable design — extend as needed
Install
npm install @tahanabavi/typeaction
# or
yarn add @tahanabavi/typeactionQuick start
- Server action
"use server";
export type RequestData = { id: number };
export type ResponseData = { message: string };
export async function fetchMessage(input: RequestData): Promise<ResponseData> {
await new Promise((resolve) => setTimeout(resolve, 500)); // simulate server delay
if (input.id < 0) throw new Error("Invalid ID");
return { message: `Hello ${input.id}` };
}- Hook
"use client";
import { createAction } from "@tahanabavi/typeaction";
import { fetchMessage, RequestData, ResponseData } from "./action";
// Wrap the server action with createAction
export const useFetchMessage = createAction<RequestData, ResponseData>(fetchMessage);- Usage
"use client";
import { useFetchMessage } from "./hook";
export default function App() {
const { mutate, data, error, isPending, reset, abort } = useFetchMessage({
key: "message",
optimisticUpdate: (prev: any, input: any) => ({
message: `Optimistic ${input.id}`,
}),
});
return (
<div>
<button onClick={() => mutate({ id: 1 })}>Fetch id=1</button>
<button onClick={() => mutate({ id: -1 })}>Fetch Invalid</button>
<button onClick={abort}>Abort</button>
<button onClick={reset}>Reset</button>
<div>Status: {isPending ? "Loading..." : "Idle"}</div>
<div>Data: {data?.message ?? "No data"}</div>
<div>Error: {error ? (error as Error).message : "No error"}</div>
</div>
);
}
API reference
createAction(fn, options)
Wraps an async function or server action.
| Parameter | Type | Description |
| ------------- | ------------------------- | ------------------------------- |
| fn | (data: T) => Promise<R> | Async function or server action |
| options.key | string (optional) | Unique key for caching results |
Returned API
const action = createAction(fn) returns an object with:
| Method | Description |
| -------------- | -------------------------------------------------------- |
| useAction() | Hook that exposes isPending, mutate, data, error |
| invalidate() | Clears cached data for this action |
| prefetch(d) | Runs action in background and caches it |
Inside useAction()
| Property | Type | Description |
| ----------- | ------------ | ------------------------------- |
| isPending | boolean | True while action is running |
| mutate(d) | Promise<R> | Runs the action with input d |
| data | R \| null | Last successful result (cached) |
| error | any | Last error if call failed |
Testing / Development
Run unit tests with Jest:
npm testBuild TypeScript:
npm run buildLocal develop/test with another app:
npm linkContributing
Contributions are welcome! Please follow these steps:
- Fork the repository
- Create a feature branch:
git checkout -b feat/my-feature - Run tests and linters locally
- Open a PR with a clear description and changelog entry (if applicable)
Please include tests for new features and follow the established code style.
Maintainers & Support
Maintained by @tahanabavi.
For issues, please open a GitHub issue in this repository. For questions or suggestions, create an issue or reach out on GitHub Discussions.
Thank you for using @tahanabavi/typeaction — feedback and contributions are highly appreciated!
