@reduxjs/toolkit
Advanced tools
Comparing version 2.0.0-rc.0 to 2.0.0-rc.1
@@ -0,0 +0,0 @@ import type { Middleware } from 'redux'; |
@@ -0,0 +0,0 @@ import type { StoreEnhancer } from 'redux'; |
@@ -0,0 +0,0 @@ import type { UnknownAction, Reducer, StateFromReducersMapObject } from 'redux'; |
@@ -0,0 +0,0 @@ import type { Reducer, ReducersMapObject, Middleware, Action, StoreEnhancer, Store, UnknownAction } from 'redux'; |
@@ -1,2 +0,1 @@ | ||
import type { Action } from 'redux'; | ||
import type { IsUnknownOrNonInferrable, IfMaybeUndefined, IfVoid, IsAny } from './tsHelpers'; | ||
@@ -59,3 +58,3 @@ /** | ||
type: T; | ||
match: (action: Action<string>) => action is PayloadAction<P, T, M, E>; | ||
match: (action: unknown) => action is PayloadAction<P, T, M, E>; | ||
} | ||
@@ -178,6 +177,2 @@ /** | ||
/** | ||
* Returns true if value is a plain object with a `type` property. | ||
*/ | ||
export declare function isAction(action: unknown): action is Action<string>; | ||
/** | ||
* Returns true if value is an RTK-like action creator, with a static type property and match method. | ||
@@ -184,0 +179,0 @@ */ |
@@ -0,0 +0,0 @@ import type { Dispatch, UnknownAction } from 'redux'; |
@@ -0,0 +0,0 @@ import { createSelectorCreator, defaultMemoize } from 'reselect'; |
@@ -0,0 +0,0 @@ import type { Draft } from 'immer'; |
@@ -0,0 +0,0 @@ import type { Action, UnknownAction, Reducer } from 'redux'; |
@@ -0,0 +0,0 @@ import type { Action, ActionCreator, StoreEnhancer } from 'redux'; |
import type { Dispatch as ReduxDispatch, UnknownAction } from 'redux'; | ||
import type { DynamicMiddlewareInstance } from './types'; | ||
export declare const createDynamicMiddleware: <State = any, Dispatch extends ReduxDispatch<UnknownAction> = ReduxDispatch<UnknownAction>>() => DynamicMiddlewareInstance<State, Dispatch>; |
@@ -0,0 +0,0 @@ import type { Action as ReduxAction, UnknownAction, Dispatch as ReduxDispatch, Middleware } from 'redux'; |
@@ -0,0 +0,0 @@ import type { Middleware, Dispatch as ReduxDispatch, UnknownAction, MiddlewareAPI } from 'redux'; |
@@ -0,0 +0,0 @@ import type { Comparer, IdSelector, EntityAdapter, EntityId } from './models'; |
@@ -0,0 +0,0 @@ import type { EntityId, EntityState } from './models'; |
export { createEntityAdapter } from './create_adapter'; | ||
export type { EntityState, EntityAdapter, Update, IdSelector, Comparer, } from './models'; |
@@ -0,0 +0,0 @@ import type { UncheckedIndexedAccess } from '../uncheckedindexed'; |
import type { IdSelector, Comparer, EntityStateAdapter, EntityId } from './models'; | ||
export declare function createSortedStateAdapter<T, Id extends EntityId>(selectId: IdSelector<T, Id>, sort: Comparer<T>): EntityStateAdapter<T, Id>; |
@@ -5,3 +5,3 @@ import type { Draft } from 'immer'; | ||
export declare const isDraftTyped: <T>(value: T | Draft<T>) => value is Draft<T>; | ||
export declare function createSingleArgumentStateOperator<T, Id extends EntityId>(mutator: (state: DraftableEntityState<T, Id>) => void): <S extends DraftableEntityState<T, Id>>(state: import("../tsHelpers").IsAny<S, import("./models").EntityState<T, Id>, S>) => S; | ||
export declare function createSingleArgumentStateOperator<T, Id extends EntityId>(mutator: (state: DraftableEntityState<T, Id>) => void): <S extends DraftableEntityState<T, Id>>(state: PreventAny<S, T, Id>) => S; | ||
export declare function createStateOperator<T, Id extends EntityId, R>(mutator: (arg: R, state: DraftableEntityState<T, Id>) => void): <S extends DraftableEntityState<T, Id>>(state: S, arg: R | PayloadAction<R>) => S; |
@@ -0,0 +0,0 @@ import type { CreateSelectorFunction } from 'reselect'; |
import type { EntityStateAdapter, IdSelector, EntityId } from './models'; | ||
export declare function createUnsortedStateAdapter<T, Id extends EntityId>(selectId: IdSelector<T, Id>): EntityStateAdapter<T, Id>; |
@@ -0,0 +0,0 @@ import type { IdSelector, Update, EntityId, DraftableEntityState } from './models'; |
@@ -0,0 +0,0 @@ /** |
@@ -14,3 +14,3 @@ import type { StoreEnhancer } from 'redux'; | ||
dispatch: ExtractDispatchExtensions<M>; | ||
}, {}>) => GetDefaultEnhancers<M>; | ||
}>) => GetDefaultEnhancers<M>; | ||
export {}; |
@@ -0,0 +0,0 @@ import type { UnknownAction } from 'redux'; |
@@ -0,0 +0,0 @@ import type { Middleware } from 'redux'; |
@@ -11,3 +11,3 @@ export * from 'redux'; | ||
export type { DevToolsEnhancerOptions } from './devtoolsExtension'; | ||
export { createAction, isAction, isActionCreator, isFSA as isFluxStandardAction, } from './createAction'; | ||
export { createAction, isActionCreator, isFSA as isFluxStandardAction, } from './createAction'; | ||
export type { PayloadAction, PayloadActionCreator, ActionCreatorWithNonInferrablePayload, ActionCreatorWithOptionalPayload, ActionCreatorWithPayload, ActionCreatorWithoutPayload, ActionCreatorWithPreparedPayload, PrepareAction, } from './createAction'; | ||
@@ -33,3 +33,2 @@ export { createReducer, } from './createReducer'; | ||
export { nanoid } from './nanoid'; | ||
export { default as isPlainObject } from './isPlainObject'; | ||
export type { ListenerEffect, ListenerMiddleware, ListenerEffectAPI, ListenerMiddlewareInstance, CreateListenerMiddlewareOptions, ListenerErrorHandler, TypedStartListening, TypedAddListener, TypedStopListening, TypedRemoveListener, UnsubscribeListener, UnsubscribeListenerOptions, ForkedTaskExecutor, ForkedTask, ForkedTaskAPI, AsyncTaskExecutor, SyncTaskExecutor, TaskCancelled, TaskRejected, TaskResolved, TaskResult, } from './listenerMiddleware/index'; | ||
@@ -36,0 +35,0 @@ export type { AnyListenerPredicate } from './listenerMiddleware/types'; |
@@ -0,0 +0,0 @@ import type { SerializedError } from '@reduxjs/toolkit'; |
import type { Action, Dispatch, UnknownAction } from 'redux'; | ||
import type { ThunkDispatch } from 'redux-thunk'; | ||
import type { ListenerMiddlewareInstance, CreateListenerMiddlewareOptions, TypedAddListener, TypedCreateListenerEntry, ListenerEntry, TypedRemoveListener } from './types'; | ||
import type { ListenerMiddlewareInstance, CreateListenerMiddlewareOptions, TypedAddListener, TypedCreateListenerEntry, TypedRemoveListener } from './types'; | ||
export { TaskAbortError } from './exceptions'; | ||
@@ -11,3 +11,3 @@ export type { ListenerEffect, ListenerMiddleware, ListenerEffectAPI, ListenerMiddlewareInstance, CreateListenerMiddlewareOptions, ListenerErrorHandler, TypedStartListening, TypedAddListener, TypedStopListening, TypedRemoveListener, UnsubscribeListener, UnsubscribeListenerOptions, ForkedTaskExecutor, ForkedTask, ForkedTaskAPI, AsyncTaskExecutor, SyncTaskExecutor, TaskCancelled, TaskRejected, TaskResolved, TaskResult, } from './types'; | ||
*/ | ||
export declare const addListener: TypedAddListener<unknown, ThunkDispatch<unknown, unknown, UnknownAction>, unknown, ListenerEntry<unknown, ThunkDispatch<unknown, unknown, UnknownAction>>, "listenerMiddleware/add">; | ||
export declare const addListener: TypedAddListener<unknown>; | ||
/** | ||
@@ -20,3 +20,3 @@ * @public | ||
*/ | ||
export declare const removeListener: TypedRemoveListener<unknown, ThunkDispatch<unknown, unknown, UnknownAction>, ListenerEntry<unknown, ThunkDispatch<unknown, unknown, UnknownAction>>, "listenerMiddleware/remove">; | ||
export declare const removeListener: TypedRemoveListener<unknown>; | ||
/** | ||
@@ -23,0 +23,0 @@ * @public |
@@ -0,0 +0,0 @@ import type { AbortSignalWithReason, TaskResult } from './types'; |
@@ -200,2 +200,10 @@ import type { PayloadAction, BaseActionCreator } from '../createAction'; | ||
/** | ||
* Cancels the instance of this listener that made this call. | ||
*/ | ||
cancel: () => void; | ||
/** | ||
* Throws a `TaskAbortError` if this listener has been cancelled | ||
*/ | ||
throwIfCancelled: () => void; | ||
/** | ||
* An abort signal whose `aborted` property is set to `true` | ||
@@ -317,3 +325,3 @@ * if the listener execution is either aborted or completed. | ||
/** Accepts an RTK matcher function, such as `incrementByAmount.match` */ | ||
<MA extends ReduxAction, M extends MatchFunction<MA>>(options: { | ||
<M extends MatchFunction<UnknownAction>>(options: { | ||
actionCreator?: never; | ||
@@ -390,4 +398,4 @@ type?: never; | ||
/** @public */ | ||
export type GuardedType<T> = T extends (x: any, ...args: unknown[]) => x is infer T ? T : never; | ||
export type GuardedType<T> = T extends (x: any, ...args: any[]) => x is infer T ? T : never; | ||
/** @public */ | ||
export type ListenerPredicateGuardedActionType<T> = T extends ListenerPredicate<infer Action, any> ? Action : never; |
@@ -0,0 +0,0 @@ export declare const assertFunction: (func: unknown, expected: string) => asserts func is (...args: unknown[]) => unknown; |
@@ -0,0 +0,0 @@ import type { Action } from 'redux'; |
@@ -0,0 +0,0 @@ import type { ActionFromMatcher, Matcher, UnionToIntersection } from './tsHelpers'; |
@@ -0,0 +0,0 @@ /** |
@@ -0,0 +0,0 @@ import type { EndpointDefinitions, EndpointBuilder, EndpointDefinition, UpdateDefinitions } from './endpointDefinitions'; |
@@ -0,0 +0,0 @@ import type { ThunkDispatch } from '@reduxjs/toolkit'; |
@@ -0,0 +0,0 @@ import type { SerializedError } from '@reduxjs/toolkit'; |
@@ -0,0 +0,0 @@ import type { EndpointDefinitions, QueryDefinition, MutationDefinition, QueryArgFrom, ResultTypeFrom } from '../endpointDefinitions'; |
@@ -0,0 +0,0 @@ import type { InternalHandlerBuilder, SubscriptionSelectors } from './types'; |
@@ -0,0 +0,0 @@ import type { BaseQueryFn } from '../../baseQueryTypes'; |
@@ -0,0 +0,0 @@ import type { UnknownAction } from 'redux'; |
import type { InternalHandlerBuilder } from './types'; | ||
export declare const buildDevCheckHandler: InternalHandlerBuilder; |
@@ -0,0 +0,0 @@ import type { Middleware, ThunkDispatch, UnknownAction } from '@reduxjs/toolkit'; |
import type { InternalHandlerBuilder } from './types'; | ||
export declare const buildInvalidationByTagsHandler: InternalHandlerBuilder; |
import type { InternalHandlerBuilder } from './types'; | ||
export declare const buildPollingHandler: InternalHandlerBuilder; |
@@ -0,0 +0,0 @@ import type { BaseQueryError, BaseQueryFn, BaseQueryMeta } from '../../baseQueryTypes'; |
@@ -0,0 +0,0 @@ import type { Action, AsyncThunkAction, Middleware, MiddlewareAPI, ThunkDispatch, UnknownAction } from '@reduxjs/toolkit'; |
import type { InternalHandlerBuilder } from './types'; | ||
export declare const buildWindowEventHandler: InternalHandlerBuilder; |
@@ -0,0 +0,0 @@ import type { MutationSubState, QuerySubState, RootState as _RootState, RequestStatusFlags, QueryCacheKey, QueryKeys } from './apiState'; |
@@ -0,0 +0,0 @@ import type { UnknownAction } from '@reduxjs/toolkit'; |
@@ -0,0 +0,0 @@ import type { InternalSerializeQueryArgs } from '../defaultSerializeQueryArgs'; |
@@ -0,0 +0,0 @@ import { CreateApi } from '../createApi'; |
@@ -0,0 +0,0 @@ /** |
export { createAction, createSlice, createSelector, createAsyncThunk, combineReducers, createNextState, isAnyOf, isAllOf, isAction, isPending, isRejected, isFulfilled, isRejectedWithValue, isAsyncThunkAction, prepareAutoBatched, SHOULD_AUTOBATCH, isPlainObject, nanoid, } from '@reduxjs/toolkit'; |
@@ -0,0 +0,0 @@ import type { ThunkDispatch, ActionCreatorWithoutPayload } from '@reduxjs/toolkit'; |
@@ -0,0 +0,0 @@ import type { Api, Module, ModuleName } from './apiTypes'; |
@@ -0,0 +0,0 @@ import type { QueryCacheKey } from './core/apiState'; |
@@ -0,0 +0,0 @@ import type { SerializeQueryArgs } from './defaultSerializeQueryArgs'; |
@@ -0,0 +0,0 @@ import type { BaseQueryFn } from './baseQueryTypes'; |
@@ -0,0 +0,0 @@ import type { BaseQueryApi, BaseQueryFn } from './baseQueryTypes'; |
@@ -0,0 +0,0 @@ export declare class HandledError { |
@@ -0,0 +0,0 @@ export type { CombinedState, QueryCacheKey, QueryKeys, QuerySubState, RootState, SubscriptionOptions, } from './core/apiState'; |
@@ -0,0 +0,0 @@ import type { Context } from 'react'; |
@@ -0,0 +0,0 @@ import { useEffect } from 'react'; |
export declare const UNINITIALIZED_VALUE: unique symbol; | ||
export type UninitializedValue = typeof UNINITIALIZED_VALUE; |
@@ -0,0 +0,0 @@ import { reactHooksModule, reactHooksModuleName } from './module'; |
@@ -0,0 +0,0 @@ import type { MutationHooks, QueryHooks } from './buildHooks'; |
@@ -0,0 +0,0 @@ import type { UseMutation, UseLazyQuery, UseQuery } from './buildHooks'; |
import type { SerializeQueryArgs } from '@reduxjs/toolkit/query'; | ||
import type { EndpointDefinition } from '@reduxjs/toolkit/query'; | ||
export declare function useStableQueryArgs<T>(queryArgs: T, serialize: SerializeQueryArgs<any>, endpointDefinition: EndpointDefinition<any, any, any, any>, endpointName: string): T; |
export declare function useShallowStableValue<T>(value: T): T; |
@@ -0,0 +0,0 @@ import type { BaseQueryApi, BaseQueryArg, BaseQueryEnhancer, BaseQueryExtraOptions, BaseQueryFn } from './baseQueryTypes'; |
@@ -0,0 +0,0 @@ export type Id<T> = { |
export declare function capitalize(str: string): string; |
export declare function copyWithStructuralSharing<T>(oldObj: any, newObj: T): T; |
export declare function countObjectKeys(obj: Record<any, any>): number; |
@@ -0,0 +0,0 @@ /** |
@@ -0,0 +0,0 @@ export * from './isAbsoluteUrl'; |
@@ -0,0 +0,0 @@ /** |
@@ -0,0 +0,0 @@ /** |
export declare function isNotNullish<T>(v: T | null | undefined): v is T; |
@@ -0,0 +0,0 @@ /** |
export declare function isValidUrl(string: string): boolean; |
export declare function joinUrls(base: string | undefined, url: string | undefined): string; |
export * from '@reduxjs/toolkit'; | ||
export { createDynamicMiddleware } from '../dynamicMiddleware/react'; |
@@ -0,0 +0,0 @@ import type { Middleware } from 'redux'; |
@@ -0,0 +0,0 @@ import type { Middleware, StoreEnhancer } from 'redux'; |
@@ -0,0 +0,0 @@ export declare function getTimeMeasureUtils(maxDelay: number, fnName: string): { |
{ | ||
"name": "@reduxjs/toolkit", | ||
"version": "2.0.0-rc.0", | ||
"version": "2.0.0-rc.1", | ||
"description": "The official, opinionated, batteries-included toolset for efficient Redux development", | ||
@@ -52,2 +52,3 @@ "author": "Mark Erikson <mark@isquaredsoftware.com>", | ||
"devDependencies": { | ||
"@arethetypeswrong/cli": "^0.13.1", | ||
"@microsoft/api-extractor": "^7.13.2", | ||
@@ -58,3 +59,2 @@ "@phryneas/ts-version": "^1.0.2", | ||
"@testing-library/user-event": "^13.1.5", | ||
"@types/convert-source-map": "^1.5.1", | ||
"@types/json-stringify-safe": "^5.0.0", | ||
@@ -67,7 +67,6 @@ "@types/nanoid": "^2.1.0", | ||
"@types/yargs": "^16.0.1", | ||
"@typescript-eslint/eslint-plugin": "^4.22.0", | ||
"@typescript-eslint/parser": "^4.22.0", | ||
"@typescript-eslint/eslint-plugin": "^6", | ||
"@typescript-eslint/parser": "^6", | ||
"axios": "^0.19.2", | ||
"console-testing-library": "0.6.1", | ||
"convert-source-map": "^1.7.0", | ||
"esbuild-extra": "^0.3.1", | ||
@@ -96,3 +95,3 @@ "eslint": "^7.25.0", | ||
"tsx": "^3.12.2", | ||
"typescript": "~4.9", | ||
"typescript": "5.2", | ||
"vitest": "^0.30.1", | ||
@@ -120,3 +119,3 @@ "yargs": "^15.3.1" | ||
"immer": "^10.0.3", | ||
"redux": "^5.0.0-rc.0", | ||
"redux": "^5.0.0-rc.1", | ||
"redux-thunk": "^3.0.0-rc.0", | ||
@@ -123,0 +122,0 @@ "reselect": "^5.0.0-beta.1" |
@@ -10,7 +10,12 @@ import type { | ||
} from 'redux' | ||
import { applyMiddleware, createStore, compose, combineReducers } from 'redux' | ||
import { | ||
applyMiddleware, | ||
createStore, | ||
compose, | ||
combineReducers, | ||
isPlainObject, | ||
} from 'redux' | ||
import type { DevToolsEnhancerOptions as DevToolsOptions } from './devtoolsExtension' | ||
import { composeWithDevTools } from './devtoolsExtension' | ||
import isPlainObject from './isPlainObject' | ||
import type { | ||
@@ -17,0 +22,0 @@ ThunkMiddlewareFor, |
@@ -1,2 +0,2 @@ | ||
import type { Action, UnknownAction } from 'redux' | ||
import { isAction } from 'redux' | ||
import type { | ||
@@ -9,3 +9,2 @@ IsUnknownOrNonInferrable, | ||
import { hasMatchFunction } from './tsHelpers' | ||
import isPlainObject from './isPlainObject' | ||
@@ -88,3 +87,3 @@ /** | ||
type: T | ||
match: (action: Action<string>) => action is PayloadAction<P, T, M, E> | ||
match: (action: unknown) => action is PayloadAction<P, T, M, E> | ||
} | ||
@@ -284,4 +283,4 @@ | ||
actionCreator.match = (action: Action<string>): action is PayloadAction => | ||
action.type === type | ||
actionCreator.match = (action: unknown): action is PayloadAction => | ||
isAction(action) && action.type === type | ||
@@ -292,13 +291,2 @@ return actionCreator | ||
/** | ||
* Returns true if value is a plain object with a `type` property. | ||
*/ | ||
export function isAction(action: unknown): action is Action<string> { | ||
return ( | ||
isPlainObject(action) && | ||
'type' in action && | ||
typeof (action as Record<'type', unknown>).type === 'string' | ||
) | ||
} | ||
/** | ||
* Returns true if value is an RTK-like action creator, with a static type property and match method. | ||
@@ -305,0 +293,0 @@ */ |
@@ -7,3 +7,3 @@ import type { | ||
import { compose } from 'redux' | ||
import { createAction, isAction } from '../createAction' | ||
import { createAction } from '../createAction' | ||
import { isAllOf } from '../matchers' | ||
@@ -79,7 +79,3 @@ import { nanoid } from '../nanoid' | ||
const isWithMiddleware = isAllOf( | ||
isAction, | ||
withMiddleware, | ||
matchInstance(instanceId) | ||
) | ||
const isWithMiddleware = isAllOf(withMiddleware, matchInstance(instanceId)) | ||
@@ -86,0 +82,0 @@ const middleware: DynamicMiddleware<State, Dispatch> = |
@@ -5,3 +5,2 @@ import type { Middleware } from 'redux' | ||
import type { BaseActionCreator, PayloadAction } from '../../createAction' | ||
import { isAction } from '../../createAction' | ||
import { createAction } from '../../createAction' | ||
@@ -29,3 +28,3 @@ import { isAllOf } from '../../matchers' | ||
}> => { | ||
const isMiddlewareAction = isAllOf(isAction, probeMiddleware, matchId(id)) | ||
const isMiddlewareAction = isAllOf(probeMiddleware, matchId(id)) | ||
return (api) => (next) => (action) => { | ||
@@ -32,0 +31,0 @@ if (isMiddlewareAction(action)) { |
@@ -45,3 +45,2 @@ // This must remain here so that the `mangleErrors.cjs` build script | ||
createAction, | ||
isAction, | ||
isActionCreator, | ||
@@ -161,4 +160,2 @@ isFSA as isFluxStandardAction, | ||
export { default as isPlainObject } from './isPlainObject' | ||
export type { | ||
@@ -165,0 +162,0 @@ ListenerEffect, |
import type { Action, Dispatch, MiddlewareAPI, UnknownAction } from 'redux' | ||
import { isAction } from 'redux' | ||
import type { ThunkDispatch } from 'redux-thunk' | ||
import { createAction, isAction } from '../createAction' | ||
import { createAction } from '../createAction' | ||
import { nanoid } from '../nanoid' | ||
@@ -406,2 +407,12 @@ | ||
}, | ||
cancel: () => { | ||
abortControllerWithReason( | ||
internalTaskController, | ||
listenerCancelled | ||
) | ||
entry.pending.delete(internalTaskController) | ||
}, | ||
throwIfCancelled: () => { | ||
validateActive(internalTaskController.signal) | ||
}, | ||
}) | ||
@@ -408,0 +419,0 @@ ) |
@@ -6,3 +6,3 @@ import { | ||
isAnyOf, | ||
isFSA, | ||
isFluxStandardAction, | ||
} from '@reduxjs/toolkit' | ||
@@ -52,2 +52,4 @@ import type { Mock } from 'vitest' | ||
cancelActiveListeners: expect.any(Function), | ||
cancel: expect.any(Function), | ||
throwIfCancelled: expect.any(Function), | ||
} | ||
@@ -653,3 +655,74 @@ | ||
test('"can unsubscribe via middleware api', () => { | ||
test('can self-cancel via middleware api', async () => { | ||
const notifyDeferred = createAction<Deferred<string>>('notify-deferred') | ||
startListening({ | ||
actionCreator: notifyDeferred, | ||
effect: async ({ payload }, { signal, cancel, delay }) => { | ||
signal.addEventListener( | ||
'abort', | ||
() => { | ||
payload.resolve((signal as AbortSignalWithReason<string>).reason) | ||
}, | ||
{ once: true } | ||
) | ||
cancel() | ||
}, | ||
}) | ||
const deferredCancelledSignalReason = store.dispatch( | ||
notifyDeferred(deferred<string>()) | ||
).payload | ||
expect(await deferredCancelledSignalReason).toBe(listenerCancelled) | ||
}) | ||
test('Can easily check if the listener has been cancelled', async () => { | ||
const pauseDeferred = deferred<void>() | ||
let listenerCancelled = false | ||
let listenerStarted = false | ||
let listenerCompleted = false | ||
let cancelListener: () => void = () => {} | ||
let error: TaskAbortError | undefined = undefined | ||
startListening({ | ||
actionCreator: testAction1, | ||
effect: async ({ payload }, { throwIfCancelled, cancel }) => { | ||
cancelListener = cancel | ||
try { | ||
listenerStarted = true | ||
throwIfCancelled() | ||
await pauseDeferred | ||
throwIfCancelled() | ||
listenerCompleted = true | ||
} catch (err) { | ||
if (err instanceof TaskAbortError) { | ||
listenerCancelled = true | ||
error = err | ||
} | ||
} | ||
}, | ||
}) | ||
store.dispatch(testAction1('a')) | ||
expect(listenerStarted).toBe(true) | ||
expect(listenerCompleted).toBe(false) | ||
expect(listenerCancelled).toBe(false) | ||
// Cancel it while the listener is paused at a non-cancel-aware promise | ||
cancelListener() | ||
pauseDeferred.resolve() | ||
await delay(10) | ||
expect(listenerCompleted).toBe(false) | ||
expect(listenerCancelled).toBe(true) | ||
expect((error as any)?.message).toBe( | ||
'task cancelled (reason: listener-cancelled)' | ||
) | ||
}) | ||
test('can unsubscribe via middleware api', () => { | ||
const effect = vi.fn( | ||
@@ -1454,3 +1527,5 @@ (action: TestAction1, api: ListenerEffectAPI<any, any>) => { | ||
): action is PayloadAction<number> => { | ||
return isFSA(action) && typeof action.payload === 'boolean' | ||
return ( | ||
isFluxStandardAction(action) && typeof action.payload === 'boolean' | ||
) | ||
}, | ||
@@ -1464,3 +1539,5 @@ effect: (action, listenerApi) => { | ||
predicate: (action, currentState) => { | ||
return isFSA(action) && typeof action.payload === 'number' | ||
return ( | ||
isFluxStandardAction(action) && typeof action.payload === 'number' | ||
) | ||
}, | ||
@@ -1467,0 +1544,0 @@ effect: (action, listenerApi) => { |
@@ -11,2 +11,3 @@ import type { PayloadAction, BaseActionCreator } from '../createAction' | ||
import type { TaskAbortError } from './exceptions' | ||
import { NoInfer } from '../tsHelpers' | ||
@@ -238,2 +239,10 @@ /** | ||
/** | ||
* Cancels the instance of this listener that made this call. | ||
*/ | ||
cancel: () => void | ||
/** | ||
* Throws a `TaskAbortError` if this listener has been cancelled | ||
*/ | ||
throwIfCancelled: () => void | ||
/** | ||
* An abort signal whose `aborted` property is set to `true` | ||
@@ -441,3 +450,3 @@ * if the listener execution is either aborted or completed. | ||
/** Accepts an RTK matcher function, such as `incrementByAmount.match` */ | ||
<MA extends ReduxAction, M extends MatchFunction<MA>>( | ||
<M extends MatchFunction<UnknownAction>>( | ||
options: { | ||
@@ -579,6 +588,3 @@ actionCreator?: never | ||
/** @public */ | ||
export type GuardedType<T> = T extends ( | ||
x: any, | ||
...args: unknown[] | ||
) => x is infer T | ||
export type GuardedType<T> = T extends (x: any, ...args: any[]) => x is infer T | ||
? T | ||
@@ -585,0 +591,0 @@ : never |
@@ -169,3 +169,3 @@ import type { Action } from 'redux' | ||
throw new Error( | ||
'`builder.addCase` cannot be called with two reducers for the same action type' | ||
`\`builder.addCase\` cannot be called with two reducers for the same action type '${type}'` | ||
) | ||
@@ -172,0 +172,0 @@ } |
@@ -1,5 +0,4 @@ | ||
import isPlainObject from './isPlainObject' | ||
import type { Middleware } from 'redux' | ||
import { isAction, isPlainObject } from 'redux' | ||
import { getTimeMeasureUtils } from './utils' | ||
import { isAction } from './createAction' | ||
@@ -6,0 +5,0 @@ /** |
@@ -1,2 +0,2 @@ | ||
import { createAction, isAction, isActionCreator } from '@reduxjs/toolkit' | ||
import { createAction, isActionCreator } from '@reduxjs/toolkit' | ||
@@ -130,23 +130,2 @@ describe('createAction', () => { | ||
} | ||
describe('isAction', () => { | ||
it('should only return true for plain objects with a string type property', () => { | ||
const actionCreator = createAction('anAction') | ||
class Action { | ||
type = 'totally an action' | ||
} | ||
const testCases: [action: unknown, expected: boolean][] = [ | ||
[{ type: 'an action' }, true], | ||
[{ type: 'more props', extra: true }, true], | ||
[{ type: 0 }, false], | ||
[actionCreator(), true], | ||
[actionCreator, false], | ||
[Promise.resolve({ type: 'an action' }), false], | ||
[new Action(), false], | ||
['a string', false], | ||
] | ||
for (const [action, expected] of testCases) { | ||
expect(isAction(action)).toBe(expected) | ||
} | ||
}) | ||
}) | ||
@@ -153,0 +132,0 @@ describe('isActionCreator', () => { |
@@ -357,3 +357,3 @@ import { vi } from 'vitest' | ||
).toThrowErrorMatchingInlineSnapshot( | ||
'"`builder.addCase` cannot be called with two reducers for the same action type"' | ||
'"`builder.addCase` cannot be called with two reducers for the same action type \'increment\'"' | ||
) | ||
@@ -368,3 +368,3 @@ expect(() => | ||
).toThrowErrorMatchingInlineSnapshot( | ||
'"`builder.addCase` cannot be called with two reducers for the same action type"' | ||
'"`builder.addCase` cannot be called with two reducers for the same action type \'increment\'"' | ||
) | ||
@@ -371,0 +371,0 @@ }) |
@@ -255,3 +255,3 @@ import { vi } from 'vitest' | ||
}).toThrowErrorMatchingInlineSnapshot( | ||
'"`builder.addCase` cannot be called with two reducers for the same action type"' | ||
'"`builder.addCase` cannot be called with two reducers for the same action type \'increment\'"' | ||
) | ||
@@ -258,0 +258,0 @@ }) |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
43
10
5332902
309
61259
Updatedredux@^5.0.0-rc.1