rxpoweredup
Version:
A Typescript RxJS-based library for controlling LEGO Powered UP hubs & peripherals.
67 lines (66 loc) • 2.57 kB
JavaScript
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;
}
}