Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 34 additions & 5 deletions src/composition/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ use wasmtime::component::{HasData, Linker};

use super::composer::Composer;
use super::graph::{ComponentGraph, Edge, Node};
use super::wit::{ComponentMetadata, Parser};
use crate::types::{CapabilityDefinition, ComponentDefinition, ComponentState, Function};
use super::wit::Parser;
use crate::types::{
CapabilityDefinition, ComponentDefinition, ComponentMetadata, ComponentState, Function,
};

/// Trait implemented by host capability instances.
///
Expand Down Expand Up @@ -160,10 +162,12 @@ pub struct ComponentSpec {
pub name: String,
pub namespace: Option<String>,
pub package: Option<String>,
pub labels: HashMap<String, String>,
pub bytes: Arc<[u8]>,
pub imports: Vec<String>,
pub exports: Vec<String>,
pub capabilities: Vec<String>,
pub dependents: Vec<String>,
pub functions: HashMap<String, Function>,
}

Expand Down Expand Up @@ -271,7 +275,7 @@ pub async fn build_registries(

let mut built_components = HashMap::new();

for node_index in sorted_indices {
for &node_index in &sorted_indices {
if let Node::Component(definition) = &component_graph[node_index] {
let temp_component_registry = ComponentRegistry {
components: Arc::new(built_components.clone()),
Expand All @@ -289,6 +293,20 @@ pub async fn build_registries(
}
}

// Compute dependents from graph edges
for &node_index in &sorted_indices {
if let Node::Component(definition) = &component_graph[node_index] {
for (dep_index, edge) in component_graph.get_dependencies(node_index) {
if matches!(edge, Edge::Dependency)
&& let Node::Component(dep_def) = &component_graph[dep_index]
&& let Some(spec) = built_components.get_mut(&dep_def.name)
{
spec.dependents.push(definition.name.clone());
}
}
}
}

Ok((
ComponentRegistry {
components: Arc::new(built_components),
Expand Down Expand Up @@ -509,6 +527,15 @@ async fn process_component(

let mut all_capabilities = HashSet::new();

let component_metadata = ComponentMetadata {
name: definition.name.clone(),
namespace: metadata.namespace.clone(),
package: metadata.name.clone(),
labels: definition.labels.clone(),
dependents: None,
exports: exports.clone(),
};

let dependencies: Vec<_> = component_graph.get_dependencies(node_index).collect();
for (dependency_node_index, edge) in &dependencies {
let dependency_node = &component_graph[*dependency_node_index];
Expand All @@ -517,7 +544,7 @@ async fn process_component(
let component_spec = component_registry.get_required_import(
dependency_def,
definition,
&metadata,
&component_metadata,
)?;

if matches!(edge, Edge::Interceptor(_)) && is_advice_component(&exports) {
Expand Down Expand Up @@ -614,11 +641,13 @@ async fn process_component(
Ok(ComponentSpec {
name: definition.name.clone(),
namespace: metadata.namespace,
package: metadata.package,
package: metadata.name,
labels: definition.labels.clone(),
bytes: Arc::from(bytes),
imports,
exports,
capabilities: all_capabilities.into_iter().collect(),
dependents: Vec::new(),
functions,
})
}
Expand Down
14 changes: 7 additions & 7 deletions src/composition/wit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ use wit_parser::{Resolve, Type};
use crate::types::{Function, FunctionParam, Interface};

#[derive(Debug, Clone)]
pub struct ComponentMetadata {
pub struct PackageMetadata {
pub namespace: Option<String>,
pub package: Option<String>,
pub name: Option<String>,
}

pub struct Parser;
Expand All @@ -18,7 +18,7 @@ impl Parser {
pub fn parse(
component_bytes: &[u8],
) -> Result<(
ComponentMetadata,
PackageMetadata,
Vec<String>,
Vec<String>,
HashMap<String, Function>,
Expand All @@ -36,14 +36,14 @@ impl Parser {
let component_metadata = if let Some(package_id) = &world.package {
let package = resolve.packages.get(*package_id).unwrap();
let package_name = &package.name;
ComponentMetadata {
PackageMetadata {
namespace: Some(package_name.namespace.clone()),
package: Some(package_name.name.clone()),
name: Some(package_name.name.clone()),
}
} else {
ComponentMetadata {
PackageMetadata {
namespace: None,
package: None,
name: None,
}
};

Expand Down
45 changes: 44 additions & 1 deletion src/config/handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,15 @@ impl ConfigHandler for ComponentConfigHandler {
fn claimed_properties(&self) -> HashMap<&str, &[&str]> {
HashMap::from([(
"component",
["uri", "scope", "imports", "interceptors", "config"].as_slice(),
[
"uri",
"scope",
"imports",
"interceptors",
"config",
"labels",
]
.as_slice(),
)])
}

Expand All @@ -48,6 +56,7 @@ impl ConfigHandler for ComponentConfigHandler {
let imports = take_string_array(&mut properties, "imports").map_err(ctx)?;
let interceptors = take_string_array(&mut properties, "interceptors").map_err(ctx)?;
let config = take_object(&mut properties, "config").map_err(ctx)?;
let labels = take_string_map(&mut properties, "labels").map_err(ctx)?;

if !properties.is_empty() {
let unknown: Vec<_> = properties.keys().collect();
Expand All @@ -63,6 +72,7 @@ impl ConfigHandler for ComponentConfigHandler {
imports,
interceptors,
config,
labels,
});
Ok(())
}
Expand Down Expand Up @@ -225,3 +235,36 @@ fn take_object(
None => Ok(HashMap::new()),
}
}

fn take_string_map(
properties: &mut PropertyMap,
key: &str,
) -> Result<HashMap<String, String>, PropertyError> {
match properties.remove(key) {
Some(serde_json::Value::Object(map)) => {
let mut result = HashMap::new();
for (k, v) in map {
let s = match v {
serde_json::Value::String(s) => s,
serde_json::Value::Number(n) => n.to_string(),
serde_json::Value::Bool(b) => b.to_string(),
got => {
return Err(PropertyError::TypeMismatch {
key: format!("{key}.{k}"),
expected: "a scalar value",
got,
});
}
};
result.insert(k, s);
}
Ok(result)
}
Some(got) => Err(PropertyError::TypeMismatch {
key: key.into(),
expected: "an object/table of strings",
got,
}),
None => Ok(HashMap::new()),
}
}
Loading