Skip to content

Commit

Permalink
Add types to constant node
Browse files Browse the repository at this point in the history
  • Loading branch information
rm-dr committed Nov 9, 2024
1 parent 9fb24df commit 9c3ebde
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 25 deletions.
81 changes: 76 additions & 5 deletions copperc/src/app/u/pipeline/_nodes/constant.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import { NumberInput, Select, TextInput } from "@mantine/core";
import { Node, NodeProps, useReactFlow } from "@xyflow/react";
import { BaseNode } from "./base";
import { NodeDef } from ".";
import { stringUnionToArray } from "@/lib/util";

const types = ["Text", "Integer", "Float"] as const;
type ValueType =
| {
type: "Text";
Expand All @@ -12,8 +12,25 @@ type ValueType =
| {
type: "Integer";
value: number;
}
| {
type: "Float";
value: number;
}
| {
type: "Boolean";
value: boolean;
};

type ConstType = ValueType["type"];

export const constTypes = stringUnionToArray<ConstType>()(
"Text",
"Integer",
"Float",
"Boolean",
);

type ConstantNodeType = Node<
{
value: ValueType;
Expand Down Expand Up @@ -45,9 +62,9 @@ function ConstantNodeElement({ data, id }: NodeProps<ConstantNodeType>) {
input = (
<NumberInput
label="Value"
placeholder="enter constant number"
placeholder="enter constant integer"
onChange={(value) => {
if (typeof value === "string") {
if (typeof value !== "number") {
return;
}

Expand All @@ -62,6 +79,44 @@ function ConstantNodeElement({ data, id }: NodeProps<ConstantNodeType>) {
allowDecimal={false}
/>
);
} else if (data.value.type === "Float") {
input = (
<NumberInput
label="Value"
placeholder="enter constant float"
onChange={(value) => {
if (typeof value !== "number") {
return;
}

updateNodeData(id, {
value: {
type: "Float",
value,
},
});
}}
value={data.value.value}
allowDecimal={true}
/>
);
} else if (data.value.type === "Boolean") {
input = (
<Select
label="Value"
placeholder="enter constant boolean"
data={["true", "false"]}
value={data.value.value ? "true" : "false"}
onChange={(value) => {
updateNodeData(id, {
value: {
type: "Boolean",
value: value === "true",
},
});
}}
/>
);
}

return (
Expand All @@ -76,8 +131,10 @@ function ConstantNodeElement({ data, id }: NodeProps<ConstantNodeType>) {
<Select
label="Data type"
placeholder="Pick value"
data={types}
onChange={(value) => {
data={constTypes}
onChange={(v) => {
const value = v as ConstType | null;

if (value === null || value == data.value.type) {
return;
}
Expand All @@ -102,6 +159,20 @@ function ConstantNodeElement({ data, id }: NodeProps<ConstantNodeType>) {
value: 0,
},
});
} else if (value === "Float") {
updateNodeData(id, {
value: {
type: "Float",
value: 0,
},
});
} else if (value === "Boolean") {
updateNodeData(id, {
value: {
type: "Boolean",
value: false,
},
});
}
}}
value={data.value.type}
Expand Down
15 changes: 3 additions & 12 deletions copperc/src/app/u/pipeline/_nodes/input.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,11 @@
import { Select } from "@mantine/core";
import { Node, NodeProps, useReactFlow } from "@xyflow/react";
import { BaseNode } from "./base";
import { dataTypes } from "@/lib/attributes";
import { DataType, dataTypes } from "@/lib/attributes";
import { NodeDef } from ".";
import { components } from "@/lib/api/openapi";

const types = ["Text", "Integer", "Float"] as const;

type InputNodeType = Node<
{
type: (typeof types)[number];
},
"pipelineinput"
>;
type InputNodeType = Node<{ type: DataType }, "pipelineinput">;

function InputNodeElement({ data, id }: NodeProps<InputNodeType>) {
const { deleteElements, getEdges, updateNodeData } = useReactFlow();
Expand Down Expand Up @@ -92,8 +85,6 @@ export const InputNode: NodeDef<InputNodeType> = {
return null;
}

return {
type: data_type.value as (typeof types)[number],
};
return { type: data_type.value as DataType };
},
};
9 changes: 1 addition & 8 deletions copperc/src/lib/attributes/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,11 @@ import { _integerAttrType } from "./impls/integer";
import { _hashAttrType } from "./impls/hash";
import { _referenceAttrType } from "./impls/reference";
import { components } from "../api/openapi";
import { stringUnionToArray } from "../util";

export type DataType =
components["schemas"]["AttributeInfo"]["data_type"]["type"];

// Hack types to enforce `attrTypes`
type NonEmptyArray<T> = [T, ...T[]];
type MustInclude<T, U extends T[]> = [T] extends [U[keyof U]] ? U : never;
function stringUnionToArray<T>() {
return <U extends NonEmptyArray<T>>(...elements: MustInclude<T, U>) =>
elements;
}

export const dataTypes = stringUnionToArray<DataType>()(
"Text",
"Integer",
Expand Down
13 changes: 13 additions & 0 deletions copperc/src/lib/util.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Hack types to enforce `attrTypes`
type NonEmptyArray<T> = [T, ...T[]];
type MustInclude<T, U extends T[]> = [T] extends [U[keyof U]] ? U : never;

/**
* Hack that allows us to create a type-checked array
* that contains every variant of a string union.
*/
// TODO: uniqueness
export function stringUnionToArray<T>() {
return <U extends NonEmptyArray<T>>(...elements: MustInclude<T, U>) =>
elements;
}

0 comments on commit 9c3ebde

Please sign in to comment.