Repository: pmndrs/zustand
File: src/middleware/devtools.ts (TypeScript)

Code before:
                  error?: boolean
                  symbol?: boolean
                  map?: boolean
                  set?: boolean
                }
          }
        }
  ) =>
  (
    set: CustomSetState,
    get: CustomGetState,
    api: CustomStoreApi &
      StoreApiWithDevtools<S> & {
        dispatch?: unknown
        dispatchFromDevtools?: boolean
      }
  ): S => {
    const devtoolsOptions =
      options === undefined
        ? { name: undefined, anonymousActionType: undefined }
        : typeof options === 'string'
        ? { name: options }
        : options

    const extensionConnector =
      typeof window !== 'undefined' &&
      ((window as any).__REDUX_DEVTOOLS_EXTENSION__ ||
        (window as any).top.__REDUX_DEVTOOLS_EXTENSION__)

    if (!extensionConnector) {
      if (
        process.env.NODE_ENV === 'development' &&
        typeof window !== 'undefined'
      ) {
        console.warn(
          '[zustand devtools middleware] Please install/enable Redux devtools extension'
        )
      }

      return fn(set, get, api)
    }

    let extension = Object.create(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) {

Review comment (suggestion):
Maybe it is also an idea to add an early return in the very beginning (line 83) of the devtools function?
`if (typeof window === 'undefined') return fn(set, get, api)`
It would also make it more obvious that the devtools are only running in a browser environment.

That way you would not have to deal with these window checks throughout the function.

Code after:
                  error?: boolean
                  symbol?: boolean
                  map?: boolean
                  set?: boolean
                }
          }
        }
  ) =>
  (
    set: CustomSetState,
    get: CustomGetState,
    api: CustomStoreApi &
      StoreApiWithDevtools<S> & {
        dispatch?: unknown
        dispatchFromDevtools?: boolean
      }
  ): S => {
    const devtoolsOptions =
      options === undefined
        ? { name: undefined, anonymousActionType: undefined }
        : typeof options === 'string'
        ? { name: options }
        : options

    if (typeof window === 'undefined') {
      return fn(set, get, api)
    }

    const extensionConnector =
      (window as any).__REDUX_DEVTOOLS_EXTENSION__ ||
      (window as any).top.__REDUX_DEVTOOLS_EXTENSION__

    if (!extensionConnector) {
      if (process.env.NODE_ENV === 'development') {
        console.warn(
          '[zustand devtools middleware] Please install/enable Redux devtools extension'
        )
      }
      return fn(set, get, api)
    }

    let extension = Object.create(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(