import * as I from 'immutable'; import {Resource} from '@avocado/resource'; import {Property} from '@avocado/mixins'; export class Trait { constructor(entity, params, state) { this.entity = entity; this.params = I.fromJS(this.constructor.defaultParams()).merge(params); this.state = I.fromJS(this.constructor.defaultState()).merge(state); } acceptStateChange(change) { if (!change.state) { return; } const undefinedProperties = {}; for (const key in change.state) { const value = change.state[key]; if (key in this.entity) { this.entity[key] = value; } else { undefinedProperties[key] = value; } } this.state = this.state.merge(undefinedProperties); } actions() { return {}; } destroy() {} hooks() { return {}; } hydrate() { return Promise.resolve(); } label() { return this.constructor.name; } listeners() { return {}; } toJSON() { return { params: this.params.toJS(), state: this.state.toJS(), }; } static contextType() { return {}; } static defaultParams() { return {}; } static defaultState() { return {}; } static dependencies() { return []; } static type() { return this.name.toLowerCase(); } } export function simpleState(key, meta = {}) { return (Superclass) => { meta.emit = meta.emit || function(...args) { this.entity.emit(...args); }; meta.get = meta.get || function(value) { return this.state.get(key); }; meta.set = meta.set || function(value) { this.state = this.state.set(key, value); }; return Property(key, meta)(Superclass); } }