Packages
reactive_dag
0.17.0-rc.21
0.17.0-rc.43
0.17.0-rc.42
0.17.0-rc.41
0.17.0-rc.40
0.17.0-rc.39
0.17.0-rc.38
0.17.0-rc.37
0.17.0-rc.36
0.17.0-rc.35
0.17.0-rc.34
0.17.0-rc.33
0.17.0-rc.32
0.17.0-rc.31
0.17.0-rc.30
0.17.0-rc.29
0.17.0-rc.28
0.17.0-rc.27
0.17.0-rc.26
0.17.0-rc.25
0.17.0-rc.24
0.17.0-rc.23
0.17.0-rc.22
0.17.0-rc.21
0.17.0-rc.20
0.17.0-rc.19
0.17.0-rc.18
0.17.0-rc.17
0.17.0-rc.16
0.17.0-rc.15
0.17.0-rc.14
0.17.0-rc.13
0.17.0-rc.12
0.17.0-rc.11
0.17.0-rc.10
0.17.0-rc.9
0.17.0-rc.8
0.17.0-rc.7
0.17.0-rc.6
0.17.0-rc.5
0.17.0-rc.4
0.17.0-rc.3
0.17.0-rc.2
0.17.0-rc.1
0.17.0-rc
0.16.0
Reactive DAG engine as an Ash extension: dirty frontier, depth-ordered incremental drain, change propagation. Author nodes as Ash resources with reduce/join/aggregate combinators; each node's results are its own rows. You declare the relationships; one engine runs them.
Current section
Files
Jump to
Current section
Files
reactive_dag
mix.exs
mix.exs
defmodule ReactiveDag.MixProject do
use Mix.Project
@moduledoc false
# release-please manages this version (and the tag/CHANGELOG) via the
# annotation below — bump it by merging the release PR, not by hand.
@version "0.17.0-rc.21" # x-release-please-version
def project do
[
app: :reactive_dag,
version: @version,
elixir: "~> 1.18",
description:
"Reactive DAG engine as an Ash extension: dirty frontier, depth-ordered " <>
"incremental drain, change propagation. Author nodes as Ash resources " <>
"with reduce/join/aggregate combinators; each node's results are its own " <>
"rows, and the domain plugs in at three seams.",
elixirc_paths: elixirc_paths(Mix.env()),
deps: deps(),
docs: docs(),
package: package()
]
end
defp package do
[
licenses: ["MIT"],
links: %{"GitHub" => "https://github.com/u2i/reactive_dag"},
# guides/ + docs/ ship in the package so hexdocs can build the extras
files: ~w(lib guides docs mix.exs README.md LICENSE)
]
end
defp docs do
[
main: "getting-started",
source_url: "https://github.com/u2i/reactive_dag",
source_ref: "v#{@version}",
extras: [
"guides/getting-started.md",
"guides/configuration.md",
"guides/authoring-nodes.md",
"guides/llm-nodes.md",
"guides/sources.md",
"guides/seams.md",
"README.md",
"docs/adr-001-reactive-dag-library.md"
],
groups_for_extras: [
Guides: ~r/guides\/.*/,
Design: ~r/docs\/.*/
],
groups_for_modules: [
Authoring: [
ReactiveDag.Node,
ReactiveDag.Node.Payload,
ReactiveDag.Node.Recompute.Aggregate,
ReactiveDag.Calendar
],
Attestation: [
ReactiveDag.Attestation,
ReactiveDag.Attestation.Scope,
ReactiveDag.Attestation.Basis,
ReactiveDag.Attestation.Requirement,
ReactiveDag.Attestation.Evaluation,
ReactiveDag.Attestation.Op
],
Seams: [
ReactiveDag.Source,
ReactiveDag.RecomputeStrategy,
ReactiveDag.KeyRule,
ReactiveDag.CoordinationWriter
],
Engine: [
ReactiveDag.Drain,
ReactiveDag.Graph,
ReactiveDag.Lowering,
ReactiveDag.Plan,
ReactiveDag.Cell
]
]
]
end
def application, do: [extra_applications: [:logger]]
defp elixirc_paths(:test), do: ["lib", "test/support"]
defp elixirc_paths(_), do: ["lib"]
# Both host apps are Ash/AshPostgres/Spark, so the library IS an Ash extension:
# it owns the frontier + substrate resources and the reactive-DAG Spark DSL.
# Only the op algebra + recompute model stay app-side (the two real seams).
defp deps do
[
{:ash, "~> 3.5"},
{:ash_postgres, "~> 2.0"},
{:spark, "~> 2.7"},
# the drain's observability seam. Arrives transitively via Ash anyway, but
# the drain calls :telemetry.execute directly, so it is a direct dependency.
{:telemetry, "~> 1.1"},
# the scan worker. Optional: a host that schedules its own polls, or runs
# none, never loads `ReactiveDag.ScanWorker` and needs no Oban.
{:oban, "~> 2.17", optional: true},
# TEST-ONLY: proves an ash_ai prompt-backed action composes with `run`,
# so an LLM node needs no library code (see guides/llm-nodes.md). Never a
# runtime dependency — hosts that want LLM nodes add ash_ai themselves.
{:ash_ai, "~> 0.8", only: :test},
{:ex_doc, "~> 0.34", only: :dev, runtime: false}
]
end
end