81 lines
2.5 KiB
TypeScript
81 lines
2.5 KiB
TypeScript
/**
|
|
* Data type system for shape-to-shape data piping.
|
|
*
|
|
* Shapes declare typed input/output ports. Arrows connect ports,
|
|
* flowing data from source outputs to target inputs with type checking.
|
|
*/
|
|
|
|
import { FLOW_COLORS, type FlowKind } from "./layer-types";
|
|
|
|
/** Supported data types for ports. */
|
|
export type DataType =
|
|
| "string"
|
|
| "number"
|
|
| "boolean"
|
|
| "image-url"
|
|
| "video-url"
|
|
| "text"
|
|
| "json"
|
|
| "trigger"
|
|
| "any";
|
|
|
|
/** Describes a single input or output port on a shape. */
|
|
export interface PortDescriptor {
|
|
name: string;
|
|
type: DataType;
|
|
direction: "input" | "output";
|
|
}
|
|
|
|
/** Type compatibility matrix: can `source` flow into `target`? */
|
|
export function isCompatible(source: DataType, target: DataType): boolean {
|
|
if (source === target) return true;
|
|
if (target === "any" || source === "any") return true;
|
|
// text and string are interchangeable
|
|
if ((source === "text" && target === "string") || (source === "string" && target === "text")) return true;
|
|
// URLs are strings
|
|
if ((source === "image-url" || source === "video-url") && (target === "string" || target === "text")) return true;
|
|
// strings can be image/video URLs (user knows best)
|
|
if ((source === "string" || source === "text") && (target === "image-url" || target === "video-url")) return true;
|
|
return false;
|
|
}
|
|
|
|
/** Infer the FlowKind from a port name for flow-typed arrow coloring. */
|
|
export function inferFlowKind(portName: string): FlowKind {
|
|
const lower = portName.toLowerCase();
|
|
if (/balance|deposit|transfer|allocation|flow|wallet/.test(lower)) return "economic";
|
|
if (/vote|decision|proposal|governance|passed/.test(lower)) return "governance";
|
|
if (/trust|reputation|endorsement/.test(lower)) return "trust";
|
|
if (/attention|view|engagement/.test(lower)) return "attention";
|
|
if (/file|asset|resource|photo/.test(lower)) return "resource";
|
|
return "data";
|
|
}
|
|
|
|
/** Get the color for a FlowKind. */
|
|
export function flowKindColor(kind: FlowKind): string {
|
|
return FLOW_COLORS[kind] || "#94a3b8";
|
|
}
|
|
|
|
/** Color tint per data type for arrow visualization. */
|
|
export function dataTypeColor(type: DataType): string {
|
|
switch (type) {
|
|
case "text":
|
|
case "string":
|
|
return "#3b82f6"; // blue
|
|
case "number":
|
|
return "#f59e0b"; // amber
|
|
case "boolean":
|
|
return "#8b5cf6"; // purple
|
|
case "image-url":
|
|
return "#10b981"; // emerald
|
|
case "video-url":
|
|
return "#ef4444"; // red
|
|
case "json":
|
|
return "#6366f1"; // indigo
|
|
case "trigger":
|
|
return "#f97316"; // orange
|
|
case "any":
|
|
default:
|
|
return "#6b7280"; // gray
|
|
}
|
|
}
|