@data-client/core
v0.14.16
Published
Async State Management without the Management. REST, GraphQL, SSE, Websockets, Fetch
Downloads
4,153
Maintainers
Readme
Reducer/flux normalized, framework-agnostic data store. Includes managers/middleware, global referential equality guarantees, automatic expiry policies, data normalization. Consumes TypeScript Standard Endpoints
📖Read The Docs | 🏁Getting Started | 🎮Todo Demo | 🎮Github Demo | 🎮NextJS SSR Demo
Framework Implementations
Sample React Hook suspense implementation
function useSuspense(endpoint, ...args)
const state = useCacheState();
const controller = useController();
const key = args[0] !== null ? endpoint.key(...args) : '';
const cacheResults = key && state.endpoints[key];
const meta = state.meta[key];
// Compute denormalized value
const { data, expiryStatus, expiresAt } = useMemo(() => {
return controller.getResponse(endpoint, ...args, state);
}, [
cacheResults,
state.indexes,
state.entities,
state.entityMeta,
meta,
key,
]);
const error = controller.getError(endpoint, ...args, state);
// If we are hard invalid we must fetch regardless of triggering or staleness
const forceFetch = expiryStatus === ExpiryStatus.Invalid;
const maybePromise = useMemo(() => {
// null params mean don't do anything
if ((Date.now() <= expiresAt && !forceFetch) || !key) return;
return controller.fetch(endpoint, ...args);
// we need to check against serialized params, since params can change frequently
}, [expiresAt, controller, key, forceFetch, state.lastReset]);
// fully "valid" data will not suspend even if it is not fresh
if (expiryStatus !== ExpiryStatus.Valid && maybePromise) {
throw maybePromise;
}
if (error) throw error;
return data;
}
API
- Controller
- Middleware: LogoutManager, NetworkManager, SubscriptionManager, PollingSubscription, DevToolsManager
- State: createReducer(), initialState, applyManager