Skip to main content

fraiseql_functions/runtime/
mod.rs

1//! Function runtime trait and implementations.
2
3#[cfg(feature = "runtime-wasm")]
4pub mod wasm;
5
6#[cfg(feature = "runtime-deno")]
7pub mod deno;
8
9use std::future::Future;
10
11use async_trait::async_trait;
12use fraiseql_error::Result;
13
14use crate::{
15    HostContext,
16    types::{EventPayload, FunctionModule, FunctionResult, ResourceLimits},
17};
18
19/// Trait for function execution backends (WASM, Deno, etc.).
20///
21/// Implementors provide the ability to load and execute function modules
22/// with resource limits enforced. This trait uses native async for zero-cost
23/// abstraction on hot paths.
24pub trait FunctionRuntime: Send + Sync {
25    /// Execute a function module with the given event and host context.
26    ///
27    /// # Errors
28    ///
29    /// Returns `Err` if:
30    /// - The module cannot be loaded or parsed
31    /// - Execution raises an error (runtime error, timeout, memory limit exceeded)
32    /// - The host context raises an error
33    fn invoke<H>(
34        &self,
35        module: &FunctionModule,
36        event: EventPayload,
37        host: &H,
38        limits: ResourceLimits,
39    ) -> impl Future<Output = Result<FunctionResult>> + Send
40    where
41        H: HostContext + ?Sized;
42
43    /// Get the list of file extensions this runtime supports.
44    fn supported_extensions(&self) -> &[&str];
45
46    /// Check if this runtime supports hot-reloading modules without restart.
47    fn supports_hot_reload(&self) -> bool;
48
49    /// Get the name of this runtime (e.g., "wasm", "deno").
50    fn name(&self) -> &str;
51}
52
53/// Type alias for a boxable function runtime (with static lifetime bounds).
54/// Used for dynamic dispatch where concrete types aren't known at compile time.
55pub type BoxedFunctionRuntime = Box<dyn FunctionRuntime + Send + Sync>;
56
57/// Object-safe variant of `FunctionRuntime` for dynamic dispatch.
58///
59/// This trait has the same semantic methods but without generic parameters,
60/// making it suitable for `Arc<dyn SendFunctionRuntime>`. The `invoke_raw`
61/// method uses a [`NoopHostContext`](crate::NoopHostContext) internally.
62#[async_trait]
63pub trait SendFunctionRuntime: Send + Sync {
64    /// Execute a function module with the given event and resource limits.
65    ///
66    /// Uses [`NoopHostContext`](crate::NoopHostContext) — callers that need
67    /// host-bridge functionality should use [`FunctionRuntime::invoke`] with
68    /// a concrete host context instead.
69    ///
70    /// # Errors
71    ///
72    /// Returns `Err` if the module cannot be loaded, or execution fails.
73    async fn invoke_raw(
74        &self,
75        module: &FunctionModule,
76        event: EventPayload,
77        limits: ResourceLimits,
78    ) -> Result<FunctionResult>;
79
80    /// Get the list of file extensions this runtime supports.
81    fn supported_extensions(&self) -> &[&str];
82
83    /// Check if this runtime supports hot-reloading modules without restart.
84    fn supports_hot_reload(&self) -> bool;
85
86    /// Get the name of this runtime (e.g., "wasm", "deno").
87    fn name(&self) -> &str;
88}