diff --git a/routes/router.api.events.js b/routes/router.api.events.js index 83c0494..93005d7 100644 --- a/routes/router.api.events.js +++ b/routes/router.api.events.js @@ -2,6 +2,8 @@ const WebSocket = require("ws"); const path = require("path"); const fs = require("fs"); +const { emitter, emitted } = require("../system/component/class.events.js"); + module.exports = (app, router) => { let wss = new WebSocket.Server({ @@ -39,10 +41,23 @@ module.exports = (app, router) => { ]; */ + emitter.on(emitted, (obj) => { + wss.clients.forEach((client) => { + + let { readyState, filter } = client; + let { event, component } = obj; + + if (readyState === WebSocket.OPEN && filter.events.includes(event) && filter.components.includes(component)) { + client.send(JSON.stringify(obj)); + } + + }); + }); + // fix #403 "Add missing components" let componentNames = fs.readdirSync(path.resolve(process.cwd(), "components")); - + /* function reemit(event, component) { return (...args) => { @@ -60,7 +75,7 @@ module.exports = (app, router) => { if (client.intents.includes(event) /*&& client.components.includes(component)* && client.readyState === WebSocket.OPEN) { client.send(obj); } - */ + * let { readyState, filter } = client; @@ -73,6 +88,7 @@ module.exports = (app, router) => { }; } + // create reemit more automaticly // TODO: loop over events defined in .events // https://nodejs.org/dist/latest-v16.x/docs/api/events.html#emittereventnames @@ -101,6 +117,7 @@ module.exports = (app, router) => { } }); + */ router.get("/", (req, res) => { diff --git a/system/component/class.base.js b/system/component/class.base.js index 6852a04..e99a037 100644 --- a/system/component/class.base.js +++ b/system/component/class.base.js @@ -1,7 +1,8 @@ const process = require("process"); -const events = require("events"); +//const events = require("events"); const Hooks = require("../class.hooks.js"); +const Events = require("./class.events.js"); /** * @description @@ -22,10 +23,11 @@ const Hooks = require("../class.hooks.js"); */ module.exports = class BASE { - constructor() { + constructor(name) { this.ready = false; - this.events = new events(); + this.events = new Events(name); this.hooks = new Hooks(); + // this.logger = ...? } // NOTE improve/change function name diff --git a/system/component/class.common.js b/system/component/class.common.js index c80ad6b..2d35f92 100644 --- a/system/component/class.common.js +++ b/system/component/class.common.js @@ -2,6 +2,7 @@ const _expose = require("../../helper/expose.js"); const BASE = require("./class.base.js"); +const Logger = require("../../system/logger"); const promisify = require("../../helper/promisify"); /** @@ -20,11 +21,11 @@ const promisify = require("../../helper/promisify"); */ module.exports = class COMMON extends BASE { - constructor(logger) { + constructor(name) { - super(); + super(name); - this.logger = logger; + this.logger = Logger.create(name); } diff --git a/system/component/class.component.js b/system/component/class.component.js index 8fdd88e..130253d 100644 --- a/system/component/class.component.js +++ b/system/component/class.component.js @@ -47,7 +47,7 @@ module.exports = class COMPONENT extends COMMON { constructor(name, schema, classes = []) { - super(require("../../system/logger").create(name)); + super(name); classes.forEach((cls) => { Object.defineProperty(cls, "scope", { diff --git a/system/component/class.events.js b/system/component/class.events.js new file mode 100644 index 0000000..b4b9488 --- /dev/null +++ b/system/component/class.events.js @@ -0,0 +1,42 @@ +const { EventEmitter } = require("events"); + +module.exports = class Events extends EventEmitter { + + static emitted = Symbol("emitted"); + static registered = Symbol("registerd"); + static emitter = new EventEmitter(); + + constructor(name) { + super(); + this.name = name; + this._registeredEvents = new Set(); + } + + emit(event, ...args) { + + // the idea behin this was that it is used for /api/events ws route + // but the static "side chain" emitter, can also be used + // the purpuse of it was to transfer events between workers + // see #6 when implmented + // also, the "scenes" component can use it to detect state changes, e.g. for triggers + if (!this._registeredEvents.has(event)) { + + this._registeredEvents.add(event); + + process.nextTick(() => { + super.emit(Events.registered, ...args); + }); + + } + + Events.emitter.emit(Events.emitted, { + component: this.name, + event, + args + }); + + return super.emit(event, ...args); + + } + +}; \ No newline at end of file