Storybook Channel - A deprecated package that provides shims for the internal channels module used for communication between Storybook Manager and Renderer
—
Transport systems provide the underlying communication mechanisms for channels. Storybook Channels supports multiple transport types for different scenarios including PostMessage for iframe communication and WebSocket for real-time development communication.
Transport implementation using the postMessage API for secure iframe communication between Storybook Manager and Preview.
/**
* Transport implementation using postMessage API for iframe communication
* Handles secure communication between different origins
*/
class PostMessageTransport {
/**
* Create PostMessage transport with configuration
* @param config - Configuration with page identifier
* @throws Error if config.page is not 'manager' or 'preview'
*/
constructor(config: Config);
/**
* Set event handler for incoming messages
* @param handler - Function to handle incoming channel events
*/
setHandler(handler: ChannelHandler): void;
/**
* Send event via postMessage
* @param event - Channel event to send
* @param options - Optional sending options
* @returns Promise that resolves when message is sent
*/
send(event: ChannelEvent, options?: any): Promise<any>;
}
interface Config {
/** Page identifier - determines message routing */
page: 'manager' | 'preview';
}
/** Message key identifier used in postMessage communication */
const KEY: string; // 'storybook-channel'Usage Examples:
import { PostMessageTransport } from "@storybook/channels";
// Create transport for manager
const managerTransport = new PostMessageTransport({ page: 'manager' });
// Set up event handler
managerTransport.setHandler((event) => {
console.log('Received event:', event.type, event.args);
});
// Send events
await managerTransport.send({
type: 'story-selected',
from: 'manager',
args: [{ storyId: 'example-story' }]
});Transport implementation using WebSocket for real-time communication during development, with built-in heartbeat mechanism for connection monitoring.
/**
* Transport implementation using WebSocket for real-time communication
* Includes heartbeat mechanism for connection health monitoring
*/
class WebsocketTransport {
/** Create WebSocket transport with connection arguments */
constructor(args: WebsocketTransportArgs);
/**
* Set event handler for incoming WebSocket messages
* @param handler - Function to handle incoming channel events
*/
setHandler(handler: ChannelHandler): void;
/**
* Send event via WebSocket connection
* @param event - Event data to send
*/
send(event: any): void;
}
interface WebsocketTransportArgs extends Partial<Config> {
/** WebSocket server URL */
url: string;
/** Error handling callback for connection errors */
onError: OnError;
/** Optional page identifier (inherited from Config) */
page?: 'manager' | 'preview';
}
type OnError = (message: Event) => void;
/** Heartbeat interval in milliseconds (15000ms = 15 seconds) */
const HEARTBEAT_INTERVAL: number; // 15000
/** Maximum heartbeat latency in milliseconds (5000ms = 5 seconds) */
const HEARTBEAT_MAX_LATENCY: number; // 5000Usage Examples:
import { WebsocketTransport } from "@storybook/channels";
// Create WebSocket transport
const wsTransport = new WebsocketTransport({
url: 'ws://localhost:9001',
onError: (error) => console.error('WebSocket error:', error),
page: 'preview'
});
// Set up event handler
wsTransport.setHandler((event) => {
if (event.type === 'heartbeat') {
console.log('Heartbeat received');
} else {
console.log('Event received:', event.type);
}
});
// Send events
wsTransport.send({
type: 'story-rendered',
from: 'preview',
args: [{ storyId: 'example-story', success: true }]
});Common interface that all transport implementations must follow for pluggability.
/**
* Common interface for all transport implementations
* Ensures consistent API across different transport types
*/
interface ChannelTransport {
/**
* Send event through this transport
* @param event - Channel event to send
* @param options - Optional transport-specific options
*/
send(event: ChannelEvent, options?: any): void;
/**
* Set handler for incoming events from this transport
* @param handler - Function to handle incoming events
*/
setHandler(handler: ChannelHandler): void;
}
/**
* Handler function type for processing channel events
* @param event - The received channel event
*/
type ChannelHandler = (event: ChannelEvent) => void;
/**
* Standard channel event structure
*/
interface ChannelEvent {
/** Event type identifier */
type: string;
/** Source identifier (e.g., 'manager', 'preview') */
from: string;
/** Event payload arguments */
args: any[];
}For handling events that need to be queued and processed asynchronously.
/**
* Event structure for buffered/queued events
* Used internally for async event processing
*/
interface BufferedEvent {
/** The channel event to be processed */
event: ChannelEvent;
/** Promise resolve function for async handling */
resolve: (value?: any) => void;
/** Promise reject function for error handling */
reject: (reason?: any) => void;
}PostMessage Transport:
WebSocket Transport:
Multiple Transports:
Install with Tessl CLI
npx tessl i tessl/npm-storybook--channels