Skip to content

Commit 758f115

Browse files
authored
Merge branch 'main' into test/vanilla-basic-add-getInitialState
2 parents aa6989d + 670b60e commit 758f115

File tree

3 files changed

+48
-3
lines changed

3 files changed

+48
-3
lines changed

docs/middlewares/devtools.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,8 @@ devtools<T>(stateCreatorFn: StateCreator<T, [], []>, devtoolsOptions?: DevtoolsO
5858
- **optional** `enabled`: Defaults to `true` when is on development mode, and defaults to `false`
5959
when is on production mode. Enables or disables the Redux DevTools integration
6060
for this store.
61-
- **optional** `anonymousActionType`: Defaults to `anonymous`. A string to use as the action type
62-
for anonymous mutations in the Redux DevTools.
61+
- **optional** `anonymousActionType`: Defaults to the inferred action type or `anonymous` if
62+
unavailable. A string to use as the action type for anonymous mutations in the Redux DevTools.
6363
- **optional** `store`: A custom identifier for the store in the Redux DevTools.
6464

6565
#### Returns

src/middleware/devtools.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type {} from '@redux-devtools/extension'
2+
23
import type {
34
StateCreator,
45
StoreApi,
@@ -112,6 +113,7 @@ type ConnectionInformation = {
112113
connection: Connection
113114
stores: Record<StoreName, StoreInformation>
114115
}
116+
115117
const trackedConnections: Map<ConnectionName, ConnectionInformation> = new Map()
116118

117119
const getTrackedConnectionState = (
@@ -162,6 +164,17 @@ const removeStoreFromTrackedConnections = (
162164
}
163165
}
164166

167+
const findCallerName = (stack: string | undefined) => {
168+
if (!stack) return undefined
169+
const traceLines = stack.split('\n')
170+
const apiSetStateLineIndex = traceLines.findIndex((traceLine) =>
171+
traceLine.includes('api.setState'),
172+
)
173+
if (apiSetStateLineIndex < 0) return undefined
174+
const callerLine = traceLines[apiSetStateLineIndex + 1]?.trim() || ''
175+
return /.+ (.+) .+/.exec(callerLine)?.[1]
176+
}
177+
165178
const devtoolsImpl: DevtoolsImpl =
166179
(fn, devtoolsOptions = {}) =>
167180
(set, get, api) => {
@@ -194,9 +207,10 @@ const devtoolsImpl: DevtoolsImpl =
194207
;(api.setState as any) = ((state, replace, nameOrAction: Action) => {
195208
const r = set(state, replace as any)
196209
if (!isRecording) return r
210+
const inferredActionType = findCallerName(new Error().stack)
197211
const action: { type: string } =
198212
nameOrAction === undefined
199-
? { type: anonymousActionType || 'anonymous' }
213+
? { type: anonymousActionType || inferredActionType || 'anonymous' }
200214
: typeof nameOrAction === 'string'
201215
? { type: nameOrAction }
202216
: nameOrAction

tests/devtools.test.tsx

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,37 @@ describe('When state changes...', () => {
193193
})
194194
})
195195

196+
describe('When state changes with automatic setter inferring...', () => {
197+
it("sends { type: setStateName || 'setCount`, ...rest } as the action with current state", async () => {
198+
const options = {
199+
name: 'testOptionsName',
200+
enabled: true,
201+
}
202+
203+
const api = createStore<{
204+
count: number
205+
setCount: (count: number) => void
206+
}>()(
207+
devtools(
208+
(set) => ({
209+
count: 0,
210+
setCount: (newCount: number) => {
211+
set({ count: newCount })
212+
},
213+
}),
214+
options,
215+
),
216+
)
217+
218+
api.getState().setCount(10)
219+
const [connection] = getNamedConnectionApis(options.name)
220+
expect(connection.send).toHaveBeenLastCalledWith(
221+
{ type: 'Object.setCount' },
222+
{ count: 10, setCount: expect.any(Function) },
223+
)
224+
})
225+
})
226+
196227
describe('when it receives a message of type...', () => {
197228
describe('ACTION...', () => {
198229
it('does nothing', async () => {

0 commit comments

Comments
 (0)