# `Expresso.Presenter.Schema`
[🔗](https://github.com/rellen/expresso/blob/main/lib/expresso/presenter/schema.ex#L1)

Describes each value that Elixir writes for the script of the presenter

The renderer writes seven values for the script:

  * the program that `Expresso.Presenter.Program` makes;
  * the list of the steps that `Expresso.Steps` makes;
  * the commands of a page of the overview and of a row of the menu;
  * the commands of the links that `Expresso.Goto` makes;
  * the sources of the embeds that `Expresso.Element.Embed` makes;
  * the sources of the videos that `Expresso.Element.Video` makes;
  * the sources of the sounds that `Expresso.Element.Audio` makes.

The two windows of the presenter also send a
message to each other. This module describes the JSON form of each value.
It is the one source of these forms:

  * `Expresso.Presenter.Verifier` reads the fields of the state, the views,
    the built-in functions and the kind of each value from it.
  * `Expresso.Test.SchemaWriter` writes `assets/src/schema.ts` from it. That
    file holds a TypeScript type and a decoder for each value. A test fails
    when the file does not agree with this module.
  * `Expresso.Presenter.Schema.Check` examines a value with the forms.
    The verifier uses it for the values of a definition, and the tests use
    it for each value that the renderer writes.

`types/0` returns the forms in order. A form can name an earlier form only.
`t:type/0` describes the terms of a form.

`constants/0` returns the constants of the script, such as the kinds of
element and the selectors of the elements that hold commands.
`Expresso.Test.SchemaWriter` writes each constant into
`assets/src/schema.ts` too, so the script and Elixir use the same values.

# `kind`

```elixir
@type kind() :: :index | :slide | :view | :boolean | :digits
```

The kind of value of a field of the state

# `type`

```elixir
@type type() ::
  :boolean
  | :string
  | {:string, String.t()}
  | {:integer, integer() | nil}
  | {:number, number() | nil, number() | nil}
  | {:literal, String.t() | boolean() | integer()}
  | {:enum, [String.t()]}
  | {:nullable, type()}
  | {:list, type()}
  | {:tuple, [type()]}
  | {:object, [{atom(), type()}]}
  | {:open_object, [{atom(), type()}]}
  | {:partial, [{atom(), type()}]}
  | {:record, [{atom(), type()}]}
  | {:union, [type()]}
  | {:ref, atom()}
```

The form of a JSON value

  * `:boolean` and `:string` - a value of that type.
  * `{:string, pattern}` - a string that agrees with a regular expression,
    in source text.
  * `{:integer, min}` - an integer that is not less than `min`, or any
    integer for `nil`.
  * `{:number, min, max}` - a finite number from `min` to `max`. `nil` sets
    no limit.
  * `{:literal, value}` - exactly one string, boolean or integer.
  * `{:enum, values}` - one of the strings.
  * `{:nullable, type}` - a value of the type, or `null`.
  * `{:list, type}` - an array of values of the type.
  * `{:tuple, types}` - an array with one value of each type, in order.
  * `{:record, fields}` - an array with one value of each field, in order.
    The script reads it as an object with these keys, and
    `Expresso.Presenter.Schema.Record.write/2` writes it. Only a form with
    a name that starts with `written_` holds a record, or a union of records
    with the same keys.
  * `{:object, fields}` - an object with exactly these keys.
  * `{:open_object, fields}` - an object with these keys. It can have other
    keys, and the decoder does not return them.
  * `{:partial, fields}` - an object with some of these keys and no other key.
  * `{:union, types}` - a value of one of the types.
  * `{:ref, name}` - the form of `types/0` with that name.

# `builtins`

```elixir
@spec builtins() :: [atom()]
```

Return the built-in functions of the browser that a command can call

# `constants`

```elixir
@spec constants() :: [{atom(), String.t(), type(), term()}]
```

Return each constant of the script, with its name, the text that tells
what it is, its form and its value

A constant comes from Elixir and goes into the script when esbuild makes
the bundle, so the document does not hold it.

# `directions`

```elixir
@spec directions() :: [atom()]
```

Return the directions of a swipe

# `fields`

```elixir
@spec fields() :: [{atom(), kind()}]
```

Return the fields of the state and the kind of value of each field, in order

# `kind`

```elixir
@spec kind(kind()) :: type()
```

Return the form of a value of a kind

    iex> Expresso.Presenter.Schema.kind(:slide)
    {:integer, 1}

# `regions`

```elixir
@spec regions() :: [atom()]
```

Return the parts of the window under a click

# `transitions`

```elixir
@spec transitions() :: [atom()]
```

Return the built-in kinds of the transition into a slide

# `types`

```elixir
@spec types() :: [{atom(), String.t(), type()}]
```

Return each form, with its name and the text that tells what it is

The forms come in order. A form can name an earlier form only.

# `views`

```elixir
@spec views() :: [atom()]
```

Return the views of the presenter

---

*Consult [api-reference.md](api-reference.md) for complete listing*
