import * as I from 'immutable'; import {compose} from '@avocado/core'; import {Property} from '@avocado/mixins'; import {nextStep} from './next-step'; const decorate = compose( Property('state'), ); export class Synchronized extends decorate(class {}) { constructor() { super(); this.state = I.Map(); } synchronizedChildren() { return []; } patchState(patch) { for (const step of patch) { const {op, path, value} = step; if ('/' === path) { for (const key in value) { this.patchStateStep(key, { op, path, value: value[key], }); } } else { const [key, substep] = nextStep(step); this.patchStateStep(key, { op: substep.op, path: substep.path, value: substep.value, }); } } } patchStateStep(key, step) { if (!(key in this)) { return; } if (this[key] instanceof Synchronized) { this[key].patchState([step]); } else { this[key] = step.value; } } tick(elapsed) { const children = this.synchronizedChildren(); for (const key of children) { if (this[key] instanceof Synchronized) { this[key].tick(elapsed); } } this.state = this.state.withMutations((state) => { for (const key of children) { if (this[key] instanceof Synchronized) { state.set(key, this[key].state); } else { state.set(key, this[key]); } } }); } }