Skip to content

Commit 5aa90ea

Browse files
committed
multi wit version handling for data-collection
1 parent 4ae01a5 commit 5aa90ea

File tree

14 files changed

+708
-309
lines changed

14 files changed

+708
-309
lines changed

crates/cli/src/commands/components/check.rs

+62-17
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ use colored::Colorize;
44
pub struct Options {
55
#[arg(long = "filename")]
66
filename: Option<String>,
7+
#[arg(long = "component-type")]
8+
component_type: Option<String>,
9+
#[arg(long = "wit-version")]
10+
wit_version: Option<String>,
711
}
812

913
pub enum ComponentType {
@@ -15,6 +19,7 @@ pub enum ComponentType {
1519
pub async fn check_component(
1620
component_type: ComponentType,
1721
component_path: &str,
22+
component_wit_version: &str,
1823
) -> anyhow::Result<()> {
1924
use edgee_components_runtime::config::{
2025
ComponentsConfiguration, ConsentMappingComponents, DataCollectionComponents,
@@ -29,13 +34,26 @@ pub async fn check_component(
2934
}
3035

3136
let config = match component_type {
32-
ComponentType::DataCollection => ComponentsConfiguration {
33-
data_collection: vec![DataCollectionComponents {
34-
id: component_path.to_string(),
35-
file: component_path.to_string(),
37+
ComponentType::DataCollection => match component_wit_version {
38+
"0.5.0" => ComponentsConfiguration {
39+
data_collection: vec![DataCollectionComponents {
40+
id: component_path.to_string(),
41+
file: component_path.to_string(),
42+
wit_version: edgee_components_runtime::data_collection::version::DataCollectionWitVersion::V0_5_0,
43+
..Default::default()
44+
}],
3645
..Default::default()
37-
}],
38-
..Default::default()
46+
},
47+
"1.0.0" => ComponentsConfiguration {
48+
data_collection: vec![DataCollectionComponents {
49+
id: component_path.to_string(),
50+
file: component_path.to_string(),
51+
wit_version: edgee_components_runtime::data_collection::version::DataCollectionWitVersion::V1_0_0,
52+
..Default::default()
53+
}],
54+
..Default::default()
55+
},
56+
_ => anyhow::bail!("Invalid WIT version: {}", component_wit_version),
3957
},
4058
ComponentType::ConsentMapping => ComponentsConfiguration {
4159
consent_mapping: vec![ConsentMappingComponents {
@@ -53,11 +71,19 @@ pub async fn check_component(
5371
let mut store = context.empty_store();
5472

5573
match component_type {
56-
ComponentType::DataCollection => {
57-
let _ = context
58-
.get_data_collection_instance(component_path, &mut store)
59-
.await?;
60-
}
74+
ComponentType::DataCollection => match component_wit_version {
75+
"0.5.0" => {
76+
let _ = context
77+
.get_data_collection_0_5_0_instance(component_path, &mut store)
78+
.await?;
79+
}
80+
"1.0.0" => {
81+
let _ = context
82+
.get_data_collection_instance(component_path, &mut store)
83+
.await?;
84+
}
85+
_ => anyhow::bail!("Invalid WIT version: {}", component_wit_version),
86+
},
6187
ComponentType::ConsentMapping => {
6288
let _ = context
6389
.get_consent_mapping_instance(component_path, &mut store)
@@ -74,9 +100,20 @@ pub async fn run(_opts: Options) -> anyhow::Result<()> {
74100

75101
use crate::components::manifest::{self, Manifest};
76102

77-
let component_path = match _opts.filename {
78-
Some(filename) => filename,
79-
None => {
103+
let (component_path, component_type, component_wit_version) = match (
104+
_opts.filename,
105+
_opts.component_type,
106+
_opts.wit_version,
107+
) {
108+
(Some(filename), Some(component_type), Some(version)) => match component_type.as_str() {
109+
"data-collection" => (filename, ComponentType::DataCollection, version),
110+
"consent-mapping" => (filename, ComponentType::ConsentMapping, version),
111+
_ => anyhow::bail!(
112+
"Invalid component type: {}, expected 'data-collection' or 'consent-mapping'",
113+
component_type
114+
),
115+
},
116+
_ => {
80117
let Some(manifest_path) = manifest::find_manifest_path() else {
81118
anyhow::bail!("Edgee Manifest not found. Please run `edgee component new` and start from a template or `edgee component init` to create a new empty manifest in this folder.");
82119
};
@@ -88,12 +125,20 @@ pub async fn run(_opts: Options) -> anyhow::Result<()> {
88125
.output_path
89126
.to_str()
90127
.context("Output path should be a valid UTF-8 string")?;
91-
component_path.to_string()
128+
(
129+
component_path.to_string(),
130+
ComponentType::DataCollection,
131+
manifest.component.wit_version,
132+
)
92133
}
93134
};
94135

95-
// TODO: dont assume that it is a data collection component, add type in manifest
96-
check_component(ComponentType::DataCollection, component_path.as_str()).await?;
136+
check_component(
137+
component_type,
138+
component_path.as_str(),
139+
component_wit_version.as_str(),
140+
)
141+
.await?;
97142

98143
Ok(())
99144
}

crates/cli/src/commands/components/push.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,13 @@ pub async fn run(opts: Options) -> Result<()> {
8585

8686
// check if the output file is a valid Data Collection component
8787
match super::check::check_component(
88-
super::check::ComponentType::DataCollection,
88+
match manifest.component.category {
89+
api_types::ComponentCreateInputCategory::DataCollection => {
90+
super::check::ComponentType::DataCollection
91+
}
92+
},
8993
output_path.to_str().unwrap(),
94+
&manifest.component.wit_version,
9095
)
9196
.await
9297
{

crates/cli/src/commands/components/test.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ use std::collections::HashMap;
77
use edgee_components_runtime::data_collection;
88
use std::str::FromStr;
99

10-
use edgee_components_runtime::data_collection::exports::edgee::components::data_collection::EdgeeRequest;
11-
use edgee_components_runtime::data_collection::exports::edgee::components::data_collection::HttpMethod;
10+
use edgee_components_runtime::data_collection::v1_0_0::data_collection::exports::edgee::components1_0_0::data_collection::EdgeeRequest;
11+
use edgee_components_runtime::data_collection::v1_0_0::data_collection::exports::edgee::components1_0_0::data_collection::HttpMethod;
1212
use edgee_components_runtime::data_collection::payload::{Event, EventType};
1313
use http::{HeaderMap, HeaderName, HeaderValue};
1414
#[derive(Debug, clap::Parser)]
@@ -118,7 +118,7 @@ async fn test_data_collection_component(opts: Options) -> anyhow::Result<()> {
118118
let instance = context
119119
.get_data_collection_instance(&component_path, &mut store)
120120
.await?;
121-
let component = instance.edgee_components_data_collection();
121+
let component = instance.edgee_components1_0_0_data_collection();
122122

123123
// events generated with demo.edgee.app
124124
let page_event_json = r#"[{"uuid":"37009b9b-a572-4615-87c1-09e257331ecb","timestamp":"2025-02-03T15:46:39.283317613Z","type":"page","data":{"keywords":["demo","tag manager"],"title":"Page with Edgee components","url":"https://demo.edgee.app/analytics-with-edgee.html","path":"/analytics-with-edgee.html","referrer":"https://demo.edgee.dev/analytics-with-js.html"},"context":{"page":{"keywords":["demo","tag manager"],"title":"Page with Edgee components","url":"https://demo.edgee.app/analytics-with-edgee.html","path":"/analytics-with-edgee.html","referrer":"https://demo.edgee.dev/analytics-with-js.html"},"user":{"edgee_id":"6bb171d5-2284-41ee-9889-91af03b71dc5"},"client":{"ip":"127.0.0.1","locale":"en-us","accept_language":"en-US,en;q=0.9","timezone":"Europe/Paris","user_agent":"Mozilla/5.0 (X11; Linux x86_64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36","user_agent_version_list":"Not A(Brand;8|Chromium;132","user_agent_mobile":"0","os_name":"Linux","user_agent_architecture":"x86","user_agent_bitness":"64","user_agent_full_version_list":"Not A(Brand;8.0.0.0|Chromium;132.0.6834.159","user_agent_model":"","os_version":"6.12.11","screen_width":1920,"screen_height":1280,"screen_density":1.5},"session":{"session_id":"1738597536","session_count":1,"session_start":false,"first_seen":"2025-02-03T15:45:36.569004889Z","last_seen":"2025-02-03T15:46:39.278740029Z"}},"from":"edge"}]"#;

crates/components-runtime/src/config.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use crate::data_collection::version::DataCollectionWitVersion;
12
use std::{collections::HashMap, path::PathBuf};
23

34
use serde::Deserialize;
@@ -11,7 +12,7 @@ pub struct ComponentsConfiguration {
1112
pub cache: Option<PathBuf>,
1213
}
1314

14-
#[derive(Deserialize, Debug, Default, Clone)]
15+
#[derive(Deserialize, Debug, Clone, Default)]
1516
pub struct DataCollectionComponents {
1617
#[serde(skip_deserializing)]
1718
pub project_component_id: String,
@@ -21,6 +22,7 @@ pub struct DataCollectionComponents {
2122
pub file: String,
2223
#[serde(default)]
2324
pub settings: DataCollectionComponentSettings,
25+
pub wit_version: DataCollectionWitVersion,
2426
}
2527

2628
#[derive(Deserialize, Debug, Clone)]

crates/components-runtime/src/context.rs

+62-7
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,50 @@ use wasmtime_wasi::{IoView, WasiCtx, WasiView};
88

99
use crate::config::{ComponentsConfiguration, DataCollectionComponents};
1010
use crate::consent_mapping::{ConsentMapping, ConsentMappingPre};
11-
use crate::data_collection::{DataCollection, DataCollectionPre};
11+
use crate::data_collection::v0_5_0::data_collection::{
12+
DataCollectionZeroFiveZero, DataCollectionZeroFiveZeroPre,
13+
};
14+
use crate::data_collection::v1_0_0::data_collection::{
15+
DataCollectionOneZeroZero, DataCollectionOneZeroZeroPre,
16+
};
17+
use crate::data_collection::version::DataCollectionWitVersion;
1218

1319
pub struct ComponentsContext {
1420
pub engine: Engine,
1521
pub components: Components,
1622
}
1723

1824
pub struct Components {
19-
pub data_collection: HashMap<String, DataCollectionPre<HostState>>,
25+
pub data_collection_0_5_0: HashMap<String, DataCollectionZeroFiveZeroPre<HostState>>,
26+
pub data_collection: HashMap<String, DataCollectionOneZeroZeroPre<HostState>>,
2027
pub consent_mapping: HashMap<String, ConsentMappingPre<HostState>>,
2128
}
2229

2330
pub fn pre_instanciate_data_collection_component_internal(
2431
engine: &Engine,
2532
component_config: &DataCollectionComponents,
26-
) -> anyhow::Result<DataCollectionPre<HostState>> {
33+
) -> anyhow::Result<DataCollectionOneZeroZeroPre<HostState>> {
34+
let mut linker = Linker::new(engine);
35+
wasmtime_wasi::add_to_linker_async(&mut linker)?;
36+
37+
let span = tracing::info_span!("component-context", component = %component_config.id, category = "data-collection");
38+
let _span = span.enter();
39+
40+
tracing::debug!("Loading new data collection component");
41+
42+
let component = Component::from_file(engine, &component_config.file)?;
43+
let instance_pre = linker.instantiate_pre(&component)?;
44+
let instance_pre = DataCollectionOneZeroZeroPre::new(instance_pre)?;
45+
46+
tracing::debug!("loaded new data collection component");
47+
48+
Ok(instance_pre)
49+
}
50+
51+
pub fn pre_instanciate_data_collection_0_5_0_component_internal(
52+
engine: &Engine,
53+
component_config: &DataCollectionComponents,
54+
) -> anyhow::Result<DataCollectionZeroFiveZeroPre<HostState>> {
2755
let mut linker = Linker::new(engine);
2856
wasmtime_wasi::add_to_linker_async(&mut linker)?;
2957

@@ -34,7 +62,7 @@ pub fn pre_instanciate_data_collection_component_internal(
3462

3563
let component = Component::from_file(engine, &component_config.file)?;
3664
let instance_pre = linker.instantiate_pre(&component)?;
37-
let instance_pre = DataCollectionPre::new(instance_pre)?;
65+
let instance_pre = DataCollectionZeroFiveZeroPre::new(instance_pre)?;
3866

3967
tracing::debug!("loaded new data collection component");
4068

@@ -62,13 +90,25 @@ impl ComponentsContext {
6290
let data_collection_components = config
6391
.data_collection
6492
.iter()
93+
.filter(|entry| entry.wit_version == DataCollectionWitVersion::V1_0_0)
6594
.map(|entry| {
6695
let instance_pre =
6796
pre_instanciate_data_collection_component_internal(&engine, entry)?;
6897
Ok((entry.id.clone(), instance_pre))
6998
})
7099
.collect::<anyhow::Result<_>>()?;
71100

101+
let data_collection_0_5_0_components = config
102+
.data_collection
103+
.iter()
104+
.filter(|entry| entry.wit_version == DataCollectionWitVersion::V0_5_0)
105+
.map(|entry| {
106+
let instance_pre =
107+
pre_instanciate_data_collection_0_5_0_component_internal(&engine, entry)?;
108+
Ok((entry.id.clone(), instance_pre))
109+
})
110+
.collect::<anyhow::Result<_>>()?;
111+
72112
// Consent mapping components
73113
let consent_mapping_components = config
74114
.consent_mapping
@@ -91,6 +131,7 @@ impl ComponentsContext {
91131

92132
let components = Components {
93133
data_collection: data_collection_components,
134+
data_collection_0_5_0: data_collection_0_5_0_components,
94135
consent_mapping: consent_mapping_components,
95136
};
96137

@@ -100,7 +141,7 @@ impl ComponentsContext {
100141
pub fn pre_instanciate_data_collection_component(
101142
&self,
102143
component_config: DataCollectionComponents,
103-
) -> anyhow::Result<DataCollectionPre<HostState>> {
144+
) -> anyhow::Result<DataCollectionOneZeroZeroPre<HostState>> {
104145
let instance_pre =
105146
pre_instanciate_data_collection_component_internal(&self.engine, &component_config)?;
106147
Ok(instance_pre)
@@ -109,7 +150,7 @@ impl ComponentsContext {
109150
pub fn add_data_collection_component(
110151
&mut self,
111152
component_config: DataCollectionComponents,
112-
instance_pre: DataCollectionPre<HostState>,
153+
instance_pre: DataCollectionOneZeroZeroPre<HostState>,
113154
) {
114155
if !self
115156
.components
@@ -134,7 +175,7 @@ impl ComponentsContext {
134175
&self,
135176
id: &str,
136177
store: &mut Store<HostState>,
137-
) -> anyhow::Result<DataCollection> {
178+
) -> anyhow::Result<DataCollectionOneZeroZero> {
138179
let instance_pre = self.components.data_collection.get(id);
139180

140181
if instance_pre.is_none() {
@@ -144,6 +185,20 @@ impl ComponentsContext {
144185
instance_pre.unwrap().instantiate_async(store).await
145186
}
146187

188+
pub async fn get_data_collection_0_5_0_instance(
189+
&self,
190+
id: &str,
191+
store: &mut Store<HostState>,
192+
) -> anyhow::Result<DataCollectionZeroFiveZero> {
193+
let instance_pre = self.components.data_collection_0_5_0.get(id);
194+
195+
if instance_pre.is_none() {
196+
return Err(anyhow::anyhow!("component not found: {}", id));
197+
}
198+
199+
instance_pre.unwrap().instantiate_async(store).await
200+
}
201+
147202
pub async fn get_consent_mapping_instance(
148203
&self,
149204
id: &str,

0 commit comments

Comments
 (0)