Skip to content

dinghar/vscode-extension-messaging-framework

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

vscode-extension-messaging-framework

A TypeScript library that wraps VS Code's postMessage API with typed request/response semantics, timeout handling, and error propagation.

Why

VS Code webview communication via postMessage is untyped and fire-and-forget. There's no built-in way to send a request and wait for a response, handle timeouts, or propagate errors. You end up writing boilerplate to correlate messages, track pending requests, and serialize errors.

This library gives you:

  • Request/response - send a request, await the result
  • Notifications - fire-and-forget messages
  • Bidirectional - both extension and webview can send requests to each other
  • Type safety - define a schema once, get compile-time checks on method names, params, and results
  • Timeout handling - configurable per-request or per-messenger, with automatic cleanup
  • Error propagation - errors thrown in handlers are serialized, sent across the boundary, and re-thrown as MessagingError on the caller side

Install

npm install vscode-extension-messaging-framework

Usage

1. Define a schema

Create a shared schema that both your extension and webview code can import:

import type { DefineRequest, DefineNotification, MessageSchema } from 'vscode-extension-messaging-framework/shared';

type GetUser = DefineRequest<'getUser', { id: string }, { name: string; email: string }>;
type SaveDraft = DefineRequest<'saveDraft', { content: string }, { saved: boolean }>;
type ThemeChanged = DefineNotification<'themeChanged', { theme: 'light' | 'dark' }>;

export interface MySchema extends MessageSchema {
  webviewRequests: GetUser | SaveDraft;    // webview -> extension
  extensionRequests: never;                 // extension -> webview (none in this example)
  webviewNotifications: never;
  extensionNotifications: ThemeChanged;
}

2. Extension side

import { ExtensionMessenger } from 'vscode-extension-messaging-framework/extension';
import type { MySchema } from './shared/schema';

const messenger = new ExtensionMessenger<MySchema>(panel.webview, {
  defaultTimeout: 5000,
});

// Handle requests from the webview
messenger.onRequest('getUser', async ({ id }) => {
  const user = await db.findUser(id);
  return { name: user.name, email: user.email };
});

// Send a notification to the webview
messenger.notify('themeChanged', { theme: 'dark' });

3. Webview side

import { WebviewMessenger } from 'vscode-extension-messaging-framework/webview';
import type { MySchema } from '../shared/schema';

const messenger = new WebviewMessenger<MySchema>();
messenger.start();

// Send a request to the extension
const user = await messenger.request('getUser', { id: '123' });
console.log(user.name);

// Listen for notifications
messenger.onNotification('themeChanged', ({ theme }) => {
  document.body.className = theme;
});

Error handling

Errors thrown in handlers are automatically propagated to the caller:

import { MessagingError, ErrorCode } from 'vscode-extension-messaging-framework/shared';

// Extension side
messenger.onRequest('saveDraft', ({ content }) => {
  if (!content) {
    throw new MessagingError(ErrorCode.InvalidParams, 'Content cannot be empty');
  }
  return { saved: true };
});

// Webview side
try {
  await messenger.request('saveDraft', { content: '' });
} catch (err) {
  // err is a MessagingError with code, message, and optional data
}

Requests that exceed the timeout throw a MessagingError with ErrorCode.Timeout. You can override the timeout per request:

const result = await messenger.request('saveDraft', { content }, { timeout: 10000 });

Cleanup

Both messengers implement dispose() which removes listeners and cancels pending requests:

messenger.dispose();

Demo

The demo/ directory contains a working VS Code extension that exercises the main features of the library:

  • Request/response - increment a counter by sending typed requests from the webview to the extension
  • Bidirectional requests - the extension requests an input value from the webview
  • Timeout handling - a slow operation that succeeds (2s) vs one that exceeds the 5s timeout
  • Error propagation - a handler that intentionally throws, demonstrating error serialization across the boundary
  • Notifications - real-time counter updates and log messages pushed from the extension to the webview

To run the demo:

cd demo
npm install
npm run build

Then press F5 in VS Code to launch the Extension Development Host, and run the Messaging Demo: Show Panel command.

About

A TypeScript library that wraps VSCode's `postMessage` API with typed request/response semantics.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors