@itwin/core-common
Version:
iTwin.js components common to frontend and backend
172 lines • 7.01 kB
JavaScript
import { RpcManager } from "../../RpcManager";
import { RpcControlChannel } from "./RpcControl";
import { RpcProtocol } from "./RpcProtocol";
import { INSTANCE } from "./RpcRegistry";
import { RpcRequest } from "./RpcRequest";
import { RpcRoutingToken } from "./RpcRoutingToken";
/** @internal */
export var RpcRoutingMap;
(function (RpcRoutingMap) {
function create() {
const configurations = new Map();
return Object.assign((routing) => configurations.get(routing.id)(), { configurations });
}
RpcRoutingMap.create = create;
})(RpcRoutingMap || (RpcRoutingMap = {}));
/** A RpcConfiguration specifies how calls on an RPC interface will be marshalled, plus other operating parameters.
* RpcConfiguration is the base class for specific configurations.
* @beta
*/
export class RpcConfiguration {
/** Whether development mode is enabled.
* @note This parameter determines whether developer convenience features like backend stack traces are available.
*/
static developmentMode = false;
/** Whether frontend checks that are relevant in a cloud-hosted routing scenario are disabled. */
static disableRoutingValidation = false;
/** Whether strict mode is enabled.
* This parameter determines system behaviors relating to strict checking:
* - Whether an error is thrown if the type marshaling system encounters an unregistered type (only in strict mode).
*/
static strictMode = false;
/**
* Whether to throw an error when the IModelRpcProps in the operation parameter list differs from the token in the URL.
* @note By default, a warning is logged and the operation is allowed to proceed.
* @note The parameter token is always replaced by the url token (unless RpcOperationPolicy.allowTokenMismatch is set).
*/
static throwOnTokenMismatch = false;
/** @internal Sets the configuration supplier for an RPC interface class. */
static assign(definition, supplier) {
const map = definition.prototype.configurationSupplier;
if (!map || typeof (map.configurations) === "undefined") {
definition.prototype.configurationSupplier = supplier;
}
else {
map.configurations.set(RpcRoutingToken.default.id, supplier);
}
}
/** Sets the configuration supplier for an RPC interface class for a given routing. */
static assignWithRouting(definition, routing, configuration) {
if (!definition.prototype.configurationSupplier) {
RpcConfiguration.assign(definition, RpcRoutingMap.create());
}
let map = definition.prototype.configurationSupplier;
if (typeof (map.configurations) === "undefined") {
const existing = map;
map = RpcRoutingMap.create();
RpcConfiguration.assign(definition, map);
map.configurations.set(RpcRoutingToken.default.id, existing);
}
const supplier = () => configuration;
map.configurations.set(routing.id, supplier);
}
/** Obtains the instance of an RPC configuration class. */
static obtain(configurationConstructor) {
let instance = configurationConstructor[INSTANCE];
if (!instance)
instance = configurationConstructor[INSTANCE] = new configurationConstructor();
return instance;
}
/** @internal Enables passing of application-specific context with each RPC request. */
static requestContext = {
getId: (_request) => "",
serialize: async (request) => ({
id: request.id,
applicationId: "",
applicationVersion: "",
sessionId: "",
authorization: "",
}),
};
/** @internal */
attached = [];
/** @internal */
allowAttachedInterfaces = true;
/** @internal */
get attachedInterfaces() { return this.attached; }
/** The target interval (in milliseconds) between connection attempts for pending RPC operation requests. */
pendingOperationRetryInterval = 10000;
/** The maximum number of transient faults permitted before request failure. */
transientFaultLimit = 4;
/** @internal */
routing = RpcRoutingToken.default;
/** The control channel for the configuration.
* @internal
*/
controlChannel = RpcControlChannel.obtain(this);
/** @internal */
attach(definition) {
if (!this.allowAttachedInterfaces) {
return;
}
if (this.interfaces().indexOf(definition) !== -1 || this.attached.indexOf(definition) !== -1) {
return;
}
this.attached.push(definition);
RpcConfiguration.assign(definition, () => this.constructor);
RpcManager.initializeInterface(definition);
}
/** Initializes the RPC interfaces managed by the configuration. */
static initializeInterfaces(configuration) {
configuration.interfaces().forEach((definition) => RpcManager.initializeInterface(definition));
}
/** @internal */
static supply(definition) {
return RpcConfiguration.obtain(definition.configurationSupplier ? definition.configurationSupplier(definition.routing) : RpcDefaultConfiguration);
}
/** @internal */
onRpcClientInitialized(definition, client) {
this.protocol.onRpcClientInitialized(definition, client);
}
/** @internal */
onRpcImplInitialized(definition, impl) {
this.protocol.onRpcImplInitialized(definition, impl);
}
/** @internal */
onRpcClientTerminated(definition, client) {
this.protocol.onRpcClientTerminated(definition, client);
}
/** @internal */
onRpcImplTerminated(definition, impl) {
this.protocol.onRpcImplTerminated(definition, impl);
}
}
/** A default configuration that can be used for basic testing within a library.
* @internal
*/
export class RpcDefaultConfiguration extends RpcConfiguration {
interfaces = () => [];
protocol = new RpcDirectProtocol(this);
}
/** A default protocol that can be used for basic testing within a library.
* @internal
*/
export class RpcDirectProtocol extends RpcProtocol {
requestType = RpcDirectRequest;
}
/** A default request type that can be used for basic testing within a library.
* @internal
*/
export class RpcDirectRequest extends RpcRequest {
headers = new Map();
fulfillment = undefined;
async send() {
const request = await this.protocol.serialize(this);
return new Promise(async (resolve, reject) => {
try {
this.fulfillment = await this.protocol.fulfill(request);
resolve(this.fulfillment.status);
}
catch (err) {
reject(err); // eslint-disable-line @typescript-eslint/prefer-promise-reject-errors
}
});
}
setHeader(name, value) {
this.headers.set(name, value);
}
async load() {
return this.fulfillment.result;
}
}
//# sourceMappingURL=RpcConfiguration.js.map