reactor/documentation/dsls/DSL:-Reactor.md

1498 lines
32 KiB
Markdown
Raw Normal View History

2023-12-15 10:36:25 +13:00
<!--
This file was generated by Spark. Do not edit it by hand.
-->
# DSL: Reactor.Dsl
## reactor
The top-level reactor DSL
### Nested DSLs
* [middlewares](#reactor-middlewares)
* middleware
2023-12-15 10:36:25 +13:00
* [around](#reactor-around)
* argument
* wait_for
* [collect](#reactor-collect)
* argument
* wait_for
* [compose](#reactor-compose)
* argument
* wait_for
* [debug](#reactor-debug)
* argument
* wait_for
* [flunk](#reactor-flunk)
* argument
* wait_for
2023-12-15 10:36:25 +13:00
* [group](#reactor-group)
* argument
* wait_for
* [input](#reactor-input)
* [map](#reactor-map)
* argument
* wait_for
2023-12-15 10:36:25 +13:00
* [step](#reactor-step)
* argument
* wait_for
* [switch](#reactor-switch)
* matches?
* default
### Options
| Name | Type | Default | Docs |
|------|------|---------|------|
| [`return`](#reactor-return){: #reactor-return } | `atom` | | Specify which step result to return upon completion. |
## reactor.middlewares
Middleware to be added to the Reactor
### Nested DSLs
* [middleware](#reactor-middlewares-middleware)
## reactor.middlewares.middleware
```elixir
middleware module
```
Name a middleware to be added to the Reactor.
### Arguments
| Name | Type | Default | Docs |
|------|------|---------|------|
| [`module`](#reactor-middlewares-middleware-module){: #reactor-middlewares-middleware-module .spark-required} | `module` | | The middleware to be added to the Reactor. |
### Introspection
Target: `Reactor.Dsl.Middleware`
2023-12-15 10:36:25 +13:00
## reactor.around
```elixir
around name, fun \\ nil
```
Wrap a function around a group of steps.
### Nested DSLs
* [argument](#reactor-around-argument)
* [wait_for](#reactor-around-wait_for)
### Arguments
| Name | Type | Default | Docs |
|------|------|---------|------|
| [`name`](#reactor-around-name){: #reactor-around-name .spark-required} | `atom` | | A unique name for the group of steps. |
2023-12-15 10:36:25 +13:00
| [`fun`](#reactor-around-fun){: #reactor-around-fun .spark-required} | `(any, any, any, any -> any) \| mfa` | | The around function. See `Reactor.Step.Around` for more information. |
### Options
| Name | Type | Default | Docs |
|------|------|---------|------|
| [`allow_async?`](#reactor-around-allow_async?){: #reactor-around-allow_async? } | `boolean` | `false` | Whether the emitted steps should be allowed to run asynchronously. |
## reactor.around.argument
```elixir
argument name, source \\ nil
```
Specifies an argument to a Reactor step.
Each argument is a value which is either the result of another step, or an input value.
Individual arguments can be transformed with an arbitrary function before
being passed to any steps.
### Examples
```
argument :name, input(:name)
```
```
argument :year, input(:date, [:year])
```
```
argument :user, result(:create_user)
```
```
argument :user_id, result(:create_user) do
transform & &1.id
end
```
```
argument :user_id, result(:create_user, [:id])
```
```
argument :three, value(3)
```
### Arguments
| Name | Type | Default | Docs |
|------|------|---------|------|
| [`name`](#reactor-around-argument-name){: #reactor-around-argument-name .spark-required} | `atom` | | The name of the argument which will be used as the key in the `arguments` map passed to the implementation. |
| [`source`](#reactor-around-argument-source){: #reactor-around-argument-source .spark-required} | `Reactor.Template.Element \| Reactor.Template.Input \| Reactor.Template.Result \| Reactor.Template.Value` | | What to use as the source of the argument. See `Reactor.Dsl.Argument` for more information. |
2023-12-15 10:36:25 +13:00
### Options
| Name | Type | Default | Docs |
|------|------|---------|------|
| [`transform`](#reactor-around-argument-transform){: #reactor-around-argument-transform } | `(any -> any) \| module \| nil` | | An optional transformation function which can be used to modify the argument before it is passed to the step. |
### Introspection
Target: `Reactor.Dsl.Argument`
## reactor.around.wait_for
```elixir
wait_for names
```
Wait for the named step to complete before allowing this one to start.
Desugars to `argument :_, result(step_to_wait_for)`
### Examples
```
wait_for :create_user
```
### Arguments
| Name | Type | Default | Docs |
|------|------|---------|------|
| [`names`](#reactor-around-wait_for-names){: #reactor-around-wait_for-names .spark-required} | `atom \| list(atom)` | | The name of the step to wait for. |
### Introspection
Target: `Reactor.Dsl.WaitFor`
### Introspection
Target: `Reactor.Dsl.Around`
## reactor.collect
```elixir
collect name
```
A Reactor step which simply collects and returns it's arguments.
Arguments can optionally be transformed before returning.
### Nested DSLs
* [argument](#reactor-collect-argument)
* [wait_for](#reactor-collect-wait_for)
### Examples
```
collect :latest_release_uri do
argument :repository, input(:repository)
argument :organisation, input(:organisation)
transform fn inputs ->
%{uri: "https://api.github.com/repos/#{inputs.organisation}/#{inputs.repository}/releases/latest"}
end
end
```
### Arguments
| Name | Type | Default | Docs |
|------|------|---------|------|
| [`name`](#reactor-collect-name){: #reactor-collect-name .spark-required} | `atom` | | A unique name for the step. Used when choosing the return value of the Reactor and for arguments into other steps. |
### Options
| Name | Type | Default | Docs |
|------|------|---------|------|
| [`transform`](#reactor-collect-transform){: #reactor-collect-transform } | `(any -> any) \| module \| nil` | | An optional transformation function which can be used to modify the entire argument map before it is returned. |
## reactor.collect.argument
```elixir
argument name, source \\ nil
```
Specifies an argument to a Reactor step.
Each argument is a value which is either the result of another step, or an input value.
Individual arguments can be transformed with an arbitrary function before
being passed to any steps.
### Examples
```
argument :name, input(:name)
```
```
argument :year, input(:date, [:year])
```
```
argument :user, result(:create_user)
```
```
argument :user_id, result(:create_user) do
transform & &1.id
end
```
```
argument :user_id, result(:create_user, [:id])
```
```
argument :three, value(3)
```
### Arguments
| Name | Type | Default | Docs |
|------|------|---------|------|
| [`name`](#reactor-collect-argument-name){: #reactor-collect-argument-name .spark-required} | `atom` | | The name of the argument which will be used as the key in the `arguments` map passed to the implementation. |
| [`source`](#reactor-collect-argument-source){: #reactor-collect-argument-source .spark-required} | `Reactor.Template.Element \| Reactor.Template.Input \| Reactor.Template.Result \| Reactor.Template.Value` | | What to use as the source of the argument. See `Reactor.Dsl.Argument` for more information. |
2023-12-15 10:36:25 +13:00
### Options
| Name | Type | Default | Docs |
|------|------|---------|------|
| [`transform`](#reactor-collect-argument-transform){: #reactor-collect-argument-transform } | `(any -> any) \| module \| nil` | | An optional transformation function which can be used to modify the argument before it is passed to the step. |
### Introspection
Target: `Reactor.Dsl.Argument`
## reactor.collect.wait_for
```elixir
wait_for names
```
Wait for the named step to complete before allowing this one to start.
Desugars to `argument :_, result(step_to_wait_for)`
### Examples
```
wait_for :create_user
```
### Arguments
| Name | Type | Default | Docs |
|------|------|---------|------|
| [`names`](#reactor-collect-wait_for-names){: #reactor-collect-wait_for-names .spark-required} | `atom \| list(atom)` | | The name of the step to wait for. |
### Introspection
Target: `Reactor.Dsl.WaitFor`
### Introspection
Target: `Reactor.Dsl.Collect`
## reactor.compose
```elixir
compose name, reactor
```
Compose another Reactor into this one.
Allows place another Reactor into this one as if it were a single step.
### Nested DSLs
* [argument](#reactor-compose-argument)
* [wait_for](#reactor-compose-wait_for)
### Arguments
| Name | Type | Default | Docs |
|------|------|---------|------|
| [`name`](#reactor-compose-name){: #reactor-compose-name .spark-required} | `atom` | | A unique name for the step. Allows the result of the composed reactor to be depended upon by steps in this reactor. |
| [`reactor`](#reactor-compose-reactor){: #reactor-compose-reactor .spark-required} | `Reactor \| module` | | The reactor module or struct to compose upon. |
## reactor.compose.argument
```elixir
argument name, source \\ nil
```
Specifies an argument to a Reactor step.
Each argument is a value which is either the result of another step, or an input value.
Individual arguments can be transformed with an arbitrary function before
being passed to any steps.
### Examples
```
argument :name, input(:name)
```
```
argument :year, input(:date, [:year])
```
```
argument :user, result(:create_user)
```
```
argument :user_id, result(:create_user) do
transform & &1.id
end
```
```
argument :user_id, result(:create_user, [:id])
```
```
argument :three, value(3)
```
### Arguments
| Name | Type | Default | Docs |
|------|------|---------|------|
| [`name`](#reactor-compose-argument-name){: #reactor-compose-argument-name .spark-required} | `atom` | | The name of the argument which will be used as the key in the `arguments` map passed to the implementation. |
| [`source`](#reactor-compose-argument-source){: #reactor-compose-argument-source .spark-required} | `Reactor.Template.Element \| Reactor.Template.Input \| Reactor.Template.Result \| Reactor.Template.Value` | | What to use as the source of the argument. See `Reactor.Dsl.Argument` for more information. |
2023-12-15 10:36:25 +13:00
### Options
| Name | Type | Default | Docs |
|------|------|---------|------|
| [`transform`](#reactor-compose-argument-transform){: #reactor-compose-argument-transform } | `(any -> any) \| module \| nil` | | An optional transformation function which can be used to modify the argument before it is passed to the step. |
### Introspection
Target: `Reactor.Dsl.Argument`
## reactor.compose.wait_for
```elixir
wait_for names
```
Wait for the named step to complete before allowing this one to start.
Desugars to `argument :_, result(step_to_wait_for)`
### Examples
```
wait_for :create_user
```
### Arguments
| Name | Type | Default | Docs |
|------|------|---------|------|
| [`names`](#reactor-compose-wait_for-names){: #reactor-compose-wait_for-names .spark-required} | `atom \| list(atom)` | | The name of the step to wait for. |
### Introspection
Target: `Reactor.Dsl.WaitFor`
### Introspection
Target: `Reactor.Dsl.Compose`
## reactor.debug
```elixir
debug name
```
Inserts a step which will send debug information to the `Logger`.
### Nested DSLs
* [argument](#reactor-debug-argument)
* [wait_for](#reactor-debug-wait_for)
### Examples
```
debug :debug do
argument :suss, result(:suss_step)
end
```
### Arguments
| Name | Type | Default | Docs |
|------|------|---------|------|
| [`name`](#reactor-debug-name){: #reactor-debug-name .spark-required} | `atom` | | A unique identifier for the step. |
### Options
| Name | Type | Default | Docs |
|------|------|---------|------|
| [`level`](#reactor-debug-level){: #reactor-debug-level } | `:emergency \| :alert \| :critical \| :error \| :warning \| :notice \| :info \| :debug` | `:debug` | The log level to send the debug information to. |
## reactor.debug.argument
```elixir
argument name, source \\ nil
```
Specifies an argument to a Reactor step.
Each argument is a value which is either the result of another step, or an input value.
Individual arguments can be transformed with an arbitrary function before
being passed to any steps.
### Examples
```
argument :name, input(:name)
```
```
argument :year, input(:date, [:year])
```
```
argument :user, result(:create_user)
```
```
argument :user_id, result(:create_user) do
transform & &1.id
end
```
```
argument :user_id, result(:create_user, [:id])
```
```
argument :three, value(3)
```
### Arguments
| Name | Type | Default | Docs |
|------|------|---------|------|
| [`name`](#reactor-debug-argument-name){: #reactor-debug-argument-name .spark-required} | `atom` | | The name of the argument which will be used as the key in the `arguments` map passed to the implementation. |
| [`source`](#reactor-debug-argument-source){: #reactor-debug-argument-source .spark-required} | `Reactor.Template.Element \| Reactor.Template.Input \| Reactor.Template.Result \| Reactor.Template.Value` | | What to use as the source of the argument. See `Reactor.Dsl.Argument` for more information. |
2023-12-15 10:36:25 +13:00
### Options
| Name | Type | Default | Docs |
|------|------|---------|------|
| [`transform`](#reactor-debug-argument-transform){: #reactor-debug-argument-transform } | `(any -> any) \| module \| nil` | | An optional transformation function which can be used to modify the argument before it is passed to the step. |
### Introspection
Target: `Reactor.Dsl.Argument`
## reactor.debug.wait_for
```elixir
wait_for names
```
Wait for the named step to complete before allowing this one to start.
Desugars to `argument :_, result(step_to_wait_for)`
### Examples
```
wait_for :create_user
```
### Arguments
| Name | Type | Default | Docs |
|------|------|---------|------|
| [`names`](#reactor-debug-wait_for-names){: #reactor-debug-wait_for-names .spark-required} | `atom \| list(atom)` | | The name of the step to wait for. |
### Introspection
Target: `Reactor.Dsl.WaitFor`
### Introspection
Target: `Reactor.Dsl.Debug`
## reactor.flunk
```elixir
flunk name, message
```
Creates a step which will always cause the Reactor to exit with an error.
This step will flunk with a `Reactor.Error.Invalid.ForcedFailureError` with it's message set to the provided message.
Additionally, any arguments to the step will be stored in the exception under the `arguments` key.
### Nested DSLs
* [argument](#reactor-flunk-argument)
* [wait_for](#reactor-flunk-wait_for)
### Examples
```
flunk :outaroad, "Ran out of road before reaching 88Mph"
```
### Arguments
| Name | Type | Default | Docs |
|------|------|---------|------|
| [`name`](#reactor-flunk-name){: #reactor-flunk-name .spark-required} | `atom` | | A unique name for the step. Used when choosing the return value of the Reactor and for arguments into other steps. |
| [`message`](#reactor-flunk-message){: #reactor-flunk-message } | `nil \| String.t \| Reactor.Template.Element \| Reactor.Template.Input \| Reactor.Template.Result \| Reactor.Template.Value` | | The message to to attach to the exception. |
## reactor.flunk.argument
```elixir
argument name, source \\ nil
```
Specifies an argument to a Reactor step.
Each argument is a value which is either the result of another step, or an input value.
Individual arguments can be transformed with an arbitrary function before
being passed to any steps.
### Examples
```
argument :name, input(:name)
```
```
argument :year, input(:date, [:year])
```
```
argument :user, result(:create_user)
```
```
argument :user_id, result(:create_user) do
transform & &1.id
end
```
```
argument :user_id, result(:create_user, [:id])
```
```
argument :three, value(3)
```
### Arguments
| Name | Type | Default | Docs |
|------|------|---------|------|
| [`name`](#reactor-flunk-argument-name){: #reactor-flunk-argument-name .spark-required} | `atom` | | The name of the argument which will be used as the key in the `arguments` map passed to the implementation. |
| [`source`](#reactor-flunk-argument-source){: #reactor-flunk-argument-source .spark-required} | `Reactor.Template.Element \| Reactor.Template.Input \| Reactor.Template.Result \| Reactor.Template.Value` | | What to use as the source of the argument. See `Reactor.Dsl.Argument` for more information. |
### Options
| Name | Type | Default | Docs |
|------|------|---------|------|
| [`transform`](#reactor-flunk-argument-transform){: #reactor-flunk-argument-transform } | `(any -> any) \| module \| nil` | | An optional transformation function which can be used to modify the argument before it is passed to the step. |
### Introspection
Target: `Reactor.Dsl.Argument`
## reactor.flunk.wait_for
```elixir
wait_for names
```
Wait for the named step to complete before allowing this one to start.
Desugars to `argument :_, result(step_to_wait_for)`
### Examples
```
wait_for :create_user
```
### Arguments
| Name | Type | Default | Docs |
|------|------|---------|------|
| [`names`](#reactor-flunk-wait_for-names){: #reactor-flunk-wait_for-names .spark-required} | `atom \| list(atom)` | | The name of the step to wait for. |
### Introspection
Target: `Reactor.Dsl.WaitFor`
### Introspection
Target: `Reactor.Dsl.Flunk`
2023-12-15 10:36:25 +13:00
## reactor.group
```elixir
group name
```
Call functions before and after a group of steps.
### Nested DSLs
* [argument](#reactor-group-argument)
* [wait_for](#reactor-group-wait_for)
### Arguments
| Name | Type | Default | Docs |
|------|------|---------|------|
| [`name`](#reactor-group-name){: #reactor-group-name .spark-required} | `atom` | | A unique name for the group of steps. |
### Options
| Name | Type | Default | Docs |
|------|------|---------|------|
| [`before_all`](#reactor-group-before_all){: #reactor-group-before_all .spark-required} | `(any, any, any -> any) \| mfa` | | The before function. See `Reactor.Step.Group` for more information. |
| [`after_all`](#reactor-group-after_all){: #reactor-group-after_all .spark-required} | `(any -> any) \| mfa` | | The after function. See `Reactor.Step.Group` for more information. |
2023-12-15 10:36:25 +13:00
| [`allow_async?`](#reactor-group-allow_async?){: #reactor-group-allow_async? } | `boolean` | `true` | Whether the emitted steps should be allowed to run asynchronously. |
## reactor.group.argument
```elixir
argument name, source \\ nil
```
Specifies an argument to a Reactor step.
Each argument is a value which is either the result of another step, or an input value.
Individual arguments can be transformed with an arbitrary function before
being passed to any steps.
### Examples
```
argument :name, input(:name)
```
```
argument :year, input(:date, [:year])
```
```
argument :user, result(:create_user)
```
```
argument :user_id, result(:create_user) do
transform & &1.id
end
```
```
argument :user_id, result(:create_user, [:id])
```
```
argument :three, value(3)
```
### Arguments
| Name | Type | Default | Docs |
|------|------|---------|------|
| [`name`](#reactor-group-argument-name){: #reactor-group-argument-name .spark-required} | `atom` | | The name of the argument which will be used as the key in the `arguments` map passed to the implementation. |
| [`source`](#reactor-group-argument-source){: #reactor-group-argument-source .spark-required} | `Reactor.Template.Element \| Reactor.Template.Input \| Reactor.Template.Result \| Reactor.Template.Value` | | What to use as the source of the argument. See `Reactor.Dsl.Argument` for more information. |
2023-12-15 10:36:25 +13:00
### Options
| Name | Type | Default | Docs |
|------|------|---------|------|
| [`transform`](#reactor-group-argument-transform){: #reactor-group-argument-transform } | `(any -> any) \| module \| nil` | | An optional transformation function which can be used to modify the argument before it is passed to the step. |
### Introspection
Target: `Reactor.Dsl.Argument`
## reactor.group.wait_for
```elixir
wait_for names
```
Wait for the named step to complete before allowing this one to start.
Desugars to `argument :_, result(step_to_wait_for)`
### Examples
```
wait_for :create_user
```
### Arguments
| Name | Type | Default | Docs |
|------|------|---------|------|
| [`names`](#reactor-group-wait_for-names){: #reactor-group-wait_for-names .spark-required} | `atom \| list(atom)` | | The name of the step to wait for. |
### Introspection
Target: `Reactor.Dsl.WaitFor`
### Introspection
Target: `Reactor.Dsl.Group`
## reactor.input
```elixir
input name
```
Specifies an input to the Reactor.
An input is a value passed in to the Reactor when executing.
If a Reactor were a function, these would be it's arguments.
Inputs can be transformed with an arbitrary function before being passed
to any steps.
### Examples
```
input :name
```
```
input :age do
transform &String.to_integer/1
end
```
### Arguments
| Name | Type | Default | Docs |
|------|------|---------|------|
| [`name`](#reactor-input-name){: #reactor-input-name .spark-required} | `atom` | | A unique name for this input. Used to allow steps to depend on it. |
### Options
| Name | Type | Default | Docs |
|------|------|---------|------|
| [`transform`](#reactor-input-transform){: #reactor-input-transform } | `(any -> any) \| module \| nil` | | An optional transformation function which can be used to modify the input before it is passed to any steps. |
### Introspection
Target: `Reactor.Dsl.Input`
## reactor.map
```elixir
map name
```
Execute nested steps for every item of an iterator.
Allows you to "map over" a collection applying a some steps to each element,
returning a list of new values. The input collection must be bounded - ie you
cannot pass infinite streams into this step or it will just loop forever - and
because it has to keep the results from each batch will eventually just use up
all available RAM.
Under the hood we use `Iter` to handle lazy iteration of the collection. This
means that you can pass an `Iter.t` or any value for which `Iter.IntoIterable`
is implemented.
> #### A note on ordering {: .tip}
>
> If your application doesn't need the results back in the same order that they
> were provided then setting `strict_ordering?` to `false` will increase
> performance - especially on large input sets.
### Nested DSLs
* [argument](#reactor-map-argument)
* [wait_for](#reactor-map-wait_for)
### Examples
```
map :double_numbers do
input input(:numbers)
step :double do
argument :number, element(:double_numbers)
run %{number: number}, _, _ ->
{:ok, number * 2}
end
end
end
```
```
step :get_subscriptions do
run _, _, _ ->
Stripe.Subscription.list()
end
end
map :cancel_subscriptions do
input result(:get_subscriptions)
step :cancel do
argument :sub_id, element(:cancel_subscriptions, [:id])
run fn args, _, _ ->
Stripe.Subscription.cancel(arg.sub_id, %{prorate: true, invoice_now: true})
end
end
return :cancel
end
```
### Arguments
| Name | Type | Default | Docs |
|------|------|---------|------|
| [`name`](#reactor-map-name){: #reactor-map-name .spark-required} | `atom` | | A unique name for the step. |
### Options
| Name | Type | Default | Docs |
|------|------|---------|------|
| [`source`](#reactor-map-source){: #reactor-map-source .spark-required} | `Reactor.Template.Element \| Reactor.Template.Input \| Reactor.Template.Result \| Reactor.Template.Value` | | The iterator or enumerable to use as the source of the iteration. |
| [`allow_async?`](#reactor-map-allow_async?){: #reactor-map-allow_async? } | `boolean` | `false` | Whether the emitted steps should be allowed to run asynchronously. |
| [`batch_size`](#reactor-map-batch_size){: #reactor-map-batch_size } | `pos_integer` | `100` | The number of items to consume off the source when emitting steps. |
| [`return`](#reactor-map-return){: #reactor-map-return } | `atom` | | The name of the nested step to use as the return value. |
| [`strict_ordering?`](#reactor-map-strict_ordering?){: #reactor-map-strict_ordering? } | `boolean` | `true` | Whether the mapped values must be returned in the same order that they were provided. |
## reactor.map.argument
```elixir
argument name, source \\ nil
```
Specifies an argument to a Reactor step.
Each argument is a value which is either the result of another step, or an input value.
Individual arguments can be transformed with an arbitrary function before
being passed to any steps.
### Examples
```
argument :name, input(:name)
```
```
argument :year, input(:date, [:year])
```
```
argument :user, result(:create_user)
```
```
argument :user_id, result(:create_user) do
transform & &1.id
end
```
```
argument :user_id, result(:create_user, [:id])
```
```
argument :three, value(3)
```
### Arguments
| Name | Type | Default | Docs |
|------|------|---------|------|
| [`name`](#reactor-map-argument-name){: #reactor-map-argument-name .spark-required} | `atom` | | The name of the argument which will be used as the key in the `arguments` map passed to the implementation. |
| [`source`](#reactor-map-argument-source){: #reactor-map-argument-source .spark-required} | `Reactor.Template.Element \| Reactor.Template.Input \| Reactor.Template.Result \| Reactor.Template.Value` | | What to use as the source of the argument. See `Reactor.Dsl.Argument` for more information. |
### Options
| Name | Type | Default | Docs |
|------|------|---------|------|
| [`transform`](#reactor-map-argument-transform){: #reactor-map-argument-transform } | `(any -> any) \| module \| nil` | | An optional transformation function which can be used to modify the argument before it is passed to the step. |
### Introspection
Target: `Reactor.Dsl.Argument`
## reactor.map.wait_for
```elixir
wait_for names
```
Wait for the named step to complete before allowing this one to start.
Desugars to `argument :_, result(step_to_wait_for)`
### Examples
```
wait_for :create_user
```
### Arguments
| Name | Type | Default | Docs |
|------|------|---------|------|
| [`names`](#reactor-map-wait_for-names){: #reactor-map-wait_for-names .spark-required} | `atom \| list(atom)` | | The name of the step to wait for. |
### Introspection
Target: `Reactor.Dsl.WaitFor`
### Introspection
Target: `Reactor.Dsl.Map`
2023-12-15 10:36:25 +13:00
## reactor.step
```elixir
step name, impl \\ nil
```
Specifies a Reactor step.
Steps are the unit of work in a Reactor. Reactor will calculate the
dependencies graph between the steps and execute as many as it can in each
iteration.
See the `Reactor.Step` behaviour for more information.
### Nested DSLs
* [argument](#reactor-step-argument)
* [wait_for](#reactor-step-wait_for)
### Examples
```
step :create_user, MyApp.Steps.CreateUser do
argument :username, input(:username)
argument :password_hash, result(:hash_password)
end
```
```
step :hash_password do
argument :password, input(:password)
run fn %{password: password}, _ ->
{:ok, Bcrypt.hash_pwd_salt(password)}
end
end
```
### Arguments
| Name | Type | Default | Docs |
|------|------|---------|------|
| [`name`](#reactor-step-name){: #reactor-step-name .spark-required} | `atom` | | A unique name for the step. Used when choosing the return value of the Reactor and for arguments into other steps. |
| [`impl`](#reactor-step-impl){: #reactor-step-impl } | `module \| nil` | | A module that implements the `Reactor.Step` behaviour that provides the implementation. |
### Options
| Name | Type | Default | Docs |
|------|------|---------|------|
| [`run`](#reactor-step-run){: #reactor-step-run } | `(any -> any) \| mfa \| (any, any -> any) \| mfa` | | Provide an anonymous function which implements the `run/3` callback. Cannot be provided at the same time as the `impl` argument. |
| [`undo`](#reactor-step-undo){: #reactor-step-undo } | `(any -> any) \| mfa \| (any, any -> any) \| mfa \| (any, any, any -> any) \| mfa` | | Provide an anonymous function which implements the `undo/4` callback. Cannot be provided at the same time as the `impl` argument. |
| [`compensate`](#reactor-step-compensate){: #reactor-step-compensate } | `(any -> any) \| mfa \| (any, any -> any) \| mfa \| (any, any, any -> any) \| mfa` | | Provide an anonymous function which implements the `undo/4` callback. Cannot be provided at the same time as the `impl` argument. |
| [`max_retries`](#reactor-step-max_retries){: #reactor-step-max_retries } | `:infinity \| non_neg_integer` | `:infinity` | The maximum number of times that the step can be retried before failing. Only used when the result of the `compensate/4` callback is `:retry`. |
| [`async?`](#reactor-step-async?){: #reactor-step-async? } | `boolean` | `true` | When set to true the step will be executed asynchronously via Reactor's `TaskSupervisor`. |
| [`transform`](#reactor-step-transform){: #reactor-step-transform } | `(any -> any) \| module \| nil` | | An optional transformation function which can be used to modify the entire argument map before it is passed to the step. |
## reactor.step.argument
```elixir
argument name, source \\ nil
```
Specifies an argument to a Reactor step.
Each argument is a value which is either the result of another step, or an input value.
Individual arguments can be transformed with an arbitrary function before
being passed to any steps.
### Examples
```
argument :name, input(:name)
```
```
argument :year, input(:date, [:year])
```
```
argument :user, result(:create_user)
```
```
argument :user_id, result(:create_user) do
transform & &1.id
end
```
```
argument :user_id, result(:create_user, [:id])
```
```
argument :three, value(3)
```
### Arguments
| Name | Type | Default | Docs |
|------|------|---------|------|
| [`name`](#reactor-step-argument-name){: #reactor-step-argument-name .spark-required} | `atom` | | The name of the argument which will be used as the key in the `arguments` map passed to the implementation. |
| [`source`](#reactor-step-argument-source){: #reactor-step-argument-source .spark-required} | `Reactor.Template.Element \| Reactor.Template.Input \| Reactor.Template.Result \| Reactor.Template.Value` | | What to use as the source of the argument. See `Reactor.Dsl.Argument` for more information. |
2023-12-15 10:36:25 +13:00
### Options
| Name | Type | Default | Docs |
|------|------|---------|------|
| [`transform`](#reactor-step-argument-transform){: #reactor-step-argument-transform } | `(any -> any) \| module \| nil` | | An optional transformation function which can be used to modify the argument before it is passed to the step. |
### Introspection
Target: `Reactor.Dsl.Argument`
## reactor.step.wait_for
```elixir
wait_for names
```
Wait for the named step to complete before allowing this one to start.
Desugars to `argument :_, result(step_to_wait_for)`
### Examples
```
wait_for :create_user
```
### Arguments
| Name | Type | Default | Docs |
|------|------|---------|------|
| [`names`](#reactor-step-wait_for-names){: #reactor-step-wait_for-names .spark-required} | `atom \| list(atom)` | | The name of the step to wait for. |
### Introspection
Target: `Reactor.Dsl.WaitFor`
### Introspection
Target: `Reactor.Dsl.Step`
## reactor.switch
```elixir
switch name
```
Use a predicate to determine which steps should be executed.
### Nested DSLs
* [matches?](#reactor-switch-matches?)
* [default](#reactor-switch-default)
### Arguments
| Name | Type | Default | Docs |
|------|------|---------|------|
| [`name`](#reactor-switch-name){: #reactor-switch-name .spark-required} | `atom` | | A unique name for the switch. |
### Options
| Name | Type | Default | Docs |
|------|------|---------|------|
| [`on`](#reactor-switch-on){: #reactor-switch-on .spark-required} | `Reactor.Template.Element \| Reactor.Template.Input \| Reactor.Template.Result \| Reactor.Template.Value` | | The value to match against. |
2023-12-15 10:36:25 +13:00
| [`allow_async?`](#reactor-switch-allow_async?){: #reactor-switch-allow_async? } | `boolean` | `true` | Whether the emitted steps should be allowed to run asynchronously. |
## reactor.switch.matches?
```elixir
matches? predicate
```
A group of steps to run when the predicate matches.
### Arguments
| Name | Type | Default | Docs |
|------|------|---------|------|
| [`predicate`](#reactor-switch-matches?-predicate){: #reactor-switch-matches?-predicate .spark-required} | `(any -> any) \| mfa` | | A one-arity function which is used to match the switch input. If the switch returns a truthy value, then the nested steps will be run. |
### Options
| Name | Type | Default | Docs |
|------|------|---------|------|
| [`allow_async?`](#reactor-switch-matches?-allow_async?){: #reactor-switch-matches?-allow_async? } | `boolean` | `true` | Whether the emitted steps should be allowed to run asynchronously. |
| [`return`](#reactor-switch-matches?-return){: #reactor-switch-matches?-return } | `atom` | | Specify which step result to return upon completion. |
### Introspection
Target: `Reactor.Dsl.Switch.Match`
## reactor.switch.default
If none of the `matches?` branches match the input, then the `default`
steps will be run if provided.
### Options
| Name | Type | Default | Docs |
|------|------|---------|------|
| [`return`](#reactor-switch-default-return){: #reactor-switch-default-return } | `atom` | | Specify which step result to return upon completion. |
### Introspection
Target: `Reactor.Dsl.Switch.Default`
### Introspection
Target: `Reactor.Dsl.Switch`
<style type="text/css">.spark-required::after { content: "*"; color: red !important; }</style>