@itwin/imodel-transformer 2.0.0-dev.7 → 2.0.0-dev.71

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 (132) hide show
  1. package/README.md +13 -27
  2. package/lib/cjs/Algo.d.ts +0 -4
  3. package/lib/cjs/Algo.d.ts.map +1 -1
  4. package/lib/cjs/Algo.js +0 -11
  5. package/lib/cjs/Algo.js.map +1 -1
  6. package/lib/cjs/BigMap.d.ts.map +1 -1
  7. package/lib/cjs/BigMap.js.map +1 -1
  8. package/lib/cjs/BranchProvenanceInitializer.d.ts.map +1 -1
  9. package/lib/cjs/BranchProvenanceInitializer.js +26 -26
  10. package/lib/cjs/BranchProvenanceInitializer.js.map +1 -1
  11. package/lib/cjs/ChangedElementForest.d.ts +14 -0
  12. package/lib/cjs/ChangedElementForest.d.ts.map +1 -0
  13. package/lib/cjs/ChangedElementForest.js +86 -0
  14. package/lib/cjs/ChangedElementForest.js.map +1 -0
  15. package/lib/cjs/ChangesetScanner.d.ts +141 -0
  16. package/lib/cjs/ChangesetScanner.d.ts.map +1 -0
  17. package/lib/cjs/ChangesetScanner.js +187 -0
  18. package/lib/cjs/ChangesetScanner.js.map +1 -0
  19. package/lib/cjs/ECReferenceTypesCache.d.ts +0 -4
  20. package/lib/cjs/ECReferenceTypesCache.d.ts.map +1 -1
  21. package/lib/cjs/ECReferenceTypesCache.js +61 -111
  22. package/lib/cjs/ECReferenceTypesCache.js.map +1 -1
  23. package/lib/cjs/ECSqlReaderAsyncIterableIteratorAdapter.d.ts.map +1 -1
  24. package/lib/cjs/ECSqlReaderAsyncIterableIteratorAdapter.js.map +1 -1
  25. package/lib/cjs/ElementAspectCleanup.d.ts +16 -0
  26. package/lib/cjs/ElementAspectCleanup.d.ts.map +1 -0
  27. package/lib/cjs/ElementAspectCleanup.js +87 -0
  28. package/lib/cjs/ElementAspectCleanup.js.map +1 -0
  29. package/lib/cjs/ElementAspectExportCoordinator.d.ts +44 -0
  30. package/lib/cjs/ElementAspectExportCoordinator.d.ts.map +1 -0
  31. package/lib/cjs/ElementAspectExportCoordinator.js +148 -0
  32. package/lib/cjs/ElementAspectExportCoordinator.js.map +1 -0
  33. package/lib/cjs/ElementAspectExportProcessor.d.ts +44 -0
  34. package/lib/cjs/ElementAspectExportProcessor.d.ts.map +1 -0
  35. package/lib/cjs/ElementAspectExportProcessor.js +152 -0
  36. package/lib/cjs/ElementAspectExportProcessor.js.map +1 -0
  37. package/lib/cjs/ElementBulkDelete.d.ts +30 -0
  38. package/lib/cjs/ElementBulkDelete.d.ts.map +1 -0
  39. package/lib/cjs/ElementBulkDelete.js +358 -0
  40. package/lib/cjs/ElementBulkDelete.js.map +1 -0
  41. package/lib/cjs/EntityExistenceCache.d.ts +43 -0
  42. package/lib/cjs/EntityExistenceCache.d.ts.map +1 -0
  43. package/lib/cjs/EntityExistenceCache.js +91 -0
  44. package/lib/cjs/EntityExistenceCache.js.map +1 -0
  45. package/lib/cjs/EntityUnifier.d.ts +7 -7
  46. package/lib/cjs/EntityUnifier.d.ts.map +1 -1
  47. package/lib/cjs/EntityUnifier.js +55 -24
  48. package/lib/cjs/EntityUnifier.js.map +1 -1
  49. package/lib/cjs/IModelCloneContext.d.ts +9 -3
  50. package/lib/cjs/IModelCloneContext.d.ts.map +1 -1
  51. package/lib/cjs/IModelCloneContext.js +56 -22
  52. package/lib/cjs/IModelCloneContext.js.map +1 -1
  53. package/lib/cjs/IModelExporter.d.ts +180 -43
  54. package/lib/cjs/IModelExporter.d.ts.map +1 -1
  55. package/lib/cjs/IModelExporter.js +946 -247
  56. package/lib/cjs/IModelExporter.js.map +1 -1
  57. package/lib/cjs/IModelImporter.d.ts +75 -30
  58. package/lib/cjs/IModelImporter.d.ts.map +1 -1
  59. package/lib/cjs/IModelImporter.js +292 -132
  60. package/lib/cjs/IModelImporter.js.map +1 -1
  61. package/lib/cjs/IModelTransformContext.d.ts +54 -0
  62. package/lib/cjs/IModelTransformContext.d.ts.map +1 -0
  63. package/lib/cjs/IModelTransformContext.js +3 -0
  64. package/lib/cjs/IModelTransformContext.js.map +1 -0
  65. package/lib/cjs/IModelTransformer.d.ts +184 -206
  66. package/lib/cjs/IModelTransformer.d.ts.map +1 -1
  67. package/lib/cjs/IModelTransformer.js +819 -1278
  68. package/lib/cjs/IModelTransformer.js.map +1 -1
  69. package/lib/cjs/IModelTransformerError.d.ts +84 -0
  70. package/lib/cjs/IModelTransformerError.d.ts.map +1 -0
  71. package/lib/cjs/IModelTransformerError.js +93 -0
  72. package/lib/cjs/IModelTransformerError.js.map +1 -0
  73. package/lib/cjs/ProvenanceManager.d.ts +177 -0
  74. package/lib/cjs/ProvenanceManager.d.ts.map +1 -0
  75. package/lib/cjs/ProvenanceManager.js +719 -0
  76. package/lib/cjs/ProvenanceManager.js.map +1 -0
  77. package/lib/cjs/SourceClassKinds.d.ts +22 -0
  78. package/lib/cjs/SourceClassKinds.d.ts.map +1 -0
  79. package/lib/cjs/SourceClassKinds.js +60 -0
  80. package/lib/cjs/SourceClassKinds.js.map +1 -0
  81. package/lib/cjs/SyncTypeResolver.d.ts +32 -0
  82. package/lib/cjs/SyncTypeResolver.d.ts.map +1 -0
  83. package/lib/cjs/SyncTypeResolver.js +92 -0
  84. package/lib/cjs/SyncTypeResolver.js.map +1 -0
  85. package/lib/cjs/TransformerLoggerCategory.d.ts +1 -1
  86. package/lib/cjs/TransformerLoggerCategory.js +1 -1
  87. package/lib/cjs/TransformerLoggerCategory.js.map +1 -1
  88. package/lib/cjs/TransformerPackageMetadata.d.ts +8 -0
  89. package/lib/cjs/TransformerPackageMetadata.d.ts.map +1 -0
  90. package/lib/cjs/TransformerPackageMetadata.js +47 -0
  91. package/lib/cjs/TransformerPackageMetadata.js.map +1 -0
  92. package/lib/cjs/imodel-transformer.d.ts +28 -0
  93. package/lib/cjs/imodel-transformer.d.ts.map +1 -1
  94. package/lib/cjs/imodel-transformer.js +61 -34
  95. package/lib/cjs/imodel-transformer.js.map +1 -1
  96. package/lib/cjs/schema-processing/DynamicSchemaUnionStrategy.d.ts +29 -0
  97. package/lib/cjs/schema-processing/DynamicSchemaUnionStrategy.d.ts.map +1 -0
  98. package/lib/cjs/schema-processing/DynamicSchemaUnionStrategy.js +212 -0
  99. package/lib/cjs/schema-processing/DynamicSchemaUnionStrategy.js.map +1 -0
  100. package/lib/cjs/schema-processing/SchemaProcessingCoordinator.d.ts +25 -0
  101. package/lib/cjs/schema-processing/SchemaProcessingCoordinator.d.ts.map +1 -0
  102. package/lib/cjs/schema-processing/SchemaProcessingCoordinator.js +196 -0
  103. package/lib/cjs/schema-processing/SchemaProcessingCoordinator.js.map +1 -0
  104. package/lib/cjs/schema-processing/SchemaProcessingStrategy.d.ts +59 -0
  105. package/lib/cjs/schema-processing/SchemaProcessingStrategy.d.ts.map +1 -0
  106. package/lib/cjs/schema-processing/SchemaProcessingStrategy.js +28 -0
  107. package/lib/cjs/schema-processing/SchemaProcessingStrategy.js.map +1 -0
  108. package/lib/cjs/schema-processing.d.ts +7 -0
  109. package/lib/cjs/schema-processing.d.ts.map +1 -0
  110. package/lib/cjs/schema-processing.js +27 -0
  111. package/lib/cjs/schema-processing.js.map +1 -0
  112. package/package.json +70 -57
  113. package/lib/cjs/DetachedExportElementAspectsStrategy.d.ts +0 -16
  114. package/lib/cjs/DetachedExportElementAspectsStrategy.d.ts.map +0 -1
  115. package/lib/cjs/DetachedExportElementAspectsStrategy.js +0 -106
  116. package/lib/cjs/DetachedExportElementAspectsStrategy.js.map +0 -1
  117. package/lib/cjs/ElementCascadingDeleter.d.ts +0 -22
  118. package/lib/cjs/ElementCascadingDeleter.d.ts.map +0 -1
  119. package/lib/cjs/ElementCascadingDeleter.js +0 -57
  120. package/lib/cjs/ElementCascadingDeleter.js.map +0 -1
  121. package/lib/cjs/EntityMap.d.ts +0 -26
  122. package/lib/cjs/EntityMap.d.ts.map +0 -1
  123. package/lib/cjs/EntityMap.js +0 -54
  124. package/lib/cjs/EntityMap.js.map +0 -1
  125. package/lib/cjs/ExportElementAspectsStrategy.d.ts +0 -35
  126. package/lib/cjs/ExportElementAspectsStrategy.d.ts.map +0 -1
  127. package/lib/cjs/ExportElementAspectsStrategy.js +0 -52
  128. package/lib/cjs/ExportElementAspectsStrategy.js.map +0 -1
  129. package/lib/cjs/ExportElementAspectsWithElementsStrategy.d.ts +0 -12
  130. package/lib/cjs/ExportElementAspectsWithElementsStrategy.d.ts.map +0 -1
  131. package/lib/cjs/ExportElementAspectsWithElementsStrategy.js +0 -47
  132. package/lib/cjs/ExportElementAspectsWithElementsStrategy.js.map +0 -1
@@ -11,8 +11,9 @@ exports.ECReferenceTypesCache = exports.SchemaNotInCacheErr = void 0;
11
11
  const core_bentley_1 = require("@itwin/core-bentley");
12
12
  const core_common_1 = require("@itwin/core-common");
13
13
  const ecschema_metadata_1 = require("@itwin/ecschema-metadata");
14
- const assert = require("assert");
14
+ const node_assert_1 = require("node:assert");
15
15
  const TransformerLoggerCategory_1 = require("./TransformerLoggerCategory");
16
+ const IModelTransformerError_1 = require("./IModelTransformerError");
16
17
  /** The context for transforming a *source* Element to a *target* Element and remapping internal identifiers to the target iModel.
17
18
  * @internal
18
19
  */
@@ -35,12 +36,7 @@ class ECReferenceTypesCache {
35
36
  _propQualifierToRefType = new core_bentley_1.TupleKeyedMap();
36
37
  _relClassNameEndToRefTypes = new core_bentley_1.TupleKeyedMap();
37
38
  _initedSchemas = new Map();
38
- // Performance optimization caches
39
- _rootBisClassCache = new Map();
40
- _relationshipInfoCache = new Map();
41
- _constraintClassCache = new Map();
42
39
  static bisRootClassToRefType = {
43
- /* eslint-disable quote-props, @typescript-eslint/naming-convention */
44
40
  Element: core_common_1.ConcreteEntityTypes.Element,
45
41
  Model: core_common_1.ConcreteEntityTypes.Model,
46
42
  ElementAspect: core_common_1.ConcreteEntityTypes.ElementAspect,
@@ -48,14 +44,8 @@ class ECReferenceTypesCache {
48
44
  ElementDrivesElement: core_common_1.ConcreteEntityTypes.Relationship,
49
45
  // code spec is technically a potential root class but it is ignored currently
50
46
  // see [ConcreteEntityTypes]($common)
51
- /* eslint-enable quote-props, @typescript-eslint/naming-convention */
52
47
  };
53
48
  async getRootBisClass(ecclass) {
54
- const cacheKey = ecclass.fullName;
55
- const cached = this._rootBisClassCache.get(cacheKey);
56
- if (cached) {
57
- return cached;
58
- }
59
49
  let bisRootForConstraint = ecclass;
60
50
  await ecclass.traverseBaseClasses((baseClass) => {
61
51
  // The depth first traversal will descend all the way to the root class before making any lateral traversal
@@ -71,68 +61,54 @@ class ECReferenceTypesCache {
71
61
  });
72
62
  // if the root class of the constraint was a mixin, use its AppliesToEntityClass
73
63
  if (bisRootForConstraint instanceof ecschema_metadata_1.Mixin) {
74
- assert(bisRootForConstraint.appliesTo !== undefined, "The referenced AppliesToEntityClass could not be found, how did it pass schema validation?");
64
+ (0, node_assert_1.strict)(bisRootForConstraint.appliesTo !== undefined, "The referenced AppliesToEntityClass could not be found, how did it pass schema validation?");
75
65
  bisRootForConstraint = await this.getRootBisClass(await bisRootForConstraint.appliesTo);
76
66
  }
77
- this._rootBisClassCache.set(cacheKey, bisRootForConstraint);
78
67
  return bisRootForConstraint;
79
68
  }
80
69
  async getAbstractConstraintClass(constraint) {
81
- const cacheKey = `${constraint.fullName}_${constraint.constraintClasses?.[0]?.fullName || "abstract"}`;
82
- const cached = this._constraintClassCache.get(cacheKey);
83
- if (cached) {
84
- return cached;
85
- }
86
70
  // constraint classes must share a base so we can get the root from any of them, just use the first
87
71
  const ecclass = await (constraint.constraintClasses?.[0] ||
88
72
  constraint.abstractConstraint);
89
- assert(ecclass !== undefined, "At least one constraint class or an abstract constraint must have been defined, the constraint is not valid");
90
- this._constraintClassCache.set(cacheKey, ecclass);
73
+ (0, node_assert_1.strict)(ecclass !== undefined, "At least one constraint class or an abstract constraint must have been defined, the constraint is not valid");
91
74
  return ecclass;
92
75
  }
93
76
  /** initialize from an imodel with metadata */
94
77
  async initAllSchemasInIModel(imodel) {
95
- let totalSchemaCount = 0;
96
- let schemaCompletedCount = 0;
97
- const initStartTime = performance.now();
98
78
  const query = `
99
79
  WITH RECURSIVE refs(SchemaId) AS (
100
80
  SELECT ECInstanceId FROM ECDbMeta.ECSchemaDef WHERE Name='BisCore'
101
- UNION ALL
81
+ UNION
102
82
  SELECT sr.SourceECInstanceId
103
83
  FROM ECDbMeta.SchemaHasSchemaReferences sr
104
84
  JOIN refs ON sr.TargetECInstanceId = refs.SchemaId
105
85
  )
106
- SELECT DISTINCT s.Name as name
86
+ SELECT s.Name as name
107
87
  FROM refs
108
88
  JOIN ECDbMeta.ECSchemaDef s ON refs.SchemaId=s.ECInstanceId
109
- -- ensure schema dependency order
110
- ORDER BY s.ECInstanceId
111
89
  `;
112
- for await (const row of imodel.createQueryReader(query)) {
90
+ for await (const row of imodel.createQueryReader(query, undefined, {
91
+ usePrimaryConn: true,
92
+ })) {
113
93
  const schemaName = row.name;
114
- const startTime = performance.now();
115
- core_bentley_1.Logger.logTrace(TransformerLoggerCategory_1.TransformerLoggerCategory.ECReferenceTypesCache, `Loading schema: ${schemaName}`);
116
94
  const schemaItemKey = new ecschema_metadata_1.SchemaKey(schemaName);
117
95
  const schema = await imodel.schemaContext.getSchema(schemaItemKey);
118
- if (schema) {
119
- await this.considerInitSchema(schema);
120
- const endTime = performance.now();
121
- core_bentley_1.Logger.logTrace(TransformerLoggerCategory_1.TransformerLoggerCategory.ECReferenceTypesCache, `Completed schema: ${schemaName} in ${(endTime - startTime).toFixed(2)}ms`);
122
- schemaCompletedCount++;
123
- }
124
- else {
125
- core_bentley_1.Logger.logInfo(TransformerLoggerCategory_1.TransformerLoggerCategory.ECReferenceTypesCache, `Did not load schema: ${schemaName}`);
96
+ if (!schema) {
97
+ core_bentley_1.ITwinError.throwError({
98
+ iTwinErrorId: {
99
+ scope: IModelTransformerError_1.IModelTransformerErrorScope,
100
+ key: IModelTransformerError_1.IModelTransformerError.SchemaLoadFailed,
101
+ },
102
+ message: `Failed to load schema: ${schemaName}`,
103
+ });
126
104
  }
127
- totalSchemaCount++;
105
+ await this.considerInitSchema(schema);
128
106
  }
129
- const initEndTime = performance.now();
130
- core_bentley_1.Logger.logTrace(TransformerLoggerCategory_1.TransformerLoggerCategory.ECReferenceTypesCache, `Schemas completed out of total: ${schemaCompletedCount} / ${totalSchemaCount} in ${(initEndTime - initStartTime).toFixed(2)}ms`);
131
107
  }
132
108
  async considerInitSchema(schema) {
133
109
  if (this._initedSchemas.has(schema.name)) {
134
110
  const cachedSchemaKey = this._initedSchemas.get(schema.name);
135
- assert(cachedSchemaKey !== undefined);
111
+ (0, node_assert_1.strict)(cachedSchemaKey !== undefined);
136
112
  const incomingSchemaIsEqualOrOlder = schema.schemaKey.compareByVersion(cachedSchemaKey) <= 0;
137
113
  if (incomingSchemaIsEqualOrOlder) {
138
114
  return;
@@ -141,73 +117,55 @@ class ECReferenceTypesCache {
141
117
  return this.initSchema(schema);
142
118
  }
143
119
  async initSchema(schema) {
144
- core_bentley_1.Logger.logInfo(TransformerLoggerCategory_1.TransformerLoggerCategory.ECReferenceTypesCache, `Init Schema: ${schema.name}`);
120
+ core_bentley_1.Logger.logTrace(TransformerLoggerCategory_1.TransformerLoggerCategory.ECReferenceTypesCache, `initSchema started for ${schema.name}`);
145
121
  const schemaNameLower = schema.name.toLowerCase();
146
- // Pre-collect all items to reduce iterator overhead
147
- const allItems = Array.from(schema.getItems());
148
- const ecClasses = [];
149
- const relationshipClasses = [];
150
- // Single pass through items with type checking
151
- for (const item of allItems) {
152
- // eslint-disable-next-line @itwin/no-internal
153
- if (!ecschema_metadata_1.ECClass.isECClass(item))
154
- continue;
155
- ecClasses.push(item);
156
- if (item instanceof ecschema_metadata_1.RelationshipClass) {
157
- relationshipClasses.push(item);
122
+ // Local dedup map — scoped to this single initSchema call, not persisted
123
+ const localRelInfoMap = new Map();
124
+ const getRelInfo = async (relClass) => {
125
+ let promise = localRelInfoMap.get(relClass.fullName);
126
+ if (!promise) {
127
+ promise = this.relInfoFromRelClass(relClass);
128
+ localRelInfoMap.set(relClass.fullName, promise);
158
129
  }
159
- }
160
- // Process relationship classes in parallel and populate global cache
161
- const relInfoPromises = relationshipClasses.map(async (relClass) => {
162
- const relInfo = await this.relInfoFromRelClass(relClass);
163
- this._relationshipInfoCache.set(relClass.fullName, relInfo);
164
- if (relInfo) {
165
- this._relClassNameEndToRefTypes.set([schemaNameLower, relClass.name.toLowerCase()], relInfo);
130
+ return promise;
131
+ };
132
+ // Process all classes concurrently
133
+ const classPromises = Array.from(schema.getItems())
134
+ .filter((item) => ecschema_metadata_1.ECClass.isECClass(item))
135
+ .map(async (ecclass) => {
136
+ // Handle relationship end types
137
+ if (ecclass instanceof ecschema_metadata_1.RelationshipClass) {
138
+ const relInfo = await getRelInfo(ecclass);
139
+ if (relInfo) {
140
+ this._relClassNameEndToRefTypes.set([schemaNameLower, ecclass.name.toLowerCase()], relInfo);
141
+ }
166
142
  }
167
- return relInfo;
168
- });
169
- // Wait for all relationship info to be cached
170
- await Promise.all(relInfoPromises);
171
- // Process navigation properties with optimized batching
172
- const propertyBatchSize = 25;
173
- for (let i = 0; i < ecClasses.length; i += propertyBatchSize) {
174
- const classBatch = ecClasses.slice(i, i + propertyBatchSize);
175
- const classPromises = classBatch.map(async (ecclass) => {
176
- const properties = await ecclass.getProperties();
177
- if (!properties)
143
+ // Handle nav props
144
+ const properties = await ecclass.getProperties();
145
+ const classNameLower = ecclass.name.toLowerCase();
146
+ const navPropPromises = Array.from(properties)
147
+ .filter((prop) => prop.isNavigation())
148
+ .map(async (prop) => {
149
+ if (!prop.isNavigation())
178
150
  return;
179
- const classNameLower = ecclass.name.toLowerCase();
180
- // Efficiently filter navigation properties
181
- const navProps = Array.from(properties).filter((prop) => prop.isNavigation());
182
- if (navProps.length === 0)
151
+ const relClass = await prop.relationshipClass;
152
+ const relInfo = await getRelInfo(relClass);
153
+ if (relInfo === undefined)
183
154
  return;
184
- const navPropPromises = navProps.map(async (prop) => {
185
- const relClass = await prop.relationshipClass;
186
- // Use cached relation info
187
- let relInfo = this._relationshipInfoCache.get(relClass.fullName);
188
- if (relInfo === undefined &&
189
- !this._relationshipInfoCache.has(relClass.fullName)) {
190
- relInfo = await this.relInfoFromRelClass(relClass);
191
- this._relationshipInfoCache.set(relClass.fullName, relInfo);
192
- }
193
- if (relInfo === undefined)
194
- return;
195
- const navPropRefType = prop.direction === ecschema_metadata_1.StrengthDirection.Forward
196
- ? // eslint-disable-next-line @itwin/no-internal
197
- relInfo.target
198
- : // eslint-disable-next-line @itwin/no-internal
199
- relInfo.source;
200
- this._propQualifierToRefType.set([schemaNameLower, classNameLower, prop.name.toLowerCase()], navPropRefType);
201
- });
202
- await Promise.all(navPropPromises);
155
+ const navPropRefType = prop.direction === ecschema_metadata_1.StrengthDirection.Forward
156
+ ? relInfo.target
157
+ : relInfo.source;
158
+ this._propQualifierToRefType.set([schemaNameLower, classNameLower, prop.name.toLowerCase()], navPropRefType);
203
159
  });
204
- await Promise.all(classPromises);
205
- }
160
+ await Promise.all(navPropPromises);
161
+ });
162
+ await Promise.all(classPromises);
206
163
  this._initedSchemas.set(schema.name, schema.schemaKey);
164
+ core_bentley_1.Logger.logTrace(TransformerLoggerCategory_1.TransformerLoggerCategory.ECReferenceTypesCache, `initSchema completed for ${schema.name}`);
207
165
  }
208
166
  async relInfoFromRelClass(ecclass) {
209
- assert(ecclass.source.constraintClasses !== undefined);
210
- assert(ecclass.target.constraintClasses !== undefined);
167
+ (0, node_assert_1.strict)(ecclass.source.constraintClasses !== undefined);
168
+ (0, node_assert_1.strict)(ecclass.target.constraintClasses !== undefined);
211
169
  const [[sourceClass, sourceRootBisClass], [targetClass, targetRootBisClass],] = await Promise.all([
212
170
  this.getAbstractConstraintClass(ecclass.source).then(async (constraintClass) => [
213
171
  constraintClass,
@@ -236,8 +194,8 @@ class ECReferenceTypesCache {
236
194
  `the nav prop reference type cache for ${cls.fullName}.`,
237
195
  "This is a bug.",
238
196
  ].join("\n");
239
- assert(sourceType !== undefined, makeAssertMsg(sourceRootBisClass, sourceClass));
240
- assert(targetType !== undefined, makeAssertMsg(targetRootBisClass, targetClass));
197
+ (0, node_assert_1.strict)(sourceType !== undefined, makeAssertMsg(sourceRootBisClass, sourceClass));
198
+ (0, node_assert_1.strict)(targetType !== undefined, makeAssertMsg(targetRootBisClass, targetClass));
241
199
  return { source: sourceType, target: targetType };
242
200
  }
243
201
  getNavPropRefType(schemaName, className, propName) {
@@ -257,14 +215,6 @@ class ECReferenceTypesCache {
257
215
  className.toLowerCase(),
258
216
  ]);
259
217
  }
260
- clear() {
261
- this._initedSchemas.clear();
262
- this._propQualifierToRefType.clear();
263
- this._relClassNameEndToRefTypes.clear();
264
- this._rootBisClassCache.clear();
265
- this._relationshipInfoCache.clear();
266
- this._constraintClassCache.clear();
267
- }
268
218
  }
269
219
  exports.ECReferenceTypesCache = ECReferenceTypesCache;
270
220
  //# sourceMappingURL=ECReferenceTypesCache.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ECReferenceTypesCache.js","sourceRoot":"","sources":["../../src/ECReferenceTypesCache.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n/** @packageDocumentation\n * @module iModels\n */\n\nimport { Logger, TupleKeyedMap } from \"@itwin/core-bentley\";\nimport { ConcreteEntityTypes, RelTypeInfo } from \"@itwin/core-common\";\nimport {\n ECClass,\n Mixin,\n RelationshipClass,\n RelationshipConstraint,\n Schema,\n SchemaKey,\n StrengthDirection,\n} from \"@itwin/ecschema-metadata\";\nimport * as assert from \"assert\";\nimport { IModelDb } from \"@itwin/core-backend\";\nimport { TransformerLoggerCategory } from \"./TransformerLoggerCategory\";\n\n/** The context for transforming a *source* Element to a *target* Element and remapping internal identifiers to the target iModel.\n * @internal\n */\nexport class SchemaNotInCacheErr extends Error {\n public constructor() {\n super(\"Schema was not in cache, initialize that schema\");\n }\n}\n\n/**\n * A cache of the entity types referenced by navprops in ecchemas, as well as the source and target entity types of\n * The transformer needs the referenced type to determine how to resolve references.\n *\n * Using multiple of these usually performs redundant computation, for static schemas at least. A possible future optimization\n * would be to seed the computation from a global cache of non-dynamic schemas, but dynamic schemas can collide willy-nilly\n * @internal\n */\nexport class ECReferenceTypesCache {\n /** nesting based tuple map keyed by qualified property path tuple [schemaName, className, propName] */\n private _propQualifierToRefType = new TupleKeyedMap<\n [string, string, string],\n ConcreteEntityTypes\n >();\n private _relClassNameEndToRefTypes = new TupleKeyedMap<\n [string, string],\n RelTypeInfo\n >();\n private _initedSchemas = new Map<string, SchemaKey>();\n\n // Performance optimization caches\n private _rootBisClassCache = new Map<string, ECClass>();\n private _relationshipInfoCache = new Map<string, RelTypeInfo | undefined>();\n private _constraintClassCache = new Map<string, ECClass>();\n\n private static bisRootClassToRefType: Record<\n string,\n ConcreteEntityTypes | undefined\n > = {\n /* eslint-disable quote-props, @typescript-eslint/naming-convention */\n Element: ConcreteEntityTypes.Element,\n Model: ConcreteEntityTypes.Model,\n ElementAspect: ConcreteEntityTypes.ElementAspect,\n ElementRefersToElements: ConcreteEntityTypes.Relationship,\n ElementDrivesElement: ConcreteEntityTypes.Relationship,\n // code spec is technically a potential root class but it is ignored currently\n // see [ConcreteEntityTypes]($common)\n /* eslint-enable quote-props, @typescript-eslint/naming-convention */\n };\n\n private async getRootBisClass(ecclass: ECClass) {\n const cacheKey = ecclass.fullName;\n const cached = this._rootBisClassCache.get(cacheKey);\n if (cached) {\n return cached;\n }\n\n let bisRootForConstraint: ECClass = ecclass;\n await ecclass.traverseBaseClasses((baseClass) => {\n // The depth first traversal will descend all the way to the root class before making any lateral traversal\n // of mixin hierarchies, (or if the constraint is a mixin, it will traverse to the root of the mixin hierarchy)\n // Once we see that we've moved laterally, we can terminate early\n const isFirstTest = bisRootForConstraint === ecclass;\n const traversalSwitchedRootPath =\n baseClass.name !== bisRootForConstraint.baseClass?.name;\n const stillTraversingRootPath = isFirstTest || !traversalSwitchedRootPath;\n if (!stillTraversingRootPath) return true; // stop traversal early\n bisRootForConstraint = baseClass;\n return false;\n });\n // if the root class of the constraint was a mixin, use its AppliesToEntityClass\n if (bisRootForConstraint instanceof Mixin) {\n assert(\n bisRootForConstraint.appliesTo !== undefined,\n \"The referenced AppliesToEntityClass could not be found, how did it pass schema validation?\"\n );\n bisRootForConstraint = await this.getRootBisClass(\n await bisRootForConstraint.appliesTo\n );\n }\n\n this._rootBisClassCache.set(cacheKey, bisRootForConstraint);\n return bisRootForConstraint;\n }\n\n private async getAbstractConstraintClass(\n constraint: RelationshipConstraint\n ): Promise<ECClass> {\n const cacheKey = `${constraint.fullName}_${constraint.constraintClasses?.[0]?.fullName || \"abstract\"}`;\n const cached = this._constraintClassCache.get(cacheKey);\n if (cached) {\n return cached;\n }\n\n // constraint classes must share a base so we can get the root from any of them, just use the first\n const ecclass = await (constraint.constraintClasses?.[0] ||\n constraint.abstractConstraint);\n assert(\n ecclass !== undefined,\n \"At least one constraint class or an abstract constraint must have been defined, the constraint is not valid\"\n );\n\n this._constraintClassCache.set(cacheKey, ecclass);\n return ecclass;\n }\n\n /** initialize from an imodel with metadata */\n public async initAllSchemasInIModel(imodel: IModelDb): Promise<void> {\n let totalSchemaCount = 0;\n let schemaCompletedCount = 0;\n\n const initStartTime = performance.now();\n\n const query = `\n WITH RECURSIVE refs(SchemaId) AS (\n SELECT ECInstanceId FROM ECDbMeta.ECSchemaDef WHERE Name='BisCore'\n UNION ALL\n SELECT sr.SourceECInstanceId\n FROM ECDbMeta.SchemaHasSchemaReferences sr\n JOIN refs ON sr.TargetECInstanceId = refs.SchemaId\n )\n SELECT DISTINCT s.Name as name\n FROM refs\n JOIN ECDbMeta.ECSchemaDef s ON refs.SchemaId=s.ECInstanceId\n -- ensure schema dependency order\n ORDER BY s.ECInstanceId\n `;\n\n for await (const row of imodel.createQueryReader(query)) {\n const schemaName = row.name;\n const startTime = performance.now();\n Logger.logTrace(\n TransformerLoggerCategory.ECReferenceTypesCache,\n `Loading schema: ${schemaName}`\n );\n const schemaItemKey = new SchemaKey(schemaName);\n const schema = await imodel.schemaContext.getSchema(schemaItemKey);\n if (schema) {\n await this.considerInitSchema(schema);\n const endTime = performance.now();\n Logger.logTrace(\n TransformerLoggerCategory.ECReferenceTypesCache,\n `Completed schema: ${schemaName} in ${(endTime - startTime).toFixed(2)}ms`\n );\n schemaCompletedCount++;\n } else {\n Logger.logInfo(\n TransformerLoggerCategory.ECReferenceTypesCache,\n `Did not load schema: ${schemaName}`\n );\n }\n\n totalSchemaCount++;\n }\n\n const initEndTime = performance.now();\n Logger.logTrace(\n TransformerLoggerCategory.ECReferenceTypesCache,\n `Schemas completed out of total: ${schemaCompletedCount} / ${totalSchemaCount} in ${(initEndTime - initStartTime).toFixed(2)}ms`\n );\n }\n\n private async considerInitSchema(schema: Schema): Promise<void> {\n if (this._initedSchemas.has(schema.name)) {\n const cachedSchemaKey = this._initedSchemas.get(schema.name);\n assert(cachedSchemaKey !== undefined);\n const incomingSchemaIsEqualOrOlder =\n schema.schemaKey.compareByVersion(cachedSchemaKey) <= 0;\n if (incomingSchemaIsEqualOrOlder) {\n return;\n }\n }\n return this.initSchema(schema);\n }\n\n private async initSchema(schema: Schema): Promise<void> {\n Logger.logInfo(\n TransformerLoggerCategory.ECReferenceTypesCache,\n `Init Schema: ${schema.name}`\n );\n const schemaNameLower = schema.name.toLowerCase();\n\n // Pre-collect all items to reduce iterator overhead\n const allItems = Array.from(schema.getItems());\n const ecClasses: ECClass[] = [];\n const relationshipClasses: RelationshipClass[] = [];\n\n // Single pass through items with type checking\n for (const item of allItems) {\n // eslint-disable-next-line @itwin/no-internal\n if (!ECClass.isECClass(item)) continue;\n ecClasses.push(item);\n if (item instanceof RelationshipClass) {\n relationshipClasses.push(item);\n }\n }\n\n // Process relationship classes in parallel and populate global cache\n const relInfoPromises = relationshipClasses.map(async (relClass) => {\n const relInfo = await this.relInfoFromRelClass(relClass);\n this._relationshipInfoCache.set(relClass.fullName, relInfo);\n if (relInfo) {\n this._relClassNameEndToRefTypes.set(\n [schemaNameLower, relClass.name.toLowerCase()],\n relInfo\n );\n }\n return relInfo;\n });\n\n // Wait for all relationship info to be cached\n await Promise.all(relInfoPromises);\n\n // Process navigation properties with optimized batching\n const propertyBatchSize = 25;\n for (let i = 0; i < ecClasses.length; i += propertyBatchSize) {\n const classBatch = ecClasses.slice(i, i + propertyBatchSize);\n\n const classPromises = classBatch.map(async (ecclass) => {\n const properties = await ecclass.getProperties();\n if (!properties) return;\n\n const classNameLower = ecclass.name.toLowerCase();\n\n // Efficiently filter navigation properties\n const navProps = Array.from(properties).filter((prop) =>\n prop.isNavigation()\n );\n if (navProps.length === 0) return;\n\n const navPropPromises = navProps.map(async (prop) => {\n const relClass = await prop.relationshipClass;\n\n // Use cached relation info\n let relInfo = this._relationshipInfoCache.get(relClass.fullName);\n if (\n relInfo === undefined &&\n !this._relationshipInfoCache.has(relClass.fullName)\n ) {\n relInfo = await this.relInfoFromRelClass(relClass);\n this._relationshipInfoCache.set(relClass.fullName, relInfo);\n }\n\n if (relInfo === undefined) return;\n\n const navPropRefType =\n prop.direction === StrengthDirection.Forward\n ? // eslint-disable-next-line @itwin/no-internal\n relInfo.target\n : // eslint-disable-next-line @itwin/no-internal\n relInfo.source;\n\n this._propQualifierToRefType.set(\n [schemaNameLower, classNameLower, prop.name.toLowerCase()],\n navPropRefType\n );\n });\n\n await Promise.all(navPropPromises);\n });\n\n await Promise.all(classPromises);\n }\n\n this._initedSchemas.set(schema.name, schema.schemaKey);\n }\n\n private async relInfoFromRelClass(\n ecclass: RelationshipClass\n ): Promise<RelTypeInfo | undefined> {\n assert(ecclass.source.constraintClasses !== undefined);\n assert(ecclass.target.constraintClasses !== undefined);\n const [\n [sourceClass, sourceRootBisClass],\n [targetClass, targetRootBisClass],\n ] = await Promise.all([\n this.getAbstractConstraintClass(ecclass.source).then(\n async (constraintClass) => [\n constraintClass,\n await this.getRootBisClass(constraintClass),\n ]\n ),\n this.getAbstractConstraintClass(ecclass.target).then(\n async (constraintClass) => [\n constraintClass,\n await this.getRootBisClass(constraintClass),\n ]\n ),\n ]);\n\n if (\n sourceRootBisClass.name === \"CodeSpec\" ||\n targetRootBisClass.name === \"CodeSpec\"\n )\n return undefined;\n const sourceType =\n ECReferenceTypesCache.bisRootClassToRefType[sourceRootBisClass.name];\n const targetType =\n ECReferenceTypesCache.bisRootClassToRefType[targetRootBisClass.name];\n if (\n (!sourceType &&\n sourceRootBisClass.customAttributes?.has(\"ECDbMap.QueryView\")) ||\n (!targetType &&\n targetRootBisClass.customAttributes?.has(\"ECDbMap.QueryView\"))\n ) {\n // ECView elements are not \"real\" data and transformer does not need to process them.\n // Relationships that point to ECView elements can only be used in ECViews so the mapping is not needed.\n return undefined;\n }\n\n const makeAssertMsg = (root: ECClass, cls: ECClass) =>\n [\n `An unknown root class '${root.fullName}' was encountered while populating`,\n `the nav prop reference type cache for ${cls.fullName}.`,\n \"This is a bug.\",\n ].join(\"\\n\");\n assert(\n sourceType !== undefined,\n makeAssertMsg(sourceRootBisClass, sourceClass)\n );\n assert(\n targetType !== undefined,\n makeAssertMsg(targetRootBisClass, targetClass)\n );\n return { source: sourceType, target: targetType };\n }\n\n public getNavPropRefType(\n schemaName: string,\n className: string,\n propName: string\n ): undefined | ConcreteEntityTypes {\n if (!this._initedSchemas.has(schemaName)) throw new SchemaNotInCacheErr();\n return this._propQualifierToRefType.get([\n schemaName.toLowerCase(),\n className.toLowerCase(),\n propName.toLowerCase(),\n ]);\n }\n\n public getRelationshipEndType(\n schemaName: string,\n className: string\n ): undefined | RelTypeInfo {\n if (!this._initedSchemas.has(schemaName)) throw new SchemaNotInCacheErr();\n return this._relClassNameEndToRefTypes.get([\n schemaName.toLowerCase(),\n className.toLowerCase(),\n ]);\n }\n\n public clear() {\n this._initedSchemas.clear();\n this._propQualifierToRefType.clear();\n this._relClassNameEndToRefTypes.clear();\n this._rootBisClassCache.clear();\n this._relationshipInfoCache.clear();\n this._constraintClassCache.clear();\n }\n}\n"]}
1
+ {"version":3,"file":"ECReferenceTypesCache.js","sourceRoot":"","sources":["../../src/ECReferenceTypesCache.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n/** @packageDocumentation\n * @module iModels\n */\n\nimport { ITwinError, Logger, TupleKeyedMap } from \"@itwin/core-bentley\";\nimport { ConcreteEntityTypes, RelTypeInfo } from \"@itwin/core-common\";\nimport {\n ECClass,\n Mixin,\n Property,\n RelationshipClass,\n RelationshipConstraint,\n Schema,\n SchemaKey,\n StrengthDirection,\n} from \"@itwin/ecschema-metadata\";\nimport { strict as assert } from \"node:assert\";\nimport { IModelDb } from \"@itwin/core-backend\";\nimport { TransformerLoggerCategory } from \"./TransformerLoggerCategory\";\nimport {\n IModelTransformerError,\n IModelTransformerErrorScope,\n} from \"./IModelTransformerError\";\n\n/** The context for transforming a *source* Element to a *target* Element and remapping internal identifiers to the target iModel.\n * @internal\n */\nexport class SchemaNotInCacheErr extends Error {\n public constructor() {\n super(\"Schema was not in cache, initialize that schema\");\n }\n}\n\n/**\n * A cache of the entity types referenced by navprops in ecchemas, as well as the source and target entity types of\n * The transformer needs the referenced type to determine how to resolve references.\n *\n * Using multiple of these usually performs redundant computation, for static schemas at least. A possible future optimization\n * would be to seed the computation from a global cache of non-dynamic schemas, but dynamic schemas can collide willy-nilly\n * @internal\n */\nexport class ECReferenceTypesCache {\n /** nesting based tuple map keyed by qualified property path tuple [schemaName, className, propName] */\n private _propQualifierToRefType = new TupleKeyedMap<\n [string, string, string],\n ConcreteEntityTypes\n >();\n private _relClassNameEndToRefTypes = new TupleKeyedMap<\n [string, string],\n RelTypeInfo\n >();\n private _initedSchemas = new Map<string, SchemaKey>();\n\n private static bisRootClassToRefType: Record<\n string,\n ConcreteEntityTypes | undefined\n > = {\n Element: ConcreteEntityTypes.Element,\n Model: ConcreteEntityTypes.Model,\n ElementAspect: ConcreteEntityTypes.ElementAspect,\n ElementRefersToElements: ConcreteEntityTypes.Relationship,\n ElementDrivesElement: ConcreteEntityTypes.Relationship,\n // code spec is technically a potential root class but it is ignored currently\n // see [ConcreteEntityTypes]($common)\n };\n\n private async getRootBisClass(ecclass: ECClass) {\n let bisRootForConstraint: ECClass = ecclass;\n await ecclass.traverseBaseClasses((baseClass) => {\n // The depth first traversal will descend all the way to the root class before making any lateral traversal\n // of mixin hierarchies, (or if the constraint is a mixin, it will traverse to the root of the mixin hierarchy)\n // Once we see that we've moved laterally, we can terminate early\n const isFirstTest = bisRootForConstraint === ecclass;\n const traversalSwitchedRootPath =\n baseClass.name !== bisRootForConstraint.baseClass?.name;\n const stillTraversingRootPath = isFirstTest || !traversalSwitchedRootPath;\n if (!stillTraversingRootPath) return true; // stop traversal early\n bisRootForConstraint = baseClass;\n return false;\n });\n // if the root class of the constraint was a mixin, use its AppliesToEntityClass\n if (bisRootForConstraint instanceof Mixin) {\n assert(\n bisRootForConstraint.appliesTo !== undefined,\n \"The referenced AppliesToEntityClass could not be found, how did it pass schema validation?\"\n );\n bisRootForConstraint = await this.getRootBisClass(\n await bisRootForConstraint.appliesTo\n );\n }\n return bisRootForConstraint;\n }\n\n private async getAbstractConstraintClass(\n constraint: RelationshipConstraint\n ): Promise<ECClass> {\n // constraint classes must share a base so we can get the root from any of them, just use the first\n const ecclass = await (constraint.constraintClasses?.[0] ||\n constraint.abstractConstraint);\n assert(\n ecclass !== undefined,\n \"At least one constraint class or an abstract constraint must have been defined, the constraint is not valid\"\n );\n return ecclass;\n }\n\n /** initialize from an imodel with metadata */\n public async initAllSchemasInIModel(imodel: IModelDb): Promise<void> {\n const query = `\n WITH RECURSIVE refs(SchemaId) AS (\n SELECT ECInstanceId FROM ECDbMeta.ECSchemaDef WHERE Name='BisCore'\n UNION\n SELECT sr.SourceECInstanceId\n FROM ECDbMeta.SchemaHasSchemaReferences sr\n JOIN refs ON sr.TargetECInstanceId = refs.SchemaId\n )\n SELECT s.Name as name\n FROM refs\n JOIN ECDbMeta.ECSchemaDef s ON refs.SchemaId=s.ECInstanceId\n `;\n\n for await (const row of imodel.createQueryReader(query, undefined, {\n usePrimaryConn: true,\n })) {\n const schemaName = row.name;\n const schemaItemKey = new SchemaKey(schemaName);\n const schema = await imodel.schemaContext.getSchema(schemaItemKey);\n if (!schema) {\n ITwinError.throwError({\n iTwinErrorId: {\n scope: IModelTransformerErrorScope,\n key: IModelTransformerError.SchemaLoadFailed,\n },\n message: `Failed to load schema: ${schemaName}`,\n });\n }\n await this.considerInitSchema(schema);\n }\n }\n\n private async considerInitSchema(schema: Schema): Promise<void> {\n if (this._initedSchemas.has(schema.name)) {\n const cachedSchemaKey = this._initedSchemas.get(schema.name);\n assert(cachedSchemaKey !== undefined);\n const incomingSchemaIsEqualOrOlder =\n schema.schemaKey.compareByVersion(cachedSchemaKey) <= 0;\n if (incomingSchemaIsEqualOrOlder) {\n return;\n }\n }\n return this.initSchema(schema);\n }\n\n private async initSchema(schema: Schema): Promise<void> {\n Logger.logTrace(\n TransformerLoggerCategory.ECReferenceTypesCache,\n `initSchema started for ${schema.name}`\n );\n const schemaNameLower = schema.name.toLowerCase();\n\n // Local dedup map — scoped to this single initSchema call, not persisted\n const localRelInfoMap = new Map<string, Promise<RelTypeInfo | undefined>>();\n\n const getRelInfo = async (relClass: RelationshipClass) => {\n let promise = localRelInfoMap.get(relClass.fullName);\n if (!promise) {\n promise = this.relInfoFromRelClass(relClass);\n localRelInfoMap.set(relClass.fullName, promise);\n }\n return promise;\n };\n\n // Process all classes concurrently\n const classPromises = Array.from(schema.getItems())\n .filter((item): item is ECClass => ECClass.isECClass(item))\n .map(async (ecclass) => {\n // Handle relationship end types\n if (ecclass instanceof RelationshipClass) {\n const relInfo = await getRelInfo(ecclass);\n if (relInfo) {\n this._relClassNameEndToRefTypes.set(\n [schemaNameLower, ecclass.name.toLowerCase()],\n relInfo\n );\n }\n }\n\n // Handle nav props\n const properties = await ecclass.getProperties();\n const classNameLower = ecclass.name.toLowerCase();\n\n const navPropPromises = Array.from(properties)\n .filter((prop: Property) => prop.isNavigation())\n .map(async (prop: Property) => {\n if (!prop.isNavigation()) return;\n const relClass = await prop.relationshipClass;\n const relInfo = await getRelInfo(relClass);\n if (relInfo === undefined) return;\n\n const navPropRefType =\n prop.direction === StrengthDirection.Forward\n ? relInfo.target\n : relInfo.source;\n\n this._propQualifierToRefType.set(\n [schemaNameLower, classNameLower, prop.name.toLowerCase()],\n navPropRefType\n );\n });\n\n await Promise.all(navPropPromises);\n });\n\n await Promise.all(classPromises);\n this._initedSchemas.set(schema.name, schema.schemaKey);\n Logger.logTrace(\n TransformerLoggerCategory.ECReferenceTypesCache,\n `initSchema completed for ${schema.name}`\n );\n }\n\n private async relInfoFromRelClass(\n ecclass: RelationshipClass\n ): Promise<RelTypeInfo | undefined> {\n assert(ecclass.source.constraintClasses !== undefined);\n assert(ecclass.target.constraintClasses !== undefined);\n const [\n [sourceClass, sourceRootBisClass],\n [targetClass, targetRootBisClass],\n ] = await Promise.all([\n this.getAbstractConstraintClass(ecclass.source).then(\n async (constraintClass) => [\n constraintClass,\n await this.getRootBisClass(constraintClass),\n ]\n ),\n this.getAbstractConstraintClass(ecclass.target).then(\n async (constraintClass) => [\n constraintClass,\n await this.getRootBisClass(constraintClass),\n ]\n ),\n ]);\n\n if (\n sourceRootBisClass.name === \"CodeSpec\" ||\n targetRootBisClass.name === \"CodeSpec\"\n )\n return undefined;\n const sourceType =\n ECReferenceTypesCache.bisRootClassToRefType[sourceRootBisClass.name];\n const targetType =\n ECReferenceTypesCache.bisRootClassToRefType[targetRootBisClass.name];\n if (\n (!sourceType &&\n sourceRootBisClass.customAttributes?.has(\"ECDbMap.QueryView\")) ||\n (!targetType &&\n targetRootBisClass.customAttributes?.has(\"ECDbMap.QueryView\"))\n ) {\n // ECView elements are not \"real\" data and transformer does not need to process them.\n // Relationships that point to ECView elements can only be used in ECViews so the mapping is not needed.\n return undefined;\n }\n\n const makeAssertMsg = (root: ECClass, cls: ECClass) =>\n [\n `An unknown root class '${root.fullName}' was encountered while populating`,\n `the nav prop reference type cache for ${cls.fullName}.`,\n \"This is a bug.\",\n ].join(\"\\n\");\n assert(\n sourceType !== undefined,\n makeAssertMsg(sourceRootBisClass, sourceClass)\n );\n assert(\n targetType !== undefined,\n makeAssertMsg(targetRootBisClass, targetClass)\n );\n return { source: sourceType, target: targetType };\n }\n\n public getNavPropRefType(\n schemaName: string,\n className: string,\n propName: string\n ): undefined | ConcreteEntityTypes {\n if (!this._initedSchemas.has(schemaName)) throw new SchemaNotInCacheErr();\n return this._propQualifierToRefType.get([\n schemaName.toLowerCase(),\n className.toLowerCase(),\n propName.toLowerCase(),\n ]);\n }\n\n public getRelationshipEndType(\n schemaName: string,\n className: string\n ): undefined | RelTypeInfo {\n if (!this._initedSchemas.has(schemaName)) throw new SchemaNotInCacheErr();\n return this._relClassNameEndToRefTypes.get([\n schemaName.toLowerCase(),\n className.toLowerCase(),\n ]);\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"ECSqlReaderAsyncIterableIteratorAdapter.d.ts","sourceRoot":"","sources":["../../src/ECSqlReaderAsyncIterableIteratorAdapter.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEhE;;;;GAIG;AACH,qBAAa,uCACX,YAAW,qBAAqB,CAAC,aAAa,CAAC;IAE5B,OAAO,CAAC,YAAY;gBAAZ,YAAY,EAAE,WAAW;IAE7C,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,qBAAqB,CAAC,aAAa,CAAC;IAIxD,IAAI,IAAI,OAAO,CAAC,cAAc,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC;CAOjE;AAED;;;;GAIG;AACH,wBAAgB,wCAAwC,CACtD,WAAW,EACP,CAAC,WAAW,GAAG,qBAAqB,CAAC,aAAa,CAAC,CAAC,GACpD,IAAI,CAAC,WAAW,EAAE,MAAM,qBAAqB,CAAC,aAAa,CAAC,CAAC,GAChE,qBAAqB,CAAC,aAAa,CAAC,CAUtC"}
1
+ {"version":3,"file":"ECSqlReaderAsyncIterableIteratorAdapter.d.ts","sourceRoot":"","sources":["../../src/ECSqlReaderAsyncIterableIteratorAdapter.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEhE;;;;GAIG;AACH,qBAAa,uCAAwC,YAAW,qBAAqB,CAAC,aAAa,CAAC;IAC/E,OAAO,CAAC,YAAY;IAAvC,YAA2B,YAAY,EAAE,WAAW,EAAI;IAEjD,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,qBAAqB,CAAC,aAAa,CAAC,CAEpE;IAEY,IAAI,IAAI,OAAO,CAAC,cAAc,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC,CAM/D;CACF;AAED;;;;GAIG;AACH,wBAAgB,wCAAwC,CACtD,WAAW,EACP,CAAC,WAAW,GAAG,qBAAqB,CAAC,aAAa,CAAC,CAAC,GACpD,IAAI,CAAC,WAAW,EAAE,MAAM,qBAAqB,CAAC,aAAa,CAAC,CAAC,GAChE,qBAAqB,CAAC,aAAa,CAAC,CAUtC"}
@@ -1 +1 @@
1
- {"version":3,"file":"ECSqlReaderAsyncIterableIteratorAdapter.js","sourceRoot":"","sources":["../../src/ECSqlReaderAsyncIterableIteratorAdapter.ts"],"names":[],"mappings":";AAAA;;;gGAGgG;;;AAgChG,4FAcC;AA1CD;;;;GAIG;AACH,MAAa,uCAAuC;IAGvB;IAA3B,YAA2B,YAAyB;QAAzB,iBAAY,GAAZ,YAAY,CAAa;IAAG,CAAC;IAEjD,CAAC,MAAM,CAAC,aAAa,CAAC;QAC3B,OAAO,IAAI,CAAC;IACd,CAAC;IAEM,KAAK,CAAC,IAAI;QACf,MAAM,IAAI,GAAG,CAAC,CAAC,MAAM,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,CAAC;QAC/C,OAAO;YACL,IAAI;YACJ,KAAK,EAAE,IAAI,CAAC,YAAY,CAAC,OAAO;SACjC,CAAC;IACJ,CAAC;CACF;AAhBD,0FAgBC;AAED;;;;GAIG;AACH,SAAgB,wCAAwC,CACtD,WAEiE;IAEjE,IAAI,MAAM,CAAC,aAAa,IAAI,WAAW,EAAE,CAAC;QACxC,kBAAkB;QAClB,OAAO,WAAW,CAAC;IACrB,CAAC;SAAM,CAAC;QACN,kBAAkB;QAClB,OAAO,IAAI,uCAAuC,CAChD,WAA0B,CAC3B,CAAC;IACJ,CAAC;AACH,CAAC","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport { ECSqlReader, QueryRowProxy } from \"@itwin/core-common\";\n\n/**\n * Adapter class for ECSqlReader for AsyncIterableIterator interface.\n * It allows to iterate through query results in itwin 3.x using for await() syntax like using itwin 4.x version.\n * @internal\n */\nexport class ECSqlReaderAsyncIterableIteratorAdapter\n implements AsyncIterableIterator<QueryRowProxy>\n{\n public constructor(private _ecSqlReader: ECSqlReader) {}\n\n public [Symbol.asyncIterator](): AsyncIterableIterator<QueryRowProxy> {\n return this;\n }\n\n public async next(): Promise<IteratorResult<QueryRowProxy, any>> {\n const done = !(await this._ecSqlReader.step());\n return {\n done,\n value: this._ecSqlReader.current,\n };\n }\n}\n\n/**\n * Wraps ECSqlReader with ECSqlReaderAsyncIterableIteratorAdapter if it's needed.\n * @param ecSqlReader ECSqlReader isntance from itwin 3.x or 4.x version\n * @internal\n */\nexport function ensureECSqlReaderIsAsyncIterableIterator(\n ecSqlReader:\n | (ECSqlReader & AsyncIterableIterator<QueryRowProxy>)\n | Omit<ECSqlReader, keyof AsyncIterableIterator<QueryRowProxy>>\n): AsyncIterableIterator<QueryRowProxy> {\n if (Symbol.asyncIterator in ecSqlReader) {\n // using itwin 4.x\n return ecSqlReader;\n } else {\n // using itwin 3.x\n return new ECSqlReaderAsyncIterableIteratorAdapter(\n ecSqlReader as ECSqlReader\n );\n }\n}\n"]}
1
+ {"version":3,"file":"ECSqlReaderAsyncIterableIteratorAdapter.js","sourceRoot":"","sources":["../../src/ECSqlReaderAsyncIterableIteratorAdapter.ts"],"names":[],"mappings":";AAAA;;;gGAGgG;;;;AAIhG;;;;GAIG;AACH;IAC6B,YAAY;IAAvC,YAA2B,YAAyB;4BAAzB,YAAY;IAAgB,CAAC;IAEjD,CAAC,MAAM,CAAC,aAAa,CAAC;QAC3B,OAAO,IAAI,CAAC;IACd,CAAC;IAEM,KAAK,CAAC,IAAI;QACf,MAAM,IAAI,GAAG,CAAC,CAAC,MAAM,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,CAAC;QAC/C,OAAO;YACL,IAAI;YACJ,KAAK,EAAE,IAAI,CAAC,YAAY,CAAC,OAAO;SACjC,CAAC;IACJ,CAAC;CACF;;AAED;;;;GAIG;AACH,kDACE,WAEiE;IAEjE,IAAI,MAAM,CAAC,aAAa,IAAI,WAAW,EAAE,CAAC;QACxC,kBAAkB;QAClB,OAAO,WAAW,CAAC;IACrB,CAAC;SAAM,CAAC;QACN,kBAAkB;QAClB,OAAO,IAAI,uCAAuC,CAChD,WAA0B,CAC3B,CAAC;IACJ,CAAC;AACH,CAAC","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport { ECSqlReader, QueryRowProxy } from \"@itwin/core-common\";\n\n/**\n * Adapter class for ECSqlReader for AsyncIterableIterator interface.\n * It allows to iterate through query results in itwin 3.x using for await() syntax like using itwin 4.x version.\n * @internal\n */\nexport class ECSqlReaderAsyncIterableIteratorAdapter implements AsyncIterableIterator<QueryRowProxy> {\n public constructor(private _ecSqlReader: ECSqlReader) {}\n\n public [Symbol.asyncIterator](): AsyncIterableIterator<QueryRowProxy> {\n return this;\n }\n\n public async next(): Promise<IteratorResult<QueryRowProxy, any>> {\n const done = !(await this._ecSqlReader.step());\n return {\n done,\n value: this._ecSqlReader.current,\n };\n }\n}\n\n/**\n * Wraps ECSqlReader with ECSqlReaderAsyncIterableIteratorAdapter if it's needed.\n * @param ecSqlReader ECSqlReader isntance from itwin 3.x or 4.x version\n * @internal\n */\nexport function ensureECSqlReaderIsAsyncIterableIterator(\n ecSqlReader:\n | (ECSqlReader & AsyncIterableIterator<QueryRowProxy>)\n | Omit<ECSqlReader, keyof AsyncIterableIterator<QueryRowProxy>>\n): AsyncIterableIterator<QueryRowProxy> {\n if (Symbol.asyncIterator in ecSqlReader) {\n // using itwin 4.x\n return ecSqlReader;\n } else {\n // using itwin 3.x\n return new ECSqlReaderAsyncIterableIteratorAdapter(\n ecSqlReader as ECSqlReader\n );\n }\n}\n"]}
@@ -0,0 +1,16 @@
1
+ import { EditTxn, ElementAspect, IModelDb } from "@itwin/core-backend";
2
+ import { Id64String } from "@itwin/core-bentley";
3
+ /** Deletes replaceable ElementAspects for target owners while preserving excluded classes and transformer provenance aspects.
4
+ * @internal
5
+ */
6
+ export declare class ElementAspectCleanup {
7
+ private readonly _targetDb;
8
+ private readonly _editTxn;
9
+ private readonly _deleteAspect;
10
+ constructor(_targetDb: IModelDb, _editTxn: EditTxn, _deleteAspect: (aspect: ElementAspect) => Promise<void>);
11
+ /** Deletes replaceable unique and multi-aspects owned by the supplied target elements.
12
+ * Excluded classes and transformer provenance aspects for `provenanceScopeId` are preserved. Each deletion is performed through the configured callback and requires the target `EditTxn` to be active.
13
+ */
14
+ delete(targetElementIds: ReadonlySet<Id64String>, excludedElementAspectClassFullNames: ReadonlySet<string>, provenanceScopeId?: Id64String, pageSize?: number): Promise<void>;
15
+ }
16
+ //# sourceMappingURL=ElementAspectCleanup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ElementAspectCleanup.d.ts","sourceRoot":"","sources":["../../src/ElementAspectCleanup.ts"],"names":[],"mappings":"AAKA,OAAO,EACL,OAAO,EACP,aAAa,EAIb,QAAQ,EACT,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAGjD;;GAEG;AACH,qBAAa,oBAAoB;IAE7B,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,aAAa;IAHhC,YACmB,SAAS,EAAE,QAAQ,EACnB,QAAQ,EAAE,OAAO,EACjB,aAAa,EAAE,CAAC,MAAM,EAAE,aAAa,KAAK,OAAO,CAAC,IAAI,CAAC,EACtE;IAEJ;;OAEG;IACU,MAAM,CACjB,gBAAgB,EAAE,WAAW,CAAC,UAAU,CAAC,EACzC,mCAAmC,EAAE,WAAW,CAAC,MAAM,CAAC,EACxD,iBAAiB,CAAC,EAAE,UAAU,EAC9B,QAAQ,SAAwB,GAC/B,OAAO,CAAC,IAAI,CAAC,CA8Cf;CACF"}
@@ -0,0 +1,87 @@
1
+ "use strict";
2
+ /*---------------------------------------------------------------------------------------------
3
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
4
+ * See LICENSE.md in the project root for license terms and full copyright notice.
5
+ *--------------------------------------------------------------------------------------------*/
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.ElementAspectCleanup = void 0;
8
+ const core_backend_1 = require("@itwin/core-backend");
9
+ const core_common_1 = require("@itwin/core-common");
10
+ /** Deletes replaceable ElementAspects for target owners while preserving excluded classes and transformer provenance aspects.
11
+ * @internal
12
+ */
13
+ class ElementAspectCleanup {
14
+ _targetDb;
15
+ _editTxn;
16
+ _deleteAspect;
17
+ constructor(_targetDb, _editTxn, _deleteAspect) {
18
+ this._targetDb = _targetDb;
19
+ this._editTxn = _editTxn;
20
+ this._deleteAspect = _deleteAspect;
21
+ }
22
+ /** Deletes replaceable unique and multi-aspects owned by the supplied target elements.
23
+ * Excluded classes and transformer provenance aspects for `provenanceScopeId` are preserved. Each deletion is performed through the configured callback and requires the target `EditTxn` to be active.
24
+ */
25
+ async delete(targetElementIds, excludedElementAspectClassFullNames, provenanceScopeId, pageSize = core_backend_1.IModelDb.maxLimit - 1) {
26
+ if (!this._editTxn.isActive) {
27
+ throw new Error("The target EditTxn must be active when deleting ElementAspects.");
28
+ }
29
+ if (pageSize <= 0 || !Number.isSafeInteger(pageSize)) {
30
+ throw new Error("ElementAspect deletion pageSize must be a positive integer.");
31
+ }
32
+ if (targetElementIds.size === 0)
33
+ return;
34
+ const targetExcludedElementAspectClassFullNames = [
35
+ ...excludedElementAspectClassFullNames,
36
+ ].filter((classFullName) => this._targetDb.containsClass(classFullName));
37
+ for (const aspectClassFullName of [
38
+ core_backend_1.ElementUniqueAspect.classFullName,
39
+ core_backend_1.ElementMultiAspect.classFullName,
40
+ ]) {
41
+ const { ecsql, params } = replaceableAspectQuery(aspectClassFullName, targetElementIds, targetExcludedElementAspectClassFullNames, provenanceScopeId, pageSize);
42
+ while (true) {
43
+ // Drain the full page before deleting: mutating a table while a reader is still
44
+ // scanning it is unsafe.
45
+ const candidateIds = [];
46
+ for await (const row of this._targetDb.createQueryReader(ecsql, params, { usePrimaryConn: true })) {
47
+ candidateIds.push(row.id);
48
+ }
49
+ if (candidateIds.length === 0)
50
+ break;
51
+ for (const aspectId of candidateIds) {
52
+ const aspect = this._targetDb.elements.getAspect(aspectId);
53
+ await this._deleteAspect(aspect);
54
+ }
55
+ }
56
+ }
57
+ }
58
+ }
59
+ exports.ElementAspectCleanup = ElementAspectCleanup;
60
+ /** Builds the page query for aspects of `aspectClassFullName` owned by `elementIds`, skipping excluded classes and provenance aspects for `provenanceScopeId`. */
61
+ function replaceableAspectQuery(aspectClassFullName, elementIds, excludedClassFullNames, provenanceScopeId, pageSize) {
62
+ const params = new core_common_1.QueryBinder().bindIdSet("elementIds", elementIds);
63
+ const conditions = [];
64
+ if (excludedClassFullNames.length > 0) {
65
+ conditions.push(`aspect.ECClassId IS NOT (${excludedClassFullNames.join(", ")})`);
66
+ }
67
+ // ExternalSourceAspect is a multi-aspect, so provenance aspects are only found
68
+ // when querying ElementMultiAspect. For each candidate, check whether it is a
69
+ // provenance aspect rather than listing every provenance aspect on each page.
70
+ if (provenanceScopeId !== undefined &&
71
+ aspectClassFullName === core_backend_1.ElementMultiAspect.classFullName) {
72
+ params.bindId("provenanceScopeId", provenanceScopeId);
73
+ conditions.push(`NOT EXISTS (
74
+ SELECT 1 FROM ${core_backend_1.ExternalSourceAspect.classFullName} esa
75
+ WHERE esa.ECInstanceId = aspect.ECInstanceId
76
+ AND (esa.Element.Id = :provenanceScopeId OR esa.Scope.Id = :provenanceScopeId)
77
+ )`);
78
+ }
79
+ const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
80
+ const ecsql = `SELECT aspect.ECInstanceId as id
81
+ FROM ${aspectClassFullName} aspect
82
+ INNER JOIN IdSet(:elementIds) ids ON ids.id = aspect.Element.Id
83
+ ${whereClause}
84
+ LIMIT ${pageSize}`;
85
+ return { ecsql, params };
86
+ }
87
+ //# sourceMappingURL=ElementAspectCleanup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ElementAspectCleanup.js","sourceRoot":"","sources":["../../src/ElementAspectCleanup.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport {\n EditTxn,\n ElementAspect,\n ElementMultiAspect,\n ElementUniqueAspect,\n ExternalSourceAspect,\n IModelDb,\n} from \"@itwin/core-backend\";\nimport { Id64String } from \"@itwin/core-bentley\";\nimport { QueryBinder } from \"@itwin/core-common\";\n\n/** Deletes replaceable ElementAspects for target owners while preserving excluded classes and transformer provenance aspects.\n * @internal\n */\nexport class ElementAspectCleanup {\n public constructor(\n private readonly _targetDb: IModelDb,\n private readonly _editTxn: EditTxn,\n private readonly _deleteAspect: (aspect: ElementAspect) => Promise<void>\n ) {}\n\n /** Deletes replaceable unique and multi-aspects owned by the supplied target elements.\n * Excluded classes and transformer provenance aspects for `provenanceScopeId` are preserved. Each deletion is performed through the configured callback and requires the target `EditTxn` to be active.\n */\n public async delete(\n targetElementIds: ReadonlySet<Id64String>,\n excludedElementAspectClassFullNames: ReadonlySet<string>,\n provenanceScopeId?: Id64String,\n pageSize = IModelDb.maxLimit - 1\n ): Promise<void> {\n if (!this._editTxn.isActive) {\n throw new Error(\n \"The target EditTxn must be active when deleting ElementAspects.\"\n );\n }\n if (pageSize <= 0 || !Number.isSafeInteger(pageSize)) {\n throw new Error(\n \"ElementAspect deletion pageSize must be a positive integer.\"\n );\n }\n if (targetElementIds.size === 0) return;\n\n const targetExcludedElementAspectClassFullNames = [\n ...excludedElementAspectClassFullNames,\n ].filter((classFullName) => this._targetDb.containsClass(classFullName));\n for (const aspectClassFullName of [\n ElementUniqueAspect.classFullName,\n ElementMultiAspect.classFullName,\n ]) {\n const { ecsql, params } = replaceableAspectQuery(\n aspectClassFullName,\n targetElementIds,\n targetExcludedElementAspectClassFullNames,\n provenanceScopeId,\n pageSize\n );\n while (true) {\n // Drain the full page before deleting: mutating a table while a reader is still\n // scanning it is unsafe.\n const candidateIds: Id64String[] = [];\n for await (const row of this._targetDb.createQueryReader(\n ecsql,\n params,\n { usePrimaryConn: true }\n )) {\n candidateIds.push(row.id);\n }\n if (candidateIds.length === 0) break;\n\n for (const aspectId of candidateIds) {\n const aspect = this._targetDb.elements.getAspect(aspectId);\n await this._deleteAspect(aspect);\n }\n }\n }\n }\n}\n\n/** Builds the page query for aspects of `aspectClassFullName` owned by `elementIds`, skipping excluded classes and provenance aspects for `provenanceScopeId`. */\nfunction replaceableAspectQuery(\n aspectClassFullName: string,\n elementIds: ReadonlySet<Id64String>,\n excludedClassFullNames: readonly string[],\n provenanceScopeId: Id64String | undefined,\n pageSize: number\n): { ecsql: string; params: QueryBinder } {\n const params = new QueryBinder().bindIdSet(\"elementIds\", elementIds);\n const conditions: string[] = [];\n if (excludedClassFullNames.length > 0) {\n conditions.push(\n `aspect.ECClassId IS NOT (${excludedClassFullNames.join(\", \")})`\n );\n }\n // ExternalSourceAspect is a multi-aspect, so provenance aspects are only found\n // when querying ElementMultiAspect. For each candidate, check whether it is a\n // provenance aspect rather than listing every provenance aspect on each page.\n if (\n provenanceScopeId !== undefined &&\n aspectClassFullName === ElementMultiAspect.classFullName\n ) {\n params.bindId(\"provenanceScopeId\", provenanceScopeId);\n conditions.push(`NOT EXISTS (\n SELECT 1 FROM ${ExternalSourceAspect.classFullName} esa\n WHERE esa.ECInstanceId = aspect.ECInstanceId\n AND (esa.Element.Id = :provenanceScopeId OR esa.Scope.Id = :provenanceScopeId)\n )`);\n }\n const whereClause =\n conditions.length > 0 ? `WHERE ${conditions.join(\" AND \")}` : \"\";\n const ecsql = `SELECT aspect.ECInstanceId as id\n FROM ${aspectClassFullName} aspect\n INNER JOIN IdSet(:elementIds) ids ON ids.id = aspect.Element.Id\n ${whereClause}\n LIMIT ${pageSize}`;\n return { ecsql, params };\n}\n"]}
@@ -0,0 +1,44 @@
1
+ import { Id64String } from "@itwin/core-bentley";
2
+ export type ElementAspectExportPreparation = (excludedElementAspectClassFullNames: ReadonlySet<string>, ownerElementIds: ReadonlySet<Id64String>) => Promise<void>;
3
+ /** Coordinates scoped batches of accepted ElementAspect owners, including preparation before aspect export.
4
+ * @internal
5
+ */
6
+ export declare class ElementAspectExportCoordinator {
7
+ private readonly _defaultBatchSize;
8
+ private readonly _excludedClassFullNames;
9
+ private readonly _exportAspects;
10
+ private readonly _resetCaches;
11
+ private readonly _acceptedOwnerIds;
12
+ private readonly _processedOwnerIds;
13
+ private _batchSize;
14
+ private _depth;
15
+ private _prepare?;
16
+ constructor(_defaultBatchSize: number, _excludedClassFullNames: () => ReadonlySet<string>, _exportAspects: (ownerElementIds: ReadonlySet<Id64String>) => Promise<void>, _resetCaches?: () => void);
17
+ /** Whether an accepted-owner collection scope is active. */
18
+ get isActive(): boolean;
19
+ /** Sets the callback that prepares each accepted-owner group before its aspects are exported. */
20
+ setPreparation(prepare: ElementAspectExportPreparation): void;
21
+ /** Begins an accepted-owner collection scope.
22
+ * Nested scopes share the outer scope's state and batch size.
23
+ */
24
+ begin(batchSize?: number): void;
25
+ /** Ends an accepted-owner collection scope.
26
+ * Ending the outermost scope exports pending owners and resets all scope state.
27
+ */
28
+ end(): Promise<void>;
29
+ /** Discards the active scope and its pending owner state without exporting it. */
30
+ abort(): void;
31
+ /** Runs element export within an accepted-owner collection scope.
32
+ * A scope created by this call is aborted if element export fails; an existing outer scope remains responsible for its own failure handling.
33
+ */
34
+ run(exportElements: () => Promise<void>): Promise<void>;
35
+ /** Adds an accepted source owner to the current group and exports the group when it reaches the configured batch size. */
36
+ addAcceptedOwner(elementId: Id64String): Promise<void>;
37
+ /** Runs preparation and aspect export for an explicit owner set in bounded groups. */
38
+ exportOwners(ownerElementIds: ReadonlySet<Id64String>): Promise<void>;
39
+ private exportOwnerBatch;
40
+ private flush;
41
+ private resetScopeState;
42
+ private reset;
43
+ }
44
+ //# sourceMappingURL=ElementAspectExportCoordinator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ElementAspectExportCoordinator.d.ts","sourceRoot":"","sources":["../../src/ElementAspectExportCoordinator.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjD,MAAM,MAAM,8BAA8B,GAAG,CAC3C,mCAAmC,EAAE,WAAW,CAAC,MAAM,CAAC,EACxD,eAAe,EAAE,WAAW,CAAC,UAAU,CAAC,KACrC,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnB;;GAEG;AACH,qBAAa,8BAA8B;IAQvC,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAClC,OAAO,CAAC,QAAQ,CAAC,uBAAuB;IACxC,OAAO,CAAC,QAAQ,CAAC,cAAc;IAG/B,OAAO,CAAC,QAAQ,CAAC,YAAY;IAZ/B,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAyB;IAC3D,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAyB;IAC5D,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,QAAQ,CAAC,CAAiC;IAElD,YACmB,iBAAiB,EAAE,MAAM,EACzB,uBAAuB,EAAE,MAAM,WAAW,CAAC,MAAM,CAAC,EAClD,cAAc,EAAE,CAC/B,eAAe,EAAE,WAAW,CAAC,UAAU,CAAC,KACrC,OAAO,CAAC,IAAI,CAAC,EACD,YAAY,GAAE,MAAM,IAAe,EAGrD;IAED,4DAA4D;IAC5D,IAAW,QAAQ,IAAI,OAAO,CAE7B;IAED,iGAAiG;IAC1F,cAAc,CAAC,OAAO,EAAE,8BAA8B,GAAG,IAAI,CAEnE;IAED;;OAEG;IACI,KAAK,CAAC,SAAS,SAAyB,GAAG,IAAI,CAOrD;IAED;;OAEG;IACU,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,CAehC;IAED,kFAAkF;IAC3E,KAAK,IAAI,IAAI,CAEnB;IAED;;OAEG;IACU,GAAG,CAAC,cAAc,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAcnE;IAED,0HAA0H;IAC7G,gBAAgB,CAAC,SAAS,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAOlE;IAED,sFAAsF;IACzE,YAAY,CACvB,eAAe,EAAE,WAAW,CAAC,UAAU,CAAC,GACvC,OAAO,CAAC,IAAI,CAAC,CA8Bf;YAEa,gBAAgB;YAOhB,KAAK;IAMnB,OAAO,CAAC,eAAe;IAKvB,OAAO,CAAC,KAAK;CAKd"}