import { Stream } from "stream"; export class Interactor { #actions = new Stream(); #reactions = new Stream(); #latestReaction; #latestReactions = {}; constructor(initialReaction = new Reaction()) { this.#actions.listen((action) => this[`handle${action.constructor.name}`](action) ); this._react(initialReaction); } act(action) { if (!(action instanceof Action)) throw "invalid action"; this.#actions.add(action); } observe(reactionHandler, provideLatestReaction = true) { if (provideLatestReaction) reactionHandler(this.#latestReaction); let listener = (reaction) => { if (!(reaction instanceof Reaction)) throw "invalid reaction"; reactionHandler(reaction); }; this.#reactions.listen(listener); return listener; } ignore(listener) { this.#reactions.ignore(listener); } _react(reaction) { if (!(reaction instanceof Reaction)) throw "invalid reaction"; let latest = this.#latestReactions[reaction.constructor.name]; if (!reaction.equals(latest)) { this.#latestReaction = reaction; this.#latestReactions[reaction.constructor.name] = reaction; this.#reactions.add(reaction); } } } export class Action {} export class Reaction { equals(reaction) { return false; } }