@itwin/core-common
Version:
iTwin.js components common to frontend and backend
141 lines • 5.68 kB
JavaScript
;
/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
/** @packageDocumentation
* @module RpcInterface
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.RpcControlChannel = exports.RpcNotFoundResponse = exports.RpcPendingResponse = exports.RpcControlResponse = void 0;
const js_base64_1 = require("js-base64");
const RpcInterface_1 = require("../../RpcInterface");
const RpcManager_1 = require("../../RpcManager");
const RpcConfiguration_1 = require("./RpcConfiguration");
const RpcOperation_1 = require("./RpcOperation");
const RpcRegistry_1 = require("./RpcRegistry");
/** An RPC operation control response.
* @public
*/
class RpcControlResponse {
message = "RpcControlResponse";
}
exports.RpcControlResponse = RpcControlResponse;
/** A pending RPC operation response.
* @public
*/
class RpcPendingResponse extends RpcControlResponse {
/** Extended status regarding the pending operation. */
message;
/** Constructs a pending response. */
constructor(message = "") {
super();
this.message = message;
}
}
exports.RpcPendingResponse = RpcPendingResponse;
/** A RPC operation response.
* @public
*/
class RpcNotFoundResponse extends RpcControlResponse {
message = "Not found";
}
exports.RpcNotFoundResponse = RpcNotFoundResponse;
/** Manages requests and responses for an RPC configuration.
* @internal
*/
class RpcControlChannel {
/** @internal */
static channels = [];
static _obtainLock = 0;
_configuration;
_initialized = false;
_clientActive = false;
_describeEndpoints = undefined;
/** @internal */
static ensureInitialized() {
this.channels.forEach((channel) => channel.initialize());
}
constructor(configuration) {
this._configuration = configuration;
RpcControlChannel.channels.push(this);
}
/** @internal */
async describeEndpoints() {
this.activateClient();
if (!this._channelInterface.interfaceName) {
return [];
}
return this._describeEndpoints();
}
/** @internal */
static obtain(configuration) {
if (RpcControlChannel._obtainLock)
return undefined;
++RpcControlChannel._obtainLock;
const channel = new RpcControlChannel(configuration);
--RpcControlChannel._obtainLock;
return channel;
}
_channelInterface = class extends RpcInterface_1.RpcInterface {
static interfaceVersion = "CONTROL";
static interfaceName = "";
async describeEndpoints() { return this.forward(arguments); }
};
_channelImpl = class extends RpcInterface_1.RpcInterface {
async describeEndpoints() {
const endpoints = [];
this.configuration.interfaces().forEach((definition) => {
if (!RpcRegistry_1.RpcRegistry.instance.isRpcInterfaceInitialized(definition))
return;
const description = { interfaceName: definition.interfaceName, interfaceVersion: definition.interfaceVersion, operationNames: [], compatible: true };
RpcOperation_1.RpcOperation.forEach(definition, (operation) => description.operationNames.push(operation.operationName));
endpoints.push(description);
});
return endpoints;
}
};
computeId() {
const interfaces = [];
this._configuration.interfaces().forEach((definition) => interfaces.push(`${definition.interfaceName}@${definition.interfaceVersion}`));
const id = interfaces.sort().join(",");
return js_base64_1.Base64.encode(id);
}
activateClient() {
if (this._clientActive)
return;
this.initialize();
const token = { key: "none", iTwinId: "none", iModelId: "none", changeset: { id: "none" } };
RpcOperation_1.RpcOperation.forEach(this._channelInterface, (operation) => operation.policy.token = (_request) => RpcOperation_1.RpcOperation.fallbackToken ?? token);
const client = RpcManager_1.RpcManager.getClientForInterface(this._channelInterface);
this._describeEndpoints = async () => client.describeEndpoints();
this._clientActive = true;
}
/** @internal */
initialize() {
if (this._initialized) {
return;
}
const id = this.computeId();
Object.defineProperty(this._channelInterface, "interfaceName", { value: id });
Object.defineProperty(this._channelImpl, "interfaceName", { value: id });
RpcConfiguration_1.RpcConfiguration.assign(this._channelInterface, () => this._configuration.constructor);
RpcManager_1.RpcManager.registerImpl(this._channelInterface, this._channelImpl);
RpcManager_1.RpcManager.initializeInterface(this._channelInterface);
this._initialized = true;
}
/** @internal */
handleUnknownOperation(invocation, _error) {
this.initialize();
const op = invocation.request.operation;
if (op.interfaceVersion === "CONTROL" && op.operationName === "describeEndpoints") {
if (this._channelInterface.interfaceName) {
op.interfaceDefinition = this._channelInterface.interfaceName;
}
return true;
}
return false;
}
}
exports.RpcControlChannel = RpcControlChannel;
//# sourceMappingURL=RpcControl.js.map