mirror of
https://github.com/gorules/zen.git
synced 2026-10-05 00:02:26 +00:00
feat: custom node (#138)
* feat: custom node * add zen template, expose $nodes and $root * add custom handler to go and nodejs * add support for python, improve bindings, add error to zen template * fix: correct binding exports for nodejs and python * fix benchmark * improve rust api, trim template in zen templates * update cargo action * update expression version * compile action * fix action format
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
use crate::custom_node::CustomNode;
|
||||
use crate::decision::ZenDecision;
|
||||
use crate::loader::DecisionLoader;
|
||||
use crate::types::ZenEngineResponse;
|
||||
use napi::anyhow::{anyhow, Context};
|
||||
use napi::bindgen_prelude::Buffer;
|
||||
use napi::{tokio, Env, JsFunction};
|
||||
@@ -11,7 +13,7 @@ use zen_engine::{DecisionEngine, EvaluationOptions};
|
||||
|
||||
#[napi]
|
||||
pub struct ZenEngine {
|
||||
graph: Arc<DecisionEngine<DecisionLoader>>,
|
||||
graph: Arc<DecisionEngine<DecisionLoader, CustomNode>>,
|
||||
}
|
||||
|
||||
#[napi(object)]
|
||||
@@ -33,6 +35,9 @@ impl Default for ZenEvaluateOptions {
|
||||
pub struct ZenEngineOptions {
|
||||
#[napi(ts_type = "(key: string) => Promise<Buffer>")]
|
||||
pub loader: Option<JsFunction>,
|
||||
|
||||
#[napi(ts_type = "(request: ZenEngineHandlerRequest) => Promise<ZenEngineHandlerResponse>")]
|
||||
pub custom_handler: Option<JsFunction>,
|
||||
}
|
||||
|
||||
#[napi]
|
||||
@@ -41,18 +46,26 @@ impl ZenEngine {
|
||||
pub fn new(mut env: Env, options: Option<ZenEngineOptions>) -> napi::Result<Self> {
|
||||
let Some(opts) = options else {
|
||||
return Ok(Self {
|
||||
graph: DecisionEngine::new(DecisionLoader::default()).into(),
|
||||
graph: DecisionEngine::new(
|
||||
DecisionLoader::default().into(),
|
||||
CustomNode::default().into(),
|
||||
)
|
||||
.into(),
|
||||
});
|
||||
};
|
||||
|
||||
let Some(loader_fn) = opts.loader else {
|
||||
return Ok(Self {
|
||||
graph: DecisionEngine::new(DecisionLoader::default()).into(),
|
||||
});
|
||||
let loader = match opts.loader {
|
||||
None => DecisionLoader::default(),
|
||||
Some(loader_fn) => DecisionLoader::try_new(&mut env, loader_fn)?,
|
||||
};
|
||||
|
||||
let custom_handler = match opts.custom_handler {
|
||||
None => CustomNode::default(),
|
||||
Some(custom_fn) => CustomNode::try_new(&mut env, custom_fn)?,
|
||||
};
|
||||
|
||||
Ok(Self {
|
||||
graph: DecisionEngine::new(DecisionLoader::try_new(&mut env, loader_fn)?).into(),
|
||||
graph: DecisionEngine::new(loader.into(), custom_handler.into()).into(),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -62,7 +75,7 @@ impl ZenEngine {
|
||||
key: String,
|
||||
context: Value,
|
||||
opts: Option<ZenEvaluateOptions>,
|
||||
) -> napi::Result<Value> {
|
||||
) -> napi::Result<ZenEngineResponse> {
|
||||
let graph = self.graph.clone();
|
||||
let result = tokio::spawn(async move {
|
||||
let options = opts.unwrap_or_default();
|
||||
@@ -82,7 +95,7 @@ impl ZenEngine {
|
||||
anyhow!(serde_json::to_string(e.as_ref()).unwrap_or_else(|_| e.to_string()))
|
||||
})?;
|
||||
|
||||
Ok(serde_json::to_value(&result)?)
|
||||
Ok(ZenEngineResponse::from(result))
|
||||
}
|
||||
|
||||
#[napi]
|
||||
|
||||
Reference in New Issue
Block a user