diff --git a/packages/toolkit/src/query/core/buildMiddleware/applyUpdates.ts b/packages/toolkit/src/query/core/buildMiddleware/applyUpdates.ts new file mode 100644 index 0000000000..4caefcded0 --- /dev/null +++ b/packages/toolkit/src/query/core/buildMiddleware/applyUpdates.ts @@ -0,0 +1,66 @@ +import type { EndpointDefinitions } from '../../endpointDefinitions' +import type { + AllQueryKeys, + DataFromAnyQueryDefinition, + QueryArgFromAnyQueryDefinition, + Recipe, +} from '../buildThunks' + +export enum UpdateKind { + update = 'update', + upsert = 'upsert', +} + +export enum UpdateMode { + optimistic = 'optimistic', + pessimistic = 'pessimistic', +} + +export interface UpdateDescription< + Kind extends UpdateKind, + Mode extends UpdateMode, + EndpointName extends PropertyKey, + Arg, + Result, +> { + kind: Kind + mode: Mode + endpointName: EndpointName + arg: Arg + update: Recipe +} + +export type UpdateDescriptions = ReadonlyArray< + UpdateDescription +> + +export type UpdateDescriptionFactory< + Definitions extends EndpointDefinitions, + Kind extends UpdateKind, + Mode extends UpdateMode, +> = >( + endpointName: EndpointName, + arg: QueryArgFromAnyQueryDefinition, + update: Recipe>, +) => UpdateDescription< + Kind, + Mode, + EndpointName, + QueryArgFromAnyQueryDefinition, + DataFromAnyQueryDefinition +> + +export const buildUpdateFactory = + ( + kind: Kind, + mode: Mode, + ): UpdateDescriptionFactory => + (endpointName, arg, update) => { + return { + kind, + mode, + endpointName, + arg, + update, + } + } diff --git a/packages/toolkit/src/query/core/module.ts b/packages/toolkit/src/query/core/module.ts index e9bfa08b76..5e1bd52fa4 100644 --- a/packages/toolkit/src/query/core/module.ts +++ b/packages/toolkit/src/query/core/module.ts @@ -72,6 +72,12 @@ import { buildThunks } from './buildThunks' import { createSelector as _createSelector } from './rtkImports' import { onFocus, onFocusLost, onOffline, onOnline } from './setupListeners' import type { InternalMiddlewareState } from './buildMiddleware/types' +import type { UpdateDescriptionFactory } from './buildMiddleware/applyUpdates' +import { + UpdateKind, + UpdateMode, + buildUpdateFactory, +} from './buildMiddleware/applyUpdates' /** * `ifOlderThan` - (default: `false` | `number`) - _number is value in seconds_ @@ -395,6 +401,29 @@ export interface ApiModules< state: RootState, queryName: QueryName, ) => Array> + + build: { + optimisticUpdate: UpdateDescriptionFactory< + Definitions, + UpdateKind.update, + UpdateMode.optimistic + > + pessimisticUpdate: UpdateDescriptionFactory< + Definitions, + UpdateKind.update, + UpdateMode.pessimistic + > + optimisticUpsert: UpdateDescriptionFactory< + Definitions, + UpdateKind.upsert, + UpdateMode.optimistic + > + pessimisticUpsert: UpdateDescriptionFactory< + Definitions, + UpdateKind.upsert, + UpdateMode.pessimistic + > + } } /** * Endpoints based on the input endpoints provided to `createApi`, containing `select` and `action matchers`. @@ -616,6 +645,24 @@ export const coreModule = ({ prefetch, resetApiState: sliceActions.resetApiState, upsertQueryEntries: sliceActions.cacheEntriesUpserted as any, + build: { + optimisticUpdate: buildUpdateFactory( + UpdateKind.update, + UpdateMode.optimistic, + ), + pessimisticUpdate: buildUpdateFactory( + UpdateKind.update, + UpdateMode.pessimistic, + ), + optimisticUpsert: buildUpdateFactory( + UpdateKind.upsert, + UpdateMode.optimistic, + ), + pessimisticUpsert: buildUpdateFactory( + UpdateKind.upsert, + UpdateMode.pessimistic, + ), + }, }) safeAssign(api.internalActions, sliceActions)