a3s-flow 0.4.1

Durable workflow engine and Rust SDK for A3S
Documentation
use a3s_flow::{
    A3sFlowEventBridge, FlowEngine, FlowRuntime, LocalFileA3sFlowEventSink, RuntimeCommand,
    StepInvocation, WorkflowInvocation, WorkflowSpec,
};
use async_trait::async_trait;
use serde_json::json;
use std::sync::Arc;

struct AuditRuntime;

#[async_trait]
impl FlowRuntime for AuditRuntime {
    async fn run_workflow(
        &self,
        invocation: WorkflowInvocation,
    ) -> a3s_flow::Result<RuntimeCommand> {
        let ctx = invocation.context();
        if let Some(output) = ctx.step_output("build-report") {
            return Ok(ctx.complete(output.clone()));
        }

        Ok(ctx.schedule_step(
            "build-report",
            "build_report",
            json!({ "topic": ctx.input()["topic"] }),
        ))
    }

    async fn run_step(&self, invocation: StepInvocation) -> a3s_flow::Result<serde_json::Value> {
        Ok(json!({
            "title": format!("Report: {}", invocation.input["topic"].as_str().unwrap_or("unknown")),
            "ready": true,
        }))
    }
}

#[tokio::main(flavor = "current_thread")]
async fn main() -> a3s_flow::Result<()> {
    let dir = tempfile::tempdir()?;
    let audit_path = dir.path().join("audit/flow-events.jsonl");
    let sink = Arc::new(LocalFileA3sFlowEventSink::new(&audit_path));
    let observer = Arc::new(A3sFlowEventBridge::new(sink.clone()));
    let engine = FlowEngine::builder(Arc::new(AuditRuntime))
        .with_observer(observer)
        .build();
    let spec = WorkflowSpec::rust_embedded("examples.local-audit", "0.1.0", "examples", "main");

    let run_id = engine
        .start_with_id("local-audit-demo", spec, json!({ "topic": "A3S Flow" }))
        .await?;
    let snapshot = engine.snapshot(&run_id).await?;
    let events = sink.events().await?;

    println!("audit_log={}", audit_path.display());
    println!("status={:?}", snapshot.status);
    println!("audit_events={}", events.len());
    println!("first_event={}", events.first().unwrap().key);
    println!("last_event={}", events.last().unwrap().key);
    println!("last_error={:?}", sink.last_error().await);
    Ok(())
}