//! # Ankurah
//!
//! <div style="display:flex; background:linear-gradient(0deg, rgba(112,182,255,1) 0%, rgba(200,200,255,1) 100%); padding: 8px; margin: -15px 0 10px 0">
//! <img
//!  src="data:image/png;base64,[encoded data, 28108 characters]"
//!  alt="Ankurah Logo" width=64 height=64
//!  style=""
//! />
//! <div style="margin: auto 0 auto 5px">The root of all cosmic projections of state</div>
//! </div>
//!
//!
//! Ankurah is a state-management framework that enables real-time
//! data synchronization across multiple nodes with built-in observability.
//!
//! It supports multiple storage and data type backends to enable no-compromise representation of your data.
//!
//! This project is in the early stages of development, and is not yet ready for production use.
//!
//! ## Key Features
//!
//! - **Schema-First Design**: Define data models using Rust structs with an ActiveRecord-style interface - [View](Model::View)/[Mutable](Model::Mutable)
//! - **Content-filtered pub/sub**: Subscribe to changes on a collection using a SQL-like query - [subscribe](Node::subscribe)
//! - **Real-Time Observability**: Signal-based pattern for tracking entity changes
//! - **Distributed Architecture**: Multi-node synchronization with event sourcing
//! - **Flexible Storage**: Support for multiple storage backends (Sled, Postgres, TiKV)
//! - **Isomorphic code**: Server applications and Web applications use the same code, including first-class support for React and Leptos out of the box
//!
//! ## Core Concepts
//!
//! - **Model**: A struct describing fields and types for entities in a collection (data binding)
//! - **Collection**: A group of entities of the same type (similar to a database table, and backed by a table in the postgres backend)
//! - **Entity**: A discrete identity in a collection - Dynamic schema (similar to a schema-less database row)
//! - **View**: A read-only representation of an entity - Typed by the model
//! - **Mutable**: A mutable state representation of an entity - Typed by the model
//! - **Event**: An atomic change that can be applied to an entity - used for syncrhonization and audit trail
//!
//! ## Quick Start
//!
//! 1. Start the server:
//! ```bash
//! cargo run -p ankurah-example-server
//!
//! # or dev mode
//! cargo watch -x 'run -p ankurah-example-server'
//! ```
//!
//! 2. Build WASM bindings:
//! ```bash
//! cd examples/wasm-bindings
//! wasm-pack build --target web --debug
//!
//! # or dev mode
//! cargo watch -s 'wasm-pack build --target web --debug'
//! ```
//!
//! 3. Run the React example app:
//! ```bash
//! cd examples/react-app
//! bun install
//! bun dev
//! ```
//!
//! Then load http://localhost:5173/ in one regular browser tab, and one incognito browser tab and play with the example app.
//! You can also use two regular browser tabs, but they share one IndexedDB local storage backend, so it's not as good of a test.
//! In this example, the "server" process is a native Rust process whose node is flagged as "durable", meaning that it attests it
//! will not lose data. The "client" process is a WASM process that is also durable in some sense, but not to be relied upon to have
//! all data. The demo server currently uses the sled backend, but postgres is also supported, and TiKV support is planned.
//!
//! ## Example: Inter-Node Subscription
//!
//! ```rust
//! # #[cfg(feature="derive")]
//! # mod doctest {
//! # use ankurah::{Node,Model};
//! # use ankurah_storage_sled::SledStorageEngine;
//! # use ankurah_connector_local_process::LocalProcessConnection;
//! # use std::sync::Arc;
//! # use serde::{Serialize, Deserialize};
//! #[derive(Model, Debug, Serialize, Deserialize)]
//! pub struct Album {
//!     name: String,
//!     year: String,
//! }
//! #
//! # #[tokio::main]
//! # async fn main() -> Result<(), Box<dyn std::error::Error>> {
//!     // Create server and client nodes
//!     let server = Node::new_durable(Arc::new(SledStorageEngine::new_test()?), ankurah::policy::PermissiveAgent::new());
//!     server.system.create().await?;
//!     let client = Node::new(Arc::new(SledStorageEngine::new_test()?), ankurah::policy::PermissiveAgent::new());
//!
//!     // Connect nodes using local process connection
//!     let _conn = LocalProcessConnection::new(&server, &client).await?;
//!     client.system.wait_system_ready().await; // Wait for the client to join the server "system"
//!
//!     // Get contexts for the server and client
//!     let server = server.context(ankurah::policy::DEFAULT_CONTEXT)?;
//!     let client = client.context(ankurah::policy::DEFAULT_CONTEXT)?;
//!
//!     // Create a LiveQuery and subscribe to changes on the client
//!     let livequery = client.query::<AlbumView>("name = 'Origin of Symmetry'")?;
//!     use ankurah::signals::Subscribe;
//!     let _guard = livequery.subscribe(|changes| {
//!         println!("Received changes: {}", changes);
//!     });
//!
//!     // Create a new album on the server
//!     let trx = server.begin();
//!     trx.create(&Album {
//!         name: "Origin of Symmetry".into(),
//!         year: "2001".into(),
//!     }).await;
//!     trx.commit().await?;
//!
//!     Ok(())
//! }
//! # }
//! ```
//!
//! ## Design Philosophy
//!
//! Ankurah follows an event-sourced architecture where:
//! - All operations have unique IDs and precursor operations
//! - Entity state is maintained per node with operation tree tracking
//! - Operations use ULID for distributed ID generation
//! - Entity IDs are derived from their creation operation
//!
//! For more details, see the [repository documentation](https://github.com/ankurah/ankurah).
//! And join the [Discord server](https://discord.gg/XMUUxsbT5S) to be part of the discussion!

pub use ankql;
pub use ankurah_core as core;
#[cfg(feature = "derive")]
pub use ankurah_derive as derive;
pub use ankurah_proto as proto;
pub use ankurah_signals as signals;

pub use proto::EntityId;
// Re-export commonly used types
pub use ankurah_core::{
    changes,
    context::Context,
    entity, error,
    livequery::LiveQuery,
    model,
    model::View,
    model::{Model, Mutable},
    node::{MatchArgs, Node},
    policy::{self, PermissiveAgent},
    property::{self, Property, Ref},
    resultset::ResultSet,
    storage, transaction, value,
    value::{Value, ValueType},
};

// Re-export the derive macro
#[cfg(feature = "derive")]
pub use ankurah_derive::*;

// Re-export macros for ergonomic entity creation
pub use ankurah_core::{create, into};

// Re-export dependencies needed by derive macros
#[cfg(feature = "derive")]
#[doc(hidden)]
pub mod derive_deps {
    #[cfg(feature = "wasm")]
    pub use ::js_sys;
    #[cfg(feature = "wasm")]
    pub use ::send_wrapper;
    pub use ::tracing;
    #[cfg(feature = "wasm")]
    pub use ::wasm_bindgen;
    #[cfg(feature = "wasm")]
    pub use ::wasm_bindgen_futures;

    pub use ::serde;
    pub use ::serde_json;
}
