chore: make some things a bit more typesafe

This commit is contained in:
Max Richter
2025-11-23 15:15:38 +01:00
parent 2dcd797762
commit 64ea7ac349
4 changed files with 252 additions and 162 deletions

View File

@@ -2,17 +2,17 @@ import { Graph, NodeDefinition, NodeId } from "./types";
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
*/
* 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
*/
* @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: NodeId[]) => Promise<NodeDefinition[]>;
/**
* Get a node by id
@@ -27,30 +27,30 @@ export interface NodeRegistry {
getAllNodes: () => NodeDefinition[];
/**
* Register a new node
* @param wasmBuffer - The WebAssembly buffer for the node
* @returns The node definition
* Register a new node
* @param wasmBuffer - The WebAssembly buffer for the node
* @returns The node definition
*/
register: (wasmBuffer: ArrayBuffer) => Promise<NodeDefinition>;
cache?: AsyncCache<ArrayBuffer>;
}
export interface RuntimeExecutor {
/**
* Execute the given graph
* @param graph - The graph to execute
* @returns The result of the execution
*/
execute: (graph: Graph, settings: Record<string, unknown>) => Promise<Int32Array>;
* Execute the given graph
* @param graph - The graph to execute
* @returns The result of the execution
*/
execute: (
graph: Graph,
settings: Record<string, unknown>,
) => Promise<Int32Array>;
}
export interface SyncCache<T = unknown> {
/**
* The maximum number of items that can be stored in the cache
* @remarks When the cache size exceeds this value, the oldest items should be removed
*/
* The maximum number of items that can be stored in the cache
* @remarks When the cache size exceeds this value, the oldest items should be removed
*/
size: number;
/**
@@ -69,14 +69,13 @@ export interface SyncCache<T = unknown> {
* Clear the cache
*/
clear: () => void;
}
export interface AsyncCache<T = unknown> {
/**
* The maximum number of items that can be stored in the cache
* @remarks When the cache size exceeds this value, the oldest items should be removed
*/
* The maximum number of items that can be stored in the cache
* @remarks When the cache size exceeds this value, the oldest items should be removed
*/
size: number;
/**

View File

@@ -1,17 +1,27 @@
import { z } from "zod";
import { NodeInputSchema } from "./inputs";
export type NodeId = `${string}/${string}/${string}`;
export const NodeTypeSchema = z
.string()
.regex(/^[^/]+\/[^/]+\/[^/]+$/, "Invalid NodeId format")
.transform((value) => value as `${string}/${string}/${string}`);
export type NodeType = z.infer<typeof NodeTypeSchema>;
export const NodeSchema = z.object({
id: z.number(),
type: z.string(),
props: z.record(z.union([z.number(), z.array(z.number())])).optional(),
meta: z.object({
title: z.string().optional(),
lastModified: z.string().optional(),
}).optional(),
position: z.tuple([z.number(), z.number()])
type: NodeTypeSchema,
tmp: z.any().optional(),
props: z
.record(z.string(), z.union([z.number(), z.array(z.number())]))
.optional(),
meta: z
.object({
title: z.string().optional(),
lastModified: z.string().optional(),
})
.optional(),
position: z.tuple([z.number(), z.number()]),
});
export type Node = {
@@ -19,9 +29,9 @@ export type Node = {
depth?: number;
mesh?: any;
random?: number;
parents?: Node[],
children?: Node[],
inputNodes?: Record<string, Node>
parents?: Node[];
children?: Node[];
inputNodes?: Record<string, Node>;
type?: NodeDefinition;
downX?: number;
downY?: number;
@@ -30,17 +40,19 @@ export type Node = {
ref?: HTMLElement;
visible?: boolean;
isMoving?: boolean;
}
};
} & z.infer<typeof NodeSchema>;
export const NodeDefinitionSchema = z.object({
id: z.string(),
inputs: z.record(NodeInputSchema).optional(),
inputs: z.record(z.string(), NodeInputSchema).optional(),
outputs: z.array(z.string()).optional(),
meta: z.object({
description: z.string().optional(),
title: z.string().optional(),
}).optional(),
meta: z
.object({
description: z.string().optional(),
title: z.string().optional(),
})
.optional(),
});
export type NodeDefinition = z.infer<typeof NodeDefinitionSchema> & {
@@ -56,12 +68,14 @@ export type Socket = {
export type Edge = [Node, number, Node, string];
export const GraphSchema = z.object({
id: z.number().optional(),
meta: z.object({
title: z.string().optional(),
lastModified: z.string().optional(),
}).optional(),
settings: z.record(z.any()).optional(),
id: z.number(),
meta: z
.object({
title: z.string().optional(),
lastModified: z.string().optional(),
})
.optional(),
settings: z.record(z.string(), z.any()).optional(),
nodes: z.array(NodeSchema),
edges: z.array(z.tuple([z.number(), z.number(), z.number(), z.string()])),
});