austin icon indicating copy to clipboard operation
austin copied to clipboard

Client-side projects

Open danielsz opened this issue 10 years ago • 9 comments

Client-side projects don't necessarily have a server component (and shouldn't be required to have one). Take for example the basic tutorial for om: https://github.com/swannodette/om/wiki/Basic-Tutorial That tutorial has instructions for starting a Clojurescript repl in LightTable.

"Type the key chord Control-SPACE to open up the command list. Start typing Add Connection, press enter to select it. In the list of options select Browser (External). Copy and paste the script tag into index.html before the div tag."

And that's all there is to it.

I tried to emulate that tutorial for Austin. I started an Austin repl like so:

(def repl-env (reset! cemerick.austin.repls/browser-repl-env
                      (cemerick.austin/repl-env)))

Then I looked at the value of

(cemerick.austin.repls/browser-connected-repl-js)

and used it for manual inclusion in the index.html.

I made sure that the cljs source requires

:require [clojure.browser.repl]

Loading index.html does initiates a connection, but errors out with this message:

Uncaught Error: URI file://localhost/robots.txt is invalid for field ppu

Can this be fixed?

If LightTable can do it, I'm hopeful Austin can too.

danielsz avatar Feb 08 '14 17:02 danielsz

OK, this thread explains that the problem lies with the Clojurescript repl itself, so not an Austin issue.

http://comments.gmane.org/gmane.comp.java.clojure.user/60605

So what's LightTable secret sauce and how can Austin benefit from it?

Contrary to the official Clojurescript stance that it is not supported, LightTable enables the use case where a html file is opened from disk and successfully establishes a connection with a Clojurescript repl.

danielsz avatar Feb 08 '14 18:02 danielsz

Preliminary findings indicate that LightTable fires up an internal web server with websockets transport.

https://github.com/LightTable/LightTable/blob/92ef49faa985d85bad74b131ee46c8977650bc9f/src/lt/objs/clients/ws.cljs

Very interesting. Is this outside the scope of Austin? If so, I'll close this issue. Thanks.

BTW, there is a reward for implementing this: https://twitter.com/swannodette/status/365272360896569344

:-)

danielsz avatar Feb 08 '14 18:02 danielsz

Either way, there's a server, something needs to be available to compile the ClojureScript you're evaluating, etc. Given that, what's the benefit of a websocket server vs. HTTP?

Note that Austin just reuses the stock ClojureScript browser-REPL client-side bits, which uses a CrossPageChannel to talk to the server. Changing that isn't necessarily outside of Austin's scope, but (a) it's not a nontrivial change, and (b) the work would necessitate a compelling benefit.

cemerick avatar Feb 08 '14 20:02 cemerick

I agee, it doesn't need to be websocket per se.

In this particular instance, I care about the use case, which could be defined like this: "given a client-side project with no server component, start an in-browser Clojurescript repl." This is currently not possible with Austin, but it is with LightTable.

When I was doing the Om tutorial (https://github.com/swannodette/om/wiki/Basic-Tutorial) which contains instructions for LightTable, I was shocked to see how easy it was.

Austin should probably continue to use the stock ClojureScript browser-REPL as-is, but it could provide the additional tooling LightTable has. Whatever the implementation details are, with or without websockets. It's all public, open source code anyway.

danielsz avatar Feb 09 '14 05:02 danielsz

There are a couple of things:

  1. LightTable's approach works because WebSockets are not bound by the same-origin policy. We can modify Austin's embedded server to add the necessary Access-Control-Allow-Origin: * header to all responses (or whatever less-permissive one that will allow only localhost and whatever the origin is for file:// URLs).
  2. This would work with the existing client-side bits, with the exception that the CrossPageChannel (or one of its dependencies) does some questionable URL string-munging in order to (potentially?) check for a robots.txt, which ends up yielding an invalid URL (since there's no host in e.g. file:///tmp/start-repl.html).

I've long wanted Austin to have its own browser-side component to replace cljs.browser.repl, probably using SSEs instead of the CrossPageChannel (the big advantage of which was that it worked on all browsers, including IE 6, back when CLJS was first released). Combined with the CORS header server-side, this should make austin suitable for this use case.

cemerick avatar Feb 09 '14 12:02 cemerick

That all makes a lot of sense. And it sounds like a good plan. If Austin is to become a default go-to REPL for Clojurescript development, it will need to support that use case. I'll be happy to help to the best of ability.

danielsz avatar Feb 09 '14 16:02 danielsz

An easier approach would be to allow the user to "mount" a local directory as the root of all resources served for a particular REPL session (mock usage here):

user=> (cemerick.austin.repls/mount-static "/app/directory" ...other REPL env config)
Static local site mounted @ http://localhost:51665/3889/

So /app/directory/index.html would be served via http://localhost:51665/3889/ or http://localhost:51665/3889/index.html; similarly for the usual sorts of web resources. Further, Austin could use enlive or similar to inject the necessary JavaScript (equivalent to the output of (browser-connected-repl-js)) at the end of the <head> or <body> tag, populated with the corresponding URL for that session, e.g. http://localhost:51665/3889/repl.

This would be a much less significant change, but achieve the same objectives…while preserving the ability to have multiple concurrent browser-REPL sessions. Patch welcome.

cemerick avatar Feb 10 '14 17:02 cemerick

I agree. I discovered that somebody already proposed something along those lines. Adrian Medina posted a lein template (om-cljs) that has all the machinery required in dev/user.clj.

https://github.com/aamedina/cljs/blob/master/src/leiningen/new/om_cljs/dev/user.clj

I tried it myself and it works great. Austin could borrow from it, no?

danielsz avatar Feb 10 '14 19:02 danielsz

Yes, it looks like the approach I described is exactly what was implemented there. So, "borrow", yes, conceptually.

The user in question hasn't submitted a PR themselves, so any kind of copy/paste wouldn't be appropriate; but even so, they are operating a separate server that happens to coordinate with a running Austin REPL environment to get the necessary connect URL, etc. The "mounting" of a directory as the root of an Austin session's served content can and should be part of cemerick.austin.

cemerick avatar Feb 10 '14 19:02 cemerick