UNPKG

rxpoweredup

Version:

A Typescript RxJS-based library for controlling LEGO Powered UP hubs & peripherals.

67 lines (66 loc) 2.57 kB
import { Observable, bufferCount, concatWith, map } from 'rxjs'; import { TaskPortOutputCommand, TaskWithResponse, TaskWithoutResponse } from './queue-tasks'; export class OutboundMessenger { taskQueueFactory; logger; isDisposed = false; genericTaskQueue; portOutputCommandTaskQueues = new Map(); constructor(taskQueueFactory, logger) { this.taskQueueFactory = taskQueueFactory; this.logger = logger; this.genericTaskQueue = this.taskQueueFactory.createTaskQueue(); } sendWithoutResponse(message) { const task = new TaskWithoutResponse(message); return this.createExecutionStreamForTask(task, this.genericTaskQueue); } sendWithResponse(...sequenceItems) { const tasks = sequenceItems.map(({ message, reply }) => new TaskWithResponse(message, reply)); const executionStreams = tasks.map((task) => this.createExecutionStreamForTask(task, this.genericTaskQueue)); if (executionStreams.length === 1) { return executionStreams[0]; } else { return executionStreams[0].pipe(concatWith(...executionStreams.slice(1)), bufferCount(sequenceItems.length), map((r) => r.at(-1))); } } sendPortOutputCommand(message) { const task = new TaskPortOutputCommand(message); return this.createExecutionStreamForTask(task, this.getQueueForPort(task.portId)); } createExecutionStreamForTask(task, queue) { let isEnqueued = false; return new Observable((observer) => { if (this.isDisposed) { observer.error(new Error('Outbound messenger is disposed')); return; } if (!isEnqueued) { queue.enqueueTask(task); isEnqueued = true; } const sub = task.result.subscribe(observer); return () => sub.unsubscribe(); }); } dispose() { if (this.isDisposed) { throw new Error('Already disposed'); } this.isDisposed = true; this.genericTaskQueue.dispose(); for (const queue of this.portOutputCommandTaskQueues.values()) { queue.dispose(); } this.logger.debug('Outbound messenger disposed'); } getQueueForPort(portId) { let queue = this.portOutputCommandTaskQueues.get(portId); if (!queue) { queue = this.taskQueueFactory.createTaskQueue(); this.portOutputCommandTaskQueues.set(portId, queue); } return queue; } }