migrate-to-tanstack
GitHub将数据获取端点从旧版 ExtensionRegistryService 迁移至 TanStack Query Hook,涉及消费者重构、重试策略调整及测试更新。
Trigger Scenarios
Install
npx skills add eclipse-openvsx/openvsx --skill migrate-to-tanstack -g -y
SKILL.md
Frontmatter
{
"name": "migrate-to-tanstack",
"description": "Migrate a data-fetching endpoint from the legacy ExtensionRegistryService + fetch-retry pattern to a TanStack Query hook. Only do this when the user explicitly asks — it is an opt-in, in-progress migration. Pairs with the tanstack-query-conventions skill."
}
Migrating an endpoint to TanStack Query
Only run this when the user explicitly asks to migrate an endpoint. The migration is in progress and opt-in — never convert endpoints as a side effect of other work.
The current picture
src/extension-registry-service.ts (ExtensionRegistryService, plus service.admin.*) holds every server call. Legacy, un-migrated consumers call these methods straight from a component, passing an AbortController and relying on fetch-retry's 10-attempt backoff inside sendRequest. That drags along per-component AbortController refs, useEffect fetch-on-mount wiring, and hand-rolled loading/error state.
Migrated endpoints instead go through a use* hook wrapping useQuery/useMutation, and retries move to the shared query client (src/query-client.ts). Roughly half the service is migrated — grep before assuming either state.
Steps
-
Find every consumer of the method you're migrating:
grep -rn "service\.<method>\|\.<method>(" src. List them — you'll migrate all of them or a named subset. -
Decide the retry scope — ask if unsure. Ideally the service method flips from
sendRequest(retriable) tosendNonRetriableRequest, handing retries to TanStack. Only do that when every consumer is moving to a hook — a legacy consumer still calling the method directly would silently lose its retry. If you're migrating just one of several consumers, either leave the method retriable (the query then double-retries, tolerated in the interim) or confirm scope with the user. When the request doesn't make the consumer scope clear, ask. -
Adjust the service method.
- Query methods: keep the
AbortControllerparam — the hook passescontrollerFromSignal(signal). - Mutation methods: drop the
AbortControllerparam — we no longer abort writes.
- Query methods: keep the
-
Create the hook — shape and naming per the
tanstack-query-conventionsskill. Co-locate it in the feature's folder first; move tosrc/hooks/only when a second place needs it. The hook returns the react-query result object as-is, never justdataor a picked subset. -
Update the consumers. Replace the
AbortController/useEffect/ manual-state boilerplate with the hook, destructuring and renaming its result (const { data: user, error: userError } = ...;const { mutateAsync, isPending } = ...). Delete the dead boilerplate. -
Finish per the
write-codeskill: add or update tests (write-tests), add a changelog entry, and passyarn lint.
Don't
- Don't strip
fetch-retryfromsendRequestglobally — that's the final cleanup once the whole migration is done, and un-migrated direct callers still depend on it. Keep the 429 /Retry-Afterblock regardless. - Don't migrate endpoints nobody asked you to.
Version History
- 4c33308 Current 2026-08-20 15:09


