use super::super::ActModule;
use crate::{ActError, Context, Result, Vars, env::value::ActJsValue};
use rquickjs::{CatchResultExt, Module as JsModule};
pub struct ActJsModule;
impl ActJsModule {
pub fn new() -> Self {
Self
}
pub fn vars(&self) -> Option<Vars> {
if let Ok(ctx) = Context::current() {
return Some(ctx.task().vars());
}
None
}
}
#[allow(clippy::module_inception)]
#[rquickjs::module(rename_vars = "camelCase")]
mod act {
use crate::{
Context, TimeoutLimit, Vars,
env::value::ActJsValue,
utils::{self, consts},
};
#[rquickjs::function]
pub fn get_act_value(name: String) -> Option<ActJsValue> {
Context::with(|ctx| {
if let Some(v) = ctx.task().find(&name) {
let v = ActJsValue::new(v);
return Some(v);
}
None
})
}
#[rquickjs::function]
pub fn set_act_value(name: String, value: ActJsValue) {
Context::with(|ctx| {
let vars = Vars::new().with(&name, value.inner());
ctx.task().update_data(&vars);
})
}
#[rquickjs::function]
pub fn set_process_var(name: String, value: ActJsValue) {
Context::with(|ctx| {
let vars = Vars::new().with(&name, value.inner());
ctx.proc.set_data(&vars);
})
}
#[rquickjs::function]
pub fn get_act_inputs() -> ActJsValue {
Context::with(|ctx| ctx.task().inputs().into())
}
#[rquickjs::function]
pub fn get_act_data() -> ActJsValue {
Context::with(|ctx| ctx.task().data().into())
}
#[rquickjs::function]
pub fn err_code() -> Option<String> {
Context::with(|ctx| ctx.task().data().get::<String>(consts::ACT_ERR_CODE))
}
#[rquickjs::function]
pub fn cost() -> i64 {
Context::with(|ctx| {
if let Some(cost) = ctx.task().data().get::<i64>(consts::TASK_COST) {
return cost;
}
ctx.task().cost()
})
}
#[rquickjs::function]
pub fn cost_in(value: String) -> bool {
Context::with(|ctx| {
let mut cost = utils::time::time_millis() - ctx.task().start_time();
if let Some(v) = ctx.task().data().get::<i64>(consts::TASK_COST) {
cost = v;
}
let on = TimeoutLimit::parse(&value).unwrap_or_default();
cost >= on.as_secs() * 1000
})
}
}
impl ActModule for ActJsModule {
fn init(&self, ctx: &rquickjs::Ctx<'_>) -> Result<()> {
JsModule::declare_def::<js_act, _>(ctx.clone(), "@acts/act").unwrap();
if let Some(vars) = self.vars() {
for (key, value) in &vars {
ctx.globals().set(&key, ActJsValue::new(value))?;
}
}
let source = r#"
import { get_act_value, set_act_value, set_process_var, get_act_inputs, get_act_data, err_code, cost, cost_in } from '@acts/act';
globalThis.$get = get_act_value;
globalThis.$set = set_act_value;
globalThis.$inputs = get_act_inputs;
globalThis.$data = get_act_data;
globalThis.$set_process_var = set_process_var;
globalThis.$ecode = err_code;
globalThis.$cost = cost
globalThis.$cost_in = cost_in
"#;
let _ = JsModule::evaluate(ctx.clone(), "@acts/act", source)
.catch(ctx)
.map_err(|err| ActError::Script(err.to_string()))?;
Ok(())
}
}