Visualize.VirtualSource (Visualize v0.8.1)

Copy Markdown View Source

A virtual source: a source computed from other sources by a function, rows in and rows out (spec/08 §10.5, #643, D-194).

It is data — id, its inputs (from), its output's schema, and its function as source text (elixir, checked by Visualize.VirtualSource.Sandbox) or a host function's name (function, defined with Visualize.VirtualSources.defsource/2) — so a board holds it and a codec writes it. With per: the function runs once per entity of one input and its rows are joined back by that input's declared identity (D-167).

iex> {:ok, health} =
...>   Visualize.VirtualSource.new(
...>     id: :health,
...>     from: [hosts: {:window, last: 20}],
...>     per: :identity,
...>     schema: %{
...>       host: %{type: :category, identity: true},
...>       state: %{type: :category, values: [:ok, :warning, :error]}
...>     },
...>     elixir: "fn rows -> %{state: :ok} end"
...>   )
iex> health.from
[{"hosts", %{last: 20}}]
iex> Visualize.VirtualSource.conform(health, [%{host: "a", state: :ok}])
{:ok, [%{host: "a", state: :ok}]}
iex> Visualize.VirtualSource.conform(health, [%{host: "a", state: :unknown}])
{:error, {0, "state", :not_in_values}}
iex> Visualize.VirtualSource.resolve([[:health], [:ops, :health]], [:ops], :health)
{:ok, ["ops", "health"]}

Summary

Types

A fault: the path from the source to the value, and why (spec/14 §10.1).

What an input names (spec/08 §10.5.6): a short id or a feed, a feed, a path.

t()

How much of an input the function needs (spec/08 §10.5.6).

Functions

An answer held to the source's schema (spec/08 §10.5.7): {:ok, rows}, or {:error, {index, field, reason}} for the first row that does not hold — never the value.

A path shown dotted (spec/08 §10.5.9).

One fault as a line a person reads, the root named virtual source (spec/08 §10.5.5).

The name of the input a per source's entities come from — the only input under :identity, the one named under {:identity, input} — or nil without per (spec/08 §10.5.7).

The key an input is read under (spec/08 §10.5.6): its name, or a path's last atom.

A virtual source of its map form or a keyword list of the same keys, checked alone (spec/08 §10.5.5): {:ok, source}, or {:error, errors} with every fault by path. {:window, opts} is read as the window map opts makes.

The virtual source, or ArgumentError naming every fault.

What a reference names (spec/08 §10.5.9), given every definition's path (a list, or a map keyed by path) and the scope it is read from: a short id from the inside out — the scope, then each container around it — a full path exactly. {:ok, path} or :error; a string is a feed's name and is never resolved.

The source's map form (spec/08 §10.5.10): new(to_map(source)) is {:ok, source}.

:ok, or every fault of the source given what it reads (spec/08 §10.5.5): inputs:, a map from an input's name to its %Visualize.Data.Schema{} where it is known; functions:, the host functions' registry (Visualize.VirtualSources.registry/1), or nil to leave the name unchecked; and vars:, the names of the variables the source's scope declares, or nil to leave a stored function's literal reads of them unchecked (D-228).

Types

error()

@type error() :: {list(), term()}

A fault: the path from the source to the value, and why (spec/14 §10.1).

name()

@type name() :: atom() | String.t() | [atom(), ...]

What an input names (spec/08 §10.5.6): a short id or a feed, a feed, a path.

t()

@type t() :: %Visualize.VirtualSource{
  elixir: String.t() | nil,
  from: [{name(), window()}, ...],
  function: atom() | nil,
  id: atom(),
  per: nil | :identity | {:identity, name()},
  schema: Visualize.Data.Schema.t()
}

window()

@type window() ::
  nil
  | %{last: pos_integer()}
  | %{optional(:ranges) => map(), optional(:latest) => boolean()}

How much of an input the function needs (spec/08 §10.5.6).

Functions

conform(virtual_source, rows)

@spec conform(t(), term()) ::
  {:ok, [map()]} | {:error, {non_neg_integer() | nil, term(), term()}}

An answer held to the source's schema (spec/08 §10.5.7): {:ok, rows}, or {:error, {index, field, reason}} for the first row that does not hold — never the value.

dotted(path)

@spec dotted([atom()]) :: String.t()

A path shown dotted (spec/08 §10.5.9).

iex> Visualize.VirtualSource.dotted([:ops, :health])
"ops.health"

format_error(error)

@spec format_error(error()) :: String.t()

One fault as a line a person reads, the root named virtual source (spec/08 §10.5.5).

iex> Visualize.VirtualSource.format_error({[:per], {:per, :ambiguous}})
"per: is :identity over several inputs: name the input, {:identity, input}"

identity_input(virtual_source)

@spec identity_input(t()) :: name() | nil

The name of the input a per source's entities come from — the only input under :identity, the one named under {:identity, input} — or nil without per (spec/08 §10.5.7).

key(path)

@spec key(name()) :: atom() | String.t() | nil

The key an input is read under (spec/08 §10.5.6): its name, or a path's last atom.

iex> Visualize.VirtualSource.key([:ops, :health])
:health
iex> Visualize.VirtualSource.key("vm.memory.total")
"vm.memory.total"

new(source)

@spec new(map() | keyword()) :: {:ok, t()} | {:error, [error(), ...]}

A virtual source of its map form or a keyword list of the same keys, checked alone (spec/08 §10.5.5): {:ok, source}, or {:error, errors} with every fault by path. {:window, opts} is read as the window map opts makes.

new!(source)

@spec new!(map() | keyword()) :: t()

The virtual source, or ArgumentError naming every fault.

resolve(paths, scope, ref)

@spec resolve([[atom()]] | map(), [atom()], name()) :: {:ok, [atom()]} | :error

What a reference names (spec/08 §10.5.9), given every definition's path (a list, or a map keyed by path) and the scope it is read from: a short id from the inside out — the scope, then each container around it — a full path exactly. {:ok, path} or :error; a string is a feed's name and is never resolved.

iex> paths = [[:health], [:ops, :health], [:ops, :box, :load]]
iex> Visualize.VirtualSource.resolve(paths, [:ops, :box], :health)
{:ok, ["ops", "health"]}
iex> Visualize.VirtualSource.resolve(paths, [:other], :health)
{:ok, ["health"]}
iex> Visualize.VirtualSource.resolve(paths, [], [:ops, :box, :load])
{:ok, ["ops", "box", "load"]}
iex> Visualize.VirtualSource.resolve(paths, [:ops], {:feed, "health"})
:error

to_map(source)

@spec to_map(t()) :: map()

The source's map form (spec/08 §10.5.10): new(to_map(source)) is {:ok, source}.

validate(source, opts \\ [])

@spec validate(t(), keyword()) :: :ok | {:error, [error(), ...]}

:ok, or every fault of the source given what it reads (spec/08 §10.5.5): inputs:, a map from an input's name to its %Visualize.Data.Schema{} where it is known; functions:, the host functions' registry (Visualize.VirtualSources.registry/1), or nil to leave the name unchecked; and vars:, the names of the variables the source's scope declares, or nil to leave a stored function's literal reads of them unchecked (D-228).