ntcore-ts-client
Version:
A TypeScript library for communication over [WPILib's NetworkTables 4.1 protocol](https://github.com/wpilibsuite/allwpilib/blob/main/ntcore/doc/networktables4.adoc).
214 lines • 8.41 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.PubSubClient = void 0;
var tslib_1 = require("tslib");
var messenger_1 = require("../socket/messenger");
/** The client for the PubSub protocol. */
var PubSubClient = /** @class */ (function () {
function PubSubClient(serverUrl) {
var _this = this;
/**
* Called by the messenger when a topic is updated.
* @param message - The message data.
*/
this.onTopicUpdate = function (message) {
var topic = _this.getTopicFromId(message.topicId);
if (topic) {
topic.updateValue(message.value, message.serverTime);
}
var knownTopic = _this.getKnownTopicParams(message.topicId);
if (knownTopic) {
_this.prefixTopics.forEach(function (prefixTopic) {
if (knownTopic.name.startsWith(prefixTopic.name)) {
prefixTopic.updateValue(knownTopic, message.value, message.serverTime);
}
});
}
if (!topic && !knownTopic) {
console.warn("Received update for unknown topic with ID ".concat(message.topicId));
}
};
/**
* Called by the messenger when a topic is announced.
* @param params - The announce message parameters.
*/
this.onTopicAnnounce = function (params) {
_this.knownTopicParams.set(params.id, params);
// Announce to the topic
var topic = _this.topics.get(params.name);
topic === null || topic === void 0 ? void 0 : topic.announce(params);
// Find all prefix topics that match the announced topic
_this.prefixTopics.forEach(function (prefixTopic) {
if (params.name.startsWith(prefixTopic.name)) {
prefixTopic.announce(params);
}
});
};
/**
* Called by the messenger when a topic is unannounced.
* @param params - The unannounce message parameters.
*/
this.onTopicUnannounce = function (params) {
var topic = _this.topics.get(params.name);
if (!topic) {
console.warn("Topic ".concat(params.name, " was unannounced, but does not exist"));
return;
}
topic.unannounce();
};
/**
* Called by the messenger when a topic's properties are updated.
* @param params - The properties message parameters.
*/
this.onTopicProperties = function (params) {
var topic = _this.topics.get(params.name);
if (params.ack) {
if (!topic) {
console.warn("Topic ".concat(params.name, " properties were updated, but does not exist"));
return;
}
}
};
this._messenger = messenger_1.Messenger.getInstance(serverUrl, this.onTopicUpdate, this.onTopicAnnounce, this.onTopicUnannounce, this.onTopicProperties);
this.topics = new Map();
this.prefixTopics = new Map();
this.knownTopicParams = new Map();
// In the DOM, auto-cleanup
if (typeof window !== 'undefined') {
window.onbeforeunload = function () {
_this.cleanup();
};
}
}
Object.defineProperty(PubSubClient.prototype, "messenger", {
get: function () {
return this._messenger;
},
enumerable: false,
configurable: true
});
/**
* Gets the instance of the NetworkTables client.
* @param serverUrl - The URL of the server to connect to. This is not used after the first call.
* @returns The instance of the NetworkTables client.
*/
PubSubClient.getInstance = function (serverUrl) {
var instance = this._instances.get(serverUrl);
if (!instance) {
instance = new PubSubClient(serverUrl);
this._instances.set(serverUrl, instance);
}
return instance;
};
/**
* Reinstantiates the client by resubscribing to all previously subscribed topics
* and republishing for all previously published topics.
* @param url - The URL of the server to connect to.
*/
PubSubClient.prototype.reinstantiate = function (url) {
var _this = this;
this._messenger.reinstantiate(url);
this.topics.forEach(function (topic) {
topic.resubscribeAll(_this);
if (topic.publisher)
topic.republish(_this);
});
this.prefixTopics.forEach(function (prefixTopic) {
prefixTopic.resubscribeAll(_this);
});
};
/**
* Registers a topic with this PubSubClient.
* @param topic - The topic to register
*/
PubSubClient.prototype.registerTopic = function (topic) {
if (topic.isRegular()) {
if (this.topics.has(topic.name)) {
throw new Error("Topic ".concat(topic.name, " already exists. Cannot register a topic with the same name."));
}
this.topics.set(topic.name, topic);
}
else if (topic.isPrefix()) {
if (this.prefixTopics.has(topic.name)) {
throw new Error("Prefix topic ".concat(topic.name, " already exists. Cannot register a topic with the same name."));
}
this.prefixTopics.set(topic.name, topic);
}
};
/**
* Updates the value of a topic on the server.
* @param topic - The topic to update.
* @param value - The new value of the topic.
*/
PubSubClient.prototype.updateServer = function (topic, value) {
this._messenger.sendToTopic(topic, value);
};
/**
* Gets the topic with the given ID.
* @param topicId - The ID of the topic to get.
* @returns The topic with the given ID, or null if no topic with that ID exists.
*/
PubSubClient.prototype.getTopicFromId = function (topicId) {
var e_1, _a;
try {
for (var _b = tslib_1.__values(this.topics.values()), _c = _b.next(); !_c.done; _c = _b.next()) {
var topic = _c.value;
if (topic.id === topicId) {
return topic;
}
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
}
finally { if (e_1) throw e_1.error; }
}
return null;
};
/**
* Gets the topic with the given name.
* @param topicName - The name of the topic to get.
* @returns The topic with the given name, or null if no topic with that name exists.
*/
PubSubClient.prototype.getTopicFromName = function (topicName) {
var _a;
return (_a = this.topics.get(topicName)) !== null && _a !== void 0 ? _a : null;
};
/**
* Gets the topic with the given name.
* @param topicName - The name of the topic to get.
* @returns The topic with the given name, or null if no topic with that name exists.
*/
PubSubClient.prototype.getPrefixTopicFromName = function (topicName) {
var _a;
return (_a = this.prefixTopics.get(topicName)) !== null && _a !== void 0 ? _a : null;
};
/**
* Gets the known announcement parameters for a topic.
* @param id - The ID of the topic.
* @returns The known announcement parameters for the topic, or undefined if the topic is not known.
*/
PubSubClient.prototype.getKnownTopicParams = function (id) {
return this.knownTopicParams.get(id);
};
/**
* Cleans up the client by unsubscribing from all topics and stopping publishing for all topics.
*/
PubSubClient.prototype.cleanup = function () {
this.topics.forEach(function (topic) {
topic.unsubscribeAll();
if (topic.publisher)
topic.unpublish();
});
this.prefixTopics.forEach(function (prefixTopic) {
prefixTopic.unsubscribeAll();
});
this._messenger.socket.close();
};
PubSubClient._instances = new Map();
return PubSubClient;
}());
exports.PubSubClient = PubSubClient;
//# sourceMappingURL=pubsub.js.map