1"use strict";(self.webpackChunkrdc_website=self.webpackChunkrdc_website||[]).push([[2636],{94899(e,n,t){t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>i,default:()=>h,frontMatter:()=>a,metadata:()=>r,toc:()=>c});const r=JSON.parse('{"id":"api/DevToolsManager","title":"DevToolsManager","description":"Integrates with Redux DevTools to track","source":"@site/../docs/.core-vue/api/DevToolsManager.md","sourceDirName":"api","slug":"/api/DevToolsManager","permalink":"/vue/api/DevToolsManager","draft":false,"unlisted":false,"editUrl":"https://github.com/reactive/data-client/edit/master/docs/core/api/DevToolsManager.md","tags":[],"version":"current","frontMatter":{"title":"DevToolsManager","sidebar_label":"DevToolsManager"},"sidebar":"api","previous":{"title":"PollingSubscription","permalink":"/vue/api/PollingSubscription"},"next":{"title":"LogoutManager","permalink":"/vue/api/LogoutManager"}}');var o=t(62540),s=t(43023);const a={title:"DevToolsManager",sidebar_label:"DevToolsManager"},i=void 0,l={},c=[{value:"constructor(options?, skipLogging?)",id:"constructoroptions-skiplogging",level:2},{value:"options",id:"options",level:3},{value:"skipLogging",id:"skiplogging",level:3},{value:"Skipping high-frequency updates",id:"skipping-high-frequency-updates",level:4},{value:"Programmatic store access",id:"controllers",level:2},{value:"More info",id:"more-info",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h2:"h2",h3:"h3",h4:"h4",p:"p",pre:"pre",...(0,s.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-typescript",children:"class DevToolsManager implements Manager\n"})}),"\n",(0,o.jsxs)(n.p,{children:["Integrates with ",(0,o.jsx)(n.a,{href:"https://github.com/reduxjs/redux-devtools",children:"Redux DevTools"})," to track\nstate and ",(0,o.jsx)(n.a,{href:"/vue/api/Actions",children:"actions"}),". Note: does not integrate time-travel."]}),"\n",(0,o.jsxs)(n.p,{children:["Add the ",(0,o.jsx)(n.a,{href:"https://chrome.google.com/webstore/detail/redux-devtools/lmhkpmbekcpmknklioeibfkpmmfibljd?hl=en",children:"chrome extension"}),"\nor ",(0,o.jsx)(n.a,{href:"https://addons.mozilla.org/en-US/firefox/addon/reduxdevtools/",children:"firefox extension"})," to your\nbrowser to get started."]}),"\n",(0,o.jsx)(n.admonition,{title:"implements",type:"info",children:(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.code,{children:"DevToolsManager"})," implements ",(0,o.jsx)(n.a,{href:"/vue/api/Manager",children:"Manager"})]})}),"\n",(0,o.jsx)(n.h2,{id:"constructoroptions-skiplogging",children:"constructor(options?, skipLogging?)"}),"\n",(0,o.jsx)(n.h3,{id:"options",children:"options"}),"\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.a,{href:"https://github.com/reduxjs/redux-devtools/blob/main/extension/docs/API/Arguments.md",children:"Arguments"}),"\nto send to redux devtools."]}),"\n",(0,o.jsxs)(n.p,{children:["For example, we can enable the ",(0,o.jsx)(n.a,{href:"https://github.com/reduxjs/redux-devtools/blob/main/extension/docs/API/Arguments.md#trace",children:"trace"})," option to help track down where actions are dispatched from."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-tsx",metastring:'title="index.tsx"',children:"import { DataProvider, getDefaultManagers } from '@data-client/react';\nimport { createRoot } from 'react-dom/client';\n\nconst managers = getDefaultManagers({\n // highlight-next-line\n devToolsManager: { trace: true },\n});\n\ncreateRoot(document.body).render(\n <DataProvider managers={managers}>\n <App />\n </DataProvider>,\n);\n"})}),"\n",(0,o.jsx)(n.h3,{id:"skiplogging",children:"skipLogging"}),"\n",(0,o.jsx)(n.p,{children:(0,o.jsx)(n.code,{children:"(action: ActionTypes) => boolean"})}),"\n",(0,o.jsx)(n.p,{children:"Can skip some actions to be registered in the browser devtool."}),"\n",(0,o.jsxs)(n.p,{children:["By default will skip inflight ",(0,o.jsx)(n.a,{href:"/vue/api/Controller#fetch",children:"fetch actions"})]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-tsx",metastring:'title="index.tsx"',children:"import {\n DevToolsManager,\n DataProvider,\n getDefaultManagers,\n} from '@data-client/react';\nimport { createRoot } from 'react-dom/client';\n\nconst managers =\n process.env.NODE_ENV !== 'production'\n ? [\n // highlight-start\n new DevToolsManager(undefined, () => true),\n // highlight-end\n ...getDefaultManagers().filter(\n manager => manager.constructor.name !== 'DevToolsManager',\n ),\n ]\n : getDefaultManagers();\n\ncreateRoot(document.body).render(\n <DataProvider managers={managers}>\n <App />\n </DataProvider>,\n);\n"})}),"\n",(0,o.jsx)(n.h4,{id:"skipping-high-frequency-updates",children:"Skipping high-frequency updates"}),"\n",(0,o.jsxs)(n.p,{children:["When using ",(0,o.jsx)(n.a,{href:"/vue/concepts/managers#data-stream",children:"WebSockets"})," or other real-time data sources,\nhigh-frequency updates can overwhelm the DevTools extension. Use the ",(0,o.jsx)(n.code,{children:"predicate"})," option to\nfilter out specific action types or schemas:"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-tsx",metastring:'title="index.tsx"',children:"import { getDefaultManagers, actionTypes } from '@data-client/react';\nimport { Ticker } from './resources/Ticker';\n\nconst managers = getDefaultManagers({\n devToolsManager: {\n // Increase latency buffer for high-frequency updates\n latency: 1000,\n // Skip WebSocket SET actions for Ticker to reduce log spam\n // (including batched set([Ticker], rows) writes)\n // highlight-start\n predicate: (state, action) =>\n action.type !== actionTypes.SET ||\n (action.schema !== Ticker && action.schema[0] !== Ticker),\n // highlight-end\n },\n});\n"})}),"\n",(0,o.jsx)(n.h2,{id:"controllers",children:"Programmatic store access"}),"\n",(0,o.jsxs)(n.p,{children:["In development mode, ",(0,o.jsx)(n.code,{children:"DevToolsManager"})," registers each ",(0,o.jsx)(n.a,{href:"/vue/api/Controller",children:"Controller"})," on\n",(0,o.jsx)(n.code,{children:"globalThis.__DC_CONTROLLERS__"})," \u2014 a ",(0,o.jsx)(n.code,{children:"Map"})," keyed by the devtools connection name. This works\nin browsers, React Native, and Node."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-js",metastring:'title="Browser DevTools console"',children:"// List all registered providers\n__DC_CONTROLLERS__.keys();\n\n// Get state from the first provider\n__DC_CONTROLLERS__.values().next().value.getState();\n\n// Get state by name\n__DC_CONTROLLERS__.get('Data Client: My App').getState();\n"})}),"\n",(0,o.jsxs)(n.p,{children:["This is useful for AI coding assistants using the ",(0,o.jsx)(n.a,{href:"https://developer.chrome.com/blog/chrome-devtools-mcp",children:"Chrome DevTools MCP"}),"\nor ",(0,o.jsx)(n.a,{href:"https://docs.expo.dev/eas/ai/mcp/",children:"Expo MCP"})," to programmatically inspect and interact\nwith the store. Each ","installed DataClientPlugin"," registers independently, so\nmultiple ","apps"," on the same page are fully supported."]}),"\n",(0,o.jsxs)(n.p,{children:["Controllers are removed from the map when ",(0,o.jsx)(n.code,{children:"cleanup()"})," is called."]}),"\n",(0,o.jsx)(n.h2,{id:"more-info",children:"More info"}),"\n",(0,o.jsxs)(n.p,{children:["Using this Manager allows in browser ",(0,o.jsx)(n.a,{href:"/vue/getting-started/debugging",children:"debugging and store inspection"}),"."]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.