use-api-kt
v1.0.0
Published
Tiny helper to manage short-lived authorization data (tokens), refresh credentials, retry failed API calls after refresh, and abort in-flight requests.
Maintainers
Readme
use-api-kt
A tiny, dependency-free helper for managing short-lived authorization data and safely calling APIs that require it.
This package provides a simple pattern for fetching/refreshing authorization credentials (e.g. access tokens) and using them in API calls. It handles an initial authorization fetch, optional periodic "hydration" (refresh), retrying a failed API call after refreshing credentials, and aborting in-flight requests.
Install
npm install use-api-kt
# or
yarn add use-api-ktQuick example (TypeScript)
import { createApiManager } from "use-api-kt";
// imaginary function that fetches a fresh token
async function fetchAuth(_signal: AbortSignal) {
const res = await fetch("https://auth.example.com/token", { signal: _signal });
if (!res.ok) throw new Error("failed to fetch token");
return (await res.json()).accessToken;
}
async function main() {
const manager = await createApiManager({
callback: fetchAuth,
onError: (err) => {
// called when a useApi call throws. Return true to reattempt
// after refreshing auth data, or false to bubble the error.
console.warn("API call failed, will reattempt after refresh", err);
return true; // reattempt by default
},
// optional: refresh token every 5 minutes
hydrationIntervalInMs: 5 * 60 * 1000,
});
// run an API call that needs the token
const data = await manager.useApi(async (token, signal) => {
const r = await fetch("https://api.example.com/me", {
headers: { Authorization: `Bearer ${token}` },
signal,
});
if (!r.ok) throw new Error("api error");
return r.json();
});
console.log(data);
// When done, which aborts any ongoing calls and closes hydrations
manager.cleanup();
}
main().catch(console.error);JavaScript (CommonJS) example
const { createApiManager } = require("use-api-kt");
async function fetchAuth(signal) {
const res = await fetch("https://auth.example.com/token", { signal });
if (!res.ok) throw new Error("failed to fetch token");
return (await res.json()).accessToken;
}
(async () => {
const manager = await createApiManager({ callback: fetchAuth });
try {
const result = await manager.useApi((token, signal) =>
fetch("https://api.example.com/data", { headers: { Authorization: `Bearer ${token}` }, signal })
.then(r => r.json())
);
console.log(result);
} finally {
manager.cleanup();
}
})();API Reference
createApiManager({ callback, onError?, hydrationIntervalInMs? }) => Promise<{ startHydration, stopHydration, useApi, abort, cleanup }>
callback: (abortSignal: AbortSignal) => T | Promise
- Called to obtain the auth/credential data. Called once during manager creation and again when the cache is empty or a re-hydration/refresh is needed.
- Receives an AbortSignal so you can cancel any network requests.
onError?: (error: any) => boolean | Promise
- Called when a
useApicallback throws. Should returntrueto reattempt the call after refreshing credentials, orfalseto rethrow the original error. - If not provided, the manager defaults to reattempting on error.
- Called when a
hydrationIntervalInMs?: number
- If provided, the manager will periodically call
callbackand refresh the cached auth data.
- If provided, the manager will periodically call
Returned helpers
useApi(useApiCallback: (authData: T, abortSignal: AbortSignal) => Promise | R): Promise
- Use this to perform API calls that depend on the auth data. If the call throws,
onErrordetermines whether the manager should refresh credentials and retry once.
- Use this to perform API calls that depend on the auth data. If the call throws,
startHydration(): void
- Start the periodic refresh (requires
hydrationIntervalInMsto be set).
- Start the periodic refresh (requires
stopHydration(): void
- Stop the periodic refresh.
abort(): void
- Abort current in-flight requests and create a fresh internal AbortController.
cleanup(): void
- Convenience to stop hydration and abort in-flight requests.
Behavior notes and edge cases
Initial callback invocation:
createApiManagercalls yourcallbackonce during setup to populate the cached auth data. If it throws, the error will bubble up.Default onError behavior: If
onErroris not provided, the manager will reattempt a faileduseApicall once by refreshing credentials. ProvideonErrorto customize this behavior.Aborting: The manager exposes
abort()to cancel current in-flight requests. The internal AbortController is replaced after aborting so future calls get a fresh signal.Hydration: Use
hydrationIntervalInMsfor periodic refresh (for example to refresh short-lived tokens). Hydration errors are caught and logged; they don't throw.
Quick patterns
Refresh-only on-demand (no hydration): call
useApi, rely ononErrorto returntrueso failed calls are retried after refresh.Scheduled refresh: pass
hydrationIntervalInMsto keep the auth data fresh in the background.
Testing tips
- Keep
callbacksmall and easy to stub in tests; e.g. return a static token string or an in-memory rotating value. - Test
onErrorbehavior by makinguseApithrow once and assert that thecallbackis called again before retry.
License
MIT
Contributions
PRs welcome — keep changes small and add tests where applicable.
