@truffle/dashboard-message-bus-client
Version:
Client library for accessing the truffle dashboard's message bus
122 lines • 5.93 kB
JavaScript
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.PublishMessageLifecycle = void 0;
const dashboard_message_bus_common_1 = require("@truffle/dashboard-message-bus-common");
const debug_1 = __importDefault(require("debug"));
const debug = (0, debug_1.default)(`dashboard-message-bus-client:publish`);
class PublishMessageLifecycle {
constructor({ message, connection }) {
this._responseReceived = false;
this._invalidated = false;
this._abandoned = false;
this.message = message;
this._connection = connection;
this._messageHandler = this._messageHandler.bind(this);
this.response = new Promise(resolve => {
this._responsePromiseResolve = resolve;
});
connection.on("message", this._messageHandler);
}
/**
* Notify other potential subscribers of this message that it has been
* invalidated, and they therefore should not respond.
*/
invalidate() {
return __awaiter(this, void 0, void 0, function* () {
if (this._abandoned || this._invalidated || this._responseReceived) {
return;
}
this._invalidated = true;
this._connection.off("message", this._messageHandler);
/*
* Resolving the response promise with `null` is the best of the bad options
* when a message is invalidated
*
* Other options included rejecting with an error, and simply letting the
* promise go unresolved.
*
* Letting the promise go unresolved is worst option, as it prevents the
* `finally` block/handler from ever running.
*
* Rejecting with an error is maybe okay, but there's nothing to prompt the
* consumer of this library to know that they'll need to catch this error or
* else they'll encounter terminations due to unresolved promises.
*
* Returning null means that authors writing TS code against this library
* will at least have some indicator that the message invalidation mechanism
* exists, and they may need to write code to handle it.
*
*/
this._responsePromiseResolve(null);
yield this._connection.send((0, dashboard_message_bus_common_1.createMessage)(dashboard_message_bus_common_1.invalidateMessageType, this.message.id));
});
}
/**
* Stop waiting for the response to this message, but don't invalidate it,
* either.
*/
abandon() {
return __awaiter(this, void 0, void 0, function* () {
if (this._abandoned || this._invalidated || this._responseReceived) {
return;
}
this._abandoned = true;
this._connection.off("message", this._messageHandler);
/*
* Resolving the response promise with `null` is the best of the bad options
* when a message is invalidated
*
* Other options included rejecting with an error, and simply letting the
* promise go unresolved.
*
* Letting the promise go unresolved is worst option, as it prevents the
* `finally` block/handler from ever running.
*
* Rejecting with an error is maybe okay, but there's nothing to prompt the
* consumer of this library to know that they'll need to catch this error or
* else they'll encounter terminations due to unresolved promises.
*
* Returning null means that authors writing TS code against this library
* will at least have some indicator that the message invalidation mechanism
* exists, and they may need to write code to handle it.
*
*/
this._responsePromiseResolve(null);
});
}
_messageHandler(response) {
if (response.id === this.message.id) {
this._responseReceived = true;
this._connection.off("message", this._messageHandler);
debug("Received response %o for message %s of type '%s'", response, this.message.id, this.message.type);
return this._responsePromiseResolve(response);
}
if (invalidatesMessage({ response, message: this.message })) {
this._invalidated = true;
this._connection.off("message", this._messageHandler);
debug("Message id %s of type '%s' was invalidated.", this.message.id, this.message.type);
return this._responsePromiseResolve(null);
}
}
}
exports.PublishMessageLifecycle = PublishMessageLifecycle;
function invalidatesMessage({ response, message }) {
if (response.type !== dashboard_message_bus_common_1.invalidateMessageType &&
message.type !== dashboard_message_bus_common_1.invalidateMessageType) {
return false;
}
return response.payload === message.id;
}
//# sourceMappingURL=publish.js.map