Skip to main content

aimdb_core/transform/
mod.rs

1//! Reactive transform primitives for derived records.
2//!
3//! # Transform Archetypes
4//!
5//! - **Map** (1:1, stateless): Transform each input value to zero-or-one output value
6//! - **Accumulate** (N:1, stateful): Aggregate a stream of values with persistent state
7//! - **Join** (M×N:1, stateful, multi-input): Combine values from multiple input records
8//!
9//! All three are handled by a unified API surface:
10//! - Single-input: `.transform()` with `TransformBuilder`
11//! - Multi-input: `.transform_join()` with `JoinBuilder`
12
13use core::any::Any;
14use core::fmt::Debug;
15
16use alloc::{boxed::Box, string::String, sync::Arc, vec::Vec};
17
18use crate::typed_record::BoxFuture;
19
20pub mod join;
21pub mod single;
22
23// Public re-exports
24pub use single::{StatefulTransformBuilder, TransformBuilder, TransformPipeline};
25
26#[cfg(feature = "alloc")]
27pub use join::{JoinBuilder, JoinEventRx, JoinPipeline, JoinTrigger};
28
29// ============================================================================
30// TransformDescriptor — stored per output record in TypedRecord
31// ============================================================================
32
33pub(crate) struct TransformDescriptor<T, R: aimdb_executor::Spawn + 'static>
34where
35    T: Send + 'static + Debug + Clone,
36{
37    pub input_keys: Vec<String>,
38
39    #[allow(clippy::type_complexity)]
40    pub spawn_fn: Box<
41        dyn FnOnce(
42                crate::Producer<T, R>,
43                Arc<crate::AimDb<R>>,
44                Arc<dyn Any + Send + Sync>,
45            ) -> BoxFuture<'static, ()>
46            + Send,
47    >,
48}