Scene Streamer
Watch a dom for changes and stream changes to the dom via an xml protocol.
Usage
Install:
npm install --save scene-streamer
Then require:
import { Patch, Apply } from 'scene-streamer'
Watch a DOM and generate patches:
new Patch(window, domnode, (events) => {
ws.send(events);
});
You need to specify the global object that has an MutationObserver
and HTMLElement
defined on it. window
will work on the browser. You can use scenevr/microdom
for
server side.
Recieve patches and apply them to a local DOM:
let apply = new Apply(domnode);
ws.on('message', (event) => {
apply.onPatch(event.data);
})
Overview
I invented this for SceneVR, where I need to simulate a scene on the server and then stream changes down to all connected clients.
Your dom implementation must support MutationObservers, thats how we watch for changes. The wire format looks like this:
<patch><html data-uuid="2f77f229-0f39-42c1-9cb5-ac6a398db356"><body data-uuid="d923081d-8afa-4436-8cef-752ab208fa3f"><a-scene data-uuid="df37f93d-e67f-4878-9613-8d3c2edb51be"><a-cube data-uuid="2443b32f-8c93-4cca-ac57-5767fb747f0d"></a-cube></a-scene></body></html></patch>
Each patch is send in a patch element. Each element has a data-uuid
added. This
is a private attribute that won't be added to your markup. You can look up an
element by data-uuid
, or find an elements data-uuid
using the private-attributes
module.
When an element is deleted, we send a dead
element. Here is an exaxample of removing
an element that is parented to the scene.
<patch><a-scene data-uuid="cdb755c3-87fa-492c-b8a5-29034968c3d9"><dead data-uuid="c20fb03d-7eaa-4277-8dc2-0ee09b55d82e"></dead></a-scene></patch>
Use the supplied apply
function to apply changes to the dom. The wire protocol
may change as I find more efficient ways of diffing and patching, but the exposed
API should stay the same.
Notes
Sorry I used es6 in this so it requires babelify. It's not really necessary but oh well.