rxpoweredup
Version:
A Typescript RxJS-based library for controlling LEGO Powered UP hubs & peripherals.
70 lines (69 loc) • 2.64 kB
JavaScript
import { ReplaySubject, from, of, switchMap, take, tap } from 'rxjs';
import { PortCommandExecutionStatus } from '../../../hub';
export var PortOutputCommandTaskState;
(function (PortOutputCommandTaskState) {
PortOutputCommandTaskState[PortOutputCommandTaskState["pending"] = 0] = "pending";
PortOutputCommandTaskState[PortOutputCommandTaskState["waitingForResponse"] = 1] = "waitingForResponse";
PortOutputCommandTaskState[PortOutputCommandTaskState["inProgress"] = 2] = "inProgress";
})(PortOutputCommandTaskState || (PortOutputCommandTaskState = {}));
export class TaskPortOutputCommand {
message;
result = new ReplaySubject();
_state = PortOutputCommandTaskState.pending;
responseReceived = new ReplaySubject(1);
terminalExecutionStates = new Set([
PortCommandExecutionStatus.completed,
PortCommandExecutionStatus.discarded,
PortCommandExecutionStatus.executionError,
]);
stateTransitions = new Map([
[PortOutputCommandTaskState.pending, PortOutputCommandTaskState.waitingForResponse],
[PortOutputCommandTaskState.waitingForResponse, PortOutputCommandTaskState.inProgress],
[PortOutputCommandTaskState.inProgress, PortOutputCommandTaskState.waitingForResponse],
]);
constructor(message) {
this.message = message;
}
get portId() {
return this.message.portId;
}
get state() {
return this._state;
}
set state(value) {
if (this._state === value) {
return;
}
if (this.stateTransitions.get(this._state) === value) {
this._state = value;
}
else {
throw new Error(`Invalid state transition from ${this._state} to ${value}`);
}
}
discard() {
this.result.complete();
}
emitError(error) {
this.result.error(error);
}
setExecutionStatus(status) {
this.result.next(status);
this.responseReceived.next(true);
if (this.terminalExecutionStates.has(status)) {
this.result.complete();
}
}
dispose() {
return void 0;
}
accept(visitor) {
visitor.visitTaskPortOutputCommand(this);
}
execute(channel) {
if (this.message.waitForFeedback) {
return of(null).pipe(switchMap(() => from(channel.sendMessage(this.message, () => (this.state = PortOutputCommandTaskState.waitingForResponse)))), switchMap(() => this.responseReceived), take(1));
}
return from(channel.sendMessage(this.message)).pipe(tap(() => this.setExecutionStatus(PortCommandExecutionStatus.completed)));
}
}