@itwin/core-backend 5.10.0-dev.8 → 5.10.0

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 (278) hide show
  1. package/CHANGELOG.md +45 -1
  2. package/lib/cjs/BriefcaseManager.d.ts +8 -1
  3. package/lib/cjs/BriefcaseManager.d.ts.map +1 -1
  4. package/lib/cjs/BriefcaseManager.js.map +1 -1
  5. package/lib/cjs/Category.d.ts +4 -4
  6. package/lib/cjs/Category.js.map +1 -1
  7. package/lib/cjs/ChangesetECAdaptor.d.ts +6 -6
  8. package/lib/cjs/ChangesetECAdaptor.js +4 -4
  9. package/lib/cjs/ChangesetECAdaptor.js.map +1 -1
  10. package/lib/cjs/ChangesetReader.d.ts +84 -1
  11. package/lib/cjs/ChangesetReader.d.ts.map +1 -1
  12. package/lib/cjs/ChangesetReader.js +108 -12
  13. package/lib/cjs/ChangesetReader.js.map +1 -1
  14. package/lib/cjs/ClassRegistry.d.ts +3 -3
  15. package/lib/cjs/ClassRegistry.js +3 -3
  16. package/lib/cjs/ClassRegistry.js.map +1 -1
  17. package/lib/cjs/CodeSpecs.d.ts +3 -3
  18. package/lib/cjs/CodeSpecs.js.map +1 -1
  19. package/lib/cjs/DisplayStyle.d.ts +2 -2
  20. package/lib/cjs/DisplayStyle.js.map +1 -1
  21. package/lib/cjs/ECSqlStatement.d.ts.map +1 -1
  22. package/lib/cjs/ECSqlStatement.js +4 -0
  23. package/lib/cjs/ECSqlStatement.js.map +1 -1
  24. package/lib/cjs/ECSqlSyncReader.d.ts.map +1 -1
  25. package/lib/cjs/ECSqlSyncReader.js +1 -0
  26. package/lib/cjs/ECSqlSyncReader.js.map +1 -1
  27. package/lib/cjs/Element.d.ts +16 -13
  28. package/lib/cjs/Element.d.ts.map +1 -1
  29. package/lib/cjs/Element.js +8 -5
  30. package/lib/cjs/Element.js.map +1 -1
  31. package/lib/cjs/ElementAspect.d.ts +1 -1
  32. package/lib/cjs/ElementAspect.js.map +1 -1
  33. package/lib/cjs/ElementTreeWalker.d.ts +5 -5
  34. package/lib/cjs/ElementTreeWalker.js.map +1 -1
  35. package/lib/cjs/Entity.d.ts +13 -5
  36. package/lib/cjs/Entity.d.ts.map +1 -1
  37. package/lib/cjs/Entity.js +13 -5
  38. package/lib/cjs/Entity.js.map +1 -1
  39. package/lib/cjs/ExternalSource.d.ts +2 -2
  40. package/lib/cjs/ExternalSource.js.map +1 -1
  41. package/lib/cjs/IModelDb.d.ts +112 -40
  42. package/lib/cjs/IModelDb.d.ts.map +1 -1
  43. package/lib/cjs/IModelDb.js +215 -42
  44. package/lib/cjs/IModelDb.js.map +1 -1
  45. package/lib/cjs/LineStyle.d.ts +6 -6
  46. package/lib/cjs/LineStyle.js.map +1 -1
  47. package/lib/cjs/LocalHub.d.ts +6 -0
  48. package/lib/cjs/LocalHub.d.ts.map +1 -1
  49. package/lib/cjs/LocalHub.js +23 -0
  50. package/lib/cjs/LocalHub.js.map +1 -1
  51. package/lib/cjs/Material.d.ts +1 -1
  52. package/lib/cjs/Material.js.map +1 -1
  53. package/lib/cjs/Model.d.ts +6 -6
  54. package/lib/cjs/Model.js.map +1 -1
  55. package/lib/cjs/Relationship.d.ts +13 -11
  56. package/lib/cjs/Relationship.d.ts.map +1 -1
  57. package/lib/cjs/Relationship.js +9 -7
  58. package/lib/cjs/Relationship.js.map +1 -1
  59. package/lib/cjs/SheetIndex.d.ts +4 -4
  60. package/lib/cjs/SheetIndex.js.map +1 -1
  61. package/lib/cjs/Texture.d.ts +1 -1
  62. package/lib/cjs/Texture.js.map +1 -1
  63. package/lib/cjs/TxnManager.d.ts.map +1 -1
  64. package/lib/cjs/TxnManager.js +7 -0
  65. package/lib/cjs/TxnManager.js.map +1 -1
  66. package/lib/cjs/ViewDefinition.d.ts +6 -6
  67. package/lib/cjs/ViewDefinition.js.map +1 -1
  68. package/lib/cjs/annotations/ElementDrivesTextAnnotation.d.ts +1 -1
  69. package/lib/cjs/annotations/ElementDrivesTextAnnotation.js.map +1 -1
  70. package/lib/cjs/annotations/FrameGeometry.d.ts.map +1 -1
  71. package/lib/cjs/annotations/FrameGeometry.js +2 -3
  72. package/lib/cjs/annotations/FrameGeometry.js.map +1 -1
  73. package/lib/cjs/assets/Settings/Schemas/Base.Schema.json +6 -2
  74. package/lib/cjs/assets/Settings/Schemas/Gcs.schema.json +1 -0
  75. package/lib/cjs/domains/FunctionalElements.d.ts +1 -1
  76. package/lib/cjs/domains/FunctionalElements.js.map +1 -1
  77. package/lib/cjs/domains/GenericElements.d.ts +2 -2
  78. package/lib/cjs/domains/GenericElements.js.map +1 -1
  79. package/lib/cjs/internal/ChannelAdmin.d.ts +2 -2
  80. package/lib/cjs/internal/ChannelAdmin.js.map +1 -1
  81. package/lib/cjs/internal/ElementLRUCache.d.ts.map +1 -1
  82. package/lib/cjs/internal/ElementLRUCache.js +23 -4
  83. package/lib/cjs/internal/ElementLRUCache.js.map +1 -1
  84. package/lib/cjs/internal/HubMock.d.ts +24 -1
  85. package/lib/cjs/internal/HubMock.d.ts.map +1 -1
  86. package/lib/cjs/internal/HubMock.js +60 -39
  87. package/lib/cjs/internal/HubMock.js.map +1 -1
  88. package/lib/cjs/internal/ServerBasedLocks.d.ts +19 -1
  89. package/lib/cjs/internal/ServerBasedLocks.d.ts.map +1 -1
  90. package/lib/cjs/internal/ServerBasedLocks.js +55 -1
  91. package/lib/cjs/internal/ServerBasedLocks.js.map +1 -1
  92. package/lib/cjs/internal/cross-package.d.ts +1 -1
  93. package/lib/cjs/internal/cross-package.d.ts.map +1 -1
  94. package/lib/cjs/internal/cross-package.js +1 -2
  95. package/lib/cjs/internal/cross-package.js.map +1 -1
  96. package/lib/cjs/internal/workspace/SettingsSchemasImpl.d.ts.map +1 -1
  97. package/lib/cjs/internal/workspace/SettingsSchemasImpl.js +55 -9
  98. package/lib/cjs/internal/workspace/SettingsSchemasImpl.js.map +1 -1
  99. package/lib/cjs/internal/workspace/WorkspaceImpl.d.ts.map +1 -1
  100. package/lib/cjs/internal/workspace/WorkspaceImpl.js +7 -11
  101. package/lib/cjs/internal/workspace/WorkspaceImpl.js.map +1 -1
  102. package/lib/cjs/workspace/SettingsSchemas.d.ts +20 -3
  103. package/lib/cjs/workspace/SettingsSchemas.d.ts.map +1 -1
  104. package/lib/cjs/workspace/SettingsSchemas.js.map +1 -1
  105. package/lib/cjs/workspace/Workspace.d.ts +3 -1
  106. package/lib/cjs/workspace/Workspace.d.ts.map +1 -1
  107. package/lib/cjs/workspace/Workspace.js.map +1 -1
  108. package/lib/esm/BriefcaseManager.d.ts +8 -1
  109. package/lib/esm/BriefcaseManager.d.ts.map +1 -1
  110. package/lib/esm/BriefcaseManager.js.map +1 -1
  111. package/lib/esm/Category.d.ts +4 -4
  112. package/lib/esm/Category.js.map +1 -1
  113. package/lib/esm/ChangesetECAdaptor.d.ts +6 -6
  114. package/lib/esm/ChangesetECAdaptor.js +4 -4
  115. package/lib/esm/ChangesetECAdaptor.js.map +1 -1
  116. package/lib/esm/ChangesetReader.d.ts +84 -1
  117. package/lib/esm/ChangesetReader.d.ts.map +1 -1
  118. package/lib/esm/ChangesetReader.js +108 -12
  119. package/lib/esm/ChangesetReader.js.map +1 -1
  120. package/lib/esm/ClassRegistry.d.ts +3 -3
  121. package/lib/esm/ClassRegistry.js +3 -3
  122. package/lib/esm/ClassRegistry.js.map +1 -1
  123. package/lib/esm/CodeSpecs.d.ts +3 -3
  124. package/lib/esm/CodeSpecs.js.map +1 -1
  125. package/lib/esm/DisplayStyle.d.ts +2 -2
  126. package/lib/esm/DisplayStyle.js.map +1 -1
  127. package/lib/esm/ECSqlStatement.d.ts.map +1 -1
  128. package/lib/esm/ECSqlStatement.js +4 -0
  129. package/lib/esm/ECSqlStatement.js.map +1 -1
  130. package/lib/esm/ECSqlSyncReader.d.ts.map +1 -1
  131. package/lib/esm/ECSqlSyncReader.js +1 -0
  132. package/lib/esm/ECSqlSyncReader.js.map +1 -1
  133. package/lib/esm/Element.d.ts +16 -13
  134. package/lib/esm/Element.d.ts.map +1 -1
  135. package/lib/esm/Element.js +8 -5
  136. package/lib/esm/Element.js.map +1 -1
  137. package/lib/esm/ElementAspect.d.ts +1 -1
  138. package/lib/esm/ElementAspect.js.map +1 -1
  139. package/lib/esm/ElementTreeWalker.d.ts +5 -5
  140. package/lib/esm/ElementTreeWalker.js.map +1 -1
  141. package/lib/esm/Entity.d.ts +13 -5
  142. package/lib/esm/Entity.d.ts.map +1 -1
  143. package/lib/esm/Entity.js +13 -5
  144. package/lib/esm/Entity.js.map +1 -1
  145. package/lib/esm/ExternalSource.d.ts +2 -2
  146. package/lib/esm/ExternalSource.js.map +1 -1
  147. package/lib/esm/IModelDb.d.ts +112 -40
  148. package/lib/esm/IModelDb.d.ts.map +1 -1
  149. package/lib/esm/IModelDb.js +216 -43
  150. package/lib/esm/IModelDb.js.map +1 -1
  151. package/lib/esm/LineStyle.d.ts +6 -6
  152. package/lib/esm/LineStyle.js.map +1 -1
  153. package/lib/esm/LocalHub.d.ts +6 -0
  154. package/lib/esm/LocalHub.d.ts.map +1 -1
  155. package/lib/esm/LocalHub.js +23 -0
  156. package/lib/esm/LocalHub.js.map +1 -1
  157. package/lib/esm/Material.d.ts +1 -1
  158. package/lib/esm/Material.js.map +1 -1
  159. package/lib/esm/Model.d.ts +6 -6
  160. package/lib/esm/Model.js.map +1 -1
  161. package/lib/esm/Relationship.d.ts +13 -11
  162. package/lib/esm/Relationship.d.ts.map +1 -1
  163. package/lib/esm/Relationship.js +9 -7
  164. package/lib/esm/Relationship.js.map +1 -1
  165. package/lib/esm/SheetIndex.d.ts +4 -4
  166. package/lib/esm/SheetIndex.js.map +1 -1
  167. package/lib/esm/Texture.d.ts +1 -1
  168. package/lib/esm/Texture.js.map +1 -1
  169. package/lib/esm/TxnManager.d.ts.map +1 -1
  170. package/lib/esm/TxnManager.js +7 -0
  171. package/lib/esm/TxnManager.js.map +1 -1
  172. package/lib/esm/ViewDefinition.d.ts +6 -6
  173. package/lib/esm/ViewDefinition.js.map +1 -1
  174. package/lib/esm/annotations/ElementDrivesTextAnnotation.d.ts +1 -1
  175. package/lib/esm/annotations/ElementDrivesTextAnnotation.js.map +1 -1
  176. package/lib/esm/annotations/FrameGeometry.d.ts.map +1 -1
  177. package/lib/esm/annotations/FrameGeometry.js +2 -3
  178. package/lib/esm/annotations/FrameGeometry.js.map +1 -1
  179. package/lib/esm/domains/FunctionalElements.d.ts +1 -1
  180. package/lib/esm/domains/FunctionalElements.js.map +1 -1
  181. package/lib/esm/domains/GenericElements.d.ts +2 -2
  182. package/lib/esm/domains/GenericElements.js.map +1 -1
  183. package/lib/esm/internal/ChannelAdmin.d.ts +2 -2
  184. package/lib/esm/internal/ChannelAdmin.js.map +1 -1
  185. package/lib/esm/internal/ElementLRUCache.d.ts.map +1 -1
  186. package/lib/esm/internal/ElementLRUCache.js +23 -4
  187. package/lib/esm/internal/ElementLRUCache.js.map +1 -1
  188. package/lib/esm/internal/HubMock.d.ts +24 -1
  189. package/lib/esm/internal/HubMock.d.ts.map +1 -1
  190. package/lib/esm/internal/HubMock.js +61 -40
  191. package/lib/esm/internal/HubMock.js.map +1 -1
  192. package/lib/esm/internal/ServerBasedLocks.d.ts +19 -1
  193. package/lib/esm/internal/ServerBasedLocks.d.ts.map +1 -1
  194. package/lib/esm/internal/ServerBasedLocks.js +55 -1
  195. package/lib/esm/internal/ServerBasedLocks.js.map +1 -1
  196. package/lib/esm/internal/cross-package.d.ts +1 -1
  197. package/lib/esm/internal/cross-package.d.ts.map +1 -1
  198. package/lib/esm/internal/cross-package.js +1 -1
  199. package/lib/esm/internal/cross-package.js.map +1 -1
  200. package/lib/esm/internal/workspace/SettingsSchemasImpl.d.ts.map +1 -1
  201. package/lib/esm/internal/workspace/SettingsSchemasImpl.js +55 -9
  202. package/lib/esm/internal/workspace/SettingsSchemasImpl.js.map +1 -1
  203. package/lib/esm/internal/workspace/WorkspaceImpl.d.ts.map +1 -1
  204. package/lib/esm/internal/workspace/WorkspaceImpl.js +7 -11
  205. package/lib/esm/internal/workspace/WorkspaceImpl.js.map +1 -1
  206. package/lib/esm/test/ElementLRUCache.test.js +60 -0
  207. package/lib/esm/test/ElementLRUCache.test.js.map +1 -1
  208. package/lib/esm/test/SchemaChangesetCanBeReversed.test.d.ts +2 -0
  209. package/lib/esm/test/SchemaChangesetCanBeReversed.test.d.ts.map +1 -0
  210. package/lib/esm/test/SchemaChangesetCanBeReversed.test.js +239 -0
  211. package/lib/esm/test/SchemaChangesetCanBeReversed.test.js.map +1 -0
  212. package/lib/esm/test/annotations/FrameGeometry.test.js +2 -1
  213. package/lib/esm/test/annotations/FrameGeometry.test.js.map +1 -1
  214. package/lib/esm/test/ecdb/CTE.test.js +1 -0
  215. package/lib/esm/test/ecdb/CTE.test.js.map +1 -1
  216. package/lib/esm/test/ecdb/ECSqlQuery.test.js +10 -2
  217. package/lib/esm/test/ecdb/ECSqlQuery.test.js.map +1 -1
  218. package/lib/esm/test/ecdb/ECSqlStatement.test.js +10 -0
  219. package/lib/esm/test/ecdb/ECSqlStatement.test.js.map +1 -1
  220. package/lib/esm/test/ecdb/ECSqlSyncReader.test.js +1 -0
  221. package/lib/esm/test/ecdb/ECSqlSyncReader.test.js.map +1 -1
  222. package/lib/esm/test/ecdb/QueryReaders.test.js +13 -0
  223. package/lib/esm/test/ecdb/QueryReaders.test.js.map +1 -1
  224. package/lib/esm/test/ecsql/src/ECSqlTestRunner.test.js +1 -0
  225. package/lib/esm/test/ecsql/src/ECSqlTestRunner.test.js.map +1 -1
  226. package/lib/esm/test/element/DeleteDefinitionElements.test.js +6 -2
  227. package/lib/esm/test/element/DeleteDefinitionElements.test.js.map +1 -1
  228. package/lib/esm/test/element/ElementRoundTrip.test.js +5 -0
  229. package/lib/esm/test/element/ElementRoundTrip.test.js.map +1 -1
  230. package/lib/esm/test/element/ExcludedElements.test.js +1 -0
  231. package/lib/esm/test/element/ExcludedElements.test.js.map +1 -1
  232. package/lib/esm/test/hubaccess/ApplyChangeset.test.js +10 -0
  233. package/lib/esm/test/hubaccess/ApplyChangeset.test.js.map +1 -1
  234. package/lib/esm/test/hubaccess/SemanticRebase.test.js +1 -0
  235. package/lib/esm/test/hubaccess/SemanticRebase.test.js.map +1 -1
  236. package/lib/esm/test/imodel/IModel.test.js +31 -0
  237. package/lib/esm/test/imodel/IModel.test.js.map +1 -1
  238. package/lib/esm/test/schema/ClassRegistry.test.js +3 -0
  239. package/lib/esm/test/schema/ClassRegistry.test.js.map +1 -1
  240. package/lib/esm/test/schema/IModelSchemaContext.test.js +2 -0
  241. package/lib/esm/test/schema/IModelSchemaContext.test.js.map +1 -1
  242. package/lib/esm/test/schema/SchemaViewHidden.test.d.ts +2 -0
  243. package/lib/esm/test/schema/SchemaViewHidden.test.d.ts.map +1 -0
  244. package/lib/esm/test/schema/SchemaViewHidden.test.js +275 -0
  245. package/lib/esm/test/schema/SchemaViewHidden.test.js.map +1 -0
  246. package/lib/esm/test/schema/SchemaViewKoQ.test.d.ts +2 -0
  247. package/lib/esm/test/schema/SchemaViewKoQ.test.d.ts.map +1 -0
  248. package/lib/esm/test/schema/SchemaViewKoQ.test.js +184 -0
  249. package/lib/esm/test/schema/SchemaViewKoQ.test.js.map +1 -0
  250. package/lib/esm/test/schema/SchemaViewLifecycle.test.d.ts +2 -0
  251. package/lib/esm/test/schema/SchemaViewLifecycle.test.d.ts.map +1 -0
  252. package/lib/esm/test/schema/SchemaViewLifecycle.test.js +141 -0
  253. package/lib/esm/test/schema/SchemaViewLifecycle.test.js.map +1 -0
  254. package/lib/esm/test/schema/SchemaViewValidation.test.d.ts +2 -0
  255. package/lib/esm/test/schema/SchemaViewValidation.test.d.ts.map +1 -0
  256. package/lib/esm/test/schema/SchemaViewValidation.test.js +475 -0
  257. package/lib/esm/test/schema/SchemaViewValidation.test.js.map +1 -0
  258. package/lib/esm/test/standalone/ChangesetReader.test.js +945 -337
  259. package/lib/esm/test/standalone/ChangesetReader.test.js.map +1 -1
  260. package/lib/esm/test/standalone/DeleteElements.test.js +45 -0
  261. package/lib/esm/test/standalone/DeleteElements.test.js.map +1 -1
  262. package/lib/esm/test/standalone/IModelWrite.test.js +6 -0
  263. package/lib/esm/test/standalone/IModelWrite.test.js.map +1 -1
  264. package/lib/esm/test/standalone/ServerBasedLocks.test.js +62 -0
  265. package/lib/esm/test/standalone/ServerBasedLocks.test.js.map +1 -1
  266. package/lib/esm/test/standalone/Settings.test.js +2 -0
  267. package/lib/esm/test/standalone/Settings.test.js.map +1 -1
  268. package/lib/esm/test/standalone/SettingsSchemas.test.js +397 -0
  269. package/lib/esm/test/standalone/SettingsSchemas.test.js.map +1 -1
  270. package/lib/esm/test/standalone/Workspace.test.js +23 -0
  271. package/lib/esm/test/standalone/Workspace.test.js.map +1 -1
  272. package/lib/esm/workspace/SettingsSchemas.d.ts +20 -3
  273. package/lib/esm/workspace/SettingsSchemas.d.ts.map +1 -1
  274. package/lib/esm/workspace/SettingsSchemas.js.map +1 -1
  275. package/lib/esm/workspace/Workspace.d.ts +3 -1
  276. package/lib/esm/workspace/Workspace.d.ts.map +1 -1
  277. package/lib/esm/workspace/Workspace.js.map +1 -1
  278. package/package.json +15 -15
@@ -29,6 +29,7 @@ import { PropertyFilter } from "./ChangesetReaderTypes";
29
29
  * @beta
30
30
  */
31
31
  export class ChangesetReader {
32
+ static defaultSpillThresholdInBytes = 50 * 1024 * 1024; // 50 MiB
32
33
  _nativeReader = new IModelNative.platform.ChangesetReader();
33
34
  // Internal options — keep ECClassId as raw Id so the unifier can use it as-is.
34
35
  _rowOptions;
@@ -43,6 +44,7 @@ export class ChangesetReader {
43
44
  /**
44
45
  * `true` when the current row belongs to an EC-mapped table.
45
46
  * Valid only after a successful call to [[step]].
47
+ * @throws [[IModelError]] if called before a successful [[step]] call.
46
48
  * @beta
47
49
  */
48
50
  get isECTable() {
@@ -53,6 +55,7 @@ export class ChangesetReader {
53
55
  /**
54
56
  * Name of the SQLite table for the current change row.
55
57
  * Valid only after a successful call to [[step]].
58
+ * @throws [[IModelError]] if called before a successful [[step]] call.
56
59
  * @beta
57
60
  */
58
61
  get tableName() {
@@ -63,6 +66,7 @@ export class ChangesetReader {
63
66
  /**
64
67
  * `true` when the current change was applied indirectly
65
68
  * Valid only after a successful call to [[step]].
69
+ * @throws [[IModelError]] if called before a successful [[step]] call.
66
70
  * @beta
67
71
  */
68
72
  get isIndirectChange() {
@@ -105,6 +109,7 @@ export class ChangesetReader {
105
109
  * @param args.invert When `true`, invert all operations (Insert↔Delete).
106
110
  * @param args.valueOptions Row adaptor options controlling how EC property values are formatted.
107
111
  * @param args.propFilter Controls which properties are included. Defaults to `All`.
112
+ * @throws if the native layer fails to open the file.
108
113
  * @beta
109
114
  */
110
115
  static openFile(args) {
@@ -116,7 +121,7 @@ export class ChangesetReader {
116
121
  reader._nativeReader.openFile(args.db[_nativeDb], args.fileName, args.invert ?? false, reader._propFilter);
117
122
  }
118
123
  catch (e) {
119
- reader.close();
124
+ reader.handleCloseErrorWhileOpening(e);
120
125
  throw e;
121
126
  }
122
127
  return reader;
@@ -127,20 +132,26 @@ export class ChangesetReader {
127
132
  * @param args.db Database with schema at or ahead of the last changeset.
128
133
  * @param args.valueOptions Row adaptor options controlling how EC property values are formatted.
129
134
  * @param args.propFilter Controls which properties are included. Defaults to `All`.
135
+ * @param args.spillThresholdInBytes When the total size of the changeset data in the change group exceeds this threshold (in bytes),
136
+ * the reader writes the data to a temporary file on disk and streams it from there instead of buffering everything in memory.
137
+ * This keeps peak memory usage bounded, making the API suitable for processing large changeset groups under low-memory conditions.
138
+ * Defaults to 50 MiB.
139
+ * @throws if `changesetFiles` is empty, or if the native layer fails to open
140
+ * the group.
130
141
  * @beta
131
142
  */
132
143
  static openGroup(args) {
133
144
  if (args.changesetFiles.length === 0)
134
- throw new Error("changesetFiles must contain at least one file.");
145
+ throw new IModelError(IModelStatus.BadArg, "changesetFiles must contain at least one file.");
135
146
  const reader = new ChangesetReader(args.db);
136
147
  reader._rowOptions = args.rowOptions;
137
148
  const propFilter = args.propFilter ?? PropertyFilter.All;
138
149
  reader._propFilter = propFilter;
139
150
  try {
140
- reader._nativeReader.openGroup(args.db[_nativeDb], args.changesetFiles, args.invert ?? false, reader._propFilter);
151
+ reader._nativeReader.openGroup(args.db[_nativeDb], args.changesetFiles, args.invert ?? false, reader._propFilter, args.spillThresholdInBytes ?? this.defaultSpillThresholdInBytes);
141
152
  }
142
153
  catch (e) {
143
- reader.close();
154
+ reader.handleCloseErrorWhileOpening(e);
144
155
  throw e;
145
156
  }
146
157
  return reader;
@@ -151,6 +162,12 @@ export class ChangesetReader {
151
162
  * @param args.includeInMemoryChanges Also include in-memory (not yet saved to disk) changes.
152
163
  * @param args.valueOptions Row adaptor options controlling how EC property values are formatted.
153
164
  * @param args.propFilter Controls which properties are included. Defaults to `All`.
165
+ * @param args.spillThresholdInBytes When the total size of all local un-pushed saved changes exceeds this threshold (in bytes),
166
+ * the reader writes the data to a temporary file on disk and streams it from there instead of buffering everything in memory.
167
+ * This keeps peak memory usage bounded, making the API suitable for iModels with large local change backlogs under low-memory conditions.
168
+ * Defaults to 50 MiB.
169
+ * @throws if the native layer
170
+ * fails to open the local changes.
154
171
  * @beta
155
172
  */
156
173
  static openLocalChanges(args) {
@@ -159,10 +176,10 @@ export class ChangesetReader {
159
176
  const propFilter = args.propFilter ?? PropertyFilter.All;
160
177
  reader._propFilter = propFilter;
161
178
  try {
162
- reader._nativeReader.openLocalChanges(args.db[_nativeDb], args.includeInMemoryChanges ?? false, args.invert ?? false, reader._propFilter);
179
+ reader._nativeReader.openLocalChanges(args.db[_nativeDb], args.includeInMemoryChanges ?? false, args.invert ?? false, reader._propFilter, args.spillThresholdInBytes ?? this.defaultSpillThresholdInBytes);
163
180
  }
164
181
  catch (e) {
165
- reader.close();
182
+ reader.handleCloseErrorWhileOpening(e);
166
183
  throw e;
167
184
  }
168
185
  return reader;
@@ -172,6 +189,11 @@ export class ChangesetReader {
172
189
  * @param args.db Must be an [IModelDb]($backend).
173
190
  * @param args.valueOptions Row adaptor options controlling how EC property values are formatted.
174
191
  * @param args.propFilter Controls which properties are included. Defaults to `All`.
192
+ * @param args.spillThresholdInBytes When the total size of the in-memory (unsaved) change data exceeds this threshold (in bytes),
193
+ * the reader writes the data to a temporary file on disk and streams it from there instead of buffering everything in memory.
194
+ * This keeps peak memory usage bounded, making the API suitable for large in-memory transactions under low-memory conditions.
195
+ * Defaults to 50 MiB.
196
+ * @throws if the native layer encounters an error while opening the in-memory changes.
175
197
  * @beta
176
198
  */
177
199
  static openInMemoryChanges(args) {
@@ -180,10 +202,10 @@ export class ChangesetReader {
180
202
  const propFilter = args.propFilter ?? PropertyFilter.All;
181
203
  reader._propFilter = propFilter;
182
204
  try {
183
- reader._nativeReader.openInMemoryChanges(args.db[_nativeDb], args.invert ?? false, reader._propFilter);
205
+ reader._nativeReader.openInMemoryChanges(args.db[_nativeDb], args.invert ?? false, reader._propFilter, args.spillThresholdInBytes ?? this.defaultSpillThresholdInBytes);
184
206
  }
185
207
  catch (e) {
186
- reader.close();
208
+ reader.handleCloseErrorWhileOpening(e);
187
209
  throw e;
188
210
  }
189
211
  return reader;
@@ -194,22 +216,40 @@ export class ChangesetReader {
194
216
  * @param args.txnId The id of the saved transaction to read.
195
217
  * @param args.valueOptions Row adaptor options controlling how EC property values are formatted.
196
218
  * @param args.propFilter Controls which properties are included. Defaults to `All`.
219
+ * @param args.spillThresholdInBytes When the total size of the transaction's change data exceeds this threshold (in bytes),
220
+ * the reader writes the data to a temporary file on disk and streams it from there instead of buffering everything in memory.
221
+ * This keeps peak memory usage bounded, making the API suitable for large transactions under low-memory conditions.
222
+ * Defaults to 50 MiB.
223
+ * @throws if `txnId` is not found, or
224
+ * the native layer fails to open the transaction data.
197
225
  * @beta
198
226
  */
199
227
  static openTxn(args) {
200
228
  const reader = new ChangesetReader(args.db);
201
- reader._rowOptions = args.rowOptions ?? {};
229
+ reader._rowOptions = args.rowOptions;
202
230
  const propFilter = args.propFilter ?? PropertyFilter.All;
203
231
  reader._propFilter = propFilter;
204
232
  try {
205
- reader._nativeReader.openTxn(args.db[_nativeDb], args.txnId, args.invert ?? false, reader._propFilter);
233
+ reader._nativeReader.openTxn(args.db[_nativeDb], args.txnId, args.invert ?? false, reader._propFilter, args.spillThresholdInBytes ?? this.defaultSpillThresholdInBytes);
206
234
  }
207
235
  catch (e) {
208
- reader.close();
236
+ reader.handleCloseErrorWhileOpening(e);
209
237
  throw e;
210
238
  }
211
239
  return reader;
212
240
  }
241
+ /** Handle errors that occur while auto closing the reader if there is also an error while opening the reader */
242
+ handleCloseErrorWhileOpening(e) {
243
+ try {
244
+ this.close();
245
+ }
246
+ catch (closeError) {
247
+ throw new IModelError(IModelStatus.BadArg, `Failed to open ChangesetReader with error ${e instanceof Error ? e.message : String(e)}.
248
+ Additionally, that triggered an automatic closure of the reader
249
+ releasing native resources which also failed with failure ${closeError instanceof Error ? closeError.message : String(closeError)}.
250
+ Check native error logs for more details.`);
251
+ }
252
+ }
213
253
  // ---------------------------------------------------------------------------
214
254
  // Filtering
215
255
  // ---------------------------------------------------------------------------
@@ -218,6 +258,7 @@ export class ChangesetReader {
218
258
  * That means the rows for changes from other tables will be skipped entirely and won't be visible through the reader.
219
259
  * @param tableNames SQLite table names to include.
220
260
  * Note: Table names must be provided in the correct case for proper filtering.
261
+ * @throws if the native layer encounters an error while setting the filter.
221
262
  * @beta
222
263
  */
223
264
  setTableNameFilters(tableNames) {
@@ -227,6 +268,7 @@ export class ChangesetReader {
227
268
  * Restrict iteration to changes with the given operation types.
228
269
  * That means the rows for changes with other operation types will be skipped entirely and won't be visible through the reader.
229
270
  * @param ops Operations to include.
271
+ * @throws if the native layer encounters an error while setting the filter.
230
272
  * @beta
231
273
  */
232
274
  setOpCodeFilters(ops) {
@@ -237,6 +279,7 @@ export class ChangesetReader {
237
279
  * That means the rows for changes from other EC classes will be skipped entirely and won't be visible through the reader.
238
280
  * @param classNames EC class names to include. The classNames should be in the full name format(i.e. "SchemaName:ClassName").
239
281
  * Note: Schema names and class names must be provided in the correct case for proper filtering. Derived classes are not automatically included, so they must be specified explicitly if needed.
282
+ * @throws if the native layer encounters an error while setting the filter.
240
283
  * @beta
241
284
  */
242
285
  setClassNameFilters(classNames) {
@@ -244,6 +287,7 @@ export class ChangesetReader {
244
287
  }
245
288
  /**
246
289
  * Remove the table-name filters
290
+ * @throws if the native layer encounters an error.
247
291
  * @beta
248
292
  */
249
293
  clearTableNameFilters() {
@@ -251,6 +295,7 @@ export class ChangesetReader {
251
295
  }
252
296
  /**
253
297
  * Remove the op-code filters
298
+ * @throws if the native layer encounters an error.
254
299
  * @beta
255
300
  */
256
301
  clearOpCodeFilters() {
@@ -258,17 +303,61 @@ export class ChangesetReader {
258
303
  }
259
304
  /**
260
305
  * Remove the class-name filters
306
+ * @throws if the native layer encounters an error.
261
307
  * @beta
262
308
  */
263
309
  clearClassNameFilters() {
264
310
  this._nativeReader.clearClassNameFilters();
265
311
  }
266
312
  // ---------------------------------------------------------------------------
313
+ // Strict mode
314
+ // ---------------------------------------------------------------------------
315
+ /**
316
+ * Enable strict mode on the reader.
317
+ *
318
+ * Strict mode affects how the reader handles a **column-count mismatch** between a change
319
+ * record and the corresponding live database table. Such a mismatch can occur when columns
320
+ * have been added to a table after the changeset was created.
321
+ *
322
+ * When strict mode is **enabled**: if the number of columns recorded in a change row differs
323
+ * from the number of columns currently present in the live table, the reader throws an error
324
+ * instead of processing that row.
325
+ *
326
+ * Use strict mode when you need to be certain that every change row is interpreted against
327
+ * exactly the schema that was in effect when the changeset was written.
328
+ *
329
+ * @see [[disableStrictMode]] — the default (lenient) behaviour.
330
+ * @throws if the native layer encounters an error.
331
+ * @beta
332
+ */
333
+ enableStrictMode() {
334
+ this._nativeReader.enableStrictMode();
335
+ }
336
+ /**
337
+ * Disable strict mode on the reader (this is the default).
338
+ *
339
+ * When strict mode is **disabled**: if the number of columns recorded in a change row differs
340
+ * from the number of columns currently present in the live table, the reader takes the
341
+ * **minimum** of the two column counts and proceeds normally with that subset. This is safe
342
+ * because SQLite only ever appends new columns at the end of a table and never removes them —
343
+ * so older change records simply lack the trailing columns that were added later, and those
344
+ * missing columns are silently ignored.
345
+ *
346
+ * @see [[enableStrictMode]] — throw on column-count mismatches instead.
347
+ * @throws if the native layer encounters an error.
348
+ * @beta
349
+ */
350
+ disableStrictMode() {
351
+ this._nativeReader.disableStrictMode();
352
+ }
353
+ // ---------------------------------------------------------------------------
267
354
  // Iteration
268
355
  // ---------------------------------------------------------------------------
269
356
  /**
270
357
  * Advance to the next change and populate `inserted` and/or `deleted`.
271
358
  * @returns `true` while positioned on a valid change; `false` when the stream is exhausted.
359
+ * @throws if the native layer encounters an error while reading or decoding
360
+ * the next change.
272
361
  * @beta
273
362
  */
274
363
  step() {
@@ -333,6 +422,7 @@ export class ChangesetReader {
333
422
  /**
334
423
  * SQLite opcode of the current change.
335
424
  * Valid only after a successful call to [[step]].
425
+ * @throws [[IModelError]] if called before a successful [[step]] call.
336
426
  * @beta
337
427
  */
338
428
  get op() {
@@ -345,6 +435,10 @@ export class ChangesetReader {
345
435
  // ---------------------------------------------------------------------------
346
436
  /**
347
437
  * Close the reader and release all native resources.
438
+ *
439
+ * @throws if the native layer encounters an error during cleanup. Native resources
440
+ * are not fully released when this throws — check the native error
441
+ * logs for details.
348
442
  * @beta
349
443
  */
350
444
  close() {
@@ -358,7 +452,9 @@ export class ChangesetReader {
358
452
  this._nativeReader.close();
359
453
  }
360
454
  /**
361
- * Implements the `Disposable` contract — calls [[close]].
455
+ * Implements the `Disposable` contract — delegates to [[close]].
456
+ *
457
+ * @throws if the native layer fails to release its resources (re-thrown from [[close]]).
362
458
  * @beta
363
459
  */
364
460
  [Symbol.dispose]() {
@@ -1 +1 @@
1
- {"version":3,"file":"ChangesetReader.js","sourceRoot":"","sources":["../../src/ChangesetReader.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 ECDb\n */\nimport { DbChangeStage, DbOpcode, Id64String, IModelStatus } from \"@itwin/core-bentley\";\nimport { IModelError } from \"@itwin/core-common\";\nimport { IModelDb } from \"./IModelDb\";\nimport { IModelNative } from \"./internal/NativePlatform\";\nimport { _nativeDb } from \"./internal/Symbols\";\nimport { IModelJsNative } from \"@bentley/imodeljs-native\";\nimport { ChangeInstance, ChangesetReaderArgs, ChangeSource, PropertyFilter, RowFormatOptions } from \"./ChangesetReaderTypes\";\nimport { AnyDb, SqliteChangeOp } from \"./SqliteChangesetReader\";\n\n\n// ---------------------------------------------------------------------------\n// ChangesetReader\n// ---------------------------------------------------------------------------\n\n/**\n * Reads EC-typed changeset data natively from a changeset file, changeset group,\n * in-memory transaction, or local un-pushed changes.\n *\n * Implements [ChangeSource]($backend) so rows can be fed directly into\n * [PartialChangeUnifier]($backend) to merge partial (per-table) instances into\n * complete EC instances.\n *\n * When the current row is a non-EC internal SQLite table, [[isECTable]] is `false`\n * and both [[inserted]] and [[deleted]] remain `undefined`.\n *\n * @note The native reader operates one SQLite table-row at a time. Multi-table EC\n * instances must be merged using [PartialChangeUnifier]($backend).\n * @beta\n */\nexport class ChangesetReader implements Disposable, ChangeSource {\n private readonly _nativeReader: IModelJsNative.ChangesetReader = new IModelNative.platform.ChangesetReader();\n // Internal options — keep ECClassId as raw Id so the unifier can use it as-is.\n private _rowOptions?: RowFormatOptions;\n private _propFilter: PropertyFilter = PropertyFilter.All;\n private _changeIndex = 0;\n private _op?: SqliteChangeOp;\n private _isECTable?: boolean;\n private _tableName?: string;\n private _isIndirectChange?: boolean;\n\n /** The db used for EC schema resolution. */\n public readonly db: AnyDb;\n\n /**\n * `true` when the current row belongs to an EC-mapped table.\n * Valid only after a successful call to [[step]].\n * @beta\n */\n public get isECTable(): boolean {\n if (this._isECTable === undefined)\n throw new IModelError(IModelStatus.BadRequest, \"ChangesetReader.isECTable is only valid after step() has positioned the reader on a current valid change.\");\n return this._isECTable;\n }\n\n /**\n * Name of the SQLite table for the current change row.\n * Valid only after a successful call to [[step]].\n * @beta\n */\n public get tableName(): string {\n if (this._tableName === undefined)\n throw new IModelError(IModelStatus.BadRequest, \"ChangesetReader.tableName is only valid after step() has positioned the reader on a current valid change.\");\n return this._tableName;\n }\n\n /**\n * `true` when the current change was applied indirectly\n * Valid only after a successful call to [[step]].\n * @beta\n */\n public get isIndirectChange(): boolean {\n if (this._isIndirectChange === undefined)\n throw new IModelError(IModelStatus.BadRequest, \"ChangesetReader.isIndirectChange is only valid after step() has positioned the reader on a current valid change.\");\n return this._isIndirectChange;\n }\n\n /**\n * Post-change (inserted or updated-new) EC instance, populated after each [[step]] call.\n * `undefined` when the current row is a Delete or a non-EC table row or [[step]] returned false.\n * @beta\n */\n public inserted?: ChangeInstance;\n\n /**\n * Pre-change (deleted or updated-old) EC instance, populated after each [[step]] call.\n * `undefined` when the current row is an Insert or a non-EC table row or [[step]] returned false.\n * @beta\n */\n public deleted?: ChangeInstance;\n\n // Private — callers use static factory methods.\n private constructor(db: AnyDb) {\n this.db = db;\n }\n\n /** Map public RowFormatOptions to the native adaptor options.\n * @internal */\n private toNativeRowOptions(opts: RowFormatOptions): IModelJsNative.ECSqlRowAdaptorOptions {\n return {\n abbreviateBlobs: opts.abbreviateBlobs,\n classIdsToClassNames: opts.classIdsToClassNames,\n useJsName: opts.useJsName,\n };\n }\n\n // ---------------------------------------------------------------------------\n // Static factory methods\n // ---------------------------------------------------------------------------\n\n /**\n * Open a changeset file from disk.\n * @param args.fileName Absolute path to the changeset file.\n * @param args.db Database at or after the changeset's ending state, used for schema resolution.\n * @param args.invert When `true`, invert all operations (Insert↔Delete).\n * @param args.valueOptions Row adaptor options controlling how EC property values are formatted.\n * @param args.propFilter Controls which properties are included. Defaults to `All`.\n * @beta\n */\n public static openFile(args: { readonly fileName: string } & ChangesetReaderArgs): ChangesetReader {\n const reader = new ChangesetReader(args.db);\n reader._rowOptions = args.rowOptions;\n const propFilter = args.propFilter ?? PropertyFilter.All;\n reader._propFilter = propFilter;\n try {\n reader._nativeReader.openFile(args.db[_nativeDb], args.fileName, args.invert ?? false, reader._propFilter);\n }\n catch (e) {\n reader.close();\n throw e;\n }\n return reader;\n }\n\n /**\n * Concatenate multiple changeset files and read them as a single logical stream.\n * @param args.changesetFiles Ordered list of changeset file paths.\n * @param args.db Database with schema at or ahead of the last changeset.\n * @param args.valueOptions Row adaptor options controlling how EC property values are formatted.\n * @param args.propFilter Controls which properties are included. Defaults to `All`.\n * @beta\n */\n public static openGroup(args: { readonly changesetFiles: string[] } & ChangesetReaderArgs): ChangesetReader {\n if (args.changesetFiles.length === 0)\n throw new Error(\"changesetFiles must contain at least one file.\");\n const reader = new ChangesetReader(args.db);\n reader._rowOptions = args.rowOptions;\n const propFilter = args.propFilter ?? PropertyFilter.All;\n reader._propFilter = propFilter;\n try {\n reader._nativeReader.openGroup(args.db[_nativeDb], args.changesetFiles, args.invert ?? false, reader._propFilter);\n }\n catch (e) {\n reader.close();\n throw e;\n }\n return reader;\n }\n\n /**\n * Read pending (not yet pushed) local changes from an open IModelDb.\n * @param args.db Must be an [IModelDb]($backend) (not [ECDb]($backend)).\n * @param args.includeInMemoryChanges Also include in-memory (not yet saved to disk) changes.\n * @param args.valueOptions Row adaptor options controlling how EC property values are formatted.\n * @param args.propFilter Controls which properties are included. Defaults to `All`.\n * @beta\n */\n public static openLocalChanges(\n args: Omit<ChangesetReaderArgs, \"db\"> & { db: IModelDb; includeInMemoryChanges?: boolean },\n ): ChangesetReader {\n const reader = new ChangesetReader(args.db);\n reader._rowOptions = args.rowOptions;\n const propFilter = args.propFilter ?? PropertyFilter.All;\n reader._propFilter = propFilter;\n try {\n reader._nativeReader.openLocalChanges(args.db[_nativeDb], args.includeInMemoryChanges ?? false, args.invert ?? false, reader._propFilter);\n } catch (e) {\n reader.close();\n throw e;\n }\n return reader;\n }\n\n /**\n * Read the in-memory (not yet saved to disk) changes of an open IModelDb.\n * @param args.db Must be an [IModelDb]($backend).\n * @param args.valueOptions Row adaptor options controlling how EC property values are formatted.\n * @param args.propFilter Controls which properties are included. Defaults to `All`.\n * @beta\n */\n public static openInMemoryChanges(\n args: Omit<ChangesetReaderArgs, \"db\"> & { db: IModelDb },\n ): ChangesetReader {\n const reader = new ChangesetReader(args.db);\n reader._rowOptions = args.rowOptions;\n const propFilter = args.propFilter ?? PropertyFilter.All;\n reader._propFilter = propFilter;\n try {\n reader._nativeReader.openInMemoryChanges(args.db[_nativeDb], args.invert ?? false, reader._propFilter);\n } catch (e) {\n reader.close();\n throw e;\n }\n return reader;\n }\n\n /**\n * Read a single saved transaction by its id.\n * @param args.db Must be an [IModelDb]($backend) ([ECDb]($backend) does not support transactions).\n * @param args.txnId The id of the saved transaction to read.\n * @param args.valueOptions Row adaptor options controlling how EC property values are formatted.\n * @param args.propFilter Controls which properties are included. Defaults to `All`.\n * @beta\n */\n public static openTxn(\n args: Omit<ChangesetReaderArgs, \"db\"> & { db: IModelDb; txnId: Id64String },\n ): ChangesetReader {\n const reader = new ChangesetReader(args.db);\n reader._rowOptions = args.rowOptions ?? {};\n const propFilter = args.propFilter ?? PropertyFilter.All;\n reader._propFilter = propFilter;\n try {\n reader._nativeReader.openTxn(args.db[_nativeDb], args.txnId, args.invert ?? false, reader._propFilter);\n } catch (e) {\n reader.close();\n throw e;\n }\n return reader;\n }\n\n // ---------------------------------------------------------------------------\n // Filtering\n // ---------------------------------------------------------------------------\n\n /**\n * Restrict iteration to changes from the named SQLite tables.\n * That means the rows for changes from other tables will be skipped entirely and won't be visible through the reader.\n * @param tableNames SQLite table names to include.\n * Note: Table names must be provided in the correct case for proper filtering.\n * @beta\n */\n public setTableNameFilters(tableNames: Set<string>): void {\n this._nativeReader.setTableNameFilters(Array.from(tableNames));\n }\n\n /**\n * Restrict iteration to changes with the given operation types.\n * That means the rows for changes with other operation types will be skipped entirely and won't be visible through the reader.\n * @param ops Operations to include.\n * @beta\n */\n public setOpCodeFilters(ops: Set<SqliteChangeOp>): void {\n this._nativeReader.setOpCodeFilters(Array.from(ops));\n }\n\n /**\n * Restrict iteration to changes for the given EC class names.\n * That means the rows for changes from other EC classes will be skipped entirely and won't be visible through the reader.\n * @param classNames EC class names to include. The classNames should be in the full name format(i.e. \"SchemaName:ClassName\").\n * Note: Schema names and class names must be provided in the correct case for proper filtering. Derived classes are not automatically included, so they must be specified explicitly if needed.\n * @beta\n */\n public setClassNameFilters(classNames: Set<string>): void {\n this._nativeReader.setClassNameFilters(Array.from(classNames));\n }\n\n /**\n * Remove the table-name filters\n * @beta\n */\n public clearTableNameFilters(): void {\n this._nativeReader.clearTableNameFilters();\n }\n\n /**\n * Remove the op-code filters\n * @beta\n */\n public clearOpCodeFilters(): void {\n this._nativeReader.clearOpCodeFilters();\n }\n\n /**\n * Remove the class-name filters\n * @beta\n */\n public clearClassNameFilters(): void {\n this._nativeReader.clearClassNameFilters();\n }\n\n // ---------------------------------------------------------------------------\n // Iteration\n // ---------------------------------------------------------------------------\n\n /**\n * Advance to the next change and populate `inserted` and/or `deleted`.\n * @returns `true` while positioned on a valid change; `false` when the stream is exhausted.\n * @beta\n */\n public step(): boolean {\n this.inserted = undefined;\n this.deleted = undefined;\n this._op = undefined;\n this._isECTable = undefined;\n this._tableName = undefined;\n this._isIndirectChange = undefined;\n\n if (this._nativeReader.step()) {\n this._changeIndex++;\n const meta = this._nativeReader.getChangeMetadata();\n const nativeOp = meta.opCode;\n const op: SqliteChangeOp = nativeOp === DbOpcode.Insert ? \"Inserted\" : nativeOp === DbOpcode.Update ? \"Updated\" : \"Deleted\";\n this._op = op;\n\n this._tableName = meta.tableName;\n this._isIndirectChange = meta.isIndirectChange;\n this._isECTable = meta.isECTable;\n\n const nativeRowOpts = this._rowOptions ? this.toNativeRowOptions(this._rowOptions) : {};\n\n if (op === \"Inserted\" || op === \"Updated\") {\n const rowValue = this._nativeReader.getValue(DbChangeStage.New, nativeRowOpts);\n if (rowValue !== undefined) {\n this.inserted = {\n ...rowValue.data,\n $meta: {\n op,\n tables: [this._tableName],\n changeIndexes: [this._changeIndex],\n stage: \"New\",\n instanceKey: rowValue.key,\n propFilter: this._propFilter,\n changeFetchedPropNames: rowValue.changeFetchedPropNames,\n rowOptions: this._rowOptions,\n isIndirectChange: this._isIndirectChange,\n },\n };\n }\n }\n\n if (op === \"Deleted\" || op === \"Updated\") {\n const rowValue = this._nativeReader.getValue(DbChangeStage.Old, nativeRowOpts);\n if (rowValue !== undefined) {\n this.deleted = {\n ...rowValue.data,\n $meta: {\n op,\n tables: [this._tableName],\n changeIndexes: [this._changeIndex],\n stage: \"Old\",\n instanceKey: rowValue.key,\n propFilter: this._propFilter,\n changeFetchedPropNames: rowValue.changeFetchedPropNames,\n rowOptions: this._rowOptions,\n isIndirectChange: this._isIndirectChange,\n },\n };\n }\n }\n\n return true;\n }\n\n return false;\n }\n\n /**\n * SQLite opcode of the current change.\n * Valid only after a successful call to [[step]].\n * @beta\n */\n public get op(): SqliteChangeOp {\n if (this._op === undefined)\n throw new IModelError(IModelStatus.BadRequest, \"ChangesetReader.op is only valid after step() has positioned the reader on a current valid change.\");\n return this._op;\n }\n\n // ---------------------------------------------------------------------------\n // Lifecycle\n // ---------------------------------------------------------------------------\n\n /**\n * Close the reader and release all native resources.\n * @beta\n */\n public close(): void {\n this._changeIndex = 0;\n this._op = undefined;\n this._isECTable = undefined;\n this._tableName = undefined;\n this._isIndirectChange = undefined;\n this.inserted = undefined;\n this.deleted = undefined;\n this._nativeReader.close();\n }\n\n /**\n * Implements the `Disposable` contract — calls [[close]].\n * @beta\n */\n public [Symbol.dispose](): void {\n this.close();\n }\n}\n\n\n"]}
1
+ {"version":3,"file":"ChangesetReader.js","sourceRoot":"","sources":["../../src/ChangesetReader.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 ECDb\n */\nimport { DbChangeStage, DbOpcode, Id64String, IModelStatus } from \"@itwin/core-bentley\";\nimport { IModelError } from \"@itwin/core-common\";\nimport { IModelDb } from \"./IModelDb\";\nimport { IModelNative } from \"./internal/NativePlatform\";\nimport { _nativeDb } from \"./internal/Symbols\";\nimport { IModelJsNative } from \"@bentley/imodeljs-native\";\nimport { ChangeInstance, ChangesetReaderArgs, ChangeSource, PropertyFilter, RowFormatOptions } from \"./ChangesetReaderTypes\";\nimport { AnyDb, SqliteChangeOp } from \"./SqliteChangesetReader\";\n\n\n// ---------------------------------------------------------------------------\n// ChangesetReader\n// ---------------------------------------------------------------------------\n\n/**\n * Reads EC-typed changeset data natively from a changeset file, changeset group,\n * in-memory transaction, or local un-pushed changes.\n *\n * Implements [ChangeSource]($backend) so rows can be fed directly into\n * [PartialChangeUnifier]($backend) to merge partial (per-table) instances into\n * complete EC instances.\n *\n * When the current row is a non-EC internal SQLite table, [[isECTable]] is `false`\n * and both [[inserted]] and [[deleted]] remain `undefined`.\n *\n * @note The native reader operates one SQLite table-row at a time. Multi-table EC\n * instances must be merged using [PartialChangeUnifier]($backend).\n * @beta\n */\nexport class ChangesetReader implements Disposable, ChangeSource {\n private static readonly defaultSpillThresholdInBytes = 50 * 1024 * 1024; // 50 MiB\n private readonly _nativeReader: IModelJsNative.ChangesetReader = new IModelNative.platform.ChangesetReader();\n // Internal options — keep ECClassId as raw Id so the unifier can use it as-is.\n private _rowOptions?: RowFormatOptions;\n private _propFilter: PropertyFilter = PropertyFilter.All;\n private _changeIndex = 0;\n private _op?: SqliteChangeOp;\n private _isECTable?: boolean;\n private _tableName?: string;\n private _isIndirectChange?: boolean;\n\n /** The db used for EC schema resolution. */\n public readonly db: AnyDb;\n\n /**\n * `true` when the current row belongs to an EC-mapped table.\n * Valid only after a successful call to [[step]].\n * @throws [[IModelError]] if called before a successful [[step]] call.\n * @beta\n */\n public get isECTable(): boolean {\n if (this._isECTable === undefined)\n throw new IModelError(IModelStatus.BadRequest, \"ChangesetReader.isECTable is only valid after step() has positioned the reader on a current valid change.\");\n return this._isECTable;\n }\n\n /**\n * Name of the SQLite table for the current change row.\n * Valid only after a successful call to [[step]].\n * @throws [[IModelError]] if called before a successful [[step]] call.\n * @beta\n */\n public get tableName(): string {\n if (this._tableName === undefined)\n throw new IModelError(IModelStatus.BadRequest, \"ChangesetReader.tableName is only valid after step() has positioned the reader on a current valid change.\");\n return this._tableName;\n }\n\n /**\n * `true` when the current change was applied indirectly\n * Valid only after a successful call to [[step]].\n * @throws [[IModelError]] if called before a successful [[step]] call.\n * @beta\n */\n public get isIndirectChange(): boolean {\n if (this._isIndirectChange === undefined)\n throw new IModelError(IModelStatus.BadRequest, \"ChangesetReader.isIndirectChange is only valid after step() has positioned the reader on a current valid change.\");\n return this._isIndirectChange;\n }\n\n /**\n * Post-change (inserted or updated-new) EC instance, populated after each [[step]] call.\n * `undefined` when the current row is a Delete or a non-EC table row or [[step]] returned false.\n * @beta\n */\n public inserted?: ChangeInstance;\n\n /**\n * Pre-change (deleted or updated-old) EC instance, populated after each [[step]] call.\n * `undefined` when the current row is an Insert or a non-EC table row or [[step]] returned false.\n * @beta\n */\n public deleted?: ChangeInstance;\n\n // Private — callers use static factory methods.\n private constructor(db: AnyDb) {\n this.db = db;\n }\n\n /** Map public RowFormatOptions to the native adaptor options.\n * @internal */\n private toNativeRowOptions(opts: RowFormatOptions): IModelJsNative.ECSqlRowAdaptorOptions {\n return {\n abbreviateBlobs: opts.abbreviateBlobs,\n classIdsToClassNames: opts.classIdsToClassNames,\n useJsName: opts.useJsName,\n };\n }\n\n // ---------------------------------------------------------------------------\n // Static factory methods\n // ---------------------------------------------------------------------------\n\n /**\n * Open a changeset file from disk.\n * @param args.fileName Absolute path to the changeset file.\n * @param args.db Database at or after the changeset's ending state, used for schema resolution.\n * @param args.invert When `true`, invert all operations (Insert↔Delete).\n * @param args.valueOptions Row adaptor options controlling how EC property values are formatted.\n * @param args.propFilter Controls which properties are included. Defaults to `All`.\n * @throws if the native layer fails to open the file.\n * @beta\n */\n public static openFile(args: { readonly fileName: string } & ChangesetReaderArgs): ChangesetReader {\n const reader = new ChangesetReader(args.db);\n reader._rowOptions = args.rowOptions;\n const propFilter = args.propFilter ?? PropertyFilter.All;\n reader._propFilter = propFilter;\n try {\n reader._nativeReader.openFile(args.db[_nativeDb], args.fileName, args.invert ?? false, reader._propFilter);\n }\n catch (e) {\n reader.handleCloseErrorWhileOpening(e);\n throw e;\n }\n return reader;\n }\n\n /**\n * Concatenate multiple changeset files and read them as a single logical stream.\n * @param args.changesetFiles Ordered list of changeset file paths.\n * @param args.db Database with schema at or ahead of the last changeset.\n * @param args.valueOptions Row adaptor options controlling how EC property values are formatted.\n * @param args.propFilter Controls which properties are included. Defaults to `All`.\n * @param args.spillThresholdInBytes When the total size of the changeset data in the change group exceeds this threshold (in bytes),\n * the reader writes the data to a temporary file on disk and streams it from there instead of buffering everything in memory.\n * This keeps peak memory usage bounded, making the API suitable for processing large changeset groups under low-memory conditions.\n * Defaults to 50 MiB.\n * @throws if `changesetFiles` is empty, or if the native layer fails to open\n * the group.\n * @beta\n */\n public static openGroup(args: { readonly changesetFiles: string[], spillThresholdInBytes?: number } & ChangesetReaderArgs): ChangesetReader {\n if (args.changesetFiles.length === 0)\n throw new IModelError(IModelStatus.BadArg, \"changesetFiles must contain at least one file.\");\n const reader = new ChangesetReader(args.db);\n reader._rowOptions = args.rowOptions;\n const propFilter = args.propFilter ?? PropertyFilter.All;\n reader._propFilter = propFilter;\n try {\n reader._nativeReader.openGroup(args.db[_nativeDb], args.changesetFiles, args.invert ?? false, reader._propFilter, args.spillThresholdInBytes ?? this.defaultSpillThresholdInBytes);\n }\n catch (e) {\n reader.handleCloseErrorWhileOpening(e);\n throw e;\n }\n return reader;\n }\n\n /**\n * Read pending (not yet pushed) local changes from an open IModelDb.\n * @param args.db Must be an [IModelDb]($backend) (not [ECDb]($backend)).\n * @param args.includeInMemoryChanges Also include in-memory (not yet saved to disk) changes.\n * @param args.valueOptions Row adaptor options controlling how EC property values are formatted.\n * @param args.propFilter Controls which properties are included. Defaults to `All`.\n * @param args.spillThresholdInBytes When the total size of all local un-pushed saved changes exceeds this threshold (in bytes),\n * the reader writes the data to a temporary file on disk and streams it from there instead of buffering everything in memory.\n * This keeps peak memory usage bounded, making the API suitable for iModels with large local change backlogs under low-memory conditions.\n * Defaults to 50 MiB.\n * @throws if the native layer\n * fails to open the local changes.\n * @beta\n */\n public static openLocalChanges(\n args: Omit<ChangesetReaderArgs, \"db\"> & { db: IModelDb; includeInMemoryChanges?: boolean, spillThresholdInBytes?: number },\n ): ChangesetReader {\n const reader = new ChangesetReader(args.db);\n reader._rowOptions = args.rowOptions;\n const propFilter = args.propFilter ?? PropertyFilter.All;\n reader._propFilter = propFilter;\n try {\n reader._nativeReader.openLocalChanges(args.db[_nativeDb], args.includeInMemoryChanges ?? false, args.invert ?? false, reader._propFilter, args.spillThresholdInBytes ?? this.defaultSpillThresholdInBytes);\n } catch (e) {\n reader.handleCloseErrorWhileOpening(e);\n throw e;\n }\n return reader;\n }\n\n /**\n * Read the in-memory (not yet saved to disk) changes of an open IModelDb.\n * @param args.db Must be an [IModelDb]($backend).\n * @param args.valueOptions Row adaptor options controlling how EC property values are formatted.\n * @param args.propFilter Controls which properties are included. Defaults to `All`.\n * @param args.spillThresholdInBytes When the total size of the in-memory (unsaved) change data exceeds this threshold (in bytes),\n * the reader writes the data to a temporary file on disk and streams it from there instead of buffering everything in memory.\n * This keeps peak memory usage bounded, making the API suitable for large in-memory transactions under low-memory conditions.\n * Defaults to 50 MiB.\n * @throws if the native layer encounters an error while opening the in-memory changes.\n * @beta\n */\n public static openInMemoryChanges(\n args: Omit<ChangesetReaderArgs, \"db\"> & { db: IModelDb, spillThresholdInBytes?: number },\n ): ChangesetReader {\n const reader = new ChangesetReader(args.db);\n reader._rowOptions = args.rowOptions;\n const propFilter = args.propFilter ?? PropertyFilter.All;\n reader._propFilter = propFilter;\n try {\n reader._nativeReader.openInMemoryChanges(args.db[_nativeDb], args.invert ?? false, reader._propFilter, args.spillThresholdInBytes ?? this.defaultSpillThresholdInBytes);\n } catch (e) {\n reader.handleCloseErrorWhileOpening(e);\n throw e;\n }\n return reader;\n }\n\n /**\n * Read a single saved transaction by its id.\n * @param args.db Must be an [IModelDb]($backend) ([ECDb]($backend) does not support transactions).\n * @param args.txnId The id of the saved transaction to read.\n * @param args.valueOptions Row adaptor options controlling how EC property values are formatted.\n * @param args.propFilter Controls which properties are included. Defaults to `All`.\n * @param args.spillThresholdInBytes When the total size of the transaction's change data exceeds this threshold (in bytes),\n * the reader writes the data to a temporary file on disk and streams it from there instead of buffering everything in memory.\n * This keeps peak memory usage bounded, making the API suitable for large transactions under low-memory conditions.\n * Defaults to 50 MiB.\n * @throws if `txnId` is not found, or\n * the native layer fails to open the transaction data.\n * @beta\n */\n public static openTxn(\n args: Omit<ChangesetReaderArgs, \"db\"> & { db: IModelDb; txnId: Id64String, spillThresholdInBytes?: number },\n ): ChangesetReader {\n const reader = new ChangesetReader(args.db);\n reader._rowOptions = args.rowOptions;\n const propFilter = args.propFilter ?? PropertyFilter.All;\n reader._propFilter = propFilter;\n try {\n reader._nativeReader.openTxn(args.db[_nativeDb], args.txnId, args.invert ?? false, reader._propFilter, args.spillThresholdInBytes ?? this.defaultSpillThresholdInBytes);\n } catch (e) {\n reader.handleCloseErrorWhileOpening(e);\n throw e;\n }\n return reader;\n }\n\n /** Handle errors that occur while auto closing the reader if there is also an error while opening the reader */\n private handleCloseErrorWhileOpening(e: unknown): void {\n try {\n this.close();\n } catch (closeError) {\n throw new IModelError(IModelStatus.BadArg, `Failed to open ChangesetReader with error ${e instanceof Error ? e.message : String(e)}.\n Additionally, that triggered an automatic closure of the reader\n releasing native resources which also failed with failure ${closeError instanceof Error ? closeError.message : String(closeError)}.\n Check native error logs for more details.`);\n }\n }\n\n // ---------------------------------------------------------------------------\n // Filtering\n // ---------------------------------------------------------------------------\n\n /**\n * Restrict iteration to changes from the named SQLite tables.\n * That means the rows for changes from other tables will be skipped entirely and won't be visible through the reader.\n * @param tableNames SQLite table names to include.\n * Note: Table names must be provided in the correct case for proper filtering.\n * @throws if the native layer encounters an error while setting the filter.\n * @beta\n */\n public setTableNameFilters(tableNames: Set<string>): void {\n this._nativeReader.setTableNameFilters(Array.from(tableNames));\n }\n\n /**\n * Restrict iteration to changes with the given operation types.\n * That means the rows for changes with other operation types will be skipped entirely and won't be visible through the reader.\n * @param ops Operations to include.\n * @throws if the native layer encounters an error while setting the filter.\n * @beta\n */\n public setOpCodeFilters(ops: Set<SqliteChangeOp>): void {\n this._nativeReader.setOpCodeFilters(Array.from(ops));\n }\n\n /**\n * Restrict iteration to changes for the given EC class names.\n * That means the rows for changes from other EC classes will be skipped entirely and won't be visible through the reader.\n * @param classNames EC class names to include. The classNames should be in the full name format(i.e. \"SchemaName:ClassName\").\n * Note: Schema names and class names must be provided in the correct case for proper filtering. Derived classes are not automatically included, so they must be specified explicitly if needed.\n * @throws if the native layer encounters an error while setting the filter.\n * @beta\n */\n public setClassNameFilters(classNames: Set<string>): void {\n this._nativeReader.setClassNameFilters(Array.from(classNames));\n }\n\n /**\n * Remove the table-name filters\n * @throws if the native layer encounters an error.\n * @beta\n */\n public clearTableNameFilters(): void {\n this._nativeReader.clearTableNameFilters();\n }\n\n /**\n * Remove the op-code filters\n * @throws if the native layer encounters an error.\n * @beta\n */\n public clearOpCodeFilters(): void {\n this._nativeReader.clearOpCodeFilters();\n }\n\n /**\n * Remove the class-name filters\n * @throws if the native layer encounters an error.\n * @beta\n */\n public clearClassNameFilters(): void {\n this._nativeReader.clearClassNameFilters();\n }\n\n // ---------------------------------------------------------------------------\n // Strict mode\n // ---------------------------------------------------------------------------\n\n /**\n * Enable strict mode on the reader.\n *\n * Strict mode affects how the reader handles a **column-count mismatch** between a change\n * record and the corresponding live database table. Such a mismatch can occur when columns\n * have been added to a table after the changeset was created.\n *\n * When strict mode is **enabled**: if the number of columns recorded in a change row differs\n * from the number of columns currently present in the live table, the reader throws an error\n * instead of processing that row.\n *\n * Use strict mode when you need to be certain that every change row is interpreted against\n * exactly the schema that was in effect when the changeset was written.\n *\n * @see [[disableStrictMode]] — the default (lenient) behaviour.\n * @throws if the native layer encounters an error.\n * @beta\n */\n public enableStrictMode(): void {\n this._nativeReader.enableStrictMode();\n }\n\n /**\n * Disable strict mode on the reader (this is the default).\n *\n * When strict mode is **disabled**: if the number of columns recorded in a change row differs\n * from the number of columns currently present in the live table, the reader takes the\n * **minimum** of the two column counts and proceeds normally with that subset. This is safe\n * because SQLite only ever appends new columns at the end of a table and never removes them —\n * so older change records simply lack the trailing columns that were added later, and those\n * missing columns are silently ignored.\n *\n * @see [[enableStrictMode]] — throw on column-count mismatches instead.\n * @throws if the native layer encounters an error.\n * @beta\n */\n public disableStrictMode(): void {\n this._nativeReader.disableStrictMode();\n }\n\n // ---------------------------------------------------------------------------\n // Iteration\n // ---------------------------------------------------------------------------\n\n /**\n * Advance to the next change and populate `inserted` and/or `deleted`.\n * @returns `true` while positioned on a valid change; `false` when the stream is exhausted.\n * @throws if the native layer encounters an error while reading or decoding\n * the next change.\n * @beta\n */\n public step(): boolean {\n this.inserted = undefined;\n this.deleted = undefined;\n this._op = undefined;\n this._isECTable = undefined;\n this._tableName = undefined;\n this._isIndirectChange = undefined;\n\n if (this._nativeReader.step()) {\n this._changeIndex++;\n const meta = this._nativeReader.getChangeMetadata();\n const nativeOp = meta.opCode;\n const op: SqliteChangeOp = nativeOp === DbOpcode.Insert ? \"Inserted\" : nativeOp === DbOpcode.Update ? \"Updated\" : \"Deleted\";\n this._op = op;\n\n this._tableName = meta.tableName;\n this._isIndirectChange = meta.isIndirectChange;\n this._isECTable = meta.isECTable;\n\n const nativeRowOpts = this._rowOptions ? this.toNativeRowOptions(this._rowOptions) : {};\n\n if (op === \"Inserted\" || op === \"Updated\") {\n const rowValue = this._nativeReader.getValue(DbChangeStage.New, nativeRowOpts);\n if (rowValue !== undefined) {\n this.inserted = {\n ...rowValue.data,\n $meta: {\n op,\n tables: [this._tableName],\n changeIndexes: [this._changeIndex],\n stage: \"New\",\n instanceKey: rowValue.key,\n propFilter: this._propFilter,\n changeFetchedPropNames: rowValue.changeFetchedPropNames,\n rowOptions: this._rowOptions,\n isIndirectChange: this._isIndirectChange,\n },\n };\n }\n }\n\n if (op === \"Deleted\" || op === \"Updated\") {\n const rowValue = this._nativeReader.getValue(DbChangeStage.Old, nativeRowOpts);\n if (rowValue !== undefined) {\n this.deleted = {\n ...rowValue.data,\n $meta: {\n op,\n tables: [this._tableName],\n changeIndexes: [this._changeIndex],\n stage: \"Old\",\n instanceKey: rowValue.key,\n propFilter: this._propFilter,\n changeFetchedPropNames: rowValue.changeFetchedPropNames,\n rowOptions: this._rowOptions,\n isIndirectChange: this._isIndirectChange,\n },\n };\n }\n }\n\n return true;\n }\n\n return false;\n }\n\n /**\n * SQLite opcode of the current change.\n * Valid only after a successful call to [[step]].\n * @throws [[IModelError]] if called before a successful [[step]] call.\n * @beta\n */\n public get op(): SqliteChangeOp {\n if (this._op === undefined)\n throw new IModelError(IModelStatus.BadRequest, \"ChangesetReader.op is only valid after step() has positioned the reader on a current valid change.\");\n return this._op;\n }\n\n // ---------------------------------------------------------------------------\n // Lifecycle\n // ---------------------------------------------------------------------------\n\n /**\n * Close the reader and release all native resources.\n *\n * @throws if the native layer encounters an error during cleanup. Native resources\n * are not fully released when this throws — check the native error\n * logs for details.\n * @beta\n */\n public close(): void {\n this._changeIndex = 0;\n this._op = undefined;\n this._isECTable = undefined;\n this._tableName = undefined;\n this._isIndirectChange = undefined;\n this.inserted = undefined;\n this.deleted = undefined;\n this._nativeReader.close();\n }\n\n /**\n * Implements the `Disposable` contract — delegates to [[close]].\n *\n * @throws if the native layer fails to release its resources (re-thrown from [[close]]).\n * @beta\n */\n public [Symbol.dispose](): void {\n this.close();\n }\n}\n\n\n"]}
@@ -115,7 +115,7 @@ export declare class ClassRegistry {
115
115
  * A cache that records the mapping between class names and class metadata.
116
116
  * @see [[IModelDb.classMetaDataRegistry]] to access the registry for a specific iModel.
117
117
  * @internal
118
- * @deprecated in 5.0 - will not be removed until after 2026-06-13. Please use `schemaContext` from the `iModel` instead.
118
+ * @deprecated in 5.0 - will not be removed until after 2026-06-13. Use `getSchemaView()` from the `iModel` instead.
119
119
  *
120
120
  * @example
121
121
  * @
@@ -126,8 +126,8 @@ export declare class ClassRegistry {
126
126
  *
127
127
  * Replacement:
128
128
  * ```ts
129
- * const entityMetaData: EntityClass | undefined = iModel.schemaContext.getSchemaItemSync("SchemaName.ClassName", EntityClass);
130
- * const relationshipMetaData: RelationshipClass | undefined = iModel.schemaContext.getSchemaItemSync("SchemaName", "ClassName", RelationshipClass);
129
+ * const view = await iModel.getSchemaView();
130
+ * const cls = view.findClass("SchemaName:ClassName");
131
131
  * ```
132
132
  */
133
133
  export declare class MetaDataRegistry {
@@ -292,7 +292,7 @@ export class ClassRegistry {
292
292
  * A cache that records the mapping between class names and class metadata.
293
293
  * @see [[IModelDb.classMetaDataRegistry]] to access the registry for a specific iModel.
294
294
  * @internal
295
- * @deprecated in 5.0 - will not be removed until after 2026-06-13. Please use `schemaContext` from the `iModel` instead.
295
+ * @deprecated in 5.0 - will not be removed until after 2026-06-13. Use `getSchemaView()` from the `iModel` instead.
296
296
  *
297
297
  * @example
298
298
  * @
@@ -303,8 +303,8 @@ export class ClassRegistry {
303
303
  *
304
304
  * Replacement:
305
305
  * ```ts
306
- * const entityMetaData: EntityClass | undefined = iModel.schemaContext.getSchemaItemSync("SchemaName.ClassName", EntityClass);
307
- * const relationshipMetaData: RelationshipClass | undefined = iModel.schemaContext.getSchemaItemSync("SchemaName", "ClassName", RelationshipClass);
306
+ * const view = await iModel.getSchemaView();
307
+ * const cls = view.findClass("SchemaName:ClassName");
308
308
  * ```
309
309
  */
310
310
  export class MetaDataRegistry {
@@ -1 +1 @@
1
- {"version":3,"file":"ClassRegistry.js","sourceRoot":"","sources":["../../src/ClassRegistry.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 Schema\n */\n\nimport { DbResult, Id64, Id64String, IModelStatus, Logger } from \"@itwin/core-bentley\";\nimport { EntityMetaData, EntityReferenceSet, IModelError, RelatedElement } from \"@itwin/core-common\";\nimport { Entity } from \"./Entity\";\nimport { IModelDb } from \"./IModelDb\";\nimport { Schema, Schemas } from \"./Schema\";\nimport { EntityReferences } from \"./EntityReferences\";\nimport * as assert from \"assert\";\nimport { _nativeDb } from \"./internal/Symbols\";\n\nconst isGeneratedClassTag = Symbol(\"isGeneratedClassTag\");\n\n/** Maintains the mapping between the name of a BIS [ECClass]($ecschema-metadata) (in \"schema:class\" format) and the JavaScript [[Entity]] class that implements it.\n * @public\n */\nexport class EntityJsClassMap {\n private readonly _classMap = new Map<string, typeof Entity>();\n\n /** @internal */\n public has(classFullName: string): boolean {\n return this._classMap.has(classFullName.toLowerCase());\n }\n\n /** @internal */\n public get(classFullName: string): typeof Entity | undefined {\n return this._classMap.get(classFullName.toLowerCase());\n }\n\n /** @internal */\n public set(classFullName: string, entityClass: typeof Entity): void {\n this._classMap.set(classFullName.toLowerCase(), entityClass);\n }\n\n /** @internal */\n public delete(classFullName: string): boolean {\n return this._classMap.delete(classFullName.toLowerCase());\n }\n\n /** @internal */\n public clear(): void {\n this._classMap.clear();\n }\n\n /** @internal */\n public [Symbol.iterator](): IterableIterator<[string, typeof Entity]> {\n return this._classMap[Symbol.iterator]();\n }\n\n /**\n * Registers a single `entityClass` defined in the specified `schema`.\n * This method registers the class globally. To register a class for a specific iModel, use [[IModelDb.jsClassMap]].\n *\n * @param entityClass - The JavaScript class that implements the BIS [ECClass](@itwin/core-common) to be registered.\n * @param schema - The schema that contains the `entityClass`.\n *\n * @throws Error if the class is already registered.\n *\n * @public\n */\n public register(entityClass: typeof Entity, schema: typeof Schema): void {\n const key = (`${schema.schemaName}:${entityClass.className}`).toLowerCase();\n if (this.has(key)) {\n const errMsg = `Class ${key} is already registered. Make sure static className member is correct on JavaScript class ${entityClass.name}`;\n Logger.logError(\"core-frontend.classRegistry\", errMsg);\n throw new Error(errMsg);\n }\n entityClass.schema = schema;\n this.set(key, entityClass);\n }\n}\n\n/** Maintains the mapping between the name of a BIS [ECClass]($ecschema-metadata) (in \"schema:class\" format) and the JavaScript [[Entity]] class that implements it.\n * Applications or modules that supply their own Entity subclasses should use [[registerModule]] or [[register]] at startup\n * to establish their mappings.\n *\n * When creating custom Entity subclasses for registration, you should:\n * - Override the `className` property to match your ECClass name:\n * ```typescript\n * public static override get className() { return \"TestElement\"; }\n * ```\n * - Do NOT override `schemaName` or `schema` - these will be wired up automatically during registration\n *\n * @public\n */\nexport class ClassRegistry {\n private static readonly _globalClassMap = new EntityJsClassMap();\n /** @internal */\n public static isNotFoundError(err: any) { return (err instanceof IModelError) && (err.errorNumber === IModelStatus.NotFound); }\n /** @internal */\n public static makeMetaDataNotFoundError(className: string): IModelError { return new IModelError(IModelStatus.NotFound, `metadata not found for ${className}`); }\n /** Register a single `entityClass` defined in the specified `schema`.\n * @see [[registerModule]] to register multiple classes.\n * @public\n */\n public static register(entityClass: typeof Entity, schema: typeof Schema) {\n this._globalClassMap.register(entityClass, schema);\n }\n\n /** Generate a proxy Schema for a domain that has not been registered. */\n private static generateProxySchema(domain: string, iModel: IModelDb): typeof Schema {\n const hasBehavior = iModel.withPreparedSqliteStatement(`\n SELECT NULL FROM [ec_CustomAttribute] [c]\n JOIN [ec_schema] [s] ON [s].[Id] = [c].[ContainerId]\n JOIN [ec_class] [e] ON [e].[Id] = [c].[ClassId]\n JOIN [ec_schema] [b] ON [e].[SchemaId] = [b].[Id]\n WHERE [c].[ContainerType] = 1 AND [s].[Name] = ? AND [b].[Name] || '.' || [e].[name] = ?`, (stmt) => {\n stmt.bindString(1, domain);\n stmt.bindString(2, \"BisCore.SchemaHasBehavior\");\n return stmt.step() === DbResult.BE_SQLITE_ROW;\n });\n\n const schemaClass = class extends Schema {\n public static override get schemaName() { return domain; }\n public static override get missingRequiredBehavior() { return hasBehavior; }\n };\n\n iModel.schemaMap.registerSchema(schemaClass); // register the class before we return it.\n return schemaClass;\n }\n\n /** First, finds the root BisCore entity class for an entity, by traversing base classes and mixin targets (AppliesTo).\n * Then, gets its metadata and returns that.\n * @param iModel - iModel containing the metadata for this type\n * @param ecTypeQualifier - a full name of an ECEntityClass to find the root of\n * @returns the qualified full name of an ECEntityClass\n * @internal public for testing only\n */\n public static getRootEntity(iModel: IModelDb, ecTypeQualifier: string): string {\n const [classSchema, className] = ecTypeQualifier.split(\".\");\n const schemaItemJson = iModel[_nativeDb].getSchemaItem(classSchema, className);\n if (schemaItemJson.error)\n throw new IModelError(schemaItemJson.error.status, `failed to get schema item '${ecTypeQualifier}'`);\n\n assert(undefined !== schemaItemJson.result);\n const schemaItem = JSON.parse(schemaItemJson.result);\n if (!(\"appliesTo\" in schemaItem) && schemaItem.baseClass === undefined) {\n return ecTypeQualifier;\n }\n\n // typescript doesn't understand that the inverse of the above condition is\n // (\"appliesTo\" in rootclassMetaData || rootClassMetaData.baseClass !== undefined)\n const parentItemQualifier = schemaItem.appliesTo ?? schemaItem.baseClass as string;\n return this.getRootEntity(iModel, parentItemQualifier);\n }\n\n /** Generate a JavaScript class from Entity metadata.\n * @param entityMetaData The Entity metadata that defines the class\n */\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n private static generateClassForEntity(entityMetaData: EntityMetaData, iModel: IModelDb): typeof Entity {\n const name = entityMetaData.ecclass.split(\":\");\n const domainName = name[0];\n const className = name[1];\n\n if (0 === entityMetaData.baseClasses.length) // metadata must contain a superclass\n throw new IModelError(IModelStatus.BadArg, `class ${entityMetaData.ecclass} has no superclass`);\n\n // make sure schema exists\n let schema = iModel.schemaMap.get(domainName) ?? Schemas.getRegisteredSchema(domainName);\n if (undefined === schema)\n schema = this.generateProxySchema(domainName, iModel); // no schema found, create it too\n\n const superClassFullName = entityMetaData.baseClasses[0].toLowerCase();\n const superclass = iModel.jsClassMap.get(superClassFullName) ?? this._globalClassMap.get(superClassFullName);\n if (undefined === superclass)\n throw new IModelError(IModelStatus.NotFound, `cannot find superclass for class ${entityMetaData.ecclass}`);\n\n // user defined class hierarchies may skip a class in the hierarchy, and therefore their JS base class cannot\n // be used to tell if there are any generated classes in the hierarchy\n let generatedClassHasNonGeneratedNonCoreAncestor = false;\n let currentSuperclass = superclass;\n const MAX_ITERS = 1000;\n for (let i = 0; i < MAX_ITERS; ++i) {\n if (currentSuperclass.schema.schemaName === \"BisCore\")\n break;\n\n if (!currentSuperclass.isGeneratedClass) {\n generatedClassHasNonGeneratedNonCoreAncestor = true;\n break;\n }\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n const superclassMetaData = iModel.classMetaDataRegistry.find(currentSuperclass.classFullName);\n if (superclassMetaData === undefined)\n throw new IModelError(IModelStatus.BadSchema, `could not find the metadata for class '${currentSuperclass.name}', class metadata should be loaded by now`);\n const maybeNextSuperclass = this.getClass(superclassMetaData.baseClasses[0], iModel);\n if (maybeNextSuperclass === undefined)\n throw new IModelError(IModelStatus.BadSchema, `could not find the base class of '${currentSuperclass.name}', all generated classes must have a base class`);\n currentSuperclass = maybeNextSuperclass;\n }\n\n const generatedClass = class extends superclass {\n public static override get className() { return className; }\n private static [isGeneratedClassTag] = true;\n public static override get isGeneratedClass() { return this.hasOwnProperty(isGeneratedClassTag); }\n };\n\n // the above creates an anonymous class. For help debugging, set the \"constructor.name\" property to be the same as the bisClassName.\n Object.defineProperty(generatedClass, \"name\", { get: () => className }); // this is the (only) way to change that readonly property.\n\n // a class only gets an automatic `collectReferenceIds` implementation if:\n // - it is not in the `BisCore` schema\n // - there are no ancestors with manually registered JS implementations, (excluding BisCore base classes)\n if (!generatedClassHasNonGeneratedNonCoreAncestor) {\n const navigationProps = Object.entries(entityMetaData.properties)\n .filter(([_name, prop]) => prop.isNavigation)\n // eslint-disable-next-line @typescript-eslint/no-shadow\n .map(([name, prop]) => {\n assert(prop.relationshipClass);\n const maybeMetaData = iModel[_nativeDb].getSchemaItem(...prop.relationshipClass.split(\":\") as [string, string]);\n assert(maybeMetaData.result !== undefined, \"The nav props relationship metadata was not found\");\n const relMetaData = JSON.parse(maybeMetaData.result);\n const rootClassMetaData = ClassRegistry.getRootEntity(iModel, relMetaData.target.constraintClasses[0]);\n // root class must be in BisCore so should be loaded since biscore classes will never get this\n // generated implementation\n const normalizeClassName = (clsName: string) => clsName.replace(\".\", \":\");\n const rootClass = ClassRegistry.findRegisteredClass(normalizeClassName(rootClassMetaData));\n assert(rootClass, `The root class for ${prop.relationshipClass} was not in BisCore.`);\n return { name, concreteEntityType: EntityReferences.typeFromClass(rootClass) };\n });\n\n Object.defineProperty(\n generatedClass.prototype,\n \"collectReferenceIds\",\n {\n value(this: typeof generatedClass, referenceIds: EntityReferenceSet) {\n // eslint-disable-next-line @typescript-eslint/dot-notation\n const superImpl = superclass.prototype[\"collectReferenceIds\"];\n superImpl.call(this, referenceIds);\n for (const navProp of navigationProps) {\n const relatedElem: RelatedElement | undefined = (this as any)[navProp.name]; // cast to any since subclass can have any extensions\n if (!relatedElem || !Id64.isValid(relatedElem.id))\n continue;\n const referenceId = EntityReferences.fromEntityType(relatedElem.id, navProp.concreteEntityType);\n referenceIds.add(referenceId);\n }\n },\n // defaults for methods on a prototype (required for sinon to stub out methods on tests)\n writable: true,\n configurable: true,\n },\n );\n }\n\n // if the schema is a proxy for a domain with behavior, throw exceptions for all protected operations\n if (schema.missingRequiredBehavior) {\n const throwError = () => {\n throw new IModelError(IModelStatus.WrongHandler, `Schema [${domainName}] not registered, but is marked with SchemaHasBehavior`);\n };\n\n superclass.protectedOperations.forEach((operation) => (generatedClass as any)[operation] = throwError);\n }\n\n iModel.jsClassMap.register(generatedClass, schema); // register it before returning\n return generatedClass;\n }\n\n /** Register all of the classes found in the given module that derive from [[Entity]].\n * [[register]] will be invoked for each subclass of `Entity` exported by `moduleObj`.\n * @param moduleObj The module to search for subclasses of Entity\n * @param schema The schema that contains all of the [ECClass]($ecschema-metadata)es exported by `moduleObj`.\n */\n public static registerModule(moduleObj: any, schema: typeof Schema) {\n for (const thisMember in moduleObj) { // eslint-disable-line guard-for-in\n const thisClass = moduleObj[thisMember];\n if (thisClass.prototype instanceof Entity)\n this.register(thisClass, schema);\n }\n }\n\n /**\n * This function fetches the specified Entity from the imodel, generates a JavaScript class for it, and registers the generated\n * class. This function also ensures that all of the base classes of the Entity exist and are registered.\n */\n private static generateClass(classFullName: string, iModel: IModelDb): typeof Entity {\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n const metadata: EntityMetaData | undefined = iModel.classMetaDataRegistry.find(classFullName);\n if (metadata === undefined || metadata.ecclass === undefined)\n throw this.makeMetaDataNotFoundError(classFullName);\n\n // Make sure we have all base classes registered.\n if (metadata.baseClasses && (0 !== metadata.baseClasses.length))\n this.getClass(metadata.baseClasses[0], iModel);\n\n // Now we can generate the class from the classDef.\n return this.generateClassForEntity(metadata, iModel);\n }\n\n /** Find a registered class by classFullName.\n * @param classFullName class to find\n * @param iModel The IModel that contains the class definitions\n * @returns The Entity class or undefined\n */\n public static findRegisteredClass(classFullName: string): typeof Entity | undefined {\n return this._globalClassMap.get(classFullName.toLowerCase());\n }\n\n /** Get the Entity class for the specified Entity className.\n * @param classFullName The full BIS class name of the Entity\n * @param iModel The IModel that contains the class definitions\n * @returns The Entity class\n */\n public static getClass(classFullName: string, iModel: IModelDb): typeof Entity {\n const key = classFullName.toLowerCase();\n return iModel.jsClassMap.get(key) ?? this._globalClassMap.get(key) ?? this.generateClass(key, iModel);\n }\n\n /** Unregister a class, by name, if one is already registered.\n * This function is not normally needed, but is useful for cases where a generated *proxy* class needs to be replaced by the *real* class.\n * @param classFullName Name of the class to unregister\n * @return true if the class was unregistered\n * @internal\n */\n public static unregisterClass(classFullName: string) { return this._globalClassMap.delete(classFullName.toLowerCase()); }\n\n /** Unregister all classes from a schema.\n * This function is not normally needed, but is useful for cases where a generated *proxy* schema needs to be replaced by the *real* schema.\n * @param schema Name of the schema to unregister\n * @internal\n */\n public static unregisterClassesFrom(schema: typeof Schema) {\n for (const entry of Array.from(this._globalClassMap)) {\n if (entry[1].schema === schema)\n this.unregisterClass(entry[0]);\n }\n }\n}\n\n/**\n * A cache that records the mapping between class names and class metadata.\n * @see [[IModelDb.classMetaDataRegistry]] to access the registry for a specific iModel.\n * @internal\n * @deprecated in 5.0 - will not be removed until after 2026-06-13. Please use `schemaContext` from the `iModel` instead.\n *\n * @example\n * @\n * Current Usage:\n * ```ts\n * const metaData: EntityMetaData | undefined = iModel.classMetaDataRegistry.find(\"SchemaName:ClassName\");\n * ```\n *\n * Replacement:\n * ```ts\n * const entityMetaData: EntityClass | undefined = iModel.schemaContext.getSchemaItemSync(\"SchemaName.ClassName\", EntityClass);\n * const relationshipMetaData: RelationshipClass | undefined = iModel.schemaContext.getSchemaItemSync(\"SchemaName\", \"ClassName\", RelationshipClass);\n * ```\n */\nexport class MetaDataRegistry {\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n private _registry = new Map<string, EntityMetaData>();\n private _classIdToName = new Map<Id64String, string>();\n\n /** Get the specified Entity metadata */\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n public find(classFullName: string): EntityMetaData | undefined {\n return this._registry.get(classFullName.toLowerCase());\n }\n\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n public findByClassId(classId: Id64String): EntityMetaData | undefined {\n const name = this._classIdToName.get(classId);\n return undefined !== name ? this.find(name) : undefined;\n }\n\n /** Add metadata to the cache */\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n public add(classFullName: string, metaData: EntityMetaData): void {\n const name = classFullName.toLowerCase();\n this._registry.set(name, metaData);\n this._classIdToName.set(metaData.classId, name);\n }\n}\n"]}
1
+ {"version":3,"file":"ClassRegistry.js","sourceRoot":"","sources":["../../src/ClassRegistry.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 Schema\n */\n\nimport { DbResult, Id64, Id64String, IModelStatus, Logger } from \"@itwin/core-bentley\";\nimport { EntityMetaData, EntityReferenceSet, IModelError, RelatedElement } from \"@itwin/core-common\";\nimport { Entity } from \"./Entity\";\nimport { IModelDb } from \"./IModelDb\";\nimport { Schema, Schemas } from \"./Schema\";\nimport { EntityReferences } from \"./EntityReferences\";\nimport * as assert from \"assert\";\nimport { _nativeDb } from \"./internal/Symbols\";\n\nconst isGeneratedClassTag = Symbol(\"isGeneratedClassTag\");\n\n/** Maintains the mapping between the name of a BIS [ECClass]($ecschema-metadata) (in \"schema:class\" format) and the JavaScript [[Entity]] class that implements it.\n * @public\n */\nexport class EntityJsClassMap {\n private readonly _classMap = new Map<string, typeof Entity>();\n\n /** @internal */\n public has(classFullName: string): boolean {\n return this._classMap.has(classFullName.toLowerCase());\n }\n\n /** @internal */\n public get(classFullName: string): typeof Entity | undefined {\n return this._classMap.get(classFullName.toLowerCase());\n }\n\n /** @internal */\n public set(classFullName: string, entityClass: typeof Entity): void {\n this._classMap.set(classFullName.toLowerCase(), entityClass);\n }\n\n /** @internal */\n public delete(classFullName: string): boolean {\n return this._classMap.delete(classFullName.toLowerCase());\n }\n\n /** @internal */\n public clear(): void {\n this._classMap.clear();\n }\n\n /** @internal */\n public [Symbol.iterator](): IterableIterator<[string, typeof Entity]> {\n return this._classMap[Symbol.iterator]();\n }\n\n /**\n * Registers a single `entityClass` defined in the specified `schema`.\n * This method registers the class globally. To register a class for a specific iModel, use [[IModelDb.jsClassMap]].\n *\n * @param entityClass - The JavaScript class that implements the BIS [ECClass](@itwin/core-common) to be registered.\n * @param schema - The schema that contains the `entityClass`.\n *\n * @throws Error if the class is already registered.\n *\n * @public\n */\n public register(entityClass: typeof Entity, schema: typeof Schema): void {\n const key = (`${schema.schemaName}:${entityClass.className}`).toLowerCase();\n if (this.has(key)) {\n const errMsg = `Class ${key} is already registered. Make sure static className member is correct on JavaScript class ${entityClass.name}`;\n Logger.logError(\"core-frontend.classRegistry\", errMsg);\n throw new Error(errMsg);\n }\n entityClass.schema = schema;\n this.set(key, entityClass);\n }\n}\n\n/** Maintains the mapping between the name of a BIS [ECClass]($ecschema-metadata) (in \"schema:class\" format) and the JavaScript [[Entity]] class that implements it.\n * Applications or modules that supply their own Entity subclasses should use [[registerModule]] or [[register]] at startup\n * to establish their mappings.\n *\n * When creating custom Entity subclasses for registration, you should:\n * - Override the `className` property to match your ECClass name:\n * ```typescript\n * public static override get className() { return \"TestElement\"; }\n * ```\n * - Do NOT override `schemaName` or `schema` - these will be wired up automatically during registration\n *\n * @public\n */\nexport class ClassRegistry {\n private static readonly _globalClassMap = new EntityJsClassMap();\n /** @internal */\n public static isNotFoundError(err: any) { return (err instanceof IModelError) && (err.errorNumber === IModelStatus.NotFound); }\n /** @internal */\n public static makeMetaDataNotFoundError(className: string): IModelError { return new IModelError(IModelStatus.NotFound, `metadata not found for ${className}`); }\n /** Register a single `entityClass` defined in the specified `schema`.\n * @see [[registerModule]] to register multiple classes.\n * @public\n */\n public static register(entityClass: typeof Entity, schema: typeof Schema) {\n this._globalClassMap.register(entityClass, schema);\n }\n\n /** Generate a proxy Schema for a domain that has not been registered. */\n private static generateProxySchema(domain: string, iModel: IModelDb): typeof Schema {\n const hasBehavior = iModel.withPreparedSqliteStatement(`\n SELECT NULL FROM [ec_CustomAttribute] [c]\n JOIN [ec_schema] [s] ON [s].[Id] = [c].[ContainerId]\n JOIN [ec_class] [e] ON [e].[Id] = [c].[ClassId]\n JOIN [ec_schema] [b] ON [e].[SchemaId] = [b].[Id]\n WHERE [c].[ContainerType] = 1 AND [s].[Name] = ? AND [b].[Name] || '.' || [e].[name] = ?`, (stmt) => {\n stmt.bindString(1, domain);\n stmt.bindString(2, \"BisCore.SchemaHasBehavior\");\n return stmt.step() === DbResult.BE_SQLITE_ROW;\n });\n\n const schemaClass = class extends Schema {\n public static override get schemaName() { return domain; }\n public static override get missingRequiredBehavior() { return hasBehavior; }\n };\n\n iModel.schemaMap.registerSchema(schemaClass); // register the class before we return it.\n return schemaClass;\n }\n\n /** First, finds the root BisCore entity class for an entity, by traversing base classes and mixin targets (AppliesTo).\n * Then, gets its metadata and returns that.\n * @param iModel - iModel containing the metadata for this type\n * @param ecTypeQualifier - a full name of an ECEntityClass to find the root of\n * @returns the qualified full name of an ECEntityClass\n * @internal public for testing only\n */\n public static getRootEntity(iModel: IModelDb, ecTypeQualifier: string): string {\n const [classSchema, className] = ecTypeQualifier.split(\".\");\n const schemaItemJson = iModel[_nativeDb].getSchemaItem(classSchema, className);\n if (schemaItemJson.error)\n throw new IModelError(schemaItemJson.error.status, `failed to get schema item '${ecTypeQualifier}'`);\n\n assert(undefined !== schemaItemJson.result);\n const schemaItem = JSON.parse(schemaItemJson.result);\n if (!(\"appliesTo\" in schemaItem) && schemaItem.baseClass === undefined) {\n return ecTypeQualifier;\n }\n\n // typescript doesn't understand that the inverse of the above condition is\n // (\"appliesTo\" in rootclassMetaData || rootClassMetaData.baseClass !== undefined)\n const parentItemQualifier = schemaItem.appliesTo ?? schemaItem.baseClass as string;\n return this.getRootEntity(iModel, parentItemQualifier);\n }\n\n /** Generate a JavaScript class from Entity metadata.\n * @param entityMetaData The Entity metadata that defines the class\n */\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n private static generateClassForEntity(entityMetaData: EntityMetaData, iModel: IModelDb): typeof Entity {\n const name = entityMetaData.ecclass.split(\":\");\n const domainName = name[0];\n const className = name[1];\n\n if (0 === entityMetaData.baseClasses.length) // metadata must contain a superclass\n throw new IModelError(IModelStatus.BadArg, `class ${entityMetaData.ecclass} has no superclass`);\n\n // make sure schema exists\n let schema = iModel.schemaMap.get(domainName) ?? Schemas.getRegisteredSchema(domainName);\n if (undefined === schema)\n schema = this.generateProxySchema(domainName, iModel); // no schema found, create it too\n\n const superClassFullName = entityMetaData.baseClasses[0].toLowerCase();\n const superclass = iModel.jsClassMap.get(superClassFullName) ?? this._globalClassMap.get(superClassFullName);\n if (undefined === superclass)\n throw new IModelError(IModelStatus.NotFound, `cannot find superclass for class ${entityMetaData.ecclass}`);\n\n // user defined class hierarchies may skip a class in the hierarchy, and therefore their JS base class cannot\n // be used to tell if there are any generated classes in the hierarchy\n let generatedClassHasNonGeneratedNonCoreAncestor = false;\n let currentSuperclass = superclass;\n const MAX_ITERS = 1000;\n for (let i = 0; i < MAX_ITERS; ++i) {\n if (currentSuperclass.schema.schemaName === \"BisCore\")\n break;\n\n if (!currentSuperclass.isGeneratedClass) {\n generatedClassHasNonGeneratedNonCoreAncestor = true;\n break;\n }\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n const superclassMetaData = iModel.classMetaDataRegistry.find(currentSuperclass.classFullName);\n if (superclassMetaData === undefined)\n throw new IModelError(IModelStatus.BadSchema, `could not find the metadata for class '${currentSuperclass.name}', class metadata should be loaded by now`);\n const maybeNextSuperclass = this.getClass(superclassMetaData.baseClasses[0], iModel);\n if (maybeNextSuperclass === undefined)\n throw new IModelError(IModelStatus.BadSchema, `could not find the base class of '${currentSuperclass.name}', all generated classes must have a base class`);\n currentSuperclass = maybeNextSuperclass;\n }\n\n const generatedClass = class extends superclass {\n public static override get className() { return className; }\n private static [isGeneratedClassTag] = true;\n public static override get isGeneratedClass() { return this.hasOwnProperty(isGeneratedClassTag); }\n };\n\n // the above creates an anonymous class. For help debugging, set the \"constructor.name\" property to be the same as the bisClassName.\n Object.defineProperty(generatedClass, \"name\", { get: () => className }); // this is the (only) way to change that readonly property.\n\n // a class only gets an automatic `collectReferenceIds` implementation if:\n // - it is not in the `BisCore` schema\n // - there are no ancestors with manually registered JS implementations, (excluding BisCore base classes)\n if (!generatedClassHasNonGeneratedNonCoreAncestor) {\n const navigationProps = Object.entries(entityMetaData.properties)\n .filter(([_name, prop]) => prop.isNavigation)\n // eslint-disable-next-line @typescript-eslint/no-shadow\n .map(([name, prop]) => {\n assert(prop.relationshipClass);\n const maybeMetaData = iModel[_nativeDb].getSchemaItem(...prop.relationshipClass.split(\":\") as [string, string]);\n assert(maybeMetaData.result !== undefined, \"The nav props relationship metadata was not found\");\n const relMetaData = JSON.parse(maybeMetaData.result);\n const rootClassMetaData = ClassRegistry.getRootEntity(iModel, relMetaData.target.constraintClasses[0]);\n // root class must be in BisCore so should be loaded since biscore classes will never get this\n // generated implementation\n const normalizeClassName = (clsName: string) => clsName.replace(\".\", \":\");\n const rootClass = ClassRegistry.findRegisteredClass(normalizeClassName(rootClassMetaData));\n assert(rootClass, `The root class for ${prop.relationshipClass} was not in BisCore.`);\n return { name, concreteEntityType: EntityReferences.typeFromClass(rootClass) };\n });\n\n Object.defineProperty(\n generatedClass.prototype,\n \"collectReferenceIds\",\n {\n value(this: typeof generatedClass, referenceIds: EntityReferenceSet) {\n // eslint-disable-next-line @typescript-eslint/dot-notation\n const superImpl = superclass.prototype[\"collectReferenceIds\"];\n superImpl.call(this, referenceIds);\n for (const navProp of navigationProps) {\n const relatedElem: RelatedElement | undefined = (this as any)[navProp.name]; // cast to any since subclass can have any extensions\n if (!relatedElem || !Id64.isValid(relatedElem.id))\n continue;\n const referenceId = EntityReferences.fromEntityType(relatedElem.id, navProp.concreteEntityType);\n referenceIds.add(referenceId);\n }\n },\n // defaults for methods on a prototype (required for sinon to stub out methods on tests)\n writable: true,\n configurable: true,\n },\n );\n }\n\n // if the schema is a proxy for a domain with behavior, throw exceptions for all protected operations\n if (schema.missingRequiredBehavior) {\n const throwError = () => {\n throw new IModelError(IModelStatus.WrongHandler, `Schema [${domainName}] not registered, but is marked with SchemaHasBehavior`);\n };\n\n superclass.protectedOperations.forEach((operation) => (generatedClass as any)[operation] = throwError);\n }\n\n iModel.jsClassMap.register(generatedClass, schema); // register it before returning\n return generatedClass;\n }\n\n /** Register all of the classes found in the given module that derive from [[Entity]].\n * [[register]] will be invoked for each subclass of `Entity` exported by `moduleObj`.\n * @param moduleObj The module to search for subclasses of Entity\n * @param schema The schema that contains all of the [ECClass]($ecschema-metadata)es exported by `moduleObj`.\n */\n public static registerModule(moduleObj: any, schema: typeof Schema) {\n for (const thisMember in moduleObj) { // eslint-disable-line guard-for-in\n const thisClass = moduleObj[thisMember];\n if (thisClass.prototype instanceof Entity)\n this.register(thisClass, schema);\n }\n }\n\n /**\n * This function fetches the specified Entity from the imodel, generates a JavaScript class for it, and registers the generated\n * class. This function also ensures that all of the base classes of the Entity exist and are registered.\n */\n private static generateClass(classFullName: string, iModel: IModelDb): typeof Entity {\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n const metadata: EntityMetaData | undefined = iModel.classMetaDataRegistry.find(classFullName);\n if (metadata === undefined || metadata.ecclass === undefined)\n throw this.makeMetaDataNotFoundError(classFullName);\n\n // Make sure we have all base classes registered.\n if (metadata.baseClasses && (0 !== metadata.baseClasses.length))\n this.getClass(metadata.baseClasses[0], iModel);\n\n // Now we can generate the class from the classDef.\n return this.generateClassForEntity(metadata, iModel);\n }\n\n /** Find a registered class by classFullName.\n * @param classFullName class to find\n * @param iModel The IModel that contains the class definitions\n * @returns The Entity class or undefined\n */\n public static findRegisteredClass(classFullName: string): typeof Entity | undefined {\n return this._globalClassMap.get(classFullName.toLowerCase());\n }\n\n /** Get the Entity class for the specified Entity className.\n * @param classFullName The full BIS class name of the Entity\n * @param iModel The IModel that contains the class definitions\n * @returns The Entity class\n */\n public static getClass(classFullName: string, iModel: IModelDb): typeof Entity {\n const key = classFullName.toLowerCase();\n return iModel.jsClassMap.get(key) ?? this._globalClassMap.get(key) ?? this.generateClass(key, iModel);\n }\n\n /** Unregister a class, by name, if one is already registered.\n * This function is not normally needed, but is useful for cases where a generated *proxy* class needs to be replaced by the *real* class.\n * @param classFullName Name of the class to unregister\n * @return true if the class was unregistered\n * @internal\n */\n public static unregisterClass(classFullName: string) { return this._globalClassMap.delete(classFullName.toLowerCase()); }\n\n /** Unregister all classes from a schema.\n * This function is not normally needed, but is useful for cases where a generated *proxy* schema needs to be replaced by the *real* schema.\n * @param schema Name of the schema to unregister\n * @internal\n */\n public static unregisterClassesFrom(schema: typeof Schema) {\n for (const entry of Array.from(this._globalClassMap)) {\n if (entry[1].schema === schema)\n this.unregisterClass(entry[0]);\n }\n }\n}\n\n/**\n * A cache that records the mapping between class names and class metadata.\n * @see [[IModelDb.classMetaDataRegistry]] to access the registry for a specific iModel.\n * @internal\n * @deprecated in 5.0 - will not be removed until after 2026-06-13. Use `getSchemaView()` from the `iModel` instead.\n *\n * @example\n * @\n * Current Usage:\n * ```ts\n * const metaData: EntityMetaData | undefined = iModel.classMetaDataRegistry.find(\"SchemaName:ClassName\");\n * ```\n *\n * Replacement:\n * ```ts\n * const view = await iModel.getSchemaView();\n * const cls = view.findClass(\"SchemaName:ClassName\");\n * ```\n */\nexport class MetaDataRegistry {\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n private _registry = new Map<string, EntityMetaData>();\n private _classIdToName = new Map<Id64String, string>();\n\n /** Get the specified Entity metadata */\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n public find(classFullName: string): EntityMetaData | undefined {\n return this._registry.get(classFullName.toLowerCase());\n }\n\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n public findByClassId(classId: Id64String): EntityMetaData | undefined {\n const name = this._classIdToName.get(classId);\n return undefined !== name ? this.find(name) : undefined;\n }\n\n /** Add metadata to the cache */\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n public add(classFullName: string, metaData: EntityMetaData): void {\n const name = classFullName.toLowerCase();\n this._registry.set(name, metaData);\n this._classIdToName.set(metaData.classId, name);\n }\n}\n"]}