@itwin/core-common
Version:
iTwin.js components common to frontend and backend
127 lines • 5.86 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
*/
import { BentleyStatus } from "@itwin/core-bentley";
import { IModelError } from "../../IModelError";
import { RpcResponseCacheControl } from "./RpcConstants";
import { OPERATION, POLICY, RpcRegistry } from "./RpcRegistry";
/** The policy for an RPC operation.
* @internal
*/
export class RpcOperationPolicy {
/** Supplies the IModelRpcProps for an operation request. */
token = (request) => request.findTokenPropsParameter();
/** Supplies the initial retry interval for an operation request. */
retryInterval = (configuration) => configuration.pendingOperationRetryInterval;
/** Called before every operation request on the frontend is sent. */
requestCallback = (_request) => { };
/** Called after every operation request on the frontend is sent. */
sentCallback = (_request) => { };
/**
* Determines if caching is permitted for an operation response.
* @note Not all RPC protocols support caching.
*/
allowResponseCaching = (_request) => RpcResponseCacheControl.None;
/** Forces RpcConfiguration.strictMode for this operation. */
forceStrictMode = false;
/** Whether the IModelRpcProps in the operation parameter list is allowed to differ from the token in the request URL. */
allowTokenMismatch = false;
/** Whether to compress the operation response with one of the client's supported encodings. */
allowResponseCompression = true;
}
/** An RPC operation descriptor.
* @internal
*/
export class RpcOperation {
/** A fallback token to use for RPC requests that do not semantically depend on an iModel. */
static fallbackToken = undefined;
/** Looks up an RPC operation by name. */
static lookup(target, operationName) {
const definition = typeof (target) === "string" ? RpcRegistry.instance.lookupInterfaceDefinition(target) : target;
const propertyName = RpcOperation.computeOperationName(operationName);
const proto = definition.prototype;
if (!proto.hasOwnProperty(propertyName))
throw new IModelError(BentleyStatus.ERROR, `RPC interface class "${definition.interfaceName}" does not does not declare operation "${operationName}"`);
return proto[propertyName][OPERATION];
}
/** Iterates the operations of an RPC interface definition. */
static forEach(definition, callback) {
Object.getOwnPropertyNames(definition.prototype).forEach((operationName) => {
if (operationName === "constructor" || operationName === "configurationSupplier")
return;
const propertyName = RpcOperation.computeOperationName(operationName);
callback(definition.prototype[propertyName][OPERATION]);
});
}
/** The RPC interface definition for this operation. */
interfaceDefinition;
/** The name of this operation. */
operationName;
/** The version of this operation. */
get interfaceVersion() { return this.interfaceDefinition.interfaceVersion; }
/** The policy for this operation. */
policy;
/** @internal */
constructor(definition, operation, policy) {
this.interfaceDefinition = definition;
this.operationName = operation;
this.policy = policy;
}
/** @internal */
static computeOperationName(identifier) {
const c = identifier.indexOf(":");
if (c === -1)
return identifier;
return identifier.substring(0, c + 1);
}
}
/** @internal */
(function (RpcOperation) {
function obtainInstance(obj) {
if (obj instanceof RpcOperationPolicy) {
return obj;
}
else {
const instance = new RpcOperationPolicy();
Object.assign(instance, obj);
return instance;
}
}
/** Decorator for setting the policy for an RPC operation function. */
function setPolicy(policy) {
return (target, propertyKey, descriptor) => {
descriptor.value[OPERATION] = new RpcOperation(target.constructor, propertyKey, obtainInstance(policy));
};
}
RpcOperation.setPolicy = setPolicy;
/** Convenience decorator for setting an RPC operation policy that allows response caching. */
function allowResponseCaching(control = RpcResponseCacheControl.Immutable) {
return (target, propertyKey, descriptor) => {
descriptor.value[OPERATION] = new RpcOperation(target.constructor, propertyKey, new class extends RpcOperationPolicy {
allowResponseCaching = () => control;
}());
};
}
RpcOperation.allowResponseCaching = allowResponseCaching;
/** Convenience decorator for setting an RPC operation policy that supplies the IModelRpcProps for an operation. */
function setRoutingProps(handler) {
return (target, propertyKey, descriptor) => {
descriptor.value[OPERATION] = new RpcOperation(target.constructor, propertyKey, new class extends RpcOperationPolicy {
token = handler;
}());
};
}
RpcOperation.setRoutingProps = setRoutingProps;
/** Decorator for setting the default policy for an RPC interface definition class. */
function setDefaultPolicy(policy) {
return (definition) => {
definition[POLICY] = obtainInstance(policy);
};
}
RpcOperation.setDefaultPolicy = setDefaultPolicy;
})(RpcOperation || (RpcOperation = {}));
//# sourceMappingURL=RpcOperation.js.map