331 lines
8.8 KiB
Markdown
331 lines
8.8 KiB
Markdown
# Architecture of the `rhailib_engine` Crate
|
|
|
|
The `rhailib_engine` crate serves as the central Rhai scripting engine for the heromodels ecosystem. It provides a unified interface for creating, configuring, and executing Rhai scripts with access to all business domain modules through a feature-based architecture.
|
|
|
|
## Core Architecture
|
|
|
|
The engine acts as an orchestration layer that brings together the DSL modules and provides execution utilities:
|
|
|
|
```mermaid
|
|
graph TD
|
|
A[rhailib_engine] --> B[Engine Creation]
|
|
A --> C[Script Execution]
|
|
A --> D[Mock Database]
|
|
A --> E[Feature Management]
|
|
|
|
B --> B1[create_heromodels_engine]
|
|
B --> B2[Engine Configuration]
|
|
B --> B3[DSL Registration]
|
|
|
|
C --> C1[eval_script]
|
|
C --> C2[eval_file]
|
|
C --> C3[compile_script]
|
|
C --> C4[run_ast]
|
|
|
|
D --> D1[create_mock_db]
|
|
D --> D2[seed_mock_db]
|
|
D --> D3[Domain Data Seeding]
|
|
|
|
E --> E1[calendar]
|
|
E --> E2[finance]
|
|
E --> E3[flow]
|
|
E --> E4[legal]
|
|
E --> E5[projects]
|
|
E --> E6[biz]
|
|
|
|
B3 --> F[rhailib_dsl]
|
|
F --> G[All Domain Modules]
|
|
```
|
|
|
|
## Core Components
|
|
|
|
### 1. Engine Factory (`create_heromodels_engine`)
|
|
|
|
The primary entry point for creating a fully configured Rhai engine:
|
|
|
|
```rust
|
|
pub fn create_heromodels_engine() -> Engine
|
|
```
|
|
|
|
**Responsibilities:**
|
|
- Creates a new Rhai engine instance
|
|
- Configures engine limits and settings
|
|
- Registers all available DSL modules
|
|
- Returns a ready-to-use engine
|
|
|
|
**Configuration Settings:**
|
|
- **Expression Depth**: 128 levels for both expressions and functions
|
|
- **String Size Limit**: 10 MB maximum string size
|
|
- **Array Size Limit**: 10,000 elements maximum
|
|
- **Map Size Limit**: 10,000 key-value pairs maximum
|
|
|
|
### 2. Script Execution Utilities
|
|
|
|
#### Direct Script Evaluation
|
|
```rust
|
|
pub fn eval_script(engine: &Engine, script: &str) -> Result<Dynamic, Box<EvalAltResult>>
|
|
```
|
|
Executes Rhai script strings directly with immediate results.
|
|
|
|
#### File-Based Script Execution
|
|
```rust
|
|
pub fn eval_file(engine: &Engine, file_path: &Path) -> Result<Dynamic, Box<EvalAltResult>>
|
|
```
|
|
Loads and executes Rhai scripts from filesystem with proper error handling.
|
|
|
|
#### Compiled Script Execution
|
|
```rust
|
|
pub fn compile_script(engine: &Engine, script: &str) -> Result<AST, Box<EvalAltResult>>
|
|
pub fn run_ast(engine: &Engine, ast: &AST, scope: &mut Scope) -> Result<Dynamic, Box<EvalAltResult>>
|
|
```
|
|
Provides compilation and execution of scripts for performance optimization.
|
|
|
|
### 3. Mock Database System
|
|
|
|
#### Database Creation
|
|
```rust
|
|
pub fn create_mock_db() -> Arc<OurDB>
|
|
```
|
|
Creates an in-memory database instance for testing and examples.
|
|
|
|
#### Data Seeding
|
|
```rust
|
|
pub fn seed_mock_db(db: Arc<OurDB>)
|
|
```
|
|
Populates the mock database with representative data across all domains.
|
|
|
|
## Feature-Based Architecture
|
|
|
|
The engine uses Cargo features to control which domain modules are included:
|
|
|
|
### Available Features
|
|
|
|
- **`calendar`** (default): Calendar and event management
|
|
- **`finance`** (default): Financial accounts, assets, and marketplace
|
|
- **`flow`**: Workflow and approval processes
|
|
- **`legal`**: Contract and legal document management
|
|
- **`projects`**: Project and task management
|
|
- **`biz`**: Business operations and entities
|
|
|
|
### Feature Integration Pattern
|
|
|
|
```rust
|
|
#[cfg(feature = "calendar")]
|
|
use heromodels::models::calendar::*;
|
|
|
|
#[cfg(feature = "finance")]
|
|
use heromodels::models::finance::*;
|
|
```
|
|
|
|
This allows for:
|
|
- **Selective Compilation**: Only include needed functionality
|
|
- **Reduced Binary Size**: Exclude unused domain modules
|
|
- **Modular Deployment**: Different configurations for different use cases
|
|
|
|
## Mock Database Architecture
|
|
|
|
### Database Structure
|
|
|
|
The mock database provides a complete testing environment:
|
|
|
|
```mermaid
|
|
graph LR
|
|
A[Mock Database] --> B[Calendar Data]
|
|
A --> C[Finance Data]
|
|
A --> D[Flow Data]
|
|
A --> E[Legal Data]
|
|
A --> F[Projects Data]
|
|
|
|
B --> B1[Calendars]
|
|
B --> B2[Events]
|
|
B --> B3[Attendees]
|
|
|
|
C --> C1[Accounts]
|
|
C --> C2[Assets - ERC20/ERC721]
|
|
C --> C3[Marketplace Listings]
|
|
|
|
D --> D1[Flows]
|
|
D --> D2[Flow Steps]
|
|
D --> D3[Signature Requirements]
|
|
|
|
E --> E1[Contracts]
|
|
E --> E2[Contract Revisions]
|
|
E --> E3[Contract Signers]
|
|
|
|
F --> F1[Projects]
|
|
F --> F2[Project Members]
|
|
F --> F3[Project Tags]
|
|
```
|
|
|
|
### Seeding Strategy
|
|
|
|
Each domain has its own seeding function that creates realistic test data:
|
|
|
|
#### Calendar Seeding
|
|
- Creates work calendars with descriptions
|
|
- Adds team meetings with attendees
|
|
- Sets up recurring events
|
|
|
|
#### Finance Seeding
|
|
- Creates demo trading accounts
|
|
- Generates ERC20 tokens and ERC721 NFTs
|
|
- Sets up marketplace listings with metadata
|
|
|
|
#### Flow Seeding (Feature-Gated)
|
|
- Creates document approval workflows
|
|
- Defines multi-step approval processes
|
|
- Sets up signature requirements
|
|
|
|
#### Legal Seeding (Feature-Gated)
|
|
- Creates service agreements
|
|
- Adds contract revisions and versions
|
|
- Defines contract signers and roles
|
|
|
|
#### Projects Seeding (Feature-Gated)
|
|
- Creates project instances with status tracking
|
|
- Assigns team members and priorities
|
|
- Adds project tags and categorization
|
|
|
|
## Error Handling Architecture
|
|
|
|
### Comprehensive Error Propagation
|
|
|
|
```rust
|
|
Result<Dynamic, Box<EvalAltResult>>
|
|
```
|
|
|
|
All functions return proper Rhai error types that include:
|
|
- **Script Compilation Errors**: Syntax and parsing issues
|
|
- **Runtime Errors**: Execution failures and exceptions
|
|
- **File System Errors**: File reading and path resolution issues
|
|
- **Database Errors**: Mock database operation failures
|
|
|
|
### Error Context Enhancement
|
|
|
|
File operations include enhanced error context:
|
|
```rust
|
|
Err(Box::new(EvalAltResult::ErrorSystem(
|
|
format!("Failed to read script file: {}", file_path.display()),
|
|
Box::new(io_err),
|
|
)))
|
|
```
|
|
|
|
## Performance Considerations
|
|
|
|
### Engine Configuration
|
|
|
|
Optimized settings for production use:
|
|
- **Memory Limits**: Prevent runaway script execution
|
|
- **Depth Limits**: Avoid stack overflow from deep recursion
|
|
- **Size Limits**: Control memory usage for large data structures
|
|
|
|
### Compilation Strategy
|
|
|
|
- **AST Caching**: Compile once, execute multiple times
|
|
- **Scope Management**: Efficient variable scope handling
|
|
- **Module Registration**: One-time registration at engine creation
|
|
|
|
### Mock Database Performance
|
|
|
|
- **In-Memory Storage**: Fast access for testing scenarios
|
|
- **Temporary Directories**: Automatic cleanup after use
|
|
- **Lazy Loading**: Data seeded only when needed
|
|
|
|
## Integration Patterns
|
|
|
|
### Script Development Workflow
|
|
|
|
```rust
|
|
// 1. Create engine with all modules
|
|
let engine = create_heromodels_engine();
|
|
|
|
// 2. Execute business logic scripts
|
|
let result = eval_script(&engine, r#"
|
|
let company = new_company()
|
|
.name("Tech Startup")
|
|
.business_type("startup");
|
|
save_company(company)
|
|
"#)?;
|
|
|
|
// 3. Handle results and errors
|
|
match result {
|
|
Ok(value) => println!("Success: {:?}", value),
|
|
Err(error) => eprintln!("Error: {}", error),
|
|
}
|
|
```
|
|
|
|
### Testing Integration
|
|
|
|
```rust
|
|
// 1. Create mock database
|
|
let db = create_mock_db();
|
|
seed_mock_db(db.clone());
|
|
|
|
// 2. Create engine
|
|
let engine = create_heromodels_engine();
|
|
|
|
// 3. Test scripts against seeded data
|
|
let script = r#"
|
|
let calendars = list_calendars();
|
|
calendars.len()
|
|
"#;
|
|
let count = eval_script(&engine, script)?;
|
|
```
|
|
|
|
### File-Based Script Execution
|
|
|
|
```rust
|
|
// Execute scripts from files
|
|
let result = eval_file(&engine, Path::new("scripts/business_logic.rhai"))?;
|
|
```
|
|
|
|
## Deployment Configurations
|
|
|
|
### Minimal Configuration
|
|
```toml
|
|
[dependencies]
|
|
rhailib_engine = { version = "0.1.0", default-features = false, features = ["calendar"] }
|
|
```
|
|
|
|
### Full Configuration
|
|
```toml
|
|
[dependencies]
|
|
rhailib_engine = { version = "0.1.0", features = ["calendar", "finance", "flow", "legal", "projects", "biz"] }
|
|
```
|
|
|
|
### Custom Configuration
|
|
```toml
|
|
[dependencies]
|
|
rhailib_engine = { version = "0.1.0", default-features = false, features = ["finance", "biz"] }
|
|
```
|
|
|
|
## Security Considerations
|
|
|
|
### Script Execution Limits
|
|
- **Resource Limits**: Prevent resource exhaustion attacks
|
|
- **Execution Time**: Configurable timeouts for long-running scripts
|
|
- **Memory Bounds**: Controlled memory allocation
|
|
|
|
### Database Access
|
|
- **Mock Environment**: Safe testing without production data exposure
|
|
- **Temporary Storage**: Automatic cleanup prevents data persistence
|
|
- **Isolated Execution**: Each test run gets fresh database state
|
|
|
|
## Extensibility
|
|
|
|
### Adding New Domains
|
|
1. Create new feature flag in `Cargo.toml`
|
|
2. Add conditional imports for new models
|
|
3. Implement seeding function for test data
|
|
4. Register with DSL module system
|
|
|
|
### Custom Engine Configuration
|
|
```rust
|
|
let mut engine = Engine::new();
|
|
// Custom configuration
|
|
engine.set_max_expr_depths(256, 256);
|
|
// Register specific modules
|
|
rhailib_dsl::register_dsl_modules(&mut engine);
|
|
```
|
|
|
|
This architecture provides a robust, feature-rich foundation for Rhai script execution while maintaining flexibility, performance, and security. |