Implement fromJSON, export, toJSON, toString serialization for FlowGraph
This commit is contained in:
@@ -1,13 +1,15 @@
|
||||
import { DirectedGraph } from "graphology";
|
||||
import type { TSchema, Static } from "@alkdev/typebox";
|
||||
import { Value } from "@alkdev/typebox/value";
|
||||
import { willCreateCycle, topologicalSort, hasCycle } from "graphology-dag";
|
||||
import {
|
||||
DuplicateNodeError,
|
||||
DuplicateEdgeError,
|
||||
NodeNotFoundError,
|
||||
CycleError,
|
||||
InvalidInputError,
|
||||
} from "../error/index.js";
|
||||
import type { CallStatus, AnyValidationError } from "../error/index.js";
|
||||
import type { CallStatus, AnyValidationError, ValidationError } from "../error/index.js";
|
||||
import {
|
||||
findCycles,
|
||||
reachableFrom as reachableFromFn,
|
||||
@@ -16,8 +18,10 @@ import { validate as _validate } from "./validation.js";
|
||||
import {
|
||||
OperationNodeAttrs as OperationNodeAttrsSchema,
|
||||
OperationEdgeAttrs as OperationEdgeAttrsSchema,
|
||||
OperationGraphSerialized,
|
||||
CallGraphSerialized,
|
||||
} from "../schema/index.js";
|
||||
import type { OperationNodeAttrs } from "../schema/index.js";
|
||||
import type { OperationNodeAttrs, FlowGraphSerialized } from "../schema/index.js";
|
||||
import { typeCompat, type TypeCompatResult } from "../analysis/type-compat.js";
|
||||
|
||||
export interface FlowGraphOptions {
|
||||
@@ -367,10 +371,64 @@ export class FlowGraph<
|
||||
throw new Error("not implemented");
|
||||
}
|
||||
|
||||
export(): FlowGraphSerialized {
|
||||
return this._graph.export() as unknown as FlowGraphSerialized;
|
||||
}
|
||||
|
||||
toJSON(): FlowGraphSerialized {
|
||||
return this.export();
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
return JSON.stringify(this.export());
|
||||
}
|
||||
|
||||
static fromJSON(
|
||||
_data: unknown,
|
||||
data: FlowGraphSerialized,
|
||||
): FlowGraph<TSchema, TSchema> {
|
||||
throw new Error("not implemented");
|
||||
const opCheck = Value.Check(OperationGraphSerialized, data);
|
||||
const callCheck = Value.Check(CallGraphSerialized, data);
|
||||
if (!opCheck && !callCheck) {
|
||||
const errors: ValidationError[] = [];
|
||||
const opIter = Value.Errors(OperationGraphSerialized, data as Record<string, unknown>);
|
||||
for (const err of opIter) {
|
||||
errors.push({
|
||||
type: "schema",
|
||||
nodeKey: "",
|
||||
field: err.path.replace(/^\//, "") || err.path,
|
||||
message: err.message,
|
||||
value: err.value,
|
||||
});
|
||||
}
|
||||
if (errors.length === 0) {
|
||||
const callIter = Value.Errors(CallGraphSerialized, data as Record<string, unknown>);
|
||||
for (const err of callIter) {
|
||||
errors.push({
|
||||
type: "schema",
|
||||
nodeKey: "",
|
||||
field: err.path.replace(/^\//, "") || err.path,
|
||||
message: err.message,
|
||||
value: err.value,
|
||||
});
|
||||
}
|
||||
}
|
||||
throw new InvalidInputError(errors);
|
||||
}
|
||||
|
||||
const fg = new FlowGraph<TSchema, TSchema>();
|
||||
for (const node of data.nodes) {
|
||||
fg._graph.addNode(node.key, node.attributes as Attrs);
|
||||
}
|
||||
for (const edge of data.edges) {
|
||||
fg._graph.addEdgeWithKey(edge.key, edge.source, edge.target, edge.attributes as Attrs);
|
||||
}
|
||||
|
||||
if (hasCycle(fg._graph)) {
|
||||
const cycles = findCycles(fg._graph);
|
||||
throw new CycleError(cycles);
|
||||
}
|
||||
|
||||
return fg;
|
||||
}
|
||||
|
||||
private _findPath(from: string, to: string): string[] {
|
||||
|
||||
Reference in New Issue
Block a user