defmodule MobAsh do @moduledoc """ Resource-driven Mob screens from Ash. Declare Ash resources in your host app, register the domains, and mob_ash generates a list / detail / create screen set per resource — Ash runs on-device in the host BEAM (use a device-friendly data layer such as `Ash.DataLayer.Ets` or AshSqlite over the bundled SQLite). ## Host setup # mix.exs {:mob_ash, "~> 0.1"} # mob.exs config :mob, :plugins, [:mob_ash] # config/config.exs config :my_app, :ash_domains, [MyApp.Blog] The build's screens generator (spec v2) introspects each domain's resources and emits routes: /ash/post MobAsh.ListScreen (params: %{resource: MyApp.Blog.Post}) /ash/post/detail MobAsh.DetailScreen /ash/post/new MobAsh.FormScreen All three are SHARED parameterized screens — the resource module rides the route as route-bound params (`Mob.Nav.Registry.register/3`), so `push_screen(socket, :"/ash/post")` works with no extra arguments, and `MobAsh.navigate/3` works without routes at all. ## Navigating programmatically MobAsh.navigate(socket, MyApp.Blog.Post, :list) MobAsh.navigate(socket, MyApp.Blog.Post, :new) """ @doc """ Push the mob_ash screen for `resource`: `:list`, `:detail` (needs `id:` in `params`), or `:new`. """ @spec navigate(Mob.Socket.t(), module(), :list | :detail | :new, map()) :: Mob.Socket.t() def navigate(socket, resource, action, params \\ %{}) do screen = case action do :list -> MobAsh.ListScreen :detail -> MobAsh.DetailScreen :new -> MobAsh.FormScreen end Mob.Socket.push_screen(socket, screen, Map.put(params, :resource, resource)) end end