mirror of
https://github.com/pmndrs/zustand.git
synced 2025-12-08 19:45:52 +00:00
feat(devtool): inferred action type (#2987)
* feat(devtools middleware) add automatic action name finding * docs(readme) add inferActionName example * feat: update readmes * feat: update devtools middleware and tests * feat: remove inferActionName --------- Co-authored-by: Daishi Kato <dai-shi@users.noreply.github.com> Co-authored-by: Danilo Britto <dbritto.dev@gmail.com>
This commit is contained in:
parent
6953c29dc5
commit
670b60e19a
@ -58,8 +58,8 @@ devtools<T>(stateCreatorFn: StateCreator<T, [], []>, devtoolsOptions?: DevtoolsO
|
||||
- **optional** `enabled`: Defaults to `true` when is on development mode, and defaults to `false`
|
||||
when is on production mode. Enables or disables the Redux DevTools integration
|
||||
for this store.
|
||||
- **optional** `anonymousActionType`: Defaults to `anonymous`. A string to use as the action type
|
||||
for anonymous mutations in the Redux DevTools.
|
||||
- **optional** `anonymousActionType`: Defaults to the inferred action type or `anonymous` if
|
||||
unavailable. A string to use as the action type for anonymous mutations in the Redux DevTools.
|
||||
- **optional** `store`: A custom identifier for the store in the Redux DevTools.
|
||||
|
||||
#### Returns
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import type {} from '@redux-devtools/extension'
|
||||
|
||||
import type {
|
||||
StateCreator,
|
||||
StoreApi,
|
||||
@ -112,6 +113,7 @@ type ConnectionInformation = {
|
||||
connection: Connection
|
||||
stores: Record<StoreName, StoreInformation>
|
||||
}
|
||||
|
||||
const trackedConnections: Map<ConnectionName, ConnectionInformation> = new Map()
|
||||
|
||||
const getTrackedConnectionState = (
|
||||
@ -162,6 +164,17 @@ const removeStoreFromTrackedConnections = (
|
||||
}
|
||||
}
|
||||
|
||||
const findCallerName = (stack: string | undefined) => {
|
||||
if (!stack) return undefined
|
||||
const traceLines = stack.split('\n')
|
||||
const apiSetStateLineIndex = traceLines.findIndex((traceLine) =>
|
||||
traceLine.includes('api.setState'),
|
||||
)
|
||||
if (apiSetStateLineIndex < 0) return undefined
|
||||
const callerLine = traceLines[apiSetStateLineIndex + 1]?.trim() || ''
|
||||
return /.+ (.+) .+/.exec(callerLine)?.[1]
|
||||
}
|
||||
|
||||
const devtoolsImpl: DevtoolsImpl =
|
||||
(fn, devtoolsOptions = {}) =>
|
||||
(set, get, api) => {
|
||||
@ -194,9 +207,10 @@ const devtoolsImpl: DevtoolsImpl =
|
||||
;(api.setState as any) = ((state, replace, nameOrAction: Action) => {
|
||||
const r = set(state, replace as any)
|
||||
if (!isRecording) return r
|
||||
const inferredActionType = findCallerName(new Error().stack)
|
||||
const action: { type: string } =
|
||||
nameOrAction === undefined
|
||||
? { type: anonymousActionType || 'anonymous' }
|
||||
? { type: anonymousActionType || inferredActionType || 'anonymous' }
|
||||
: typeof nameOrAction === 'string'
|
||||
? { type: nameOrAction }
|
||||
: nameOrAction
|
||||
|
||||
@ -193,6 +193,37 @@ describe('When state changes...', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('When state changes with automatic setter inferring...', () => {
|
||||
it("sends { type: setStateName || 'setCount`, ...rest } as the action with current state", async () => {
|
||||
const options = {
|
||||
name: 'testOptionsName',
|
||||
enabled: true,
|
||||
}
|
||||
|
||||
const api = createStore<{
|
||||
count: number
|
||||
setCount: (count: number) => void
|
||||
}>()(
|
||||
devtools(
|
||||
(set) => ({
|
||||
count: 0,
|
||||
setCount: (newCount: number) => {
|
||||
set({ count: newCount })
|
||||
},
|
||||
}),
|
||||
options,
|
||||
),
|
||||
)
|
||||
|
||||
api.getState().setCount(10)
|
||||
const [connection] = getNamedConnectionApis(options.name)
|
||||
expect(connection.send).toHaveBeenLastCalledWith(
|
||||
{ type: 'Object.setCount' },
|
||||
{ count: 10, setCount: expect.any(Function) },
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('when it receives a message of type...', () => {
|
||||
describe('ACTION...', () => {
|
||||
it('does nothing', async () => {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user