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.
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
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.
@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
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).
iex> Visualize.VirtualSource.dotted([:ops, :health])
"ops.health"
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}"
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.
iex> Visualize.VirtualSource.key([:ops, :health])
:health
iex> Visualize.VirtualSource.key("vm.memory.total")
"vm.memory.total"
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.
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
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).