Documentation Index
Fetch the complete documentation index at: https://crsdk.app/llms.txt
Use this file to discover all available pages before exploring further.
The Client SDK has two separate event categories that serve different purposes and are subscribed to differently.
| Category | Source | Purpose |
|---|
| Connection events | manager.on() | Camera discovery and connection state |
| Property & action events | manager.camera(id).events | Camera settings changes, warnings, transfers |
Connection Events
Emitted by CameraManager (both server and browser variants). Use these to monitor camera discovery, connection state, and errors.
Events table
| Event | Payload | When |
|---|
camera-found | { camera } | New camera detected by polling |
camera-lost | { camera } | Camera no longer detected (unplugged/offline) |
camera-connecting | { cameraId } | Connection attempt started |
camera-ready | { cameraId, camera } | Connected and ready for commands |
camera-disconnected | { cameraId, error? } | Disconnected (explicit or unexpected) |
connection-failed | { cameraId, error, attempt } | Connection attempt failed |
error | { message } | Manager-level error (poll failure, SSE error) |
Subscribing
manager.on('camera-found', ({ camera }) => {
console.log(`Discovered ${camera.model} (${camera.id})`);
});
manager.on('camera-ready', ({ cameraId, camera }) => {
console.log(`${camera.model} ready for commands`);
});
manager.on('camera-disconnected', ({ cameraId, error }) => {
if (error) {
console.log(`Unexpected disconnect: ${error}`);
} else {
console.log('Clean disconnect');
}
});
manager.on('connection-failed', ({ cameraId, error, attempt }) => {
console.log(`Attempt ${attempt} failed: ${error}`);
});
manager.on('error', ({ message }) => {
console.error('Manager error:', message);
});
Unsubscribing
// Remove a specific listener
const handler = ({ cameraId }) => console.log('ready', cameraId);
manager.on('camera-ready', handler);
manager.off('camera-ready', handler);
// Remove all listeners for an event
manager.off('camera-ready');
One-shot listeners
// Auto-removed after the first fire
manager.on('camera-ready', async ({ cameraId }) => {
// runs only once for the first camera that connects
});
Property & Action Events
Real-time notifications from the camera via SSE. Use manager.camera(id).events to subscribe to property changes, warnings, autofocus status, file transfers, and errors.
Events table
| Event | Payload | When |
|---|
connected | { cameraId } | Camera connection established (SSE callback from server) |
disconnected | { error } | Camera disconnected (SSE callback from server) |
propertyChanged | { codes } | Camera settings changed (ISO, aperture, etc.) |
warning | { code } | Camera warning (code 0x20011 = photo captured) |
afStatus | { state } | Autofocus state changed ('focused' | 'unlocked' | 'tracking') |
downloadComplete | { filename } | File saved to host PC |
transferProgress | { percent, filename } | File transfer progress |
error | { code } | SSE connection error |
close | — | SSE stream closed by manager |
Via bound camera (recommended)
The simplest way to subscribe to per-camera events is via manager.camera(id).events:
manager.on('camera-ready', ({ cameraId }) => {
const cam = manager.camera(cameraId);
cam.events.on('propertyChanged', (data) => {
console.log('Properties changed:', data.codes);
});
cam.events.on('warning', (data) => {
if (data.code === '0x20011') console.log('Photo captured!');
});
cam.events.on('downloadComplete', (data) => {
console.log('File saved:', data.filename);
});
cam.events.on('afStatus', (data) => {
console.log('AF state:', data.state);
});
cam.events.on('transferProgress', (data) => {
console.log(`Transfer: ${data.percent}%`, data.filename);
});
// One-shot listener — auto-removed after first fire
cam.events.once('connected', () => {
console.log('First connection established');
});
});
Via EventStream directly
For manual control, create an EventStream directly:
import { EventStream } from 'camera-remote-web-api';
// All cameras
const events = new EventStream('http://localhost:8080');
// Or filter to a single camera
const camEvents = new EventStream('http://localhost:8080', 'D10F60149B0C');
camEvents.on('propertyChanged', (data) => {
console.log('Properties changed:', data.codes);
});
Cleanup
// Remove specific callback
const handler = (data) => console.log(data);
events.on('downloadComplete', handler);
events.off('downloadComplete', handler);
// Close SSE connection
events.close();
Using Both Together
Connection events tell you when a camera is ready. Property & action events tell you what’s happening on the camera.
import { CameraManager } from 'camera-remote-web-api/server';
const manager = new CameraManager({ port: 8080, connectionMode: 'remote-transfer' });
// Connection events — monitor lifecycle
manager.on('camera-ready', async ({ cameraId, camera }) => {
console.log(`${camera.model} connected`);
const cam = manager.camera(cameraId);
// Property events — monitor camera activity
cam.events.on('downloadComplete', (data) => {
console.log(`${camera.model}: file saved — ${data.filename}`);
});
cam.events.on('propertyChanged', (data) => {
console.log(`${camera.model}: settings changed — ${data.codes}`);
});
});
await manager.start();