Skip to content

feat(core): Expose __DC_CONTROLLERS__ for programmatic store access via MCP#3753

Merged
ntucker merged 4 commits intomasterfrom
devtools
Mar 31, 2026
Merged

feat(core): Expose __DC_CONTROLLERS__ for programmatic store access via MCP#3753
ntucker merged 4 commits intomasterfrom
devtools

Conversation

@ntucker
Copy link
Copy Markdown
Collaborator

@ntucker ntucker commented Mar 1, 2026

Motivation

AI coding assistants using Chrome DevTools MCP or Expo MCP have no programmatic way to inspect or interact with the data-client store. The Redux DevTools Extension integration is one-way (app → extension) with no API to read state back from page context via evaluate_script.

Solution

DevToolsManager now registers each Controller on globalThis.__DC_CONTROLLERS__ (a Map keyed by the devtools connection name) during init() in dev mode.

  • Browser: Chrome DevTools MCP can call __DC_CONTROLLERS__.values().next().value.getState() via evaluate_script
  • React Native: Uses globalThis instead of window, so it works with Hermes debugger and Expo MCP
  • Multiple providers: Each DataProvider registers independently by name
  • Cleanup: Controllers are removed from the map in cleanup() with an identity check to prevent one provider's unmount from removing another's entry
  • Same trust boundary: Fully gated behind process.env.NODE_ENV !== 'production', matching the existing Redux DevTools integration

Code changes

  • DevToolsManager.init() registers this.controller into globalThis.__DC_CONTROLLERS__ Map
  • DevToolsManager.cleanup() removes the entry only if the current controller owns it (map.get(name) === this.controller)
  • Middleware now assigns this.controller before the early return when devTools is unavailable, so the controller is always available on the instance for __DC_CONTROLLERS__
  • New devtoolsName public property exposes the computed connection name

Docs & tooling

  • DevToolsManager docs: new "Programmatic store access" section with console examples
  • Cursor skill: devtools-debugging.md reference for React — full guide for agents to inspect normalized store state, track actions, and invoke Controller methods via Chrome DevTools MCP evaluate_script
  • Blog and playground type definitions updated

@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Mar 1, 2026

🦋 Changeset detected

Latest commit: 60001df

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 7 packages
Name Type
@data-client/core Patch
@data-client/react Patch
@data-client/vue Patch
example-benchmark Patch
example-benchmark-react Patch
test-bundlesize Patch
coinbase-lite Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 1, 2026

Size Change: +58 B (+0.07%)

Total Size: 80.9 kB

📦 View Changed
Filename Size Change
examples/test-bundlesize/dist/rdcClient.js 10.4 kB +58 B (+0.56%)
ℹ️ View Unchanged
Filename Size
examples/test-bundlesize/dist/App.js 3.44 kB
examples/test-bundlesize/dist/polyfill.js 307 B
examples/test-bundlesize/dist/rdcEndpoint.js 6.35 kB
examples/test-bundlesize/dist/react.js 59.7 kB
examples/test-bundlesize/dist/webpack-runtime.js 726 B

compressed-size-action

@codecov
Copy link
Copy Markdown

codecov bot commented Mar 1, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.08%. Comparing base (57381bf) to head (60001df).
⚠️ Report is 2 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff           @@
##           master    #3753   +/-   ##
=======================================
  Coverage   98.08%   98.08%           
=======================================
  Files         152      152           
  Lines        2871     2871           
  Branches      563      563           
=======================================
  Hits         2816     2816           
  Misses         11       11           
  Partials       44       44           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Copy Markdown
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmark

Details
Benchmark suite Current: 60001df Previous: 63633c7 Ratio
normalizeLong 462 ops/sec (±1.20%) 458 ops/sec (±0.78%) 0.99
normalizeLong Values 415 ops/sec (±0.21%) 415 ops/sec (±0.22%) 1
denormalizeLong 291 ops/sec (±2.43%) 293 ops/sec (±2.50%) 1.01
denormalizeLong Values 257 ops/sec (±2.44%) 268 ops/sec (±2.26%) 1.04
denormalizeLong donotcache 1102 ops/sec (±0.13%) 1015 ops/sec (±0.17%) 0.92
denormalizeLong Values donotcache 785 ops/sec (±0.16%) 756 ops/sec (±0.30%) 0.96
denormalizeShort donotcache 500x 1504 ops/sec (±0.12%) 1574 ops/sec (±0.12%) 1.05
denormalizeShort 500x 778 ops/sec (±2.16%) 856 ops/sec (±2.01%) 1.10
denormalizeShort 500x withCache 6477 ops/sec (±0.13%) 6157 ops/sec (±0.08%) 0.95
queryShort 500x withCache 2823 ops/sec (±0.06%) 2744 ops/sec (±0.10%) 0.97
buildQueryKey All 47065 ops/sec (±0.30%) 52794 ops/sec (±0.35%) 1.12
query All withCache 6473 ops/sec (±0.19%) 5877 ops/sec (±0.17%) 0.91
denormalizeLong with mixin Entity 270 ops/sec (±2.12%) 277 ops/sec (±1.96%) 1.03
denormalizeLong withCache 5878 ops/sec (±0.12%) 6938 ops/sec (±0.16%) 1.18
denormalizeLong Values withCache 6280 ops/sec (±0.20%) 5095 ops/sec (±0.27%) 0.81
denormalizeLong All withCache 6104 ops/sec (±0.10%) 5780 ops/sec (±0.11%) 0.95
denormalizeLong Query-sorted withCache 6497 ops/sec (±0.13%) 6033 ops/sec (±0.08%) 0.93
denormalizeLongAndShort withEntityCacheOnly 1514 ops/sec (±0.12%) 1680 ops/sec (±0.21%) 1.11
denormalize bidirectional 50 5565 ops/sec (±1.86%) 5948 ops/sec (±1.81%) 1.07
denormalize bidirectional 50 donotcache 44049 ops/sec (±0.77%) 41837 ops/sec (±0.60%) 0.95
getResponse 5742 ops/sec (±1.29%) 4693 ops/sec (±0.52%) 0.82
getResponse (null) 10714408 ops/sec (±0.56%) 9672457 ops/sec (±1.06%) 0.90
getResponse (clear cache) 264 ops/sec (±2.08%) 269 ops/sec (±1.97%) 1.02
getSmallResponse 3697 ops/sec (±0.35%) 3353 ops/sec (±0.12%) 0.91
getSmallInferredResponse 2518 ops/sec (±0.13%) 2505 ops/sec (±0.10%) 0.99
getResponse Collection 5508 ops/sec (±1.12%) 4587 ops/sec (±0.16%) 0.83
get Collection 5358 ops/sec (±0.30%) 4615 ops/sec (±0.25%) 0.86
get Query-sorted 6544 ops/sec (±0.32%) 5247 ops/sec (±0.26%) 0.80
setLong 465 ops/sec (±0.20%) 464 ops/sec (±0.20%) 1.00
setLongWithMerge 258 ops/sec (±0.20%) 260 ops/sec (±0.18%) 1.01
setLongWithSimpleMerge 274 ops/sec (±0.12%) 273 ops/sec (±0.12%) 1.00
setSmallResponse 500x 902 ops/sec (±0.05%) 943 ops/sec (±0.70%) 1.05

This comment was automatically generated by workflow using github-action-benchmark.

@ntucker ntucker force-pushed the devtools branch 3 times, most recently from 55b9fca to db5b610 Compare March 2, 2026 13:25
Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

@vercel
Copy link
Copy Markdown

vercel bot commented Mar 31, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
docs-site Ready Ready Preview, Comment Mar 31, 2026 1:10pm

Copy link
Copy Markdown
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmark React

Details
Benchmark suite Current: 60001df Previous: 63633c7 Ratio
data-client: getlist-100 185.19 ops/s (± 5.2%) 169.49 ops/s (± 4.1%) 0.92
data-client: getlist-500 48.31 ops/s (± 4.8%) 43.48 ops/s (± 6.5%) 0.90
data-client: update-entity 454.55 ops/s (± 5.0%) 384.62 ops/s (± 5.7%) 0.85
data-client: update-user 488.1 ops/s (± 3.8%) 400 ops/s (± 6.6%) 0.82
data-client: getlist-500-sorted 51.15 ops/s (± 6.4%) 51.29 ops/s (± 5.4%) 1.00
data-client: update-entity-sorted 416.67 ops/s (± 0.0%) 350.99 ops/s (± 5.7%) 0.84
data-client: update-entity-multi-view 370.37 ops/s (± 7.6%) 357.14 ops/s (± 4.1%) 0.96
data-client: list-detail-switch-10 11.04 ops/s (± 4.7%) 11.85 ops/s (± 9.0%) 1.07
data-client: update-user-10000 111.12 ops/s (± 2.6%) 93.46 ops/s (± 5.0%) 0.84
data-client: invalidate-and-resolve 51.95 ops/s (± 5.6%) 47.96 ops/s (± 3.9%) 0.92
data-client: unshift-item 333.33 ops/s (± 4.1%) 270.27 ops/s (± 4.2%) 0.81
data-client: delete-item 384.62 ops/s (± 7.3%) 350.99 ops/s (± 4.3%) 0.91
data-client: move-item 250 ops/s (± 4.8%) 202.04 ops/s (± 7.3%) 0.81

This comment was automatically generated by workflow using github-action-benchmark.

When multiple DataProviders use the default DevToolsManager (same
devtoolsName), cleanup() unconditionally deleted the __DC_CONTROLLERS__
map entry by name. If Provider A unmounts first, it would remove
Provider B's still-active controller from the map.

Add an identity check (map.get(name) === this.controller) before
deleting so only the instance that currently owns the entry removes it.

Co-authored-by: Nathaniel Tucker <me@ntucker.me>
@ntucker ntucker merged commit e54c9b6 into master Mar 31, 2026
28 checks passed
@ntucker ntucker deleted the devtools branch March 31, 2026 13:16
@github-actions github-actions bot mentioned this pull request Mar 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants