Socket
Socket
Sign inDemoInstall

@reduxjs/toolkit

Package Overview
Dependencies
Maintainers
5
Versions
96
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@reduxjs/toolkit - npm Package Compare versions

Comparing version 2.0.0-beta.2 to 2.0.0-beta.3

src/entities/tests/entity_slice_enhancer.test.ts

2

dist/configureStore.d.ts

@@ -25,3 +25,3 @@ import type { Reducer, ReducersMapObject, Middleware, Action, StoreEnhancer, Store, UnknownAction } from 'redux';

*/
middleware?: ((getDefaultMiddleware: GetDefaultMiddleware<S>) => M) | M;
middleware?: (getDefaultMiddleware: GetDefaultMiddleware<S>) => M;
/**

@@ -28,0 +28,0 @@ * Whether to enable Redux DevTools integration. Defaults to `true`.

import type { UncheckedIndexedAccess } from '../uncheckedindexed';
import type { Draft } from 'immer';
import type { PayloadAction } from '../createAction';

@@ -39,2 +40,3 @@ import type { GetSelectorsOptions } from './state_selectors';

export type PreventAny<S, T, Id extends EntityId> = CastAny<S, EntityState<T, Id>>;
export type DraftableEntityState<T, Id extends EntityId> = EntityState<T, Id> | Draft<EntityState<T, Id>>;
/**

@@ -44,25 +46,25 @@ * @public

export interface EntityStateAdapter<T, Id extends EntityId> {
addOne<S extends EntityState<T, Id>>(state: PreventAny<S, T, Id>, entity: T): S;
addOne<S extends EntityState<T, Id>>(state: PreventAny<S, T, Id>, action: PayloadAction<T>): S;
addMany<S extends EntityState<T, Id>>(state: PreventAny<S, T, Id>, entities: readonly T[] | Record<Id, T>): S;
addMany<S extends EntityState<T, Id>>(state: PreventAny<S, T, Id>, entities: PayloadAction<readonly T[] | Record<Id, T>>): S;
setOne<S extends EntityState<T, Id>>(state: PreventAny<S, T, Id>, entity: T): S;
setOne<S extends EntityState<T, Id>>(state: PreventAny<S, T, Id>, action: PayloadAction<T>): S;
setMany<S extends EntityState<T, Id>>(state: PreventAny<S, T, Id>, entities: readonly T[] | Record<Id, T>): S;
setMany<S extends EntityState<T, Id>>(state: PreventAny<S, T, Id>, entities: PayloadAction<readonly T[] | Record<Id, T>>): S;
setAll<S extends EntityState<T, Id>>(state: PreventAny<S, T, Id>, entities: readonly T[] | Record<Id, T>): S;
setAll<S extends EntityState<T, Id>>(state: PreventAny<S, T, Id>, entities: PayloadAction<readonly T[] | Record<Id, T>>): S;
removeOne<S extends EntityState<T, Id>>(state: PreventAny<S, T, Id>, key: Id): S;
removeOne<S extends EntityState<T, Id>>(state: PreventAny<S, T, Id>, key: PayloadAction<Id>): S;
removeMany<S extends EntityState<T, Id>>(state: PreventAny<S, T, Id>, keys: readonly Id[]): S;
removeMany<S extends EntityState<T, Id>>(state: PreventAny<S, T, Id>, keys: PayloadAction<readonly Id[]>): S;
removeAll<S extends EntityState<T, Id>>(state: PreventAny<S, T, Id>): S;
updateOne<S extends EntityState<T, Id>>(state: PreventAny<S, T, Id>, update: Update<T, Id>): S;
updateOne<S extends EntityState<T, Id>>(state: PreventAny<S, T, Id>, update: PayloadAction<Update<T, Id>>): S;
updateMany<S extends EntityState<T, Id>>(state: PreventAny<S, T, Id>, updates: ReadonlyArray<Update<T, Id>>): S;
updateMany<S extends EntityState<T, Id>>(state: PreventAny<S, T, Id>, updates: PayloadAction<ReadonlyArray<Update<T, Id>>>): S;
upsertOne<S extends EntityState<T, Id>>(state: PreventAny<S, T, Id>, entity: T): S;
upsertOne<S extends EntityState<T, Id>>(state: PreventAny<S, T, Id>, entity: PayloadAction<T>): S;
upsertMany<S extends EntityState<T, Id>>(state: PreventAny<S, T, Id>, entities: readonly T[] | Record<Id, T>): S;
upsertMany<S extends EntityState<T, Id>>(state: PreventAny<S, T, Id>, entities: PayloadAction<readonly T[] | Record<Id, T>>): S;
addOne<S extends DraftableEntityState<T, Id>>(state: PreventAny<S, T, Id>, entity: T): S;
addOne<S extends DraftableEntityState<T, Id>>(state: PreventAny<S, T, Id>, action: PayloadAction<T>): S;
addMany<S extends DraftableEntityState<T, Id>>(state: PreventAny<S, T, Id>, entities: readonly T[] | Record<Id, T>): S;
addMany<S extends DraftableEntityState<T, Id>>(state: PreventAny<S, T, Id>, entities: PayloadAction<readonly T[] | Record<Id, T>>): S;
setOne<S extends DraftableEntityState<T, Id>>(state: PreventAny<S, T, Id>, entity: T): S;
setOne<S extends DraftableEntityState<T, Id>>(state: PreventAny<S, T, Id>, action: PayloadAction<T>): S;
setMany<S extends DraftableEntityState<T, Id>>(state: PreventAny<S, T, Id>, entities: readonly T[] | Record<Id, T>): S;
setMany<S extends DraftableEntityState<T, Id>>(state: PreventAny<S, T, Id>, entities: PayloadAction<readonly T[] | Record<Id, T>>): S;
setAll<S extends DraftableEntityState<T, Id>>(state: PreventAny<S, T, Id>, entities: readonly T[] | Record<Id, T>): S;
setAll<S extends DraftableEntityState<T, Id>>(state: PreventAny<S, T, Id>, entities: PayloadAction<readonly T[] | Record<Id, T>>): S;
removeOne<S extends DraftableEntityState<T, Id>>(state: PreventAny<S, T, Id>, key: Id): S;
removeOne<S extends DraftableEntityState<T, Id>>(state: PreventAny<S, T, Id>, key: PayloadAction<Id>): S;
removeMany<S extends DraftableEntityState<T, Id>>(state: PreventAny<S, T, Id>, keys: readonly Id[]): S;
removeMany<S extends DraftableEntityState<T, Id>>(state: PreventAny<S, T, Id>, keys: PayloadAction<readonly Id[]>): S;
removeAll<S extends DraftableEntityState<T, Id>>(state: PreventAny<S, T, Id>): S;
updateOne<S extends DraftableEntityState<T, Id>>(state: PreventAny<S, T, Id>, update: Update<T, Id>): S;
updateOne<S extends DraftableEntityState<T, Id>>(state: PreventAny<S, T, Id>, update: PayloadAction<Update<T, Id>>): S;
updateMany<S extends DraftableEntityState<T, Id>>(state: PreventAny<S, T, Id>, updates: ReadonlyArray<Update<T, Id>>): S;
updateMany<S extends DraftableEntityState<T, Id>>(state: PreventAny<S, T, Id>, updates: PayloadAction<ReadonlyArray<Update<T, Id>>>): S;
upsertOne<S extends DraftableEntityState<T, Id>>(state: PreventAny<S, T, Id>, entity: T): S;
upsertOne<S extends DraftableEntityState<T, Id>>(state: PreventAny<S, T, Id>, entity: PayloadAction<T>): S;
upsertMany<S extends DraftableEntityState<T, Id>>(state: PreventAny<S, T, Id>, entities: readonly T[] | Record<Id, T>): S;
upsertMany<S extends DraftableEntityState<T, Id>>(state: PreventAny<S, T, Id>, entities: PayloadAction<readonly T[] | Record<Id, T>>): S;
}

@@ -69,0 +71,0 @@ /**

@@ -1,5 +0,6 @@

import type { EntityId, EntityState, PreventAny } from './models';
import type { Draft } from 'immer';
import type { EntityId, DraftableEntityState, PreventAny } from './models';
import type { PayloadAction } from '../createAction';
import { IsAny } from '../tsHelpers';
export declare function createSingleArgumentStateOperator<T, Id extends EntityId>(mutator: (state: EntityState<T, Id>) => void): <S extends EntityState<T, Id>>(state: IsAny<S, EntityState<T, Id>, S>) => S;
export declare function createStateOperator<T, Id extends EntityId, R>(mutator: (arg: R, state: EntityState<T, Id>) => void): <S extends EntityState<T, Id>>(state: S, arg: R | PayloadAction<R>) => S;
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 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;

@@ -1,4 +0,4 @@

import type { EntityState, IdSelector, Update, EntityId } from './models';
import type { IdSelector, Update, EntityId, DraftableEntityState } from './models';
export declare function selectIdValue<T, Id extends EntityId>(entity: T, selectId: IdSelector<T, Id>): Id;
export declare function ensureEntitiesArray<T, Id extends EntityId>(entities: readonly T[] | Record<Id, T>): readonly T[];
export declare function splitAddedUpdatedEntities<T, Id extends EntityId>(newEntities: readonly T[] | Record<Id, T>, selectId: IdSelector<T, Id>, state: EntityState<T, Id>): [T[], Update<T, Id>[]];
export declare function splitAddedUpdatedEntities<T, Id extends EntityId>(newEntities: readonly T[] | Record<Id, T>, selectId: IdSelector<T, Id>, state: DraftableEntityState<T, Id>): [T[], Update<T, Id>[]];

@@ -89,3 +89,3 @@ import type { MutationHooks, QueryHooks } from './buildHooks';

*/
export declare const reactHooksModule: ({ batch, hooks, unstable__sideEffectsInRender, }?: ReactHooksModuleOptions) => Module<ReactHooksModule>;
export declare const reactHooksModule: ({ batch, hooks, unstable__sideEffectsInRender, ...rest }?: ReactHooksModuleOptions) => Module<ReactHooksModule>;
export {};
import type { UseMutation, UseLazyQuery, UseQuery } from './buildHooks';
import type { DefinitionType, EndpointDefinitions, MutationDefinition, QueryDefinition } from '@reduxjs/toolkit/query';
export type HooksWithUniqueNames<Definitions extends EndpointDefinitions> = keyof Definitions extends infer Keys ? Keys extends string ? Definitions[Keys] extends {
type: DefinitionType.query;
} ? {
[K in Keys as `use${Capitalize<K>}Query`]: UseQuery<Extract<Definitions[K], QueryDefinition<any, any, any, any>>>;
} & {
[K in Keys as `useLazy${Capitalize<K>}Query`]: UseLazyQuery<Extract<Definitions[K], QueryDefinition<any, any, any, any>>>;
} : Definitions[Keys] extends {
type: DefinitionType.mutation;
} ? {
[K in Keys as `use${Capitalize<K>}Mutation`]: UseMutation<Extract<Definitions[K], MutationDefinition<any, any, any, any>>>;
} : never : never : never;
type QueryHookNames<Definitions extends EndpointDefinitions> = {
[K in keyof Definitions as Definitions[K] extends {
type: DefinitionType.query;
} ? `use${Capitalize<K & string>}Query` : never]: UseQuery<Extract<Definitions[K], QueryDefinition<any, any, any, any>>>;
};
type LazyQueryHookNames<Definitions extends EndpointDefinitions> = {
[K in keyof Definitions as Definitions[K] extends {
type: DefinitionType.query;
} ? `useLazy${Capitalize<K & string>}Query` : never]: UseLazyQuery<Extract<Definitions[K], QueryDefinition<any, any, any, any>>>;
};
type MutationHookNames<Definitions extends EndpointDefinitions> = {
[K in keyof Definitions as Definitions[K] extends {
type: DefinitionType.mutation;
} ? `use${Capitalize<K & string>}Mutation` : never]: UseMutation<Extract<Definitions[K], MutationDefinition<any, any, any, any>>>;
};
export type HooksWithUniqueNames<Definitions extends EndpointDefinitions> = QueryHookNames<Definitions> & LazyQueryHookNames<Definitions> & MutationHookNames<Definitions>;
export {};
// src/query/react/index.ts
import { coreModule, buildCreateApi } from "@reduxjs/toolkit/query";
// src/query/react/module.ts
import { formatProdErrorMessage as _formatProdErrorMessage3 } from "@reduxjs/toolkit";
// src/query/react/buildHooks.ts

@@ -460,59 +463,81 @@ import { formatProdErrorMessage as _formatProdErrorMessage2 } from "@reduxjs/toolkit";

},
unstable__sideEffectsInRender = false
} = {}) => ({
name: reactHooksModuleName,
init(api, {
serializeQueryArgs
}, context) {
const anyApi = api;
const {
buildQueryHooks,
buildMutationHook,
usePrefetch
} = buildHooks({
api,
moduleOptions: {
batch,
hooks,
unstable__sideEffectsInRender
},
serializeQueryArgs,
context
});
safeAssign(anyApi, {
usePrefetch
});
safeAssign(context, {
batch
});
return {
injectEndpoint(endpointName, definition) {
if (isQueryDefinition(definition)) {
const {
useQuery,
useLazyQuery,
useLazyQuerySubscription,
useQueryState,
useQuerySubscription
} = buildQueryHooks(endpointName);
safeAssign(anyApi.endpoints[endpointName], {
useQuery,
useLazyQuery,
useLazyQuerySubscription,
useQueryState,
useQuerySubscription
});
api[`use${capitalize(endpointName)}Query`] = useQuery;
api[`useLazy${capitalize(endpointName)}Query`] = useLazyQuery;
} else if (isMutationDefinition(definition)) {
const useMutation = buildMutationHook(endpointName);
safeAssign(anyApi.endpoints[endpointName], {
useMutation
});
api[`use${capitalize(endpointName)}Mutation`] = useMutation;
unstable__sideEffectsInRender = false,
...rest
} = {}) => {
if (process.env.NODE_ENV !== "production") {
const hookNames = ["useDispatch", "useSelector", "useStore"];
let warned = false;
for (const hookName of hookNames) {
if (Object.keys(rest).length > 0) {
if (rest[hookName]) {
if (!warned) {
console.warn("As of RTK 2.0, the hooks now need to be specified as one object, provided under a `hooks` key:\n`reactHooksModule({ hooks: { useDispatch, useSelector, useStore } })`");
warned = true;
}
}
hooks[hookName] = rest[hookName];
}
};
if (typeof hooks[hookName] !== "function") {
throw new Error(process.env.NODE_ENV === "production" ? _formatProdErrorMessage3(32) : `When using custom hooks for context, all ${hookNames.length} hooks need to be provided: ${hookNames.join(", ")}.
Hook ${hookName} was either not provided or not a function.`);
}
}
}
});
return {
name: reactHooksModuleName,
init(api, {
serializeQueryArgs
}, context) {
const anyApi = api;
const {
buildQueryHooks,
buildMutationHook,
usePrefetch
} = buildHooks({
api,
moduleOptions: {
batch,
hooks,
unstable__sideEffectsInRender
},
serializeQueryArgs,
context
});
safeAssign(anyApi, {
usePrefetch
});
safeAssign(context, {
batch
});
return {
injectEndpoint(endpointName, definition) {
if (isQueryDefinition(definition)) {
const {
useQuery,
useLazyQuery,
useLazyQuerySubscription,
useQueryState,
useQuerySubscription
} = buildQueryHooks(endpointName);
safeAssign(anyApi.endpoints[endpointName], {
useQuery,
useLazyQuery,
useLazyQuerySubscription,
useQueryState,
useQuerySubscription
});
api[`use${capitalize(endpointName)}Query`] = useQuery;
api[`useLazy${capitalize(endpointName)}Query`] = useLazyQuery;
} else if (isMutationDefinition(definition)) {
const useMutation = buildMutationHook(endpointName);
safeAssign(anyApi.endpoints[endpointName], {
useMutation
});
api[`use${capitalize(endpointName)}Mutation`] = useMutation;
}
}
};
}
};
};

@@ -519,0 +544,0 @@ // src/query/react/index.ts

{
"name": "@reduxjs/toolkit",
"version": "2.0.0-beta.2",
"version": "2.0.0-beta.3",
"description": "The official, opinionated, batteries-included toolset for efficient Redux development",

@@ -53,2 +53,3 @@ "author": "Mark Erikson <mark@isquaredsoftware.com>",

"@microsoft/api-extractor": "^7.13.2",
"@phryneas/ts-version": "^1.0.2",
"@size-limit/preset-small-lib": "^4.11.0",

@@ -55,0 +56,0 @@ "@testing-library/react": "^13.3.0",

@@ -56,3 +56,3 @@ import type {

*/
middleware?: ((getDefaultMiddleware: GetDefaultMiddleware<S>) => M) | M
middleware?: (getDefaultMiddleware: GetDefaultMiddleware<S>) => M

@@ -125,3 +125,3 @@ /**

reducer = undefined,
middleware = getDefaultMiddleware(),
middleware,
devTools = true,

@@ -144,6 +144,10 @@ preloadedState = undefined,

let finalMiddleware = middleware
if (typeof finalMiddleware === 'function') {
finalMiddleware = finalMiddleware(getDefaultMiddleware)
if (!IS_PRODUCTION && middleware && typeof middleware !== 'function') {
throw new Error('"middleware" field must be a callback')
}
let finalMiddleware: Tuple<Middlewares<S>>
if (typeof middleware === 'function') {
finalMiddleware = middleware(getDefaultMiddleware)
if (!IS_PRODUCTION && !Array.isArray(finalMiddleware)) {

@@ -154,2 +158,4 @@ throw new Error(

}
} else {
finalMiddleware = getDefaultMiddleware()
}

@@ -156,0 +162,0 @@ if (

import type { UncheckedIndexedAccess } from '../uncheckedindexed'
import type { Draft } from 'immer'
import type { PayloadAction } from '../createAction'

@@ -45,4 +46,6 @@ import type { GetSelectorsOptions } from './state_selectors'

EntityState<T, Id>
>
>
export type DraftableEntityState<T, Id extends EntityId> = EntityState<T, Id> | Draft<EntityState<T, Id>>
/**

@@ -52,7 +55,7 @@ * @public

export interface EntityStateAdapter<T, Id extends EntityId> {
addOne<S extends EntityState<T, Id>>(
addOne<S extends DraftableEntityState<T, Id>>(
state: PreventAny<S, T, Id>,
entity: T
): S
addOne<S extends EntityState<T, Id>>(
addOne<S extends DraftableEntityState<T, Id>>(
state: PreventAny<S, T, Id>,

@@ -62,7 +65,7 @@ action: PayloadAction<T>

addMany<S extends EntityState<T, Id>>(
addMany<S extends DraftableEntityState<T, Id>>(
state: PreventAny<S, T, Id>,
entities: readonly T[] | Record<Id, T>
): S
addMany<S extends EntityState<T, Id>>(
addMany<S extends DraftableEntityState<T, Id>>(
state: PreventAny<S, T, Id>,

@@ -72,23 +75,23 @@ entities: PayloadAction<readonly T[] | Record<Id, T>>

setOne<S extends EntityState<T, Id>>(
setOne<S extends DraftableEntityState<T, Id>>(
state: PreventAny<S, T, Id>,
entity: T
): S
setOne<S extends EntityState<T, Id>>(
setOne<S extends DraftableEntityState<T, Id>>(
state: PreventAny<S, T, Id>,
action: PayloadAction<T>
): S
setMany<S extends EntityState<T, Id>>(
setMany<S extends DraftableEntityState<T, Id>>(
state: PreventAny<S, T, Id>,
entities: readonly T[] | Record<Id, T>
): S
setMany<S extends EntityState<T, Id>>(
setMany<S extends DraftableEntityState<T, Id>>(
state: PreventAny<S, T, Id>,
entities: PayloadAction<readonly T[] | Record<Id, T>>
): S
setAll<S extends EntityState<T, Id>>(
setAll<S extends DraftableEntityState<T, Id>>(
state: PreventAny<S, T, Id>,
entities: readonly T[] | Record<Id, T>
): S
setAll<S extends EntityState<T, Id>>(
setAll<S extends DraftableEntityState<T, Id>>(
state: PreventAny<S, T, Id>,

@@ -98,7 +101,7 @@ entities: PayloadAction<readonly T[] | Record<Id, T>>

removeOne<S extends EntityState<T, Id>>(
removeOne<S extends DraftableEntityState<T, Id>>(
state: PreventAny<S, T, Id>,
key: Id
): S
removeOne<S extends EntityState<T, Id>>(
removeOne<S extends DraftableEntityState<T, Id>>(
state: PreventAny<S, T, Id>,

@@ -108,7 +111,7 @@ key: PayloadAction<Id>

removeMany<S extends EntityState<T, Id>>(
removeMany<S extends DraftableEntityState<T, Id>>(
state: PreventAny<S, T, Id>,
keys: readonly Id[]
): S
removeMany<S extends EntityState<T, Id>>(
removeMany<S extends DraftableEntityState<T, Id>>(
state: PreventAny<S, T, Id>,

@@ -118,9 +121,9 @@ keys: PayloadAction<readonly Id[]>

removeAll<S extends EntityState<T, Id>>(state: PreventAny<S, T, Id>): S
removeAll<S extends DraftableEntityState<T, Id>>(state: PreventAny<S, T, Id>): S
updateOne<S extends EntityState<T, Id>>(
updateOne<S extends DraftableEntityState<T, Id>>(
state: PreventAny<S, T, Id>,
update: Update<T, Id>
): S
updateOne<S extends EntityState<T, Id>>(
updateOne<S extends DraftableEntityState<T, Id>>(
state: PreventAny<S, T, Id>,

@@ -130,7 +133,7 @@ update: PayloadAction<Update<T, Id>>

updateMany<S extends EntityState<T, Id>>(
updateMany<S extends DraftableEntityState<T, Id>>(
state: PreventAny<S, T, Id>,
updates: ReadonlyArray<Update<T, Id>>
): S
updateMany<S extends EntityState<T, Id>>(
updateMany<S extends DraftableEntityState<T, Id>>(
state: PreventAny<S, T, Id>,

@@ -140,7 +143,7 @@ updates: PayloadAction<ReadonlyArray<Update<T, Id>>>

upsertOne<S extends EntityState<T, Id>>(
upsertOne<S extends DraftableEntityState<T, Id>>(
state: PreventAny<S, T, Id>,
entity: T
): S
upsertOne<S extends EntityState<T, Id>>(
upsertOne<S extends DraftableEntityState<T, Id>>(
state: PreventAny<S, T, Id>,

@@ -150,7 +153,7 @@ entity: PayloadAction<T>

upsertMany<S extends EntityState<T, Id>>(
upsertMany<S extends DraftableEntityState<T, Id>>(
state: PreventAny<S, T, Id>,
entities: readonly T[] | Record<Id, T>
): S
upsertMany<S extends EntityState<T, Id>>(
upsertMany<S extends DraftableEntityState<T, Id>>(
state: PreventAny<S, T, Id>,

@@ -157,0 +160,0 @@ entities: PayloadAction<readonly T[] | Record<Id, T>>

import type {
EntityState,
IdSelector,

@@ -8,2 +7,3 @@ Comparer,

EntityId,
DraftableEntityState
} from './models'

@@ -22,3 +22,3 @@ import { createStateOperator } from './state_adapter'

): EntityStateAdapter<T, Id> {
type R = EntityState<T, Id>
type R = DraftableEntityState<T, Id>

@@ -83,3 +83,3 @@ const { removeOne, removeMany, removeAll } =

for (let update of updates) {
const entity: T | undefined = state.entities[update.id]
const entity: T | undefined = (state.entities as Record<Id, T>)[update.id]
if (!entity) {

@@ -94,4 +94,4 @@ continue

if (update.id !== newId) {
delete state.entities[update.id]
state.entities[newId] = entity
delete (state.entities as Record<Id, T>)[update.id];
(state.entities as Record<Id, T>)[newId] = entity
}

@@ -140,3 +140,3 @@ }

models.forEach((model) => {
state.entities[selectId(model)] = model
(state.entities as Record<Id, T>)[selectId(model)] = model
})

@@ -143,0 +143,0 @@

import { produce as createNextState, isDraft } from 'immer'
import type { EntityId, EntityState, PreventAny } from './models'
import type { Draft } from 'immer'
import type { EntityId, DraftableEntityState, PreventAny } from './models'
import type { PayloadAction } from '../createAction'
import { isFSA } from '../createAction'
import { IsAny } from '../tsHelpers'
export const isDraftTyped = isDraft as <T>(value: T | Draft<T>) => value is Draft<T>
export function createSingleArgumentStateOperator<T, Id extends EntityId>(
mutator: (state: EntityState<T, Id>) => void
mutator: (state: DraftableEntityState<T, Id>) => void
) {
const operator = createStateOperator(
(_: undefined, state: EntityState<T, Id>) => mutator(state)
(_: undefined, state: DraftableEntityState<T, Id>) => mutator(state)
)
return function operation<S extends EntityState<T, Id>>(
return function operation<S extends DraftableEntityState<T, Id>>(
state: PreventAny<S, T, Id>

@@ -22,5 +24,5 @@ ): S {

export function createStateOperator<T, Id extends EntityId, R>(
mutator: (arg: R, state: EntityState<T, Id>) => void
mutator: (arg: R, state: DraftableEntityState<T, Id>) => void
) {
return function operation<S extends EntityState<T, Id>>(
return function operation<S extends DraftableEntityState<T, Id>>(
state: S,

@@ -35,3 +37,3 @@ arg: R | PayloadAction<R>

const runMutator = (draft: EntityState<T, Id>) => {
const runMutator = (draft: DraftableEntityState<T, Id>) => {
if (isPayloadActionArgument(arg)) {

@@ -44,3 +46,3 @@ mutator(arg.payload, draft)

if (isDraft(state)) {
if (isDraftTyped<DraftableEntityState<T, Id>>(state)) {
// we must already be inside a `createNextState` call, likely because

@@ -53,9 +55,6 @@ // this is being wrapped in `createReducer` or `createSlice`.

return state
} else {
// @ts-ignore createNextState() produces an Immutable<Draft<S>> rather
// than an Immutable<S>, and TypeScript cannot find out how to reconcile
// these two types.
return createNextState(state, runMutator)
}
return createNextState(state, runMutator)
}
}

@@ -9,3 +9,3 @@ import type { EntityAdapter } from '../index'

describe('Entity State', () => {
let adapter: EntityAdapter<string, BookModel>
let adapter: EntityAdapter<BookModel, string>

@@ -12,0 +12,0 @@ beforeEach(() => {

@@ -0,3 +1,3 @@

import type { Draft } from 'immer'
import type {
EntityState,
EntityStateAdapter,

@@ -7,2 +7,3 @@ IdSelector,

EntityId,
DraftableEntityState
} from './models'

@@ -22,3 +23,3 @@ import {

): EntityStateAdapter<T, Id> {
type R = EntityState<T, Id>
type R = DraftableEntityState<T, Id>

@@ -32,4 +33,4 @@ function addOneMutably(entity: T, state: R): void {

state.ids.push(key)
state.entities[key] = entity
state.ids.push(key as Id & Draft<Id>);
(state.entities as Record<Id, T>)[key] = entity
}

@@ -51,5 +52,5 @@

if (!(key in state.entities)) {
state.ids.push(key)
state.ids.push(key as Id & Draft<Id>);
}
state.entities[key] = entity
(state.entities as Record<Id, T>)[key] = entity
}

@@ -88,3 +89,3 @@

if (key in state.entities) {
delete state.entities[key]
delete (state.entities as Record<Id, T>)[key]
didMutate = true

@@ -95,3 +96,3 @@ }

if (didMutate) {
state.ids = state.ids.filter((id) => id in state.entities)
state.ids = (state.ids as Id[]).filter((id) => id in state.entities) as Id[] | Draft<Id[]>
}

@@ -112,3 +113,3 @@ }

): boolean {
const original: T | undefined = state.entities[update.id]
const original: T | undefined = (state.entities as Record<Id, T>)[update.id]
if (original === undefined) {

@@ -123,6 +124,6 @@ return false

keys[update.id] = newKey
delete state.entities[update.id]
delete (state.entities as Record<Id, T>)[update.id]
}
state.entities[newKey] = updated
(state.entities as Record<Id, T>)[newKey] = updated

@@ -129,0 +130,0 @@ return hasNewKey

@@ -1,2 +0,2 @@

import type { EntityState, IdSelector, Update, EntityId } from './models'
import type { IdSelector, Update, EntityId, DraftableEntityState } from './models'

@@ -36,3 +36,3 @@ export function selectIdValue<T, Id extends EntityId>(

selectId: IdSelector<T, Id>,
state: EntityState<T, Id>
state: DraftableEntityState<T, Id>
): [T[], Update<T, Id>[]] {

@@ -39,0 +39,0 @@ newEntities = ensureEntitiesArray(newEntities)

@@ -143,55 +143,91 @@ import type { MutationHooks, QueryHooks } from './buildHooks'

unstable__sideEffectsInRender = false,
}: ReactHooksModuleOptions = {}): Module<ReactHooksModule> => ({
name: reactHooksModuleName,
init(api, { serializeQueryArgs }, context) {
const anyApi = api as any as Api<
any,
Record<string, any>,
string,
string,
ReactHooksModule
>
const { buildQueryHooks, buildMutationHook, usePrefetch } = buildHooks({
api,
moduleOptions: {
batch,
hooks,
unstable__sideEffectsInRender,
},
serializeQueryArgs,
context,
})
safeAssign(anyApi, { usePrefetch })
safeAssign(context, { batch })
return {
injectEndpoint(endpointName, definition) {
if (isQueryDefinition(definition)) {
const {
useQuery,
useLazyQuery,
useLazyQuerySubscription,
useQueryState,
useQuerySubscription,
} = buildQueryHooks(endpointName)
safeAssign(anyApi.endpoints[endpointName], {
useQuery,
useLazyQuery,
useLazyQuerySubscription,
useQueryState,
useQuerySubscription,
})
;(api as any)[`use${capitalize(endpointName)}Query`] = useQuery
;(api as any)[`useLazy${capitalize(endpointName)}Query`] =
useLazyQuery
} else if (isMutationDefinition(definition)) {
const useMutation = buildMutationHook(endpointName)
safeAssign(anyApi.endpoints[endpointName], {
useMutation,
})
;(api as any)[`use${capitalize(endpointName)}Mutation`] = useMutation
...rest
}: ReactHooksModuleOptions = {}): Module<ReactHooksModule> => {
if (process.env.NODE_ENV !== 'production') {
const hookNames = ['useDispatch', 'useSelector', 'useStore'] as const
let warned = false
for (const hookName of hookNames) {
// warn for old hook options
if (Object.keys(rest).length > 0) {
if ((rest as Partial<typeof hooks>)[hookName]) {
if (!warned) {
console.warn(
'As of RTK 2.0, the hooks now need to be specified as one object, provided under a `hooks` key:' +
'\n`reactHooksModule({ hooks: { useDispatch, useSelector, useStore } })`'
)
warned = true
}
}
},
// migrate
// @ts-ignore
hooks[hookName] = rest[hookName]
}
// then make sure we have them all
if (typeof hooks[hookName] !== 'function') {
throw new Error(
`When using custom hooks for context, all ${
hookNames.length
} hooks need to be provided: ${hookNames.join(
', '
)}.\nHook ${hookName} was either not provided or not a function.`
)
}
}
},
})
}
return {
name: reactHooksModuleName,
init(api, { serializeQueryArgs }, context) {
const anyApi = api as any as Api<
any,
Record<string, any>,
string,
string,
ReactHooksModule
>
const { buildQueryHooks, buildMutationHook, usePrefetch } = buildHooks({
api,
moduleOptions: {
batch,
hooks,
unstable__sideEffectsInRender,
},
serializeQueryArgs,
context,
})
safeAssign(anyApi, { usePrefetch })
safeAssign(context, { batch })
return {
injectEndpoint(endpointName, definition) {
if (isQueryDefinition(definition)) {
const {
useQuery,
useLazyQuery,
useLazyQuerySubscription,
useQueryState,
useQuerySubscription,
} = buildQueryHooks(endpointName)
safeAssign(anyApi.endpoints[endpointName], {
useQuery,
useLazyQuery,
useLazyQuerySubscription,
useQueryState,
useQuerySubscription,
})
;(api as any)[`use${capitalize(endpointName)}Query`] = useQuery
;(api as any)[`useLazy${capitalize(endpointName)}Query`] =
useLazyQuery
} else if (isMutationDefinition(definition)) {
const useMutation = buildMutationHook(endpointName)
safeAssign(anyApi.endpoints[endpointName], {
useMutation,
})
;(api as any)[`use${capitalize(endpointName)}Mutation`] =
useMutation
}
},
}
},
}
}

@@ -9,24 +9,35 @@ import type { UseMutation, UseLazyQuery, UseQuery } from './buildHooks'

type QueryHookNames<Definitions extends EndpointDefinitions> = {
[K in keyof Definitions as Definitions[K] extends {
type: DefinitionType.query
}
? `use${Capitalize<K & string>}Query`
: never]: UseQuery<
Extract<Definitions[K], QueryDefinition<any, any, any, any>>
>
}
type LazyQueryHookNames<Definitions extends EndpointDefinitions> = {
[K in keyof Definitions as Definitions[K] extends {
type: DefinitionType.query
}
? `useLazy${Capitalize<K & string>}Query`
: never]: UseLazyQuery<
Extract<Definitions[K], QueryDefinition<any, any, any, any>>
>
}
type MutationHookNames<Definitions extends EndpointDefinitions> = {
[K in keyof Definitions as Definitions[K] extends {
type: DefinitionType.mutation
}
? `use${Capitalize<K & string>}Mutation`
: never]: UseMutation<
Extract<Definitions[K], MutationDefinition<any, any, any, any>>
>
}
export type HooksWithUniqueNames<Definitions extends EndpointDefinitions> =
keyof Definitions extends infer Keys
? Keys extends string
? Definitions[Keys] extends { type: DefinitionType.query }
? {
[K in Keys as `use${Capitalize<K>}Query`]: UseQuery<
Extract<Definitions[K], QueryDefinition<any, any, any, any>>
>
} &
{
[K in Keys as `useLazy${Capitalize<K>}Query`]: UseLazyQuery<
Extract<Definitions[K], QueryDefinition<any, any, any, any>>
>
}
: Definitions[Keys] extends { type: DefinitionType.mutation }
? {
[K in Keys as `use${Capitalize<K>}Mutation`]: UseMutation<
Extract<Definitions[K], MutationDefinition<any, any, any, any>>
>
}
: never
: never
: never
QueryHookNames<Definitions> &
LazyQueryHookNames<Definitions> &
MutationHookNames<Definitions>

@@ -113,3 +113,3 @@ import { vi } from 'vitest'

expect(
configureStore({ middleware: new Tuple(), reducer })
configureStore({ middleware: () => new Tuple(), reducer })
).toBeInstanceOf(Object)

@@ -126,2 +126,11 @@ expect(redux.applyMiddleware).toHaveBeenCalledWith()

describe('given an array of middleware', () => {
it('throws an error requiring a callback', () => {
// @ts-expect-error
expect(() => configureStore({ middleware: [], reducer })).toThrow(
'"middleware" field must be a callback'
)
})
})
describe('given undefined middleware', () => {

@@ -167,10 +176,2 @@ it('calls createStore with default middleware', () => {

describe('given custom middleware that contains non-functions', () => {
it('throws an error', () => {
expect(() =>
configureStore({ middleware: [true] as any, reducer })
).toThrow('each middleware provided to configureStore must be a function')
})
})
describe('given custom middleware', () => {

@@ -181,3 +182,3 @@ it('calls createStore with custom middleware and without default middleware', () => {

expect(
configureStore({ middleware: new Tuple(thank), reducer })
configureStore({ middleware: () => new Tuple(thank), reducer })
).toBeInstanceOf(Object)

@@ -337,3 +338,3 @@ expect(redux.applyMiddleware).toHaveBeenCalledWith(thank)

reducer,
middleware: new Tuple(),
middleware: () => new Tuple(),
enhancers: () => new Tuple(dummyEnhancer),

@@ -340,0 +341,0 @@ })

@@ -77,3 +77,3 @@ /* eslint-disable no-lone-blocks */

reducer: () => 0,
middleware: new Tuple(middleware),
middleware: () => new Tuple(middleware),
})

@@ -84,3 +84,3 @@

// @ts-expect-error
middleware: [middleware],
middleware: () => [middleware],
})

@@ -91,3 +91,3 @@

// @ts-expect-error
middleware: new Tuple('not middleware'),
middleware: () => new Tuple('not middleware'),
})

@@ -526,3 +526,3 @@ }

reducer: reducerA,
middleware: new Tuple(),
middleware: () => new Tuple(),
})

@@ -540,3 +540,3 @@ // @ts-expect-error

reducer: reducerA,
middleware: new Tuple(thunk as ThunkMiddleware<StateA>),
middleware: () => new Tuple(thunk as ThunkMiddleware<StateA>),
})

@@ -553,5 +553,4 @@ store.dispatch(thunkA())

reducer: reducerA,
middleware: new Tuple(
0 as unknown as Middleware<(a: StateA) => boolean, StateA>
),
middleware: () =>
new Tuple(0 as unknown as Middleware<(a: StateA) => boolean, StateA>),
})

@@ -575,3 +574,3 @@ const result: boolean = store.dispatch(5)

reducer: reducerA,
middleware,
middleware: () => middleware,
})

@@ -578,0 +577,0 @@

@@ -24,2 +24,3 @@ /* eslint-disable no-lone-blocks */

} from '@internal/createAsyncThunk'
import type { TSVersion } from '@phryneas/ts-version'

@@ -295,4 +296,18 @@ const ANY = {} as any

const asyncThunk = createAsyncThunk('test', (arg?: number) => 0)
expectType<(arg?: number) => any>(asyncThunk)
asyncThunk()
// Per https://github.com/reduxjs/redux-toolkit/issues/3758#issuecomment-1742152774 , this is a bug in
// TS 5.1 and 5.2, that is fixed in 5.3. Conditionally run the TS assertion here.
type IsTS51Or52 = TSVersion.Major extends 5
? TSVersion.Minor extends 1 | 2
? true
: false
: false
type expectedType = IsTS51Or52 extends true
? (arg: number) => any
: (arg?: number) => any
expectType<expectedType>(asyncThunk)
// We _should_ be able to call this with no arguments, but we run into that error in 5.1 and 5.2.
// Disabling this for now.
// asyncThunk()
asyncThunk(5)

@@ -299,0 +314,0 @@ // @ts-expect-error

@@ -253,3 +253,3 @@ import { vi } from 'vitest'

}).toThrowErrorMatchingInlineSnapshot(
`"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"'
)

@@ -256,0 +256,0 @@ })

@@ -150,13 +150,14 @@ import { vi } from 'vitest'

const middleware = getDefaultMiddleware({
thunk: false,
immutableCheck: {
isImmutable: () => {
immutableCheckWasCalled = true
return true
const middleware = () =>
getDefaultMiddleware({
thunk: false,
immutableCheck: {
isImmutable: () => {
immutableCheckWasCalled = true
return true
},
},
},
serializableCheck: false,
actionCreatorCheck: false,
})
serializableCheck: false,
actionCreatorCheck: false,
})

@@ -176,13 +177,14 @@ const reducer = () => ({})

const middleware = getDefaultMiddleware({
thunk: false,
immutableCheck: false,
serializableCheck: {
isSerializable: () => {
serializableCheckWasCalled = true
return true
const middleware = () =>
getDefaultMiddleware({
thunk: false,
immutableCheck: false,
serializableCheck: {
isSerializable: () => {
serializableCheckWasCalled = true
return true
},
},
},
actionCreatorCheck: false,
})
actionCreatorCheck: false,
})

@@ -205,13 +207,14 @@ const reducer = () => ({})

const middleware = getDefaultMiddleware({
thunk: false,
immutableCheck: false,
serializableCheck: false,
actionCreatorCheck: {
isActionCreator: (action: unknown): action is Function => {
actionCreatorCheckWasCalled = true
return false
const middleware = () =>
getDefaultMiddleware({
thunk: false,
immutableCheck: false,
serializableCheck: false,
actionCreatorCheck: {
isActionCreator: (action: unknown): action is Function => {
actionCreatorCheckWasCalled = true
return false
},
},
},
})
})

@@ -218,0 +221,0 @@ const reducer = () => ({})

@@ -104,3 +104,3 @@ import {

reducer,
middleware: new Tuple(serializableStateInvariantMiddleware),
middleware: () => new Tuple(serializableStateInvariantMiddleware),
})

@@ -152,3 +152,3 @@

},
middleware: new Tuple(serializableStateInvariantMiddleware),
middleware: () => new Tuple(serializableStateInvariantMiddleware),
})

@@ -213,3 +213,3 @@

},
middleware: new Tuple(serializableStateInvariantMiddleware),
middleware: () => new Tuple(serializableStateInvariantMiddleware),
})

@@ -261,3 +261,3 @@

},
middleware: new Tuple(serializableStateInvariantMiddleware),
middleware: () => new Tuple(serializableStateInvariantMiddleware),
})

@@ -306,3 +306,3 @@

},
middleware: new Tuple(serializableStateInvariantMiddleware),
middleware: () => new Tuple(serializableStateInvariantMiddleware),
})

@@ -331,3 +331,3 @@

reducer: () => ({}),
middleware: new Tuple(serializableStateMiddleware),
middleware: () => new Tuple(serializableStateMiddleware),
})

@@ -357,3 +357,4 @@

reducer,
middleware: new Tuple(createSerializableStateInvariantMiddleware()),
middleware: () =>
new Tuple(createSerializableStateInvariantMiddleware()),
}).dispatch({ type: 'test', meta: { arg: nonSerializableValue } })

@@ -367,7 +368,8 @@

reducer,
middleware: new Tuple(
createSerializableStateInvariantMiddleware({
ignoredActionPaths: [],
})
),
middleware: () =>
new Tuple(
createSerializableStateInvariantMiddleware({
ignoredActionPaths: [],
})
),
}).dispatch({ type: 'test', meta: { arg: nonSerializableValue } })

@@ -391,7 +393,8 @@

reducer,
middleware: new Tuple(
createSerializableStateInvariantMiddleware({
ignoredActionPaths: ['payload', 'meta.arg'],
})
),
middleware: () =>
new Tuple(
createSerializableStateInvariantMiddleware({
ignoredActionPaths: ['payload', 'meta.arg'],
})
),
}).dispatch({

@@ -409,7 +412,8 @@ type: 'test',

reducer,
middleware: new Tuple(
createSerializableStateInvariantMiddleware({
ignoredActionPaths: [/^payload\..*$/],
})
),
middleware: () =>
new Tuple(
createSerializableStateInvariantMiddleware({
ignoredActionPaths: [/^payload\..*$/],
})
),
}).dispatch({

@@ -438,3 +442,3 @@ type: 'test',

reducer: () => ({}),
middleware: new Tuple(serializableStateMiddleware),
middleware: () => new Tuple(serializableStateMiddleware),
})

@@ -502,3 +506,3 @@

},
middleware: new Tuple(serializableStateInvariantMiddleware),
middleware: () => new Tuple(serializableStateInvariantMiddleware),
})

@@ -522,11 +526,12 @@

reducer,
middleware: new Tuple(
createSerializableStateInvariantMiddleware({
isSerializable: () => {
numTimesCalled++
return true
},
ignoreState: true,
})
),
middleware: () =>
new Tuple(
createSerializableStateInvariantMiddleware({
isSerializable: () => {
numTimesCalled++
return true
},
ignoreState: true,
})
),
})

@@ -550,12 +555,13 @@

reducer,
middleware: new Tuple(
createSerializableStateInvariantMiddleware({
isSerializable: () => {
numTimesCalled++
return true
},
ignoreState: true,
ignoreActions: true,
})
),
middleware: () =>
new Tuple(
createSerializableStateInvariantMiddleware({
isSerializable: () => {
numTimesCalled++
return true
},
ignoreState: true,
ignoreActions: true,
})
),
})

@@ -583,3 +589,3 @@

},
middleware: new Tuple(serializableStateInvariantMiddleware),
middleware: () => new Tuple(serializableStateInvariantMiddleware),
})

@@ -610,3 +616,3 @@

},
middleware: new Tuple(serializableStateInvariantMiddleware),
middleware: () => new Tuple(serializableStateInvariantMiddleware),
})

@@ -635,3 +641,3 @@

},
middleware: new Tuple(serializableStateInvariantMiddleware),
middleware: () => new Tuple(serializableStateInvariantMiddleware),
})

@@ -638,0 +644,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 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 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 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

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

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc