Skip to content

Commit 901b4d2

Browse files
authored
refactor: redesign webview package as @microsoft/vscode-ext-webview (#766)
2 parents 39ed915 + 1ee371f commit 901b4d2

118 files changed

Lines changed: 11443 additions & 2530 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/skills/webview-trpc-messaging/SKILL.md

Lines changed: 47 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,15 @@ useTrpcClient() hook WebviewController
2323

2424
| File | Purpose |
2525
| ---------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
26-
| `@microsoft/vscode-ext-react-webview/server` (trpc) | tRPC init, `publicProcedure`, `createMiddleware`, `router`, `BaseRouterContext` |
27-
| `src/webviews/_integration/appRouter.ts` | Root router + telemetry middleware + `publicProcedureWithTelemetry` + `WithTelemetry` + DocumentDB `BaseRouterContext` |
26+
| `@microsoft/vscode-ext-webview` (shared) | tRPC init via `initWebviewTrpc`, `publicProcedure`, `router`, `BaseRouterContext` |
27+
| `@microsoft/vscode-ext-webview/host` (telemetry) | `telemetryMiddlewareBody`, `ProcedureLogger`, `TelemetryRunner` (consumer builds `publicProcedureWithTelemetry`) |
28+
| `src/webviews/_integration/trpc.ts` | Consumer tRPC instance: `publicProcedureWithTelemetry`, the DocumentDB `TelemetryRunner`, `WithTelemetry` |
29+
| `src/webviews/_integration/appRouter.ts` | Root router + `publicProcedureWithTelemetry` wiring + DocumentDB `BaseRouterContext` |
2830
| `src/webviews/_integration/configuration.ts` | Consumer-owned knobs (telemetry namespace, bundle layout, dev-server host) |
29-
| `@microsoft/vscode-ext-react-webview/server` (WebviewController) | WebviewPanel lifecycle, tRPC message dispatcher (queries, mutations, subscriptions, abort) |
30-
| `src/webviews/_integration/WebviewControllerBase.ts` | DocumentDB-tuned base class that pre-fills router + bundle layout |
31+
| `@microsoft/vscode-ext-webview/host` (WebviewController) | `WebviewController` + `openWebview` factory: WebviewPanel lifecycle, tRPC dispatcher (queries, mutations, subscriptions, abort) |
32+
| `src/webviews/_integration/openAppWebview.ts` | DocumentDB factory preset that pre-fills router + bundle layout (`openAppWebview`) |
3133
| `src/webviews/_integration/useTrpcClient.ts` | React hook providing the tRPC client (pre-typed against `AppRouter`) |
32-
| `@microsoft/vscode-ext-react-webview` (vscodeLink) | Custom tRPC link bridging `postMessage` transport |
34+
| `@microsoft/vscode-ext-webview/webview` (vscodeLink) | Custom tRPC link bridging `postMessage` transport |
3335

3436
## Creating a New Router
3537

@@ -91,33 +93,53 @@ export const appRouter = router({
9193

9294
### 4. Create the controller
9395

96+
Construction-only panels are opened with a factory function that builds the
97+
config + router context and calls the `openAppWebview` preset (which pre-fills
98+
the app router, caller factory, and bundle layout):
99+
94100
```typescript
95101
// src/webviews/documentdb/myView/myViewController.ts
96-
import { WebviewControllerBase } from '../../_integration/WebviewControllerBase';
102+
import * as vscode from 'vscode';
103+
import { API } from '../../../DocumentDBExperiences';
104+
import { type AppWebviewController, openAppWebview } from '../../_integration/openAppWebview';
97105
import { type RouterContext } from './myViewRouter';
98106

99-
export class MyViewController extends WebviewControllerBase<MyViewConfig> {
100-
constructor(initialData: MyViewConfig) {
101-
super(ext.context, title, 'myViewName', initialData);
102-
103-
const trpcContext: RouterContext = {
104-
dbExperience: API.DocumentDB,
105-
webviewName: 'myView',
106-
clusterId: initialData.clusterId,
107-
viewId: initialData.viewId,
108-
databaseName: initialData.databaseName,
109-
};
110-
111-
this.setupTrpc(trpcContext);
112-
}
107+
export function openMyViewPanel(initialData: MyViewConfig): AppWebviewController<MyViewConfig> {
108+
const title = `${initialData.databaseName}`;
109+
110+
const trpcContext: RouterContext = {
111+
dbExperience: API.DocumentDB,
112+
webviewName: 'myView',
113+
clusterId: initialData.clusterId,
114+
viewId: initialData.viewId,
115+
databaseName: initialData.databaseName,
116+
};
117+
118+
return openAppWebview({
119+
title,
120+
webviewName: 'myView',
121+
config: initialData,
122+
context: trpcContext,
123+
});
113124
}
114125
```
115126

116-
> **Important:** The `webviewName` in the `WebviewControllerBase` constructor is the **registry key** (must match a key in `WebviewRegistry`, e.g. `collectionView`). The `webviewName` in the tRPC context is a **telemetry label** used in telemetry event names (e.g. `collectionView`). These may be the same string but serve different purposes — do not confuse them.
127+
The returned `AppWebviewController` handle exposes `panel`, `onDisposed`,
128+
`revealToForeground`, `isDisposed`, and `dispose`. Genuinely stateful panels may
129+
still extend `WebviewController` from `@microsoft/vscode-ext-webview/host`
130+
directly instead of using the factory.
131+
132+
> **Important:** The `webviewName` field passed to `openAppWebview` is the
133+
> **registry key** (`viewType`, must match a key in `WebviewRegistry`, e.g.
134+
> `collectionView`). The `webviewName` in the tRPC context is a **telemetry
135+
> label** used in telemetry event names. These may be the same string but serve
136+
> different purposes -- do not confuse them.
117137
118138
### 5. Register in WebviewRegistry
119139

120-
Add your React component to the registry. The key must match the `webviewName` passed to `WebviewControllerBase`'s constructor. The `WebviewName` type (exported from the same file) ensures compile-time validation of webview names.
140+
Add your React component to the registry. The key must match the `webviewName`
141+
passed to `openAppWebview` (`viewType`). The `WebviewName` type (exported from
142+
the same file) ensures compile-time validation of webview names.
121143

122144
```typescript
123145
// src/webviews/_integration/WebviewRegistry.ts
@@ -191,7 +213,7 @@ getData: publicProcedureWithTelemetry
191213
### Client-side abort
192214

193215
```tsx
194-
const { trpcClient } = useTrpcClient();
216+
const trpcClient = useTrpcClient();
195217
const abortControllerRef = useRef<AbortController>();
196218

197219
const runQuery = async () => {
@@ -241,10 +263,10 @@ sub.unsubscribe();
241263

242264
```tsx
243265
import { useTrpcClient } from '../_integration/useTrpcClient';
244-
import { useConfiguration } from '@microsoft/vscode-ext-react-webview';
266+
import { useConfiguration } from '@microsoft/vscode-ext-webview/react';
245267

246268
export const MyComponent = () => {
247-
const { trpcClient } = useTrpcClient();
269+
const trpcClient = useTrpcClient();
248270
const config = useConfiguration<MyViewConfig>();
249271

250272
useEffect(() => {

0 commit comments

Comments
 (0)