@smile-design/preview-server
v0.1.0
Published
Preview server primitives for smile-design — Vite child-process lifecycle manager, headless Playwright screenshot, and HookBus-aware preview state. Consumed by smile-design Web UI / MCP Server / future desktop shell.
Downloads
94
Maintainers
Readme
@smile-design/preview-server
Preview server primitives for smile-design — Vite child-process lifecycle management, headless Playwright screenshots, and HookBus-aware preview state. Consumed by the smile-design Web UI, @smile-design/mcp-server, and the future desktop shell.
This package is the runtime layer that turns "an arbitrary user project directory" into a managed dev-server process you can attach an iframe to and capture screenshots from. End users typically interact with it through @smile-design/mcp-server rather than directly.
Install
pnpm add @smile-design/preview-serverPeer requirements: a project that runs on Vite (the manager spawns npx vite in the target directory) and Node.js ≥ 22 LTS.
Use
ViteManager — managed dev-server lifecycle
import { ViteManager } from '@smile-design/preview-server/vite-manager';
const manager = new ViteManager({ port: 5173, startTimeout: 30_000 });
manager.on('status', (state) => {
// state: { status: 'idle' | 'starting' | 'running' | 'stopping' | 'error',
// url?: string, port?: number, projectDir?: string, error?: string }
console.log('preview state →', state);
});
await manager.start({ projectDir: '/path/to/user/project' });
// state.url is now `http://localhost:<port>/`
await manager.stop(); // SIGTERM with SIGKILL fallback after `killTimeout`ViteManager extends EventEmitter and emits a single status event whose payload is a PreviewState snapshot. Errors are surfaced through state.error rather than the Node error event, so missing listeners never throw. Hook events (on-preview-error, etc.) are forwarded to the smile-design HookBus automatically.
ScreenshotManager — headless capture
import { ScreenshotManager } from '@smile-design/preview-server/screenshot';
const screenshots = new ScreenshotManager();
const result = await screenshots.capture({
url: 'http://localhost:5173',
width: 1280,
height: 720,
fullPage: false,
});
// result: { path: string, width: number, height: number, sizeBytes: number }The manager keeps a single Chromium instance alive across captures. Pages wait on load (not networkidle) so that Vite's HMR WebSocket does not block completion.
Subpath exports
| Specifier | Use |
| ------------------------------------------- | -------------------------------------------------------------- |
| @smile-design/preview-server | Re-exports ViteManager + ScreenshotManager for convenience |
| @smile-design/preview-server/vite-manager | Direct import of ViteManager (smaller graph) |
| @smile-design/preview-server/screenshot | Direct import of ScreenshotManager (smaller graph) |
Requirements
- Node.js ≥ 22 (LTS)
playwrightpeer install: a Chromium download vianpx playwright install chromium- TypeScript ≥ 5.4 (consumers)
License
MIT
