Skip to main content
Spacedrive’s event system broadcasts real-time updates to all connected clients using a unified resource event architecture that eliminates per-resource event variants in favor of generic, horizontally-scalable events.

Overview

The event bus enables reactive UI updates by notifying clients when data changes. The system uses:
  • Generic Resource Events: A single event type (ResourceChanged) handles all database entities
  • Path-Scoped Subscriptions: Subscribe to events affecting specific directories or files
  • Infrastructure Events: Specialized events for jobs, sync, and system lifecycle
  • Automatic Emission: Events are emitted automatically by the TransactionManager - no manual calls needed

Event Types

Resource Events

Generic events that work for ALL resources (files, tags, albums, locations, etc.):
Supported Resources:
  • file - Files and directories (Entry entity)
  • tag - User tags
  • collection - File collections
  • location - Indexed locations
  • device - Devices in the network
  • volume - Storage volumes (replaces deprecated volume events)
  • sidecar - Generated thumbnails and metadata
  • user_metadata - User-added metadata (notes, favorites, etc.)
  • content_identity - Deduplicated content records
Volume events (VolumeAdded, VolumeUpdated, etc.) and indexing events (IndexingStarted, IndexingProgress, etc.) are deprecated. Use ResourceChanged for volumes and job events for indexing progress.

Infrastructure Events

Specialized events for system operations: Core Lifecycle:
  • CoreStarted, CoreShutdown - Daemon lifecycle
Library Management:
  • LibraryCreated, LibraryOpened, LibraryClosed, LibraryDeleted
  • Refresh - Invalidate all frontend caches
Jobs:
  • JobQueued, JobStarted, JobProgress, JobCompleted, JobFailed, JobCancelled
Sync:
  • SyncStateChanged - Sync state transitions
  • SyncActivity - Peer sync activity
  • SyncConnectionChanged - Peer connections
  • SyncError - Sync errors
Volumes (deprecated - use ResourceChanged with resource_type: "volume"):
  • VolumeAdded, VolumeRemoved, VolumeUpdated
  • VolumeMountChanged, VolumeSpeedTested
Indexing (deprecated - use job events):
  • IndexingStarted, IndexingProgress, IndexingCompleted, IndexingFailed
Filesystem:
  • FsRawChange - Raw filesystem watcher events (before database resolution)

Event Emission

Events are emitted automatically when using the TransactionManager:
The TransactionManager emits ResourceChanged after successful commits, ensuring:
  • ✅ Events always match database state
  • ✅ No forgotten emissions
  • ✅ Automatic sync log integration

Manual Emission (Infrastructure Only)

Only use manual emission for infrastructure events:

Path-Scoped Subscriptions

Subscribe to events affecting specific directories or files:
The ResourceMetadata field includes affected_paths that indicate which directories/files changed:
Path matching supports:
  • Physical paths: Match by device slug + path prefix
  • Content IDs: Match by content identifier
  • Cloud paths: Match by service + bucket + path
  • Sidecar paths: Match by content ID

Client Integration

TypeScript (useNormalizedQuery)

The useNormalizedQuery hook automatically subscribes to resource events and updates the cache:
The normalized cache:
  1. Subscribes to ResourceChanged events matching the resource type
  2. Deserializes the JSON resource using generated TypeScript types
  3. Updates the local cache
  4. Triggers React re-renders

Swift

CLI Event Monitoring

Monitor events in real-time using the CLI:
Available Filters:
  • -t, --event-type - Comma-separated event types (e.g., ResourceChanged,JobProgress)
  • -l, --library-id - Filter by library UUID
  • -j, --job-id - Filter by job ID
  • -d, --device-id - Filter by device UUID
  • --timestamps - Show event timestamps
  • -v, --verbose - Show full event JSON
  • -p, --pretty - Pretty-print JSON output
Example Output:

Implementation Reference

Event enum: core/src/infra/event/mod.rs
Event bus: core/src/infra/event/mod.rs

Benefits

Backend

  • Zero Manual Emission: TransactionManager handles all resource events
  • Type Safety: Events always match actual resources
  • Centralized: Single point of emission prevents drift
  • Scalable: Adding new resources requires no event code

Frontend

  • Zero Boilerplate: One event handler for all resource types
  • Type Registry: Automatic deserialization via generated types
  • Path Scoping: Subscribe only to relevant directory changes
  • Cache Integration: useNormalizedQuery handles subscriptions automatically

Developer Experience

  • No Event Variants: ~40 variants eliminated → 3 generic events
  • No Manual Calls: Never call event_bus.emit() for resources
  • No Client Changes: Adding a 100th resource type = zero event handling updates
  • CLI Debugging: Monitor events in real-time with filtering