Hey everybody, it seems like Signals are really catching on as a standard for reactivity in the front end space. Pretty much all the front end frameworks are adopting them, and they are also starting to make their way through the TC39 standards process. As an experiment, I decided to see how easy it would be to connect signals to a Pheonix Channel. Spoiler alert: it was really easy! I used LiveState (a thing I built) to hold the state for the signal.
So far, preact signals and the TC39 polyfill are supported, but adding additional signal implementations should be trivial PRs I would be delighted to receive and merge
This topic is a pure announcement. For Elixir or Phoenix it’s not a problem, but in this case lots of people may have no idea what Signals are. If you are one of them take a look at this article:
createSignal() returns a [getter, setter], the setter is being used in the interval to count up, the getter is used in the JSX. The reactive system will now change exatly that number directly in the DOM and nothing else on each change of count().
What would live-signals do now with this?
Do I transparently get “subscribe” to the signal on the server and vice-versa?
What about stores? (A Comprehensive Guide to SolidJS Stores - Raqueebuddin Aziz)
While signals (at least in solid) are mainly used for view-stuff, stores are where the state is, so that would be really nice to get access to from the server.
From the example, my first thought is that adding support for SolidJS, at least initially, would work in a very similar way to the preact and polyfill versions: with a createSolidSignal that returns an array of [signal, dispatchEvent]. If it’s as trivial to build an example with Solid as it was with Preact (which I have pretty much zero experience with) it should be really easy to do.
I don’t think it’s a complete example (as onInput and onClick don’t seem to be used) but I think onClick in the following:
Shows how you can trigger events on the server:
Presumably, the state of the signal client-side will reflect what the server sent it, and the client uses dispatchEvent to call those server-side handlers.
Yup that’s pretty much it. I’ll see if I can do a more complete example later this week. If I really get ambitious I’ll do a solid example as well.
I’ve added a little more to the preact example now. It’s not as fleshed out as the live-templates example I copied it from, but it works as far as showing how to dispatch event. Note that I have really know idea what I’m doing with Preact, so there is likely I more ideomatic preact approach. To your question @Sebb , as it seems like Signals are getting a reasonable amount of traction, using them to re-render state updates pushed down over a Phoenix Channel seems to be viable AFAICT. It really doesn’t change much: we are doing much the same with Lit Element based apps without signals, and it’s worked well for us.
// this will tick up each second
customElement('my-counter', () => {
const [count, setCount] = createSignal(0);
setInterval(() => setCount(count() + 1), 1000);
return <div>Count: {count()}</div>;
})
and use this in your LV like
<my-counter id="counter_1"></my-counter>
You could just handle the state of the counter in LV-handle_info, or overwrite the count from the server. Without a bridge for the signals, you’d have to do that manually using events and hooks or such.
This library is designed to help with front end frameworks that use Signals, such as Preact and eventually other signal embracing libraries such as Solid, Svelte, etc, etc. It can also be used by web components, but LiveState already has very nice support for web components without needing signals.
However, all of these options (and LiveState in general) are designed to help you when, for whatever reason, LiveView is not a good option. Integrating LiveView itself with front end frameworks is whole separate topic and something you probably don’t want to try to do unless you really, really have to
Yeah, it sounds like you may want something specific for Solid to create a store backed by a LiveState channel. LiveSolid or some such thing? My guess, based on experience so far, is that you could use LiveSignals as an example and create such a thing in just few lines of code.