Skip to main content

greentic_runner_host/
component_api.rs

1pub mod v0_4 {
2    wasmtime::component::bindgen!({
3        inline: r#"
4        package greentic:component@0.4.0;
5
6        interface control {
7          should-cancel: func() -> bool;
8          yield-now: func();
9        }
10
11        interface node {
12          type json = string;
13
14          record tenant-ctx {
15            tenant: string,
16            team: option<string>,
17            user: option<string>,
18            trace-id: option<string>,
19            correlation-id: option<string>,
20            deadline-unix-ms: option<u64>,
21            attempt: u32,
22            idempotency-key: option<string>,
23          }
24
25          record exec-ctx {
26            tenant: tenant-ctx,
27            flow-id: string,
28            node-id: option<string>,
29          }
30
31          record node-error {
32            code: string,
33            message: string,
34            retryable: bool,
35            backoff-ms: option<u64>,
36            details: option<json>,
37          }
38
39          variant invoke-result {
40            ok(json),
41            err(node-error),
42          }
43
44          variant stream-event {
45            data(json),
46            progress(u8),
47            done,
48            error(string),
49          }
50
51          enum lifecycle-status { ok }
52
53          get-manifest: func() -> json;
54          on-start: func(ctx: exec-ctx) -> result<lifecycle-status, string>;
55          on-stop: func(ctx: exec-ctx, reason: string) -> result<lifecycle-status, string>;
56          invoke: func(ctx: exec-ctx, op: string, input: json) -> invoke-result;
57          invoke-stream: func(ctx: exec-ctx, op: string, input: json) -> list<stream-event>;
58        }
59
60        world component {
61          import control;
62          export node;
63        }
64        "#,
65        world: "component",
66    });
67}
68
69pub mod v0_5 {
70    wasmtime::component::bindgen!({
71        inline: r#"
72        package greentic:component@0.5.0;
73
74        interface control {
75          should-cancel: func() -> bool;
76          yield-now: func();
77        }
78
79        interface node {
80          type json = string;
81
82          record tenant-ctx {
83            tenant: string,
84            team: option<string>,
85            user: option<string>,
86            trace-id: option<string>,
87            correlation-id: option<string>,
88            deadline-unix-ms: option<u64>,
89            attempt: u32,
90            idempotency-key: option<string>,
91          }
92
93          record exec-ctx {
94            tenant: tenant-ctx,
95            flow-id: string,
96            node-id: option<string>,
97          }
98
99          record node-error {
100            code: string,
101            message: string,
102            retryable: bool,
103            backoff-ms: option<u64>,
104            details: option<json>,
105          }
106
107          variant invoke-result {
108            ok(json),
109            err(node-error),
110          }
111
112          variant stream-event {
113            data(json),
114            progress(u8),
115            done,
116            error(string),
117          }
118
119          enum lifecycle-status { ok }
120
121          get-manifest: func() -> json;
122          on-start: func(ctx: exec-ctx) -> result<lifecycle-status, string>;
123          on-stop: func(ctx: exec-ctx, reason: string) -> result<lifecycle-status, string>;
124          invoke: func(ctx: exec-ctx, op: string, input: json) -> invoke-result;
125          invoke-stream: func(ctx: exec-ctx, op: string, input: json) -> list<stream-event>;
126        }
127
128        world component {
129          import control;
130          export node;
131        }
132        "#,
133        world: "component",
134    });
135}
136
137pub mod node {
138    pub type Json = String;
139
140    #[derive(Clone, Debug)]
141    pub struct TenantCtx {
142        pub tenant: String,
143        pub team: Option<String>,
144        pub user: Option<String>,
145        pub trace_id: Option<String>,
146        pub correlation_id: Option<String>,
147        pub deadline_unix_ms: Option<u64>,
148        pub attempt: u32,
149        pub idempotency_key: Option<String>,
150    }
151
152    #[derive(Clone, Debug)]
153    pub struct ExecCtx {
154        pub tenant: TenantCtx,
155        pub flow_id: String,
156        pub node_id: Option<String>,
157    }
158
159    #[derive(Clone, Debug)]
160    pub struct NodeError {
161        pub code: String,
162        pub message: String,
163        pub retryable: bool,
164        pub backoff_ms: Option<u64>,
165        pub details: Option<Json>,
166    }
167
168    #[derive(Clone, Debug)]
169    pub enum InvokeResult {
170        Ok(Json),
171        Err(NodeError),
172    }
173}
174
175pub fn exec_ctx_v0_4(ctx: &node::ExecCtx) -> v0_4::exports::greentic::component::node::ExecCtx {
176    v0_4::exports::greentic::component::node::ExecCtx {
177        tenant: v0_4::exports::greentic::component::node::TenantCtx {
178            tenant: ctx.tenant.tenant.clone(),
179            team: ctx.tenant.team.clone(),
180            user: ctx.tenant.user.clone(),
181            trace_id: ctx.tenant.trace_id.clone(),
182            correlation_id: ctx.tenant.correlation_id.clone(),
183            deadline_unix_ms: ctx.tenant.deadline_unix_ms,
184            attempt: ctx.tenant.attempt,
185            idempotency_key: ctx.tenant.idempotency_key.clone(),
186        },
187        flow_id: ctx.flow_id.clone(),
188        node_id: ctx.node_id.clone(),
189    }
190}
191
192pub fn exec_ctx_v0_5(ctx: &node::ExecCtx) -> v0_5::exports::greentic::component::node::ExecCtx {
193    v0_5::exports::greentic::component::node::ExecCtx {
194        tenant: v0_5::exports::greentic::component::node::TenantCtx {
195            tenant: ctx.tenant.tenant.clone(),
196            team: ctx.tenant.team.clone(),
197            user: ctx.tenant.user.clone(),
198            trace_id: ctx.tenant.trace_id.clone(),
199            correlation_id: ctx.tenant.correlation_id.clone(),
200            deadline_unix_ms: ctx.tenant.deadline_unix_ms,
201            attempt: ctx.tenant.attempt,
202            idempotency_key: ctx.tenant.idempotency_key.clone(),
203        },
204        flow_id: ctx.flow_id.clone(),
205        node_id: ctx.node_id.clone(),
206    }
207}
208
209pub fn invoke_result_from_v0_4(
210    result: v0_4::exports::greentic::component::node::InvokeResult,
211) -> node::InvokeResult {
212    match result {
213        v0_4::exports::greentic::component::node::InvokeResult::Ok(body) => {
214            node::InvokeResult::Ok(body)
215        }
216        v0_4::exports::greentic::component::node::InvokeResult::Err(err) => {
217            node::InvokeResult::Err(node::NodeError {
218                code: err.code,
219                message: err.message,
220                retryable: err.retryable,
221                backoff_ms: err.backoff_ms,
222                details: err.details,
223            })
224        }
225    }
226}
227
228pub fn invoke_result_from_v0_5(
229    result: v0_5::exports::greentic::component::node::InvokeResult,
230) -> node::InvokeResult {
231    match result {
232        v0_5::exports::greentic::component::node::InvokeResult::Ok(body) => {
233            node::InvokeResult::Ok(body)
234        }
235        v0_5::exports::greentic::component::node::InvokeResult::Err(err) => {
236            node::InvokeResult::Err(node::NodeError {
237                code: err.code,
238                message: err.message,
239                retryable: err.retryable,
240                backoff_ms: err.backoff_ms,
241                details: err.details,
242            })
243        }
244    }
245}