angular-fetcher
Version:
Signal-based state management for remote API data in Angular with support for reactive loading, error tracking, optimistic updates, and auto refetching.
77 lines • 2.62 kB
TypeScript
import { MutationHandlers, WithResourceOptions } from "../models";
import { Signal } from "@angular/core";
import { Observable } from "rxjs";
/**
* Extended options for `withResource`.
*
* @typeParam T Type of the resource data.
*/
interface ExtendedWithResourceOptions<T> extends WithResourceOptions {
/**
* Initial value used when no resource has been loaded or after invalidation.
*/
emptyValue?: T;
}
/**
* Manages API data with reactive signals in Angular applications.
*
* @public
* @typeParam T Resource data type.
* @typeParam E Error type (default: unknown).
*
* @param loader A method that returns `Observable<T>` (e.g., from a service method).
* @param options Optional configuration, including `destroy$` for cleanup.
*
* @returns Resource controller with reactive state and methods:
* - `state`: Signals for data, loading, and error.
* - `fetch()`: Fetches data.
* - `update()`: Updates local data.
* - `withMutation()`: Executes mutations with optional optimistic updates.
* - `invalidate()`: Clears and refetches data.
* - `abort()`: Cancels ongoing requests.
*
* @example
* ```ts
* // user.service.ts
* export class UserService {
* getUser() { return this.http.get('/api/user'); }
* updateUser(data) { return this.http.put('/api/user', data); }
* userResource = withResource(() => this.getUser());
* }
*
* // user.component.ts
* userResource.fetch();
* userResource.withMutation(updateUser({ name: 'foo' }), {
* key: 'update-user',
* optimisticUpdate: (prev) => ({ ...prev, name: 'foo' })
* });
* ```
*/
export declare function withResource<T, E = unknown>(loader: () => Observable<T>, options?: ExtendedWithResourceOptions<T>): {
state: {
/** Current resource data. */
data: Signal<T>;
/** Fetch operation status. */
fetchLoading: Signal<boolean>;
/** Mutation operation status. */
mutationLoading: Signal<boolean>;
/** Individual mutation loading states by key. */
mutationLoadingKey: Signal<{
[key: string]: boolean;
}>;
/** Latest error, if any. */
error: Signal<E | null>;
/** Whether resource data is empty. */
isEmpty: Signal<boolean>;
};
fetch: (handlers?: {
next?: (res: T) => void;
error?: (err: any) => void;
}) => void;
update: (updater: (prev: T) => T) => void;
withMutation: <R>(request$: Observable<R>, handlers: MutationHandlers<R, T>) => void;
invalidate: () => void;
abort: () => void;
};
export {};
//# sourceMappingURL=withResource.d.ts.map