ux icon indicating copy to clipboard operation
ux copied to clipboard

[Turbo][Mercure] Allow turbo_stream_listen() to subscribe multiple topics in single connection

Open JanMikes opened this issue 2 years ago • 0 comments

Hi! First thanks for turbo and mercure integration, i am playing with it for last several days and it is awesome!

I am struggling with finding a way, how to subscribe to multiple topics using turbo_stream_listen() in twig and after some digging around, it seems that it is not currently supported.

I can do it this way, but i would love to avoid writing javascript in twig (as documented in https://symfony.com/doc/current/mercure.html#subscribing):

<script>
const eventSource = new EventSource("{{ mercure([
    'a',
    'b'
])|escape('js') }}");
</script>

But by doing this i am loosing a lot of comfort.

What i tried:

<div {{ turbo_stream_listen(['a', 'b']) }}></div>  {# Ends with error #}
<div {{ turbo_stream_listen('a,b']) }}></div>  {# Subscribes to single "a,b" topic #}
<div {{ turbo_stream_listen('a&topic=b') }}></div>  {# Subscribes to single "a&topic=b" topic #}

That a&topic=b variant was my favourite that it would work, but unfortunately it escapes the & so final URL is like this, which is why it is treated as single topic:

URL: http://localhost:8080/.well-known/mercure?topic=a%26topic%3Db

What i am actually trying to achieve is this hub url with single turbo_stream_listem():

http://localhost:8080/.well-known/mercure?topic=a&topic=b

My current solution is to:

<div {{ turbo_stream_listen('a') }}></div>
<div {{ turbo_stream_listen('b') }}></div>

Which results into two connections to hub and i believe it would be more efficient to have one connection with two subscriptions.

I could probably solve this by writing my own stimulus controller (inspired by turbo_stream_controller.js).

My idea is to update Symfony\UX\Turbo\Bridge\Mercure\TurboStreamListenRenderer

public function renderTurboStreamListen(Environment $env, $topic): string
    {
+        if (\is_array($topic)) {
+            // .. some logic here :-)
+        }

         if (\is_object($topic)) {

JanMikes avatar Jan 08 '22 12:01 JanMikes