Skip to main content

songbird-sync

Sync engine — channel-based state routing, transforms, guards, and transports The songbird-sync crate provides the core synchronization infrastructure for Songbird, implementing a sophisticated channel-based architecture for routing state updates between the audio engine, UI frontends, collaboration systems, and external integrations.

Overview

The sync engine acts as the central nervous system of Songbird, coordinating state changes across all components through a unified channel-based messaging system. It ensures consistency, provides transformation capabilities, implements access controls, and enables real-time collaboration.

Architecture

┌─────────────────────────────────────────────────────────────┐
│                    Sync Engine Core                         │
├─────────────────────────────────────────────────────────────┤
│  Channels  │  Guards   │ Transforms │ Transports │ Dispatch │
│  ─────────────────────────────────────────────────────────  │
│  • mixer   │  • load   │  • JSON    │  • Native  │ • Context│
│  • transport│  • drag   │  • binary  │  • WebSocket│ • Helpers│
│  • project │  • collab │  • path    │  • IPC     │ • Routing│
│  • ai      │  • echo   │  mapping   │  • Collab  │          │
│  • plugin  │           │            │           │          │
│  • recording│          │            │           │          │
│  • export  │           │            │           │          │
│  • meters  │           │            │           │          │
│  • settings│           │            │           │          │
│  • notifications       │            │           │          │
│  • collab  │           │            │           │          │
│  • engine  │           │            │           │          │
└─────────────────────────────────────────────────────────────┘

Core Components

Channels

The sync engine organizes functionality into logical channels, each handling a specific domain:
  • mixer - Audio mixing, track routing, effects, sends/returns
  • transport - Playback control, tempo, looping, metronome
  • project - Project lifecycle, file operations, templates, presets
  • ai - AI-powered composition and chat functionality
  • plugin - Plugin management, parameter automation, presets
  • recording - Audio/MIDI recording, input management, take lanes
  • export - Audio export, rendering, format conversion
  • meters - Real-time audio level monitoring and analysis
  • settings - User preferences and application configuration
  • notifications - System notifications and alerts
  • collab - Real-time collaboration and conflict resolution
  • engine - Audio engine configuration and control
Each channel provides:
  • Command definitions - Available operations and their parameters
  • Event definitions - State change notifications
  • Action handlers - Command execution logic
  • TypeScript bindings - Type-safe frontend integration

Guards

Guards implement access control and state validation:
  • Load guards - Prevent operations during project loading
  • Drag guards - Handle UI interaction conflicts
  • Collaboration guards - Manage concurrent user access
  • Echo suppression - Prevent feedback loops in distributed systems

Transforms

Data transformation pipeline for format conversion:
  • JSON ↔ Binary - Efficient serialization for real-time transport
  • Path mapping - Route updates to specific state locations
  • Schema validation - Ensure data integrity
  • Versioning - Handle compatibility across different client versions

Transports

Multiple transport mechanisms for different integration scenarios:
  • Native functions - Direct in-process communication
  • WebSocket - Real-time web frontend integration
  • Tauri IPC - Desktop application bridge
  • Collaboration transport - Distributed state synchronization

Dispatch System

Unified command routing and execution:
  • DispatchContext - Execution context with state access
  • dispatch_helpers - Common operations and state queries
  • Channel routing - Route commands to appropriate handlers
  • Error handling - Consistent error reporting and recovery

Key Features

Real-time State Synchronization

  • Immediate consistency - All clients see the same state
  • Conflict resolution - Handle concurrent modifications gracefully
  • Selective updates - Only transmit changed data
  • Batch optimization - Group related changes for efficiency

TypeScript Integration

  • Automatic type generation - ts-rs generates TypeScript types from Rust
  • Type-safe channels - Frontend gets compile-time type checking
  • Command validation - Parameters are validated at the boundary
  • Event subscriptions - Strongly typed event handlers

Performance Optimization

  • Batching and throttling - Reduce update frequency for high-frequency events
  • Profiling integration - Track performance of sync operations
  • Memory efficiency - Minimize allocations in hot paths
  • Concurrent processing - Handle multiple channels simultaneously

Extensibility

  • Plugin architecture - Add new channels without modifying core
  • Custom transforms - Implement domain-specific data processing
  • Transport abstraction - Support new communication protocols
  • Guard composition - Combine multiple access control strategies

Usage

Basic Engine Setup

use songbird_sync::{SyncEngine, SyncEngineConfig, wiring};
use songbird_state::StateStore;

// Initialize state store
let store = StateStore::new(/* ... */);

// Configure sync engine
let config = SyncEngineConfig::default();
let engine = SyncEngine::new(config);

// Wire channels and transports
wiring::init_sync_engine(&engine, &store)?;

Command Dispatch

use songbird_sync::dispatch::{dispatch_command, DispatchContext};

// Create dispatch context
let ctx = DispatchContext::new(store, engine, transport);

// Execute command
let result = dispatch_command(
    &ctx,
    "mixer",
    "set_track_gain", 
    &json!({
        "track_id": "track_1",
        "gain": 0.8
    })
)?;

Event Subscription

use songbird_sync::subscribers::{subscribe_to_channel, EventHandler};

// Subscribe to mixer events
subscribe_to_channel("mixer", |event| {
    match event.name.as_str() {
        "track_gain_changed" => {
            // Handle gain change
        }
        "track_muted" => {
            // Handle mute
        }
        _ => {}
    }
})?;

TypeScript Integration

The sync engine automatically generates TypeScript types for frontend integration:
# Generate TypeScript bindings
cargo test -p songbird-sync export_bindings
This creates type-safe definitions that can be imported in TypeScript:
import { MixerCommands, MixerEvents, TransportCommands } from './generated/sync-types';

// Type-safe command execution
const result = await invoke<MixerCommands>('mixer:set_track_gain', {
  track_id: 'track_1',
  gain: 0.8
});

// Type-safe event handling  
onEvent<MixerEvents>('mixer:track_gain_changed', (event) => {
  console.log(`Track ${event.track_id} gain: ${event.gain}`);
});

Development

Adding a New Channel

  1. Create channel module in src/channels/:
    // src/channels/my_channel/mod.rs
    pub mod defs;
    pub mod commands;
    
    pub use defs::*;
    pub use commands::*;
    
  2. Define commands and events:
    // src/channels/my_channel/defs.rs
    use ts_rs::TS;
    use serde::{Serialize, Deserialize};
    
    #[derive(Serialize, Deserialize, TS)]
    pub struct MyCommand {
        pub param: String,
    }
    
  3. Implement command handlers:
    // src/channels/my_channel/commands.rs
    use crate::dispatch_context::DispatchContext;
    
    pub fn dispatch(ctx: &DispatchContext, command: &str, params: &serde_json::Value) -> Result<serde_json::Value, String> {
        match command {
            "my_command" => handle_my_command(ctx, params),
            _ => Err(format!("Unknown command: {}", command))
        }
    }
    
  4. Register in channel registry (src/channels/mod.rs):
    pub mod my_channel;
    
    // Add to channel list in all_default_channel_defs()
    

Running Tests

# Run all sync engine tests
cargo test -p songbird-sync

# Test specific functionality
cargo test -p songbird-sync channels
cargo test -p songbird-sync guards
cargo test -p songbird-sync transforms

# Test TypeScript export
cargo test -p songbird-sync export_bindings

Dependencies

  • songbird-state - State management and persistence
  • songbird-engine - Audio engine integration
  • songbird-plugins - Plugin system integration
  • serde - JSON serialization
  • ts-rs - TypeScript type generation
  • chrono - Timestamp handling

License

Part of the Songbird audio production suite.