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

breaking(middleware/devtools): remove deprecations and warnings #892

Merged
merged 141 commits into from
Apr 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
141 commits
Select commit Hold shift + click to select a range
cf511cf
imaginary code that uses uSES
dai-shi Aug 31, 2021
5570b10
revert backward compatibility code as this is not going to be v4
dai-shi Aug 31, 2021
b03b226
use use-sync-external-store
dai-shi Sep 4, 2021
8112285
revert to react 17
dai-shi Sep 4, 2021
50f2963
handle error by our own
dai-shi Sep 4, 2021
94d9d4a
v4.0.0-alpha.2
dai-shi Sep 4, 2021
d36611b
fix&refactor a bit
dai-shi Sep 6, 2021
453e59a
Merge branch 'main' into use-sync-external-store
dai-shi Sep 14, 2021
ef89673
update uSES experimental package
dai-shi Sep 14, 2021
d61a0b7
remove error propagation hack
dai-shi Sep 14, 2021
ec117e6
update size snapshot
dai-shi Sep 14, 2021
e2081c8
update uSES and add dts
dai-shi Sep 27, 2021
1fee70e
split react.ts and no export wild
dai-shi Sep 27, 2021
9aaeb5e
split useStore impl
dai-shi Sep 27, 2021
a914052
context to follow the new api, export wild again
dai-shi Sep 27, 2021
9021456
v4.0.0-alpha.3
dai-shi Sep 27, 2021
b9a70f2
add missing await
dai-shi Sep 28, 2021
98c59d3
merge main
dai-shi Sep 28, 2021
c9c8ae9
merge main
dai-shi Oct 1, 2021
cc391bc
update uSES
dai-shi Oct 1, 2021
bef6f81
update uSES
dai-shi Oct 3, 2021
d78e91f
Merge branch 'main' into use-sync-external-store
dai-shi Oct 3, 2021
54a5b8c
uses uSES extra!
dai-shi Oct 4, 2021
66fc5a7
Merge branch 'main' into use-sync-external-store
dai-shi Oct 4, 2021
1ee93aa
v4.0.0-alpha.3
dai-shi Oct 4, 2021
c643ebf
merge main
dai-shi Oct 7, 2021
a20e4d1
merge main
dai-shi Oct 19, 2021
002d101
fix(types): Rename from UseStore to UseBoundStore
dai-shi Oct 19, 2021
674e307
breaking(types): drop deprecated UseStore type
dai-shi Oct 19, 2021
0c641fd
breaking(core): drop v2 hook compatibility
dai-shi Oct 19, 2021
0037eb3
breaking(middleware): drop deprecated persist options
dai-shi Oct 19, 2021
57d2b85
merge main
dai-shi Oct 21, 2021
56d512a
merge main
dai-shi Oct 21, 2021
9b97050
breaking(core): drop deprecated store.subscribe with selector
dai-shi Oct 21, 2021
b691632
Merge branch 'main' into breaking/core/drop-deprecated-subscribe-with…
dai-shi Oct 27, 2021
bedad91
Merge branch 'main' into breaking/middleware/drop-deprecated-persist-…
dai-shi Oct 27, 2021
263fce4
Merge branch 'main' into breaking/drop-v2-hook-compatibility
dai-shi Oct 27, 2021
916f0b8
Merge branch 'main' into breaking/types/drop-use-store
dai-shi Oct 27, 2021
3b03362
merge main
dai-shi Oct 27, 2021
24d9750
update uSES
dai-shi Oct 27, 2021
f75e868
fix update uSES
dai-shi Oct 27, 2021
2ed60eb
v4.0.0-alpha.5
dai-shi Oct 27, 2021
3bb2fef
combine subscribe type
dai-shi Oct 29, 2021
d3eec66
merge main
dai-shi Oct 30, 2021
5e062a6
Merge branch 'main' into breaking/middleware/drop-deprecated-persist-…
dai-shi Oct 30, 2021
4d00841
Merge branch 'main' into breaking/drop-v2-hook-compatibility
dai-shi Oct 30, 2021
4c80f17
Merge branch 'main' into breaking/types/drop-use-store
dai-shi Oct 30, 2021
9675378
merge main
dai-shi Oct 30, 2021
ba9d6d0
intentional undefined type
dai-shi Oct 31, 2021
8fad667
add useDebugValue
dai-shi Oct 31, 2021
7575357
update uSES
dai-shi Oct 31, 2021
e51f75a
update uSES types
dai-shi Nov 2, 2021
018f9b2
Merge branch 'main' into breaking/core/drop-deprecated-subscribe-with…
dai-shi Nov 2, 2021
9d7ea48
merge main
dai-shi Nov 2, 2021
ebf571e
Merge branch 'main' into breaking/drop-v2-hook-compatibility
dai-shi Nov 2, 2021
48684d2
Merge branch 'main' into breaking/types/drop-use-store
dai-shi Nov 2, 2021
c001de4
breaking(middleware): make persist options.removeItem required
dai-shi Nov 2, 2021
7941091
merge main
dai-shi Nov 2, 2021
e7adbbf
update uSES
dai-shi Nov 2, 2021
5812d0e
v4.0.0-alpha.6
dai-shi Nov 2, 2021
19d40a6
merge main
dai-shi Nov 4, 2021
b669f7e
Merge branch 'main' into breaking/middleware/drop-deprecated-persist-…
dai-shi Nov 4, 2021
3357bee
Merge branch 'main' into breaking/drop-v2-hook-compatibility
dai-shi Nov 4, 2021
dc0b449
Merge branch 'main' into breaking/types/drop-use-store
dai-shi Nov 4, 2021
9690a11
merge main
dai-shi Nov 4, 2021
f037a2a
fix(readme): remove memoization section which is no longer valid with…
dai-shi Nov 4, 2021
8339d52
feat(readme): add new createStore/useStore usage
dai-shi Nov 4, 2021
258e895
Merge branch 'main' into breaking/core/drop-deprecated-subscribe-with…
dai-shi Nov 9, 2021
2392f8f
Merge branch 'main' into breaking/middleware/drop-deprecated-persist-…
dai-shi Nov 9, 2021
707b37b
Merge branch 'main' into breaking/drop-v2-hook-compatibility
dai-shi Nov 9, 2021
de84ec8
Merge branch 'main' into breaking/types/drop-use-store
dai-shi Nov 9, 2021
2e5ab21
merge main
dai-shi Nov 9, 2021
37119f5
update useSES
dai-shi Nov 9, 2021
835684a
update uSES and deps
dai-shi Nov 15, 2021
20abedf
Merge branch 'main' into use-sync-external-store
dai-shi Nov 15, 2021
e91bde6
v4.0.0-alpha.7
dai-shi Nov 15, 2021
7206e1a
merge main
dai-shi Nov 16, 2021
e8f7316
merge main
dai-shi Nov 16, 2021
6372ee8
merge main
dai-shi Nov 16, 2021
b5d8665
merge main
dai-shi Nov 16, 2021
c009886
merge main
dai-shi Nov 16, 2021
e87182b
Merge branch 'main' into breaking/core/drop-deprecated-subscribe-with…
dai-shi Nov 22, 2021
50022f9
Merge branch 'main' into breaking/middleware/drop-deprecated-persist-…
dai-shi Nov 22, 2021
3c12d7d
Merge branch 'main' into breaking/drop-v2-hook-compatibility
dai-shi Nov 22, 2021
e675524
Merge branch 'main' into breaking/types/drop-use-store
dai-shi Nov 22, 2021
be18127
merge main
dai-shi Nov 22, 2021
9280262
update uSES
dai-shi Nov 22, 2021
9fb629a
Merge branch 'main' into breaking/core/drop-deprecated-subscribe-with…
dai-shi Dec 3, 2021
e9d2ca3
Merge branch 'main' into breaking/middleware/drop-deprecated-persist-…
dai-shi Dec 3, 2021
d6a4e42
Merge branch 'main' into breaking/drop-v2-hook-compatibility
dai-shi Dec 3, 2021
eddbf38
Merge branch 'main' into breaking/types/drop-use-store
dai-shi Dec 3, 2021
c6acc59
merge main
dai-shi Dec 3, 2021
303fd82
update uSES
dai-shi Dec 7, 2021
0d4e0d8
shave bytes
dai-shi Dec 7, 2021
ef5e758
Merge branch 'main' into breaking/core/drop-deprecated-subscribe-with…
dai-shi Dec 7, 2021
eb1e686
Merge branch 'main' into breaking/middleware/drop-deprecated-persist-…
dai-shi Dec 7, 2021
252fca0
Merge branch 'main' into breaking/drop-v2-hook-compatibility
dai-shi Dec 7, 2021
eee639e
Merge branch 'main' into breaking/types/drop-use-store
dai-shi Dec 7, 2021
445bc8f
Merge branch 'main' into use-sync-external-store
dai-shi Dec 7, 2021
5a6473b
Merge branch 'main' into breaking/core/drop-deprecated-subscribe-with…
dai-shi Dec 24, 2021
3ac128f
Merge branch 'main' into breaking/middleware/drop-deprecated-persist-…
dai-shi Dec 24, 2021
3818dc1
Merge branch 'main' into breaking/drop-v2-hook-compatibility
dai-shi Dec 24, 2021
e7a219d
Merge branch 'main' into breaking/types/drop-use-store
dai-shi Dec 24, 2021
dd57cb0
Merge branch 'main' into use-sync-external-store
dai-shi Dec 24, 2021
76b1d4c
update uSES
dai-shi Dec 24, 2021
c037c08
Merge branch 'main' into breaking/core/drop-deprecated-subscribe-with…
dai-shi Feb 11, 2022
bbbf857
Merge branch 'main' into breaking/drop-v2-hook-compatibility
dai-shi Feb 11, 2022
d3810d1
Merge branch 'main' into breaking/middleware/drop-deprecated-persist-…
dai-shi Feb 11, 2022
82856c5
Merge branch 'main' into breaking/types/drop-use-store
dai-shi Feb 11, 2022
90fd7ee
Merge branch 'main' into use-sync-external-store
dai-shi Feb 11, 2022
be51c33
breaking(middleware/devtools): use official devtools extension types
dai-shi Feb 22, 2022
06123b1
type object.create
dai-shi Feb 23, 2022
e9cf15e
avoid emitting @redux-devtools/extension
dai-shi Feb 23, 2022
4a30a95
fix type with any
dai-shi Feb 24, 2022
86d4f97
refactor
dai-shi Feb 24, 2022
4241357
Merge branch 'main' into breaking/middleware/devtools/use-devtools-ex…
dai-shi Feb 28, 2022
9b8fe3e
Merge branch 'main' into breaking/core/drop-deprecated-subscribe-with…
dai-shi Feb 28, 2022
5298a35
Merge branch 'main' into breaking/middleware/drop-deprecated-persist-…
dai-shi Feb 28, 2022
5ec8123
Merge branch 'main' into breaking/drop-v2-hook-compatibility
dai-shi Feb 28, 2022
37c4430
Merge branch 'main' into breaking/types/drop-use-store
dai-shi Feb 28, 2022
ff7358a
Merge branch 'main' into use-sync-external-store
dai-shi Feb 28, 2022
92a7094
fix yarn lock
dai-shi Feb 28, 2022
64536ee
temporary fix #829
dai-shi Feb 28, 2022
fede093
Merge branch 'breaking/core/drop-deprecated-subscribe-with-selector' …
dai-shi Feb 28, 2022
4be2722
Merge branch 'breaking/middleware/drop-deprecated-persist-options' in…
dai-shi Feb 28, 2022
12ab776
Merge branch 'breaking/drop-v2-hook-compatibility' into v4
dai-shi Feb 28, 2022
c79d27c
Merge branch 'breaking/types/drop-use-store' into v4
dai-shi Feb 28, 2022
d5f7fa7
Merge branch 'use-sync-external-store' into v4
dai-shi Feb 28, 2022
0c0f3a3
v4.0.0-beta.2
dai-shi Feb 28, 2022
304ee89
fix lint
dai-shi Feb 28, 2022
d4b7200
lock date-fns version
dai-shi Mar 4, 2022
129b64b
lock testing-library/react alpha version
dai-shi Mar 5, 2022
aacc55e
devtools: remove deprecations and warnings
devanshj Apr 5, 2022
a6ba038
fix tests
devanshj Apr 5, 2022
ad6ddad
use `__DEV__`
devanshj Apr 7, 2022
1fd769d
merge base ie main
devanshj Apr 7, 2022
ce12dc3
revert irrelevant v4 changes
devanshj Apr 7, 2022
a7a2a06
correct merge
dai-shi Apr 7, 2022
a04e74e
fix test
dai-shi Apr 7, 2022
6aa7b3c
fix `any`
devanshj Apr 8, 2022
f991f00
fix `any` again
devanshj Apr 8, 2022
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
153 changes: 20 additions & 133 deletions src/middleware/devtools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,7 @@ type Message = {
type Write<T extends object, U extends object> = Omit<T, keyof U> & U
type Cast<T, U> = T extends U ? T : U

type WithDevtools<S> = Write<Cast<S, object>, StoreSetStateWithAction<S>> & {
/**
* @deprecated `devtools` property on the store is deprecated
* it will be removed in the next major.
* You shouldn't interact with the extension directly. But in case you still want to
* you can patch `window.__REDUX_DEVTOOLS_EXTENSION__` directly
*/
devtools?: DevtoolsType
}
type WithDevtools<S> = Write<Cast<S, object>, StoreSetStateWithAction<S>>

type StoreSetStateWithAction<S> = S extends { getState: () => infer T }
? S & { setState: NamedSet<Cast<T, object>> }
Expand All @@ -50,23 +42,6 @@ interface DevtoolsOptions {
}
}

type DevtoolsType = {
/**
* @deprecated along with `api.devtools`, `api.devtools.prefix` is deprecated.
* We no longer prefix the actions/names, because the `name` option already
* creates a separate instance of devtools for each store.
*/
prefix: string
subscribe: (dispatch: any) => () => void
unsubscribe: () => void
send: {
(action: string | { type: unknown }, state: any): void
(action: null, liftedState: any): void
}
init: (state: any) => void
error: (payload: any) => void
}

export type NamedSet<T extends State> = {
<
K1 extends keyof T,
Expand All @@ -85,13 +60,6 @@ export type NamedSet<T extends State> = {
*/
export type StoreApiWithDevtools<T extends State> = StoreApi<T> & {
setState: NamedSet<T>
/**
* @deprecated `devtools` property on the store is deprecated
* it will be removed in the next major.
* You shouldn't interact with the extension directly. But in case you still want to
* you can patch `window.__REDUX_DEVTOOLS_EXTENSION__` directly
*/
devtools?: DevtoolsType
}

export function devtools<
Expand All @@ -104,11 +72,7 @@ export function devtools<
): (
set: CustomSetState,
get: CustomGetState,
api: CustomStoreApi &
StoreApiWithDevtools<S> & {
dispatch?: unknown
dispatchFromDevtools?: boolean
}
api: CustomStoreApi & StoreApiWithDevtools<S>
) => S
/**
* @deprecated Passing `name` as directly will be not allowed in next major.
Expand All @@ -125,11 +89,7 @@ export function devtools<
): (
set: CustomSetState,
get: CustomGetState,
api: CustomStoreApi &
StoreApiWithDevtools<S> & {
dispatch?: unknown
dispatchFromDevtools?: boolean
}
api: CustomStoreApi & StoreApiWithDevtools<S>
) => S
export function devtools<
S extends State,
Expand All @@ -142,11 +102,7 @@ export function devtools<
): (
set: CustomSetState,
get: CustomGetState,
api: CustomStoreApi &
StoreApiWithDevtools<S> & {
dispatch?: unknown
dispatchFromDevtools?: boolean
}
api: CustomStoreApi & StoreApiWithDevtools<S>
) => S
export function devtools<
S extends State,
Expand All @@ -160,20 +116,8 @@ export function devtools<
return (
set: CustomSetState,
get: CustomGetState,
api: CustomStoreApi &
StoreApiWithDevtools<S> & {
dispatch?: unknown
dispatchFromDevtools?: boolean
}
api: CustomStoreApi & StoreApiWithDevtools<S>
): S => {
let didWarnAboutNameDeprecation = false
if (typeof options === 'string' && !didWarnAboutNameDeprecation) {
console.warn(
'[zustand devtools middleware]: passing `name` as directly will be not allowed in next major' +
'pass the `name` in an object `{ name: ... }` instead'
)
didWarnAboutNameDeprecation = true
}
const devtoolsOptions =
options === undefined
? {}
Expand All @@ -197,71 +141,7 @@ export function devtools<
return fn(set, get, api)
}

let extension = (Object.create as <T>(t: T) => T)(
extensionConnector.connect(devtoolsOptions)
)
// We're using `Object.defineProperty` to set `prefix`, so if extensionConnector.connect
// returns the same reference we'd get cannot redefine property prefix error
// hence we `Object.create` to make a new reference

let didWarnAboutDevtools = false
Object.defineProperty(api, 'devtools', {
get: () => {
if (!didWarnAboutDevtools) {
console.warn(
'[zustand devtools middleware] `devtools` property on the store is deprecated ' +
'it will be removed in the next major.\n' +
"You shouldn't interact with the extension directly. But in case you still want to " +
'you can patch `window.__REDUX_DEVTOOLS_EXTENSION__` directly'
)
didWarnAboutDevtools = true
}
return extension
},
set: (value) => {
if (!didWarnAboutDevtools) {
console.warn(
'[zustand devtools middleware] `api.devtools` is deprecated, ' +
'it will be removed in the next major.\n' +
"You shouldn't interact with the extension directly. But in case you still want to " +
'you can patch `window.__REDUX_DEVTOOLS_EXTENSION__` directly'
)
didWarnAboutDevtools = true
}
extension = value
},
})

let didWarnAboutPrefix = false
Object.defineProperty(extension, 'prefix', {
get: () => {
if (!didWarnAboutPrefix) {
console.warn(
'[zustand devtools middleware] along with `api.devtools`, `api.devtools.prefix` is deprecated.\n' +
'We no longer prefix the actions/names' +
devtoolsOptions.name ===
undefined
? ', pass the `name` option to create a separate instance of devtools for each store.'
: ', because the `name` option already creates a separate instance of devtools for each store.'
)
didWarnAboutPrefix = true
}
return ''
},
set: () => {
if (!didWarnAboutPrefix) {
console.warn(
'[zustand devtools middleware] along with `api.devtools`, `api.devtools.prefix` is deprecated.\n' +
'We no longer prefix the actions/names' +
devtoolsOptions.name ===
undefined
? ', pass the `name` option to create a separate instance of devtools for each store.'
: ', because the `name` option already creates a separate instance of devtools for each store.'
)
didWarnAboutPrefix = true
}
},
})
const extension = extensionConnector.connect(devtoolsOptions)

let isRecording = true
;(api.setState as NamedSet<S>) = (state, replace, nameOrAction) => {
Expand All @@ -286,11 +166,18 @@ export function devtools<
const initialState = fn(api.setState, get, api)
extension.init(initialState)

if (api.dispatchFromDevtools && typeof api.dispatch === 'function') {
if (
(api as any).dispatchFromDevtools &&
typeof (api as any).dispatch === 'function'
) {
let didWarnAboutReservedActionType = false
const originalDispatch = api.dispatch
api.dispatch = (...a: any[]) => {
if (a[0].type === '__setState' && !didWarnAboutReservedActionType) {
const originalDispatch = (api as any).dispatch
;(api as any).dispatch = (...a: any[]) => {
if (
__DEV__ &&
a[0].type === '__setState' &&
!didWarnAboutReservedActionType
) {
console.warn(
'[zustand devtools middleware] "__setState" action type is reserved ' +
'to set state from the devtools. Avoid using it.'
Expand Down Expand Up @@ -325,9 +212,9 @@ export function devtools<
return
}

if (!api.dispatchFromDevtools) return
if (typeof api.dispatch !== 'function') return
;(api.dispatch as any)(action)
if (!(api as any).dispatchFromDevtools) return
if (typeof (api as any).dispatch !== 'function') return
;(api as any).dispatch(action)
}
)

Expand Down
89 changes: 49 additions & 40 deletions tests/devtools.test.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { devtools, redux } from 'zustand/middleware'
import create from 'zustand/vanilla'
import create, { StoreApi } from 'zustand/vanilla'

let extensionSubscriber: ((message: any) => void) | undefined
const extension = {
Expand Down Expand Up @@ -125,7 +125,7 @@ describe('when it receives an message of type...', () => {
it('does nothing even if there is `api.dispatch`', () => {
const initialState = { count: 0 }
const api = create(devtools(() => initialState))
api.dispatch = jest.fn()
;(api as any).dispatch = jest.fn()
const setState = jest.spyOn(api, 'setState')

;(extensionSubscriber as (message: any) => void)({
Expand All @@ -135,14 +135,14 @@ describe('when it receives an message of type...', () => {

expect(api.getState()).toBe(initialState)
expect(setState).not.toBeCalled()
expect(api.dispatch).not.toBeCalled()
expect((api as any).dispatch).not.toBeCalled()
})

it('dispatches with `api.dispatch` when `api.dispatchFromDevtools` is set to true', () => {
const initialState = { count: 0 }
const api = create(devtools(() => initialState))
api.dispatch = jest.fn()
api.dispatchFromDevtools = true
;(api as any).dispatch = jest.fn()
;(api as any).dispatchFromDevtools = true
const setState = jest.spyOn(api, 'setState')

;(extensionSubscriber as (message: any) => void)({
Expand All @@ -152,14 +152,16 @@ describe('when it receives an message of type...', () => {

expect(api.getState()).toBe(initialState)
expect(setState).not.toBeCalled()
expect(api.dispatch).toHaveBeenLastCalledWith({ type: 'INCREMENT' })
expect((api as any).dispatch).toHaveBeenLastCalledWith({
type: 'INCREMENT',
})
})

it('does not throw for unsupported payload', () => {
const initialState = { count: 0 }
const api = create(devtools(() => initialState))
api.dispatch = jest.fn()
api.dispatchFromDevtools = true
;(api as any).dispatch = jest.fn()
;(api as any).dispatchFromDevtools = true
const setState = jest.spyOn(api, 'setState')
const originalConsoleError = console.error
console.error = jest.fn()
Expand Down Expand Up @@ -195,7 +197,7 @@ describe('when it receives an message of type...', () => {

expect(api.getState()).toBe(initialState)
expect(setState).not.toBeCalled()
expect(api.dispatch).not.toBeCalled()
expect((api as any).dispatch).not.toBeCalled()

console.error = originalConsoleError
})
Expand Down Expand Up @@ -436,43 +438,50 @@ describe('when it receives an message of type...', () => {
})
})

it('works with redux middleware', () => {
const api = create(
devtools(
redux(
({ count }, { type }: { type: 'INCREMENT' | 'DECREMENT' }) => ({
count: count + (type === 'INCREMENT' ? 1 : -1),
}),
{ count: 0 }
describe('with redux middleware', () => {
let api: StoreApi<{ count: number }>

it('works as expected', () => {
api = create(
devtools(
redux(
(
{ count },
{ type }: { type: 'INCREMENT' } | { type: 'DECREMENT' }
) => ({
count: count + (type === 'INCREMENT' ? 1 : -1),
}),
{ count: 0 }
)
)
)
)
;(api as any).dispatch({ type: 'INCREMENT' })
;(api as any).dispatch({ type: 'INCREMENT' })
;(extensionSubscriber as (message: any) => void)({
type: 'ACTION',
payload: JSON.stringify({ type: 'DECREMENT' }),
})

api.dispatch({ type: 'INCREMENT' })
api.dispatch({ type: 'INCREMENT' })
;(extensionSubscriber as (message: any) => void)({
type: 'ACTION',
payload: JSON.stringify({ type: 'DECREMENT' }),
expect(extension.init.mock.calls).toMatchObject([[{ count: 0 }]])
expect(extension.send.mock.calls).toMatchObject([
[{ type: 'INCREMENT' }, { count: 1 }],
[{ type: 'INCREMENT' }, { count: 2 }],
[{ type: 'DECREMENT' }, { count: 1 }],
])
expect(api.getState()).toMatchObject({ count: 1 })
})

expect(extension.init.mock.calls).toMatchObject([[{ count: 0 }]])
expect(extension.send.mock.calls).toMatchObject([
[{ type: 'INCREMENT' }, { count: 1 }],
[{ type: 'INCREMENT' }, { count: 2 }],
[{ type: 'DECREMENT' }, { count: 1 }],
])
expect(api.getState()).toMatchObject({ count: 1 })

const originalConsoleWarn = console.warn
console.warn = jest.fn()

api.dispatch({ type: '__setState' as any })
expect(console.warn).toHaveBeenLastCalledWith(
'[zustand devtools middleware] "__setState" action type is reserved ' +
'to set state from the devtools. Avoid using it.'
)
it('[DEV-ONLY] warns about misusage', () => {
const originalConsoleWarn = console.warn
console.warn = jest.fn()
;(api as any).dispatch({ type: '__setState' as any })
expect(console.warn).toHaveBeenLastCalledWith(
'[zustand devtools middleware] "__setState" action type is reserved ' +
'to set state from the devtools. Avoid using it.'
)

console.warn = originalConsoleWarn
console.warn = originalConsoleWarn
})
})

it('works in non-browser env', () => {
Expand Down