Enhance error handling and improve script tracking in RojoTree and ServeSession

- Added a test to verify the functionality of script tracking updates in RojoTree, ensuring proper addition and removal of script references.
- Improved error handling in ServeSession by clearing temporary script IDs upon disconnection to prevent potential memory leaks.
- Updated API logic to filter out empty properties and children during instance addition, enhancing the integrity of the synchronization process.

These changes aim to optimize script management and enhance the robustness of the session handling and tree operations.
This commit is contained in:
Joe 2026-02-28 11:16:10 -06:00
parent 9d6b48a53e
commit ec51c14a41
5 changed files with 33 additions and 79 deletions

View file

@ -625,6 +625,29 @@ mod test {
use super::RojoTree;
#[test]
fn update_script_tracking_adds_and_removes() {
let snapshot = InstanceSnapshot::new().name("Root").class_name("DataModel");
let child = InstanceSnapshot::new()
.name("TestFolder")
.class_name("Folder");
let mut tree = RojoTree::new(snapshot);
let root = tree.get_root_id();
let folder_id = tree.insert_instance(root, child);
assert!(!tree.script_refs().contains(&folder_id));
tree.update_script_tracking(folder_id, "Folder", "ModuleScript");
assert!(tree.script_refs().contains(&folder_id));
tree.update_script_tracking(folder_id, "ModuleScript", "Script");
assert!(tree.script_refs().contains(&folder_id));
tree.update_script_tracking(folder_id, "Script", "Folder");
assert!(!tree.script_refs().contains(&folder_id));
}
#[test]
fn swap_duped_specified_ids() {
let custom_ref = RojoRef::new("MyCoolRef".into());

View file

@ -23,7 +23,8 @@ use rbx_dom_weak::{
use crate::{
serve_session::ServeSession,
snapshot::{
InstanceSnapshot, InstanceWithMeta, InstigatingSource, PatchAdd, PatchSet, PatchUpdate,
is_script_class, InstanceSnapshot, InstanceWithMeta, InstigatingSource, PatchAdd, PatchSet,
PatchUpdate,
},
syncback::{slugify_name, VISIBLE_SERVICES},
web::{
@ -559,6 +560,9 @@ impl ApiService {
if temp_to_real.contains_key(guid) {
continue;
}
if !added.properties.is_empty() || !added.children.is_empty() {
continue;
}
let parent = added.parent.unwrap_or(Ref::none());
let real_parent = temp_to_real.get(&parent).copied().unwrap_or(parent);
if tree.get_instance(real_parent).is_none() {
@ -593,6 +597,9 @@ impl ApiService {
for guid in temp_to_real.keys() {
updated_in_place.insert(*guid);
}
request
.added
.retain(|guid, _| !temp_to_real.contains_key(guid));
}
}
@ -3604,8 +3611,6 @@ fn parent_requirements(class: &str) -> Option<&str> {
})
}
use crate::snapshot::is_script_class;
/// Filters a SubscribeMessage to only include scripts and their ancestors.
/// Non-script ancestors get ignoreUnknownInstances: true.
fn filter_subscribe_message_for_scripts<'a>(