'use strict';
import { Reporter } from './reporter/reporter.js';
import { InformationSource } from './reporter/information_source.js';
/** Atom */
class Atom extends InformationSource {
/** @typedef {string} state */
/** @typedef {Object<state,Array<state>>} StatesAndTransitions */
/**
* @param {Reporter} reporter
* @param {string} name
* @param {StatesAndTransitions} stateTransistions
* @param {state} initialState
*/
constructor(reporter, name, stateTransistions, initialState) {
super(reporter, {
name
});
this.addEvent('change');
for (const state in stateTransistions) {
const transitions = stateTransistions[state];
if (!Array.isArray(transitions)) {
throw new Error('Missing state transitions array');
}
for (const transition of transitions) {
if (!stateTransistions.hasOwnProperty(transition)) {
throw new Error('State transition to unknown state specified');
}
}
}
if ( ! stateTransistions[ initialState ]) {
throw new Error( 'Unknown initial state ' + initialState );
}
this._states = stateTransistions;
this._state = initialState
}
/**
* @private
* @type {string}
*/
_state;
/**
* @type {Array<Object>}
* @private
*/
_states;
/**
* @param {string} newState
* @returns {Promise<Array<any>>}
*/
async setState( newState, bubbleState ) {
if (newState === this._state) {
return;
}
if (this._states[newState]) {
const previousState = this._state;
if (previousState && !this._states[previousState].includes(newState)) {
const msg = `Transition from state ${previousState} to state ${newState} not allowed`;
this.report({
msg,
level: 'error'
});
throw new Error(msg);
}
this._state = newState;
return this.emit('change', { state: this._state, previousState, bubbleState });
}
else {
// console.error( 'Requested unknown state', newState);
throw new Error('Unknown state ' + newState);
}
}
/**
* @type {state}
*/
get state() {
return this._state
}
}
export { Atom };