microsoft / microsoft/vscode-documentdb

[discuss] Per-view tRPC instances for DocumentDB webviews (remove ctx casts)

Open
#796 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
31
Forks
22
Avg merge
2d 20h
Merged PRs (30d)
21

Description

Context

@microsoft/vscode-ext-webview supports either one shared tRPC instance for all webviews or one instance per webview (initWebviewTrpc<ViewContext>()). The DocumentDB extension currently uses a single shared instance bound to the framework BaseRouterContext:

// src/webviews/_integration/trpc.ts
const trpc = initWebviewTrpc<FrameworkBaseRouterContext>();

Because that one instance serves CollectionView, DocumentView, QueryInsights, IndexView, etc., two consumer-side patterns fall out of the design (surfaced during review of #795):

  1. Per-procedure narrowing cast — every procedure re-narrows ctx to its view type:
    const myCtx = ctx as RouterContext; // ~30 sites
    
  2. Omit on the root context — controllers build the initial context, but actionContext is injected per-call by the telemetry runner, so the root object can't be a full RouterContext:
    const trpcContext: Omit<RouterContext, 'actionContext'> = { ... };
    

Neither is a package limitation — both are how this extension wires the package. vscode-cosmosdb avoids the cast by building a separate instance per webview, each initTRPC.context<QueryEditorRouterContext>().

Proposal

Move DocumentDB to per-view tRPC instances — one initWebviewTrpc<ThisViewContext>() per webview — so ctx is already the precise per-view type inside procedures.

Pros

  • Removes ~30 ctx as RouterContext casts. Procedures read ctx.sessionId, ctx.actionContext, etc. directly, fully typed.
  • Type safety instead of casts. A wrong field access becomes a compile error rather than being masked by the as cast.
  • Matches the framework's intended usage and the vscode-cosmosdb shape, making the two extensions' integration layers converge (easier shared learnings / future extraction).
  • Clearer per-view boundaries — each view owns its context type end to end; no giant shared BaseRouterContext union of concerns.

Cons

  • More wiring / boilerplate. N instances instead of one: each needs its own publicProcedure / router / createCallerFactory (and the telemetry middleware applied per instance). The framework note warns against hiding the .use() chain behind a generic helper (it collapses tRPC's ProcedureBuilder inference to any), so the wiring is repeated per instance by design.
  • Circular-import care. The current single-leaf trpc.ts deliberately breaks an appRouter -> per-view router -> appRouter cycle. Per-view instances need the same discipline replicated N times.
  • Does not remove the Omit (or optional) on the root context. actionContext is still injected per call, so the controller-built root context still lacks it regardless of instance count. This refactor fixes the cast, not the injected-field modelling.
  • Churn for limited functional gain. It's an ergonomics/typing improvement, not a behavior change; touches every router + controller.

Decision needed

  • Do we want per-view instances (remove casts) vs. keep the single instance (one cast pattern, less wiring)?
  • Independently: how to model the injected actionContext on the root context — keep Omit<RouterContext, 'actionContext'>, make it optional, or a WithActionContext<T> wrapper at read sites?

Follow-up to #795 (kept out of that PR to stay scoped to the package API change).

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with src/webviews/_integration/trpc.ts, then inspect the affected view routers and controllers that use the shared instance and context casts. Compare the per-view integration shape referenced from vscode-cosmosdb. This discussion is not ready for implementation until the instance strategy and actionContext modelling are decided; done would be a recorded decision and consistent treatment across the affected views.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
devtools
Issue type
Refactor
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Needs clarification
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.