Hey - I am replying here because I can’t start a topic on my first post. Plus I keep getting sent to the same unresolved questions on various forums.
I wanted to share what I have done here, (which is admittedly a bit of a hack) to get around this issue with LiveComponents not being a process.
I won’t share tonnes of context unless people want more, but the basic thing is this:
I have a particularly complex component - (a media picker/uploader), which is used in about 20 liveviews and will need to go to more. It is used on forms, usually in dynamic fields for associations. Therefore the logic really needs to be encapsulated inside the LiveComponent.
I can’t use a LiveView because you can;t pass initial and updated props to a LiveView when using live_render. This component has many contextual options which need to be passed on initialisation. The owner of the media, the media type etc. Media can be owned by a company and accessible by all members of the company, or by a customer, who is the only one with access until added to a public entity…
During the process of uploading, displaying and selecting media inside this component there are a bunch of background processing jobs that happen (uploading via tus/uppy, encoding videos, token generation, thumbnail generation etc) and need to be reported back to the component. Again - this is used in many places, so attaching hooks and implementing logic in mutiple liveviews doesn’t feel right. The logic for the component should live IN the component.
Up until now, I have been attaching a phx-hook to the root element in the component. Then when job status updates occur, I send a message to a phx channel channel, which sends a message to the channel socket and then the js socket client sends a message back to the mounted hook.
The above solution works, but it is messy, difficult to trace logic and hard to debug. As the complexity of the application grows, it gives me the itch! 
So I have started using another approach: Running a lightweight GenServer in my component.
defmodule MyApp.MyLiveComponent do
use MyApp, :live_component
use GenServer
....
end
Then when the component mounts and connects to the liveview, I start the GenServer, link it to the parent liveview process and pass the socket into the init of the GenServer.
if connected?(socket), do: {:ok, pid} = start_link(socket)
Now my GenServer can subscribe to pubsub events. GenServers have a handle_info, but LiveComponents don’t.
def init(socket) do
{:ok, socket, {:continue, :subscribe}}
end
def handle_continue(:subscribe, socket) do
Phoenix.PubSub.subscribe(MyApp.PubSub, "test-my-topic")
{:noreply, socket}
end
When the component server receives the message
def handle_info(message, socket) do
send_update(socket.root_pid, socket.assigns.myself, message)
{:noreply, socket}
end
Myself is the CID of the component, which is how the liveview tracks the livecomponents it is managing.
I’ll abstract this away into a macro and now I can just add the functionality to any LiveComponent that needs it.
I want to stress though - it is very rare that you ever need something like this. Most of the time, LiveComponent, Component and LiveView fit the bill, but sometimes there is a gap in the functionality where components need to receive events from external processes.
Hope it helps somebody else who is pulling their hair out like I was 