Crystal -> JS Transpiler

Are you thinking features along the lines of meteor js?
A full-stack ruby alternative to the https://hood.ie javascript stack, and to the separate https://elm-lang.org/ frontend programming language (https://blog.crisp.se/2018/03/08/perlundholm/elm-for-backend-developers) or to the https://phoenixframework.org backend with its liveview frontend generator.

It wound then likely need to include disconnected operation / re-sync / offline-first these days.
Something like next version of PouchDB in the browser (Or an own db sync connector on the server providing user-individual 2-way pub/sub/sync data shares?)
The problem: https://stackoverflow.com/questions/46351432/per-user-db-pouchdb-couchdb-shared-data-doable)

Another idea?:

What about doing it the other way around. Using for example, the http://voltframework.com and adapting it to compile the web-backend with crystal, and maybe even platform binaries?

There is even a funding offer for getting “volt” re-born:

Are you thinking along the lines of meteor js

Yes, but more exactly along the lines of hyperstack (see https: “Hyperstack” dot Org) which is based on the ideas of meteor and volt.

The difference between meteor is that its Ruby, not JS. And the difference between Volt is that it uses React.js under the hood on the client, and ActiveRecord models (on the server and client) instead of MongoDB.

So what the hyperstack core team is looking to do is port Hyperstack from Ruby to Crystal, but that requires a Crystal → JS transpiler. Once we had that I believe the rest is straight forward.

Having Crystal on the server and Ruby on the client defeats the purpose btw. You would then have to write API adapters on either side of the wire, context switch between programming languages and tool chains etc.

2 Likes

I think there is lots of confusion still here.

The HUGE advantage of transpiling to JS (rather than compiling to WASM) is that as long as you do the mapping between JS functions and crystal methods smartly, you already have the DOM bindings.

This is the approach used by the Opal Ruby transpiler.

1 Like

Why would you need DOM bindings? When none of modern web UI frameworks using it. React, Vue, Angular - it’s all higher level abstraction. Browser / DOM API is just an ugly low level thing that pretty much nobody these days uses directly.

P.S.

For Opal it would be nice if it had proper async/await (or Fibers) support.

There are still occasions even with those frameworks to reach in and manipulate the DOM. However the point is that by transpiling to JS you can interface to any JS code, whether low level (DOM) or high level (React or Vue)

As far as async/wait goes: Those provide some syntactic sugar on top a lower level promise mechanism. This is useful in JS, because you can’t really build a decent Promise DSL. In Ruby the promise class gives just as nice code as async/wait, without all the crazy caveats, and inconsistencies of async/wait.

I should do a blog post on this :-)

3 Likes

Found this listing DOM transpiling feature descriptions:

@catmando I didn’t find anything about hyperstack and offline operation, aka “progressive web apps (or PWAs)”, and re-syncing.

Does hyperstack support working with react’s PWA feature enabled?
Does the isomorphic code (and the models) re-sync well after offline periods?

I can’t speak for Vue and Angular, but React exposes DOM events and nodes (via refs) so you can’t really escape the DOM without a framework transforming those events and nodes into a different abstraction.

Plus, you probably want to provide bindings to other browser APIs like WebSockets, XHR/fetch, IndexedDB, ServiceWorker, geolocation, or Promises, so you’d need Crystal bindings for those, as well. :-)

The Clearwater framework is somewhat React-like and uses the bowser gem to handle its Ruby bindings for the DOM and other browser APIs, which I’ve used in several Clearwater apps.

Sorry for the delayed response. Probably best to continue to conversation at the Hyperstack site, as it really is not relevant to Crystal.

https://join.slack.com/t/hyperstack-org/shared_invite/enQtNTg4NTI5NzQyNTYyLWQ4YTZlMGU0OGIxMDQzZGIxMjNlOGY5MjRhOTdlMWUzZWYyMTMzYWJkNTZmZDRhMDEzODA0NWRkMDM4MjdmNDE

I can do all those things with Headless Browser emulator, without accessing the actual Browser API.

All I need inside of the Crystal Black Box are two functions browser.eval(js-code-as-string) -> response-serialised-as-string and browser.on(event-name-as-string, callback).

Using these two methods you are able to take full control over Browser and do pretty much anything, without any special api. Yes, the performance will be not good, but, the modern computers and mobile phones are so insanely fast that it will be totally fine for like 90% of apps.

You can do this in client-side code?

@jgaskins you already did something like that in Phoenix-style LiveView ;)

With LiveView it worked like that

- Browser
- HTTP communication
- Crystal Server with LiveView on remote Machine

But it also could work this way, and run everything in Browser, no need to implement any wrappers for Browser API.

- Browser
- stdin/stout communication with Crystal WASM in same Browser
- Crystal Server with LiveView compiled to WASM and run in same Browser

http://repl.it has Crystal REPL with Crystal compiled to WASM and stdin/stdout. So it should be possible to do all that.

The example from that topic the LiveView real estate Listing - could be run with the Crystal Server compiled to WASM and running inside of the browser. Without any access to Browser API.

2 Likes

Do you have any leads on how to compile Crystal to WASM?
It would be great to code in Crystal WASM instead of Rust or Go in the browser!

See Crystal in (possible) WASM everywhere future?

Thanks, I have tested. It’s great, that works. It shows that WASM will be in Crystal in the furtur but coding in byte code (currently) it’s unusable.

How do those who code in Crystal (not byte code) and compile in WASM do it?

I get a 404 for repl.it’s “crystal” link…
If it does work maybe they…published how they do it somewhere?? :)

Did you mean this link ?
https://repl.it/languages/crystal
Crystal 0.27.2 [60760a546] (2019-02-05)
LLVM: 4.0.0

1 Like

It’s not immediately clear to me if repl.it is running “all locally in the browser” or just the IDE is and execution is somewhere else…they also mention a REPL?

Seeing the websocket messages I think they run the code somewhere in the cloud and then send back the result:

2 Likes