Show red connectors on a type-erroring node and accurate connector colors upstream of it (#3110)

* Refactor TypeSource

* Add complete valid types

* Add invalid type

* Improve valid/complete types and disconnecting

* Code review

* Return types on error

---------

Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
Adam Gerhant
2025-11-18 19:00:32 -08:00
committed by GitHub
parent 7d739c4542
commit 06484ef4e0
19 changed files with 543 additions and 448 deletions

View File

@@ -39,11 +39,6 @@ pub struct NodeTypes {
pub output: Type,
}
#[derive(PartialEq, Clone, Debug, Default, serde::Serialize, serde::Deserialize)]
pub struct ResolvedDocumentNodeTypes {
pub types: HashMap<Vec<NodeId>, NodeTypes>,
}
type Path = Box<[NodeId]>;
#[derive(PartialEq, Clone, Debug, Default, serde::Serialize, serde::Deserialize)]
@@ -69,10 +64,34 @@ impl DynamicExecutor {
/// Updates the existing [`BorrowTree`] to reflect the new [`ProtoNetwork`], reusing nodes where possible.
#[cfg_attr(debug_assertions, inline(never))]
pub async fn update(&mut self, proto_network: ProtoNetwork) -> Result<ResolvedDocumentNodeTypesDelta, GraphErrors> {
pub async fn update(&mut self, proto_network: ProtoNetwork) -> Result<ResolvedDocumentNodeTypesDelta, (ResolvedDocumentNodeTypesDelta, GraphErrors)> {
self.output = proto_network.output;
self.typing_context.update(&proto_network)?;
let (add, orphaned) = self.tree.update(proto_network, &self.typing_context).await?;
self.typing_context.update(&proto_network).map_err(|e| {
// If there is an error then get types that have been resolved before the error
let add = proto_network
.nodes
.iter()
.filter_map(|(id, node)| node.original_location.path.as_ref().map(|path| (path.clone().into_boxed_slice(), self.typing_context.infer(*id, node))))
.take_while(|(_, r)| r.is_ok())
.map(|(path, r)| {
let r = r.unwrap();
(
path,
NodeTypes {
inputs: r.inputs,
output: r.return_value,
},
)
})
.collect::<Vec<_>>();
(ResolvedDocumentNodeTypesDelta { add, remove: Vec::new() }, e)
})?;
let (add, orphaned) = self
.tree
.update(proto_network, &self.typing_context)
.await
.map_err(|e| (ResolvedDocumentNodeTypesDelta::default(), e))?;
let old_to_remove = core::mem::replace(&mut self.orphaned_nodes, orphaned);
let mut remove = Vec::with_capacity(old_to_remove.len() - self.orphaned_nodes.len().min(old_to_remove.len()));
for node_id in old_to_remove {

View File

@@ -51,6 +51,7 @@ pub fn wrap_network_in_scope(mut network: NodeNetwork, editor_api: Arc<WasmEdito
},
..Default::default()
},
// Keep this in sync with the protonode in valid_input_types
DocumentNode {
call_argument: concrete!(Context),
inputs: vec![NodeInput::scope("editor-api"), NodeInput::node(NodeId(2), 0), NodeInput::node(NodeId(1), 0)],