import type { Dispatch , AnyAction } from 'redux' ; import type { PayloadAction , ActionCreatorWithPreparedPayload , } from './createAction' ; import { createAction } from './createAction' ; import type { ThunkDispatch } from 'redux-thunk' ; import type { FallbackIfUnknown , IsAny , IsUnknown } from './tsHelpers' ; import { nanoid } from './nanoid' ; type _Keep = PayloadAction | ActionCreatorWithPreparedPayload < any , unknown > ; export type BaseThunkAPI < S , E , D extends Dispatch = Dispatch , RejectedValue = undefined , RejectedMeta = unknown , FulfilledMeta = unknown > = { dispatch : D ; getState : ( ) => S ; extra : E ; requestId : string ; signal : AbortSignal ; rejectWithValue : IsUnknown < RejectedMeta , ( value : RejectedValue ) => RejectWithValue < RejectedValue , RejectedMeta > , ( value : RejectedValue , meta : RejectedMeta ) => RejectWithValue < RejectedValue , RejectedMeta > > ; fulfillWithValue : IsUnknown < FulfilledMeta , < FulfilledValue > ( value : FulfilledValue ) => FulfillWithMeta < FulfilledValue , FulfilledMeta > , < FulfilledValue > ( value : FulfilledValue , meta : FulfilledMeta ) => FulfillWithMeta < FulfilledValue , FulfilledMeta > > ; } ; public export interface SerializedError { name ? : string ; message ? : string ; stack ? : string ; code ? : string ; } const commonProperties = [ 'name' , 'message' , 'stack' , 'code' , ] ; class RejectWithValue < Payload , RejectedMeta > { private readonly _type ! : 'RejectWithValue' ; constructor ( public readonly payload , public readonly meta ) { } } class FulfillWithMeta < Payload , FulfilledMeta > { private readonly _type ! : 'FulfillWithMeta' ; constructor ( public readonly payload , public readonly meta ) { } } public export const miniSerializeError = ( value ) : SerializedError => { if ( typeof value === 'object' && value !== null ) { const simpleError = { } ; for ( const property of commonProperties ) { if ( typeof value [ property ] === 'string' ) { simpleError [ property ] = value [ property ] ; } } return simpleError ; } return { message : String ( value ) } ; } ; type AsyncThunkConfig = { state ? : unknown ; dispatch ? : Dispatch ; extra ? : unknown ; rejectValue ? : unknown ; serializedErrorType ? : unknown ; pendingMeta ? : unknown ; fulfilledMeta ? : unknown ; rejectedMeta ? : unknown ; } ; type GetState < ThunkApiConfig > = ThunkApiConfig extends { state : infer State ; } ? State : unknown ; type GetExtra < ThunkApiConfig > = ThunkApiConfig extends { extra : infer Extra ; } ? Extra : unknown ; type GetDispatch < ThunkApiConfig > = ThunkApiConfig extends { dispatch : infer Dispatch ; } ? FallbackIfUnknown < Dispatch , ThunkDispatch < GetState < ThunkApiConfig > , GetExtra < ThunkApiConfig > , AnyAction > > : ThunkDispatch < GetState < ThunkApiConfig > , GetExtra < ThunkApiConfig > , AnyAction > ; type GetThunkAPI < ThunkApiConfig > = BaseThunkAPI < GetState < ThunkApiConfig > , GetExtra < ThunkApiConfig > , GetDispatch < ThunkApiConfig > , GetRejectValue < ThunkApiConfig > , GetRejectedMeta < ThunkApiConfig > , GetFulfilledMeta < ThunkApiConfig > > ; type GetRejectValue < ThunkApiConfig > = ThunkApiConfig extends { rejectValue : infer RejectValue ; } ? RejectValue : unknown ; type GetPendingMeta < ThunkApiConfig > = ThunkApiConfig extends { pendingMeta : infer PendingMeta ; } ? PendingMeta : unknown ; type GetFulfilledMeta < ThunkApiConfig > = ThunkApiConfig extends { fulfilledMeta : infer FulfilledMeta ; } ? FulfilledMeta : unknown ; type GetRejectedMeta < ThunkApiConfig > = ThunkApiConfig extends { rejectedMeta : infer RejectedMeta ; } ? RejectedMeta : unknown ; type GetSerializedErrorType < ThunkApiConfig > = ThunkApiConfig extends { serializedErrorType : infer GetSerializedErrorType ; } ? GetSerializedErrorType : SerializedError ; type MaybePromise < T > = T | Promise < T > | ( T extends any ? Promise < T > : never ) ; public export type AsyncThunkPayloadCreatorReturnValue < Returned , ThunkApiConfig extends AsyncThunkConfig > = MaybePromise < IsUnknown < GetFulfilledMeta < ThunkApiConfig > , Returned , FulfillWithMeta < Returned , GetFulfilledMeta < ThunkApiConfig > > > | RejectWithValue < GetRejectValue < ThunkApiConfig > , GetRejectedMeta < ThunkApiConfig > > > ; public export type AsyncThunkPayloadCreator < Returned , ThunkArg = void , ThunkApiConfig extends AsyncThunkConfig = { } > = ( arg : ThunkArg , thunkAPI : GetThunkAPI < ThunkApiConfig > ) => AsyncThunkPayloadCreatorReturnValue < Returned , ThunkApiConfig > ; public export type AsyncThunkAction < Returned , ThunkArg , ThunkApiConfig extends AsyncThunkConfig > = ( dispatch : GetDispatch < ThunkApiConfig > , getState : ( ) => GetState < ThunkApiConfig > , extra : GetExtra < ThunkApiConfig > ) => Promise < ReturnType < AsyncThunkFulfilledActionCreator < Returned , ThunkArg > > | ReturnType < AsyncThunkRejectedActionCreator < ThunkArg , ThunkApiConfig > > > & { abort : ( reason ? : string ) => void ; requestId : string ; arg : ThunkArg ; unwrap : ( ) => Promise < Returned > ; } ; type AsyncThunkActionCreator < Returned , ThunkArg , ThunkApiConfig extends AsyncThunkConfig > = IsAny < ThunkArg , ( arg : ThunkArg ) => AsyncThunkAction < Returned , ThunkArg , ThunkApiConfig > , unknown extends ThunkArg ? ( arg : ThunkArg ) => AsyncThunkAction < Returned , ThunkArg , ThunkApiConfig > : [ ThunkArg ] extends [ void ] | [ undefined ] ? ( ) => AsyncThunkAction < Returned , ThunkArg , ThunkApiConfig > : [ void ] extends [ ThunkArg ] ? ( arg ? : ThunkArg ) => AsyncThunkAction < Returned , ThunkArg , ThunkApiConfig > : [ undefined ] extends [ ThunkArg ] ? WithStrictNullChecks < ( arg ? : ThunkArg ) => AsyncThunkAction < Returned , ThunkArg , ThunkApiConfig > , ( arg : ThunkArg ) => AsyncThunkAction < Returned , ThunkArg , ThunkApiConfig > > : ( arg : ThunkArg ) => AsyncThunkAction < Returned , ThunkArg , ThunkApiConfig > > ; public export type AsyncThunkOptions < ThunkArg = void , ThunkApiConfig extends AsyncThunkConfig = { } > = { returns condition ? ( arg , api ) : MaybePromise < boolean | undefined > ; default dispatchConditionRejection ? : boolean ; serializeError ? : ( x : unknown ) => GetSerializedErrorType < ThunkApiConfig > ; default idGenerator ? : ( arg : ThunkArg ) => string ; } & IsUnknown < GetPendingMeta < ThunkApiConfig > , { /**
     * A method to generate additional properties to be added to `meta` of the pending action.
     *
     * Using this optional overload will not modify the types correctly, this overload is only in place to support JavaScript users.
     * Please use the `ThunkApiConfig` parameter `pendingMeta` to get access to a correctly typed overload
     */ getPendingMeta ? ( base , api ) : GetPendingMeta < ThunkApiConfig > ; } , { /**
     * A method to generate additional properties to be added to `meta` of the pending action.
     */ getPendingMeta ( base , api ) : GetPendingMeta < ThunkApiConfig > ; } > ; export type AsyncThunkPendingActionCreator < ThunkArg , ThunkApiConfig = { } > = ActionCreatorWithPreparedPayload < [ string , ThunkArg , GetPendingMeta < ThunkApiConfig > ? ] , undefined , string , never , { arg : ThunkArg ; requestId : string ; requestStatus : 'pending' ; } & GetPendingMeta < ThunkApiConfig > > ; export type AsyncThunkRejectedActionCreator < ThunkArg , ThunkApiConfig = { } > = ActionCreatorWithPreparedPayload < [ Error | null , string , ThunkArg , GetRejectValue < ThunkApiConfig > ? , GetRejectedMeta < ThunkApiConfig > ? ] , GetRejectValue < ThunkApiConfig > | undefined , string , GetSerializedErrorType < ThunkApiConfig > , { arg : ThunkArg ; requestId : string ; requestStatus : 'rejected' ; aborted : boolean ; condition : boolean ; } & ( ( { rejectedWithValue : false ; } & { [ K in keyof GetRejectedMeta < ThunkApiConfig > ] ? : undefined ; } ) | ( { rejectedWithValue : true ; } & GetRejectedMeta < ThunkApiConfig > ) ) > ; export type AsyncThunkFulfilledActionCreator < Returned , ThunkArg , ThunkApiConfig = { } > = ActionCreatorWithPreparedPayload < [ Returned , string , ThunkArg , GetFulfilledMeta < ThunkApiConfig > ? ] , Returned , string , never , { arg : ThunkArg ; requestId : string ; requestStatus : 'fulfilled' ; } & GetFulfilledMeta < ThunkApiConfig > > ; public export type AsyncThunk < Returned , ThunkArg , ThunkApiConfig extends AsyncThunkConfig > = AsyncThunkActionCreator < Returned , ThunkArg , ThunkApiConfig > & { pending : AsyncThunkPendingActionCreator < ThunkArg , ThunkApiConfig > ; rejected : AsyncThunkRejectedActionCreator < ThunkArg , ThunkApiConfig > ; fulfilled : AsyncThunkFulfilledActionCreator < Returned , ThunkArg , ThunkApiConfig > ; typePrefix : string ; } ; param typePrefix param payloadCreator param options public export function createAsyncThunk < Returned , ThunkArg = void > ( typePrefix , payloadCreator , options ? ) ; param typePrefix param payloadCreator param options public export function createAsyncThunk < Returned , ThunkArg , ThunkApiConfig extends AsyncThunkConfig > ( typePrefix , payloadCreator , options ? ) ; export function createAsyncThunk < Returned , ThunkArg , ThunkApiConfig extends AsyncThunkConfig > ( typePrefix , payloadCreator , options ? ) { type RejectedValue = GetRejectValue < ThunkApiConfig > ; type PendingMeta = GetPendingMeta < ThunkApiConfig > ; type FulfilledMeta = GetFulfilledMeta < ThunkApiConfig > ; type RejectedMeta = GetRejectedMeta < ThunkApiConfig > ; const fulfilled = createAction ( typePrefix + '/fulfilled' , ( payload , requestId , arg , meta ? ) => ( { payload , meta : { ... ( ( meta as any ) || { } ) , arg , requestId , requestStatus : 'fulfilled' as const , } , } ) ) ; const pending = createAction ( typePrefix + '/pending' , ( requestId , arg , meta ? ) => ( { payload : undefined , meta : { ... ( ( meta as any ) || { } ) , arg , requestId , requestStatus : 'pending' as const , } , } ) ) ; const rejected = createAction ( typePrefix + '/rejected' , ( error , requestId , arg , payload ? , meta ? ) => ( { payload , error : ( ( options && options . serializeError ) || miniSerializeError ) ( error || 'Rejected' ) as GetSerializedErrorType < ThunkApiConfig > , meta : { ... ( ( meta as any ) || { } ) , arg , requestId , rejectedWithValue : ! ! payload , requestStatus : 'rejected' as const , aborted : error ?. name === 'AbortError' , condition : error ?. name === 'ConditionError' , } , } ) ) ; let displayedWarning = false ; const AC = typeof AbortController !== 'undefined' ? AbortController : class implements AbortController { signal : AbortSignal = { aborted : false , addEventListener ( ) { } , dispatchEvent ( ) { return false ; } , onabort ( ) { } , removeEventListener ( ) { } , } ; abort ( ) { if ( process . env . NODE_ENV !== 'production' ) { if ( ! displayedWarning ) { displayedWarning = true ; console . info ( `This platform does not implement AbortController. 
If you want to use the AbortController to react to \`abort\` events, please consider importing a polyfill like 'abortcontroller-polyfill/dist/abortcontroller-polyfill-only'.` ) ; } } } } ; function actionCreator ( arg ) { return ( dispatch , getState , extra ) => { const requestId = options ?. idGenerator ? options . idGenerator ( arg ) : nanoid ( ) ; const abortController = new AC ( ) ; let abortReason ; const abortedPromise = new Promise < never > ( ( _ , reject ) => abortController . signal . addEventListener ( 'abort' , ( ) => reject ( { name : 'AbortError' , message : abortReason || 'Aborted' } ) ) ) ; let started = false ; function abort ( reason ? ) { if ( started ) { abortReason = reason ; abortController . abort ( ) ; } } const promise = ( async function ( ) { let finalAction ; try { let conditionResult = options ?. condition ?. ( arg , { getState , extra } ) ; if ( isThenable ( conditionResult ) ) { conditionResult = await conditionResult ; } if ( conditionResult === false ) { throw { name : 'ConditionError' , message : 'Aborted due to condition callback returning false.' , } ; } started = true ; dispatch ( pending ( requestId , arg , options ?. getPendingMeta ?. ( { requestId , arg } , { getState , extra } ) ) ) ; finalAction = await Promise . race ( [ abortedPromise , Promise . resolve ( payloadCreator ( arg , { dispatch , getState , extra , requestId , signal : abortController . signal , rejectWithValue : ( ( value , meta ? ) => { return new RejectWithValue ( value , meta ) ; } ) as any , fulfillWithValue : ( ( value , meta ? ) => { return new FulfillWithMeta ( value , meta ) ; } ) as any , } ) ) . then ( ( result ) => { if ( result instanceof RejectWithValue ) { throw result ; } if ( result instanceof FulfillWithMeta ) { return fulfilled ( result . payload , requestId , arg , result . meta ) ; } return fulfilled ( result as any , requestId , arg ) ; } ) , ] ) ; } catch ( err ) { finalAction = err instanceof RejectWithValue ? rejected ( null , requestId , arg , err . payload , err . meta ) : rejected ( err as any , requestId , arg ) ; } const skipDispatch = options && ! options . dispatchConditionRejection && rejected . match ( finalAction ) && ( finalAction as any ) . meta . condition ; if ( ! skipDispatch ) { dispatch ( finalAction ) ; } return finalAction ; } ) ( ) ; return Object . assign ( promise as Promise < any > , { abort , requestId , arg , unwrap ( ) { return promise . then < any > ( unwrapResult ) ; } , } ) ; } ; } return Object . assign ( actionCreator as AsyncThunkActionCreator < Returned , ThunkArg , ThunkApiConfig > , { pending , rejected , fulfilled , typePrefix , } ) ; } interface UnwrappableAction { payload : any ; meta ? : any ; error ? : any ; } type UnwrappedActionPayload < T extends UnwrappableAction > = Exclude < T , { error : any ; } > [ 'payload' ] ; public export function unwrapResult < R extends UnwrappableAction > ( action ) { if ( action . meta && action . meta . rejectedWithValue ) { throw action . payload ; } if ( action . error ) { throw action . error ; } return action . payload ; } type WithStrictNullChecks < True , False > = undefined extends boolean ? False : True ; function isThenable ( value ) { return ( value !== null && typeof value === 'object' && typeof value . then === 'function' ) ; }