Skip to content
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: Allow SSE extension to use a user-defined EventSource object #143

Open
adonespitogo opened this issue Feb 5, 2025 · 7 comments
Labels
documentation Improvements or additions to documentation enhancement New feature or request help wanted Extra attention is needed

Comments

@adonespitogo
Copy link

This will allow more control over the behavior of the SSE connection. For instance, I want to implement the fix for this firefox bug where I need to have access to the EventSource object for this to be implemented. This will also fix several issues:

Another advantage is to be able to add event listeners outside of htmx context.

Also, the number of connections is limited to only 6 when not used in HTTP2, so it would be beneficial to reused an existing connection across multiple independent elements.

Warning: When not used over HTTP/2, SSE suffers from a limitation to the maximum number of open connections, which can be especially painful when opening multiple tabs, as the limit is per browser and is set to a very low number (6). The issue has been marked as "Won't fix" in Chrome and Firefox. This limit is per browser + domain, which means that you can open 6 SSE connections across all of the tabs to www.example1.com and another 6 SSE connections to www.example2.com (per Stack Overflow). When using HTTP/2, the maximum number of simultaneous HTTP streams is negotiated between the server and the client (defaults to 100).

@Telroshan
Copy link
Collaborator

Hey, it's not documented (documentation improvement PRs are always welcome btw!), but you should already be able to do it ;

  • The extension creates an EventSource with a basic constructor call:

    function createEventSource(url) {
    return new EventSource(url, { withCredentials: true })
    }

  • Though, it calls it through a public API here:

    // set a function in the public API for creating new EventSource objects
    if (htmx.createEventSource == undefined) {
    htmx.createEventSource = createEventSource
    }

So, you could already override htmx.createEventSource with a function of your own, you simply need to make sure that your code executes before the SSE extension initializes

Hope this helps!

@adonespitogo
Copy link
Author

adonespitogo commented Feb 5, 2025

Hi, @Telroshan thank you for this. Although this works, I'd like to make a PR for this as this looks like a hack. I'd like to have something like:

function createEventSource() {
  return Promise.resolve(new EventSource("/sse-events"));
}
<div hx-ext="sse" sse-create="createEventSource" sse-swap="message">

Let me know if this is something that may get accepted.

@Telroshan
Copy link
Collaborator

Hey, it's indeed not documented, which isn't ideal for sure, but it's not a hack don't worry about that, it was designed in this way so that it can be overridden, which is precisely your intent here.

Honestly I don't think adding an extra attribute is very relevant here ;

  • you're going to have a custom function defined in your JS anyway, it's just that instead of window.createEventSource = functtion(url) ... (as you need to expose it to be globally to be callable from teh extension), you'll write htmx.createEventSource = function(url) .... Your code would look exactly the same except that declaration, but the latter doesn't require an extra attribute to setup
  • this would likely involve some const functionName = elt.getAttribute("sse-create"); window[functionName](url) logic inside the extension, which honestly feels way more like a hack to me

However, if you need some async logic here to initialize the event source, it's true that for now, the extension doesn't support an async createEventSource function. I see no reason to oppose to making it promise-compatible where the extension would await the event source if the function is async (and act as it currently does if it's not). So if you are interested in the latter change, I'd say feel free to open a PR for it! But I'm not convinced indeed about the sse-create attribute

@adonespitogo
Copy link
Author

If we could make the createEventSource async, it would be very useful for when you need to fetch additional server data via ajax before creating the event source object.

For now, my requirements are already satisfied using the synchronous createEventSource function so I will not be implementing the async feature. I'll draft a PR for the createEventSource documentation later today.

@adonespitogo
Copy link
Author

Sorry, I can't seem to find the source for the documentation. Please feel free to close this issue as I have a limited time and can no longer work on the documentation part.

@Telroshan
Copy link
Collaborator

Yeah we had to run a trick for this to keep the core extensions' documentation be on the main website, if you look at this repo's sse folder, you'll see it instructs you to go to the main repo instead at https://github.com/bigskysoftware/htmx/blob/master/www/content/extensions/sse.md to find the SSE documentation

No worries about the lack of time!
I'll keep this issue open as it's an interesting point to solve imho, so if anyone (including future me that may have more time available too!) wants to tackle this and submit PRs, please feel free to do so

@Telroshan Telroshan added documentation Improvements or additions to documentation enhancement New feature or request help wanted Extra attention is needed labels Feb 10, 2025
@XChikuX
Copy link

XChikuX commented Feb 17, 2025

#139 Is similar and a fully tested EventSource replacement I use in production. (Unsure if it removes any browser connection limits though.)

Just dealing with some chaos with launching my startup. I should be able to tackle this in a few months.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation enhancement New feature or request help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

3 participants