Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Consider output error for connectability #1725

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
12 changes: 12 additions & 0 deletions src/common/types/function.ts
Original file line number Diff line number Diff line change
Expand Up @@ -605,4 +605,16 @@ export class FunctionInstance {
// we say that types A is assignable to type B if they are not disjoint
return !isDisjointWith(iType, this.definition.convertInput(inputId, type));
}

/**
* Returns a new function instance with the given input assigned to the given type.
*/
withInput(inputId: InputId, type: NonNeverType): FunctionInstance {
return FunctionInstance.fromPartialInputs(this.definition, (id) => {
if (id === inputId) {
return type;
}
return this.inputs.get(id);
});
}
}
26 changes: 24 additions & 2 deletions src/renderer/contexts/GlobalNodeState.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -861,7 +861,7 @@ export const GlobalProvider = memo(

const outputType = sourceFn.outputs.get(sourceHandleId);
if (outputType !== undefined && !targetFn.canAssign(targetHandleId, outputType)) {
const schema = schemata.get(targetNode.data.schemaId);
const { schema } = targetFn.definition;
const input = schema.inputs.find((i) => i.id === targetHandleId)!;
const inputType = withoutNull(
targetFn.definition.inputDefaults.get(targetHandleId)!
Expand All @@ -884,6 +884,28 @@ export const GlobalProvider = memo(
);
}

if (
outputType !== undefined &&
targetFn.inputErrors.length === 0 &&
targetFn.outputErrors.length === 0
) {
const assignedFn = targetFn.withInput(targetHandleId, outputType);
if (assignedFn.outputErrors.length > 0) {
// the assigned caused output error
const errorId = assignedFn.outputErrors[0].outputId;

const { schema } = targetFn.definition;
const output = schema.outputs.find((o) => o.id === errorId)!;

if (output.neverReason) {
return invalid(
`Connection would cause the following error: ${output.neverReason}`
);
}
return invalid(`Connection would cause an output error.`);
}
}

const checkTargetChildren = (parentNode: Node<NodeData>): boolean => {
const targetChildren = getOutgoers(parentNode, getNodes(), getEdges());
if (!targetChildren.length) {
Expand All @@ -908,7 +930,7 @@ export const GlobalProvider = memo(

return VALID;
},
[typeState.functions, getNode, getNodes, getEdges, schemata]
[typeState.functions, getNode, getNodes, getEdges]
);

const [inputDataChanges, addInputDataChanges] = useChangeCounter();
Expand Down