-
Notifications
You must be signed in to change notification settings - Fork 415
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature Request: declarative connection to a Turbo Stream using the turbo-stream
custom tag
#413
Comments
Could you share a use case that you have in mind to help demonstrate this feature's utility? There seems to be some confusion between concepts. A The Since the Am I misinterpreting anything here? |
Yes, this has nothing to do with Rails, the turbo-rails package, nor any server-side code. This is something entirely for In the case the This proposal is for allowing the use of the same custom element in a HTML page (of type The likely placement of the Your "seems to be some confusion between concepts" comment indeed mirrors my "need not (but may) be conflated with" thought ;-) |
Thank you for clarifying. Could you share some code or pseudo code to demonstrate the utility? Presuming the turbo-stream were rendered in the HTML on the server side, what value is there in making an additional HTTP request to the src URL? Would rendering the element directly with contents suffice? |
I think you're still confused? This isn't about the content of a turbo-stream, this is about connecting to a turbo-stream. Without Rails, how do you currently get a browser to connect to an EventStream (or WebSocket) that contains TurboStream content? You add this to the page (that could be a static HTML file) that's going to receive that stream and have parts of its DOM updated by Turbo: <head>
<script>
(window['EventSource'] && window['Turbo']) ?
Turbo.connectStreamSource(new EventSource('/my-turbo-stream')) :
console.warn('Turbo Streams over SSE not available');
</script>
</head>
<body>
<div id="some_target_of_my_turbo_stream"><div>
</body> All this feature request proposes is to remove the need for the <head>
<turbo-stream src="/my-turbo-stream" />
</head>
<body>
<div id="some_target_of_my_turbo_stream"><div>
</body> That Does calling it |
Thank you for sharing that code, I think we're aligned now. To re-contextualize a part of my original comment:
I think we're still discussing the details of a backend agnostic version of the turbo-cable-stream-source element. Based on your code sample, I'm interpreting that you're suggesting the current turbo-stream element be extended. Is that correct? I think overloading the element to behave differently based on the presence or absence of a src attribute could be tricky. Maybe a new turbo-stream-source element (like the Rails version, but without the "cable") could serve that single purpose. Is there something about extending the semantics and behavior of the existing turbo-stream element that's more compelling than introducing a new element? |
Closes hotwired#413 The `<turbo-stream-source>` element accepts a `[src]` attribute, and uses that to connect Turbo to poll for streams published on the server side. When the element is connected to the document, the stream source is connected. When the element is disconnected, the stream is disconnected. When declared with an `ws://` or `wss://` URL, the underlying Stream Source will be a `WebSocket` instance. Otherwise, the connection is through an `EventSource`. Since the document's `<head>` is persistent across navigations, the `<turbo-stream-source>` is meant to be mounted within the `<body>` element. Typical full page navigations driven by Turbo will result in the `<body>` being discarded and replaced with the resulting document. It's the server's responsibility to ensure that the element is present on each page that requires streaming.
I've opened #415 to implement this. @delitescere Could you weigh in there on whether or not it fits your use case? |
Closes hotwired#413 The `<turbo-stream-source>` element accepts a `[src]` attribute, and uses that to connect Turbo to poll for streams published on the server side. When the element is connected to the document, the stream source is connected. When the element is disconnected, the stream is disconnected. When declared with an `ws://` or `wss://` URL, the underlying Stream Source will be a `WebSocket` instance. Otherwise, the connection is through an `EventSource`. Since the document's `<head>` is persistent across navigations, the `<turbo-stream-source>` is meant to be mounted within the `<body>` element. Typical full page navigations driven by Turbo will result in the `<body>` being discarded and replaced with the resulting document. It's the server's responsibility to ensure that the element is present on each page that requires streaming.
I appreciate it might be tricky, indeed. To me, it’s the same duality as “turbo-frame acting as a source” and “turbo-frame acting as a target”. But if it were named slightly differently, that is less important than having it at all. Of course, as I’m not writing it, I defer to the developers to choose the smoothest implementation. Much appreciated! Also see https://link.medium.com/hcGxj0262jb for more (a lot more) context |
* Improve test coverage for streams over SSE Add a `<form>` element to the `src/tests/fixtures/stream.html` file so that tests can exercise receiving `<turbo-stream>` elements asynchronously over an `EventSource` instance that polls for Server-sent Events. Extend the `src/tests/server.ts` to account for the `Accept: text/event-stream` requests that are made by browsers via the `new EventSource(...)` instance. * Introduce `<turbo-stream-source>` Closes #413 The `<turbo-stream-source>` element accepts a `[src]` attribute, and uses that to connect Turbo to poll for streams published on the server side. When the element is connected to the document, the stream source is connected. When the element is disconnected, the stream is disconnected. When declared with an `ws://` or `wss://` URL, the underlying Stream Source will be a `WebSocket` instance. Otherwise, the connection is through an `EventSource`. Since the document's `<head>` is persistent across navigations, the `<turbo-stream-source>` is meant to be mounted within the `<body>` element. Typical full page navigations driven by Turbo will result in the `<body>` being discarded and replaced with the resulting document. It's the server's responsibility to ensure that the element is present on each page that requires streaming. * fix lint errors Co-authored-by: David Heinemeier Hansson <david@hey.com>
Currently, some JavaScript is needed to connect a Turbo Stream to an EventSource (SSE) or WebSocket (by the way, the docs aren't very clear about how to do this).
It would be superb if it could be done without JavaScript, rather using an incantation of the
turbo-stream
custom element.Current imperative mechanism:
Suggested declarative mechanism:
If the URL scheme was
ws:
then Turbo would create a newWebSocket
, otherwise it would be anEventSource
.The addition of a
src
attribute to the customturbo-stream
tag need not (but may) be conflated with the use of it in directives to altering the DOM as content arrives on the stream or as the result of a form submission (i.e. the existing capabilities of the custom tag).The text was updated successfully, but these errors were encountered: