Refactor Rhai integration with context-based execution and type registry
Major Changes:
- Moved Rhai support from rhai_support/ to rhai/ module
- Implemented context-based execution with signatory access control
- Added TypeRegistry for dynamic type registration and object creation
- Refactored engine to use context (Vec<String>) instead of instance
- Removed old runner binary (moved to runner_rust crate)
Rhai Module:
- engine.rs: Core Rhai engine with context-based get_context()
- functions.rs: Rhai function bindings (create_note, create_event, etc.)
- mod.rs: Module exports and organization
Store Improvements:
- TypeRegistry for registering object types and creators
- Generic store uses type registry for dynamic object creation
- Improved error handling and type safety
Documentation:
- RHAI_REFACTOR_COMPLETE.md: Refactoring details
- SIGNATORY_ACCESS_CONTROL.md: Context-based access control
- TYPE_REGISTRY_DESIGN.md: Type registry architecture
- REFACTORING_COMPLETE.md: Overall refactoring summary
- TESTS_COMPLETE.md: Testing documentation
Build Status: ✅ Compiles successfully with minor warnings
This commit is contained in:
93
TYPE_REGISTRY_DESIGN.md
Normal file
93
TYPE_REGISTRY_DESIGN.md
Normal file
@@ -0,0 +1,93 @@
|
||||
# OSIRIS Type Registry Design
|
||||
|
||||
## Problem
|
||||
|
||||
We need applications (like ZDFZ API) to register custom types with OSIRIS so that:
|
||||
1. The `save()` method can use the correct struct type instead of hardcoding `Note`
|
||||
2. Each collection name maps to a specific Rust type
|
||||
3. The type system properly deserializes, indexes, and stores data
|
||||
|
||||
## Challenge
|
||||
|
||||
The `Object` trait is not "dyn compatible" (object-safe) because it has:
|
||||
- Associated functions (`object_type()`, `from_json()`)
|
||||
- Generic methods
|
||||
- Serialize/Deserialize bounds
|
||||
|
||||
This means we **cannot** use `Box<dyn Object>` for dynamic dispatch.
|
||||
|
||||
## Solution: Type Registry with Callbacks
|
||||
|
||||
Instead of trying to return `Box<dyn Object>`, we use a callback-based approach:
|
||||
|
||||
```rust
|
||||
pub struct TypeRegistry {
|
||||
// For each collection, store a function that:
|
||||
// 1. Takes JSON string
|
||||
// 2. Deserializes to the correct type
|
||||
// 3. Stores it using GenericStore
|
||||
// 4. Returns the ID
|
||||
savers: HashMap<String, Box<dyn Fn(&GenericStore, &str, &str) -> Result<()>>>,
|
||||
}
|
||||
```
|
||||
|
||||
### Usage in ZDFZ API:
|
||||
|
||||
```rust
|
||||
// Create registry
|
||||
let registry = TypeRegistry::new();
|
||||
|
||||
// Register Resident type
|
||||
registry.register_saver("residents", |store, id, json| {
|
||||
let mut resident: Resident = serde_json::from_str(json)?;
|
||||
resident.set_id(id);
|
||||
store.put(&resident).await
|
||||
});
|
||||
|
||||
// Register Company type
|
||||
registry.register_saver("companies", |store, id, json| {
|
||||
let mut company: Company = serde_json::from_str(json)?;
|
||||
company.set_id(id);
|
||||
store.put(&company).await
|
||||
});
|
||||
|
||||
// Create OSIRIS context with registry
|
||||
let ctx = OsirisContext::new_with_registry(
|
||||
"my_context",
|
||||
"owner_id",
|
||||
herodb_url,
|
||||
db_id,
|
||||
Some(Arc::new(registry))
|
||||
);
|
||||
|
||||
// Now save() uses the registered type!
|
||||
ctx.save("residents", "id123", resident_json)?;
|
||||
```
|
||||
|
||||
### Benefits:
|
||||
|
||||
✅ **Type-safe** - Each collection uses its proper Rust type
|
||||
✅ **Flexible** - Applications register their own types
|
||||
✅ **No trait object issues** - Uses closures instead of `Box<dyn Object>`
|
||||
✅ **Proper indexing** - Each type's `index_keys()` method is called
|
||||
✅ **Clean API** - Simple registration interface
|
||||
|
||||
## Implementation Plan:
|
||||
|
||||
1. ✅ Create `TypeRegistry` with callback-based savers
|
||||
2. ✅ Add `set_registry()` to `GenericStore`
|
||||
3. ✅ Update `OsirisContext::save()` to use registry if available
|
||||
4. ✅ Fall back to `Note` if no registry or collection not registered
|
||||
5. Document usage for ZDFZ API
|
||||
|
||||
## Next Steps:
|
||||
|
||||
The type registry infrastructure is in place. Now ZDFZ API can:
|
||||
1. Create a `TypeRegistry`
|
||||
2. Register all SDK model types
|
||||
3. Pass registry when creating OSIRIS contexts
|
||||
4. Use generic `save()` method with proper types!
|
||||
|
||||
---
|
||||
|
||||
**Status:** Design complete, ready for implementation with callback approach.
|
||||
Reference in New Issue
Block a user