UNPKG

@tempots/ui

Version:

Provides a higher level of renderables to help fast development with Tempo.

60 lines (59 loc) 2.67 kB
import { Signal } from '@tempots/dom'; import { AsyncResult, NonLoading } from '@tempots/std'; /** * A write-side wrapper for async state around POST/PUT/PATCH/DELETE. * Mirrors AsyncResource but the action is explicit (execute), not implicit (reload). * * @template Req - The request payload/type you send. * @template Res - The response/value you get back on success. * @template E - The error type on failure. */ export interface MutationResource<Req, Res, E> { /** Current async status (Idle | Loading | Success | Failure). */ readonly status: Signal<AsyncResult<Res, E>>; /** Latest successful value (if any). */ readonly value: Signal<Res | undefined>; /** Latest error (if any). */ readonly error: Signal<E | undefined>; /** Whether a mutation is currently in flight. */ readonly pending: Signal<boolean>; /** Execute the mutation. */ readonly execute: (request: Req, options?: MutationResourceExecuteOptions<Req, Res, E>) => void; /** Abort the current in-flight request (if any) and clean up. */ readonly cancel: (newState?: NonLoading<Res, E>) => void; /** Dispose of resources, aborting any in-flight request. */ readonly dispose: () => void; } /** * Execution-time options for a mutation. * Useful for optimistic UI and side-effects. */ export interface MutationResourceExecuteOptions<Req, Res, E> { /** The request to execute the mutation. */ readonly request: Req; /** External abort signal for this single execution. */ readonly abortSignal: AbortSignal; /** The previous result of the mutation, if any. */ readonly previous: AsyncResult<Res, E>; /** * Optionally provide an optimistic value to set immediately. * This will set status to Loading with value prefilled. */ readonly optimisticValue?: Res; /** * Optionally derive an optimistic value from the request. * Runs only if optimisticValue is not provided. */ readonly optimisticFromRequest?: (req: Req) => Res; /** Side-effects */ readonly onSuccess?: (value: Res, req: Req) => void; readonly onError?: (error: E, req: Req) => void; readonly onSettled?: (result: AsyncResult<Res, E>, req: Req) => void; } export declare const makeMutationResource: <Req, Res, E>({ mutate, convertError, onSuccess, onError, onSettled, }: { mutate: (options: MutationResourceExecuteOptions<Req, Res, E>) => Promise<Res>; convertError: (error: unknown) => E; onSuccess?: (value: Res, req: Req) => void; onError?: (error: E, req: Req) => void; onSettled?: (result: AsyncResult<Res, E>, req: Req) => void; }) => MutationResource<Req, Res, E>;