@itwin/presentation-backend 3.0.0-extension.0 → 3.1.0-dev.11

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.
Files changed (29) hide show
  1. package/CHANGELOG.md +76 -1
  2. package/LICENSE.md +1 -1
  3. package/lib/cjs/assets/supplemental-presentation-rules/BisCore.PresentationRuleSet.json +47 -50
  4. package/lib/cjs/presentation-backend/ElementPropertiesHelper.d.ts +2 -2
  5. package/lib/cjs/presentation-backend/ElementPropertiesHelper.d.ts.map +1 -1
  6. package/lib/cjs/presentation-backend/ElementPropertiesHelper.js +36 -17
  7. package/lib/cjs/presentation-backend/ElementPropertiesHelper.js.map +1 -1
  8. package/lib/cjs/presentation-backend/Presentation.d.ts +1 -1
  9. package/lib/cjs/presentation-backend/Presentation.d.ts.map +1 -1
  10. package/lib/cjs/presentation-backend/Presentation.js +24 -22
  11. package/lib/cjs/presentation-backend/Presentation.js.map +1 -1
  12. package/lib/cjs/presentation-backend/PresentationIpcHandler.d.ts.map +1 -1
  13. package/lib/cjs/presentation-backend/PresentationIpcHandler.js +2 -1
  14. package/lib/cjs/presentation-backend/PresentationIpcHandler.js.map +1 -1
  15. package/lib/cjs/presentation-backend/PresentationManager.d.ts +14 -3
  16. package/lib/cjs/presentation-backend/PresentationManager.d.ts.map +1 -1
  17. package/lib/cjs/presentation-backend/PresentationManager.js +39 -18
  18. package/lib/cjs/presentation-backend/PresentationManager.js.map +1 -1
  19. package/lib/cjs/presentation-backend/PresentationRpcImpl.d.ts +15 -8
  20. package/lib/cjs/presentation-backend/PresentationRpcImpl.d.ts.map +1 -1
  21. package/lib/cjs/presentation-backend/PresentationRpcImpl.js +112 -48
  22. package/lib/cjs/presentation-backend/PresentationRpcImpl.js.map +1 -1
  23. package/lib/cjs/presentation-backend/RulesetEmbedder.js +1 -1
  24. package/lib/cjs/presentation-backend/RulesetEmbedder.js.map +1 -1
  25. package/lib/cjs/presentation-backend/TemporaryStorage.d.ts +67 -16
  26. package/lib/cjs/presentation-backend/TemporaryStorage.d.ts.map +1 -1
  27. package/lib/cjs/presentation-backend/TemporaryStorage.js +81 -21
  28. package/lib/cjs/presentation-backend/TemporaryStorage.js.map +1 -1
  29. package/package.json +20 -18
@@ -7,14 +7,17 @@
7
7
  * @module RPC
8
8
  */
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
- exports.PresentationRpcImpl = exports.MAX_ALLOWED_PAGE_SIZE = void 0;
10
+ exports.PresentationRpcImpl = exports.MAX_ALLOWED_KEYS_PAGE_SIZE = exports.MAX_ALLOWED_PAGE_SIZE = void 0;
11
11
  const core_backend_1 = require("@itwin/core-backend");
12
12
  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;
19
+ /** @internal */
20
+ exports.MAX_ALLOWED_KEYS_PAGE_SIZE = 10000;
18
21
  /**
19
22
  * The backend implementation of PresentationRpcInterface. All it's basically
20
23
  * responsible for is forwarding calls to [[Presentation.manager]].
@@ -28,13 +31,25 @@ exports.MAX_ALLOWED_PAGE_SIZE = 1000;
28
31
  * @internal
29
32
  */
30
33
  class PresentationRpcImpl extends presentation_common_1.PresentationRpcInterface {
31
- constructor(_id) {
34
+ constructor(props) {
35
+ var _a;
32
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
+ });
33
48
  }
34
- /**
35
- * Get the maximum result waiting time.
36
- */
37
- get requestTimeout() { return Presentation_1.Presentation.getRequestTimeout(); }
49
+ dispose() {
50
+ this._pendingRequests.dispose();
51
+ }
52
+ get requestTimeout() { return this._requestTimeout; }
38
53
  /** Returns an ok response with result inside */
39
54
  successResponse(result, diagnostics) {
40
55
  return {
@@ -69,50 +84,79 @@ class PresentationRpcImpl extends presentation_common_1.PresentationRpcInterface
69
84
  return imodel;
70
85
  }
71
86
  async makeRequest(token, requestId, requestOptions, request) {
72
- core_bentley_1.Logger.logInfo(BackendLoggerCategory_1.PresentationBackendLoggerCategory.Rpc, `Received '${requestId}' request. Params: ${JSON.stringify(requestOptions)}`);
73
- let imodel;
74
- try {
75
- imodel = this.getIModel(token);
76
- }
77
- catch (e) {
78
- 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`);
79
92
  }
80
- const { clientId, diagnostics: diagnosticsOptions, rulesetVariables, ...options } = requestOptions; // eslint-disable-line @typescript-eslint/no-unused-vars
81
- const managerRequestOptions = {
82
- ...options,
83
- imodel,
84
- };
85
- // set up ruleset variables
86
- if (rulesetVariables)
87
- managerRequestOptions.rulesetVariables = rulesetVariables.map(presentation_common_1.RulesetVariable.fromJSON);
88
- // set up diagnostics listener
89
- let diagnosticLogs;
90
- if (diagnosticsOptions) {
91
- managerRequestOptions.diagnostics = {
92
- ...diagnosticsOptions,
93
- handler: (logs) => {
94
- // istanbul ignore else
95
- if (!diagnosticLogs)
96
- diagnosticLogs = [];
97
- diagnosticLogs.push(...logs);
98
- },
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,
99
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);
100
129
  }
101
- // initiate request
102
- const resultPromise = request(managerRequestOptions)
103
- .then((result) => this.successResponse(result, diagnosticLogs))
104
- .catch((e) => this.errorResponse(e.errorNumber, e.message, diagnosticLogs));
105
- 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
+ });
106
135
  return resultPromise;
136
+ }
107
137
  let timeout;
108
138
  const timeoutPromise = new Promise((_resolve, reject) => {
109
139
  timeout = setTimeout(() => {
110
140
  reject("Timed out");
111
- }, 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;
112
158
  });
113
- return Promise.race([resultPromise, timeoutPromise])
114
- .catch(() => this.errorResponse(presentation_common_1.PresentationStatus.BackendTimeout))
115
- .finally(() => clearTimeout(timeout));
159
+ /* eslint-enable @typescript-eslint/indent */
116
160
  }
117
161
  async getNodesCount(token, requestOptions) {
118
162
  return this.makeRequest(token, "getNodesCount", requestOptions, async (options) => {
@@ -204,9 +248,6 @@ class PresentationRpcImpl extends presentation_common_1.PresentationRpcInterface
204
248
  }
205
249
  async getElementProperties(token, requestOptions) {
206
250
  return this.makeRequest(token, "getElementProperties", { ...requestOptions }, async (options) => {
207
- if (!(0, presentation_common_1.isSingleElementPropertiesRequestOptions)(options)) {
208
- options = enforceValidPageSize(options);
209
- }
210
251
  return this.getManager(requestOptions.clientId).getElementProperties(options);
211
252
  });
212
253
  }
@@ -223,6 +264,29 @@ class PresentationRpcImpl extends presentation_common_1.PresentationRpcInterface
223
264
  };
224
265
  });
225
266
  }
267
+ async getContentInstanceKeys(token, requestOptions) {
268
+ return this.makeRequest(token, "getContentInstanceKeys", requestOptions, async (options) => {
269
+ const { displayType, ...optionsNoDisplayType } = options;
270
+ options = enforceValidPageSize({
271
+ ...optionsNoDisplayType,
272
+ keys: presentation_common_1.KeySet.fromJSON(optionsNoDisplayType.keys),
273
+ descriptor: {
274
+ displayType,
275
+ contentFlags: presentation_common_1.ContentFlags.KeysOnly,
276
+ },
277
+ }, exports.MAX_ALLOWED_KEYS_PAGE_SIZE);
278
+ const [size, content] = await Promise.all([
279
+ this.getManager(requestOptions.clientId).getContentSetSize(options),
280
+ this.getManager(requestOptions.clientId).getContent(options),
281
+ ]);
282
+ if (size === 0 || !content)
283
+ return { total: 0, items: new presentation_common_1.KeySet().toJSON() };
284
+ return {
285
+ total: size,
286
+ items: content.contentSet.reduce((keys, item) => keys.add(item.primaryKeys), new presentation_common_1.KeySet()).toJSON(),
287
+ };
288
+ });
289
+ }
226
290
  async getDisplayLabelDefinition(token, requestOptions) {
227
291
  return this.makeRequest(token, "getDisplayLabelDefinition", requestOptions, async (options) => {
228
292
  const label = await this.getManager(requestOptions.clientId).getDisplayLabelDefinition(options);
@@ -252,16 +316,16 @@ class PresentationRpcImpl extends presentation_common_1.PresentationRpcInterface
252
316
  }
253
317
  }
254
318
  exports.PresentationRpcImpl = PresentationRpcImpl;
255
- const enforceValidPageSize = (requestOptions) => {
319
+ const enforceValidPageSize = (requestOptions, maxPageSize = exports.MAX_ALLOWED_PAGE_SIZE) => {
256
320
  var _a;
257
- const validPageSize = getValidPageSize((_a = requestOptions.paging) === null || _a === void 0 ? void 0 : _a.size);
321
+ const validPageSize = getValidPageSize((_a = requestOptions.paging) === null || _a === void 0 ? void 0 : _a.size, maxPageSize);
258
322
  if (!requestOptions.paging || requestOptions.paging.size !== validPageSize)
259
323
  return { ...requestOptions, paging: { ...requestOptions.paging, size: validPageSize } };
260
324
  return requestOptions;
261
325
  };
262
- const getValidPageSize = (size) => {
326
+ const getValidPageSize = (size, maxPageSize) => {
263
327
  const requestedSize = size !== null && size !== void 0 ? size : 0;
264
- return (requestedSize === 0 || requestedSize > exports.MAX_ALLOWED_PAGE_SIZE) ? exports.MAX_ALLOWED_PAGE_SIZE : requestedSize;
328
+ return (requestedSize === 0 || requestedSize > maxPageSize) ? maxPageSize : requestedSize;
265
329
  };
266
330
  const nodeKeyFromJson = (json) => {
267
331
  if (!json)
@@ -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, ContentRpcRequestOptions, ContentSourcesRpcRequestOptions, ContentSourcesRpcResult, DescriptorJSON,\r\n DiagnosticsOptions, DiagnosticsScopeLogs, DisplayLabelRpcRequestOptions, DisplayLabelsRpcRequestOptions, DisplayValueGroup, DisplayValueGroupJSON,\r\n DistinctValuesRpcRequestOptions, ElementProperties, ElementPropertiesRpcRequestOptions, ElementPropertiesRpcResult,\r\n FilterByInstancePathsHierarchyRpcRequestOptions, FilterByTextHierarchyRpcRequestOptions, HierarchyRpcRequestOptions, InstanceKey, isSingleElementPropertiesRequestOptions, ItemJSON, KeySet,\r\n KeySetJSON, LabelDefinition, LabelDefinitionJSON, MultiElementPropertiesRpcRequestOptions, Node, NodeJSON, NodeKey, NodeKeyJSON, NodePathElement,\r\n NodePathElementJSON, Paged, PagedResponse, PageOptions, PresentationError, PresentationRpcInterface, PresentationRpcResponse, PresentationStatus,\r\n Ruleset, RulesetVariable, RulesetVariableJSON, SelectClassInfo, SelectionScope, SelectionScopeRpcRequestOptions,\r\n 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\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 public override async getElementProperties(token: IModelRpcProps, requestOptions: MultiElementPropertiesRpcRequestOptions): PresentationRpcResponse<PagedResponse<ElementProperties>>;\r\n public override async getElementProperties(token: IModelRpcProps, requestOptions: ElementPropertiesRpcRequestOptions): PresentationRpcResponse<ElementPropertiesRpcResult> {\r\n return this.makeRequest(token, \"getElementProperties\", { ...requestOptions }, async (options) => {\r\n if (!isSingleElementPropertiesRequestOptions(options)) {\r\n options = enforceValidPageSize(options);\r\n }\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 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): TOptions & { paging: PageOptions } => {\r\n const validPageSize = getValidPageSize(requestOptions.paging?.size);\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) => {\r\n const requestedSize = size ?? 0;\r\n return (requestedSize === 0 || requestedSize > MAX_ALLOWED_PAGE_SIZE) ? MAX_ALLOWED_PAGE_SIZE : 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"]}
@@ -67,7 +67,7 @@ class RulesetEmbedder {
67
67
  SELECT ECInstanceId, JsonProperties
68
68
  FROM ${RulesetElements.Ruleset.schema.name}.${RulesetElements.Ruleset.className}
69
69
  WHERE json_extract(JsonProperties, '$.jsonProperties.id') = :rulesetId`;
70
- for await (const row of this._imodel.query(query, core_common_1.QueryBinder.from({ rulesetId: ruleset.id }), core_common_1.QueryRowFormat.UseJsPropertyNames)) {
70
+ for await (const row of this._imodel.query(query, core_common_1.QueryBinder.from({ rulesetId: ruleset.id }), { rowFormat: core_common_1.QueryRowFormat.UseJsPropertyNames })) {
71
71
  const existingRulesetElementId = row.id;
72
72
  const existingRuleset = JSON.parse(row.jsonProperties).jsonProperties;
73
73
  rulesetsWithSameId.push({
@@ -1 +1 @@
1
- {"version":3,"file":"RulesetEmbedder.js","sourceRoot":"","sources":["../../../src/presentation-backend/RulesetEmbedder.ts"],"names":[],"mappings":";AAAA;;;+FAG+F;AAC/F;;GAEG;;;;;;;;;;;;;;;;;;;;;;AAEH,2CAA6B;AAC7B,mCAA6E;AAC7E,sDAE6B;AAC7B,sDAAmE;AACnE,oDAG4B;AAE5B,8EAAqE;AACrE,0EAA4D;AAC5D,mCAA2C;AAoE3C;;;GAGG;AACH,MAAa,eAAe;IAO1B;;OAEG;IACH,YAAmB,KAA2B;QAP7B,gBAAW,GAAG,IAAI,CAAC,IAAI,CAAC,6BAAc,CAAC,eAAe,EAAE,iDAAiD,CAAC,CAAC;QAC3G,sBAAiB,GAAG,mBAAmB,CAAC;QACxC,wBAAmB,GAAG,mBAAmB,CAAC;QAMzD,2CAAiB,CAAC,cAAc,EAAE,CAAC;QACnC,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC;IAC9B,CAAC;IAED;;;;;OAKG;IACI,KAAK,CAAC,aAAa,CAAC,OAAgB,EAAE,OAA8B;QACzE,MAAM,iBAAiB,GAAG,6BAA6B,CAAC,OAAO,CAAC,CAAC;QACjE,MAAM,cAAc,GAAG,IAAA,wBAAgB,EAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAEzD,oEAAoE;QACpE,MAAM,IAAI,CAAC,mCAAmC,EAAE,CAAC;QAEjD,qCAAqC;QACrC,MAAM,kBAAkB,GAInB,EAAE,CAAC;QACR,MAAM,KAAK,GAAG;;aAEL,eAAe,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,IAAI,eAAe,CAAC,OAAO,CAAC,SAAS;6EACR,CAAC;QAC1E,IAAI,KAAK,EAAE,MAAM,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,yBAAW,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,EAAE,CAAC,EAAE,4BAAc,CAAC,kBAAkB,CAAC,EAAE;YACjI,MAAM,wBAAwB,GAAe,GAAG,CAAC,EAAE,CAAC;YACpD,MAAM,eAAe,GAAY,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,cAAc,CAAC;YAC/E,kBAAkB,CAAC,IAAI,CAAC;gBACtB,EAAE,EAAE,wBAAwB;gBAC5B,OAAO,EAAE,eAAe;gBACxB,iBAAiB,EAAE,IAAA,wBAAgB,EAAC,eAAe,CAAC,OAAO,CAAC;aAC7D,CAAC,CAAC;SACJ;QAED,yCAAyC;QACzC,MAAM,UAAU,GAAG,iBAAiB,CAAC,IAAI,KAAK,SAAS,IAAI,kBAAkB,CAAC,MAAM,GAAG,CAAC;eACnF,iBAAiB,CAAC,IAAI,KAAK,wBAAwB,IAAI,kBAAkB,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,iBAAiB,KAAK,cAAc,CAAC;eACrI,iBAAiB,CAAC,IAAI,KAAK,yBAAyB,IAAI,kBAAkB,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAA,YAAU,EAAC,KAAK,CAAC,iBAAiB,EAAE,cAAc,CAAC,CAAC,CAAC;QACrJ,IAAI,UAAU,EAAE;YACd,2FAA2F;YAC3F,MAAM,8BAA8B,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE;gBACjF,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,IAAI,IAAA,WAAS,EAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC;oBAC9G,OAAO,IAAI,CAAC;gBACd,OAAO,OAAO,CAAC;YACjB,CAAC,EAAE,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAC;YAC1B,OAAO,8BAA8B,CAAC,EAAE,CAAC;SAC1C;QAED,yCAAyC;QACzC,MAAM,gBAAgB,GAAiB,EAAE,CAAC;QAC1C,MAAM,YAAY,GAAG,CAAC,CAAU,EAAE,iBAAyB,EAAW,EAAE;YACtE,QAAQ,iBAAiB,CAAC,eAAe,EAAE;gBACzC,KAAK,KAAK;oBACR,OAAO,iBAAiB,KAAK,cAAc,CAAC;gBAC9C,KAAK,WAAW;oBACd,OAAO,iBAAiB,KAAK,cAAc,IAAI,IAAA,WAAS,EAAC,iBAAiB,EAAE,cAAc,CAAC,CAAC;aAC/F;YACD,OAAO,KAAK,CAAC;QACf,CAAC,CAAC;QACF,kBAAkB,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;YACnC,IAAI,YAAY,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,iBAAiB,CAAC;gBACtD,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACpC,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,gBAAgB,CAAC,CAAC;QAEtD,qDAAqD;QACrD,MAAM,UAAU,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,iBAAiB,KAAK,cAAc,CAAC,CAAC;QAChG,IAAI,UAAU,KAAK,SAAS,EAAE;YAC5B,OAAO,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,EAAE,EAAE,OAAO,EAAE,iBAAiB,CAAC,cAAc,CAAC,CAAC;SACrF;QAED,sDAAsD;QACtD,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,uBAAuB,CAAC,iBAAiB,CAAC,cAAc,CAAC,CAAC;QACnF,MAAM,WAAW,GAAG,eAAe,CAAC,OAAO,CAAC,iBAAiB,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;QAC/F,OAAO,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,iBAAiB,CAAC,cAAc,CAAC,CAAC;IAC9F,CAAC;IAEO,KAAK,CAAC,aAAa,CAAC,SAAqB,EAAE,OAAgB,EAAE,SAA2B;QAC9F,MAAM,sBAAsB,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAoB,SAAS,CAAC,CAAC;QACjG,IAAA,qBAAM,EAAC,sBAAsB,KAAK,SAAS,CAAC,CAAC;QAC7C,sBAAsB,CAAC,cAAc,CAAC,cAAc,GAAG,OAAO,CAAC;QAE/D,MAAM,IAAI,CAAC,aAAa,CAAC,sBAAsB,EAAE,SAAS,CAAC,CAAC;QAE5D,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;QAC3B,OAAO,sBAAsB,CAAC,EAAE,CAAC;IACnC,CAAC;IAEO,KAAK,CAAC,gBAAgB,CAAC,OAAgB,EAAE,KAAY,EAAE,WAAiB,EAAE,SAA2B;QAC3G,MAAM,KAAK,GAA2B;YACpC,KAAK,EAAE,KAAK,CAAC,EAAE;YACf,IAAI,EAAE,WAAW;YACjB,aAAa,EAAE,eAAe,CAAC,OAAO,CAAC,aAAa;YACpD,cAAc,EAAE,EAAE,cAAc,EAAE,OAAO,EAAE;SAC5C,CAAC;QAEF,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;QAC3D,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;QAC3B,OAAO,OAAO,CAAC,EAAE,CAAC;IACpB,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,WAAW;QACtB,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,eAAe,CAAC,OAAO,CAAC,aAAa,CAAC;YACpE,OAAO,EAAE,CAAC;QAEZ,MAAM,WAAW,GAAc,EAAE,CAAC;QAClC,IAAI,CAAC,OAAO,CAAC,qBAAqB,CAAC,kCAAkC,eAAe,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,SAAyB,EAAE,EAAE;YAC1I,OAAO,uBAAQ,CAAC,aAAa,KAAK,SAAS,CAAC,IAAI,EAAE,EAAE;gBAClD,MAAM,GAAG,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC;gBAC/B,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;gBACxE,MAAM,OAAO,GAAG,cAAc,CAAC,cAAc,CAAC,cAAc,CAAC;gBAC7D,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;aAC3B;QACH,CAAC,CAAC,CAAC;QACH,OAAO,WAAW,CAAC;IACrB,CAAC;IAEO,KAAK,CAAC,uBAAuB,CAAC,SAA2B;QAC/D,MAAM,YAAY,GAAG,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAC9C,IAAI,SAAS,KAAK,YAAY;YAC5B,OAAO,YAAY,CAAC;QAEtB,MAAM,cAAc,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;QAC3D,MAAM,mBAAmB,GAAG,MAAM,IAAI,CAAC,yBAAyB,CAAC,cAAc,EAAE,SAAS,CAAC,CAAC;QAC5F,OAAO,IAAI,CAAC,qBAAqB,CAAC,mBAAmB,EAAE,SAAS,CAAC,CAAC;IACpE,CAAC;IAEO,iBAAiB;QACvB,MAAM,mBAAmB,GAAG,IAAI,CAAC,wBAAwB,EAAE,CAAC;QAC5D,IAAI,SAAS,KAAK,mBAAmB;YACnC,OAAO,SAAS,CAAC;QAEnB,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,mBAAmB,CAAC,EAAE,CAAC,CAAC;IACjE,CAAC;IAEO,wBAAwB;QAC9B,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QACpC,IAAI,SAAS,KAAK,OAAO;YACvB,OAAO,SAAS,CAAC;QAEnB,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAsB,kCAAmB,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC;IACpJ,CAAC;IAEO,YAAY;QAClB,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,cAAc,EAAE,CAAC;QACpD,MAAM,QAAQ,GAAa,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,SAAS,CAAC,yBAAW,CAAC,OAAO,CAAC,CAAC;QACjF,MAAM,IAAI,GAAG,IAAI,kBAAI,CAAC;YACpB,IAAI,EAAE,QAAQ,CAAC,EAAE;YACjB,KAAK,EAAE,IAAI,CAAC,EAAE;YACd,KAAK,EAAE,IAAI,CAAC,mBAAmB;SAChC,CAAC,CAAC;QAEH,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAsB,IAAI,CAAC,CAAC;IACxE,CAAC;IAEO,KAAK,CAAC,qBAAqB,CAAC,mBAAwC,EAAE,SAA2B;QACvG,MAAM,UAAU,GAAe;YAC7B,cAAc,EAAE,mBAAmB;YACnC,IAAI,EAAE,IAAI,CAAC,iBAAiB;YAC5B,aAAa,EAAE,8BAAe,CAAC,aAAa;YAC5C,SAAS,EAAE,IAAI;SAChB,CAAC;QAEF,OAAO,IAAI,CAAC,WAAW,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;IACjD,CAAC;IAEO,KAAK,CAAC,yBAAyB,CAAC,cAAuB,EAAE,SAA2B;QAC1F,MAAM,aAAa,GAAG,kCAAmB,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,EAAE,cAAc,CAAC,EAAE,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAC9G,MAAM,wBAAwB,GAAqC;YACjE,MAAM,EAAE;gBACN,EAAE,EAAE,cAAc,CAAC,EAAE;gBACrB,YAAY,EAAE,sCAAsC;aACrD;YACD,KAAK,EAAE,cAAc,CAAC,KAAK;YAC3B,IAAI,EAAE,aAAa;YACnB,aAAa,EAAE,kCAAmB,CAAC,aAAa;SACjD,CAAC;QAEF,OAAO,IAAI,CAAC,aAAa,CAAC,wBAAwB,EAAE,SAAS,CAAC,CAAC;IACjE,CAAC;IAEO,KAAK,CAAC,aAAa,CAAC,SAA2B;QACrD,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,cAAc,EAAE,CAAC;QACpD,MAAM,QAAQ,GAAa,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,SAAS,CAAC,yBAAW,CAAC,OAAO,CAAC,CAAC;QACjF,MAAM,WAAW,GAAG,IAAI,kBAAI,CAAC;YAC3B,IAAI,EAAE,QAAQ,CAAC,EAAE;YACjB,KAAK,EAAE,IAAI,CAAC,EAAE;YACd,KAAK,EAAE,IAAI,CAAC,mBAAmB;SAChC,CAAC,CAAC;QACH,MAAM,YAAY,GAAiB;YACjC,aAAa,EAAE,sBAAO,CAAC,aAAa;YACpC,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,MAAM,EAAE;gBACN,EAAE,EAAE,IAAI,CAAC,EAAE;gBACX,YAAY,EAAE,6BAA6B;aAC5C;YACD,IAAI,EAAE,WAAW;SAClB,CAAC;QAEF,OAAO,IAAI,CAAC,aAAa,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC;IACrD,CAAC;IAEO,KAAK,CAAC,mCAAmC;QAC/C,IAAI,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,eAAe,CAAC,OAAO,CAAC,aAAa,CAAC;YACnE,OAAO;QAET,oCAAoC;QACpC,MAAM,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;QAErD,uCAAuC;QACvC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,sBAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,2CAAiB,CAAC,QAAQ,CAAC,OAAO,EAAE,2BAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QAE3H,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;IAC7B,CAAC;IAEO,KAAK,CAAC,aAAa,CAA8B,KAAa,EAAE,SAA2B;QACjG,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAC3D,uBAAuB;QACvB,MAAM,CAAA,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,cAAc,CAAC,OAAO,CAAC,CAAA,CAAC;QACzC,IAAI;YACF,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;SAC3D;gBAAS;YACR,uBAAuB;YACvB,MAAM,CAAA,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,aAAa,CAAC,OAAO,CAAC,CAAA,CAAC;SACzC;IACH,CAAC;IAEO,KAAK,CAAC,WAAW,CAAC,KAAiB,EAAE,SAA2B;QACtE,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QACrD,uBAAuB;QACvB,MAAM,CAAA,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,cAAc,CAAC,KAAK,CAAC,CAAA,CAAC;QACvC,IAAI;YACF,KAAK,CAAC,EAAE,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;YAC1B,OAAO,KAAK,CAAC;SACd;gBAAS;YACR,uBAAuB;YACvB,MAAM,CAAA,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,aAAa,CAAC,KAAK,CAAC,CAAA,CAAC;SACvC;IACH,CAAC;IAEO,KAAK,CAAC,aAAa,CAAC,OAAgB,EAAE,SAA2B;QACvE,uBAAuB;QACvB,MAAM,CAAA,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,cAAc,CAAC,OAAO,CAAC,CAAA,CAAC;QACzC,IAAI;YACF,OAAO,CAAC,MAAM,EAAE,CAAC;SAClB;gBAAS;YACR,uBAAuB;YACvB,MAAM,CAAA,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,aAAa,CAAC,OAAO,CAAC,CAAA,CAAC;SACzC;IACH,CAAC;CACF;AA3QD,0CA2QC;AAED,SAAS,6BAA6B,CAAC,OAA8B;;IACnE,IAAI,OAAO,KAAK,SAAS;QACvB,OAAO,EAAE,IAAI,EAAE,wBAAwB,EAAE,eAAe,EAAE,OAAO,EAAE,CAAC;IAEtE,OAAO;QACL,IAAI,EAAE,MAAA,OAAO,CAAC,IAAI,mCAAI,wBAAwB;QAC9C,eAAe,EAAE,MAAA,OAAO,CAAC,eAAe,mCAAI,OAAO;QACnD,cAAc,EAAE,OAAO,CAAC,cAAc;QACtC,cAAc,EAAE,OAAO,CAAC,cAAc;KACvC,CAAC;AACJ,CAAC","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 * as path from \"path\";\r\nimport { gt as versionGt, gte as versionGte, lt as versionLt } from \"semver\";\r\nimport {\r\n DefinitionElement, DefinitionModel, DefinitionPartition, ECSqlStatement, Element, Entity, IModelDb, KnownLocations, Model, Subject,\r\n} from \"@itwin/core-backend\";\r\nimport { assert, DbResult, Id64String } from \"@itwin/core-bentley\";\r\nimport {\r\n BisCodeSpec, Code, CodeScopeSpec, CodeSpec, DefinitionElementProps, ElementProps, InformationPartitionElementProps, ModelProps, QueryBinder,\r\n QueryRowFormat, SubjectProps,\r\n} from \"@itwin/core-common\";\r\nimport { Ruleset } from \"@itwin/presentation-common\";\r\nimport { PresentationRules } from \"./domain/PresentationRulesDomain\";\r\nimport * as RulesetElements from \"./domain/RulesetElements\";\r\nimport { normalizeVersion } from \"./Utils\";\r\n\r\n/**\r\n * Interface for callbacks which will be called before and after Element/Model updates\r\n * @beta\r\n */\r\ninterface UpdateCallbacks {\r\n onBeforeUpdate: (props: Entity) => Promise<void>;\r\n onAfterUpdate: (props: Entity) => Promise<void>;\r\n}\r\n\r\n/**\r\n * Interface for callbacks which will be called before and after Element/Model is inserted\r\n * @beta\r\n */\r\ninterface InsertCallbacks {\r\n onBeforeInsert: (props: Entity) => Promise<void>;\r\n onAfterInsert: (props: Entity) => Promise<void>;\r\n}\r\n\r\n/**\r\n * Options for [[RulesetEmbedder.insertRuleset]] operation.\r\n * @beta\r\n */\r\nexport interface RulesetInsertOptions {\r\n /**\r\n * When should insertion be skipped:\r\n * - `same-id` - if iModel already contains a ruleset with the same id and **any** version\r\n * - `same-id-and-version-eq` - if iModel already contains a ruleset with same id and version\r\n * - `same-id-and-version-gte` - if iModel already contains a ruleset with same id and\r\n * version greater or equal to version of the inserted ruleset.\r\n *\r\n * Defaults to `same-id-and-version-eq`.\r\n */\r\n skip?: \"never\" | \"same-id\" | \"same-id-and-version-eq\" | \"same-id-and-version-gte\";\r\n\r\n /**\r\n * Which existing versions of rulesets with same id should be replaced when we insert a new one:\r\n * - `all` - replace all rulesets with same id.\r\n * - `all-lower` - replace rulesets with same id and version lower than the version of inserted ruleset.\r\n * - `exact` - replace only the ruleset whose id and version matches the inserted ruleset.\r\n *\r\n * Defaults to `exact`.\r\n */\r\n replaceVersions?: \"all\" | \"all-lower\" | \"exact\";\r\n\r\n /**\r\n * Callbacks that will be called before and after `Entity` updates\r\n * @beta\r\n */\r\n onEntityUpdate?: UpdateCallbacks;\r\n\r\n /**\r\n * Callbacks that will be called before and after `Entity` is inserted\r\n * @beta\r\n */\r\n onEntityInsert?: InsertCallbacks;\r\n}\r\n\r\n/**\r\n * Properties for creating a `RulesetEmbedder` instance.\r\n * @public\r\n */\r\nexport interface RulesetEmbedderProps {\r\n /** iModel to embed rulesets to */\r\n imodel: IModelDb;\r\n}\r\n\r\n/**\r\n * An API for embedding presentation rulesets into iModels.\r\n * @beta\r\n */\r\nexport class RulesetEmbedder {\r\n\r\n private _imodel: IModelDb;\r\n private readonly _schemaPath = path.join(KnownLocations.nativeAssetsDir, \"ECSchemas/Domain/PresentationRules.ecschema.xml\");\r\n private readonly _rulesetModelName = \"PresentationRules\";\r\n private readonly _rulesetSubjectName = \"PresentationRules\";\r\n\r\n /**\r\n * Constructs RulesetEmbedder\r\n */\r\n public constructor(props: RulesetEmbedderProps) {\r\n PresentationRules.registerSchema();\r\n this._imodel = props.imodel;\r\n }\r\n\r\n /**\r\n * Inserts a ruleset into iModel.\r\n * @param ruleset Ruleset to insert.\r\n * @param options Options for inserting a ruleset.\r\n * @returns ID of inserted ruleset element or, if insertion was skipped, ID of existing ruleset with the same ID and highest version.\r\n */\r\n public async insertRuleset(ruleset: Ruleset, options?: RulesetInsertOptions): Promise<Id64String> {\r\n const normalizedOptions = normalizeRulesetInsertOptions(options);\r\n const rulesetVersion = normalizeVersion(ruleset.version);\r\n\r\n // ensure imodel has PresentationRules schema and required CodeSpecs\r\n await this.handleElementOperationPrerequisites();\r\n\r\n // find all rulesets with the same ID\r\n const rulesetsWithSameId: Array<{\r\n ruleset: Ruleset;\r\n id: Id64String;\r\n normalizedVersion: string;\r\n }> = [];\r\n const query = `\r\n SELECT ECInstanceId, JsonProperties\r\n FROM ${RulesetElements.Ruleset.schema.name}.${RulesetElements.Ruleset.className}\r\n WHERE json_extract(JsonProperties, '$.jsonProperties.id') = :rulesetId`;\r\n for await (const row of this._imodel.query(query, QueryBinder.from({ rulesetId: ruleset.id }), QueryRowFormat.UseJsPropertyNames)) {\r\n const existingRulesetElementId: Id64String = row.id;\r\n const existingRuleset: Ruleset = JSON.parse(row.jsonProperties).jsonProperties;\r\n rulesetsWithSameId.push({\r\n id: existingRulesetElementId,\r\n ruleset: existingRuleset,\r\n normalizedVersion: normalizeVersion(existingRuleset.version),\r\n });\r\n }\r\n\r\n // check if we need to do anything at all\r\n const shouldSkip = normalizedOptions.skip === \"same-id\" && rulesetsWithSameId.length > 0\r\n || normalizedOptions.skip === \"same-id-and-version-eq\" && rulesetsWithSameId.some((entry) => entry.normalizedVersion === rulesetVersion)\r\n || normalizedOptions.skip === \"same-id-and-version-gte\" && rulesetsWithSameId.some((entry) => versionGte(entry.normalizedVersion, rulesetVersion));\r\n if (shouldSkip) {\r\n // we're not inserting anything - return ID of the ruleset element with the highest version\r\n const rulesetEntryWithHighestVersion = rulesetsWithSameId.reduce((highest, curr) => {\r\n if (!highest.ruleset.version || curr.ruleset.version && versionGt(curr.ruleset.version, highest.ruleset.version))\r\n return curr;\r\n return highest;\r\n }, rulesetsWithSameId[0]);\r\n return rulesetEntryWithHighestVersion.id;\r\n }\r\n\r\n // if requested, delete existing rulesets\r\n const rulesetsToRemove: Id64String[] = [];\r\n const shouldRemove = (_: Ruleset, normalizedVersion: string): boolean => {\r\n switch (normalizedOptions.replaceVersions) {\r\n case \"all\":\r\n return normalizedVersion !== rulesetVersion;\r\n case \"all-lower\":\r\n return normalizedVersion !== rulesetVersion && versionLt(normalizedVersion, rulesetVersion);\r\n }\r\n return false;\r\n };\r\n rulesetsWithSameId.forEach((entry) => {\r\n if (shouldRemove(entry.ruleset, entry.normalizedVersion))\r\n rulesetsToRemove.push(entry.id);\r\n });\r\n this._imodel.elements.deleteElement(rulesetsToRemove);\r\n\r\n // attempt to update ruleset with same ID and version\r\n const exactMatch = rulesetsWithSameId.find((curr) => curr.normalizedVersion === rulesetVersion);\r\n if (exactMatch !== undefined) {\r\n return this.updateRuleset(exactMatch.id, ruleset, normalizedOptions.onEntityUpdate);\r\n }\r\n\r\n // no exact match found - insert a new ruleset element\r\n const model = await this.getOrCreateRulesetModel(normalizedOptions.onEntityInsert);\r\n const rulesetCode = RulesetElements.Ruleset.createRulesetCode(this._imodel, model.id, ruleset);\r\n return this.insertNewRuleset(ruleset, model, rulesetCode, normalizedOptions.onEntityInsert);\r\n }\r\n\r\n private async updateRuleset(elementId: Id64String, ruleset: Ruleset, callbacks?: UpdateCallbacks) {\r\n const existingRulesetElement = this._imodel.elements.tryGetElement<DefinitionElement>(elementId);\r\n assert(existingRulesetElement !== undefined);\r\n existingRulesetElement.jsonProperties.jsonProperties = ruleset;\r\n\r\n await this.updateElement(existingRulesetElement, callbacks);\r\n\r\n this._imodel.saveChanges();\r\n return existingRulesetElement.id;\r\n }\r\n\r\n private async insertNewRuleset(ruleset: Ruleset, model: Model, rulesetCode: Code, callbacks?: InsertCallbacks): Promise<Id64String> {\r\n const props: DefinitionElementProps = {\r\n model: model.id,\r\n code: rulesetCode,\r\n classFullName: RulesetElements.Ruleset.classFullName,\r\n jsonProperties: { jsonProperties: ruleset },\r\n };\r\n\r\n const element = await this.insertElement(props, callbacks);\r\n this._imodel.saveChanges();\r\n return element.id;\r\n }\r\n\r\n /**\r\n * Get all rulesets embedded in the iModel.\r\n */\r\n public async getRulesets(): Promise<Ruleset[]> {\r\n if (!this._imodel.containsClass(RulesetElements.Ruleset.classFullName))\r\n return [];\r\n\r\n const rulesetList: Ruleset[] = [];\r\n this._imodel.withPreparedStatement(`SELECT ECInstanceId AS id FROM ${RulesetElements.Ruleset.classFullName}`, (statement: ECSqlStatement) => {\r\n while (DbResult.BE_SQLITE_ROW === statement.step()) {\r\n const row = statement.getRow();\r\n const rulesetElement = this._imodel.elements.getElement({ id: row.id });\r\n const ruleset = rulesetElement.jsonProperties.jsonProperties;\r\n rulesetList.push(ruleset);\r\n }\r\n });\r\n return rulesetList;\r\n }\r\n\r\n private async getOrCreateRulesetModel(callbacks?: InsertCallbacks): Promise<DefinitionModel> {\r\n const rulesetModel = this.queryRulesetModel();\r\n if (undefined !== rulesetModel)\r\n return rulesetModel;\r\n\r\n const rulesetSubject = await this.insertSubject(callbacks);\r\n const definitionPartition = await this.insertDefinitionPartition(rulesetSubject, callbacks);\r\n return this.insertDefinitionModel(definitionPartition, callbacks);\r\n }\r\n\r\n private queryRulesetModel(): DefinitionModel | undefined {\r\n const definitionPartition = this.queryDefinitionPartition();\r\n if (undefined === definitionPartition)\r\n return undefined;\r\n\r\n return this._imodel.models.getSubModel(definitionPartition.id);\r\n }\r\n\r\n private queryDefinitionPartition(): DefinitionPartition | undefined {\r\n const subject = this.querySubject();\r\n if (undefined === subject)\r\n return undefined;\r\n\r\n return this._imodel.elements.tryGetElement<DefinitionPartition>(DefinitionPartition.createCode(this._imodel, subject.id, this._rulesetModelName));\r\n }\r\n\r\n private querySubject(): DefinitionPartition | undefined {\r\n const root = this._imodel.elements.getRootSubject();\r\n const codeSpec: CodeSpec = this._imodel.codeSpecs.getByName(BisCodeSpec.subject);\r\n const code = new Code({\r\n spec: codeSpec.id,\r\n scope: root.id,\r\n value: this._rulesetSubjectName,\r\n });\r\n\r\n return this._imodel.elements.tryGetElement<DefinitionPartition>(code);\r\n }\r\n\r\n private async insertDefinitionModel(definitionPartition: DefinitionPartition, callbacks?: InsertCallbacks): Promise<DefinitionModel> {\r\n const modelProps: ModelProps = {\r\n modeledElement: definitionPartition,\r\n name: this._rulesetModelName,\r\n classFullName: DefinitionModel.classFullName,\r\n isPrivate: true,\r\n };\r\n\r\n return this.insertModel(modelProps, callbacks);\r\n }\r\n\r\n private async insertDefinitionPartition(rulesetSubject: Subject, callbacks?: InsertCallbacks): Promise<DefinitionPartition> {\r\n const partitionCode = DefinitionPartition.createCode(this._imodel, rulesetSubject.id, this._rulesetModelName);\r\n const definitionPartitionProps: InformationPartitionElementProps = {\r\n parent: {\r\n id: rulesetSubject.id,\r\n relClassName: \"BisCore:SubjectOwnsPartitionElements\",\r\n },\r\n model: rulesetSubject.model,\r\n code: partitionCode,\r\n classFullName: DefinitionPartition.classFullName,\r\n };\r\n\r\n return this.insertElement(definitionPartitionProps, callbacks);\r\n }\r\n\r\n private async insertSubject(callbacks?: InsertCallbacks): Promise<Subject> {\r\n const root = this._imodel.elements.getRootSubject();\r\n const codeSpec: CodeSpec = this._imodel.codeSpecs.getByName(BisCodeSpec.subject);\r\n const subjectCode = new Code({\r\n spec: codeSpec.id,\r\n scope: root.id,\r\n value: this._rulesetSubjectName,\r\n });\r\n const subjectProps: SubjectProps = {\r\n classFullName: Subject.classFullName,\r\n model: root.model,\r\n parent: {\r\n id: root.id,\r\n relClassName: \"BisCore:SubjectOwnsSubjects\",\r\n },\r\n code: subjectCode,\r\n };\r\n\r\n return this.insertElement(subjectProps, callbacks);\r\n }\r\n\r\n private async handleElementOperationPrerequisites(): Promise<void> {\r\n if (this._imodel.containsClass(RulesetElements.Ruleset.classFullName))\r\n return;\r\n\r\n // import PresentationRules ECSchema\r\n await this._imodel.importSchemas([this._schemaPath]);\r\n\r\n // insert CodeSpec for ruleset elements\r\n this._imodel.codeSpecs.insert(CodeSpec.create(this._imodel, PresentationRules.CodeSpec.Ruleset, CodeScopeSpec.Type.Model));\r\n\r\n this._imodel.saveChanges();\r\n }\r\n\r\n private async insertElement<TProps extends ElementProps>(props: TProps, callbacks?: InsertCallbacks): Promise<Element> {\r\n const element = this._imodel.elements.createElement(props);\r\n // istanbul ignore next\r\n await callbacks?.onBeforeInsert(element);\r\n try {\r\n return this._imodel.elements.getElement(element.insert());\r\n } finally {\r\n // istanbul ignore next\r\n await callbacks?.onAfterInsert(element);\r\n }\r\n }\r\n\r\n private async insertModel(props: ModelProps, callbacks?: InsertCallbacks): Promise<Model> {\r\n const model = this._imodel.models.createModel(props);\r\n // istanbul ignore next\r\n await callbacks?.onBeforeInsert(model);\r\n try {\r\n model.id = model.insert();\r\n return model;\r\n } finally {\r\n // istanbul ignore next\r\n await callbacks?.onAfterInsert(model);\r\n }\r\n }\r\n\r\n private async updateElement(element: Element, callbacks?: UpdateCallbacks) {\r\n // istanbul ignore next\r\n await callbacks?.onBeforeUpdate(element);\r\n try {\r\n element.update();\r\n } finally {\r\n // istanbul ignore next\r\n await callbacks?.onAfterUpdate(element);\r\n }\r\n }\r\n}\r\n\r\nfunction normalizeRulesetInsertOptions(options?: RulesetInsertOptions): RulesetInsertOptions {\r\n if (options === undefined)\r\n return { skip: \"same-id-and-version-eq\", replaceVersions: \"exact\" };\r\n\r\n return {\r\n skip: options.skip ?? \"same-id-and-version-eq\",\r\n replaceVersions: options.replaceVersions ?? \"exact\",\r\n onEntityUpdate: options.onEntityUpdate,\r\n onEntityInsert: options.onEntityInsert,\r\n };\r\n}\r\n"]}
1
+ {"version":3,"file":"RulesetEmbedder.js","sourceRoot":"","sources":["../../../src/presentation-backend/RulesetEmbedder.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 * as path from \"path\";\r\nimport { gt as versionGt, gte as versionGte, lt as versionLt } from \"semver\";\r\nimport {\r\n DefinitionElement, DefinitionModel, DefinitionPartition, ECSqlStatement, Element, Entity, IModelDb, KnownLocations, Model, Subject,\r\n} from \"@itwin/core-backend\";\r\nimport { assert, DbResult, Id64String } from \"@itwin/core-bentley\";\r\nimport {\r\n BisCodeSpec, Code, CodeScopeSpec, CodeSpec, DefinitionElementProps, ElementProps, InformationPartitionElementProps, ModelProps, QueryBinder,\r\n QueryRowFormat, SubjectProps,\r\n} from \"@itwin/core-common\";\r\nimport { Ruleset } from \"@itwin/presentation-common\";\r\nimport { PresentationRules } from \"./domain/PresentationRulesDomain\";\r\nimport * as RulesetElements from \"./domain/RulesetElements\";\r\nimport { normalizeVersion } from \"./Utils\";\r\n\r\n/**\r\n * Interface for callbacks which will be called before and after Element/Model updates\r\n * @beta\r\n */\r\ninterface UpdateCallbacks {\r\n onBeforeUpdate: (props: Entity) => Promise<void>;\r\n onAfterUpdate: (props: Entity) => Promise<void>;\r\n}\r\n\r\n/**\r\n * Interface for callbacks which will be called before and after Element/Model is inserted\r\n * @beta\r\n */\r\ninterface InsertCallbacks {\r\n onBeforeInsert: (props: Entity) => Promise<void>;\r\n onAfterInsert: (props: Entity) => Promise<void>;\r\n}\r\n\r\n/**\r\n * Options for [[RulesetEmbedder.insertRuleset]] operation.\r\n * @beta\r\n */\r\nexport interface RulesetInsertOptions {\r\n /**\r\n * When should insertion be skipped:\r\n * - `same-id` - if iModel already contains a ruleset with the same id and **any** version\r\n * - `same-id-and-version-eq` - if iModel already contains a ruleset with same id and version\r\n * - `same-id-and-version-gte` - if iModel already contains a ruleset with same id and\r\n * version greater or equal to version of the inserted ruleset.\r\n *\r\n * Defaults to `same-id-and-version-eq`.\r\n */\r\n skip?: \"never\" | \"same-id\" | \"same-id-and-version-eq\" | \"same-id-and-version-gte\";\r\n\r\n /**\r\n * Which existing versions of rulesets with same id should be replaced when we insert a new one:\r\n * - `all` - replace all rulesets with same id.\r\n * - `all-lower` - replace rulesets with same id and version lower than the version of inserted ruleset.\r\n * - `exact` - replace only the ruleset whose id and version matches the inserted ruleset.\r\n *\r\n * Defaults to `exact`.\r\n */\r\n replaceVersions?: \"all\" | \"all-lower\" | \"exact\";\r\n\r\n /**\r\n * Callbacks that will be called before and after `Entity` updates\r\n * @beta\r\n */\r\n onEntityUpdate?: UpdateCallbacks;\r\n\r\n /**\r\n * Callbacks that will be called before and after `Entity` is inserted\r\n * @beta\r\n */\r\n onEntityInsert?: InsertCallbacks;\r\n}\r\n\r\n/**\r\n * Properties for creating a `RulesetEmbedder` instance.\r\n * @public\r\n */\r\nexport interface RulesetEmbedderProps {\r\n /** iModel to embed rulesets to */\r\n imodel: IModelDb;\r\n}\r\n\r\n/**\r\n * An API for embedding presentation rulesets into iModels.\r\n * @beta\r\n */\r\nexport class RulesetEmbedder {\r\n\r\n private _imodel: IModelDb;\r\n private readonly _schemaPath = path.join(KnownLocations.nativeAssetsDir, \"ECSchemas/Domain/PresentationRules.ecschema.xml\");\r\n private readonly _rulesetModelName = \"PresentationRules\";\r\n private readonly _rulesetSubjectName = \"PresentationRules\";\r\n\r\n /**\r\n * Constructs RulesetEmbedder\r\n */\r\n public constructor(props: RulesetEmbedderProps) {\r\n PresentationRules.registerSchema();\r\n this._imodel = props.imodel;\r\n }\r\n\r\n /**\r\n * Inserts a ruleset into iModel.\r\n * @param ruleset Ruleset to insert.\r\n * @param options Options for inserting a ruleset.\r\n * @returns ID of inserted ruleset element or, if insertion was skipped, ID of existing ruleset with the same ID and highest version.\r\n */\r\n public async insertRuleset(ruleset: Ruleset, options?: RulesetInsertOptions): Promise<Id64String> {\r\n const normalizedOptions = normalizeRulesetInsertOptions(options);\r\n const rulesetVersion = normalizeVersion(ruleset.version);\r\n\r\n // ensure imodel has PresentationRules schema and required CodeSpecs\r\n await this.handleElementOperationPrerequisites();\r\n\r\n // find all rulesets with the same ID\r\n const rulesetsWithSameId: Array<{\r\n ruleset: Ruleset;\r\n id: Id64String;\r\n normalizedVersion: string;\r\n }> = [];\r\n const query = `\r\n SELECT ECInstanceId, JsonProperties\r\n FROM ${RulesetElements.Ruleset.schema.name}.${RulesetElements.Ruleset.className}\r\n WHERE json_extract(JsonProperties, '$.jsonProperties.id') = :rulesetId`;\r\n for await (const row of this._imodel.query(query, QueryBinder.from({ rulesetId: ruleset.id }), { rowFormat: QueryRowFormat.UseJsPropertyNames })) {\r\n const existingRulesetElementId: Id64String = row.id;\r\n const existingRuleset: Ruleset = JSON.parse(row.jsonProperties).jsonProperties;\r\n rulesetsWithSameId.push({\r\n id: existingRulesetElementId,\r\n ruleset: existingRuleset,\r\n normalizedVersion: normalizeVersion(existingRuleset.version),\r\n });\r\n }\r\n\r\n // check if we need to do anything at all\r\n const shouldSkip = normalizedOptions.skip === \"same-id\" && rulesetsWithSameId.length > 0\r\n || normalizedOptions.skip === \"same-id-and-version-eq\" && rulesetsWithSameId.some((entry) => entry.normalizedVersion === rulesetVersion)\r\n || normalizedOptions.skip === \"same-id-and-version-gte\" && rulesetsWithSameId.some((entry) => versionGte(entry.normalizedVersion, rulesetVersion));\r\n if (shouldSkip) {\r\n // we're not inserting anything - return ID of the ruleset element with the highest version\r\n const rulesetEntryWithHighestVersion = rulesetsWithSameId.reduce((highest, curr) => {\r\n if (!highest.ruleset.version || curr.ruleset.version && versionGt(curr.ruleset.version, highest.ruleset.version))\r\n return curr;\r\n return highest;\r\n }, rulesetsWithSameId[0]);\r\n return rulesetEntryWithHighestVersion.id;\r\n }\r\n\r\n // if requested, delete existing rulesets\r\n const rulesetsToRemove: Id64String[] = [];\r\n const shouldRemove = (_: Ruleset, normalizedVersion: string): boolean => {\r\n switch (normalizedOptions.replaceVersions) {\r\n case \"all\":\r\n return normalizedVersion !== rulesetVersion;\r\n case \"all-lower\":\r\n return normalizedVersion !== rulesetVersion && versionLt(normalizedVersion, rulesetVersion);\r\n }\r\n return false;\r\n };\r\n rulesetsWithSameId.forEach((entry) => {\r\n if (shouldRemove(entry.ruleset, entry.normalizedVersion))\r\n rulesetsToRemove.push(entry.id);\r\n });\r\n this._imodel.elements.deleteElement(rulesetsToRemove);\r\n\r\n // attempt to update ruleset with same ID and version\r\n const exactMatch = rulesetsWithSameId.find((curr) => curr.normalizedVersion === rulesetVersion);\r\n if (exactMatch !== undefined) {\r\n return this.updateRuleset(exactMatch.id, ruleset, normalizedOptions.onEntityUpdate);\r\n }\r\n\r\n // no exact match found - insert a new ruleset element\r\n const model = await this.getOrCreateRulesetModel(normalizedOptions.onEntityInsert);\r\n const rulesetCode = RulesetElements.Ruleset.createRulesetCode(this._imodel, model.id, ruleset);\r\n return this.insertNewRuleset(ruleset, model, rulesetCode, normalizedOptions.onEntityInsert);\r\n }\r\n\r\n private async updateRuleset(elementId: Id64String, ruleset: Ruleset, callbacks?: UpdateCallbacks) {\r\n const existingRulesetElement = this._imodel.elements.tryGetElement<DefinitionElement>(elementId);\r\n assert(existingRulesetElement !== undefined);\r\n existingRulesetElement.jsonProperties.jsonProperties = ruleset;\r\n\r\n await this.updateElement(existingRulesetElement, callbacks);\r\n\r\n this._imodel.saveChanges();\r\n return existingRulesetElement.id;\r\n }\r\n\r\n private async insertNewRuleset(ruleset: Ruleset, model: Model, rulesetCode: Code, callbacks?: InsertCallbacks): Promise<Id64String> {\r\n const props: DefinitionElementProps = {\r\n model: model.id,\r\n code: rulesetCode,\r\n classFullName: RulesetElements.Ruleset.classFullName,\r\n jsonProperties: { jsonProperties: ruleset },\r\n };\r\n\r\n const element = await this.insertElement(props, callbacks);\r\n this._imodel.saveChanges();\r\n return element.id;\r\n }\r\n\r\n /**\r\n * Get all rulesets embedded in the iModel.\r\n */\r\n public async getRulesets(): Promise<Ruleset[]> {\r\n if (!this._imodel.containsClass(RulesetElements.Ruleset.classFullName))\r\n return [];\r\n\r\n const rulesetList: Ruleset[] = [];\r\n this._imodel.withPreparedStatement(`SELECT ECInstanceId AS id FROM ${RulesetElements.Ruleset.classFullName}`, (statement: ECSqlStatement) => {\r\n while (DbResult.BE_SQLITE_ROW === statement.step()) {\r\n const row = statement.getRow();\r\n const rulesetElement = this._imodel.elements.getElement({ id: row.id });\r\n const ruleset = rulesetElement.jsonProperties.jsonProperties;\r\n rulesetList.push(ruleset);\r\n }\r\n });\r\n return rulesetList;\r\n }\r\n\r\n private async getOrCreateRulesetModel(callbacks?: InsertCallbacks): Promise<DefinitionModel> {\r\n const rulesetModel = this.queryRulesetModel();\r\n if (undefined !== rulesetModel)\r\n return rulesetModel;\r\n\r\n const rulesetSubject = await this.insertSubject(callbacks);\r\n const definitionPartition = await this.insertDefinitionPartition(rulesetSubject, callbacks);\r\n return this.insertDefinitionModel(definitionPartition, callbacks);\r\n }\r\n\r\n private queryRulesetModel(): DefinitionModel | undefined {\r\n const definitionPartition = this.queryDefinitionPartition();\r\n if (undefined === definitionPartition)\r\n return undefined;\r\n\r\n return this._imodel.models.getSubModel(definitionPartition.id);\r\n }\r\n\r\n private queryDefinitionPartition(): DefinitionPartition | undefined {\r\n const subject = this.querySubject();\r\n if (undefined === subject)\r\n return undefined;\r\n\r\n return this._imodel.elements.tryGetElement<DefinitionPartition>(DefinitionPartition.createCode(this._imodel, subject.id, this._rulesetModelName));\r\n }\r\n\r\n private querySubject(): DefinitionPartition | undefined {\r\n const root = this._imodel.elements.getRootSubject();\r\n const codeSpec: CodeSpec = this._imodel.codeSpecs.getByName(BisCodeSpec.subject);\r\n const code = new Code({\r\n spec: codeSpec.id,\r\n scope: root.id,\r\n value: this._rulesetSubjectName,\r\n });\r\n\r\n return this._imodel.elements.tryGetElement<DefinitionPartition>(code);\r\n }\r\n\r\n private async insertDefinitionModel(definitionPartition: DefinitionPartition, callbacks?: InsertCallbacks): Promise<DefinitionModel> {\r\n const modelProps: ModelProps = {\r\n modeledElement: definitionPartition,\r\n name: this._rulesetModelName,\r\n classFullName: DefinitionModel.classFullName,\r\n isPrivate: true,\r\n };\r\n\r\n return this.insertModel(modelProps, callbacks);\r\n }\r\n\r\n private async insertDefinitionPartition(rulesetSubject: Subject, callbacks?: InsertCallbacks): Promise<DefinitionPartition> {\r\n const partitionCode = DefinitionPartition.createCode(this._imodel, rulesetSubject.id, this._rulesetModelName);\r\n const definitionPartitionProps: InformationPartitionElementProps = {\r\n parent: {\r\n id: rulesetSubject.id,\r\n relClassName: \"BisCore:SubjectOwnsPartitionElements\",\r\n },\r\n model: rulesetSubject.model,\r\n code: partitionCode,\r\n classFullName: DefinitionPartition.classFullName,\r\n };\r\n\r\n return this.insertElement(definitionPartitionProps, callbacks);\r\n }\r\n\r\n private async insertSubject(callbacks?: InsertCallbacks): Promise<Subject> {\r\n const root = this._imodel.elements.getRootSubject();\r\n const codeSpec: CodeSpec = this._imodel.codeSpecs.getByName(BisCodeSpec.subject);\r\n const subjectCode = new Code({\r\n spec: codeSpec.id,\r\n scope: root.id,\r\n value: this._rulesetSubjectName,\r\n });\r\n const subjectProps: SubjectProps = {\r\n classFullName: Subject.classFullName,\r\n model: root.model,\r\n parent: {\r\n id: root.id,\r\n relClassName: \"BisCore:SubjectOwnsSubjects\",\r\n },\r\n code: subjectCode,\r\n };\r\n\r\n return this.insertElement(subjectProps, callbacks);\r\n }\r\n\r\n private async handleElementOperationPrerequisites(): Promise<void> {\r\n if (this._imodel.containsClass(RulesetElements.Ruleset.classFullName))\r\n return;\r\n\r\n // import PresentationRules ECSchema\r\n await this._imodel.importSchemas([this._schemaPath]);\r\n\r\n // insert CodeSpec for ruleset elements\r\n this._imodel.codeSpecs.insert(CodeSpec.create(this._imodel, PresentationRules.CodeSpec.Ruleset, CodeScopeSpec.Type.Model));\r\n\r\n this._imodel.saveChanges();\r\n }\r\n\r\n private async insertElement<TProps extends ElementProps>(props: TProps, callbacks?: InsertCallbacks): Promise<Element> {\r\n const element = this._imodel.elements.createElement(props);\r\n // istanbul ignore next\r\n await callbacks?.onBeforeInsert(element);\r\n try {\r\n return this._imodel.elements.getElement(element.insert());\r\n } finally {\r\n // istanbul ignore next\r\n await callbacks?.onAfterInsert(element);\r\n }\r\n }\r\n\r\n private async insertModel(props: ModelProps, callbacks?: InsertCallbacks): Promise<Model> {\r\n const model = this._imodel.models.createModel(props);\r\n // istanbul ignore next\r\n await callbacks?.onBeforeInsert(model);\r\n try {\r\n model.id = model.insert();\r\n return model;\r\n } finally {\r\n // istanbul ignore next\r\n await callbacks?.onAfterInsert(model);\r\n }\r\n }\r\n\r\n private async updateElement(element: Element, callbacks?: UpdateCallbacks) {\r\n // istanbul ignore next\r\n await callbacks?.onBeforeUpdate(element);\r\n try {\r\n element.update();\r\n } finally {\r\n // istanbul ignore next\r\n await callbacks?.onAfterUpdate(element);\r\n }\r\n }\r\n}\r\n\r\nfunction normalizeRulesetInsertOptions(options?: RulesetInsertOptions): RulesetInsertOptions {\r\n if (options === undefined)\r\n return { skip: \"same-id-and-version-eq\", replaceVersions: \"exact\" };\r\n\r\n return {\r\n skip: options.skip ?? \"same-id-and-version-eq\",\r\n replaceVersions: options.replaceVersions ?? \"exact\",\r\n onEntityUpdate: options.onEntityUpdate,\r\n onEntityInsert: options.onEntityInsert,\r\n };\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) => 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,KAAK,IAAI,CAAC;IACjC,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;IAa9B;;;;;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"}