Skip to main content
Glama
connectable_test.rs14.9 kB
use dal::{ Component, ComponentId, ComponentType, DalContext, FuncId, OutputSocket, OutputSocketId, SchemaVariant, SchemaVariantId, }; use dal_test::{ Result, expected::{ ExpectComponent, ExpectFunc, }, helpers::{ ChangeSetTestHelpers, attribute::value, create_component_for_schema_variant_on_default_view, get_attribute_value_for_component, schema::variant, update_attribute_value_for_component, }, }; use serde_json::Value; use si_frontend_types::RawGeometry; #[derive(Debug, Clone, Copy)] pub struct ConnectableTest { pub connectable_variant_id: SchemaVariantId, pub connectable_manager_variant_id: SchemaVariantId, pub retrieve_managed_values_id: FuncId, } impl ConnectableTest { pub async fn setup(ctx: &DalContext) -> Result<Self> { let connectable_variant_id = variant::create( ctx, "connectable", r#" function main() { return { props: [ { name: "Value", kind: "string" }, { name: "One", kind: "string", valueFrom: { kind: "inputSocket", socket_name: "One" } }, { name: "Many", kind: "array", entry: { name: "ManyItem", kind: "string" }, valueFrom: { kind: "inputSocket", socket_name: "Many" }, }, { name: "Missing", kind: "string", valueFrom: { kind: "inputSocket", socket_name: "Missing" } }, { name: "Empty", kind: "array", entry: { name: "EmptyItem", kind: "string" }, valueFrom: { kind: "inputSocket", socket_name: "Empty" }, }, ], inputSockets: [ { name: "One", arity: "one", connectionAnnotations: "[\"Value\"]" }, { name: "Many", arity: "many", connectionAnnotations: "[\"Value\"]" }, { name: "Missing", arity: "one", connectionAnnotations: "[\"Value\"]" }, { name: "Empty", arity: "many", connectionAnnotations: "[\"Value\"]" }, ], outputSockets: [ { name: "Value", arity: "one", valueFrom: { kind: "prop", prop_path: [ "root", "domain", "Value" ] }, connectionAnnotations: "[\"Value\"]" }, ], }; } "#, ) .await?; let connectable_manager_variant_id = variant::create( ctx, "connectable manager", r#" function main() { return { props: [ { name: "Value", kind: "string" }, { name: "ManagedValues", kind: "array", entry: { name: "ManagedValuesItem", kind: "string" }, }, ], }; } "#, ) .await?; SchemaVariant::get_by_id(ctx, connectable_manager_variant_id) .await? .set_type(ctx, ComponentType::ConfigurationFrameDown) .await?; let retrieve_managed_values_id = variant::create_management_func( ctx, "connectable manager", "retrieve_managed_values", r#" function main(input) { let managed_values = Object.values(input.components).map(c => c.properties.domain.Value).sort(); return { status: "ok", ops: { update: { self: { properties: { domain: { ManagedValues: managed_values } } } } } } } "#, ) .await?; Ok(Self { connectable_variant_id, connectable_manager_variant_id, retrieve_managed_values_id, }) } pub async fn create_connectable(self, ctx: &DalContext, name: &str) -> Result<Connectable> { let connectable = { let component = create_component_for_schema_variant_on_default_view( ctx, self.connectable_variant_id, ) .await?; component.set_name(ctx, name).await?; Component::set_type_by_id(ctx, component.id(), ComponentType::ConfigurationFrameDown) .await?; Connectable::new(self, component.id()) }; connectable.set_value(ctx, name).await?; Ok(connectable) } pub async fn create_parent(self, ctx: &DalContext, name: &str) -> Result<Connectable> { let component = create_component_for_schema_variant_on_default_view( ctx, self.connectable_manager_variant_id, ) .await?; component.set_name(ctx, name).await?; update_attribute_value_for_component( ctx, component.id(), &["root", "domain", "Value"], name.into(), ) .await?; Ok(Connectable::new(self, component.id())) } pub async fn create_manager(self, ctx: &DalContext, name: &str) -> Result<Connectable> { self.create_parent(ctx, name).await } } // Component with output socket "Value" and input sockets "One", "Many", "Missing", and "Empty" // which can connect to "Value". #[derive(Debug, Copy, Clone, derive_more::From, derive_more::Into)] pub struct Connectable { pub test: ConnectableTest, pub id: ComponentId, } impl Connectable { pub fn new(test: ConnectableTest, id: ComponentId) -> Self { Self { test, id } } pub async fn run_management_func(self, ctx: &mut DalContext) -> Result<Value> { ExpectComponent(self.id) .execute_management_func(ctx, ExpectFunc(self.test.retrieve_managed_values_id)) .await; ChangeSetTestHelpers::commit_and_update_snapshot_to_visibility(ctx).await?; get_attribute_value_for_component(ctx, self.id, &["root", "domain", "ManagedValues"]).await } pub async fn set_value(self, ctx: &DalContext, value: &str) -> Result<()> { update_attribute_value_for_component( ctx, self.id, &["root", "domain", "Value"], value.into(), ) .await } // Get the domain, with the Many prop sorted pub async fn domain(self, ctx: &DalContext) -> Result<Value> { let mut domain = get_attribute_value_for_component(ctx, self.id, &["root", "domain"]).await?; if let Some(many) = domain.get_mut("Many") { let many = many.as_array_mut().expect("Many is an array"); many.sort_by_key(|v| v.as_str().expect("Many is an array of strings").to_string()); } Ok(domain) } pub async fn value_output_socket_id(self, ctx: &DalContext) -> Result<OutputSocketId> { let variant_id = Component::schema_variant_id(ctx, self.id).await?; let value_socket = OutputSocket::find_with_name_or_error(ctx, "Value", variant_id).await?; Ok(value_socket.id()) } } pub const GEOMETRY1: RawGeometry = RawGeometry { x: 1, y: 11, width: Some(111), height: Some(1111), }; pub const GEOMETRY2: RawGeometry = RawGeometry { x: 2, y: 22, width: Some(222), height: Some(2222), }; #[derive(Debug, Clone, Copy)] pub struct SubscribableTest { pub subscribable_variant_id: SchemaVariantId, pub subscribable_manager_variant_id: SchemaVariantId, pub retrieve_managed_values_id: FuncId, } impl SubscribableTest { pub async fn setup(ctx: &DalContext) -> Result<Self> { let subscribable_variant_id = variant::create( ctx, "subscribable", r#" function main() { return { props: [ { name: "Value", kind: "string" }, { name: "One", kind: "string" }, { name: "Many", kind: "array", entry: { name: "ManyItem", kind: "string" }, }, { name: "Missing", kind: "string" }, { name: "Empty", kind: "array", entry: { name: "EmptyItem", kind: "string" }, }, ], }; } "#, ) .await?; let subscribable_manager_variant_id = variant::create( ctx, "subscribable manager", r#" function main() { return { props: [ { name: "Value", kind: "string" }, { name: "ManagedValues", kind: "array", entry: { name: "ManagedValuesItem", kind: "string" }, }, ], }; } "#, ) .await?; SchemaVariant::get_by_id(ctx, subscribable_manager_variant_id) .await? .set_type(ctx, ComponentType::ConfigurationFrameDown) .await?; let retrieve_managed_values_id = variant::create_management_func( ctx, "subscribable manager", "retrieve_managed_values", r#" function main(input) { let managed_values = Object.values(input.components).map(c => c.properties.domain.Value).sort(); return { status: "ok", ops: { update: { self: { properties: { domain: { ManagedValues: managed_values } } } } } } } "#, ) .await?; Ok(Self { subscribable_variant_id, subscribable_manager_variant_id, retrieve_managed_values_id, }) } pub async fn create_subscribable( self, ctx: &DalContext, name: &str, subscribe_one: Option<Subscribable>, subscribe_many: impl IntoIterator<Item = Subscribable>, ) -> Result<Subscribable> { let subscribable = { let component = create_component_for_schema_variant_on_default_view( ctx, self.subscribable_variant_id, ) .await?; component.set_name(ctx, name).await?; Component::set_type_by_id(ctx, component.id(), ComponentType::ConfigurationFrameDown) .await?; Subscribable::new(self, component.id()) }; subscribable.set_value(ctx, name).await?; if let Some(from) = subscribe_one { let from_name = from.name(ctx).await?; value::subscribe( ctx, (name, "/domain/One"), (from_name.as_str(), "/domain/Value"), ) .await?; } for from in subscribe_many { let source_name = from.name(ctx).await?; value::subscribe( ctx, (name, "/domain/Many/-"), (source_name.as_str(), "/domain/Value"), ) .await?; } Ok(subscribable) } pub async fn create_parent(self, ctx: &DalContext, name: &str) -> Result<Subscribable> { let component = create_component_for_schema_variant_on_default_view( ctx, self.subscribable_manager_variant_id, ) .await?; component.set_name(ctx, name).await?; update_attribute_value_for_component( ctx, component.id(), &["root", "domain", "Value"], name.into(), ) .await?; Ok(Subscribable::new(self, component.id())) } pub async fn create_manager(self, ctx: &DalContext, name: &str) -> Result<Subscribable> { self.create_parent(ctx, name).await } } // Component that uses subscriptions instead of socket connections #[derive(Debug, Copy, Clone, derive_more::From, derive_more::Into)] pub struct Subscribable { pub test: SubscribableTest, pub id: ComponentId, } impl Subscribable { pub fn new(test: SubscribableTest, id: ComponentId) -> Self { Self { test, id } } pub async fn run_management_func(self, ctx: &mut DalContext) -> Result<Value> { ExpectComponent(self.id) .execute_management_func(ctx, ExpectFunc(self.test.retrieve_managed_values_id)) .await; ChangeSetTestHelpers::commit_and_update_snapshot_to_visibility(ctx).await?; get_attribute_value_for_component(ctx, self.id, &["root", "domain", "ManagedValues"]).await } pub async fn set_value(self, ctx: &DalContext, value: &str) -> Result<()> { update_attribute_value_for_component( ctx, self.id, &["root", "domain", "Value"], value.into(), ) .await } pub async fn name(self, ctx: &DalContext) -> Result<String> { Ok(Component::get_by_id(ctx, self.id).await?.name(ctx).await?) } // Get the domain, with the Many prop sorted pub async fn domain(self, ctx: &DalContext) -> Result<Value> { let mut domain = get_attribute_value_for_component(ctx, self.id, &["root", "domain"]).await?; if let Some(many) = domain.get_mut("Many") { let many = many.as_array_mut().expect("Many is an array"); many.sort_by_key(|v| v.as_str().expect("Many is an array of strings").to_string()); } Ok(domain) } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/systeminit/si'

If you have feedback or need assistance with the MCP directory API, please join our Discord server