Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Id type parameter in createEntityAdapter #3187

Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion examples/publish-ci/cra4/src/mocks/handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ export const handlers = [
}),

rest.get('/posts/:id', (req, res, ctx) => {
const { id } = req.params as { id: string }
const { id: idParam } = req.params as { id: string }
const id = parseInt(idParam, 10)
state = adapter.updateOne(state, {
id,
changes: { fetched_at: new Date().toUTCString() },
Expand Down
3 changes: 2 additions & 1 deletion examples/publish-ci/cra5/src/mocks/handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ export const handlers = [
}),

rest.get('/posts/:id', (req, res, ctx) => {
const { id } = req.params as { id: string }
const { id: idParam } = req.params as { id: string }
const id = parseInt(idParam, 10)
state = adapter.updateOne(state, {
id,
changes: { fetched_at: new Date().toUTCString() },
Expand Down
3 changes: 2 additions & 1 deletion examples/publish-ci/next/src/mocks/handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ export const handlers = [
}),

rest.get('/posts/:id', (req, res, ctx) => {
const { id } = req.params as { id: string }
const { id: idParam } = req.params as { id: string }
const id = parseInt(idParam, 10)
state = adapter.updateOne(state, {
id,
changes: { fetched_at: new Date().toUTCString() },
Expand Down
3 changes: 2 additions & 1 deletion examples/publish-ci/vite/src/mocks/handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ export const handlers = [
}),

rest.get('/posts/:id', (req, res, ctx) => {
const { id } = req.params as { id: string }
const { id: idParam } = req.params as { id: string }
const id = parseInt(idParam, 10)
state = adapter.updateOne(state, {
id,
changes: { fetched_at: new Date().toUTCString() },
Expand Down
9 changes: 6 additions & 3 deletions examples/query/react/kitchen-sink/src/mocks/handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,15 @@ export const handlers = [
}),

rest.get('/posts/:id', (req, res, ctx) => {
const { id } = req.params as { id: string };
const { id: idParam } = req.params as { id: string }
const id = parseInt(idParam, 10)
state = adapter.updateOne(state, { id, changes: { fetched_at: new Date().toUTCString() } });
return res(ctx.json(state.entities[id]), ctx.delay(400));
}),

rest.put('/posts/:id', (req, res, ctx) => {
const { id } = req.params as { id: string };
const { id: idParam } = req.params as { id: string }
const id = parseInt(idParam, 10)
const changes = req.body as Partial<Post>;

state = adapter.updateOne(state, { id, changes });
Expand All @@ -84,7 +86,8 @@ export const handlers = [
}),

rest.delete('/posts/:id', (req, res, ctx) => {
const { id } = req.params as { id: string };
const { id: idParam } = req.params as { id: string }
const id = parseInt(idParam, 10)

state = adapter.removeOne(state, id);

Expand Down
2 changes: 2 additions & 0 deletions packages/rtk-query-codegen-openapi/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -137,3 +137,5 @@ yalc.lock
lib
yarn.lock
test/tmp/example.ts
test/tmp/emptyApi.ts
test/tmp/out.ts
4 changes: 2 additions & 2 deletions packages/toolkit/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ Redux Toolkit includes these APIs:
- `configureStore()`: wraps `createStore` to provide simplified configuration options and good defaults. It can automatically combine your slice reducers, add whatever Redux middleware you supply, includes `redux-thunk` by default, and enables use of the Redux DevTools Extension.
- `createReducer()`: lets you supply a lookup table of action types to case reducer functions, rather than writing switch statements. In addition, it automatically uses the [`immer` library](https://github.com/mweststrate/immer) to let you write simpler immutable updates with normal mutative code, like `state.todos[3].completed = true`.
- `createAction()`: generates an action creator function for the given action type string. The function itself has `toString()` defined, so that it can be used in place of the type constant.
- `createSlice()`: combines `createReducer()` + `createAction()`. Accepts an object of reducer functions, a slice name, and an initial state value, and automatically generates a slice reducer with corresponding action creators and action types.
- `createListenerMiddleware()`: lets you define "listener" entries that contain an "effect" callback with additional logic, and a way to specify when that callback should run based on dispatched actions or state changes. A lightweight alternative to Redux async middleware like sagas and observables.
- `createSlice()`: combines `createReducer()` + `createAction()`. Accepts an object of reducer functions, a slice name, and an initial state value, and automatically generates a slice reducer with corresponding action creators and action types.
- `createListenerMiddleware()`: lets you define "listener" entries that contain an "effect" callback with additional logic, and a way to specify when that callback should run based on dispatched actions or state changes. A lightweight alternative to Redux async middleware like sagas and observables.
- `createAsyncThunk()`: accepts an action type string and a function that returns a promise, and generates a thunk that dispatches `pending/resolved/rejected` action types based on that promise
- `createEntityAdapter()`: generates a set of reusable reducers and selectors to manage normalized data in the store
- The `createSelector()` utility from the [Reselect](https://github.com/reduxjs/reselect) library, re-exported for ease of use.
Expand Down
25 changes: 20 additions & 5 deletions packages/toolkit/src/entities/create_adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,27 @@ import type {
Comparer,
IdSelector,
EntityAdapter,
EntityId,
} from './models'
import { createInitialStateFactory } from './entity_state'
import { createSelectorsFactory } from './state_selectors'
import { createSortedStateAdapter } from './sorted_state_adapter'
import { createUnsortedStateAdapter } from './unsorted_state_adapter'

export interface EntityAdapterOptions<T, Id extends EntityId> {
selectId?: IdSelector<T, Id>
sortComparer?: false | Comparer<T>
}

export function createEntityAdapter<T, Id extends EntityId>(options: {
selectId: IdSelector<T, Id>
sortComparer?: false | Comparer<T>
}): EntityAdapter<T, Id>

export function createEntityAdapter<T extends { id: EntityId }>(options?: {
sortComparer?: false | Comparer<T>
}): EntityAdapter<T, T['id']>

/**
*
* @param options
Expand All @@ -17,18 +32,18 @@ import { createUnsortedStateAdapter } from './unsorted_state_adapter'
*/
export function createEntityAdapter<T>(
options: {
selectId?: IdSelector<T>
selectId?: IdSelector<T, EntityId>
sortComparer?: false | Comparer<T>
} = {}
): EntityAdapter<T> {
const { selectId, sortComparer }: EntityDefinition<T> = {
): EntityAdapter<T, EntityId> {
const { selectId, sortComparer }: EntityDefinition<T, EntityId> = {
sortComparer: false,
selectId: (instance: any) => instance.id,
...options,
}

const stateFactory = createInitialStateFactory<T>()
const selectorsFactory = createSelectorsFactory<T>()
const stateFactory = createInitialStateFactory<T, EntityId>()
const selectorsFactory = createSelectorsFactory<T, EntityId>()
const stateAdapter = sortComparer
? createSortedStateAdapter(selectId, sortComparer)
: createUnsortedStateAdapter(selectId)
Expand Down
13 changes: 8 additions & 5 deletions packages/toolkit/src/entities/entity_state.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
import type { EntityState } from './models'
import type { EntityId, EntityState } from './models'

export function getInitialEntityState<V>(): EntityState<V> {
export function getInitialEntityState<T, Id extends EntityId>(): EntityState<
T,
Id
> {
return {
ids: [],
entities: {},
}
}

export function createInitialStateFactory<V>() {
function getInitialState(): EntityState<V>
export function createInitialStateFactory<T, Id extends EntityId>() {
function getInitialState(): EntityState<T, Id>
function getInitialState<S extends object>(
additionalState: S
): EntityState<V> & S
): EntityState<T, Id> & S
function getInitialState(additionalState: any = {}): any {
return Object.assign(getInitialEntityState(), additionalState)
}
Expand Down
Loading