Help us shape the future of Go! Take the 2026 Go Developer Survey

nodedoc

package
v0.11.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 23, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Overview

Package nodedoc is the codec for a single node's portable file form — the frontmatter-markdown (and canonical JSON) representation that `hadron memory export`, `hadron node export`, and `hadron node import` all share.

It is deliberately decoupled from genqlient's generated types: the command layer maps a gen node to a Document (see api.DocumentFromBatchNode) and the codec maps a Document to and from bytes. Keeping the on-disk format pinned to this neutral struct means a GraphQL schema reshuffle can't ripple into the file format, and the encode/decode pair lives in one place so the round-trip invariant (parse∘render == identity) holds by construction.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ContentHash

func ContentHash(content string) string

ContentHash recomputes the server's content fingerprint: sha256 of the content, hex, first 8 chars; empty content has no hash. Matches hadron-server's computeContentHash (src/lib/contentHash.ts) so an exported contentHash equals the value the server would have written. The GraphQL API does not expose the stored hash column, so the codec recomputes it.

func DecodeJSON

func DecodeJSON(raw *json.RawMessage) any

DecodeJSON turns a GraphQL JSON scalar into a value yaml/json can render as a proper structure (not a quoted JSON string). A nil pointer, empty bytes, or a literal `null` decode to nil so a caller's omitempty drops the key.

func EncodeJSON

func EncodeJSON(v any) (*json.RawMessage, error)

EncodeJSON is the inverse of DecodeJSON: it marshals a decoded value back to a GraphQL JSON scalar (json.RawMessage), returning nil for a nil value so the caller omits the field. Used to map a Document's Data/Properties/edge Condition into mutation inputs.

func MarshalYAML

func MarshalYAML(v any) (string, error)

MarshalYAML encodes v as YAML with 2-space indents (matching the server's yaml writer) and trims the trailing newline so the caller controls the document framing.

func NodeFilePath

func NodeFilePath(root, loc string) (string, error)

NodeFilePath maps a loc to its on-disk markdown path under root. The empty-loc root node is README.md; every other node is <seg>/<seg>.md, so a node's path is stable whether or not it has children (children land in the sibling <seg>/ folder). Mirrors the server's nodeFilePath.

func RenderJSON

func RenderJSON(doc *Document) (string, error)

RenderJSON emits the Document as a single pretty-printed JSON object — the canonical shape ParseJSON reads, so json↔json is trivially lossless and md↔json share the in-memory Document. HTML escaping is off so content with <, >, & stays literal. The output ends in a newline (json.Encoder framing).

contentHash is a derived field, recomputed from content (same as the markdown codec) on a copy so both formats agree and a hand-built or batch-read Document — whose ContentHash the GraphQL projection never carries — still serializes a correct hash without mutating the caller's value.

func RenderMarkdown

func RenderMarkdown(doc *Document, standalone bool) (string, error)

RenderMarkdown produces the full node file: YAML frontmatter, then the node content as the body, framed as `---\n<fm>\n---\n\n<body>\n` (hadron-server's pushMemoryToGit file shape). When standalone is true the file carries its own loc/memory keys so a lone file is self-describing and re-importable without flags; a tree export passes false (loc lives in the path, memory in the sync target).

Types

type Document

type Document struct {
	ID                 string   `json:"id"`
	MemoryURN          string   `json:"memory"`
	Loc                string   `json:"loc"`
	Name               string   `json:"name"`
	Type               string   `json:"type"`
	Alias              string   `json:"alias"`
	Description        string   `json:"description"`
	Abstract           string   `json:"abstract"`
	AbstractOriginHash string   `json:"abstractOriginHash"`
	ContentHash        string   `json:"contentHash"`
	Tags               []string `json:"tags"`
	Seq                *int     `json:"seq"`
	Data               any      `json:"data"`
	Properties         any      `json:"properties"`
	Content            string   `json:"content"`
	Edges              []Edge   `json:"edges"`
}

Document is the in-memory representation of one node that both directions of both codecs share. Optional string fields use "" for "absent" (the markdown codec omits them); Seq/Data/Properties use nil. NodeType "" means the server default (info) — it is never serialized, so a re-import defaults correctly.

func ParseJSON

func ParseJSON(data []byte) (*Document, error)

ParseJSON is the inverse of RenderJSON. Edges is normalized to a non-nil slice so a Document's shape is stable ([] not null) across the codecs.

func ParseMarkdown

func ParseMarkdown(data []byte) (*Document, error)

ParseMarkdown is the inverse of RenderMarkdown: it splits the frontmatter from the body, parses the YAML header, applies the `description ?? summary` legacy fallback, and trims the body. It accepts both a standalone single-node file (with loc/memory keys) and a tree-export file (without). A file with no `---` frontmatter is rejected.

type Edge

type Edge struct {
	TargetID    string `json:"targetId"`
	TargetLoc   string `json:"targetLoc"`
	Name        string `json:"name"`
	Loc         string `json:"loc,omitempty"`
	Description string `json:"description,omitempty"`
	IsRunnable  bool   `json:"isRunnable,omitempty"`
	Condition   any    `json:"condition"`
	Priority    int    `json:"priority"`
}

Edge is one outgoing edge carried in a node's file. TargetLoc travels alongside TargetID for readability and as the portable key when re-homing a node into another memory, where the source TargetID no longer resolves. Name/Loc/Description/IsRunnable are the spec-037 first-class edge fields (Loc is the edge's own identity, distinct from TargetLoc). Condition and Priority round-trip the edge's gating and routing order.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL