From e0fd9077e852179832903779f95d54924ace14dd Mon Sep 17 00:00:00 2001 From: Joe Date: Wed, 18 Feb 2026 08:00:49 -0600 Subject: [PATCH] Refactor service encoding to streamline properties handling - Removed the encoding of attributes and tags from the `encodeService` function, consolidating their inclusion into the properties map as `Variant::Attributes(...)` and `Variant::Tags(...)`. - Updated the `ServiceChunk` struct to reflect these changes, ensuring a more efficient serialization process during syncback operations. - Adjusted related tests to align with the new structure, enhancing overall data management and consistency in service encoding. These modifications improve the clarity and performance of the service encoding process. --- plugin/src/ChangeBatcher/encodeService.lua | 47 +++------------------- src/cli/serve.rs | 14 ------- src/web/interface.rs | 10 ++--- tests/rojo_test/serve_util.rs | 30 +++----------- tests/tests/live_syncback.rs | 39 ------------------ 5 files changed, 15 insertions(+), 125 deletions(-) diff --git a/plugin/src/ChangeBatcher/encodeService.lua b/plugin/src/ChangeBatcher/encodeService.lua index 66308cd4..1f186b60 100644 --- a/plugin/src/ChangeBatcher/encodeService.lua +++ b/plugin/src/ChangeBatcher/encodeService.lua @@ -15,8 +15,6 @@ local SKIP_PROPERTIES = { return function(service: Instance) local properties = {} - local attributes = {} - local tags = {} local refs = {} local classDescriptor = RbxDom.findClassDescriptor(service.ClassName) @@ -25,11 +23,9 @@ return function(service: Instance) if SKIP_PROPERTIES[propertyName] then continue end - if propertyName == "Attributes" or propertyName == "Tags" then - continue - end - local isReadable = propertyMeta.scriptability == "ReadWrite" or propertyMeta.scriptability == "Read" + local isReadable = propertyMeta.scriptability == "ReadWrite" + or propertyMeta.scriptability == "Read" local doesSerialize = propertyMeta.serialization ~= "DoesNotSerialize" if isReadable and doesSerialize then @@ -59,26 +55,6 @@ return function(service: Instance) end end - local attrOk, attrMap = pcall(function() - return service:GetAttributes() - end) - if attrOk and attrMap and next(attrMap) then - local descriptor = RbxDom.findCanonicalPropertyDescriptor(service.ClassName, "Attributes") - if descriptor then - local encodeOk, encoded = encodeProperty(service, "Attributes", descriptor) - if encodeOk and encoded ~= nil then - attributes = encoded - end - end - end - - local tagOk, tagList = pcall(function() - return service:GetTags() - end) - if tagOk and tagList and #tagList > 0 then - tags = tagList - end - local children = service:GetChildren() local data = buffer.create(0) if #children > 0 then @@ -90,23 +66,10 @@ return function(service: Instance) end end - local result = { + return { className = service.ClassName, data = data, + properties = properties, + refs = refs, } - - if next(properties) then - result.properties = properties - end - if next(attributes) then - result.attributes = attributes - end - if #tags > 0 then - result.tags = tags - end - if next(refs) then - result.refs = refs - end - - return result end diff --git a/src/cli/serve.rs b/src/cli/serve.rs index b03e986d..4083dbd0 100644 --- a/src/cli/serve.rs +++ b/src/cli/serve.rs @@ -139,7 +139,6 @@ fn run_live_syncback(project_path: &Path, payload: SyncbackPayload) -> anyhow::R fn build_dom_from_chunks(payload: SyncbackPayload) -> anyhow::Result { use crate::syncback::VISIBLE_SERVICES; - use rbx_dom_weak::types::{Attributes, Tags}; let mut dom = WeakDom::new(InstanceBuilder::new("DataModel")); let root_ref = dom.root_ref(); @@ -154,19 +153,6 @@ fn build_dom_from_chunks(payload: SyncbackPayload) -> anyhow::Result { builder = builder.with_property(key.as_str(), value.clone()); } - if !chunk.attributes.is_empty() { - let mut attrs = Attributes::new(); - for (key, value) in &chunk.attributes { - attrs.insert(key.clone(), value.clone()); - } - builder = builder.with_property("Attributes", Variant::Attributes(attrs)); - } - - if !chunk.tags.is_empty() { - let tags: Tags = chunk.tags.iter().map(|s| s.as_str()).collect(); - builder = builder.with_property("Tags", Variant::Tags(tags)); - } - let service_ref = dom.insert(root_ref, builder); created_services.insert(chunk.class_name.clone()); diff --git a/src/web/interface.rs b/src/web/interface.rs index fe103a65..d6400218 100644 --- a/src/web/interface.rs +++ b/src/web/interface.rs @@ -28,7 +28,11 @@ pub(crate) const SERVER_VERSION: &str = env!("CARGO_PKG_VERSION"); pub const PROTOCOL_VERSION: u64 = 6; /// A single service's children serialized as rbxm binary data, plus the -/// service's own properties, attributes, tags, and Ref property hints. +/// service's own properties and Ref property hints. +/// +/// Attributes and Tags are included in the `properties` map as +/// `Variant::Attributes(...)` and `Variant::Tags(...)` respectively, +/// matching the encoding used by the existing `/api/write` path. #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct ServiceChunk { @@ -38,10 +42,6 @@ pub struct ServiceChunk { #[serde(default)] pub properties: HashMap, #[serde(default)] - pub attributes: HashMap, - #[serde(default)] - pub tags: Vec, - #[serde(default)] pub refs: HashMap, } diff --git a/tests/rojo_test/serve_util.rs b/tests/rojo_test/serve_util.rs index d67cfcfb..eb3e785e 100644 --- a/tests/rojo_test/serve_util.rs +++ b/tests/rojo_test/serve_util.rs @@ -528,16 +528,15 @@ pub fn make_service_chunk( class_name: &str, children: Vec, ) -> librojo::web_api::ServiceChunk { - make_service_chunk_full(class_name, vec![], vec![], vec![], vec![], children) + make_service_chunk_full(class_name, vec![], vec![], children) } -/// Build a ServiceChunk with explicit service-level properties, attributes, -/// tags, and ref hints alongside the serialized children. +/// Build a ServiceChunk with explicit service-level properties and ref hints +/// alongside the serialized children. Attributes and Tags should be included +/// in the `properties` vec as `Variant::Attributes(...)` / `Variant::Tags(...)`. pub fn make_service_chunk_full( class_name: &str, properties: Vec<(&str, rbx_dom_weak::types::Variant)>, - attributes: Vec<(&str, rbx_dom_weak::types::Variant)>, - tags: Vec, refs: Vec<(&str, &str, &str)>, children: Vec, ) -> librojo::web_api::ServiceChunk { @@ -559,10 +558,6 @@ pub fn make_service_chunk_full( .into_iter() .map(|(k, v)| (k.to_string(), v)) .collect(); - let attrs_map: HashMap = attributes - .into_iter() - .map(|(k, v)| (k.to_string(), v)) - .collect(); let refs_map: HashMap = refs .into_iter() .map(|(prop, name, class)| { @@ -580,8 +575,6 @@ pub fn make_service_chunk_full( class_name: class_name.to_string(), data: buf, properties: props_map, - attributes: attrs_map, - tags, refs: refs_map, } } @@ -589,7 +582,7 @@ pub fn make_service_chunk_full( /// Build a complete rbxl file from service chunks, mirroring the same data /// that live syncback receives. Used for CLI parity testing. pub fn make_rbxl_from_chunks(chunks: &[librojo::web_api::ServiceChunk]) -> Vec { - use rbx_dom_weak::types::{Attributes, Tags, Variant}; + use rbx_dom_weak::types::Variant; use rbx_dom_weak::WeakDom; use std::collections::HashMap; use std::io::Cursor; @@ -604,19 +597,6 @@ pub fn make_rbxl_from_chunks(chunks: &[librojo::web_api::ServiceChunk]) -> Vec {} _ => { properties.insert(key.to_string(), value.clone()); } } } - let mut attributes_map = std::collections::HashMap::new(); - if let Some(rbx_dom_weak::types::Variant::Attributes(attrs)) = - service.properties.get(&rbx_dom_weak::ustr("Attributes")) - { - for (k, v) in attrs.iter() { - attributes_map.insert(k.to_string(), v.clone()); - } - } - - let tags_vec = if let Some(rbx_dom_weak::types::Variant::Tags(tags)) = - service.properties.get(&rbx_dom_weak::ustr("Tags")) - { - tags.iter().map(|s| s.to_string()).collect() - } else { - vec![] - }; - chunks.push(ServiceChunk { class_name: service.class.to_string(), data, properties, - attributes: attributes_map, - tags: tags_vec, refs: refs_map, }); }