fraiseql_functions/observer/
mod.rs1#[cfg(test)]
4mod tests;
5
6use std::{collections::HashMap, sync::Arc};
7
8use fraiseql_error::Result;
9
10use crate::{
11 HostContext,
12 runtime::FunctionRuntime,
13 types::{EventPayload, FunctionModule, FunctionResult, ResourceLimits, RuntimeType},
14};
15
16pub struct FunctionObserver {
22 runtimes: HashMap<RuntimeType, Arc<dyn std::any::Any + Send + Sync>>,
23}
24
25impl FunctionObserver {
26 #[must_use]
28 pub fn new() -> Self {
29 Self {
30 runtimes: HashMap::new(),
31 }
32 }
33
34 pub fn register_runtime<R: FunctionRuntime + 'static>(
40 &mut self,
41 runtime_type: RuntimeType,
42 runtime: R,
43 ) {
44 self.runtimes.insert(runtime_type, Arc::new(runtime));
45 }
46
47 pub async fn invoke<H>(
57 &self,
58 module: &FunctionModule,
59 #[allow(unused_variables)] event: EventPayload,
61 #[allow(unused_variables)] host: &H,
63 #[allow(unused_variables)] limits: ResourceLimits,
65 ) -> Result<FunctionResult>
66 where
67 H: HostContext + ?Sized,
68 {
69 #[allow(unused_variables)] let runtime_box = self.runtimes.get(&module.runtime).ok_or_else(|| {
71 fraiseql_error::FraiseQLError::Unsupported {
72 message: format!("No runtime registered for {:?}", module.runtime),
73 }
74 })?;
75
76 #[allow(unreachable_patterns)] match module.runtime {
79 RuntimeType::Wasm => {
80 #[cfg(feature = "runtime-wasm")]
81 {
82 let runtime = runtime_box
83 .downcast_ref::<crate::runtime::wasm::WasmRuntime>()
84 .ok_or_else(|| fraiseql_error::FraiseQLError::Unsupported {
85 message: "Invalid WASM runtime".to_string(),
86 })?;
87 runtime.invoke(module, event, host, limits).await
88 }
89 #[cfg(not(feature = "runtime-wasm"))]
90 {
91 Err(fraiseql_error::FraiseQLError::Unsupported {
92 message: "WASM runtime not enabled".to_string(),
93 })
94 }
95 },
96 RuntimeType::Deno => {
97 #[cfg(feature = "runtime-deno")]
98 {
99 let runtime = runtime_box
100 .downcast_ref::<crate::runtime::deno::DenoRuntime>()
101 .ok_or_else(|| fraiseql_error::FraiseQLError::Unsupported {
102 message: "Invalid Deno runtime".to_string(),
103 })?;
104 runtime.invoke(module, event, host, limits).await
105 }
106 #[cfg(not(feature = "runtime-deno"))]
107 {
108 Err(fraiseql_error::FraiseQLError::Unsupported {
109 message: "Deno runtime not enabled".to_string(),
110 })
111 }
112 },
113 }
114 }
115
116 #[must_use]
124 pub fn find_after_mutation_triggers(
125 &self,
126 registry: &crate::triggers::registry::TriggerRegistry,
127 event: &crate::triggers::mutation::EntityEvent,
128 ) -> Vec<crate::triggers::mutation::AfterMutationTrigger> {
129 registry.after_mutation_triggers.find(&event.entity, event.event_kind)
130 }
131}
132
133impl Default for FunctionObserver {
134 fn default() -> Self {
135 Self::new()
136 }
137}