JavaScript Interop in Hologram

Well … that’s definitely disappointing for those waiting for new news, but we all know how life works in practice. No need to sorry, but if possible you always should consider people on second side. Some people may think that project is completely abandoned especially if they see old issues that are opened for few years … Honestly even I almost forgot about your project while I believe that I have very good memory … :sweat_smile:

On GitHub I see old issues about mouse events. Having in mind that there is also no roadmap it looks very bad - it’s as click is the only event Hologram supports. Size and performance are not as important for early steps as number of features. I’m working on some app and after seeing your post I considered to give hologram a try, but I don’t see any information about features that I already use in said LiveView-based app. For now I have no idea which events are implemented, which events are planned and so on … I cannot see what and when I can do, so I can’t plan anything. That’s a huge blocker for an early adoption / first research. :icon_confused:

We know that our code would be transpiled to JavaScript, but we have no idea how to use many JavaScript APIs …

  1. DOM API
  2. Push notifications, Fullscreen API and many other desktop features …
  3. We don’t have even a JSON support as JSON (new Elixir module) uses currently unsupported with special form and Jason also does not work. I know few sites that put JSON data in element attributes and use them inside JavaScript
  4. window-based and document-based JavaScript features - some JavaScript browser APIs depend on them (for example document.fullscreenElement)

I understand that bringing it all soon may be very difficult, so how about creating some workaround until 1.0.0 version is released?

if ~JS"return document.fullscreenElement;" do
  ~JS"…"
else
  ~JS"…"
end

Well written code could be easily migrated to 1.0.0 version, to … let’s say something like …

if Hologram.Document.get().fullscreenElement do
  # …
else
  # …
end

In such case one of the most important things would be to somehow pass action name, so we can use Hologram actions for events that are not officially supported. I believe that API like that would give people some possibilities to try Hologram on more real world cases. :bulb:

I also took a look at hexdocs documentation … there is lots of modules and most probably many of them should have @moduledoc false or they are just completely not documented. :books:

I’m currently a bit busy as I’m working on my own project, but most probably in next month I would have more time for Hologram. I think about writing some mix tasks for it - maybe even port all phx tasks. :thinking:

1 Like

I hear you! Really appreciate your extensive feedback! It’s super helpful!

The GitHub repository has been cleaned up! :sparkles:

I understand the importance of having a clear picture of what works and what doesn’t. I’m currently focusing on documentation to help people get started. Soon there will be both a Roadmap docs page and a separate Events docs page. I’ve created a separate forum thread for discussion and announcements about new documentation pages: Hologram Documentation Updates/Feedback

Hologram uses a virtual DOM under the hood, providing a declarative frontend layer that abstracts DOM manipulation. The goal is to eventually transition to more efficient mechanisms similar to SolidJS or Svelte. Could you share specific use cases where you need direct DOM access?

These features are coming in future releases. :rocket: If you have a specific use case in mind, creating a separate forum thread would be very helpful - this way the whole community can join in, share similar requirements, and maybe even suggest temporary workarounds. Plus, having focused discussions helps us better understand everyone’s needs.

Could you elaborate on your specific use cases that require JSON support?

While there was a working JS sigil implementation previously, I’m cautious about reintroducing it as it might create more challenges than benefits. Proper JavaScript interoperability is relatively straightforward to implement at this stage. If this feature is blocking adoption for you or others, I’m willing to prioritize it. After completing the documentation, I plan to create a dedicated forum thread to understand what features are blocking adoption for users.

I’ve just created a GitHub Issue for this: Add @moduledoc false to modules that don't need HexDocs documentation · Issue #162 · bartblast/hologram · GitHub
Would you like to contribute a pull request? :slight_smile:

2 Likes

Before I would take a deeper look at hologram I would like to finish current project that I’m working on. There would be not just example, but a real-world use case. I just have to write documentation and tests, lots of tests …

Well … mention APIs are not that hard to visualise … For example Discourse uses Push notifications, so that’s best real world use case … As above I plan to release also a real-world case for Fullscreen API.

Oh this one is rather low priority, but still it’s definitely part of adoption. In past I saw some hobby sites (just was curious how they work) storing JSON data in data-* attributes and uses it within JavaScript code. For sure they could be rewritten, but just for a hobby project it’s much easier to simply rewrite JavaScript code to Elixir one than rewrite core site logic even if said server/client state would be much better in specific use case.

It’s not rather a part of adoption, but a workaround which would make create demo ports of existing projects much simpler (by copy-paste) rather than waiting for only one feature that’s yet not implemented. As said if there is something relatively simple then it should be added just to see by demo projects how often some features are used and therefore you may prioritise one over others.

Look that I see issue like:

and I know that there is no JavaScript workaround support.

So if I would port an existing LiveView application into Hologram I would in fact need to implement more JavaScript logic than less. However if I would have such code:

workaround(s[document.getElementById("?").addEventListener("mousemove", ?)], "some-id", :action_name)

then when feature would be delivered it would be much simpler to update the code as all I would do is to replace said one-liner or even completely remove it in favour of ~H"" markup.

So think:

  1. Temporary rewrite logic to JavaScript code + rewrite JavaScript to Hologram when feature would be delivered
  2. Write Hologram code and 1LOC in init + remove 1LOC from init when feature would be delivered

Which one would be better for first demo adoption?

Of course in my case if you would say:

Alright, but I can spend one week on it or in exactly same time support all events. What you prefer?

then I would fully agree that such workaround is not important, but this:

  1. Would not happen when right now you are focused on documentation (which is a good thing)
  2. Even if that would happen it would create just an extra pressure on you to deliver new features asap

That’s why I suggested some kind of a “quick workaround” (if possible) … :thinking:

Sure!

1 Like

I implemented the ~JS sigil. It will be released in release 0.3.0, probably even today. But please treat it as something temporary – I’m not 100% sure if it will stay.

Example: ~JS"console.log('Hello, world!');"

To return a value, just use the return keyword: ~JS"return 123"

Multiple line statements are also allowed. The sigil just evaluates the given JS code as is.

2 Likes

Brilliant! Any way to reference action?

# TODO: replace sigil code when event would be officially supported:
~JS/someElement.addEentListener("eventName", {hologram_action(:action_name)})/
# …
def action(name, event_params, component) do
  # Action logic here
end
1 Like

Nope, this will work in simple cases only that don’t affect Hologram state management and DOM abstraction. Example use case: document.documentElement.requestFullscreen(). Such cases will be easily abstracted away in future anyway. Keep in mind that Hologram uses boxed types and there’s quite complex machinery for events, state management and client-server transport underneath, so you can’t just use native JavaScript types.

2 Likes