Skip to main content

khive_pack_session/
pack.rs

1//! `SessionPack` self-registration factory and `PackRuntime` dispatch impl.
2
3use async_trait::async_trait;
4use serde_json::Value;
5
6use khive_runtime::pack::PackRuntime;
7use khive_runtime::{KhiveRuntime, NamespaceToken, RuntimeError, SchemaPlan, VerbRegistry};
8use khive_types::{EdgeEndpointRule, HandlerDef, Pack};
9
10use crate::{handlers, SessionPack, SESSION_HANDLERS};
11
12// ── inventory self-registration ───────────────────────────────────────────────
13
14struct SessionPackFactory;
15
16impl khive_runtime::PackFactory for SessionPackFactory {
17    fn name(&self) -> &'static str {
18        "session"
19    }
20
21    fn requires(&self) -> &'static [&'static str] {
22        &["kg"]
23    }
24
25    fn create(&self, runtime: KhiveRuntime) -> Box<dyn khive_runtime::PackRuntime> {
26        Box::new(SessionPack::new(runtime))
27    }
28}
29
30inventory::submit! { khive_runtime::PackRegistration(&SessionPackFactory) }
31
32// ── PackRuntime impl ──────────────────────────────────────────────────────────
33
34#[async_trait]
35impl PackRuntime for SessionPack {
36    fn name(&self) -> &str {
37        <SessionPack as Pack>::NAME
38    }
39
40    fn note_kinds(&self) -> &'static [&'static str] {
41        <SessionPack as Pack>::NOTE_KINDS
42    }
43
44    fn entity_kinds(&self) -> &'static [&'static str] {
45        <SessionPack as Pack>::ENTITY_KINDS
46    }
47
48    fn handlers(&self) -> &'static [HandlerDef] {
49        &SESSION_HANDLERS
50    }
51
52    fn edge_rules(&self) -> &'static [EdgeEndpointRule] {
53        &[]
54    }
55
56    fn requires(&self) -> &'static [&'static str] {
57        <SessionPack as Pack>::REQUIRES
58    }
59
60    fn schema_plan(&self) -> SchemaPlan {
61        SchemaPlan {
62            pack: "session",
63            statements: &crate::SESSION_SCHEMA_PLAN_STMTS,
64        }
65    }
66
67    async fn warm(&self) {
68        let config = crate::mirror::MirrorConfig::from_env();
69        if !config.enabled && !config.codex_enabled {
70            return;
71        }
72        let runtime = self.runtime().clone();
73        tokio::spawn(async move {
74            crate::mirror::run_mirror_service(runtime, config).await;
75        });
76    }
77
78    async fn dispatch(
79        &self,
80        verb: &str,
81        params: Value,
82        _registry: &VerbRegistry,
83        token: &NamespaceToken,
84    ) -> Result<Value, RuntimeError> {
85        let rt = self.runtime();
86        match verb {
87            "session.store" => handlers::store::handle_store(rt, token, params).await,
88            "session.list" => handlers::list::handle_list(rt, token, params).await,
89            "session.get" => handlers::get::handle_get(rt, token, params).await,
90            _ => Err(RuntimeError::InvalidInput(format!(
91                "session pack does not handle verb {verb:?}"
92            ))),
93        }
94    }
95}