Since the pandemic started I started watching more and more live streamers on YouTube and sometimes Twitch. While I don't plan on streaming my self (yet), I got interested in the tech stack used. One comment that came up over and over was how Twitch had better integrations for chat to interact with the stream, using a system they call redeems. I decided I wanted to build a solution for YouTube which gives a twitch like experience.
My tech stack of choice was to use an Electron App that runs an ExpressJS server on the backend / localhost. It would server Widgets that could be loaded in to OBS (the software streamers use to broadcast). But I needed way for the main application to talk to the widgets. The obvious choice is to use Websockets over localhost.
That's great - but I was working in Vue-land and I had an interesting idea.
What if I could make a Ref type variable that works natively in Vue, but automatically syncs over a local websocket server.
I decided to build a library called vue-socket-ref to do just that.
In order to understand what this does, we first have to go over Vue refs.
If you write a like code like:
const foo = Ref(5)
You will get a variable that you can use in your template HTML that will automatically re-render when the variable changes. It works by overloading the getters and setters for a value key on the variable, so for example:
foo = 6 // doesn't work
But
foo.value = 6 // does work
By overloading the setting for .value, the Vue reactivity system can tell when the value changes and surgically re-render the component that uses the value.
So my idea was simple, to make a new function/class called socketRef, that takes an initial value as well as a key, like so:
const foo = socketRef(5, 'foo');
This function returns a regular Vue ref, just like the examples above. But it wraps the ref in a closure and also watches it's value. When it's value changes, just like Vue's template system, my socketRef system gets notified. It then broadcasts the value over websockets along with it's key.
If any other application open uses the same key and the same ip/port number in the library, it will get notification that the value changed somewhere else, and change it's own value.
This is really cool. These are variables that work like regular Refs, but sync across different application instances, or even different contexts. If you have a webrowser loading a page with the socket library, an Electron APP can talk to the browser tab, and the refs magically sync in both places.
If you open a website that uses this tech in FireFox and Chrome at the same time, the tabs will sync between each other automatically.
But the dev cycle is just like using Regular Refs. I also provided socketShallowRef which works similar to Vue's own shallowRef. In fact it is Vue's own shallowRef, but with the extra closure wrapping to automatically sync over sockets. I also have read only versions of each as well, so you can just subscribe to updates but not allow changes.
This worked perfect for my needs - my Electron Application manages state & serves widgets over a localhost server, but then it talks to those widgets over these socket-ref types, so both the widgets and the application can be programmed in Vue/JS and things will just sync.
You can find the library here:
https://github.com/orokro/socket-ref
Note that this is still in development and could use some more polish. So far it's been stable in my application which I will write about in a future post, so YMMV. But so far it's been great!

