mobx-socket

Keeping MobX observable objects always in sync between a single server and multiple clients over socket.io

Usage no npm install needed!

<script type="module">
  import mobxSocket from 'https://cdn.skypack.dev/mobx-socket';
</script>

README

MobX Socket

A package for syncing the same MobX observable objects between a single server and multiple clients.

Example usage

The observable objects shared with mobx-socket need to implement the SharedObservable interface. This means that they define toTransmit() and fromTransmit() functions that will define how the state of the observable is coded into transmission.

export interface SharedObservable {
   toTransmit: () => any
   fromTransmit: (update: any) => void
}

In basic case, the toTransmit() will just return a JS object generated from all the state fields of the observable. This way the mobx-socket will be able to observe the state changes and transmit them over the socket.

The fromTransmit(update: any) => void function will decode the data back into the observables state. It will be run in action when updates arrive through the socket.

I recommend that the MobX state objects will be defined in classes, that are accessible by both client and server code.

class ExampleState implements SharedObservable {
   constructor() {
      makeAutoObservable(this)
   }

   public number = 1

   public increase() {
      this.number += 1
   }

   public toTransmit() {
      return {
         number: this.number,
      }
   }

   public fromTransmit(update: any) {
      this.number = update.number
   }
}

Settings up server

   const server = new MobxSocketServer(5010)
   const state = new ExampleState()

   // You need to define a key for each shared observable object added to mobx-socket
   server.addSharedObservable('example-state', state)
   server.run()

Setting up client

   const client = new MobxSocketClient('ws://localhost:5010')
   const state = new ExampleState()
   client.addSharedObservable('example-state', state)
   client.run()

After this the observable object states should always be in sync. Any changes made to the state objects in either end wlil update the states in the other end. Any changes made in any client will also be updated to all other clients.

Notes

Any changes will transmit the whole object returned in toTrasmit(), so there will be a lot of traffic if the objects are large. Maybe in the future add smarter change detection that will only transmit changed fields.