feat(store): useMutation hook for react (#290)

This commit is contained in:
rahim
2026-01-07 00:10:41 +11:00
committed by GitHub
parent a71a280bdc
commit ecd4940bc7
23 changed files with 827 additions and 398 deletions
+4 -8
View File
@@ -1,23 +1,19 @@
export type { AsyncStatus } from '../../core/queue';
export { MutationController } from './mutation-controller';
export type {
AsyncStatus,
MutationError,
MutationIdle,
MutationPending,
MutationResult,
MutationSuccess,
} from './mutation-controller';
export { OptimisticController } from './optimistic-controller';
export type {
OptimisticError,
OptimisticIdle,
OptimisticPending,
OptimisticResult,
OptimisticSuccess,
} from './optimistic-controller';
} from '../../shared/types';
export { MutationController } from './mutation-controller';
export { OptimisticController } from './optimistic-controller';
export { RequestController } from './request-controller';
export { SelectorController } from './selector-controller';
export { TasksController } from './tasks-controller';
@@ -1,48 +1,11 @@
import type { ReactiveController, ReactiveControllerHost } from '@lit/reactive-element';
import type { EnsureFunction } from '@videojs/utils/types';
import type { AsyncStatus, Task } from '../../core/queue';
import type { Task } from '../../core/queue';
import type { AnyStore, InferStoreRequests } from '../../core/store';
import type { MutationResult } from '../../shared/types';
import { noop } from '@videojs/utils/function';
// ----------------------------------------
// Mutation Types
// ----------------------------------------
interface MutationBase<Mutate> {
status: AsyncStatus;
mutate: Mutate;
reset: () => void;
}
export interface MutationIdle<Mutate> extends MutationBase<Mutate> {
status: 'idle';
}
export interface MutationPending<Mutate> extends MutationBase<Mutate> {
status: 'pending';
}
export interface MutationSuccess<Mutate, Data> extends MutationBase<Mutate> {
status: 'success';
data: Data;
}
export interface MutationError<Mutate> extends MutationBase<Mutate> {
status: 'error';
error: unknown;
}
export type MutationResult<Mutate, Data>
= | MutationIdle<Mutate>
| MutationPending<Mutate>
| MutationSuccess<Mutate, Data>
| MutationError<Mutate>;
// ----------------------------------------
// Controller
// ----------------------------------------
/**
* Tracks a mutation's status with discriminated union result.
* Triggers host updates when the task status changes.
@@ -2,46 +2,10 @@ import type { ReactiveController, ReactiveControllerHost } from '@lit/reactive-e
import type { EnsureFunction } from '@videojs/utils/types';
import type { Task } from '../../core/queue';
import type { AnyStore, InferStoreRequests, InferStoreState } from '../../core/store';
import type { OptimisticResult } from '../../shared/types';
import { Disposer } from '@videojs/utils/events';
// ----------------------------------------
// Optimistic Types
// ----------------------------------------
interface OptimisticBase<Value, SetValue> {
value: Value;
setValue: SetValue;
reset: () => void;
}
export interface OptimisticIdle<Value, SetValue> extends OptimisticBase<Value, SetValue> {
status: 'idle';
}
export interface OptimisticPending<Value, SetValue> extends OptimisticBase<Value, SetValue> {
status: 'pending';
}
export interface OptimisticSuccess<Value, SetValue> extends OptimisticBase<Value, SetValue> {
status: 'success';
}
export interface OptimisticError<Value, SetValue> extends OptimisticBase<Value, SetValue> {
status: 'error';
error: unknown;
}
export type OptimisticResult<Value, SetValue>
= | OptimisticIdle<Value, SetValue>
| OptimisticPending<Value, SetValue>
| OptimisticSuccess<Value, SetValue>
| OptimisticError<Value, SetValue>;
// ----------------------------------------
// Controller
// ----------------------------------------
/**
* Shows optimistic value while mutation is pending, actual value otherwise.
* When setValue is called, immediately shows the new value while the request