feat: add validation to include_definition macro
This commit is contained in:
96
packages/types/src/index.ts
Normal file
96
packages/types/src/index.ts
Normal file
@ -0,0 +1,96 @@
|
||||
import type { NodeInput } from "./inputs";
|
||||
export type { NodeInput } from "./inputs";
|
||||
|
||||
export type Node = {
|
||||
id: number;
|
||||
type: string;
|
||||
props?: Record<string, any>,
|
||||
tmp?: {
|
||||
depth?: number;
|
||||
mesh?: any;
|
||||
random?: number;
|
||||
parents?: Node[],
|
||||
children?: Node[],
|
||||
inputNodes?: Record<string, Node>
|
||||
type?: NodeType;
|
||||
downX?: number;
|
||||
downY?: number;
|
||||
x?: number;
|
||||
y?: number;
|
||||
ref?: HTMLElement;
|
||||
visible?: boolean;
|
||||
isMoving?: boolean;
|
||||
},
|
||||
meta?: {
|
||||
title?: string;
|
||||
lastModified?: string;
|
||||
},
|
||||
position: [x: number, y: number]
|
||||
}
|
||||
|
||||
export type NodeType = {
|
||||
id: string;
|
||||
inputs?: Record<string, NodeInput>
|
||||
outputs?: string[];
|
||||
meta?: {
|
||||
title?: string;
|
||||
},
|
||||
execute?: (args: number[]) => unknown;
|
||||
}
|
||||
|
||||
export type Socket = {
|
||||
node: Node;
|
||||
index: number | string;
|
||||
position: [number, number];
|
||||
};
|
||||
|
||||
|
||||
export interface NodeRegistry {
|
||||
/**
|
||||
* The status of the node registry
|
||||
* @remarks The status should be "loading" when the registry is loading, "ready" when the registry is ready, and "error" if an error occurred while loading the registry
|
||||
*/
|
||||
status: "loading" | "ready" | "error";
|
||||
/**
|
||||
* Load the nodes with the given ids
|
||||
* @param nodeIds - The ids of the nodes to load
|
||||
* @returns A promise that resolves when the nodes are loaded
|
||||
* @throws An error if the nodes could not be loaded
|
||||
* @remarks This method should be called before calling getNode or getAllNodes
|
||||
*/
|
||||
load: (nodeIds: string[]) => Promise<void>;
|
||||
/**
|
||||
* Get a node by id
|
||||
* @param id - The id of the node to get
|
||||
* @returns The node with the given id, or undefined if no such node exists
|
||||
*/
|
||||
getNode: (id: string) => NodeType | undefined;
|
||||
/**
|
||||
* Get all nodes
|
||||
* @returns An array of all nodes
|
||||
*/
|
||||
getAllNodes: () => NodeType[];
|
||||
}
|
||||
|
||||
export interface RuntimeExecutor {
|
||||
/**
|
||||
* Execute the given graph
|
||||
* @param graph - The graph to execute
|
||||
* @returns The result of the execution
|
||||
*/
|
||||
execute: (graph: Graph) => unknown;
|
||||
}
|
||||
|
||||
|
||||
export type Edge = [Node, number, Node, string];
|
||||
|
||||
export type Graph = {
|
||||
id: number;
|
||||
meta?: {
|
||||
title?: string;
|
||||
lastModified?: string;
|
||||
},
|
||||
settings?: Record<string, any>,
|
||||
nodes: Node[];
|
||||
edges: [number, number, number, string][];
|
||||
}
|
50
packages/types/src/inputs.ts
Normal file
50
packages/types/src/inputs.ts
Normal file
@ -0,0 +1,50 @@
|
||||
type NodeInputFloat = {
|
||||
type: "float";
|
||||
element?: "slider";
|
||||
value?: number;
|
||||
min?: number;
|
||||
max?: number;
|
||||
step?: number;
|
||||
}
|
||||
|
||||
type NodeInputInteger = {
|
||||
type: "integer";
|
||||
element?: "slider";
|
||||
value?: number;
|
||||
min?: number;
|
||||
max?: number;
|
||||
}
|
||||
|
||||
type NodeInputBoolean = {
|
||||
type: "boolean";
|
||||
value?: boolean;
|
||||
}
|
||||
|
||||
type NodeInputSelect = {
|
||||
type: "select";
|
||||
labels: string[];
|
||||
value?: number;
|
||||
}
|
||||
|
||||
type NodeInputSeed = {
|
||||
type: "seed"
|
||||
value?: number;
|
||||
}
|
||||
|
||||
type DefaultOptions = {
|
||||
internal?: boolean;
|
||||
external?: boolean;
|
||||
setting?: string;
|
||||
label?: string | false;
|
||||
}
|
||||
|
||||
type InputTypes = (NodeInputSeed | NodeInputBoolean | NodeInputFloat | NodeInputInteger | NodeInputSelect);
|
||||
|
||||
export type NodeInput = InputTypes & {
|
||||
type: InputTypes["type"] | InputTypes["type"][];
|
||||
} & DefaultOptions;
|
||||
|
||||
|
||||
export type NodeInputType<T extends Record<string, NodeInput>> = {
|
||||
[K in keyof T]: T[K]["value"]
|
||||
};
|
133
packages/types/src/lib.rs
Normal file
133
packages/types/src/lib.rs
Normal file
@ -0,0 +1,133 @@
|
||||
use serde::{Deserialize, Deserializer, Serialize};
|
||||
use serde_json::Value;
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
#[serde(tag = "type")]
|
||||
#[allow(non_camel_case_types)]
|
||||
pub enum InputTypes {
|
||||
float(NodeInputFloat),
|
||||
integer(NodeInputInteger),
|
||||
boolean(NodeInputBoolean),
|
||||
select(NodeInputSelect),
|
||||
seed(NodeInputSeed),
|
||||
model(NodeInputModel),
|
||||
plant(NodeInputPlant),
|
||||
vec3(NodeInputVec3),
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct NodeInputVec3 {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub value: Option<Vec<f64>>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct NodeInputFloat {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub value: Option<f64>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub min: Option<f64>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub max: Option<f64>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub step: Option<f64>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct NodeInputInteger {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub element: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub value: Option<i64>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub min: Option<i64>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub max: Option<i64>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct NodeInputBoolean {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub value: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct NodeInputSelect {
|
||||
pub labels: Vec<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub value: Option<usize>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct NodeInputSeed {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub value: Option<usize>,
|
||||
}
|
||||
|
||||
// Assuming similar structure as other NodeInput types for Model and Plant
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct NodeInputModel {
|
||||
// Model-specific fields can be added here
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct NodeInputPlant {
|
||||
// Plant-specific fields can be added here
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct DefaultOptions {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub internal: Option<bool>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub external: Option<bool>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub setting: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub label: Option<serde_json::Value>, // To handle both String and false
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
#[serde(untagged)]
|
||||
pub enum NodeTypeOrArray {
|
||||
Single(InputTypes),
|
||||
Multiple(Vec<String>),
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct NodeInput {
|
||||
pub types: Vec<String>,
|
||||
pub options: DefaultOptions,
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for NodeInput {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let raw_input: Value = Deserialize::deserialize(deserializer)?;
|
||||
let options: DefaultOptions =
|
||||
DefaultOptions::deserialize(&raw_input).map_err(serde::de::Error::custom)?; // Maps deserialization errors appropriately
|
||||
|
||||
let types: Vec<String> = match raw_input.get("type") {
|
||||
Some(Value::String(single_type)) => vec![single_type.clone()],
|
||||
Some(Value::Array(types)) => types
|
||||
.iter()
|
||||
.map(|t| t.as_str().unwrap_or("").to_owned())
|
||||
.collect(),
|
||||
_ => return Err(serde::de::Error::custom("Invalid or missing 'type' field")),
|
||||
};
|
||||
|
||||
Ok(NodeInput { types, options })
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug, Serialize)]
|
||||
pub struct NodeType {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub inputs: Option<HashMap<String, NodeInput>>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub outputs: Option<Vec<String>>,
|
||||
}
|
||||
|
26
packages/types/src/parameters.ts
Normal file
26
packages/types/src/parameters.ts
Normal file
@ -0,0 +1,26 @@
|
||||
type RandomParameter = {
|
||||
type: "random";
|
||||
min: Parameter;
|
||||
max: Parameter;
|
||||
seed: number;
|
||||
}
|
||||
|
||||
|
||||
type MathParameter = {
|
||||
type: "math";
|
||||
op_type: number;
|
||||
a: Parameter;
|
||||
b: Parameter;
|
||||
}
|
||||
|
||||
|
||||
type NoiseParameter = {
|
||||
type: "noise";
|
||||
frequency: Parameter;
|
||||
amplitude: Parameter;
|
||||
seed: number;
|
||||
}
|
||||
|
||||
|
||||
type Parameter = number | RandomParameter | MathParameter | NoiseParameter;
|
||||
|
Reference in New Issue
Block a user