netabase 0.0.2

A peer-to-peer networking layer built on libp2p with integrated type-safe storage, enabling distributed applications with automatic data synchronization across native and WASM environments.
Documentation
# Getting Started with Netabase

## Required Dependencies

Add these to your `Cargo.toml`:

```toml
[dependencies]
# Main libraries
netabase = "0.0.1"
netabase_store = "0.0.1"
netabase_deps = "0.0.1"

# Required for macros to work
bincode = { version = "2.0", features = ["serde"] }
serde = { version = "1.0", features = ["derive"] }
strum = { version = "0.27.2", features = ["derive"] }
derive_more = { version = "2.0.1", features = ["from", "try_into", "into"] }

# Runtime dependencies
tokio = { version = "1.0", features = ["full"] }
anyhow = "1.0"
```

**Why so many dependencies?** The macros from `netabase_store` generate code that uses these crates. Due to Rust's macro hygiene rules, they must be available in your `Cargo.toml`. The `netabase_deps` crate provides internal dependencies used by the macros.

## Define Your Data Model

Inside your schema definition module, import the required items:

```rust
use netabase_store::netabase_definition_module;

#[netabase_definition_module(ChatDefinition, ChatKeys)]
pub mod chat {
    use netabase_store::{NetabaseModel, netabase};

    #[derive(NetabaseModel, bincode::Encode, bincode::Decode, Clone, Debug)]
    #[netabase(ChatDefinition)]
    pub struct Message {
        #[primary_key]
        pub id: String,
        pub author: String,
        pub content: String,
        pub timestamp: i64,
        #[secondary_key]
        pub room_id: String,
    }
}

use chat::*;
```

## Complete Working Example

```rust
use netabase::Netabase;
use netabase_store::{netabase_definition_module, NetabaseModel};
use anyhow::Result;

#[netabase_definition_module(ChatDefinition, ChatKeys)]
mod chat {
    use super::*;
    use netabase_store::netabase;

    #[derive(
        NetabaseModel,
        Clone,
        Debug,
        bincode::Encode,
        bincode::Decode,
        serde::Serialize,
        serde::Deserialize,
    )]
    #[netabase(ChatDefinition)]
    pub struct Message {
        #[primary_key]
        pub id: String,
        pub author: String,
        pub content: String,
        pub timestamp: i64,
    }
}

use chat::*;

#[tokio::main]
async fn main() -> Result<()> {
    // Create netabase instance
    let mut netabase = Netabase::<ChatDefinition>::new_with_path("./chat_db")?;
    
    // Start the P2P network
    netabase.start_swarm().await?;
    println!("Network started!");
    
    // Create and publish a message
    let message = Message {
        id: "msg_1".to_string(),
        author: "Alice".to_string(),
        content: "Hello, World!".to_string(),
        timestamp: chrono::Utc::now().timestamp(),
    };
    
    netabase.put_record(message).await?;
    println!("Message published!");
    
    // Query local records
    let messages = netabase.query_local_records(None).await?;
    println!("Found {} messages", messages.len());
    
    // Subscribe to network events
    let mut events = netabase.subscribe_to_broadcasts();
    
    tokio::spawn(async move {
        while let Ok(event) = events.recv().await {
            if let libp2p::swarm::SwarmEvent::ConnectionEstablished { peer_id, .. } = &event.0 {
                println!("Connected to peer: {}", peer_id);
            }
        }
    });
    
    // Keep running...
    tokio::time::sleep(tokio::time::Duration::from_secs(60)).await;
    
    Ok(())
}
```

## Common Mistakes

### 1. Forgetting to import `netabase` attribute

**Error:**
```
error: cannot find attribute `netabase` in this scope
```

**Fix:** Add `use netabase_store::netabase;` inside your schema module.

### 2. Not starting the swarm

Your netabase instance won't connect to peers unless you call:
```rust
netabase.start_swarm().await?;
```

### 3. Missing tokio runtime

Netabase requires a tokio async runtime:
```rust
#[tokio::main]
async fn main() -> Result<()> {
    // your code
}
```

### 4. Incorrect event type imports

Use the re-exported types:
```rust
use netabase::NetabaseSwarmEvent;  // ✓ Correct
// NOT: use netabase::network::behaviour::clone_impl::NetabaseSwarmEvent;
```

## Network Configuration

### Custom Storage Backend

```rust
use netabase::network::config::{NetabaseConfig, StorageBackend};

let config = NetabaseConfig::with_backend(StorageBackend::Redb);
let netabase = Netabase::<ChatDefinition>::new_with_config(config)?;
```

### Peer Discovery

**Local Network (mDNS)**:
- Automatic on native platforms
- No configuration needed
- Works within the same LAN

**Global Network (DHT)**:
```rust
// Bootstrap to join the DHT network
netabase.bootstrap().await?;

// Add known peers manually
use libp2p::{Multiaddr, PeerId};
let peer_id: PeerId = "12D3KooW...".parse()?;
let addr: Multiaddr = "/ip4/192.168.1.100/tcp/4001".parse()?;
netabase.add_address(peer_id, addr).await?;
```

### DHT Modes

```rust
// Server mode (full participation, default)
netabase.set_mode(Some(libp2p::kad::Mode::Server)).await?;

// Client mode (lower resource usage, read-only DHT)
netabase.set_mode(Some(libp2p::kad::Mode::Client)).await?;
```

## Event Handling

### Subscribe to Network Events

```rust
let mut events = netabase.subscribe_to_broadcasts();

tokio::spawn(async move {
    while let Ok(event) = events.recv().await {
        match &event.0 {
            libp2p::swarm::SwarmEvent::ConnectionEstablished { peer_id, .. } => {
                println!("Connected: {}", peer_id);
            }
            libp2p::swarm::SwarmEvent::Behaviour(behaviour) => {
                // Handle Kad, mDNS, Identify events
                use netabase::NetabaseBehaviourEvent;
                match behaviour {
                    NetabaseBehaviourEvent::Mdns(mdns) => {
                        // mDNS peer discovery
                    }
                    NetabaseBehaviourEvent::Kad(kad) => {
                        // Kademlia DHT events
                    }
                    _ => {}
                }
            }
            _ => {}
        }
    }
});
```

### Multiple Subscribers

You can create multiple event subscribers:
```rust
let events1 = netabase.subscribe_to_broadcasts();
let events2 = netabase.subscribe_to_broadcasts();
let events3 = netabase.subscribe_to_broadcasts();
// Each receives events independently
```

## Next Steps

- Read [README.md]./README.md for complete API reference
- Check [ARCHITECTURE.md]./ARCHITECTURE.md to understand internals
- See [examples/simple_mdns_chat.rs]./examples/simple_mdns_chat.rs for a complete app
- Run the example: `cargo run --example simple_mdns_chat --features native`