ash-project / reactor

Reactor is a dynamic, concurrent, dependency resolving saga orchestrator.
https://ash-hq.org/
MIT License
44 stars 6 forks source link

Add `map` step type. #3

Closed jimsynz closed 15 hours ago

jimsynz commented 1 year ago

For feature parity with Ash.Flow

jimsynz commented 1 year ago

An idea that came out of a conversation with Zach. 🤷

use Reactor

stream :search_results do
  generator value([AshHq.Docs.Option,
    AshHq.Docs.MixTask,
    AshHq.Docs.Module,
    AshHq.Docs.Function,
    AshHq.Docs.Extension,
    AshHq.Docs.LibraryVersion,
    AshHq.Docs.Guide,
    AshHq.Docs.Dsl,
    AshHq.Discord.Message])

  filter do
    argument :resource, element(:search_results, [:__struct__])
    argument :types, input(:types)
    run fn %{resource: resource, types: types} -> resource in types end
  end

  map do
    argument :resource, element(:search_results, [:__struct__])

    read :search, argument(:resource), :search do
      input %{
        library_versions: argument(:library_versions),
        query: argument(:query)
      } # syntax TBC
    end
  end

  sort do
    argument :rank, element(:search_results, [:match_rank])

    by &(-&1.rank)
  end
end

return :search_results
jimsynz commented 1 year ago

The more I think about this the more I come down on the side of just doing this less magically:

    step :search_results do
      argument :search_results, input(:search_results)
      argument :library_versions, input(:library_versions)
      argument :query, input(:query)

      run fn arguments, _, _ ->
        types = [
          AshHq.Docs.Option,
          AshHq.Docs.MixTask,
          AshHq.Docs.Module,
          AshHq.Docs.Function,
          AshHq.Docs.Extension,
          AshHq.Docs.LibraryVersion,
          AshHq.Docs.Guide,
          AshHq.Docs.Dsl,
          AshHq.Discord.Message
        ]

        arguments.search_results
        |> Stream.filter(&(&1.__struct__ in types))
        |> Stream.map(
          & &1.__struct__.search(%{
            library_versions: arguments.library_versions,
            query: arguments.query
          })
        )
        |> Enum.sort_by(&(-&1.rank))
      end
    end