19 Commits
1.0.4 ... 1.1.5

Author SHA1 Message Date
ad774185c2 Merge pull request 'proper ref to namespaced package' (#13) from 1.1.5 into main
All checks were successful
Push to main / publish (push) Successful in 11s
Reviewed-on: #13
2025-11-07 14:09:50 -07:00
c513a54717 proper ref to namespaced package
All checks were successful
Pull request change / publish (pull_request) Successful in 11s
2025-11-07 14:09:12 -07:00
7e53db5785 Merge pull request 'make scoped' (#12) from 1.1.4 into main
All checks were successful
Push to main / publish (push) Successful in 13s
Reviewed-on: #12
2025-11-07 14:00:01 -07:00
f463dec7f1 make scoped
All checks were successful
Pull request change / publish (pull_request) Successful in 11s
2025-11-07 13:59:07 -07:00
7f55ae0d4e Merge pull request 'added better error handling for missing action handlers' (#11) from 1.1.3 into main
All checks were successful
Push to main / publish (push) Successful in 12s
Reviewed-on: #11
2025-11-06 18:47:04 -07:00
6f52c56857 added better error handling for missing action handlers
All checks were successful
Pull request change / publish (pull_request) Successful in 10s
2025-11-06 18:44:04 -07:00
cfdcdf1def Merge pull request '1.1.2' (#10) from 1.1.2 into main
All checks were successful
Push to main / publish (push) Successful in 17s
Reviewed-on: #10
2025-11-06 18:34:28 -07:00
f8cdfe131f 1.1.2
All checks were successful
Pull request change / publish (pull_request) Successful in 15s
2025-11-06 18:33:33 -07:00
95f85aedaa Merge pull request 'version bump' (#9) from 1.1.1 into main
All checks were successful
Push to main / publish (push) Successful in 14s
Reviewed-on: #9
2025-11-06 15:54:18 -07:00
5c7cf36cf3 version bump
All checks were successful
Pull request change / publish (pull_request) Successful in 10s
2025-11-06 15:53:51 -07:00
2a84086828 Merge pull request 'force handler functions' (#8) from 1.1.0 into main
Some checks failed
Push to main / publish (push) Failing after 11s
Reviewed-on: #8
2025-11-06 15:51:52 -07:00
1dcdc17436 force handler functions
Some checks failed
Pull request change / publish (pull_request) Failing after 10s
2025-11-06 15:51:16 -07:00
466e95cb14 Merge pull request '1.0.6' (#7) from 1.0.6 into main
All checks were successful
Push to main / publish (push) Successful in 13s
Reviewed-on: #7
2025-11-06 15:00:58 -07:00
7ef7c44cf7 proper stream import
All checks were successful
Pull request change / publish (pull_request) Successful in 10s
2025-11-06 15:00:33 -07:00
bf31d5371e version bump 2025-11-06 15:00:18 -07:00
fc4e96ab37 Merge pull request 'stream ver up' (#6) from 1.0.5 into main
All checks were successful
Push to main / publish (push) Successful in 12s
Reviewed-on: #6
2025-11-06 14:57:38 -07:00
7af635a19b version bump
All checks were successful
Pull request change / publish (pull_request) Successful in 10s
2025-11-06 14:57:11 -07:00
665dd28f93 remove indirect ref
Some checks failed
Pull request change / publish (pull_request) Failing after 9s
2025-11-06 14:56:46 -07:00
e026dcdb15 stream ver up
Some checks failed
Pull request change / publish (pull_request) Failing after 10s
2025-11-06 14:55:53 -07:00
3 changed files with 52 additions and 25 deletions

View File

@@ -1,2 +0,0 @@
import { Interactor, Action, Reaction } from "./interactor.js";
export { Interactor, Action, Reaction };

View File

@@ -1,52 +1,81 @@
import { Stream } from './stream.js'; import { Stream } from "@brycethorup/stream";
export class Interactor { export class Interactor {
_actions = new Stream(); #actions = new Stream();
_reactions = new Stream(); #reactions = new Stream();
_latestReaction; #latestReaction;
#latestReactions = {};
constructor(initialReaction = new Reaction()) { constructor(initialReaction = new Reaction()) {
this._latestReactions = {}; this.#actions.listen((action) => {
this._actions.listen((action) => this._interaction(action)); let funcRef = `_handle${action.constructor.name}`;
if (!this[funcRef])
throw `${this.constructor.name} does not have a handler defined for the action "${action.constructor.name}". Create one by adding a function definition named "${funcRef}" in the ${this.constructor.name} class.`;
this[funcRef](action);
});
this._react(initialReaction); this._react(initialReaction);
} }
act(action) { act(action) {
if (!(action instanceof Action)) throw 'invalid action'; if (!(action instanceof Action)) throw "invalid action";
this._actions.add(action); this.#actions.add(action);
} }
observe(reactionHandler, provideLatestReaction = true) { observe(reactionHandler, provideLatestReaction = true) {
if (provideLatestReaction) reactionHandler(this._latestReaction); if (provideLatestReaction) reactionHandler(this.#latestReaction);
let listener = (reaction) => { let listener = (reaction) => {
if (!(reaction instanceof Reaction)) throw 'invalid reaction'; if (!(reaction instanceof Reaction)) throw "invalid reaction";
reactionHandler(reaction); reactionHandler(reaction);
}; };
this._reactions.listen(listener); this.#reactions.listen(listener);
return listener; return listener;
} }
ignore(listener) { ignore(listener) {
this._reactions.ignore(listener); this.#reactions.ignore(listener);
} }
_interaction(action) {}
_react(reaction) { _react(reaction) {
if (!(reaction instanceof Reaction)) throw 'invalid reaction'; if (!(reaction instanceof Reaction)) throw "invalid reaction";
let latest = this._latestReactions[reaction.constructor.name]; let latest = this.#latestReactions[reaction.constructor.name];
if (!reaction.equals(latest)) { if (!reaction.equals(latest)) {
this._latestReaction = reaction; this.#latestReaction = reaction;
this._latestReactions[reaction.constructor.name] = reaction; this.#latestReactions[reaction.constructor.name] = reaction;
this._reactions.add(reaction); this.#reactions.add(reaction);
} }
} }
} }
export class Action {} export class Action {}
export class ActionBundle {
add(action) {
if (!(action.prototype instanceof Action)) {
throw "Only classes extended by `Action` can be added to a `ActionBundle`";
}
let actionName = action.name;
this[`#${actionName}`] = action;
Object.defineProperty(this, actionName, {
get: () => this[`#${actionName}`],
});
}
}
export class Reaction { export class Reaction {
equals(reaction) { equals(reaction) {
return false; return false;
} }
} }
export class ReactionBundle {
add(reaction) {
if (!(reaction.prototype instanceof Reaction)) {
throw "Only classes extended by `Reaction` can be added to a `ReactionBundle`";
}
let reactionName = reaction.name;
this[`#${reactionName}`] = reaction;
Object.defineProperty(this, reactionName, {
get: () => this[`#${reactionName}`],
});
}
}

View File

@@ -1,11 +1,11 @@
{ {
"name": "interactor", "name": "@brycethorup/interactor",
"version": "1.0.4", "version": "1.1.5",
"description": "Cross-element communications and state management utility.", "description": "Cross-element communications and state management utility.",
"author": "Bryce Thorup", "author": "Bryce Thorup",
"type": "module", "type": "module",
"main": "index.js", "main": "interactor.js",
"dependencies": { "dependencies": {
"stream": "^1.0.0" "@brycethorup/stream": "^1.0.1"
} }
} }