/*! * xev * Copyright (c) 2017 syuilo * MIT Licensed */ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; import { EventEmitter } from 'node:events'; import cluster from 'node:cluster'; import autobind from './autobind.js'; /** * Global Event Emitter */ export default class Xev extends EventEmitter { /** * Init event emitter * @param namespace Namespace */ constructor(namespace) { super(); /** * Whether is mounted */ this.isMounted = false; this.namespace = namespace; //this.once('newListener', () => { process.addListener('message', this.onMessage); //}); } /** * Dispose this event emitter */ dispose() { this.removeAllListeners(); process.removeListener('message', this.onMessage); if (this.isMounted) { cluster.removeListener('message', this.onClusterMessageInMaster); process.removeListener('message', this.onProcessMessageInMaster); this.isMounted = false; } } onMessage(message) { // Ignore third party messages if (message.namespace != this.namespace) return; super.emit('*', message.type, message.data); super.emit(message.type, message.data); } /** * Mount event system. * This method must be called in the master process. */ mount() { if (cluster.isWorker) { throw 'Do not call this method in a worker process.'; } // If already mounted if (this.isMounted) return; // When receiving a message from workers cluster.on('message', this.onClusterMessageInMaster); // When receiving a message from the master process.on('message', this.onProcessMessageInMaster); this.isMounted = true; } onClusterMessageInMaster(sender, message) { process.emit('message', message, null); } onProcessMessageInMaster(message) { this.broadcast(message); } /** * Broadcast the message to all workers * @param message Message you want to broadcast */ broadcast(message) { // Ignore third party messages if (message.namespace != this.namespace) return; // Send message to each all workers for (const id in cluster.workers) { const worker = cluster.workers[id]; worker.send(message); } } /** * Publish event * @param type The name of the event * @param data The payload of the event * @return Always true */ emit(type, data) { const message = { type, data, namespace: this.namespace }; if (cluster.isPrimary) { process.emit('message', message, null); } else { process.send(message); } return true; } } __decorate([ autobind ], Xev.prototype, "dispose", null); __decorate([ autobind ], Xev.prototype, "onMessage", null); __decorate([ autobind ], Xev.prototype, "mount", null); __decorate([ autobind ], Xev.prototype, "onClusterMessageInMaster", null); __decorate([ autobind ], Xev.prototype, "onProcessMessageInMaster", null); __decorate([ autobind ], Xev.prototype, "broadcast", null); __decorate([ autobind ], Xev.prototype, "emit", null);