diff --git a/backend/src/api/input.py b/backend/src/api/input.py
index ca53b1c6d..f18bc2e9d 100644
--- a/backend/src/api/input.py
+++ b/backend/src/api/input.py
@@ -49,6 +49,11 @@ def to_dict(self):
}
+@dataclass
+class IOFusion:
+ output_id: OutputId
+
+
class LiteralErrorValue(TypedDict):
type: Literal["literal"]
value: str | int | float | None
@@ -88,7 +93,7 @@ def __init__(
self.id: InputId = InputId(-1)
self.associated_type: Any = associated_type
- self.fused_with_output: OutputId | None = None
+ self.fused: IOFusion | None = None
# Optional documentation
self.description: str | None = None
@@ -141,7 +146,11 @@ def to_dict(self):
"hasHandle": self.has_handle,
"description": self.description,
"hint": self.hint,
- "fusedWithOutput": self.fused_with_output,
+ "fused": {
+ "outputId": self.fused.output_id,
+ }
+ if self.fused
+ else None,
}
def with_id(self, input_id: InputId | int):
@@ -160,8 +169,8 @@ def make_optional(self):
self.associated_type = Optional[associated_type]
return self
- def fused(self, with_output: OutputId | int = 0):
- self.fused_with_output = OutputId(with_output)
+ def make_fused(self, with_output: OutputId | int = 0):
+ self.fused = IOFusion(output_id=OutputId(with_output))
return self
def __repr__(self):
diff --git a/backend/src/packages/chaiNNer_standard/utility/color/color.py b/backend/src/packages/chaiNNer_standard/utility/color/color.py
index 4ff364f76..7b39e9749 100644
--- a/backend/src/packages/chaiNNer_standard/utility/color/color.py
+++ b/backend/src/packages/chaiNNer_standard/utility/color/color.py
@@ -13,7 +13,7 @@
description="Outputs the given color.",
icon="MdColorLens",
inputs=[
- ColorInput().fused(),
+ ColorInput().make_fused(),
],
outputs=[
ColorOutput(color_type="Input0"),
diff --git a/backend/src/packages/chaiNNer_standard/utility/value/directory.py b/backend/src/packages/chaiNNer_standard/utility/value/directory.py
index 0e66f021b..d3a9efef8 100644
--- a/backend/src/packages/chaiNNer_standard/utility/value/directory.py
+++ b/backend/src/packages/chaiNNer_standard/utility/value/directory.py
@@ -14,7 +14,7 @@
inputs=[
DirectoryInput(
"Directory", must_exist=False, hide_label=True, has_handle=True
- ).fused(),
+ ).make_fused(),
],
outputs=[
DirectoryOutput("Directory", output_type="Input0"),
diff --git a/backend/src/packages/chaiNNer_standard/utility/value/number.py b/backend/src/packages/chaiNNer_standard/utility/value/number.py
index 5be37dc54..03f79ea0b 100644
--- a/backend/src/packages/chaiNNer_standard/utility/value/number.py
+++ b/backend/src/packages/chaiNNer_standard/utility/value/number.py
@@ -19,7 +19,7 @@
precision=100,
controls_step=1,
hide_label=True,
- ).fused(),
+ ).make_fused(),
],
outputs=[
NumberOutput("Number", output_type="Input0"),
diff --git a/backend/src/packages/chaiNNer_standard/utility/value/pass_through.py b/backend/src/packages/chaiNNer_standard/utility/value/pass_through.py
index ac0bcb8bf..36ffc41c8 100644
--- a/backend/src/packages/chaiNNer_standard/utility/value/pass_through.py
+++ b/backend/src/packages/chaiNNer_standard/utility/value/pass_through.py
@@ -15,8 +15,12 @@
name="Pass Through",
description="Outputs the input value as is.",
icon="MdDoubleArrow",
- inputs=[AnyInput(label="Value")],
- outputs=[BaseOutput(output_type="Input0", label="Value")],
+ inputs=[
+ AnyInput(label="Value").make_fused(),
+ ],
+ outputs=[
+ BaseOutput(output_type="Input0", label="Value"),
+ ],
)
def pass_through_node(value: object) -> object:
return value
diff --git a/backend/src/packages/chaiNNer_standard/utility/value/percent.py b/backend/src/packages/chaiNNer_standard/utility/value/percent.py
index 202ed6aef..2210851f1 100644
--- a/backend/src/packages/chaiNNer_standard/utility/value/percent.py
+++ b/backend/src/packages/chaiNNer_standard/utility/value/percent.py
@@ -20,7 +20,7 @@
precision=0,
controls_step=1,
unit="%",
- ).fused(),
+ ).make_fused(),
],
outputs=[
NumberOutput("Percent", output_type="Input0"),
diff --git a/backend/src/packages/chaiNNer_standard/utility/value/text.py b/backend/src/packages/chaiNNer_standard/utility/value/text.py
index 40a77446f..a7192c7b8 100644
--- a/backend/src/packages/chaiNNer_standard/utility/value/text.py
+++ b/backend/src/packages/chaiNNer_standard/utility/value/text.py
@@ -14,7 +14,7 @@
inputs=[
TextInput(
"Text", min_length=0, hide_label=True, allow_empty_string=True
- ).fused(),
+ ).make_fused(),
],
outputs=[
TextOutput("Text", output_type="Input0"),
diff --git a/src/common/common-types.ts b/src/common/common-types.ts
index 57a9ad713..c40e46017 100644
--- a/src/common/common-types.ts
+++ b/src/common/common-types.ts
@@ -28,6 +28,10 @@ export interface InputConversionSchema {
readonly convert: ExpressionJson;
}
+export interface IOFusion {
+ readonly outputId: OutputId;
+}
+
interface InputBase {
readonly id: InputId;
readonly type: ExpressionJson;
@@ -54,7 +58,7 @@ interface InputBase {
readonly hasHandle: boolean;
readonly description?: string;
readonly hint: boolean;
- readonly fusedWithOutput?: OutputId | null;
+ readonly fused?: IOFusion | null;
}
export interface InputOption {
option: string;
diff --git a/src/renderer/components/inputs/SchemaInput.tsx b/src/renderer/components/inputs/SchemaInput.tsx
index 3b7fd82f0..8db16b5ac 100644
--- a/src/renderer/components/inputs/SchemaInput.tsx
+++ b/src/renderer/components/inputs/SchemaInput.tsx
@@ -1,5 +1,5 @@
import { NeverType } from '@chainner/navi';
-import { Box, HStack } from '@chakra-ui/react';
+import { Box, Center, HStack } from '@chakra-ui/react';
import { memo, useCallback } from 'react';
import { useContextSelector } from 'use-context-selector';
import { Input, InputKind, InputValue, Size } from '../../../common/common-types';
@@ -7,6 +7,7 @@ import { getInputValue } from '../../../common/util';
import { BackendContext } from '../../contexts/BackendContext';
import { NodeState } from '../../helpers/nodeState';
import { OutputHandle } from '../outputs/OutputContainer';
+import { TypeTags } from '../TypeTag';
import { ColorInput } from './ColorInput';
import { DirectoryInput } from './DirectoryInput';
import { DropDownInput } from './DropDownInput';
@@ -43,7 +44,7 @@ export interface SingleInputProps {
* Represents a single input from a schema's input list.
*/
export const SchemaInput = memo(({ input, nodeState, afterInput }: SingleInputProps) => {
- const { id: inputId, kind, hasHandle, fusedWithOutput } = input;
+ const { id: inputId, kind, hasHandle, fused } = input;
const {
schemaId,
id: nodeId,
@@ -132,28 +133,38 @@ export const SchemaInput = memo(({ input, nodeState, afterInput }: SingleInputPr
);
}
- if (fusedWithOutput != null) {
+ if (fused) {
+ const outputType = nodeState.type.instance?.outputs.get(fused.outputId);
+
const fusedOutputHandle = (
);
inputElement = (
-
+
{inputElement}
+ {input.kind === 'generic' && outputType && (
+
+
+
+ )}
{fusedOutputHandle}
);
diff --git a/src/renderer/components/node/NodeBody.tsx b/src/renderer/components/node/NodeBody.tsx
index 9997ea628..2bf0f7230 100644
--- a/src/renderer/components/node/NodeBody.tsx
+++ b/src/renderer/components/node/NodeBody.tsx
@@ -16,7 +16,7 @@ export const NodeBody = memo(({ nodeState, animated = false }: NodeBodyProps) =>
const autoInput = inputs.length === 1 && isAutoInput(inputs[0]);
const anyVisibleOutputs = outputs.some((output) => {
- return !inputs.some((input) => input.fusedWithOutput === output.id);
+ return !inputs.some((input) => input.fused?.outputId === output.id);
});
return (
diff --git a/src/renderer/components/node/NodeOutputs.tsx b/src/renderer/components/node/NodeOutputs.tsx
index b2756d98b..b5bc3c868 100644
--- a/src/renderer/components/node/NodeOutputs.tsx
+++ b/src/renderer/components/node/NodeOutputs.tsx
@@ -87,7 +87,7 @@ export const NodeOutputs = memo(({ nodeState, animated }: NodeOutputProps) => {
return (
<>
{schema.outputs.map((output) => {
- if (schema.inputs.some((i) => i.fusedWithOutput === output.id)) {
+ if (schema.inputs.some((i) => i.fused?.outputId === output.id)) {
return null;
}