"use strict";
const proxify = require("./proxify");
const protocol = Symbol("protocol");
const route = Symbol("route");
/**
* Represents an API node at a remote server.
*/
class ClientApi {
/**
* @constructor
* @param {object} pProtocol The protocol object to be used for server communication.
* @param {any[]} pRoute The stack of routes that led to this ClientApi pointer.
*/
constructor(pProtocol, pRoute) {
this[protocol] = pProtocol;
this[route] = pRoute || [];
}
/**
* Routes the ClientApi via its protocol.
* @param {...any} destination The destination to route to. Multiple destinations are handled like a chained {@link ClientApi#route} call.
* @return {ClientApi} A new {@link ClientApi} for the object the routing function returned.
*/
route(destination) {
const destinations = arguments.length > 1 ? [...arguments] : [destination];
return new ClientApi(this[protocol], [...this[route], ...destinations]);
}
/**
* Closes the Api via its protocol.
* @param {any} [data=undefined] The data to close with.
* @return {Promise} A promise that resolves to the return value of the remote API.
*/
close(data) {
try {
return Promise.resolve(this[protocol].closer(this[route], data));
}
catch(err) {
return Promise.reject(err);
}
}
/**
* Shorthand for `this.close().then()`.
* @param {function} success The success function.
* @param {function} fail The fail function.
* @return {Promise} Result of `this.close()`.
*/
then(success, fail) {
return this.close().then(success, fail);
}
/**
* Shorthand for `this.close().catch()`.
* @param {function} fail The fail function.
* @return {Promise} Rejects if `this.close()` rejects.
*/
catch(fail) {
return this.close().catch(fail);
}
/**
* The connection state of the protocol this ClientApi uses.
* @type {boolean}
*/
get connected() {
return this[protocol].connected;
}
/**
* Observe connection changes of the protocol this ClientApi uses.
* @param {function} observer The observer to use.
* @return {undefined}
*/
observeConnection(observer) {
this[protocol].observe(observer);
}
/**
* Removed connection observer from the protocol this ClientApi uses.
* @param {function} observer The observer to be removed.
* @return {undefined}
*/
unobserveConnection(observer) {
this[protocol].unobserve(observer);
}
/**
* A proxy that returns `this.route(A).proxified` when property `A` is accessed and `this.close(B)` when called with parameter `B`.
* `then` and `catch` however are directly passed through.
* @type {Proxy}
*/
get proxified() {
return proxify(this);
}
}
ClientApi.prototype[proxify.passthrough] = new Set(["then", "catch"]);
module.exports = ClientApi;