CreatingManifests
Previous: Creating a Custom Node | Table of Contents | Next: Best Practices
Creating Manifest Nodes
Polyform operates on Directed Acyclic Graphs (DAGs), where each node performs a specific task and connects to other nodes through inputs and outputs.
Manifest nodes are special types of nodes that define the final output of a graph, typically writing one or more files to the filesystem.
What is a Manifest?
A manifest is a structure that encapsulates a set of named entries, each representing an output artifact such as an image, mesh, or any other serializable content. It also optionally defines a "main" entry, which can help tell viewers the first entry to download.
For example, if we have a manifest for a textured GLTF, you might have 2 entries: the GLTF itself, and a seperate image file the GLTF references. In this scenario, we'd set the GLTF file to be the main entry that a viewer would initially download.
Here's the core structure used for manifests:
type Entry struct {
Metadata map[string]any `json:"metadata"` // Descriptive metadata about the artifact
Artifact Artifact `json:"-"` // The actual data to be written
}
type Manifest struct {
Main string `json:"main"` // Optional: name of the main entry
Entries map[string]Entry `json:"entries"` // All entries in the manifest
}
Artifacts
The Artifact
interface defines what it means to be a serializable output. Any type that implements this interface can be written as part of a manifest.
type Artifact interface {
Write(io.Writer) error // Defines how the artifact is written to disk or elsewhere
Mime() string // Describes the type of content (e.g., "image/png", "application/json")
}
Here's a minimal example for a text file:
type TextArtifact struct {
Content string
}
func (ta TextArtifact) Write(w io.Writer) error {
_, err := io.WriteString(w, ta.Content)
return err
}
func (ta TextArtifact) Mime() string {
return "text/plain"
}
Then you can include this in your manifest entry:
entry := manifest.Entry{
Metadata: map[string]any{"type": "text"},
Artifact: TextArtifact{Content: "Hello World!"},
}
Creating a Manifest Node
A manifest node in Polyform is simply a node whose output type is manifest.Manifest
. When Polyform runs a graph and reaches this node, it knows how to gather the manifest entries and process them as final outputs.
Here’s an example of what a simple manifest node might look like:
type MyManifestNode struct {
Image nodes.Output[image.Image] `description:"The image to export"`
Path nodes.Output[string] `description:"Path to export to"`
}
func (mmn MyManifestNode) Output(out *nodes.StructOutput[manifest.Manifest]) {
img := nodes.TryGetOutputValue(out, mmn.Image, nil)
if img == nil {
return
}
entry := manifest.Entry{
Metadata: map[string]any{
"description": "Exported PNG image",
},
Artifact: &manifest.ImageArtifact{
Image: img,
MimeType: "image/png",
},
}
entryPath := nodes.TryGetOutputValue(out, mmn.Path, "export.png")
out.Set(manifest.Manifest{
Main: entryPath,
Entries: map[string]manifest.Entry{
entryPath: entry,
},
})
}
Note:
manifest.ImageArtifact
in this example is a hypothetical implementation of theArtifact
interface that knows how to write an image as PNG.
Last updated