avocado-old/packages/state/synchronized.js
2019-04-23 15:25:03 -05:00

93 lines
2.1 KiB
JavaScript

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 function Synchronized(Superclass) {
return class Synchronized extends decorate(Superclass) {
constructor(...args) {
super(...args);
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 (
'undefined' !== typeof this[key]
&& 'undefined' !== typeof this[key].patchState
) {
this[key].patchState([step]);
}
else {
this[key] = step.value;
}
}
tick(elapsed) {
const children = this.synchronizedChildren();
for (let i = 0; i < children.length; ++i) {
const key = children[i];
if (
'undefined' !== typeof this[key]
&& 'undefined' !== typeof this[key].tick
) {
this[key].tick(elapsed);
}
}
if (AVOCADO_SERVER) {
this.state = this.state.withMutations((state) => {
for (let i = 0; i < children.length; ++i) {
const key = children[i];
if (
'undefined' !== typeof this[key]
&& 'undefined' !== typeof this[key].state
) {
state.set(key, this[key].state);
}
else {
state.set(key, this[key]);
}
}
});
}
}
}
}