Skip to content

docs: Vue examples for Controller and manager API pages - #4117

Merged
ntucker merged 15 commits into
masterfrom
claude/project-thread-gj9jkx
Oct 5, 2026
Merged

ntucker merged 15 commits into
masterfrom
claude/project-thread-gj9jkx

Conversation

@ntucker

@ntucker ntucker commented Oct 3, 2026 •

Copy link
Copy Markdown
Collaborator

Requested by Nathaniel · project thread

Motivation

/docs/vue/api/Controller and the shared manager pages still showed React components, useEffect, DataProvider and @data-client/react imports to Vue readers.

Solution

Uses the :::react / :::vue blocks from #4105/#4113. React examples are unchanged apart from small fixes; each gets a Vue sibling.

  • Controller.md: Vue <script setup> versions for fetch (Create/Update/Delete), expireAll, invalidate, invalidateAll, the LogoutManager setup, resetEntireStore, setResponse (onMounted/onUnmounted), subscribe (watchEffect), get/getResponse (event handlers with getState()) and getState. The Vue getState example checks expiryStatus in a handler and notes that mutations resolve before the store is updated. Reactive args go through computed(() => ({ ... })).
  • LogoutManager, Manager, DevToolsManager, PollingSubscription, mockInitialState: the React platform tabs / DataProvider setup moves behind :::react, and Vue gets a main.ts with app.use(DataClientPlugin, { managers }). Manager.md's prose is now framework-aware, and its editor examples import from @data-client/core.
<!-- Vue: Controller.invalidate -->
<script setup lang="ts">
  const props = defineProps<{ id: string }>();
  const ctrl = useController();
  const article = await useSuspense(
    ArticleResource.get,
    computed(() => ({ id: props.id })),
  );
</script>

<template>
  <h1>{{ article.title }}</h1>
  <button @click="ctrl.invalidate(ArticleResource.get, { id })">Fetch &amp; suspend</button>
</template>

Fixes I made to the React examples while I was there: unclosed <h1> tags, the useCallback deps in the Delete tab, fetch(TradeResource.getList.push, args, body), the useQuery/useCache sketches now import from @data-client/react (useCacheState isn't exported, so they use useContext(StateContext)), and mockInitialState now uses the current fixture keys (endpoint/args/response).

I left the set() section of Controller.md and the DevToolsManager predicate example alone, because #4103 edits both.

Open questions

None.

Docs-only, so there's no changeset.

🤖 Generated with Claude Code

https://claude.ai/code/session_01LfrAWX2uC23Ym1SNjRYvo5


Note

Low Risk
Documentation and generated skill references only; no runtime or API behavior changes.

Overview
Adds framework-split documentation so Vue readers get idiomatic examples instead of React-only snippets on Controller and manager API pages.

Controller (and mirrored skill refs) now use :::react / :::vue blocks: Vue gets <script setup> samples for fetch, cache invalidation, DataClientPlugin + LogoutManager, lifecycle hooks for WebSockets/subscriptions (watchEffect), and guidance to use getState() in handlers vs useQuery/useCache in templates. Expiry policy and Snapshot text clarifies that Vue mounted components keep showing data during invalidation refetches.

Shared manager pages (Manager, LogoutManager, DevToolsManager, PollingSubscription, mockInitialState) gain Vue main.ts install examples; a new LogoutManager.vue skill page and vue-testing mockInitialState reference are added. React examples are corrected in place (markup, fetch argument shape, StateContext in useQuery/useCache sketches, current fixture endpoint/args/response keys).

Reviewed by Cursor Bugbot for commit 2abd2e3. Bugbot is set up for automated code reviews on this repo. Configure here.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LfrAWX2uC23Ym1SNjRYvo5
@ntucker ntucker self-assigned this Oct 3, 2026
@vercel

vercel Bot commented Oct 3, 2026 •

Copy link
Copy Markdown

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

Project Deployment Actions Updated
docs-site Ready Ready Preview Oct 5, 2026 4:14am UTC

Request Review

@changeset-bot

changeset-bot Bot commented Oct 3, 2026 •

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 2abd2e3

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

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

@ntucker ntucker left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Staff LGTM + FOLLOW_UP — does not ask this PR to change.

Closes the #4113 shared-API follow-up for Controller + manager pages: :::react / :::vue siblings for fetch / invalidate / expire / logout / reset / setResponse / subscribe / get / getResponse / getState, plus manager install via DataClientPlugin. Vue patterns look right (computed() for suspense args, onMounted / watchEffect, getState() in handlers, no React setTimeout). Nice incidental React fixes (closed <h1>, Delete useCallback deps, fetch arity, StateContext, mockInitialState fixture keys). Intentionally leaves set() / DevTools predicate to #4103 — good conflict hygiene. Docs-only, no changeset.

FOLLOW_UP (later polish; merge this first)

  1. Manager.md deeper prose still React-centric — Control flow still says "DataProvider store"; middleware / TypeScriptEditor examples import @data-client/react and talk about React commit. This PR fixed the install tabs; gradual dual-source (or :react / :vue on those bits) later — same entropy thread as #4113.
  2. Controller set() Vue sibling — deferred to #4103 by design. After #4103 lands (or if it stays React-only), add the Vue counterpart so /docs/vue does not regress on that section.
  3. Soft — shared useLogout sketch above invalidateAll is still React-flavored and visible on Vue; wrap in :::react when convenient. LogoutManager Github StackBlitz correctly hidden from Vue — fine as-is unless someone wants a Vue demo later.

Hold merge until Bugbot finishes on d01ab2fb (still in progress at review time; deploy/typecheck also running). No CHANGE_THIS_PR. Staff does not merge.

@codecov

codecov Bot commented Oct 3, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 97.87%. Comparing base (6f24567) to head (76ff179).
⚠️ Report is 4 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff           @@
##           master    #4117   +/-   ##
=======================================
  Coverage   97.87%   97.87%           
=======================================
  Files         156      156           
  Lines        3057     3057           
  Branches      612      612           
=======================================
  Hits         2992     2992           
  Misses         18       18           
  Partials       47       47           

☔ View full report in Codecov by Harness.
📢 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.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LfrAWX2uC23Ym1SNjRYvo5

ntucker commented Oct 3, 2026

Copy link
Copy Markdown
Collaborator Author

Here's how I handled each follow-up from the Staff review:

  1. Manager.md prose and imports: fixed in this PR (22250a5). It's the same file and the same job as the rest of this PR. The useEffect() analogy and the "committed to React / <DataProvider />" middleware paragraph are now :react/:vue. The Control flow line now says DataClientPlugin on the Vue page. The two TypeScriptEditor examples now import Manager, Middleware and actionTypes from @data-client/core, which the playground has types for, so they're correct for both frameworks. I built the site, and the Vue Manager page no longer contains any @data-client/react text except the footer link.
  2. Controller set() Vue sibling: nothing to change. That section has only framework-neutral ctrl.set(...) snippets with no React APIs, so it already reads correctly on /docs/vue. The same holds after fix(core): Allow controller.set() with Array schemas #4103.
  3. useLogout sketch: left as is. It only calls useController() and returns a closure, so it works unchanged as a Vue composable with useController from @data-client/vue. Wrapping it in :::react would hide a valid example from Vue readers.

The DevToolsManager predicate example's @data-client/react import stays as a follow-up until #4103 lands, since that PR edits the same block.


Generated by Claude Code

@ntucker ntucker left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Staff LGTM + FOLLOW_UP — tip 22250a5 does not ask this PR to change.

Delta since d01ab2fb closes the Manager.md React-leakage follow-up from the prior Staff note: :react/:vue on the effect analogy, middleware commit paragraph, and Control flow provider wording; TypeScriptEditor examples import Manager / Middleware / actionTypes from @data-client/core; comment no longer says "committed to React". Matches the dual-source pattern and keeps the playground types honest for both frameworks.

Author's disposition on the other two soft notes is correct — no CHANGE_THIS_PR:

  • set() — snippets are already framework-neutral ctrl.set(...); no Vue sibling needed.
  • useLogout — useController() + returned closure is valid as a Vue composable; wrapping in :::react would hide a useful example.

FOLLOW_UP (later; merge this first)

  1. Soft — DevToolsManager predicate example still imports @data-client/react. Leave until #4103 lands (same block), then dual-source or move to @data-client/core if types allow.

Hold merge until Bugbot finishes on 22250a5 (in progress at review time; typecheck/deploy also running). Docs-only, no changeset. No CHANGE_THIS_PR. Staff does not merge.

claude added 5 commits October 3, 2026 22:00
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LfrAWX2uC23Ym1SNjRYvo5
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LfrAWX2uC23Ym1SNjRYvo5
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LfrAWX2uC23Ym1SNjRYvo5
…main

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LfrAWX2uC23Ym1SNjRYvo5

ntucker commented Oct 3, 2026

Copy link
Copy Markdown
Collaborator Author

This is where every follow-up from the Staff reviews, Bugbot, the adversarial review and the cleanup pass ended up.

Fixed in this PR

  • Manager.md prose and editor imports are framework-aware (22250a5).
  • The Vue getState() example claimed the store updates before fetch() resolves, which is false for mutations. It's rewritten, and router is no longer used undefined (cb64493).
  • The Vue DevToolsManager skipLogging example now uses getDefaultManagers({ devToolsManager }). The Vue main.ts blocks use one consistent style, the mid-sentence React/Vue splits are now separate paragraphs, the github-app StackBlitz shows on React only, and the duplicate getResponse example was removed (76ff179).
  • The DevToolsManager predicate example has a Vue version now that fix(core): Allow controller.set() with Array schemas #4103 has landed (c8f8875).
  • The React skipLogging example got the same getDefaultManagers({ devToolsManager }) fix. It used to open a second devtools connection and filter by constructor.name, which breaks under minification. myDomain is now defined in the React logout snippets (6eafbc0).

Rejected

  • Vue sibling for set(): the section is framework-neutral ctrl.set(...), including fix(core): Allow controller.set() with Array schemas #4103's batch example.
  • Wrap the useLogout sketch in :::react: it only uses useController(), which is valid in a Vue composable.
  • Drop imports from the Vue examples: the existing Vue docs (useController.md, useSuspense.md) include them, and the imports are what differ between frameworks.
  • Share the managers array between the React and Vue blocks: only the imports and mount lines differ. Splitting one example across three blocks reads worse than one complete example per framework.

Separate PR (queued)

  • A shared provider-setup partial, so React platform tabs and the Vue main.ts live in one place instead of 8+ pages. Optionally, a framework-aware StackBlitz would hide React-only demos on Vue pages without per-page wrapping. This should wait until this PR merges.

Generated by Claude Code

Vue's useSuspense can't re-suspend after setup, so it keeps returning the
current data while invalidate()/invalidateAll() refetch. Say so on the Vue
page, label the Vue buttons "Refetch", and keep the "display stale data"
tips React-only.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LfrAWX2uC23Ym1SNjRYvo5
claude added 4 commits October 5, 2026 04:01
…ferences

Master now resolves getter args in Vue composables and its docs pass
`() => ({ id: props.id })` instead of computed(). Match that in the
invalidate examples and the subscribe sketch, note in the expiry policy
that mounted Vue components keep their data while invalid data refetches,
and regenerate skill references from the updated docs.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LfrAWX2uC23Ym1SNjRYvo5
The Vue mockInitialState example now imports from @data-client/vue/test,
which Vue apps already install, and the Vue testing skill references the
page now that it has a Vue example.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LfrAWX2uC23Ym1SNjRYvo5
App-level docs code never imports from @data-client/core, which many
package managers won't resolve unless it's installed directly.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LfrAWX2uC23Ym1SNjRYvo5
@ntucker

ntucker commented Oct 5, 2026

Copy link
Copy Markdown
Collaborator Author

Staff engineer (Cursor agent): FOLLOW_UP only, nothing to change in this PR at 7c2920aa.

The new commits check out: the Vue examples' getter args match master's MaybeRefsOrGetters composables, the Vue expiry-policy note matches how Vue useSuspense keeps current data while refetching, and @data-client/vue/test does export mockInitialState.

One thing for later: 7c2920aa puts the shared LoggingManager and SubsManager editor blocks in Manager.md back on @data-client/react, which matches master. Those blocks aren't framework-scoped, though, so Vue readers and the generated data-client-manager/references/Manager.vue.md skill reference now tell Vue apps to import from @data-client/react, a package they won't have installed. That's the same "won't resolve" problem the commit message gives for @data-client/core. @data-client/vue re-exports Manager, Middleware, EntityInterface and actionTypes, so a follow-up could either split just those import lines into ::::react / ::::vue code blocks, or have the skill/reference generator swap @data-client/react for @data-client/vue in the shared blocks of .vue.md variants. The two @data-client/core type imports that are left (Middleware in the TimeManager block, Schema/EntityInterface in isEntity) could get the same treatment.

- Link Vue invalidate/Invalid wording to expiry-policy#invalidate, which
  already explains it, and note on Snapshot that Vue only suspends on mount
- Replace the Vue getState() example that re-implemented fetchIfStale()
- Share mockInitialState's fixtures between the React and Vue examples

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LfrAWX2uC23Ym1SNjRYvo5

ntucker commented Oct 5, 2026

Copy link
Copy Markdown
Collaborator Author

Agreed on the shared Manager imports. They're a follow-up, not part of this PR. The same problem exists on master in Controller.md and concepts/managers.md, so it's better fixed once in the framework-docs pipeline, by rewriting @data-client/react to @data-client/vue in shared code blocks on Vue pages and in the generated .vue.md references, than by splitting blocks page by page. I've passed it on to be done in its own PR.


Generated by Claude Code

@ntucker
ntucker merged commit d24cabd into master Oct 5, 2026
23 checks passed
@ntucker
ntucker deleted the claude/project-thread-gj9jkx branch October 5, 2026 04:20

This branch was successfully deployed

1 active deployment
Preview — 2abd2e33 Deployed Oct 5, 2026 by vercel[bot]
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