DocShell.Presentation.Source behaviour (DocShell v0.1.0)

Copy Markdown View Source

Producer contract for source-independent documentation presentation data.

A producer answers project/1 with a presentation/0, whatever it reads from — authored entries, a knowledge graph, or anything else. The renderer never learns which.

Why structs

These were maps with string keys, typed [map()], which described nothing. Two producers drifted apart under that spec without anything noticing: one emitted kind, meta, and tokens, the other omitted all three, so the renderer's TypeScript had to guess — and guessed wrong on all of them.

Structs make the shape a compile-time fact. The wire form is unchanged — DocShell.Json.stringify/1 renders them as the same string-keyed JSON — but every producer now emits the same keys, with nil where a facet does not apply, so an artifact no longer depends on who wrote it.

Summary

Types

A renderer-neutral documentation artifact.

Types

presentation()

@type presentation() :: %{
  :schema_version => String.t(),
  :navigation => [DocShell.Presentation.NavigationItem.t()],
  :search => [DocShell.Presentation.SearchEntry.t()],
  :content => %{optional(String.t()) => [DocShell.Ast.ast_node()]},
  optional(:backlinks) => %{
    optional(String.t()) => [DocShell.Presentation.Backlink.t()]
  }
}

A renderer-neutral documentation artifact.

content maps an entry id to its AST nodes; backlinks maps an entry id to the entries that reference it.

Callbacks

project(keyword)

@callback project(keyword()) :: {:ok, presentation()} | {:error, term()}