Skip to content
This repository has been archived by the owner on Apr 20, 2018. It is now read-only.

make EventSource optional #25

Open
loomis opened this issue Jul 4, 2017 · 6 comments
Open

make EventSource optional #25

loomis opened this issue Jul 4, 2017 · 6 comments

Comments

@loomis
Copy link
Contributor

loomis commented Jul 4, 2017

When using kvlt on the Microsoft Edge browser, the compiled javascript fails because EventSource is not supported and the code tries to 'require' the eventsource module (presumably for node.js). When removing the SSE support in a fork (we don't actually use it in our code), the problem no longer appears. A clean way to turn off the SSE support would allow us avoid maintaining a fork.

I've noticed that you have created a (possibly?) similar ticket for WebSocket (#20). If you have ideas on how you see options for turning on/off various features, we'd be happy to try to create a PR for this.

@moea
Copy link
Member

moea commented Jul 4, 2017

@loomis So I included both of those features (SSE and websockets), in retrospect, maybe a little exuberantly, despite not using them myself. There is a snapshot (0.2.0-SNAPSHOT) and corresponding branch (wip/smaller) which just removes that functionality and updates the deps. I'm tempted to release the snapshot at some point - would that break anything for you?

If so, (delay)'ing the requires and derefing them on first use may be the simplest approach.

@loomis
Copy link
Contributor Author

loomis commented Jul 4, 2017

@moea Just creating a release without those features would currently work for us. However, we're actually planning to start using websockets in the next few weeks, so that would be a very short term fix for us. I'll look to see if the delays would be easy to add.

@loomis
Copy link
Contributor Author

loomis commented Jul 4, 2017

@moea Unfortunately, it doesn't look like any solution with delay will work for clojurescript. The first issue is that require can only appear at the top-level in clojurescript. Therefore, it can't appear in a delay and necessitates that the user explicitly require the kvlt.platform.* namespaces. Even with that, clojurescript doesn't have any of the resolve-like functions, so the correct request! function can't be looked up dynamically (at least not without a lot of direct hacking with javascript).

The only moderately clean solution that I can find is to separate the websocket! and event-source! functions into their own namespaces. Users would then be able to choose which features they need, but with the inconvenience of requiring more than just the current kvlt.core namespace.

Would you be open to a split-namespace solution? Or perhaps you can think of something I've missed with delayed loading in clojurescript.

@moea
Copy link
Member

moea commented Jul 4, 2017

@loomis Ah, sorry, I wasn't being clear - I meant delaying the calls to js/require in the cljs modules, e.g:

(def websocket (delay (js/require "websocket")) 

And then explicitly deref'ing the websocket var within that module, at the point of use - everything would appear fine on platforms where the import will be unsuccessful, up until the point where the functionality is exercised.

@moea
Copy link
Member

moea commented Jul 4, 2017

(the only caveat would be if there are module-level uses of the required Node modules, though if there are, wrapping them in functions or just delaying them, also, shouldn't be too much trouble).

If you're going to tackle this, I am totally fine with you removing the SSE functionality and just delaying the websocket stuff, or that's something I can do subsequently - I think it's a valuable change.

@loomis
Copy link
Contributor Author

loomis commented Jul 5, 2017

@moea I've generated a PR (#26) with changes to delay the loading of EventSource and WebSocket.

I've added some logging to the delay to give the user some more specific feedback when either library is unavailable; the default "Uncaught ReferenceError: require is not defined" is not very helpful in understanding the problem. Currently the code re-throws the exception, but could be changed to eat the exception or generate one with a different method.

Getting the constructor to work from the delayed value was a bit difficult. In the end I had to bind a local symbol to get the constructor syntax to work. There's some magic going on there, that I don't understand and didn't have time to dig into. If you know a better incantation that doesn't require the local binding, please let me know.

The modified library works for us, even with the Edge browser. I've seen that the CI tests pass as well. I haven't done much other testing, so you might want to take it for a real-world spin before merging it.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants