import { type U } from "../utils"; import { type Graph, type MutGraph } from "."; /** an interface for hydrating serialized graph data */ export type Hydrator = (parsed: unknown) => T; /** convert graph to json */ export declare function toJson(grf: Graph): unknown; /** the operator that defines hydration */ export interface JsonOps { /** the node datum operator */ nodeDatum: Hydrator; /** the link datum operator */ linkDatum: Hydrator; } /** * an operator that hydrates serialized json into a graph * * Since type information is inherently lost with serialization, use {@link * nodeDatum} and {@link linkDatum} to define node and link data type, and * optionally perform extra deserialization. * * @typeParam NodeDatum - the node data type of the deserialized graph * @typeParam LinkDatum - the link data type of the deserialized graph * @typeParam Ops - the operators associated with deserialization */ export interface Json> { /** * deserialize parsed json as a graph * * @param json - the parsed json, usually created from `JSON.parse` * @returns graph - the deserialized graph */ (json: unknown): MutGraph; /** * set custom hydration for node data * * @example * * In the simpliest case, this can be used to cast the data types * appropriately (or alternatively you could just cast the Graph itself. * * ```ts * const grf: Graph = ... * const builder = graphJson().nodeDatum(data => data as number); * const deser: MutGraph = builder(JSON.parse(JSON.serialize(grf))); * ``` * * @example * * Ideally though, you'll use typescripts warnings to make serialization * error proof: * * ```ts * const grf: Graph = ... * const builder = graphJson().nodeDatum(data => { * if (typeof data === "number") { * return data; * } else { * throw new Error("..."); * } * }); * const deser: MutGraph = builder(JSON.parse(JSON.serialize(grf))); * ``` */ nodeDatum>(val: NewNode & Hydrator): Json>; /** get the node data hydrator */ nodeDatum(): Ops["nodeDatum"]; /** * set custom hydration for link data * * See {@link nodeDatum} for example of what {@link Hydrator}s should look * like. */ linkDatum>(val: NewLink & Hydrator): Json>; /** get the link data hydrator */ linkDatum(): Ops["linkDatum"]; } /** * the default {@link Json} operator created by {@link graphJson} * * This operator does no extra type conversion and so will result in unknown * data. */ export type DefaultJson = Json; /** * create a {@link Json} graph constructor with default settings * * If you serialize a graph or node using `JSON.stringify`, this operator can * be used to hydrate them back into a {@link MutGraph}. This is expecially * useful for serializing the graph to do layouts in a separate worker. * * If you serialize a {@link GraphNode} the deserialized graph will be the same * node that was serialized, but the rest of that node's connected component * will be deserialized as well, and still reachable via {@link Graph#nodes}. * The type information will inherently be lost, and will need to be cast. * * Since serialization doesn't inherently imply deserialization, * {@link Json#nodeDatum} and {@link Json#linkDatum} can be used to * provide custom hydration for node and linke data. * * @example * * This example shows how to deserialize a graph while losing type information. * * ```ts * const orig: Graph = ... * const serialized = JSON.stringify(orig); * const builder = graphJson(); * const deserialized = builder(JSON.parse(serialized)); * ``` * * Note, that because no custom hydrators were given, `deserialized` will have * type `MutGraph` which probably isn't desired. * * @example * * This example demonstrates using a simple data hydrator. * * ```ts * const orig: Graph = ... * const serialized = JSON.stringify(orig); * const builder = graphJson() * .nodeDatum(data => data as number) * .linkDatum(data => data as string); * const deserialized = builder(JSON.parse(serialized)); * ``` * * Now `deserialized` has the same type as the original grah. In real use, * you'll probably want to use type guards to guarantee the data was * deserialized correctly. */ export declare function graphJson(...args: readonly never[]): DefaultJson;