Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
9e5b787
chore(webview-ext): scaffold vscode-ext-webview as a copy
tnaum-ms Jun 30, 2026
2baed21
chore(webview-ext): rename package to @microsoft/vscode-ext-webview@0…
tnaum-ms Jun 30, 2026
68d15fb
refactor(webview-ext): introduce shared entry (wire types, TypedEvent…
tnaum-ms Jun 30, 2026
6d2e8f8
refactor(webview-ext): introduce host entry
tnaum-ms Jun 30, 2026
60e40f4
refactor(webview-ext): split framework-agnostic webview entry from re…
tnaum-ms Jun 30, 2026
7516e10
chore(webview-ext): export ./host, ./webview, ./react subpaths
tnaum-ms Jun 30, 2026
f88b342
feat(webview-ext): add initWebviewTrpc typed-init helper
tnaum-ms Jun 30, 2026
f1d9481
feat(webview-ext)!: replace bound telemetry with middleware bodies + …
tnaum-ms Jun 30, 2026
74f75d6
refactor(webview-ext): extract attachTrpc dispatcher from WebviewCont…
tnaum-ms Jun 30, 2026
f2af464
feat(webview-ext): add createEventChannel and refit errorLink as a shim
tnaum-ms Jun 30, 2026
e3e723c
feat(webview-ext): add connectTrpc webview client factory
tnaum-ms Jun 30, 2026
cca91f3
feat(webview-ext)!: split useTrpcClient (client) and useRpcEvents (ch…
tnaum-ms Jun 30, 2026
56adb9f
style(webview-ext): apply prettier normalization to phase C files
tnaum-ms Jun 30, 2026
e11ad56
feat(webview-ext)!: add openWebview factory and options-bag WebviewCo…
tnaum-ms Jun 30, 2026
9ba9bcd
docs(webview-ext): quick-start README with advanced signpost
tnaum-ms Jun 30, 2026
8012f18
docs(webview-ext): add ADVANCED.md
tnaum-ms Jun 30, 2026
237e9ed
chore(documentdb): migrate _integration to @microsoft/vscode-ext-webview
tnaum-ms Jun 30, 2026
0d7ecb3
chore(documentdb): point webview consumers at ./react and split hooks
tnaum-ms Jun 30, 2026
c73aa4d
style(documentdb): wrap trpc.ts host import per prettier
tnaum-ms Jun 30, 2026
6fa0e4a
chore(documentdb): depend on @microsoft/vscode-ext-webview
tnaum-ms Jun 30, 2026
57c3136
chore(documentdb): adopt openWebview factory for panel controllers
tnaum-ms Jun 30, 2026
309e2f0
chore: remove deprecated @microsoft/vscode-ext-react-webview package
tnaum-ms Jun 30, 2026
4e989d9
docs: add internal webview-ext migration manual
tnaum-ms Jun 30, 2026
f576f92
docs: archive webview-ext planning docs under PRs/766-webview-ext-pac…
tnaum-ms Jun 30, 2026
2294a51
fix(build): register vscode-ext-webview in root jest projects and tsc…
tnaum-ms Jun 30, 2026
cf1a2f4
docs(webview-ext): strengthen package description and README framing
tnaum-ms Jul 1, 2026
70d43a3
refactor(documentdb): rename panel factories to open*Webview and expl…
tnaum-ms Jul 1, 2026
a5af2e8
feat: add detailed README files for src, host, middleware, react, sha…
tnaum-ms Jul 2, 2026
0f54231
refactor(webview): enhance documentation and streamline naming conven…
tnaum-ms Jul 2, 2026
0292780
fix(vscode-ext-webview): call AsyncIterator.return() with no argument…
tnaum-ms Jul 3, 2026
0bd16af
refactor(vscode-ext-webview): expose attachTrpc active maps as Readon…
tnaum-ms Jul 3, 2026
c566271
refactor(documentView): return local controller from openDocumentWebv…
tnaum-ms Jul 3, 2026
76172cd
fix(vscode-ext-webview): WebviewController.dispose() now closes the p…
tnaum-ms Jul 3, 2026
9a758cc
fix(vscode-ext-webview): guard useConfiguration JSON parse against ma…
tnaum-ms Jul 3, 2026
76f9948
refactor(vscode-ext-webview): rename dispatch-logger option telemetry…
tnaum-ms Jul 3, 2026
6363a6f
refactor(vscode-ext-webview): make webview request logging opt-in (of…
tnaum-ms Jul 3, 2026
32859af
feat(vscode-ext-webview): ship generic WithTelemetry helper + documen…
tnaum-ms Jul 3, 2026
de27b50
docs(vscode-ext-webview): soften README shared-client wording; drop '…
tnaum-ms Jul 3, 2026
61a0103
docs(vscode-ext-webview): correct ADVANCED.md - subscriptions are not…
tnaum-ms Jul 3, 2026
46296ce
chore(vscode-ext-webview): ship ADVANCED.md and LICENSE in the npm pa…
tnaum-ms Jul 3, 2026
ef04494
docs(pr-766): add iteration-1 change protocol + iteration-2 plan; mov…
tnaum-ms Jul 3, 2026
7873edb
docs(pr-766): finalize iteration-2 decisions — N02 → option A, S04 co…
tnaum-ms Jul 3, 2026
ade2ce6
fix(vscode-ext-webview): guard transport listeners against foreign po…
tnaum-ms Jul 3, 2026
21b0a2f
feat(vscode-ext-webview): accept a trpc instance option; deprecate st…
tnaum-ms Jul 3, 2026
d5748ab
fix(vscode-ext-webview): deliver webview initial data via an inert JS…
tnaum-ms Jul 3, 2026
b603aff
docs(vscode-ext-webview): document the create-or-reveal panel pattern…
tnaum-ms Jul 3, 2026
dbbf996
feat(vscode-ext-webview): measure RPC concurrency to evaluate the per…
tnaum-ms Jul 3, 2026
36c8493
style(vscode-documentdb): prettier-fix rpcConcurrencyLogger imports […
tnaum-ms Jul 3, 2026
953a895
docs(pr-766): finalize iteration-2 change protocol, statuses, and N05…
tnaum-ms Jul 3, 2026
7622703
feat(vscode-ext-webview): isolate event-channel observers + add onObs…
tnaum-ms Jul 4, 2026
559a9af
docs(pr-766): record R766-N05 implementation (option 1) in the iterat…
tnaum-ms Jul 4, 2026
f7c9656
refactor(vscode-documentdb): use typed globalThis.reportError in the …
tnaum-ms Jul 4, 2026
8b690b6
docs(pr-766): document Iteration 3 (R766-N05) and triage Copilot feed…
tnaum-ms Jul 5, 2026
553bf4e
fix(vscode-ext-webview): stop recording error telemetry for aborted R…
tnaum-ms Jul 5, 2026
3301a70
fix(vscode-ext-webview): require an own string id in the webview resp…
tnaum-ms Jul 5, 2026
19b99cb
refactor(vscode-documentdb): annotate the useTrpcClient wrapper retur…
tnaum-ms Jul 5, 2026
cb9cd3b
docs(pr-766): finalize the Iteration 4 change protocol with commit SHAs
tnaum-ms Jul 5, 2026
9625bac
docs(pr-766): close Iteration 4 with a done summary of steps performed
tnaum-ms Jul 5, 2026
13ec19e
docs(webview-ext-review): add Iteration 5 focusing on consumer ergono…
tnaum-ms Jul 5, 2026
2c2e4f3
fix(vscode-ext-webview): select webview script layout by isBundled, n…
tnaum-ms Jul 5, 2026
24be648
refactor(documentdb): group _integration observability sinks into a s…
tnaum-ms Jul 5, 2026
5478d2e
docs(pr-766): record iteration 6 (R766-07 webview-load fix) and itera…
tnaum-ms Jul 5, 2026
8a279cf
perf(webview): gate per-op RPC console log to non-production (R766-P0…
tnaum-ms Jul 6, 2026
0df2f8b
perf(telemetry): split accumulating telemetry into cheap accumulate +…
tnaum-ms Jul 6, 2026
1ee371f
refactor(telemetry): rename callWithAccumulatingTelemetry -> accumula…
tnaum-ms Jul 6, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 47 additions & 25 deletions .github/skills/webview-trpc-messaging/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,15 @@ useTrpcClient() hook WebviewController

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

## Creating a New Router

Expand Down Expand Up @@ -91,33 +93,53 @@ export const appRouter = router({

### 4. Create the controller

Construction-only panels are opened with a factory function that builds the
config + router context and calls the `openAppWebview` preset (which pre-fills
the app router, caller factory, and bundle layout):

```typescript
// src/webviews/documentdb/myView/myViewController.ts
import { WebviewControllerBase } from '../../_integration/WebviewControllerBase';
import * as vscode from 'vscode';
import { API } from '../../../DocumentDBExperiences';
import { type AppWebviewController, openAppWebview } from '../../_integration/openAppWebview';
import { type RouterContext } from './myViewRouter';

export class MyViewController extends WebviewControllerBase<MyViewConfig> {
constructor(initialData: MyViewConfig) {
super(ext.context, title, 'myViewName', initialData);

const trpcContext: RouterContext = {
dbExperience: API.DocumentDB,
webviewName: 'myView',
clusterId: initialData.clusterId,
viewId: initialData.viewId,
databaseName: initialData.databaseName,
};

this.setupTrpc(trpcContext);
}
export function openMyViewPanel(initialData: MyViewConfig): AppWebviewController<MyViewConfig> {
const title = `${initialData.databaseName}`;

const trpcContext: RouterContext = {
dbExperience: API.DocumentDB,
webviewName: 'myView',
clusterId: initialData.clusterId,
viewId: initialData.viewId,
databaseName: initialData.databaseName,
};

return openAppWebview({
title,
webviewName: 'myView',
config: initialData,
context: trpcContext,
});
}
```

> **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.
The returned `AppWebviewController` handle exposes `panel`, `onDisposed`,
`revealToForeground`, `isDisposed`, and `dispose`. Genuinely stateful panels may
still extend `WebviewController` from `@microsoft/vscode-ext-webview/host`
directly instead of using the factory.

> **Important:** The `webviewName` field passed to `openAppWebview` is the
> **registry key** (`viewType`, must match a key in `WebviewRegistry`, e.g.
> `collectionView`). The `webviewName` in the tRPC context is a **telemetry
> label** used in telemetry event names. These may be the same string but serve
> different purposes -- do not confuse them.

### 5. Register in WebviewRegistry

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.
Add your React component to the registry. The key must match the `webviewName`
passed to `openAppWebview` (`viewType`). The `WebviewName` type (exported from
the same file) ensures compile-time validation of webview names.

```typescript
// src/webviews/_integration/WebviewRegistry.ts
Expand Down Expand Up @@ -191,7 +213,7 @@ getData: publicProcedureWithTelemetry
### Client-side abort

```tsx
const { trpcClient } = useTrpcClient();
const trpcClient = useTrpcClient();
const abortControllerRef = useRef<AbortController>();

const runQuery = async () => {
Expand Down Expand Up @@ -241,10 +263,10 @@ sub.unsubscribe();

```tsx
import { useTrpcClient } from '../_integration/useTrpcClient';
import { useConfiguration } from '@microsoft/vscode-ext-react-webview';
import { useConfiguration } from '@microsoft/vscode-ext-webview/react';

export const MyComponent = () => {
const { trpcClient } = useTrpcClient();
const trpcClient = useTrpcClient();
const config = useConfiguration<MyViewConfig>();

useEffect(() => {
Expand Down
Loading