@itwin/presentation-backend 3.0.0-dev.166 → 3.0.0-dev.170

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -60,10 +60,10 @@ export declare type PresentationProps = MultiManagerPresentationProps | SingleMa
60
60
  export declare class Presentation {
61
61
  private static _initProps;
62
62
  private static _clientsStorage;
63
- private static _requestTimeout;
64
63
  private static _disposeIpcHandler;
65
64
  private static _shutdownListener;
66
65
  private static _manager;
66
+ private static _rpcImpl;
67
67
  private constructor();
68
68
  /** Properties used to initialize the presentation framework */
69
69
  static get initProps(): PresentationProps | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"Presentation.d.ts","sourceRoot":"","sources":["../../../src/presentation-backend/Presentation.ts"],"names":[],"mappings":"AAIA;;GAEG;AAQH,OAAO,EAAE,mBAAmB,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AAMtF;;;;;GAKG;AACH,MAAM,WAAW,6BAA8B,SAAQ,wBAAwB;IAC7E;;;OAGG;IACH,oBAAoB,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,wBAAwB,KAAK,mBAAmB,CAAC;IAElG;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;;OAGG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED;;;;;GAKG;AACH,MAAM,WAAW,8BAA+B,SAAQ,wBAAwB;IAC9E;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED;;;GAGG;AACH,oBAAY,iBAAiB,GAAG,6BAA6B,GAAG,8BAA8B,CAAC;AAM/F;;;;;;;;;GASG;AACH,qBAAa,YAAY;IAEvB,OAAO,CAAC,MAAM,CAAC,UAAU,CAAgC;IACzD,OAAO,CAAC,MAAM,CAAC,eAAe,CAAgD;IAC9E,OAAO,CAAC,MAAM,CAAC,eAAe,CAAqB;IACnD,OAAO,CAAC,MAAM,CAAC,kBAAkB,CAA0B;IAC3D,OAAO,CAAC,MAAM,CAAC,iBAAiB,CAA0B;IAC1D,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAkC;IAGzD,OAAO;IAEP,+DAA+D;IAC/D,WAAkB,SAAS,kCAA8B;IAEzD;;;;;;;;OAQG;WACW,UAAU,CAAC,KAAK,CAAC,EAAE,iBAAiB,GAAG,IAAI;IAgCzD;;;OAGG;WACW,SAAS,IAAI,IAAI;IAsB/B,OAAO,CAAC,MAAM,CAAC,mBAAmB;IASlC,OAAO,CAAC,MAAM,CAAC,oBAAoB;IAInC;;;;OAIG;WACW,UAAU,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,mBAAmB;IAShE;;OAEG;WACW,iBAAiB,IAAI,MAAM;CAK1C"}
1
+ {"version":3,"file":"Presentation.d.ts","sourceRoot":"","sources":["../../../src/presentation-backend/Presentation.ts"],"names":[],"mappings":"AAIA;;GAEG;AAQH,OAAO,EAAE,mBAAmB,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AAMtF;;;;;GAKG;AACH,MAAM,WAAW,6BAA8B,SAAQ,wBAAwB;IAC7E;;;OAGG;IACH,oBAAoB,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,wBAAwB,KAAK,mBAAmB,CAAC;IAElG;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;;OAGG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED;;;;;GAKG;AACH,MAAM,WAAW,8BAA+B,SAAQ,wBAAwB;IAC9E;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED;;;GAGG;AACH,oBAAY,iBAAiB,GAAG,6BAA6B,GAAG,8BAA8B,CAAC;AAM/F;;;;;;;;;GASG;AACH,qBAAa,YAAY;IAEvB,OAAO,CAAC,MAAM,CAAC,UAAU,CAAgC;IACzD,OAAO,CAAC,MAAM,CAAC,eAAe,CAA4D;IAC1F,OAAO,CAAC,MAAM,CAAC,kBAAkB,CAA0B;IAC3D,OAAO,CAAC,MAAM,CAAC,iBAAiB,CAA0B;IAC1D,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAkC;IACzD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAkC;IAGzD,OAAO;IAEP,+DAA+D;IAC/D,WAAkB,SAAS,kCAA8B;IAEzD;;;;;;;;OAQG;WACW,UAAU,CAAC,KAAK,CAAC,EAAE,iBAAiB,GAAG,IAAI;IA+BzD;;;OAGG;WACW,SAAS,IAAI,IAAI;IAwB/B,OAAO,CAAC,MAAM,CAAC,mBAAmB;IASlC,OAAO,CAAC,MAAM,CAAC,oBAAoB;IAInC;;;;OAIG;WACW,UAAU,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,mBAAmB;IAShE;;OAEG;WACW,iBAAiB,IAAI,MAAM;CAK1C"}
@@ -43,34 +43,30 @@ class Presentation {
43
43
  * @param props Optional properties for [[PresentationManager]]
44
44
  */
45
45
  static initialize(props) {
46
- var _a;
46
+ var _a, _b;
47
+ this._initProps = props || {};
48
+ this._shutdownListener = core_backend_1.IModelHost.onBeforeShutdown.addListener(() => Presentation.terminate());
49
+ this._rpcImpl = new PresentationRpcImpl_1.PresentationRpcImpl({
50
+ requestTimeout: (_a = this._initProps.requestTimeout) !== null && _a !== void 0 ? _a : defaultRequestTimeout,
51
+ });
47
52
  core_common_1.RpcManager.registerImpl(presentation_common_1.PresentationRpcInterface, PresentationRpcImpl_1.PresentationRpcImpl);
53
+ core_common_1.RpcManager.supplyImplInstance(presentation_common_1.PresentationRpcInterface, this._rpcImpl);
48
54
  if (core_backend_1.IpcHost.isValid) {
49
55
  this._disposeIpcHandler = PresentationIpcHandler_1.PresentationIpcHandler.register();
50
56
  }
51
- this._initProps = props || {};
52
- this._shutdownListener = core_backend_1.IModelHost.onBeforeShutdown.addListener(() => Presentation.terminate());
53
- this._requestTimeout = (props && props.requestTimeout !== undefined)
54
- ? props.requestTimeout
55
- : defaultRequestTimeout;
56
57
  if (isSingleManagerProps(this._initProps)) {
57
58
  this._manager = new PresentationManager_1.PresentationManager(Presentation._initProps);
58
59
  }
59
60
  else {
60
- this._clientsStorage = new TemporaryStorage_1.TemporaryStorage({
61
- factory: this.createClientManager,
61
+ this._clientsStorage = new TemporaryStorage_1.FactoryBasedTemporaryStorage({
62
+ factory: this.createClientManager.bind(this),
62
63
  cleanupHandler: this.disposeClientManager,
63
64
  // cleanup unused managers every minute
64
65
  cleanupInterval: 60 * 1000,
65
66
  // by default, manager is disposed after 1 hour of being unused
66
- valueLifetime: (_a = this._initProps.unusedClientLifetime) !== null && _a !== void 0 ? _a : 60 * 60 * 1000,
67
+ unusedValueLifetime: (_b = this._initProps.unusedClientLifetime) !== null && _b !== void 0 ? _b : 60 * 60 * 1000,
67
68
  // add some logging
68
- onCreated: /* istanbul ignore next */ (id, value, onValueUsed) => {
69
- var _a;
70
- core_bentley_1.Logger.logInfo(BackendLoggerCategory_1.PresentationBackendLoggerCategory.PresentationManager, `Created a PresentationManager instance with ID: ${id}. Total instances: ${(_a = this._clientsStorage) === null || _a === void 0 ? void 0 : _a.values.length}.`);
71
- value.manager.setOnManagerUsedHandler(onValueUsed);
72
- },
73
- onDisposedSingle: /* istanbul ignore next */ (id) => { var _a; return core_bentley_1.Logger.logInfo(BackendLoggerCategory_1.PresentationBackendLoggerCategory.PresentationManager, `Disposed PresentationManager instance with ID: ${id}. Total instances: ${(_a = this._clientsStorage) === null || _a === void 0 ? void 0 : _a.values.length}.`); },
69
+ onDisposedSingle: /* istanbul ignore next */ (id) => core_bentley_1.Logger.logInfo(BackendLoggerCategory_1.PresentationBackendLoggerCategory.PresentationManager, `Disposed PresentationManager instance with ID: ${id}. Total instances: ${this._clientsStorage.values.length}.`),
74
70
  onDisposedAll: /* istanbul ignore next */ () => core_bentley_1.Logger.logInfo(BackendLoggerCategory_1.PresentationBackendLoggerCategory.PresentationManager, `Disposed all PresentationManager instances.`),
75
71
  });
76
72
  }
@@ -93,22 +89,24 @@ class Presentation {
93
89
  this._manager = undefined;
94
90
  }
95
91
  core_common_1.RpcManager.unregisterImpl(presentation_common_1.PresentationRpcInterface);
92
+ if (this._rpcImpl) {
93
+ this._rpcImpl.dispose();
94
+ this._rpcImpl = undefined;
95
+ }
96
96
  if (this._disposeIpcHandler) {
97
97
  this._disposeIpcHandler();
98
98
  }
99
99
  this._initProps = undefined;
100
- if (this._requestTimeout)
101
- this._requestTimeout = undefined;
102
100
  }
103
- static createClientManager(clientId) {
104
- let manager;
105
- if (Presentation._initProps && !isSingleManagerProps(Presentation._initProps) && Presentation._initProps.clientManagerFactory)
106
- manager = Presentation._initProps.clientManagerFactory(clientId, Presentation._initProps);
107
- else
108
- manager = new PresentationManager_1.PresentationManager(Presentation._initProps);
101
+ static createClientManager(clientId, onManagerUsed) {
102
+ const manager = (Presentation._initProps && !isSingleManagerProps(Presentation._initProps) && Presentation._initProps.clientManagerFactory)
103
+ ? Presentation._initProps.clientManagerFactory(clientId, Presentation._initProps)
104
+ : new PresentationManager_1.PresentationManager(Presentation._initProps);
105
+ manager.setOnManagerUsedHandler(onManagerUsed);
106
+ core_bentley_1.Logger.logInfo(BackendLoggerCategory_1.PresentationBackendLoggerCategory.PresentationManager, `Created a PresentationManager instance with ID: ${clientId}. Total instances: ${this._clientsStorage.values.length}.`);
109
107
  return { manager };
110
108
  }
111
- static disposeClientManager(storeItem) {
109
+ static disposeClientManager(_id, storeItem) {
112
110
  storeItem.manager.dispose();
113
111
  }
114
112
  /**
@@ -127,9 +125,9 @@ class Presentation {
127
125
  * Get the time in milliseconds that backend should respond in .
128
126
  */
129
127
  static getRequestTimeout() {
130
- if (this._requestTimeout === undefined)
128
+ if (this._rpcImpl === undefined)
131
129
  throw new presentation_common_1.PresentationError(presentation_common_1.PresentationStatus.NotInitialized, "Presentation must be first initialized by calling Presentation.initialize");
132
- return this._requestTimeout;
130
+ return this._rpcImpl.requestTimeout;
133
131
  }
134
132
  }
135
133
  exports.Presentation = Presentation;
@@ -1 +1 @@
1
- {"version":3,"file":"Presentation.js","sourceRoot":"","sources":["../../../src/presentation-backend/Presentation.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n/** @packageDocumentation\r\n * @module Core\r\n */\r\n\r\nimport { IModelHost, IpcHost } from \"@itwin/core-backend\";\r\nimport { DisposeFunc, Logger } from \"@itwin/core-bentley\";\r\nimport { RpcManager } from \"@itwin/core-common\";\r\nimport { PresentationError, PresentationRpcInterface, PresentationStatus } from \"@itwin/presentation-common\";\r\nimport { PresentationBackendLoggerCategory } from \"./BackendLoggerCategory\";\r\nimport { PresentationIpcHandler } from \"./PresentationIpcHandler\";\r\nimport { PresentationManager, PresentationManagerProps } from \"./PresentationManager\";\r\nimport { PresentationRpcImpl } from \"./PresentationRpcImpl\";\r\nimport { TemporaryStorage } from \"./TemporaryStorage\";\r\n\r\nconst defaultRequestTimeout: number = 90000;\r\n\r\n/**\r\n * Props for initializing the [[Presentation]] library for using multiple [[PresentationManager]]\r\n * instances, one for each frontend.\r\n *\r\n * @public\r\n */\r\nexport interface MultiManagerPresentationProps extends PresentationManagerProps {\r\n /**\r\n * Factory method for creating separate managers for each client\r\n * @internal\r\n */\r\n clientManagerFactory?: (clientId: string, props: PresentationManagerProps) => PresentationManager;\r\n\r\n /**\r\n * Time in milliseconds after which the request will timeout.\r\n */\r\n requestTimeout?: number;\r\n\r\n /**\r\n * How much time should an unused client manager be stored in memory\r\n * before it's disposed.\r\n */\r\n unusedClientLifetime?: number;\r\n}\r\n\r\n/**\r\n * Props for initializing the [[Presentation]] library with ability to use a single\r\n * [[PresentationManager]] instance for handling all requests.\r\n *\r\n * @public\r\n */\r\nexport interface SingleManagerPresentationProps extends PresentationManagerProps {\r\n /**\r\n * How much time should an unused client manager be stored in memory\r\n * before it's disposed.\r\n */\r\n requestTimeout?: number;\r\n\r\n /**\r\n * Specifies to use single manager for all clients.\r\n * @alpha\r\n */\r\n useSingleManager?: boolean;\r\n}\r\n\r\n/**\r\n * Properties that can be used to configure [[Presentation]] API\r\n * @public\r\n */\r\nexport type PresentationProps = MultiManagerPresentationProps | SingleManagerPresentationProps;\r\n\r\ninterface ClientStoreItem {\r\n manager: PresentationManager;\r\n}\r\n\r\n/**\r\n * Static class used to statically set up Presentation library for the backend.\r\n * Basically what it does is:\r\n * - Register a RPC implementation\r\n * - Create a singleton [[PresentationManager]] instance\r\n * - Subscribe for [IModelHost.onBeforeShutdown]($core-backend) event and terminate\r\n * the presentation manager when that happens.\r\n *\r\n * @public\r\n */\r\nexport class Presentation {\r\n\r\n private static _initProps: PresentationProps | undefined;\r\n private static _clientsStorage: TemporaryStorage<ClientStoreItem> | undefined;\r\n private static _requestTimeout: number | undefined;\r\n private static _disposeIpcHandler: DisposeFunc | undefined;\r\n private static _shutdownListener: DisposeFunc | undefined;\r\n private static _manager: PresentationManager | undefined;\r\n\r\n /* istanbul ignore next */\r\n private constructor() { }\r\n\r\n /** Properties used to initialize the presentation framework */\r\n public static get initProps() { return this._initProps; }\r\n\r\n /**\r\n * Initializes Presentation library for the backend.\r\n *\r\n * See [this]($docs/presentation/Setup/index.md#backend) for an example.\r\n *\r\n * **Important:** The method should be called after a call to [IModelHost.startup]($core-backend)\r\n *\r\n * @param props Optional properties for [[PresentationManager]]\r\n */\r\n public static initialize(props?: PresentationProps): void {\r\n RpcManager.registerImpl(PresentationRpcInterface, PresentationRpcImpl);\r\n if (IpcHost.isValid) {\r\n this._disposeIpcHandler = PresentationIpcHandler.register();\r\n }\r\n this._initProps = props || {};\r\n this._shutdownListener = IModelHost.onBeforeShutdown.addListener(() => Presentation.terminate());\r\n this._requestTimeout = (props && props.requestTimeout !== undefined)\r\n ? props.requestTimeout\r\n : defaultRequestTimeout;\r\n\r\n if (isSingleManagerProps(this._initProps)) {\r\n this._manager = new PresentationManager(Presentation._initProps);\r\n } else {\r\n this._clientsStorage = new TemporaryStorage<ClientStoreItem>({\r\n factory: this.createClientManager,\r\n cleanupHandler: this.disposeClientManager,\r\n // cleanup unused managers every minute\r\n cleanupInterval: 60 * 1000,\r\n // by default, manager is disposed after 1 hour of being unused\r\n valueLifetime: this._initProps.unusedClientLifetime ?? 60 * 60 * 1000,\r\n // add some logging\r\n onCreated: /* istanbul ignore next */(id: string, value: ClientStoreItem, onValueUsed: () => void) => {\r\n Logger.logInfo(PresentationBackendLoggerCategory.PresentationManager, `Created a PresentationManager instance with ID: ${id}. Total instances: ${this._clientsStorage?.values.length}.`);\r\n value.manager.setOnManagerUsedHandler(onValueUsed);\r\n },\r\n onDisposedSingle: /* istanbul ignore next */(id: string) => Logger.logInfo(PresentationBackendLoggerCategory.PresentationManager, `Disposed PresentationManager instance with ID: ${id}. Total instances: ${this._clientsStorage?.values.length}.`),\r\n onDisposedAll: /* istanbul ignore next */() => Logger.logInfo(PresentationBackendLoggerCategory.PresentationManager, `Disposed all PresentationManager instances.`),\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Terminates Presentation. Consumers don't need to call this as it's automatically\r\n * called on [IModelHost.onBeforeShutdown]($core-backend) event.\r\n */\r\n public static terminate(): void {\r\n if (this._clientsStorage) {\r\n this._clientsStorage.dispose();\r\n this._clientsStorage = undefined;\r\n }\r\n if (this._shutdownListener) {\r\n this._shutdownListener();\r\n this._shutdownListener = undefined;\r\n }\r\n if (this._manager) {\r\n this._manager.dispose();\r\n this._manager = undefined;\r\n }\r\n RpcManager.unregisterImpl(PresentationRpcInterface);\r\n if (this._disposeIpcHandler) {\r\n this._disposeIpcHandler();\r\n }\r\n this._initProps = undefined;\r\n if (this._requestTimeout)\r\n this._requestTimeout = undefined;\r\n }\r\n\r\n private static createClientManager(clientId: string): ClientStoreItem {\r\n let manager: PresentationManager;\r\n if (Presentation._initProps && !isSingleManagerProps(Presentation._initProps) && Presentation._initProps.clientManagerFactory)\r\n manager = Presentation._initProps.clientManagerFactory(clientId, Presentation._initProps);\r\n else\r\n manager = new PresentationManager(Presentation._initProps);\r\n return { manager };\r\n }\r\n\r\n private static disposeClientManager(storeItem: ClientStoreItem) {\r\n storeItem.manager.dispose();\r\n }\r\n\r\n /**\r\n * Get an instance of [[PresentationManager]] for specific client\r\n * @param clientId ID of the client requesting presentation data. If no\r\n * ID is provided, the default [[PresentationManager]] is returned.\r\n */\r\n public static getManager(clientId?: string): PresentationManager {\r\n if (this._initProps && isSingleManagerProps(this._initProps) && this._manager)\r\n return this._manager;\r\n if (this._clientsStorage)\r\n return this._clientsStorage.getValue(clientId || \"\").manager;\r\n\r\n throw new PresentationError(PresentationStatus.NotInitialized, \"Presentation must be first initialized by calling Presentation.initialize\");\r\n }\r\n\r\n /**\r\n * Get the time in milliseconds that backend should respond in .\r\n */\r\n public static getRequestTimeout(): number {\r\n if (this._requestTimeout === undefined)\r\n throw new PresentationError(PresentationStatus.NotInitialized, \"Presentation must be first initialized by calling Presentation.initialize\");\r\n return this._requestTimeout;\r\n }\r\n}\r\n\r\nfunction isSingleManagerProps(props: PresentationProps): props is SingleManagerPresentationProps {\r\n return !!(props as SingleManagerPresentationProps).useSingleManager;\r\n}\r\n"]}
1
+ {"version":3,"file":"Presentation.js","sourceRoot":"","sources":["../../../src/presentation-backend/Presentation.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n/** @packageDocumentation\r\n * @module Core\r\n */\r\n\r\nimport { IModelHost, IpcHost } from \"@itwin/core-backend\";\r\nimport { DisposeFunc, Logger } from \"@itwin/core-bentley\";\r\nimport { RpcManager } from \"@itwin/core-common\";\r\nimport { PresentationError, PresentationRpcInterface, PresentationStatus } from \"@itwin/presentation-common\";\r\nimport { PresentationBackendLoggerCategory } from \"./BackendLoggerCategory\";\r\nimport { PresentationIpcHandler } from \"./PresentationIpcHandler\";\r\nimport { PresentationManager, PresentationManagerProps } from \"./PresentationManager\";\r\nimport { PresentationRpcImpl } from \"./PresentationRpcImpl\";\r\nimport { FactoryBasedTemporaryStorage } from \"./TemporaryStorage\";\r\n\r\nconst defaultRequestTimeout: number = 90000;\r\n\r\n/**\r\n * Props for initializing the [[Presentation]] library for using multiple [[PresentationManager]]\r\n * instances, one for each frontend.\r\n *\r\n * @public\r\n */\r\nexport interface MultiManagerPresentationProps extends PresentationManagerProps {\r\n /**\r\n * Factory method for creating separate managers for each client\r\n * @internal\r\n */\r\n clientManagerFactory?: (clientId: string, props: PresentationManagerProps) => PresentationManager;\r\n\r\n /**\r\n * Time in milliseconds after which the request will timeout.\r\n */\r\n requestTimeout?: number;\r\n\r\n /**\r\n * How much time should an unused client manager be stored in memory\r\n * before it's disposed.\r\n */\r\n unusedClientLifetime?: number;\r\n}\r\n\r\n/**\r\n * Props for initializing the [[Presentation]] library with ability to use a single\r\n * [[PresentationManager]] instance for handling all requests.\r\n *\r\n * @public\r\n */\r\nexport interface SingleManagerPresentationProps extends PresentationManagerProps {\r\n /**\r\n * How much time should an unused client manager be stored in memory\r\n * before it's disposed.\r\n */\r\n requestTimeout?: number;\r\n\r\n /**\r\n * Specifies to use single manager for all clients.\r\n * @alpha\r\n */\r\n useSingleManager?: boolean;\r\n}\r\n\r\n/**\r\n * Properties that can be used to configure [[Presentation]] API\r\n * @public\r\n */\r\nexport type PresentationProps = MultiManagerPresentationProps | SingleManagerPresentationProps;\r\n\r\ninterface ClientStoreItem {\r\n manager: PresentationManager;\r\n}\r\n\r\n/**\r\n * Static class used to statically set up Presentation library for the backend.\r\n * Basically what it does is:\r\n * - Register a RPC implementation\r\n * - Create a singleton [[PresentationManager]] instance\r\n * - Subscribe for [IModelHost.onBeforeShutdown]($core-backend) event and terminate\r\n * the presentation manager when that happens.\r\n *\r\n * @public\r\n */\r\nexport class Presentation {\r\n\r\n private static _initProps: PresentationProps | undefined;\r\n private static _clientsStorage: FactoryBasedTemporaryStorage<ClientStoreItem> | undefined;\r\n private static _disposeIpcHandler: DisposeFunc | undefined;\r\n private static _shutdownListener: DisposeFunc | undefined;\r\n private static _manager: PresentationManager | undefined;\r\n private static _rpcImpl: PresentationRpcImpl | undefined;\r\n\r\n /* istanbul ignore next */\r\n private constructor() { }\r\n\r\n /** Properties used to initialize the presentation framework */\r\n public static get initProps() { return this._initProps; }\r\n\r\n /**\r\n * Initializes Presentation library for the backend.\r\n *\r\n * See [this]($docs/presentation/Setup/index.md#backend) for an example.\r\n *\r\n * **Important:** The method should be called after a call to [IModelHost.startup]($core-backend)\r\n *\r\n * @param props Optional properties for [[PresentationManager]]\r\n */\r\n public static initialize(props?: PresentationProps): void {\r\n this._initProps = props || {};\r\n this._shutdownListener = IModelHost.onBeforeShutdown.addListener(() => Presentation.terminate());\r\n\r\n this._rpcImpl = new PresentationRpcImpl({\r\n requestTimeout: this._initProps.requestTimeout ?? defaultRequestTimeout,\r\n });\r\n RpcManager.registerImpl(PresentationRpcInterface, PresentationRpcImpl);\r\n RpcManager.supplyImplInstance(PresentationRpcInterface, this._rpcImpl);\r\n\r\n if (IpcHost.isValid) {\r\n this._disposeIpcHandler = PresentationIpcHandler.register();\r\n }\r\n\r\n if (isSingleManagerProps(this._initProps)) {\r\n this._manager = new PresentationManager(Presentation._initProps);\r\n } else {\r\n this._clientsStorage = new FactoryBasedTemporaryStorage<ClientStoreItem>({\r\n factory: this.createClientManager.bind(this),\r\n cleanupHandler: this.disposeClientManager,\r\n // cleanup unused managers every minute\r\n cleanupInterval: 60 * 1000,\r\n // by default, manager is disposed after 1 hour of being unused\r\n unusedValueLifetime: this._initProps.unusedClientLifetime ?? 60 * 60 * 1000,\r\n // add some logging\r\n onDisposedSingle: /* istanbul ignore next */(id: string) => Logger.logInfo(PresentationBackendLoggerCategory.PresentationManager, `Disposed PresentationManager instance with ID: ${id}. Total instances: ${this._clientsStorage!.values.length}.`),\r\n onDisposedAll: /* istanbul ignore next */() => Logger.logInfo(PresentationBackendLoggerCategory.PresentationManager, `Disposed all PresentationManager instances.`),\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Terminates Presentation. Consumers don't need to call this as it's automatically\r\n * called on [IModelHost.onBeforeShutdown]($core-backend) event.\r\n */\r\n public static terminate(): void {\r\n if (this._clientsStorage) {\r\n this._clientsStorage.dispose();\r\n this._clientsStorage = undefined;\r\n }\r\n if (this._shutdownListener) {\r\n this._shutdownListener();\r\n this._shutdownListener = undefined;\r\n }\r\n if (this._manager) {\r\n this._manager.dispose();\r\n this._manager = undefined;\r\n }\r\n RpcManager.unregisterImpl(PresentationRpcInterface);\r\n if (this._rpcImpl) {\r\n this._rpcImpl.dispose();\r\n this._rpcImpl = undefined;\r\n }\r\n if (this._disposeIpcHandler) {\r\n this._disposeIpcHandler();\r\n }\r\n this._initProps = undefined;\r\n }\r\n\r\n private static createClientManager(clientId: string, onManagerUsed: () => void): ClientStoreItem {\r\n const manager = (Presentation._initProps && !isSingleManagerProps(Presentation._initProps) && Presentation._initProps.clientManagerFactory)\r\n ? Presentation._initProps.clientManagerFactory(clientId, Presentation._initProps)\r\n : new PresentationManager(Presentation._initProps);\r\n manager.setOnManagerUsedHandler(onManagerUsed);\r\n Logger.logInfo(PresentationBackendLoggerCategory.PresentationManager, `Created a PresentationManager instance with ID: ${clientId}. Total instances: ${this._clientsStorage!.values.length}.`);\r\n return { manager };\r\n }\r\n\r\n private static disposeClientManager(_id: string, storeItem: ClientStoreItem) {\r\n storeItem.manager.dispose();\r\n }\r\n\r\n /**\r\n * Get an instance of [[PresentationManager]] for specific client\r\n * @param clientId ID of the client requesting presentation data. If no\r\n * ID is provided, the default [[PresentationManager]] is returned.\r\n */\r\n public static getManager(clientId?: string): PresentationManager {\r\n if (this._initProps && isSingleManagerProps(this._initProps) && this._manager)\r\n return this._manager;\r\n if (this._clientsStorage)\r\n return this._clientsStorage.getValue(clientId || \"\").manager;\r\n\r\n throw new PresentationError(PresentationStatus.NotInitialized, \"Presentation must be first initialized by calling Presentation.initialize\");\r\n }\r\n\r\n /**\r\n * Get the time in milliseconds that backend should respond in .\r\n */\r\n public static getRequestTimeout(): number {\r\n if (this._rpcImpl === undefined)\r\n throw new PresentationError(PresentationStatus.NotInitialized, \"Presentation must be first initialized by calling Presentation.initialize\");\r\n return this._rpcImpl.requestTimeout;\r\n }\r\n}\r\n\r\nfunction isSingleManagerProps(props: PresentationProps): props is SingleManagerPresentationProps {\r\n return !!(props as SingleManagerPresentationProps).useSingleManager;\r\n}\r\n"]}
@@ -1,7 +1,7 @@
1
1
  /** @packageDocumentation
2
2
  * @module RPC
3
3
  */
4
- import { Id64String } from "@itwin/core-bentley";
4
+ import { Id64String, IDisposable } from "@itwin/core-bentley";
5
5
  import { IModelRpcProps } from "@itwin/core-common";
6
6
  import { ContentDescriptorRpcRequestOptions, ContentInstanceKeysRpcRequestOptions, ContentRpcRequestOptions, ContentSourcesRpcRequestOptions, ContentSourcesRpcResult, DescriptorJSON, DisplayLabelRpcRequestOptions, DisplayLabelsRpcRequestOptions, DisplayValueGroupJSON, DistinctValuesRpcRequestOptions, ElementProperties, FilterByInstancePathsHierarchyRpcRequestOptions, FilterByTextHierarchyRpcRequestOptions, HierarchyRpcRequestOptions, ItemJSON, KeySetJSON, LabelDefinitionJSON, NodeJSON, NodePathElementJSON, Paged, PagedResponse, PresentationRpcInterface, PresentationRpcResponse, SelectionScope, SelectionScopeRpcRequestOptions, SingleElementPropertiesRpcRequestOptions } from "@itwin/presentation-common";
7
7
  import { PresentationManager } from "./PresentationManager";
@@ -21,11 +21,13 @@ export declare const MAX_ALLOWED_KEYS_PAGE_SIZE = 10000;
21
21
  *
22
22
  * @internal
23
23
  */
24
- export declare class PresentationRpcImpl extends PresentationRpcInterface {
25
- constructor(_id?: string);
26
- /**
27
- * Get the maximum result waiting time.
28
- */
24
+ export declare class PresentationRpcImpl extends PresentationRpcInterface implements IDisposable {
25
+ private _requestTimeout;
26
+ private _pendingRequests;
27
+ constructor(props?: {
28
+ requestTimeout: number;
29
+ });
30
+ dispose(): void;
29
31
  get requestTimeout(): number;
30
32
  /** Returns an ok response with result inside */
31
33
  private successResponse;
@@ -1 +1 @@
1
- {"version":3,"file":"PresentationRpcImpl.d.ts","sourceRoot":"","sources":["../../../src/presentation-backend/PresentationRpcImpl.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"PresentationRpcImpl.d.ts","sourceRoot":"","sources":["../../../src/presentation-backend/PresentationRpcImpl.ts"],"names":[],"mappings":"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"}
@@ -13,6 +13,7 @@ const core_bentley_1 = require("@itwin/core-bentley");
13
13
  const presentation_common_1 = require("@itwin/presentation-common");
14
14
  const BackendLoggerCategory_1 = require("./BackendLoggerCategory");
15
15
  const Presentation_1 = require("./Presentation");
16
+ const TemporaryStorage_1 = require("./TemporaryStorage");
16
17
  /** @internal */
17
18
  exports.MAX_ALLOWED_PAGE_SIZE = 1000;
18
19
  /** @internal */
@@ -30,13 +31,25 @@ exports.MAX_ALLOWED_KEYS_PAGE_SIZE = 10000;
30
31
  * @internal
31
32
  */
32
33
  class PresentationRpcImpl extends presentation_common_1.PresentationRpcInterface {
33
- constructor(_id) {
34
+ constructor(props) {
35
+ var _a;
34
36
  super();
37
+ this._requestTimeout = (_a = props === null || props === void 0 ? void 0 : props.requestTimeout) !== null && _a !== void 0 ? _a : 90 * 1000;
38
+ this._pendingRequests = new TemporaryStorage_1.TemporaryStorage({
39
+ // remove the pending request after request timeout + 10 seconds - this gives
40
+ // frontend 10 seconds to re-send the request until it's removed from requests' cache
41
+ unusedValueLifetime: this._requestTimeout + 10 * 1000,
42
+ // attempt to clean up every second
43
+ cleanupInterval: 1000,
44
+ cleanupHandler: (id) => {
45
+ core_bentley_1.Logger.logTrace(BackendLoggerCategory_1.PresentationBackendLoggerCategory.Rpc, `Cleaning up request without frontend retrieving it: ${id}.`);
46
+ },
47
+ });
35
48
  }
36
- /**
37
- * Get the maximum result waiting time.
38
- */
39
- get requestTimeout() { return Presentation_1.Presentation.getRequestTimeout(); }
49
+ dispose() {
50
+ this._pendingRequests.dispose();
51
+ }
52
+ get requestTimeout() { return this._requestTimeout; }
40
53
  /** Returns an ok response with result inside */
41
54
  successResponse(result, diagnostics) {
42
55
  return {
@@ -71,50 +84,79 @@ class PresentationRpcImpl extends presentation_common_1.PresentationRpcInterface
71
84
  return imodel;
72
85
  }
73
86
  async makeRequest(token, requestId, requestOptions, request) {
74
- core_bentley_1.Logger.logInfo(BackendLoggerCategory_1.PresentationBackendLoggerCategory.Rpc, `Received '${requestId}' request. Params: ${JSON.stringify(requestOptions)}`);
75
- let imodel;
76
- try {
77
- imodel = this.getIModel(token);
78
- }
79
- catch (e) {
80
- return this.errorResponse(e.errorNumber, e.message);
87
+ const requestKey = JSON.stringify(requestOptions);
88
+ core_bentley_1.Logger.logInfo(BackendLoggerCategory_1.PresentationBackendLoggerCategory.Rpc, `Received '${requestId}' request. Params: ${requestKey}`);
89
+ let resultPromise = this._pendingRequests.getValue(requestKey);
90
+ if (resultPromise) {
91
+ core_bentley_1.Logger.logTrace(BackendLoggerCategory_1.PresentationBackendLoggerCategory.Rpc, `Request already pending`);
81
92
  }
82
- const { clientId, diagnostics: diagnosticsOptions, rulesetVariables, ...options } = requestOptions; // eslint-disable-line @typescript-eslint/no-unused-vars
83
- const managerRequestOptions = {
84
- ...options,
85
- imodel,
86
- };
87
- // set up ruleset variables
88
- if (rulesetVariables)
89
- managerRequestOptions.rulesetVariables = rulesetVariables.map(presentation_common_1.RulesetVariable.fromJSON);
90
- // set up diagnostics listener
91
- let diagnosticLogs;
92
- if (diagnosticsOptions) {
93
- managerRequestOptions.diagnostics = {
94
- ...diagnosticsOptions,
95
- handler: (logs) => {
96
- // istanbul ignore else
97
- if (!diagnosticLogs)
98
- diagnosticLogs = [];
99
- diagnosticLogs.push(...logs);
100
- },
93
+ else {
94
+ core_bentley_1.Logger.logTrace(BackendLoggerCategory_1.PresentationBackendLoggerCategory.Rpc, `Request not found, creating a new one`);
95
+ let imodel;
96
+ try {
97
+ imodel = this.getIModel(token);
98
+ }
99
+ catch (e) {
100
+ (0, core_bentley_1.assert)(e instanceof Error);
101
+ return this.errorResponse(presentation_common_1.PresentationStatus.InvalidArgument, e.message);
102
+ }
103
+ const { clientId: _, diagnostics: diagnosticsOptions, rulesetVariables, ...options } = requestOptions;
104
+ const managerRequestOptions = {
105
+ ...options,
106
+ imodel,
101
107
  };
108
+ // set up ruleset variables
109
+ if (rulesetVariables)
110
+ managerRequestOptions.rulesetVariables = rulesetVariables.map(presentation_common_1.RulesetVariable.fromJSON);
111
+ // set up diagnostics listener
112
+ let diagnosticLogs;
113
+ if (diagnosticsOptions) {
114
+ managerRequestOptions.diagnostics = {
115
+ ...diagnosticsOptions,
116
+ handler: (logs) => {
117
+ if (!diagnosticLogs)
118
+ diagnosticLogs = [];
119
+ diagnosticLogs.push(...logs);
120
+ },
121
+ };
122
+ }
123
+ // initiate request
124
+ resultPromise = request(managerRequestOptions)
125
+ .then((result) => this.successResponse(result, diagnosticLogs))
126
+ .catch((e) => this.errorResponse(e.errorNumber, e.message, diagnosticLogs));
127
+ // store the request promise
128
+ this._pendingRequests.addValue(requestKey, resultPromise);
102
129
  }
103
- // initiate request
104
- const resultPromise = request(managerRequestOptions)
105
- .then((result) => this.successResponse(result, diagnosticLogs))
106
- .catch((e) => this.errorResponse(e.errorNumber, e.message, diagnosticLogs));
107
- if (this.requestTimeout === 0)
130
+ if (this._requestTimeout === 0) {
131
+ core_bentley_1.Logger.logTrace(BackendLoggerCategory_1.PresentationBackendLoggerCategory.Rpc, `Request timeout not configured, returning promise without a timeout.`);
132
+ resultPromise.finally(() => {
133
+ this._pendingRequests.deleteValue(requestKey);
134
+ });
108
135
  return resultPromise;
136
+ }
109
137
  let timeout;
110
138
  const timeoutPromise = new Promise((_resolve, reject) => {
111
139
  timeout = setTimeout(() => {
112
140
  reject("Timed out");
113
- }, this.requestTimeout);
141
+ }, this._requestTimeout);
142
+ });
143
+ /* eslint-disable @typescript-eslint/indent */
144
+ core_bentley_1.Logger.logTrace(BackendLoggerCategory_1.PresentationBackendLoggerCategory.Rpc, `Returning a promise with a timeout of ${this._requestTimeout}.`);
145
+ return Promise
146
+ .race([resultPromise, timeoutPromise])
147
+ .catch(() => {
148
+ core_bentley_1.Logger.logTrace(BackendLoggerCategory_1.PresentationBackendLoggerCategory.Rpc, `Request timeout, returning "BackendTimeout" status.`);
149
+ return this.errorResponse(presentation_common_1.PresentationStatus.BackendTimeout);
150
+ })
151
+ .then((response) => {
152
+ if (response.statusCode !== presentation_common_1.PresentationStatus.BackendTimeout) {
153
+ core_bentley_1.Logger.logTrace(BackendLoggerCategory_1.PresentationBackendLoggerCategory.Rpc, `Request completed, returning result.`);
154
+ this._pendingRequests.deleteValue(requestKey);
155
+ }
156
+ clearTimeout(timeout);
157
+ return response;
114
158
  });
115
- return Promise.race([resultPromise, timeoutPromise])
116
- .catch(() => this.errorResponse(presentation_common_1.PresentationStatus.BackendTimeout))
117
- .finally(() => clearTimeout(timeout));
159
+ /* eslint-enable @typescript-eslint/indent */
118
160
  }
119
161
  async getNodesCount(token, requestOptions) {
120
162
  return this.makeRequest(token, "getNodesCount", requestOptions, async (options) => {
@@ -1 +1 @@
1
- {"version":3,"file":"PresentationRpcImpl.js","sourceRoot":"","sources":["../../../src/presentation-backend/PresentationRpcImpl.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n/** @packageDocumentation\r\n * @module RPC\r\n */\r\n\r\nimport { IModelDb } from \"@itwin/core-backend\";\r\nimport { Id64String, Logger } from \"@itwin/core-bentley\";\r\nimport { IModelRpcProps } from \"@itwin/core-common\";\r\nimport {\r\n ContentDescriptorRpcRequestOptions, ContentFlags, ContentInstanceKeysRpcRequestOptions, ContentRpcRequestOptions, ContentSourcesRpcRequestOptions,\r\n ContentSourcesRpcResult, DescriptorJSON, DiagnosticsOptions, DiagnosticsScopeLogs, DisplayLabelRpcRequestOptions, DisplayLabelsRpcRequestOptions,\r\n DisplayValueGroup, DisplayValueGroupJSON, DistinctValuesRpcRequestOptions, ElementProperties,\r\n FilterByInstancePathsHierarchyRpcRequestOptions, FilterByTextHierarchyRpcRequestOptions, HierarchyRpcRequestOptions,\r\n InstanceKey, ItemJSON, KeySet, KeySetJSON, LabelDefinition, LabelDefinitionJSON,\r\n Node, NodeJSON, NodeKey, NodeKeyJSON, NodePathElement, NodePathElementJSON, Paged, PagedResponse,\r\n PageOptions, PresentationError, PresentationRpcInterface, PresentationRpcResponse, PresentationStatus, Ruleset, RulesetVariable,\r\n RulesetVariableJSON, SelectClassInfo, SelectionScope, SelectionScopeRpcRequestOptions, SingleElementPropertiesRpcRequestOptions,\r\n} from \"@itwin/presentation-common\";\r\nimport { PresentationBackendLoggerCategory } from \"./BackendLoggerCategory\";\r\nimport { Presentation } from \"./Presentation\";\r\nimport { PresentationManager } from \"./PresentationManager\";\r\n\r\ntype ContentGetter<TResult = any, TOptions = any> = (requestOptions: TOptions) => TResult;\r\n\r\n/** @internal */\r\nexport const MAX_ALLOWED_PAGE_SIZE = 1000;\r\n/** @internal */\r\nexport const MAX_ALLOWED_KEYS_PAGE_SIZE = 10000;\r\n\r\n/**\r\n * The backend implementation of PresentationRpcInterface. All it's basically\r\n * responsible for is forwarding calls to [[Presentation.manager]].\r\n *\r\n * Consumers should not use this class. Instead, they should register\r\n * [PresentationRpcInterface]($presentation-common):\r\n * ``` ts\r\n * [[include:Backend.Initialization.RpcInterface]]\r\n * ```\r\n *\r\n * @internal\r\n */\r\nexport class PresentationRpcImpl extends PresentationRpcInterface {\r\n\r\n public constructor(_id?: string) {\r\n super();\r\n }\r\n\r\n /**\r\n * Get the maximum result waiting time.\r\n */\r\n public get requestTimeout(): number { return Presentation.getRequestTimeout(); }\r\n\r\n /** Returns an ok response with result inside */\r\n private successResponse<TResult>(result: TResult, diagnostics?: DiagnosticsScopeLogs[]) {\r\n return {\r\n statusCode: PresentationStatus.Success,\r\n result,\r\n diagnostics,\r\n };\r\n }\r\n\r\n /** Returns a bad request response with empty result and an error code */\r\n private errorResponse(errorCode: PresentationStatus, errorMessage?: string, diagnostics?: DiagnosticsScopeLogs[]) {\r\n return {\r\n statusCode: errorCode,\r\n result: undefined,\r\n errorMessage,\r\n diagnostics,\r\n };\r\n }\r\n\r\n /**\r\n * Get the [[PresentationManager]] used by this RPC impl.\r\n */\r\n public getManager(clientId?: string): PresentationManager {\r\n return Presentation.getManager(clientId);\r\n }\r\n\r\n private getIModel(token: IModelRpcProps): IModelDb {\r\n let imodel: IModelDb;\r\n try {\r\n imodel = IModelDb.findByKey(token.key);\r\n } catch {\r\n throw new PresentationError(PresentationStatus.InvalidArgument, \"IModelRpcProps doesn't point to a valid iModel\");\r\n }\r\n return imodel;\r\n }\r\n\r\n private async makeRequest<TRpcOptions extends { rulesetOrId?: Ruleset | string, clientId?: string, diagnostics?: DiagnosticsOptions, rulesetVariables?: RulesetVariableJSON[] }, TResult>(token: IModelRpcProps, requestId: string, requestOptions: TRpcOptions, request: ContentGetter<Promise<TResult>>): PresentationRpcResponse<TResult> {\r\n Logger.logInfo(PresentationBackendLoggerCategory.Rpc, `Received '${requestId}' request. Params: ${JSON.stringify(requestOptions)}`);\r\n let imodel: IModelDb;\r\n try {\r\n imodel = this.getIModel(token);\r\n } catch (e) {\r\n return this.errorResponse((e as PresentationError).errorNumber, (e as PresentationError).message);\r\n }\r\n\r\n const { clientId, diagnostics: diagnosticsOptions, rulesetVariables, ...options } = requestOptions; // eslint-disable-line @typescript-eslint/no-unused-vars\r\n const managerRequestOptions: any = {\r\n ...options,\r\n imodel,\r\n };\r\n\r\n // set up ruleset variables\r\n if (rulesetVariables)\r\n managerRequestOptions.rulesetVariables = rulesetVariables.map(RulesetVariable.fromJSON);\r\n\r\n // set up diagnostics listener\r\n let diagnosticLogs: DiagnosticsScopeLogs[] | undefined;\r\n if (diagnosticsOptions) {\r\n managerRequestOptions.diagnostics = {\r\n ...diagnosticsOptions,\r\n handler: (logs: DiagnosticsScopeLogs[]) => {\r\n // istanbul ignore else\r\n if (!diagnosticLogs)\r\n diagnosticLogs = [];\r\n diagnosticLogs.push(...logs);\r\n },\r\n };\r\n }\r\n\r\n // initiate request\r\n const resultPromise = request(managerRequestOptions)\r\n .then((result) => this.successResponse(result, diagnosticLogs))\r\n .catch((e: PresentationError) => this.errorResponse(e.errorNumber, e.message, diagnosticLogs));\r\n\r\n if (this.requestTimeout === 0)\r\n return resultPromise;\r\n\r\n let timeout: NodeJS.Timeout;\r\n const timeoutPromise = new Promise<any>((_resolve, reject) => {\r\n timeout = setTimeout(() => {\r\n reject(\"Timed out\");\r\n }, this.requestTimeout);\r\n });\r\n\r\n return Promise.race([resultPromise, timeoutPromise])\r\n .catch(() => this.errorResponse(PresentationStatus.BackendTimeout))\r\n .finally(() => clearTimeout(timeout));\r\n }\r\n\r\n public override async getNodesCount(token: IModelRpcProps, requestOptions: HierarchyRpcRequestOptions): PresentationRpcResponse<number> {\r\n return this.makeRequest(token, \"getNodesCount\", requestOptions, async (options) => {\r\n options = {\r\n ...options,\r\n parentKey: nodeKeyFromJson(options.parentKey),\r\n };\r\n return this.getManager(requestOptions.clientId).getNodesCount(options);\r\n });\r\n }\r\n\r\n public override async getPagedNodes(token: IModelRpcProps, requestOptions: Paged<HierarchyRpcRequestOptions>): PresentationRpcResponse<PagedResponse<NodeJSON>> {\r\n return this.makeRequest(token, \"getPagedNodes\", requestOptions, async (options) => {\r\n options = enforceValidPageSize({\r\n ...options,\r\n parentKey: nodeKeyFromJson(options.parentKey),\r\n });\r\n const [nodes, count] = await Promise.all([\r\n this.getManager(requestOptions.clientId).getNodes(options),\r\n this.getManager(requestOptions.clientId).getNodesCount(options),\r\n ]);\r\n return { total: count, items: nodes.map(Node.toJSON) };\r\n });\r\n }\r\n\r\n public override async getNodePaths(token: IModelRpcProps, requestOptions: FilterByInstancePathsHierarchyRpcRequestOptions): PresentationRpcResponse<NodePathElementJSON[]> {\r\n return this.makeRequest(token, \"getNodePaths\", requestOptions, async (options) => {\r\n const result = await this.getManager(requestOptions.clientId).getNodePaths(options);\r\n return result.map(NodePathElement.toJSON);\r\n });\r\n }\r\n\r\n public override async getFilteredNodePaths(token: IModelRpcProps, requestOptions: FilterByTextHierarchyRpcRequestOptions): PresentationRpcResponse<NodePathElementJSON[]> {\r\n return this.makeRequest(token, \"getFilteredNodePaths\", requestOptions, async (options) => {\r\n const result = await this.getManager(requestOptions.clientId).getFilteredNodePaths(options);\r\n return result.map(NodePathElement.toJSON);\r\n });\r\n }\r\n\r\n public override async getContentSources(token: IModelRpcProps, requestOptions: ContentSourcesRpcRequestOptions): PresentationRpcResponse<ContentSourcesRpcResult> {\r\n return this.makeRequest(token, \"getContentSources\", requestOptions, async (options) => {\r\n const result = await this.getManager(requestOptions.clientId).getContentSources(options);\r\n const classesMap = {};\r\n const selectClasses = result.map((sci) => SelectClassInfo.toCompressedJSON(sci, classesMap));\r\n return { sources: selectClasses, classesMap };\r\n });\r\n }\r\n\r\n public override async getContentDescriptor(token: IModelRpcProps, requestOptions: ContentDescriptorRpcRequestOptions): PresentationRpcResponse<DescriptorJSON | undefined> {\r\n return this.makeRequest(token, \"getContentDescriptor\", requestOptions, async (options) => {\r\n options = {\r\n ...options,\r\n keys: KeySet.fromJSON(options.keys),\r\n };\r\n const descriptor = await this.getManager(requestOptions.clientId).getContentDescriptor(options);\r\n if (descriptor)\r\n return descriptor.toJSON();\r\n return undefined;\r\n });\r\n }\r\n\r\n public override async getContentSetSize(token: IModelRpcProps, requestOptions: ContentRpcRequestOptions): PresentationRpcResponse<number> {\r\n return this.makeRequest(token, \"getContentSetSize\", requestOptions, async (options) => {\r\n options = {\r\n ...options,\r\n keys: KeySet.fromJSON(options.keys),\r\n };\r\n return this.getManager(requestOptions.clientId).getContentSetSize(options);\r\n });\r\n }\r\n\r\n public override async getPagedContent(token: IModelRpcProps, requestOptions: Paged<ContentRpcRequestOptions>): PresentationRpcResponse<{ descriptor: DescriptorJSON, contentSet: PagedResponse<ItemJSON> } | undefined> {\r\n return this.makeRequest(token, \"getPagedContent\", requestOptions, async (options) => {\r\n options = enforceValidPageSize({\r\n ...options,\r\n keys: KeySet.fromJSON(options.keys),\r\n });\r\n\r\n const [size, content] = await Promise.all([\r\n this.getManager(requestOptions.clientId).getContentSetSize(options),\r\n this.getManager(requestOptions.clientId).getContent(options),\r\n ]);\r\n\r\n if (!content)\r\n return undefined;\r\n\r\n return {\r\n descriptor: content.descriptor.toJSON(),\r\n contentSet: {\r\n total: size,\r\n items: content.contentSet.map((i) => i.toJSON()),\r\n },\r\n };\r\n });\r\n }\r\n\r\n public override async getPagedContentSet(token: IModelRpcProps, requestOptions: Paged<ContentRpcRequestOptions>): PresentationRpcResponse<PagedResponse<ItemJSON>> {\r\n const content = await this.getPagedContent(token, requestOptions);\r\n return this.successResponse(content.result ? content.result.contentSet : { total: 0, items: [] });\r\n }\r\n\r\n public override async getElementProperties(token: IModelRpcProps, requestOptions: SingleElementPropertiesRpcRequestOptions): PresentationRpcResponse<ElementProperties | undefined> {\r\n return this.makeRequest(token, \"getElementProperties\", { ...requestOptions }, async (options) => {\r\n return this.getManager(requestOptions.clientId).getElementProperties(options);\r\n });\r\n }\r\n\r\n public override async getPagedDistinctValues(token: IModelRpcProps, requestOptions: DistinctValuesRpcRequestOptions): PresentationRpcResponse<PagedResponse<DisplayValueGroupJSON>> {\r\n return this.makeRequest(token, \"getPagedDistinctValues\", requestOptions, async (options) => {\r\n options = enforceValidPageSize({\r\n ...options,\r\n keys: KeySet.fromJSON(options.keys),\r\n });\r\n const response = await this.getManager(requestOptions.clientId).getPagedDistinctValues(options);\r\n return {\r\n ...response,\r\n items: response.items.map(DisplayValueGroup.toJSON),\r\n };\r\n });\r\n }\r\n\r\n public override async getContentInstanceKeys(token: IModelRpcProps, requestOptions: ContentInstanceKeysRpcRequestOptions): PresentationRpcResponse<{ total: number, items: KeySetJSON }> {\r\n return this.makeRequest(token, \"getContentInstanceKeys\", requestOptions, async (options) => {\r\n const { displayType, ...optionsNoDisplayType } = options;\r\n options = enforceValidPageSize({\r\n ...optionsNoDisplayType,\r\n keys: KeySet.fromJSON(optionsNoDisplayType.keys),\r\n descriptor: {\r\n displayType,\r\n contentFlags: ContentFlags.KeysOnly,\r\n },\r\n }, MAX_ALLOWED_KEYS_PAGE_SIZE);\r\n\r\n const [size, content] = await Promise.all([\r\n this.getManager(requestOptions.clientId).getContentSetSize(options),\r\n this.getManager(requestOptions.clientId).getContent(options),\r\n ]);\r\n\r\n if (size === 0 || !content)\r\n return { total: 0, items: new KeySet().toJSON() };\r\n\r\n return {\r\n total: size,\r\n items: content.contentSet.reduce((keys, item) => keys.add(item.primaryKeys), new KeySet()).toJSON(),\r\n };\r\n });\r\n }\r\n\r\n public override async getDisplayLabelDefinition(token: IModelRpcProps, requestOptions: DisplayLabelRpcRequestOptions): PresentationRpcResponse<LabelDefinitionJSON> {\r\n return this.makeRequest(token, \"getDisplayLabelDefinition\", requestOptions, async (options) => {\r\n const label = await this.getManager(requestOptions.clientId).getDisplayLabelDefinition(options);\r\n return LabelDefinition.toJSON(label);\r\n });\r\n }\r\n\r\n public override async getPagedDisplayLabelDefinitions(token: IModelRpcProps, requestOptions: DisplayLabelsRpcRequestOptions): PresentationRpcResponse<PagedResponse<LabelDefinitionJSON>> {\r\n const pageOpts = enforceValidPageSize({ paging: { start: 0, size: requestOptions.keys.length } });\r\n if (pageOpts.paging.size < requestOptions.keys.length)\r\n requestOptions.keys.splice(pageOpts.paging.size);\r\n return this.makeRequest(token, \"getPagedDisplayLabelDefinitions\", requestOptions, async (options) => {\r\n const labels = await this.getManager(requestOptions.clientId).getDisplayLabelDefinitions({ ...options, keys: options.keys.map(InstanceKey.fromJSON) });\r\n return {\r\n total: options.keys.length,\r\n items: labels.map(LabelDefinition.toJSON),\r\n };\r\n });\r\n }\r\n\r\n public override async getSelectionScopes(token: IModelRpcProps, requestOptions: SelectionScopeRpcRequestOptions): PresentationRpcResponse<SelectionScope[]> {\r\n return this.makeRequest(token, \"getSelectionScopes\", requestOptions, async (options) =>\r\n this.getManager(requestOptions.clientId).getSelectionScopes(options),\r\n );\r\n }\r\n\r\n public override async computeSelection(token: IModelRpcProps, requestOptions: SelectionScopeRpcRequestOptions, ids: Id64String[], scopeId: string): PresentationRpcResponse<KeySetJSON> {\r\n return this.makeRequest(token, \"computeSelection\", { ...requestOptions, ids, scopeId }, async (options) => {\r\n const keys = await this.getManager(requestOptions.clientId).computeSelection(options);\r\n return keys.toJSON();\r\n });\r\n }\r\n}\r\n\r\nconst enforceValidPageSize = <TOptions extends Paged<object>>(requestOptions: TOptions, maxPageSize = MAX_ALLOWED_PAGE_SIZE): TOptions & { paging: PageOptions } => {\r\n const validPageSize = getValidPageSize(requestOptions.paging?.size, maxPageSize);\r\n if (!requestOptions.paging || requestOptions.paging.size !== validPageSize)\r\n return { ...requestOptions, paging: { ...requestOptions.paging, size: validPageSize } };\r\n return requestOptions as (TOptions & { paging: PageOptions });\r\n};\r\n\r\nconst getValidPageSize = (size: number | undefined, maxPageSize: number) => {\r\n const requestedSize = size ?? 0;\r\n return (requestedSize === 0 || requestedSize > maxPageSize) ? maxPageSize : requestedSize;\r\n};\r\n\r\nconst nodeKeyFromJson = (json: NodeKeyJSON | undefined): NodeKey | undefined => {\r\n if (!json)\r\n return undefined;\r\n return NodeKey.fromJSON(json);\r\n};\r\n"]}
1
+ {"version":3,"file":"PresentationRpcImpl.js","sourceRoot":"","sources":["../../../src/presentation-backend/PresentationRpcImpl.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n/** @packageDocumentation\r\n * @module RPC\r\n */\r\n\r\nimport { IModelDb } from \"@itwin/core-backend\";\r\nimport { assert, Id64String, IDisposable, Logger } from \"@itwin/core-bentley\";\r\nimport { IModelRpcProps } from \"@itwin/core-common\";\r\nimport {\r\n ContentDescriptorRpcRequestOptions, ContentFlags, ContentInstanceKeysRpcRequestOptions, ContentRpcRequestOptions, ContentSourcesRpcRequestOptions,\r\n ContentSourcesRpcResult, DescriptorJSON, DiagnosticsOptions, DiagnosticsScopeLogs, DisplayLabelRpcRequestOptions, DisplayLabelsRpcRequestOptions,\r\n DisplayValueGroup, DisplayValueGroupJSON, DistinctValuesRpcRequestOptions, ElementProperties, FilterByInstancePathsHierarchyRpcRequestOptions,\r\n FilterByTextHierarchyRpcRequestOptions, HierarchyRpcRequestOptions, InstanceKey, ItemJSON, KeySet, KeySetJSON, LabelDefinition, LabelDefinitionJSON,\r\n Node, NodeJSON, NodeKey, NodeKeyJSON, NodePathElement, NodePathElementJSON, Paged, PagedResponse, PageOptions, PresentationError,\r\n PresentationRpcInterface, PresentationRpcResponse, PresentationRpcResponseData, PresentationStatus, Ruleset, RulesetVariable, RulesetVariableJSON,\r\n SelectClassInfo, SelectionScope, SelectionScopeRpcRequestOptions, SingleElementPropertiesRpcRequestOptions,\r\n} from \"@itwin/presentation-common\";\r\nimport { PresentationBackendLoggerCategory } from \"./BackendLoggerCategory\";\r\nimport { Presentation } from \"./Presentation\";\r\nimport { PresentationManager } from \"./PresentationManager\";\r\nimport { TemporaryStorage } from \"./TemporaryStorage\";\r\n\r\ntype ContentGetter<TResult = any, TOptions = any> = (requestOptions: TOptions) => TResult;\r\n\r\n/** @internal */\r\nexport const MAX_ALLOWED_PAGE_SIZE = 1000;\r\n/** @internal */\r\nexport const MAX_ALLOWED_KEYS_PAGE_SIZE = 10000;\r\n\r\n/**\r\n * The backend implementation of PresentationRpcInterface. All it's basically\r\n * responsible for is forwarding calls to [[Presentation.manager]].\r\n *\r\n * Consumers should not use this class. Instead, they should register\r\n * [PresentationRpcInterface]($presentation-common):\r\n * ``` ts\r\n * [[include:Backend.Initialization.RpcInterface]]\r\n * ```\r\n *\r\n * @internal\r\n */\r\nexport class PresentationRpcImpl extends PresentationRpcInterface implements IDisposable {\r\n\r\n private _requestTimeout: number;\r\n private _pendingRequests: TemporaryStorage<PresentationRpcResponse<any>>;\r\n\r\n public constructor(props?: { requestTimeout: number }) {\r\n super();\r\n this._requestTimeout = props?.requestTimeout ?? 90 * 1000;\r\n this._pendingRequests = new TemporaryStorage({\r\n // remove the pending request after request timeout + 10 seconds - this gives\r\n // frontend 10 seconds to re-send the request until it's removed from requests' cache\r\n unusedValueLifetime: this._requestTimeout + 10 * 1000,\r\n\r\n // attempt to clean up every second\r\n cleanupInterval: 1000,\r\n\r\n cleanupHandler: (id) => {\r\n Logger.logTrace(PresentationBackendLoggerCategory.Rpc, `Cleaning up request without frontend retrieving it: ${id}.`);\r\n },\r\n });\r\n }\r\n\r\n public dispose() {\r\n this._pendingRequests.dispose();\r\n }\r\n\r\n public get requestTimeout() { return this._requestTimeout; }\r\n\r\n /** Returns an ok response with result inside */\r\n private successResponse<TResult>(result: TResult, diagnostics?: DiagnosticsScopeLogs[]) {\r\n return {\r\n statusCode: PresentationStatus.Success,\r\n result,\r\n diagnostics,\r\n };\r\n }\r\n\r\n /** Returns a bad request response with empty result and an error code */\r\n private errorResponse(errorCode: PresentationStatus, errorMessage?: string, diagnostics?: DiagnosticsScopeLogs[]) {\r\n return {\r\n statusCode: errorCode,\r\n result: undefined,\r\n errorMessage,\r\n diagnostics,\r\n };\r\n }\r\n\r\n /**\r\n * Get the [[PresentationManager]] used by this RPC impl.\r\n */\r\n public getManager(clientId?: string): PresentationManager {\r\n return Presentation.getManager(clientId);\r\n }\r\n\r\n private getIModel(token: IModelRpcProps): IModelDb {\r\n let imodel: IModelDb;\r\n try {\r\n imodel = IModelDb.findByKey(token.key);\r\n } catch {\r\n throw new PresentationError(PresentationStatus.InvalidArgument, \"IModelRpcProps doesn't point to a valid iModel\");\r\n }\r\n return imodel;\r\n }\r\n\r\n private async makeRequest<TRpcOptions extends { rulesetOrId?: Ruleset | string, clientId?: string, diagnostics?: DiagnosticsOptions, rulesetVariables?: RulesetVariableJSON[] }, TResult>(token: IModelRpcProps, requestId: string, requestOptions: TRpcOptions, request: ContentGetter<Promise<TResult>>): PresentationRpcResponse<TResult> {\r\n const requestKey = JSON.stringify(requestOptions);\r\n\r\n Logger.logInfo(PresentationBackendLoggerCategory.Rpc, `Received '${requestId}' request. Params: ${requestKey}`);\r\n\r\n let resultPromise = this._pendingRequests.getValue(requestKey);\r\n if (resultPromise) {\r\n Logger.logTrace(PresentationBackendLoggerCategory.Rpc, `Request already pending`);\r\n } else {\r\n Logger.logTrace(PresentationBackendLoggerCategory.Rpc, `Request not found, creating a new one`);\r\n let imodel: IModelDb;\r\n try {\r\n imodel = this.getIModel(token);\r\n } catch (e) {\r\n assert(e instanceof Error);\r\n return this.errorResponse(PresentationStatus.InvalidArgument, e.message);\r\n }\r\n\r\n const { clientId: _, diagnostics: diagnosticsOptions, rulesetVariables, ...options } = requestOptions;\r\n const managerRequestOptions: any = {\r\n ...options,\r\n imodel,\r\n };\r\n\r\n // set up ruleset variables\r\n if (rulesetVariables)\r\n managerRequestOptions.rulesetVariables = rulesetVariables.map(RulesetVariable.fromJSON);\r\n\r\n // set up diagnostics listener\r\n let diagnosticLogs: DiagnosticsScopeLogs[] | undefined;\r\n if (diagnosticsOptions) {\r\n managerRequestOptions.diagnostics = {\r\n ...diagnosticsOptions,\r\n handler: (logs: DiagnosticsScopeLogs[]) => {\r\n if (!diagnosticLogs)\r\n diagnosticLogs = [];\r\n diagnosticLogs.push(...logs);\r\n },\r\n };\r\n }\r\n\r\n // initiate request\r\n resultPromise = request(managerRequestOptions)\r\n .then((result) => this.successResponse(result, diagnosticLogs))\r\n .catch((e: PresentationError) => this.errorResponse(e.errorNumber, e.message, diagnosticLogs));\r\n\r\n // store the request promise\r\n this._pendingRequests.addValue(requestKey, resultPromise);\r\n }\r\n\r\n if (this._requestTimeout === 0) {\r\n Logger.logTrace(PresentationBackendLoggerCategory.Rpc, `Request timeout not configured, returning promise without a timeout.`);\r\n resultPromise.finally(() => {\r\n this._pendingRequests.deleteValue(requestKey);\r\n });\r\n return resultPromise;\r\n }\r\n\r\n let timeout: NodeJS.Timeout;\r\n const timeoutPromise = new Promise<any>((_resolve, reject) => {\r\n timeout = setTimeout(() => {\r\n reject(\"Timed out\");\r\n }, this._requestTimeout);\r\n });\r\n\r\n /* eslint-disable @typescript-eslint/indent */\r\n Logger.logTrace(PresentationBackendLoggerCategory.Rpc, `Returning a promise with a timeout of ${this._requestTimeout}.`);\r\n return Promise\r\n .race([resultPromise, timeoutPromise])\r\n .catch<PresentationRpcResponseData>(() => {\r\n Logger.logTrace(PresentationBackendLoggerCategory.Rpc, `Request timeout, returning \"BackendTimeout\" status.`);\r\n return this.errorResponse(PresentationStatus.BackendTimeout);\r\n })\r\n .then((response: PresentationRpcResponseData<any>) => {\r\n if (response.statusCode !== PresentationStatus.BackendTimeout) {\r\n Logger.logTrace(PresentationBackendLoggerCategory.Rpc, `Request completed, returning result.`);\r\n this._pendingRequests.deleteValue(requestKey);\r\n }\r\n clearTimeout(timeout);\r\n return response;\r\n });\r\n /* eslint-enable @typescript-eslint/indent */\r\n }\r\n\r\n public override async getNodesCount(token: IModelRpcProps, requestOptions: HierarchyRpcRequestOptions): PresentationRpcResponse<number> {\r\n return this.makeRequest(token, \"getNodesCount\", requestOptions, async (options) => {\r\n options = {\r\n ...options,\r\n parentKey: nodeKeyFromJson(options.parentKey),\r\n };\r\n return this.getManager(requestOptions.clientId).getNodesCount(options);\r\n });\r\n }\r\n\r\n public override async getPagedNodes(token: IModelRpcProps, requestOptions: Paged<HierarchyRpcRequestOptions>): PresentationRpcResponse<PagedResponse<NodeJSON>> {\r\n return this.makeRequest(token, \"getPagedNodes\", requestOptions, async (options) => {\r\n options = enforceValidPageSize({\r\n ...options,\r\n parentKey: nodeKeyFromJson(options.parentKey),\r\n });\r\n const [nodes, count] = await Promise.all([\r\n this.getManager(requestOptions.clientId).getNodes(options),\r\n this.getManager(requestOptions.clientId).getNodesCount(options),\r\n ]);\r\n return { total: count, items: nodes.map(Node.toJSON) };\r\n });\r\n }\r\n\r\n public override async getNodePaths(token: IModelRpcProps, requestOptions: FilterByInstancePathsHierarchyRpcRequestOptions): PresentationRpcResponse<NodePathElementJSON[]> {\r\n return this.makeRequest(token, \"getNodePaths\", requestOptions, async (options) => {\r\n const result = await this.getManager(requestOptions.clientId).getNodePaths(options);\r\n return result.map(NodePathElement.toJSON);\r\n });\r\n }\r\n\r\n public override async getFilteredNodePaths(token: IModelRpcProps, requestOptions: FilterByTextHierarchyRpcRequestOptions): PresentationRpcResponse<NodePathElementJSON[]> {\r\n return this.makeRequest(token, \"getFilteredNodePaths\", requestOptions, async (options) => {\r\n const result = await this.getManager(requestOptions.clientId).getFilteredNodePaths(options);\r\n return result.map(NodePathElement.toJSON);\r\n });\r\n }\r\n\r\n public override async getContentSources(token: IModelRpcProps, requestOptions: ContentSourcesRpcRequestOptions): PresentationRpcResponse<ContentSourcesRpcResult> {\r\n return this.makeRequest(token, \"getContentSources\", requestOptions, async (options) => {\r\n const result = await this.getManager(requestOptions.clientId).getContentSources(options);\r\n const classesMap = {};\r\n const selectClasses = result.map((sci) => SelectClassInfo.toCompressedJSON(sci, classesMap));\r\n return { sources: selectClasses, classesMap };\r\n });\r\n }\r\n\r\n public override async getContentDescriptor(token: IModelRpcProps, requestOptions: ContentDescriptorRpcRequestOptions): PresentationRpcResponse<DescriptorJSON | undefined> {\r\n return this.makeRequest(token, \"getContentDescriptor\", requestOptions, async (options) => {\r\n options = {\r\n ...options,\r\n keys: KeySet.fromJSON(options.keys),\r\n };\r\n const descriptor = await this.getManager(requestOptions.clientId).getContentDescriptor(options);\r\n if (descriptor)\r\n return descriptor.toJSON();\r\n return undefined;\r\n });\r\n }\r\n\r\n public override async getContentSetSize(token: IModelRpcProps, requestOptions: ContentRpcRequestOptions): PresentationRpcResponse<number> {\r\n return this.makeRequest(token, \"getContentSetSize\", requestOptions, async (options) => {\r\n options = {\r\n ...options,\r\n keys: KeySet.fromJSON(options.keys),\r\n };\r\n return this.getManager(requestOptions.clientId).getContentSetSize(options);\r\n });\r\n }\r\n\r\n public override async getPagedContent(token: IModelRpcProps, requestOptions: Paged<ContentRpcRequestOptions>): PresentationRpcResponse<{ descriptor: DescriptorJSON, contentSet: PagedResponse<ItemJSON> } | undefined> {\r\n return this.makeRequest(token, \"getPagedContent\", requestOptions, async (options) => {\r\n options = enforceValidPageSize({\r\n ...options,\r\n keys: KeySet.fromJSON(options.keys),\r\n });\r\n\r\n const [size, content] = await Promise.all([\r\n this.getManager(requestOptions.clientId).getContentSetSize(options),\r\n this.getManager(requestOptions.clientId).getContent(options),\r\n ]);\r\n\r\n if (!content)\r\n return undefined;\r\n\r\n return {\r\n descriptor: content.descriptor.toJSON(),\r\n contentSet: {\r\n total: size,\r\n items: content.contentSet.map((i) => i.toJSON()),\r\n },\r\n };\r\n });\r\n }\r\n\r\n public override async getPagedContentSet(token: IModelRpcProps, requestOptions: Paged<ContentRpcRequestOptions>): PresentationRpcResponse<PagedResponse<ItemJSON>> {\r\n const content = await this.getPagedContent(token, requestOptions);\r\n return this.successResponse(content.result ? content.result.contentSet : { total: 0, items: [] });\r\n }\r\n\r\n public override async getElementProperties(token: IModelRpcProps, requestOptions: SingleElementPropertiesRpcRequestOptions): PresentationRpcResponse<ElementProperties | undefined> {\r\n return this.makeRequest(token, \"getElementProperties\", { ...requestOptions }, async (options) => {\r\n return this.getManager(requestOptions.clientId).getElementProperties(options);\r\n });\r\n }\r\n\r\n public override async getPagedDistinctValues(token: IModelRpcProps, requestOptions: DistinctValuesRpcRequestOptions): PresentationRpcResponse<PagedResponse<DisplayValueGroupJSON>> {\r\n return this.makeRequest(token, \"getPagedDistinctValues\", requestOptions, async (options) => {\r\n options = enforceValidPageSize({\r\n ...options,\r\n keys: KeySet.fromJSON(options.keys),\r\n });\r\n const response = await this.getManager(requestOptions.clientId).getPagedDistinctValues(options);\r\n return {\r\n ...response,\r\n items: response.items.map(DisplayValueGroup.toJSON),\r\n };\r\n });\r\n }\r\n\r\n public override async getContentInstanceKeys(token: IModelRpcProps, requestOptions: ContentInstanceKeysRpcRequestOptions): PresentationRpcResponse<{ total: number, items: KeySetJSON }> {\r\n return this.makeRequest(token, \"getContentInstanceKeys\", requestOptions, async (options) => {\r\n const { displayType, ...optionsNoDisplayType } = options;\r\n options = enforceValidPageSize({\r\n ...optionsNoDisplayType,\r\n keys: KeySet.fromJSON(optionsNoDisplayType.keys),\r\n descriptor: {\r\n displayType,\r\n contentFlags: ContentFlags.KeysOnly,\r\n },\r\n }, MAX_ALLOWED_KEYS_PAGE_SIZE);\r\n\r\n const [size, content] = await Promise.all([\r\n this.getManager(requestOptions.clientId).getContentSetSize(options),\r\n this.getManager(requestOptions.clientId).getContent(options),\r\n ]);\r\n\r\n if (size === 0 || !content)\r\n return { total: 0, items: new KeySet().toJSON() };\r\n\r\n return {\r\n total: size,\r\n items: content.contentSet.reduce((keys, item) => keys.add(item.primaryKeys), new KeySet()).toJSON(),\r\n };\r\n });\r\n }\r\n\r\n public override async getDisplayLabelDefinition(token: IModelRpcProps, requestOptions: DisplayLabelRpcRequestOptions): PresentationRpcResponse<LabelDefinitionJSON> {\r\n return this.makeRequest(token, \"getDisplayLabelDefinition\", requestOptions, async (options) => {\r\n const label = await this.getManager(requestOptions.clientId).getDisplayLabelDefinition(options);\r\n return LabelDefinition.toJSON(label);\r\n });\r\n }\r\n\r\n public override async getPagedDisplayLabelDefinitions(token: IModelRpcProps, requestOptions: DisplayLabelsRpcRequestOptions): PresentationRpcResponse<PagedResponse<LabelDefinitionJSON>> {\r\n const pageOpts = enforceValidPageSize({ paging: { start: 0, size: requestOptions.keys.length } });\r\n if (pageOpts.paging.size < requestOptions.keys.length)\r\n requestOptions.keys.splice(pageOpts.paging.size);\r\n return this.makeRequest(token, \"getPagedDisplayLabelDefinitions\", requestOptions, async (options) => {\r\n const labels = await this.getManager(requestOptions.clientId).getDisplayLabelDefinitions({ ...options, keys: options.keys.map(InstanceKey.fromJSON) });\r\n return {\r\n total: options.keys.length,\r\n items: labels.map(LabelDefinition.toJSON),\r\n };\r\n });\r\n }\r\n\r\n public override async getSelectionScopes(token: IModelRpcProps, requestOptions: SelectionScopeRpcRequestOptions): PresentationRpcResponse<SelectionScope[]> {\r\n return this.makeRequest(token, \"getSelectionScopes\", requestOptions, async (options) =>\r\n this.getManager(requestOptions.clientId).getSelectionScopes(options),\r\n );\r\n }\r\n\r\n public override async computeSelection(token: IModelRpcProps, requestOptions: SelectionScopeRpcRequestOptions, ids: Id64String[], scopeId: string): PresentationRpcResponse<KeySetJSON> {\r\n return this.makeRequest(token, \"computeSelection\", { ...requestOptions, ids, scopeId }, async (options) => {\r\n const keys = await this.getManager(requestOptions.clientId).computeSelection(options);\r\n return keys.toJSON();\r\n });\r\n }\r\n}\r\n\r\nconst enforceValidPageSize = <TOptions extends Paged<object>>(requestOptions: TOptions, maxPageSize = MAX_ALLOWED_PAGE_SIZE): TOptions & { paging: PageOptions } => {\r\n const validPageSize = getValidPageSize(requestOptions.paging?.size, maxPageSize);\r\n if (!requestOptions.paging || requestOptions.paging.size !== validPageSize)\r\n return { ...requestOptions, paging: { ...requestOptions.paging, size: validPageSize } };\r\n return requestOptions as (TOptions & { paging: PageOptions });\r\n};\r\n\r\nconst getValidPageSize = (size: number | undefined, maxPageSize: number) => {\r\n const requestedSize = size ?? 0;\r\n return (requestedSize === 0 || requestedSize > maxPageSize) ? maxPageSize : requestedSize;\r\n};\r\n\r\nconst nodeKeyFromJson = (json: NodeKeyJSON | undefined): NodeKey | undefined => {\r\n if (!json)\r\n return undefined;\r\n return NodeKey.fromJSON(json);\r\n};\r\n"]}
@@ -7,11 +7,8 @@ import { IDisposable } from "@itwin/core-bentley";
7
7
  * @internal
8
8
  */
9
9
  export interface TemporaryStorageProps<T> {
10
- /** A factory method that creates a stored value given it's identifier */
11
- factory: (id: string) => T;
12
10
  /** A method that's called for every value before it's removed from storage */
13
- cleanupHandler?: (value: T) => void;
14
- onCreated?: (id: string, value: T, onValueUsed: () => void) => void;
11
+ cleanupHandler?: (id: string, value: T) => void;
15
12
  onDisposedSingle?: (id: string) => void;
16
13
  onDisposedAll?: () => void;
17
14
  /**
@@ -23,12 +20,30 @@ export interface TemporaryStorageProps<T> {
23
20
  cleanupInterval?: number;
24
21
  /**
25
22
  * Shortest period of time which the value should be kept in storage
26
- * unused before it's cleaned up. `0` or `undefined` means values
27
- * are removed from the storage on every cleanup (either manual call to
28
- * [[TemporaryStorage.disposeOutdatedValues]] or scheduled (controlled
29
- * by [[cleanupInterval]]))
23
+ * unused before it's cleaned up.
24
+ *
25
+ * `undefined` means the values may be kept unused in the storage indefinitely.
26
+ * `0` means the values are removed from the storage on every cleanup (either manual
27
+ * call to [[TemporaryStorage.disposeOutdatedValues]] or scheduled (controlled
28
+ * by [[cleanupInterval]])).
30
29
  */
31
- valueLifetime?: number;
30
+ unusedValueLifetime?: number;
31
+ /**
32
+ * The maximum period of time which the value should be kept in storage
33
+ * before it's cleaned up. The time is measured from the moment the value is added
34
+ * to the storage.
35
+ *
36
+ * `undefined` means the values may be kept indefinitely. `0` means they're removed
37
+ * up on every cleanup (either manual call to [[TemporaryStorage.disposeOutdatedValues]]
38
+ * or scheduled (controlled by [[cleanupInterval]])).
39
+ */
40
+ maxValueLifetime?: number;
41
+ }
42
+ /** Value with know last used time */
43
+ interface TemporaryValue<T> {
44
+ created: Date;
45
+ lastUsed: Date;
46
+ value: T;
32
47
  }
33
48
  /**
34
49
  * Storage for values that get removed from it after being unused (not-requested
@@ -37,8 +52,8 @@ export interface TemporaryStorageProps<T> {
37
52
  * @internal
38
53
  */
39
54
  export declare class TemporaryStorage<T> implements IDisposable {
40
- private _values;
41
55
  private _timer?;
56
+ protected _values: Map<string, TemporaryValue<T>>;
42
57
  readonly props: TemporaryStorageProps<T>;
43
58
  /**
44
59
  * Constructor. Creates the storage using supplied params.
@@ -51,17 +66,24 @@ export declare class TemporaryStorage<T> implements IDisposable {
51
66
  dispose(): void;
52
67
  /**
53
68
  * Cleans up values that are currently outdated (based
54
- * on their lifetime specified through [[Props]]).
69
+ * on their max and unused value lifetimes specified through [[Props]]).
55
70
  */
56
71
  disposeOutdatedValues: () => void;
72
+ private deleteExistingEntry;
57
73
  /**
58
- * Get a value from the storage. If the value with the
59
- * specified id doesn't exist, it gets created.
74
+ * Get a value from the storage.
60
75
  *
61
- * **Note:** requesting a value with this method updates
62
- * it's last used time.
76
+ * **Note:** requesting a value with this method updates it's last used time.
63
77
  */
64
- getValue(id: string): T;
78
+ getValue(id: string): T | undefined;
79
+ notifyValueUsed(id: string): void;
80
+ /**
81
+ * Adds a value into the storage.
82
+ * @throws An error when trying to add a value with ID that's already stored in the storage.
83
+ */
84
+ addValue(id: string, value: T): void;
85
+ /** Deletes a value with given id. */
86
+ deleteValue(id: string): void;
65
87
  /**
66
88
  * Get all values currently in this storage.
67
89
  *
@@ -70,4 +92,33 @@ export declare class TemporaryStorage<T> implements IDisposable {
70
92
  */
71
93
  get values(): T[];
72
94
  }
95
+ /**
96
+ * Configuration properties for [[FactoryBasedTemporaryStorage]].
97
+ * @internal
98
+ */
99
+ export interface FactoryBasedTemporaryStorageProps<T> extends TemporaryStorageProps<T> {
100
+ /** A factory method that creates a stored value given it's identifier */
101
+ factory: (id: string, onValueUsed: () => void) => T;
102
+ }
103
+ /**
104
+ * Storage for values that get removed from it after being unused (not-requested
105
+ * for a specified amount of time).
106
+ *
107
+ * @internal
108
+ */
109
+ export declare class FactoryBasedTemporaryStorage<T> extends TemporaryStorage<T> {
110
+ readonly props: FactoryBasedTemporaryStorageProps<T>;
111
+ /**
112
+ * Constructor. Creates the storage using supplied params.
113
+ */
114
+ constructor(props: FactoryBasedTemporaryStorageProps<T>);
115
+ /**
116
+ * Get a value from the storage. If the value with the specified id
117
+ * doesn't exist, it gets created.
118
+ *
119
+ * **Note:** requesting a value with this method updates it's last used time.
120
+ */
121
+ getValue(id: string): T;
122
+ }
123
+ export {};
73
124
  //# sourceMappingURL=TemporaryStorage.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"TemporaryStorage.d.ts","sourceRoot":"","sources":["../../../src/presentation-backend/TemporaryStorage.ts"],"names":[],"mappings":"AAIA;;GAEG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAElD;;;GAGG;AACH,MAAM,WAAW,qBAAqB,CAAC,CAAC;IACtC,yEAAyE;IACzE,OAAO,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,CAAC,CAAC;IAE3B,8EAA8E;IAC9E,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;IAEpC,SAAS,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,WAAW,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;IACpE,gBAAgB,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAE3B;;;;;OAKG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAQD;;;;;GAKG;AACH,qBAAa,gBAAgB,CAAC,CAAC,CAAE,YAAW,WAAW;IAErD,OAAO,CAAC,OAAO,CAAiC;IAChD,OAAO,CAAC,MAAM,CAAC,CAAe;IAC9B,SAAgB,KAAK,EAAE,qBAAqB,CAAC,CAAC,CAAC,CAAC;IAEhD;;OAEG;gBACS,KAAK,EAAE,qBAAqB,CAAC,CAAC,CAAC;IAO3C;;;OAGG;IACI,OAAO;IAad;;;OAGG;IACI,qBAAqB,aAa1B;IAEF;;;;;;OAMG;IACI,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,CAAC;IAc9B;;;;;OAKG;IACH,IAAW,MAAM,IAAI,CAAC,EAAE,CAKvB;CAEF"}
1
+ {"version":3,"file":"TemporaryStorage.d.ts","sourceRoot":"","sources":["../../../src/presentation-backend/TemporaryStorage.ts"],"names":[],"mappings":"AAIA;;GAEG;AAEH,OAAO,EAAU,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAG1D;;;GAGG;AACH,MAAM,WAAW,qBAAqB,CAAC,CAAC;IACtC,8EAA8E;IAC9E,cAAc,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;IAEhD,gBAAgB,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAE3B;;;;;OAKG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB;;;;;;;;OAQG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAE7B;;;;;;;;OAQG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,qCAAqC;AACrC,UAAU,cAAc,CAAC,CAAC;IACxB,OAAO,EAAE,IAAI,CAAC;IACd,QAAQ,EAAE,IAAI,CAAC;IACf,KAAK,EAAE,CAAC,CAAC;CACV;AAED;;;;;GAKG;AACH,qBAAa,gBAAgB,CAAC,CAAC,CAAE,YAAW,WAAW;IAErD,OAAO,CAAC,MAAM,CAAC,CAAe;IAC9B,SAAS,CAAC,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC;IAClD,SAAgB,KAAK,EAAE,qBAAqB,CAAC,CAAC,CAAC,CAAC;IAEhD;;OAEG;gBACS,KAAK,EAAE,qBAAqB,CAAC,CAAC,CAAC;IAO3C;;;OAGG;IACI,OAAO;IAad;;;OAGG;IACI,qBAAqB,aAmB1B;IAEF,OAAO,CAAC,mBAAmB;IAO3B;;;;OAIG;IACI,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS;IASnC,eAAe,CAAC,EAAE,EAAE,MAAM;IAOjC;;;OAGG;IACI,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IAMpC,qCAAqC;IAC9B,WAAW,CAAC,EAAE,EAAE,MAAM;IAM7B;;;;;OAKG;IACH,IAAW,MAAM,IAAI,CAAC,EAAE,CAKvB;CAEF;AAED;;;GAGG;AACH,MAAM,WAAW,iCAAiC,CAAC,CAAC,CAAE,SAAQ,qBAAqB,CAAC,CAAC,CAAC;IACpF,yEAAyE;IACzE,OAAO,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,IAAI,KAAK,CAAC,CAAC;CACrD;AAED;;;;;GAKG;AACH,qBAAa,4BAA4B,CAAC,CAAC,CAAE,SAAQ,gBAAgB,CAAC,CAAC,CAAC;IAEtE,SAAyB,KAAK,EAAE,iCAAiC,CAAC,CAAC,CAAC,CAAC;IAErE;;OAEG;gBACS,KAAK,EAAE,iCAAiC,CAAC,CAAC,CAAC;IAKvD;;;;;OAKG;IACa,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,CAAC;CASxC"}
@@ -7,7 +7,9 @@
7
7
  * @module Core
8
8
  */
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
- exports.TemporaryStorage = void 0;
10
+ exports.FactoryBasedTemporaryStorage = exports.TemporaryStorage = void 0;
11
+ const core_bentley_1 = require("@itwin/core-bentley");
12
+ const presentation_common_1 = require("@itwin/presentation-common");
11
13
  /**
12
14
  * Storage for values that get removed from it after being unused (not-requested
13
15
  * for a specified amount of time).
@@ -21,21 +23,27 @@ class TemporaryStorage {
21
23
  constructor(props) {
22
24
  /**
23
25
  * Cleans up values that are currently outdated (based
24
- * on their lifetime specified through [[Props]]).
26
+ * on their max and unused value lifetimes specified through [[Props]]).
25
27
  */
26
28
  this.disposeOutdatedValues = () => {
27
29
  const now = (new Date()).getTime();
28
30
  const valuesToDispose = [];
29
- for (const entry of this._values.entries()) {
30
- if (!this.props.valueLifetime || ((now - entry["1"].lastUsed.getTime()) > this.props.valueLifetime))
31
- valuesToDispose.push(entry["0"]);
32
- }
33
- for (const id of valuesToDispose) {
34
- if (this.props.cleanupHandler)
35
- this.props.cleanupHandler(this._values.get(id).value);
36
- this._values.delete(id);
37
- this.props.onDisposedSingle && this.props.onDisposedSingle(id);
31
+ for (const [key, entry] of this._values.entries()) {
32
+ if (this.props.maxValueLifetime !== undefined) {
33
+ if (this.props.maxValueLifetime === 0 || (now - entry.created.getTime()) > this.props.maxValueLifetime) {
34
+ valuesToDispose.push(key);
35
+ continue;
36
+ }
37
+ }
38
+ if (this.props.unusedValueLifetime !== undefined) {
39
+ if (this.props.unusedValueLifetime === 0 || (now - entry.lastUsed.getTime()) > this.props.unusedValueLifetime) {
40
+ valuesToDispose.push(key);
41
+ continue;
42
+ }
43
+ }
38
44
  }
45
+ for (const id of valuesToDispose)
46
+ this.deleteExistingEntry(id);
39
47
  };
40
48
  this.props = props;
41
49
  this._values = new Map();
@@ -50,19 +58,23 @@ class TemporaryStorage {
50
58
  if (this._timer)
51
59
  clearInterval(this._timer);
52
60
  if (this.props.cleanupHandler) {
53
- this._values.forEach((v) => {
54
- this.props.cleanupHandler(v.value);
61
+ this._values.forEach((v, id) => {
62
+ this.props.cleanupHandler(id, v.value);
55
63
  });
56
64
  }
57
65
  this._values.clear();
58
66
  this.props.onDisposedAll && this.props.onDisposedAll();
59
67
  }
68
+ deleteExistingEntry(id) {
69
+ (0, core_bentley_1.assert)(this._values.has(id));
70
+ this.props.cleanupHandler && this.props.cleanupHandler(id, this._values.get(id).value);
71
+ this._values.delete(id);
72
+ this.props.onDisposedSingle && this.props.onDisposedSingle(id);
73
+ }
60
74
  /**
61
- * Get a value from the storage. If the value with the
62
- * specified id doesn't exist, it gets created.
75
+ * Get a value from the storage.
63
76
  *
64
- * **Note:** requesting a value with this method updates
65
- * it's last used time.
77
+ * **Note:** requesting a value with this method updates it's last used time.
66
78
  */
67
79
  getValue(id) {
68
80
  if (this._values.has(id)) {
@@ -70,11 +82,28 @@ class TemporaryStorage {
70
82
  v.lastUsed = new Date();
71
83
  return v.value;
72
84
  }
73
- const value = this.props.factory(id);
74
- const entry = { value, lastUsed: new Date() };
75
- this._values.set(id, entry);
76
- this.props.onCreated && this.props.onCreated(id, value, () => entry.lastUsed = new Date());
77
- return value;
85
+ return undefined;
86
+ }
87
+ notifyValueUsed(id) {
88
+ const entry = this._values.get(id);
89
+ // istanbul ignore else
90
+ if (entry)
91
+ entry.lastUsed = new Date();
92
+ }
93
+ /**
94
+ * Adds a value into the storage.
95
+ * @throws An error when trying to add a value with ID that's already stored in the storage.
96
+ */
97
+ addValue(id, value) {
98
+ if (this._values.has(id))
99
+ throw new presentation_common_1.PresentationError(presentation_common_1.PresentationStatus.InvalidArgument, `A value with given ID "${id}" already exists in this storage.`);
100
+ this._values.set(id, { value, created: new Date(), lastUsed: new Date() });
101
+ }
102
+ /** Deletes a value with given id. */
103
+ deleteValue(id) {
104
+ // istanbul ignore else
105
+ if (this._values.has(id))
106
+ this.deleteExistingEntry(id);
78
107
  }
79
108
  /**
80
109
  * Get all values currently in this storage.
@@ -90,4 +119,34 @@ class TemporaryStorage {
90
119
  }
91
120
  }
92
121
  exports.TemporaryStorage = TemporaryStorage;
122
+ /**
123
+ * Storage for values that get removed from it after being unused (not-requested
124
+ * for a specified amount of time).
125
+ *
126
+ * @internal
127
+ */
128
+ class FactoryBasedTemporaryStorage extends TemporaryStorage {
129
+ /**
130
+ * Constructor. Creates the storage using supplied params.
131
+ */
132
+ constructor(props) {
133
+ super(props);
134
+ this.props = props;
135
+ }
136
+ /**
137
+ * Get a value from the storage. If the value with the specified id
138
+ * doesn't exist, it gets created.
139
+ *
140
+ * **Note:** requesting a value with this method updates it's last used time.
141
+ */
142
+ getValue(id) {
143
+ const existingValue = super.getValue(id);
144
+ if (existingValue)
145
+ return existingValue;
146
+ const value = this.props.factory(id, () => this.notifyValueUsed(id));
147
+ this.addValue(id, value);
148
+ return value;
149
+ }
150
+ }
151
+ exports.FactoryBasedTemporaryStorage = FactoryBasedTemporaryStorage;
93
152
  //# sourceMappingURL=TemporaryStorage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"TemporaryStorage.js","sourceRoot":"","sources":["../../../src/presentation-backend/TemporaryStorage.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n/** @packageDocumentation\r\n * @module Core\r\n */\r\n\r\nimport { IDisposable } from \"@itwin/core-bentley\";\r\n\r\n/**\r\n * Configuration properties for [[TemporaryStorage]].\r\n * @internal\r\n */\r\nexport interface TemporaryStorageProps<T> {\r\n /** A factory method that creates a stored value given it's identifier */\r\n factory: (id: string) => T;\r\n\r\n /** A method that's called for every value before it's removed from storage */\r\n cleanupHandler?: (value: T) => void;\r\n\r\n onCreated?: (id: string, value: T, onValueUsed: () => void) => void;\r\n onDisposedSingle?: (id: string) => void;\r\n onDisposedAll?: () => void;\r\n\r\n /**\r\n * An interval at which the storage attempts to clean up its values.\r\n * When `0` or `undefined` is specified, values are not cleaned up\r\n * automatically and cleanup has to be initiated manually by calling\r\n * [[TemporaryStorage.disposeOutdatedValues]].\r\n */\r\n cleanupInterval?: number;\r\n\r\n /**\r\n * Shortest period of time which the value should be kept in storage\r\n * unused before it's cleaned up. `0` or `undefined` means values\r\n * are removed from the storage on every cleanup (either manual call to\r\n * [[TemporaryStorage.disposeOutdatedValues]] or scheduled (controlled\r\n * by [[cleanupInterval]]))\r\n */\r\n valueLifetime?: number;\r\n}\r\n\r\n/** Value with know last used time */\r\ninterface TemporaryValue<T> {\r\n lastUsed: Date;\r\n value: T;\r\n}\r\n\r\n/**\r\n * Storage for values that get removed from it after being unused (not-requested\r\n * for a specified amount of time).\r\n *\r\n * @internal\r\n */\r\nexport class TemporaryStorage<T> implements IDisposable {\r\n\r\n private _values: Map<string, TemporaryValue<T>>;\r\n private _timer?: NodeJS.Timer;\r\n public readonly props: TemporaryStorageProps<T>;\r\n\r\n /**\r\n * Constructor. Creates the storage using supplied params.\r\n */\r\n constructor(props: TemporaryStorageProps<T>) {\r\n this.props = props;\r\n this._values = new Map<string, TemporaryValue<T>>();\r\n if (this.props.cleanupInterval)\r\n this._timer = setInterval(this.disposeOutdatedValues, this.props.cleanupInterval);\r\n }\r\n\r\n /**\r\n * Destructor. Must be called to clean up the stored values\r\n * and other resources\r\n */\r\n public dispose() {\r\n if (this._timer)\r\n clearInterval(this._timer);\r\n\r\n if (this.props.cleanupHandler) {\r\n this._values.forEach((v) => {\r\n this.props.cleanupHandler!(v.value);\r\n });\r\n }\r\n this._values.clear();\r\n this.props.onDisposedAll && this.props.onDisposedAll();\r\n }\r\n\r\n /**\r\n * Cleans up values that are currently outdated (based\r\n * on their lifetime specified through [[Props]]).\r\n */\r\n public disposeOutdatedValues = () => {\r\n const now = (new Date()).getTime();\r\n const valuesToDispose: string[] = [];\r\n for (const entry of this._values.entries()) {\r\n if (!this.props.valueLifetime || ((now - entry[\"1\"].lastUsed.getTime()) > this.props.valueLifetime))\r\n valuesToDispose.push(entry[\"0\"]);\r\n }\r\n for (const id of valuesToDispose) {\r\n if (this.props.cleanupHandler)\r\n this.props.cleanupHandler(this._values.get(id)!.value);\r\n this._values.delete(id);\r\n this.props.onDisposedSingle && this.props.onDisposedSingle(id);\r\n }\r\n };\r\n\r\n /**\r\n * Get a value from the storage. If the value with the\r\n * specified id doesn't exist, it gets created.\r\n *\r\n * **Note:** requesting a value with this method updates\r\n * it's last used time.\r\n */\r\n public getValue(id: string): T {\r\n if (this._values.has(id)) {\r\n const v = this._values.get(id)!;\r\n v.lastUsed = new Date();\r\n return v.value;\r\n }\r\n\r\n const value = this.props.factory(id);\r\n const entry = { value, lastUsed: new Date() };\r\n this._values.set(id, entry);\r\n this.props.onCreated && this.props.onCreated(id, value, () => entry.lastUsed = new Date());\r\n return value;\r\n }\r\n\r\n /**\r\n * Get all values currently in this storage.\r\n *\r\n * **Note:** requesting values with this method **doesn't**\r\n * update their last used times.\r\n */\r\n public get values(): T[] {\r\n const values = new Array<T>();\r\n for (const v of this._values.values())\r\n values.push(v.value);\r\n return values;\r\n }\r\n\r\n}\r\n"]}
1
+ {"version":3,"file":"TemporaryStorage.js","sourceRoot":"","sources":["../../../src/presentation-backend/TemporaryStorage.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n/** @packageDocumentation\r\n * @module Core\r\n */\r\n\r\nimport { assert, IDisposable } from \"@itwin/core-bentley\";\r\nimport { PresentationError, PresentationStatus } from \"@itwin/presentation-common\";\r\n\r\n/**\r\n * Configuration properties for [[TemporaryStorage]].\r\n * @internal\r\n */\r\nexport interface TemporaryStorageProps<T> {\r\n /** A method that's called for every value before it's removed from storage */\r\n cleanupHandler?: (id: string, value: T) => void;\r\n\r\n onDisposedSingle?: (id: string) => void;\r\n onDisposedAll?: () => void;\r\n\r\n /**\r\n * An interval at which the storage attempts to clean up its values.\r\n * When `0` or `undefined` is specified, values are not cleaned up\r\n * automatically and cleanup has to be initiated manually by calling\r\n * [[TemporaryStorage.disposeOutdatedValues]].\r\n */\r\n cleanupInterval?: number;\r\n\r\n /**\r\n * Shortest period of time which the value should be kept in storage\r\n * unused before it's cleaned up.\r\n *\r\n * `undefined` means the values may be kept unused in the storage indefinitely.\r\n * `0` means the values are removed from the storage on every cleanup (either manual\r\n * call to [[TemporaryStorage.disposeOutdatedValues]] or scheduled (controlled\r\n * by [[cleanupInterval]])).\r\n */\r\n unusedValueLifetime?: number;\r\n\r\n /**\r\n * The maximum period of time which the value should be kept in storage\r\n * before it's cleaned up. The time is measured from the moment the value is added\r\n * to the storage.\r\n *\r\n * `undefined` means the values may be kept indefinitely. `0` means they're removed\r\n * up on every cleanup (either manual call to [[TemporaryStorage.disposeOutdatedValues]]\r\n * or scheduled (controlled by [[cleanupInterval]])).\r\n */\r\n maxValueLifetime?: number;\r\n}\r\n\r\n/** Value with know last used time */\r\ninterface TemporaryValue<T> {\r\n created: Date;\r\n lastUsed: Date;\r\n value: T;\r\n}\r\n\r\n/**\r\n * Storage for values that get removed from it after being unused (not-requested\r\n * for a specified amount of time).\r\n *\r\n * @internal\r\n */\r\nexport class TemporaryStorage<T> implements IDisposable {\r\n\r\n private _timer?: NodeJS.Timer;\r\n protected _values: Map<string, TemporaryValue<T>>;\r\n public readonly props: TemporaryStorageProps<T>;\r\n\r\n /**\r\n * Constructor. Creates the storage using supplied params.\r\n */\r\n constructor(props: TemporaryStorageProps<T>) {\r\n this.props = props;\r\n this._values = new Map<string, TemporaryValue<T>>();\r\n if (this.props.cleanupInterval)\r\n this._timer = setInterval(this.disposeOutdatedValues, this.props.cleanupInterval);\r\n }\r\n\r\n /**\r\n * Destructor. Must be called to clean up the stored values\r\n * and other resources\r\n */\r\n public dispose() {\r\n if (this._timer)\r\n clearInterval(this._timer);\r\n\r\n if (this.props.cleanupHandler) {\r\n this._values.forEach((v, id) => {\r\n this.props.cleanupHandler!(id, v.value);\r\n });\r\n }\r\n this._values.clear();\r\n this.props.onDisposedAll && this.props.onDisposedAll();\r\n }\r\n\r\n /**\r\n * Cleans up values that are currently outdated (based\r\n * on their max and unused value lifetimes specified through [[Props]]).\r\n */\r\n public disposeOutdatedValues = () => {\r\n const now = (new Date()).getTime();\r\n const valuesToDispose: string[] = [];\r\n for (const [key, entry] of this._values.entries()) {\r\n if (this.props.maxValueLifetime !== undefined) {\r\n if (this.props.maxValueLifetime === 0 || (now - entry.created.getTime()) > this.props.maxValueLifetime) {\r\n valuesToDispose.push(key);\r\n continue;\r\n }\r\n }\r\n if (this.props.unusedValueLifetime !== undefined) {\r\n if (this.props.unusedValueLifetime === 0 || (now - entry.lastUsed.getTime()) > this.props.unusedValueLifetime) {\r\n valuesToDispose.push(key);\r\n continue;\r\n }\r\n }\r\n }\r\n for (const id of valuesToDispose)\r\n this.deleteExistingEntry(id);\r\n };\r\n\r\n private deleteExistingEntry(id: string) {\r\n assert(this._values.has(id));\r\n this.props.cleanupHandler && this.props.cleanupHandler(id, this._values.get(id)!.value);\r\n this._values.delete(id);\r\n this.props.onDisposedSingle && this.props.onDisposedSingle(id);\r\n }\r\n\r\n /**\r\n * Get a value from the storage.\r\n *\r\n * **Note:** requesting a value with this method updates it's last used time.\r\n */\r\n public getValue(id: string): T | undefined {\r\n if (this._values.has(id)) {\r\n const v = this._values.get(id)!;\r\n v.lastUsed = new Date();\r\n return v.value;\r\n }\r\n return undefined;\r\n }\r\n\r\n public notifyValueUsed(id: string) {\r\n const entry = this._values.get(id);\r\n // istanbul ignore else\r\n if (entry)\r\n entry.lastUsed = new Date();\r\n }\r\n\r\n /**\r\n * Adds a value into the storage.\r\n * @throws An error when trying to add a value with ID that's already stored in the storage.\r\n */\r\n public addValue(id: string, value: T) {\r\n if (this._values.has(id))\r\n throw new PresentationError(PresentationStatus.InvalidArgument, `A value with given ID \"${id}\" already exists in this storage.`);\r\n this._values.set(id, { value, created: new Date(), lastUsed: new Date() });\r\n }\r\n\r\n /** Deletes a value with given id. */\r\n public deleteValue(id: string) {\r\n // istanbul ignore else\r\n if (this._values.has(id))\r\n this.deleteExistingEntry(id);\r\n }\r\n\r\n /**\r\n * Get all values currently in this storage.\r\n *\r\n * **Note:** requesting values with this method **doesn't**\r\n * update their last used times.\r\n */\r\n public get values(): T[] {\r\n const values = new Array<T>();\r\n for (const v of this._values.values())\r\n values.push(v.value);\r\n return values;\r\n }\r\n\r\n}\r\n\r\n/**\r\n * Configuration properties for [[FactoryBasedTemporaryStorage]].\r\n * @internal\r\n */\r\nexport interface FactoryBasedTemporaryStorageProps<T> extends TemporaryStorageProps<T> {\r\n /** A factory method that creates a stored value given it's identifier */\r\n factory: (id: string, onValueUsed: () => void) => T;\r\n}\r\n\r\n/**\r\n * Storage for values that get removed from it after being unused (not-requested\r\n * for a specified amount of time).\r\n *\r\n * @internal\r\n */\r\nexport class FactoryBasedTemporaryStorage<T> extends TemporaryStorage<T> {\r\n\r\n public override readonly props: FactoryBasedTemporaryStorageProps<T>;\r\n\r\n /**\r\n * Constructor. Creates the storage using supplied params.\r\n */\r\n constructor(props: FactoryBasedTemporaryStorageProps<T>) {\r\n super(props);\r\n this.props = props;\r\n }\r\n\r\n /**\r\n * Get a value from the storage. If the value with the specified id\r\n * doesn't exist, it gets created.\r\n *\r\n * **Note:** requesting a value with this method updates it's last used time.\r\n */\r\n public override getValue(id: string): T {\r\n const existingValue = super.getValue(id);\r\n if (existingValue)\r\n return existingValue;\r\n\r\n const value = this.props.factory(id, () => this.notifyValueUsed(id));\r\n this.addValue(id, value);\r\n return value;\r\n }\r\n}\r\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@itwin/presentation-backend",
3
- "version": "3.0.0-dev.166",
3
+ "version": "3.0.0-dev.170",
4
4
  "description": "Backend of iTwin.js Presentation library",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -22,20 +22,20 @@
22
22
  "main": "lib/cjs/presentation-backend.js",
23
23
  "typings": "lib/cjs/presentation-backend",
24
24
  "peerDependencies": {
25
- "@itwin/core-backend": "^3.0.0-dev.166",
26
- "@itwin/core-bentley": "^3.0.0-dev.166",
27
- "@itwin/core-common": "^3.0.0-dev.166",
28
- "@itwin/core-quantity": "^3.0.0-dev.166",
29
- "@itwin/presentation-common": "^3.0.0-dev.166"
25
+ "@itwin/core-backend": "^3.0.0-dev.170",
26
+ "@itwin/core-bentley": "^3.0.0-dev.170",
27
+ "@itwin/core-common": "^3.0.0-dev.170",
28
+ "@itwin/core-quantity": "^3.0.0-dev.170",
29
+ "@itwin/presentation-common": "^3.0.0-dev.170"
30
30
  },
31
31
  "devDependencies": {
32
- "@itwin/build-tools": "3.0.0-dev.166",
33
- "@itwin/core-backend": "3.0.0-dev.166",
34
- "@itwin/core-bentley": "3.0.0-dev.166",
35
- "@itwin/core-common": "3.0.0-dev.166",
36
- "@itwin/core-quantity": "3.0.0-dev.166",
37
- "@itwin/eslint-plugin": "3.0.0-dev.166",
38
- "@itwin/presentation-common": "3.0.0-dev.166",
32
+ "@itwin/build-tools": "3.0.0-dev.170",
33
+ "@itwin/core-backend": "3.0.0-dev.170",
34
+ "@itwin/core-bentley": "3.0.0-dev.170",
35
+ "@itwin/core-common": "3.0.0-dev.170",
36
+ "@itwin/core-quantity": "3.0.0-dev.170",
37
+ "@itwin/eslint-plugin": "3.0.0-dev.170",
38
+ "@itwin/presentation-common": "3.0.0-dev.170",
39
39
  "@types/chai": "^4.1.4",
40
40
  "@types/chai-as-promised": "^7",
41
41
  "@types/chai-jest-snapshot": "^1.3.0",