@itwin/core-backend 5.8.2 → 5.9.0-dev.10

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 (751) hide show
  1. package/CHANGELOG.md +1 -1
  2. package/lib/cjs/BackendHubAccess.d.ts +38 -0
  3. package/lib/cjs/BackendHubAccess.d.ts.map +1 -1
  4. package/lib/cjs/BackendHubAccess.js.map +1 -1
  5. package/lib/cjs/BackendLoggerCategory.js.map +1 -1
  6. package/lib/cjs/BisCoreSchema.js.map +1 -1
  7. package/lib/cjs/BlobContainerService.js.map +1 -1
  8. package/lib/cjs/BriefcaseManager.js +3 -3
  9. package/lib/cjs/BriefcaseManager.js.map +1 -1
  10. package/lib/cjs/CatalogDb.js.map +1 -1
  11. package/lib/cjs/Category.d.ts +37 -7
  12. package/lib/cjs/Category.d.ts.map +1 -1
  13. package/lib/cjs/Category.js +33 -42
  14. package/lib/cjs/Category.js.map +1 -1
  15. package/lib/cjs/ChangeSummaryManager.js +2 -2
  16. package/lib/cjs/ChangeSummaryManager.js.map +1 -1
  17. package/lib/cjs/ChangedElementsDb.js.map +1 -1
  18. package/lib/cjs/ChangesetECAdaptor.d.ts.map +1 -1
  19. package/lib/cjs/ChangesetECAdaptor.js +253 -250
  20. package/lib/cjs/ChangesetECAdaptor.js.map +1 -1
  21. package/lib/cjs/ChannelControl.d.ts +29 -0
  22. package/lib/cjs/ChannelControl.d.ts.map +1 -1
  23. package/lib/cjs/ChannelControl.js.map +1 -1
  24. package/lib/cjs/CheckpointManager.js +1 -1
  25. package/lib/cjs/CheckpointManager.js.map +1 -1
  26. package/lib/cjs/ClassRegistry.js +5 -5
  27. package/lib/cjs/ClassRegistry.js.map +1 -1
  28. package/lib/cjs/CloudSqlite.d.ts +1 -1
  29. package/lib/cjs/CloudSqlite.d.ts.map +1 -1
  30. package/lib/cjs/CloudSqlite.js +68 -13
  31. package/lib/cjs/CloudSqlite.js.map +1 -1
  32. package/lib/cjs/CodeService.js.map +1 -1
  33. package/lib/cjs/CodeSpecs.d.ts +32 -3
  34. package/lib/cjs/CodeSpecs.d.ts.map +1 -1
  35. package/lib/cjs/CodeSpecs.js +48 -20
  36. package/lib/cjs/CodeSpecs.js.map +1 -1
  37. package/lib/cjs/ConcurrentQuery.js.map +1 -1
  38. package/lib/cjs/CustomViewState3dCreator.js.map +1 -1
  39. package/lib/cjs/DevTools.js.map +1 -1
  40. package/lib/cjs/DisplayStyle.d.ts +18 -3
  41. package/lib/cjs/DisplayStyle.d.ts.map +1 -1
  42. package/lib/cjs/DisplayStyle.js +10 -21
  43. package/lib/cjs/DisplayStyle.js.map +1 -1
  44. package/lib/cjs/ECDb.js.map +1 -1
  45. package/lib/cjs/ECSchemaXmlContext.js.map +1 -1
  46. package/lib/cjs/ECSqlRowExecutor.js.map +1 -1
  47. package/lib/cjs/ECSqlStatement.js.map +1 -1
  48. package/lib/cjs/ECSqlSyncReader.js.map +1 -1
  49. package/lib/cjs/EditTxn.d.ts +262 -0
  50. package/lib/cjs/EditTxn.d.ts.map +1 -0
  51. package/lib/cjs/EditTxn.js +548 -0
  52. package/lib/cjs/EditTxn.js.map +1 -0
  53. package/lib/cjs/Element.d.ts +74 -5
  54. package/lib/cjs/Element.d.ts.map +1 -1
  55. package/lib/cjs/Element.js +63 -75
  56. package/lib/cjs/Element.js.map +1 -1
  57. package/lib/cjs/ElementAspect.d.ts +10 -0
  58. package/lib/cjs/ElementAspect.d.ts.map +1 -1
  59. package/lib/cjs/ElementAspect.js +21 -12
  60. package/lib/cjs/ElementAspect.js.map +1 -1
  61. package/lib/cjs/ElementGraphics.js.map +1 -1
  62. package/lib/cjs/ElementTreeWalker.d.ts +56 -3
  63. package/lib/cjs/ElementTreeWalker.d.ts.map +1 -1
  64. package/lib/cjs/ElementTreeWalker.js +53 -40
  65. package/lib/cjs/ElementTreeWalker.js.map +1 -1
  66. package/lib/cjs/Entity.js.map +1 -1
  67. package/lib/cjs/EntityReferences.js.map +1 -1
  68. package/lib/cjs/ExportGraphics.js.map +1 -1
  69. package/lib/cjs/ExternalSource.d.ts +11 -2
  70. package/lib/cjs/ExternalSource.d.ts.map +1 -1
  71. package/lib/cjs/ExternalSource.js +10 -8
  72. package/lib/cjs/ExternalSource.js.map +1 -1
  73. package/lib/cjs/FontFile.js.map +1 -1
  74. package/lib/cjs/GeoCoordConfig.js.map +1 -1
  75. package/lib/cjs/GeographicCRSServices.js.map +1 -1
  76. package/lib/cjs/GeometrySummary.js +47 -47
  77. package/lib/cjs/GeometrySummary.js.map +1 -1
  78. package/lib/cjs/IModelDb.d.ts +66 -22
  79. package/lib/cjs/IModelDb.d.ts.map +1 -1
  80. package/lib/cjs/IModelDb.js +183 -297
  81. package/lib/cjs/IModelDb.js.map +1 -1
  82. package/lib/cjs/IModelDbFonts.js.map +1 -1
  83. package/lib/cjs/IModelElementCloneContext.js.map +1 -1
  84. package/lib/cjs/IModelHost.d.ts +58 -1
  85. package/lib/cjs/IModelHost.d.ts.map +1 -1
  86. package/lib/cjs/IModelHost.js +89 -0
  87. package/lib/cjs/IModelHost.js.map +1 -1
  88. package/lib/cjs/IModelIncrementalSchemaLocater.js.map +1 -1
  89. package/lib/cjs/IModelJsFs.js.map +1 -1
  90. package/lib/cjs/ImageSourceConversion.js.map +1 -1
  91. package/lib/cjs/IpcHost.d.ts.map +1 -1
  92. package/lib/cjs/IpcHost.js +15 -6
  93. package/lib/cjs/IpcHost.js.map +1 -1
  94. package/lib/cjs/LineStyle.d.ts +47 -7
  95. package/lib/cjs/LineStyle.d.ts.map +1 -1
  96. package/lib/cjs/LineStyle.js +38 -33
  97. package/lib/cjs/LineStyle.js.map +1 -1
  98. package/lib/cjs/LocalHub.js +1 -1
  99. package/lib/cjs/LocalHub.js.map +1 -1
  100. package/lib/cjs/LocalhostIpcHost.js.map +1 -1
  101. package/lib/cjs/LockControl.d.ts +85 -1
  102. package/lib/cjs/LockControl.d.ts.map +1 -1
  103. package/lib/cjs/LockControl.js.map +1 -1
  104. package/lib/cjs/Material.d.ts +8 -1
  105. package/lib/cjs/Material.d.ts.map +1 -1
  106. package/lib/cjs/Material.js +6 -12
  107. package/lib/cjs/Material.js.map +1 -1
  108. package/lib/cjs/Model.d.ts +59 -20
  109. package/lib/cjs/Model.d.ts.map +1 -1
  110. package/lib/cjs/Model.js +38 -80
  111. package/lib/cjs/Model.js.map +1 -1
  112. package/lib/cjs/NativeAppStorage.js.map +1 -1
  113. package/lib/cjs/NativeHost.js.map +1 -1
  114. package/lib/cjs/NavigationRelationship.js.map +1 -1
  115. package/lib/cjs/PromiseMemoizer.js.map +1 -1
  116. package/lib/cjs/PropertyStore.js.map +1 -1
  117. package/lib/cjs/Relationship.d.ts +72 -7
  118. package/lib/cjs/Relationship.d.ts.map +1 -1
  119. package/lib/cjs/Relationship.js +39 -21
  120. package/lib/cjs/Relationship.js.map +1 -1
  121. package/lib/cjs/RpcBackend.js.map +1 -1
  122. package/lib/cjs/SQLiteDb.js.map +1 -1
  123. package/lib/cjs/Schema.js.map +1 -1
  124. package/lib/cjs/SchemaSync.js +4 -4
  125. package/lib/cjs/SchemaSync.js.map +1 -1
  126. package/lib/cjs/SchemaUtils.js.map +1 -1
  127. package/lib/cjs/SheetIndex.d.ts +9 -0
  128. package/lib/cjs/SheetIndex.d.ts.map +1 -1
  129. package/lib/cjs/SheetIndex.js +38 -35
  130. package/lib/cjs/SheetIndex.js.map +1 -1
  131. package/lib/cjs/SqliteChangesetReader.js.map +1 -1
  132. package/lib/cjs/SqliteStatement.js.map +1 -1
  133. package/lib/cjs/StashManager.js +1 -1
  134. package/lib/cjs/StashManager.js.map +1 -1
  135. package/lib/cjs/Texture.d.ts +6 -0
  136. package/lib/cjs/Texture.d.ts.map +1 -1
  137. package/lib/cjs/Texture.js +6 -14
  138. package/lib/cjs/Texture.js.map +1 -1
  139. package/lib/cjs/TileStorage.js.map +1 -1
  140. package/lib/cjs/TxnManager.d.ts +105 -9
  141. package/lib/cjs/TxnManager.d.ts.map +1 -1
  142. package/lib/cjs/TxnManager.js +194 -15
  143. package/lib/cjs/TxnManager.js.map +1 -1
  144. package/lib/cjs/ViewDefinition.d.ts +21 -1
  145. package/lib/cjs/ViewDefinition.d.ts.map +1 -1
  146. package/lib/cjs/ViewDefinition.js +27 -66
  147. package/lib/cjs/ViewDefinition.js.map +1 -1
  148. package/lib/cjs/ViewStateHydrator.js.map +1 -1
  149. package/lib/cjs/ViewStore.js.map +1 -1
  150. package/lib/cjs/annotations/ElementDrivesTextAnnotation.d.ts +14 -6
  151. package/lib/cjs/annotations/ElementDrivesTextAnnotation.d.ts.map +1 -1
  152. package/lib/cjs/annotations/ElementDrivesTextAnnotation.js +33 -27
  153. package/lib/cjs/annotations/ElementDrivesTextAnnotation.js.map +1 -1
  154. package/lib/cjs/annotations/FrameGeometry.js.map +1 -1
  155. package/lib/cjs/annotations/LeaderGeometry.js.map +1 -1
  156. package/lib/cjs/annotations/TextAnnotationElement.d.ts.map +1 -1
  157. package/lib/cjs/annotations/TextAnnotationElement.js +6 -5
  158. package/lib/cjs/annotations/TextAnnotationElement.js.map +1 -1
  159. package/lib/cjs/annotations/TextAnnotationGeometry.js.map +1 -1
  160. package/lib/cjs/annotations/TextBlockGeometry.js.map +1 -1
  161. package/lib/cjs/annotations/TextBlockLayout.js.map +1 -1
  162. package/lib/cjs/assets/IModelChange.02.00.00.ecschema.xml +90 -90
  163. package/lib/cjs/assets/Settings/Schemas/Base.Schema.json +32 -32
  164. package/lib/cjs/assets/Settings/Schemas/Gcs.schema.json +27 -27
  165. package/lib/cjs/assets/Settings/Schemas/Workspace.Schema.json +94 -94
  166. package/lib/cjs/assets/Settings/backend.setting.json5 +21 -21
  167. package/lib/cjs/core-backend.d.ts +1 -0
  168. package/lib/cjs/core-backend.d.ts.map +1 -1
  169. package/lib/cjs/core-backend.js +1 -0
  170. package/lib/cjs/core-backend.js.map +1 -1
  171. package/lib/cjs/domains/FunctionalElements.d.ts +6 -2
  172. package/lib/cjs/domains/FunctionalElements.d.ts.map +1 -1
  173. package/lib/cjs/domains/FunctionalElements.js +8 -13
  174. package/lib/cjs/domains/FunctionalElements.js.map +1 -1
  175. package/lib/cjs/domains/FunctionalSchema.js.map +1 -1
  176. package/lib/cjs/domains/GenericElements.d.ts +11 -4
  177. package/lib/cjs/domains/GenericElements.d.ts.map +1 -1
  178. package/lib/cjs/domains/GenericElements.js +13 -24
  179. package/lib/cjs/domains/GenericElements.js.map +1 -1
  180. package/lib/cjs/domains/GenericSchema.js.map +1 -1
  181. package/lib/cjs/internal/ChangesetConflictArgs.js.map +1 -1
  182. package/lib/cjs/internal/ChannelAdmin.d.ts +15 -0
  183. package/lib/cjs/internal/ChannelAdmin.d.ts.map +1 -1
  184. package/lib/cjs/internal/ChannelAdmin.js +5 -3
  185. package/lib/cjs/internal/ChannelAdmin.js.map +1 -1
  186. package/lib/cjs/internal/ElementLRUCache.js.map +1 -1
  187. package/lib/cjs/internal/FontFileImpl.js.map +1 -1
  188. package/lib/cjs/internal/HubMock.d.ts +2 -0
  189. package/lib/cjs/internal/HubMock.d.ts.map +1 -1
  190. package/lib/cjs/internal/HubMock.js +7 -0
  191. package/lib/cjs/internal/HubMock.js.map +1 -1
  192. package/lib/cjs/internal/IModelDbFontsImpl.js.map +1 -1
  193. package/lib/cjs/internal/IntegrityCheck.js.map +1 -1
  194. package/lib/cjs/internal/NativePlatform.js.map +1 -1
  195. package/lib/cjs/internal/NoLocks.d.ts.map +1 -1
  196. package/lib/cjs/internal/NoLocks.js +6 -0
  197. package/lib/cjs/internal/NoLocks.js.map +1 -1
  198. package/lib/cjs/internal/OnlineStatus.js.map +1 -1
  199. package/lib/cjs/internal/ServerBasedLocks.d.ts +12 -0
  200. package/lib/cjs/internal/ServerBasedLocks.d.ts.map +1 -1
  201. package/lib/cjs/internal/ServerBasedLocks.js +285 -4
  202. package/lib/cjs/internal/ServerBasedLocks.js.map +1 -1
  203. package/lib/cjs/internal/Symbols.d.ts +4 -0
  204. package/lib/cjs/internal/Symbols.d.ts.map +1 -1
  205. package/lib/cjs/internal/Symbols.js +5 -1
  206. package/lib/cjs/internal/Symbols.js.map +1 -1
  207. package/lib/cjs/internal/annotations/fields.d.ts +3 -2
  208. package/lib/cjs/internal/annotations/fields.d.ts.map +1 -1
  209. package/lib/cjs/internal/annotations/fields.js +7 -6
  210. package/lib/cjs/internal/annotations/fields.js.map +1 -1
  211. package/lib/cjs/internal/cross-package.js.map +1 -1
  212. package/lib/cjs/internal/workspace/SettingsEditorImpl.d.ts +18 -3
  213. package/lib/cjs/internal/workspace/SettingsEditorImpl.d.ts.map +1 -1
  214. package/lib/cjs/internal/workspace/SettingsEditorImpl.js +49 -242
  215. package/lib/cjs/internal/workspace/SettingsEditorImpl.js.map +1 -1
  216. package/lib/cjs/internal/workspace/SettingsImpl.d.ts.map +1 -1
  217. package/lib/cjs/internal/workspace/SettingsImpl.js.map +1 -1
  218. package/lib/cjs/internal/workspace/SettingsSchemasImpl.js.map +1 -1
  219. package/lib/cjs/internal/workspace/WorkspaceImpl.d.ts +0 -1
  220. package/lib/cjs/internal/workspace/WorkspaceImpl.d.ts.map +1 -1
  221. package/lib/cjs/internal/workspace/WorkspaceImpl.js +70 -41
  222. package/lib/cjs/internal/workspace/WorkspaceImpl.js.map +1 -1
  223. package/lib/cjs/internal/workspace/WorkspaceSqliteDb.js.map +1 -1
  224. package/lib/cjs/rpc/multipart.js.map +1 -1
  225. package/lib/cjs/rpc/tracing.js.map +1 -1
  226. package/lib/cjs/rpc/web/logging.js.map +1 -1
  227. package/lib/cjs/rpc/web/request.js.map +1 -1
  228. package/lib/cjs/rpc/web/response.js.map +1 -1
  229. package/lib/cjs/rpc-impl/DevToolsRpcImpl.js.map +1 -1
  230. package/lib/cjs/rpc-impl/IModelReadRpcImpl.js.map +1 -1
  231. package/lib/cjs/rpc-impl/IModelTileRpcImpl.js.map +1 -1
  232. package/lib/cjs/rpc-impl/RpcBriefcaseUtility.d.ts.map +1 -1
  233. package/lib/cjs/rpc-impl/RpcBriefcaseUtility.js.map +1 -1
  234. package/lib/cjs/rpc-impl/SnapshotIModelRpcImpl.js.map +1 -1
  235. package/lib/cjs/workspace/Settings.d.ts +11 -5
  236. package/lib/cjs/workspace/Settings.d.ts.map +1 -1
  237. package/lib/cjs/workspace/Settings.js.map +1 -1
  238. package/lib/cjs/workspace/SettingsDb.d.ts +20 -99
  239. package/lib/cjs/workspace/SettingsDb.d.ts.map +1 -1
  240. package/lib/cjs/workspace/SettingsDb.js +23 -7
  241. package/lib/cjs/workspace/SettingsDb.js.map +1 -1
  242. package/lib/cjs/workspace/SettingsEditor.d.ts +40 -226
  243. package/lib/cjs/workspace/SettingsEditor.d.ts.map +1 -1
  244. package/lib/cjs/workspace/SettingsEditor.js +86 -25
  245. package/lib/cjs/workspace/SettingsEditor.js.map +1 -1
  246. package/lib/cjs/workspace/SettingsSchemas.js.map +1 -1
  247. package/lib/cjs/workspace/Workspace.d.ts +7 -11
  248. package/lib/cjs/workspace/Workspace.d.ts.map +1 -1
  249. package/lib/cjs/workspace/Workspace.js.map +1 -1
  250. package/lib/cjs/workspace/WorkspaceEditor.d.ts +14 -0
  251. package/lib/cjs/workspace/WorkspaceEditor.d.ts.map +1 -1
  252. package/lib/cjs/workspace/WorkspaceEditor.js +1 -1
  253. package/lib/cjs/workspace/WorkspaceEditor.js.map +1 -1
  254. package/lib/esm/BackendHubAccess.d.ts +38 -0
  255. package/lib/esm/BackendHubAccess.d.ts.map +1 -1
  256. package/lib/esm/BackendHubAccess.js.map +1 -1
  257. package/lib/esm/BackendLoggerCategory.js.map +1 -1
  258. package/lib/esm/BisCoreSchema.js.map +1 -1
  259. package/lib/esm/BlobContainerService.js.map +1 -1
  260. package/lib/esm/BriefcaseManager.js +3 -3
  261. package/lib/esm/BriefcaseManager.js.map +1 -1
  262. package/lib/esm/CatalogDb.js.map +1 -1
  263. package/lib/esm/Category.d.ts +37 -7
  264. package/lib/esm/Category.d.ts.map +1 -1
  265. package/lib/esm/Category.js +33 -42
  266. package/lib/esm/Category.js.map +1 -1
  267. package/lib/esm/ChangeSummaryManager.js +2 -2
  268. package/lib/esm/ChangeSummaryManager.js.map +1 -1
  269. package/lib/esm/ChangedElementsDb.js.map +1 -1
  270. package/lib/esm/ChangesetECAdaptor.d.ts.map +1 -1
  271. package/lib/esm/ChangesetECAdaptor.js +253 -250
  272. package/lib/esm/ChangesetECAdaptor.js.map +1 -1
  273. package/lib/esm/ChannelControl.d.ts +29 -0
  274. package/lib/esm/ChannelControl.d.ts.map +1 -1
  275. package/lib/esm/ChannelControl.js.map +1 -1
  276. package/lib/esm/CheckpointManager.js +1 -1
  277. package/lib/esm/CheckpointManager.js.map +1 -1
  278. package/lib/esm/ClassRegistry.js +5 -5
  279. package/lib/esm/ClassRegistry.js.map +1 -1
  280. package/lib/esm/CloudSqlite.d.ts +1 -1
  281. package/lib/esm/CloudSqlite.d.ts.map +1 -1
  282. package/lib/esm/CloudSqlite.js +69 -14
  283. package/lib/esm/CloudSqlite.js.map +1 -1
  284. package/lib/esm/CodeService.js.map +1 -1
  285. package/lib/esm/CodeSpecs.d.ts +32 -3
  286. package/lib/esm/CodeSpecs.d.ts.map +1 -1
  287. package/lib/esm/CodeSpecs.js +49 -21
  288. package/lib/esm/CodeSpecs.js.map +1 -1
  289. package/lib/esm/ConcurrentQuery.js.map +1 -1
  290. package/lib/esm/CustomViewState3dCreator.js.map +1 -1
  291. package/lib/esm/DevTools.js.map +1 -1
  292. package/lib/esm/DisplayStyle.d.ts +18 -3
  293. package/lib/esm/DisplayStyle.d.ts.map +1 -1
  294. package/lib/esm/DisplayStyle.js +10 -21
  295. package/lib/esm/DisplayStyle.js.map +1 -1
  296. package/lib/esm/ECDb.js.map +1 -1
  297. package/lib/esm/ECSchemaXmlContext.js.map +1 -1
  298. package/lib/esm/ECSqlRowExecutor.js.map +1 -1
  299. package/lib/esm/ECSqlStatement.js.map +1 -1
  300. package/lib/esm/ECSqlSyncReader.js.map +1 -1
  301. package/lib/esm/EditTxn.d.ts +262 -0
  302. package/lib/esm/EditTxn.d.ts.map +1 -0
  303. package/lib/esm/EditTxn.js +543 -0
  304. package/lib/esm/EditTxn.js.map +1 -0
  305. package/lib/esm/Element.d.ts +74 -5
  306. package/lib/esm/Element.d.ts.map +1 -1
  307. package/lib/esm/Element.js +64 -76
  308. package/lib/esm/Element.js.map +1 -1
  309. package/lib/esm/ElementAspect.d.ts +10 -0
  310. package/lib/esm/ElementAspect.d.ts.map +1 -1
  311. package/lib/esm/ElementAspect.js +22 -13
  312. package/lib/esm/ElementAspect.js.map +1 -1
  313. package/lib/esm/ElementGraphics.js.map +1 -1
  314. package/lib/esm/ElementTreeWalker.d.ts +56 -3
  315. package/lib/esm/ElementTreeWalker.d.ts.map +1 -1
  316. package/lib/esm/ElementTreeWalker.js +53 -40
  317. package/lib/esm/ElementTreeWalker.js.map +1 -1
  318. package/lib/esm/Entity.js.map +1 -1
  319. package/lib/esm/EntityReferences.js.map +1 -1
  320. package/lib/esm/ExportGraphics.js.map +1 -1
  321. package/lib/esm/ExternalSource.d.ts +11 -2
  322. package/lib/esm/ExternalSource.d.ts.map +1 -1
  323. package/lib/esm/ExternalSource.js +10 -8
  324. package/lib/esm/ExternalSource.js.map +1 -1
  325. package/lib/esm/FontFile.js.map +1 -1
  326. package/lib/esm/GeoCoordConfig.js.map +1 -1
  327. package/lib/esm/GeographicCRSServices.js.map +1 -1
  328. package/lib/esm/GeometrySummary.js +47 -47
  329. package/lib/esm/GeometrySummary.js.map +1 -1
  330. package/lib/esm/IModelDb.d.ts +66 -22
  331. package/lib/esm/IModelDb.d.ts.map +1 -1
  332. package/lib/esm/IModelDb.js +185 -299
  333. package/lib/esm/IModelDb.js.map +1 -1
  334. package/lib/esm/IModelDbFonts.js.map +1 -1
  335. package/lib/esm/IModelElementCloneContext.js.map +1 -1
  336. package/lib/esm/IModelHost.d.ts +58 -1
  337. package/lib/esm/IModelHost.d.ts.map +1 -1
  338. package/lib/esm/IModelHost.js +91 -2
  339. package/lib/esm/IModelHost.js.map +1 -1
  340. package/lib/esm/IModelIncrementalSchemaLocater.js.map +1 -1
  341. package/lib/esm/IModelJsFs.js.map +1 -1
  342. package/lib/esm/ImageSourceConversion.js.map +1 -1
  343. package/lib/esm/IpcHost.d.ts.map +1 -1
  344. package/lib/esm/IpcHost.js +16 -7
  345. package/lib/esm/IpcHost.js.map +1 -1
  346. package/lib/esm/LineStyle.d.ts +47 -7
  347. package/lib/esm/LineStyle.d.ts.map +1 -1
  348. package/lib/esm/LineStyle.js +38 -33
  349. package/lib/esm/LineStyle.js.map +1 -1
  350. package/lib/esm/LocalHub.js +1 -1
  351. package/lib/esm/LocalHub.js.map +1 -1
  352. package/lib/esm/LocalhostIpcHost.js.map +1 -1
  353. package/lib/esm/LockControl.d.ts +85 -1
  354. package/lib/esm/LockControl.d.ts.map +1 -1
  355. package/lib/esm/LockControl.js.map +1 -1
  356. package/lib/esm/Material.d.ts +8 -1
  357. package/lib/esm/Material.d.ts.map +1 -1
  358. package/lib/esm/Material.js +6 -12
  359. package/lib/esm/Material.js.map +1 -1
  360. package/lib/esm/Model.d.ts +59 -20
  361. package/lib/esm/Model.d.ts.map +1 -1
  362. package/lib/esm/Model.js +39 -81
  363. package/lib/esm/Model.js.map +1 -1
  364. package/lib/esm/NativeAppStorage.js.map +1 -1
  365. package/lib/esm/NativeHost.js.map +1 -1
  366. package/lib/esm/NavigationRelationship.js.map +1 -1
  367. package/lib/esm/PromiseMemoizer.js.map +1 -1
  368. package/lib/esm/PropertyStore.js.map +1 -1
  369. package/lib/esm/Relationship.d.ts +72 -7
  370. package/lib/esm/Relationship.d.ts.map +1 -1
  371. package/lib/esm/Relationship.js +40 -22
  372. package/lib/esm/Relationship.js.map +1 -1
  373. package/lib/esm/RpcBackend.js.map +1 -1
  374. package/lib/esm/SQLiteDb.js.map +1 -1
  375. package/lib/esm/Schema.js.map +1 -1
  376. package/lib/esm/SchemaSync.js +5 -5
  377. package/lib/esm/SchemaSync.js.map +1 -1
  378. package/lib/esm/SchemaUtils.js.map +1 -1
  379. package/lib/esm/SheetIndex.d.ts +9 -0
  380. package/lib/esm/SheetIndex.d.ts.map +1 -1
  381. package/lib/esm/SheetIndex.js +38 -35
  382. package/lib/esm/SheetIndex.js.map +1 -1
  383. package/lib/esm/SqliteChangesetReader.js.map +1 -1
  384. package/lib/esm/SqliteStatement.js.map +1 -1
  385. package/lib/esm/StashManager.js +1 -1
  386. package/lib/esm/StashManager.js.map +1 -1
  387. package/lib/esm/Texture.d.ts +6 -0
  388. package/lib/esm/Texture.d.ts.map +1 -1
  389. package/lib/esm/Texture.js +6 -14
  390. package/lib/esm/Texture.js.map +1 -1
  391. package/lib/esm/TileStorage.js.map +1 -1
  392. package/lib/esm/TxnManager.d.ts +105 -9
  393. package/lib/esm/TxnManager.d.ts.map +1 -1
  394. package/lib/esm/TxnManager.js +194 -15
  395. package/lib/esm/TxnManager.js.map +1 -1
  396. package/lib/esm/ViewDefinition.d.ts +21 -1
  397. package/lib/esm/ViewDefinition.d.ts.map +1 -1
  398. package/lib/esm/ViewDefinition.js +27 -66
  399. package/lib/esm/ViewDefinition.js.map +1 -1
  400. package/lib/esm/ViewStateHydrator.js.map +1 -1
  401. package/lib/esm/ViewStore.js.map +1 -1
  402. package/lib/esm/annotations/ElementDrivesTextAnnotation.d.ts +14 -6
  403. package/lib/esm/annotations/ElementDrivesTextAnnotation.d.ts.map +1 -1
  404. package/lib/esm/annotations/ElementDrivesTextAnnotation.js +33 -27
  405. package/lib/esm/annotations/ElementDrivesTextAnnotation.js.map +1 -1
  406. package/lib/esm/annotations/FrameGeometry.js.map +1 -1
  407. package/lib/esm/annotations/LeaderGeometry.js.map +1 -1
  408. package/lib/esm/annotations/TextAnnotationElement.d.ts.map +1 -1
  409. package/lib/esm/annotations/TextAnnotationElement.js +6 -5
  410. package/lib/esm/annotations/TextAnnotationElement.js.map +1 -1
  411. package/lib/esm/annotations/TextAnnotationGeometry.js.map +1 -1
  412. package/lib/esm/annotations/TextBlockGeometry.js.map +1 -1
  413. package/lib/esm/annotations/TextBlockLayout.js.map +1 -1
  414. package/lib/esm/core-backend.d.ts +1 -0
  415. package/lib/esm/core-backend.d.ts.map +1 -1
  416. package/lib/esm/core-backend.js +1 -0
  417. package/lib/esm/core-backend.js.map +1 -1
  418. package/lib/esm/domains/FunctionalElements.d.ts +6 -2
  419. package/lib/esm/domains/FunctionalElements.d.ts.map +1 -1
  420. package/lib/esm/domains/FunctionalElements.js +8 -13
  421. package/lib/esm/domains/FunctionalElements.js.map +1 -1
  422. package/lib/esm/domains/FunctionalSchema.js.map +1 -1
  423. package/lib/esm/domains/GenericElements.d.ts +11 -4
  424. package/lib/esm/domains/GenericElements.d.ts.map +1 -1
  425. package/lib/esm/domains/GenericElements.js +13 -24
  426. package/lib/esm/domains/GenericElements.js.map +1 -1
  427. package/lib/esm/domains/GenericSchema.js.map +1 -1
  428. package/lib/esm/internal/ChangesetConflictArgs.js.map +1 -1
  429. package/lib/esm/internal/ChannelAdmin.d.ts +15 -0
  430. package/lib/esm/internal/ChannelAdmin.d.ts.map +1 -1
  431. package/lib/esm/internal/ChannelAdmin.js +6 -4
  432. package/lib/esm/internal/ChannelAdmin.js.map +1 -1
  433. package/lib/esm/internal/ElementLRUCache.js.map +1 -1
  434. package/lib/esm/internal/FontFileImpl.js.map +1 -1
  435. package/lib/esm/internal/HubMock.d.ts +2 -0
  436. package/lib/esm/internal/HubMock.d.ts.map +1 -1
  437. package/lib/esm/internal/HubMock.js +7 -0
  438. package/lib/esm/internal/HubMock.js.map +1 -1
  439. package/lib/esm/internal/IModelDbFontsImpl.js.map +1 -1
  440. package/lib/esm/internal/IntegrityCheck.js.map +1 -1
  441. package/lib/esm/internal/NativePlatform.js.map +1 -1
  442. package/lib/esm/internal/NoLocks.d.ts.map +1 -1
  443. package/lib/esm/internal/NoLocks.js +6 -0
  444. package/lib/esm/internal/NoLocks.js.map +1 -1
  445. package/lib/esm/internal/OnlineStatus.js.map +1 -1
  446. package/lib/esm/internal/ServerBasedLocks.d.ts +12 -0
  447. package/lib/esm/internal/ServerBasedLocks.d.ts.map +1 -1
  448. package/lib/esm/internal/ServerBasedLocks.js +286 -5
  449. package/lib/esm/internal/ServerBasedLocks.js.map +1 -1
  450. package/lib/esm/internal/Symbols.d.ts +4 -0
  451. package/lib/esm/internal/Symbols.d.ts.map +1 -1
  452. package/lib/esm/internal/Symbols.js +4 -0
  453. package/lib/esm/internal/Symbols.js.map +1 -1
  454. package/lib/esm/internal/annotations/fields.d.ts +3 -2
  455. package/lib/esm/internal/annotations/fields.d.ts.map +1 -1
  456. package/lib/esm/internal/annotations/fields.js +7 -6
  457. package/lib/esm/internal/annotations/fields.js.map +1 -1
  458. package/lib/esm/internal/cross-package.js.map +1 -1
  459. package/lib/esm/internal/workspace/SettingsEditorImpl.d.ts +18 -3
  460. package/lib/esm/internal/workspace/SettingsEditorImpl.d.ts.map +1 -1
  461. package/lib/esm/internal/workspace/SettingsEditorImpl.js +52 -246
  462. package/lib/esm/internal/workspace/SettingsEditorImpl.js.map +1 -1
  463. package/lib/esm/internal/workspace/SettingsImpl.d.ts.map +1 -1
  464. package/lib/esm/internal/workspace/SettingsImpl.js.map +1 -1
  465. package/lib/esm/internal/workspace/SettingsSchemasImpl.js.map +1 -1
  466. package/lib/esm/internal/workspace/WorkspaceImpl.d.ts +0 -1
  467. package/lib/esm/internal/workspace/WorkspaceImpl.d.ts.map +1 -1
  468. package/lib/esm/internal/workspace/WorkspaceImpl.js +71 -41
  469. package/lib/esm/internal/workspace/WorkspaceImpl.js.map +1 -1
  470. package/lib/esm/internal/workspace/WorkspaceSqliteDb.js.map +1 -1
  471. package/lib/esm/rpc/multipart.js.map +1 -1
  472. package/lib/esm/rpc/tracing.js.map +1 -1
  473. package/lib/esm/rpc/web/logging.js.map +1 -1
  474. package/lib/esm/rpc/web/request.js.map +1 -1
  475. package/lib/esm/rpc/web/response.js.map +1 -1
  476. package/lib/esm/rpc-impl/DevToolsRpcImpl.js.map +1 -1
  477. package/lib/esm/rpc-impl/IModelReadRpcImpl.js.map +1 -1
  478. package/lib/esm/rpc-impl/IModelTileRpcImpl.js.map +1 -1
  479. package/lib/esm/rpc-impl/RpcBriefcaseUtility.d.ts.map +1 -1
  480. package/lib/esm/rpc-impl/RpcBriefcaseUtility.js.map +1 -1
  481. package/lib/esm/rpc-impl/SnapshotIModelRpcImpl.js.map +1 -1
  482. package/lib/esm/test/AdvancedEqual.js.map +1 -1
  483. package/lib/esm/test/AnnotationTestUtils.js.map +1 -1
  484. package/lib/esm/test/AttachDb.test.js +11 -11
  485. package/lib/esm/test/AttachDb.test.js.map +1 -1
  486. package/lib/esm/test/ElementDrivesElement.test.d.ts +20 -19
  487. package/lib/esm/test/ElementDrivesElement.test.d.ts.map +1 -1
  488. package/lib/esm/test/ElementDrivesElement.test.js +134 -119
  489. package/lib/esm/test/ElementDrivesElement.test.js.map +1 -1
  490. package/lib/esm/test/ElementLRUCache.test.js.map +1 -1
  491. package/lib/esm/test/GeometryTestUtil.js.map +1 -1
  492. package/lib/esm/test/IModelHost.test.js +56 -2
  493. package/lib/esm/test/IModelHost.test.js.map +1 -1
  494. package/lib/esm/test/IModelTestUtils.d.ts +23 -23
  495. package/lib/esm/test/IModelTestUtils.d.ts.map +1 -1
  496. package/lib/esm/test/IModelTestUtils.js +466 -449
  497. package/lib/esm/test/IModelTestUtils.js.map +1 -1
  498. package/lib/esm/test/ImageSourceConversion.test.js.map +1 -1
  499. package/lib/esm/test/IpcHost.test.js.map +1 -1
  500. package/lib/esm/test/KnownTestLocations.js.map +1 -1
  501. package/lib/esm/test/PrintElementTree.js.map +1 -1
  502. package/lib/esm/test/PropertyDb.test.js +2 -2
  503. package/lib/esm/test/PropertyDb.test.js.map +1 -1
  504. package/lib/esm/test/RevisionUtility.js.map +1 -1
  505. package/lib/esm/test/SchemaUtils.test.js +25 -25
  506. package/lib/esm/test/SchemaUtils.test.js.map +1 -1
  507. package/lib/esm/test/SequentialLogMatcher.js.map +1 -1
  508. package/lib/esm/test/SquashSchemaAndDataChanges.test.js +156 -147
  509. package/lib/esm/test/SquashSchemaAndDataChanges.test.js.map +1 -1
  510. package/lib/esm/test/TestChangeSetUtility.d.ts.map +1 -1
  511. package/lib/esm/test/TestChangeSetUtility.js +11 -7
  512. package/lib/esm/test/TestChangeSetUtility.js.map +1 -1
  513. package/lib/esm/test/TestEditTxn.d.ts +8 -0
  514. package/lib/esm/test/TestEditTxn.d.ts.map +1 -0
  515. package/lib/esm/test/TestEditTxn.js +34 -0
  516. package/lib/esm/test/TestEditTxn.js.map +1 -0
  517. package/lib/esm/test/TestUtils.d.ts +1 -0
  518. package/lib/esm/test/TestUtils.d.ts.map +1 -1
  519. package/lib/esm/test/TestUtils.js +8 -1
  520. package/lib/esm/test/TestUtils.js.map +1 -1
  521. package/lib/esm/test/annotations/Fields.test.js +135 -143
  522. package/lib/esm/test/annotations/Fields.test.js.map +1 -1
  523. package/lib/esm/test/annotations/FrameGeometry.test.js.map +1 -1
  524. package/lib/esm/test/annotations/LeaderGeometry.test.js.map +1 -1
  525. package/lib/esm/test/annotations/TextAnnotation.test.js +156 -99
  526. package/lib/esm/test/annotations/TextAnnotation.test.js.map +1 -1
  527. package/lib/esm/test/annotations/TextBlock.test.js +5 -3
  528. package/lib/esm/test/annotations/TextBlock.test.js.map +1 -1
  529. package/lib/esm/test/assets/IncrementalSchemaLocater/configs/old.config.js.map +1 -1
  530. package/lib/esm/test/assets/IncrementalSchemaLocater/configs/simple.config.js.map +1 -1
  531. package/lib/esm/test/categories/Category.test.js +63 -3
  532. package/lib/esm/test/categories/Category.test.js.map +1 -1
  533. package/lib/esm/test/codespec/CodeSpec.test.js +88 -5
  534. package/lib/esm/test/codespec/CodeSpec.test.js.map +1 -1
  535. package/lib/esm/test/ecdb/CTE.test.js +88 -88
  536. package/lib/esm/test/ecdb/CTE.test.js.map +1 -1
  537. package/lib/esm/test/ecdb/ConcurrentQuery.test.js +19 -19
  538. package/lib/esm/test/ecdb/ConcurrentQuery.test.js.map +1 -1
  539. package/lib/esm/test/ecdb/ConcurrentQueryLoad.test.js +15 -15
  540. package/lib/esm/test/ecdb/ConcurrentQueryLoad.test.js.map +1 -1
  541. package/lib/esm/test/ecdb/ECDb.test.js +72 -72
  542. package/lib/esm/test/ecdb/ECDb.test.js.map +1 -1
  543. package/lib/esm/test/ecdb/ECDbTestHelper.js.map +1 -1
  544. package/lib/esm/test/ecdb/ECSchemaXmlContext.test.js.map +1 -1
  545. package/lib/esm/test/ecdb/ECSqlAst.test.js +68 -67
  546. package/lib/esm/test/ecdb/ECSqlAst.test.js.map +1 -1
  547. package/lib/esm/test/ecdb/ECSqlQuery.test.js +6 -6
  548. package/lib/esm/test/ecdb/ECSqlQuery.test.js.map +1 -1
  549. package/lib/esm/test/ecdb/ECSqlStatement.test.js +332 -333
  550. package/lib/esm/test/ecdb/ECSqlStatement.test.js.map +1 -1
  551. package/lib/esm/test/ecdb/ECSqlSyncReader.test.js.map +1 -1
  552. package/lib/esm/test/ecdb/QueryReaders.test.js +47 -44
  553. package/lib/esm/test/ecdb/QueryReaders.test.js.map +1 -1
  554. package/lib/esm/test/ecdb/SqliteStatement.test.js +2 -2
  555. package/lib/esm/test/ecdb/SqliteStatement.test.js.map +1 -1
  556. package/lib/esm/test/ecsql/dataset/ECSqlDatasets.d.ts.map +1 -1
  557. package/lib/esm/test/ecsql/dataset/ECSqlDatasets.js +30 -28
  558. package/lib/esm/test/ecsql/dataset/ECSqlDatasets.js.map +1 -1
  559. package/lib/esm/test/ecsql/src/ECSqlTestGenerator.js +21 -21
  560. package/lib/esm/test/ecsql/src/ECSqlTestGenerator.js.map +1 -1
  561. package/lib/esm/test/ecsql/src/ECSqlTestParser.js.map +1 -1
  562. package/lib/esm/test/ecsql/src/ECSqlTestRunner.test.js.map +1 -1
  563. package/lib/esm/test/element/DeleteDefinitionElements.test.js +159 -143
  564. package/lib/esm/test/element/DeleteDefinitionElements.test.js.map +1 -1
  565. package/lib/esm/test/element/ElementAspect.test.js +90 -82
  566. package/lib/esm/test/element/ElementAspect.test.js.map +1 -1
  567. package/lib/esm/test/element/ElementDependencyGraph.test.d.ts.map +1 -1
  568. package/lib/esm/test/element/ElementDependencyGraph.test.js +51 -43
  569. package/lib/esm/test/element/ElementDependencyGraph.test.js.map +1 -1
  570. package/lib/esm/test/element/ElementRoundTrip.test.js +176 -177
  571. package/lib/esm/test/element/ElementRoundTrip.test.js.map +1 -1
  572. package/lib/esm/test/element/ExcludedElements.test.js +2 -2
  573. package/lib/esm/test/element/ExcludedElements.test.js.map +1 -1
  574. package/lib/esm/test/element/ExternalSource.test.js +40 -38
  575. package/lib/esm/test/element/ExternalSource.test.js.map +1 -1
  576. package/lib/esm/test/element/NullStructArray.test.js +23 -22
  577. package/lib/esm/test/element/NullStructArray.test.js.map +1 -1
  578. package/lib/esm/test/element/ProjectInformationRecord.test.js +5 -2
  579. package/lib/esm/test/element/ProjectInformationRecord.test.js.map +1 -1
  580. package/lib/esm/test/element/SheetInformationAspect.test.js +43 -11
  581. package/lib/esm/test/element/SheetInformationAspect.test.js.map +1 -1
  582. package/lib/esm/test/element/UrlLink.test.js +2 -2
  583. package/lib/esm/test/element/UrlLink.test.js.map +1 -1
  584. package/lib/esm/test/font/FontFile.test.js.map +1 -1
  585. package/lib/esm/test/font/IModelDbFonts.test.js +87 -73
  586. package/lib/esm/test/font/IModelDbFonts.test.js.map +1 -1
  587. package/lib/esm/test/hubaccess/ApplyChangeset.test.js +194 -155
  588. package/lib/esm/test/hubaccess/ApplyChangeset.test.js.map +1 -1
  589. package/lib/esm/test/hubaccess/BriefcaseManager.test.js +2 -4
  590. package/lib/esm/test/hubaccess/BriefcaseManager.test.js.map +1 -1
  591. package/lib/esm/test/hubaccess/CheckpointManager.test.js.map +1 -1
  592. package/lib/esm/test/hubaccess/Rebase.test.js +369 -303
  593. package/lib/esm/test/hubaccess/Rebase.test.js.map +1 -1
  594. package/lib/esm/test/hubaccess/SemanticRebase.test.js +467 -392
  595. package/lib/esm/test/hubaccess/SemanticRebase.test.js.map +1 -1
  596. package/lib/esm/test/imageData.js.map +1 -1
  597. package/lib/esm/test/imodel/Code.test.js +31 -31
  598. package/lib/esm/test/imodel/Code.test.js.map +1 -1
  599. package/lib/esm/test/imodel/ElementTreeWalker.test.js +57 -48
  600. package/lib/esm/test/imodel/ElementTreeWalker.test.js.map +1 -1
  601. package/lib/esm/test/imodel/GetTextureImage.test.js.map +1 -1
  602. package/lib/esm/test/imodel/IModel.test.js +463 -388
  603. package/lib/esm/test/imodel/IModel.test.js.map +1 -1
  604. package/lib/esm/test/imodel/ProjectExtents.test.js +2 -2
  605. package/lib/esm/test/imodel/ProjectExtents.test.js.map +1 -1
  606. package/lib/esm/test/imodel/SchemaXmlImport.test.js +13 -13
  607. package/lib/esm/test/imodel/SchemaXmlImport.test.js.map +1 -1
  608. package/lib/esm/test/incrementalSchemaLocater/ECSqlQueries.test.js.map +1 -1
  609. package/lib/esm/test/incrementalSchemaLocater/IncrementalLoading.test.js.map +1 -1
  610. package/lib/esm/test/incrementalSchemaLocater/TestContext.d.ts.map +1 -1
  611. package/lib/esm/test/incrementalSchemaLocater/TestContext.js +2 -2
  612. package/lib/esm/test/incrementalSchemaLocater/TestContext.js.map +1 -1
  613. package/lib/esm/test/index.d.ts +1 -0
  614. package/lib/esm/test/index.d.ts.map +1 -1
  615. package/lib/esm/test/index.js +1 -0
  616. package/lib/esm/test/index.js.map +1 -1
  617. package/lib/esm/test/misc/DevTools.test.js.map +1 -1
  618. package/lib/esm/test/misc/EntitySubClasses.test.js.map +1 -1
  619. package/lib/esm/test/misc/GeoServices.test.js.map +1 -1
  620. package/lib/esm/test/misc/PromiseMemoizer.test.js.map +1 -1
  621. package/lib/esm/test/native/DgnDbWorker.test.js.map +1 -1
  622. package/lib/esm/test/rpc/response.test.js.map +1 -1
  623. package/lib/esm/test/schema/ClassRegistry.test.js +122 -121
  624. package/lib/esm/test/schema/ClassRegistry.test.js.map +1 -1
  625. package/lib/esm/test/schema/FunctionalDomain.test.js +36 -34
  626. package/lib/esm/test/schema/FunctionalDomain.test.js.map +1 -1
  627. package/lib/esm/test/schema/GenericDomain.test.js +114 -94
  628. package/lib/esm/test/schema/GenericDomain.test.js.map +1 -1
  629. package/lib/esm/test/schema/IModelSchemaContext.test.js +11 -10
  630. package/lib/esm/test/schema/IModelSchemaContext.test.js.map +1 -1
  631. package/lib/esm/test/schema/SchemaImportCallbacks.test.js +226 -211
  632. package/lib/esm/test/schema/SchemaImportCallbacks.test.js.map +1 -1
  633. package/lib/esm/test/sheetindex/SheetIndex.test.d.ts +1 -3
  634. package/lib/esm/test/sheetindex/SheetIndex.test.d.ts.map +1 -1
  635. package/lib/esm/test/sheetindex/SheetIndex.test.js +312 -247
  636. package/lib/esm/test/sheetindex/SheetIndex.test.js.map +1 -1
  637. package/lib/esm/test/standalone/ChangeMerge.test.js +101 -82
  638. package/lib/esm/test/standalone/ChangeMerge.test.js.map +1 -1
  639. package/lib/esm/test/standalone/ChangesetReader.test.js +242 -213
  640. package/lib/esm/test/standalone/ChangesetReader.test.js.map +1 -1
  641. package/lib/esm/test/standalone/CustomViewState3dCreator.test.js.map +1 -1
  642. package/lib/esm/test/standalone/DisplayStyle.test.js +43 -40
  643. package/lib/esm/test/standalone/DisplayStyle.test.js.map +1 -1
  644. package/lib/esm/test/standalone/Drawing.test.js +4 -3
  645. package/lib/esm/test/standalone/Drawing.test.js.map +1 -1
  646. package/lib/esm/test/standalone/EditTxn.test.d.ts +2 -0
  647. package/lib/esm/test/standalone/EditTxn.test.d.ts.map +1 -0
  648. package/lib/esm/test/standalone/EditTxn.test.js +219 -0
  649. package/lib/esm/test/standalone/EditTxn.test.js.map +1 -0
  650. package/lib/esm/test/standalone/ElementGraphics.test.js.map +1 -1
  651. package/lib/esm/test/standalone/ElementMesh.test.js +16 -13
  652. package/lib/esm/test/standalone/ElementMesh.test.js.map +1 -1
  653. package/lib/esm/test/standalone/ExportGraphics.test.js +40 -34
  654. package/lib/esm/test/standalone/ExportGraphics.test.js.map +1 -1
  655. package/lib/esm/test/standalone/GeometryChangeEvents.test.js +11 -15
  656. package/lib/esm/test/standalone/GeometryChangeEvents.test.js.map +1 -1
  657. package/lib/esm/test/standalone/GeometryStream.test.js +212 -165
  658. package/lib/esm/test/standalone/GeometryStream.test.js.map +1 -1
  659. package/lib/esm/test/standalone/HubMock.test.js +31 -25
  660. package/lib/esm/test/standalone/HubMock.test.js.map +1 -1
  661. package/lib/esm/test/standalone/IModelLimits.test.js +11 -8
  662. package/lib/esm/test/standalone/IModelLimits.test.js.map +1 -1
  663. package/lib/esm/test/standalone/IModelWrite.test.d.ts +2 -2
  664. package/lib/esm/test/standalone/IModelWrite.test.d.ts.map +1 -1
  665. package/lib/esm/test/standalone/IModelWrite.test.js +211 -169
  666. package/lib/esm/test/standalone/IModelWrite.test.js.map +1 -1
  667. package/lib/esm/test/standalone/ITwinWorkspace.test.d.ts +2 -0
  668. package/lib/esm/test/standalone/ITwinWorkspace.test.d.ts.map +1 -0
  669. package/lib/esm/test/standalone/ITwinWorkspace.test.js +236 -0
  670. package/lib/esm/test/standalone/ITwinWorkspace.test.js.map +1 -0
  671. package/lib/esm/test/standalone/InlineGeometryPartReferences.test.js +25 -22
  672. package/lib/esm/test/standalone/InlineGeometryPartReferences.test.js.map +1 -1
  673. package/lib/esm/test/standalone/IntegrityCheck.test.js +20 -18
  674. package/lib/esm/test/standalone/IntegrityCheck.test.js.map +1 -1
  675. package/lib/esm/test/standalone/MergeConflict.test.d.ts +2 -2
  676. package/lib/esm/test/standalone/MergeConflict.test.d.ts.map +1 -1
  677. package/lib/esm/test/standalone/MergeConflict.test.js +49 -33
  678. package/lib/esm/test/standalone/MergeConflict.test.js.map +1 -1
  679. package/lib/esm/test/standalone/NativeAppStorage.test.js.map +1 -1
  680. package/lib/esm/test/standalone/RenderMaterialElement.test.js +5 -5
  681. package/lib/esm/test/standalone/RenderMaterialElement.test.js.map +1 -1
  682. package/lib/esm/test/standalone/RenderTimeline.test.js +3 -2
  683. package/lib/esm/test/standalone/RenderTimeline.test.js.map +1 -1
  684. package/lib/esm/test/standalone/SQLiteDb.test.js.map +1 -1
  685. package/lib/esm/test/standalone/SchemaUtils.test.js.map +1 -1
  686. package/lib/esm/test/standalone/SectionDrawing.test.js +7 -7
  687. package/lib/esm/test/standalone/SectionDrawing.test.js.map +1 -1
  688. package/lib/esm/test/standalone/ServerBasedLocks.test.js +928 -22
  689. package/lib/esm/test/standalone/ServerBasedLocks.test.js.map +1 -1
  690. package/lib/esm/test/standalone/Setting.test.js.map +1 -1
  691. package/lib/esm/test/standalone/Settings.test.js +26 -4
  692. package/lib/esm/test/standalone/Settings.test.js.map +1 -1
  693. package/lib/esm/test/standalone/SettingsSchemas.test.js +2 -1
  694. package/lib/esm/test/standalone/SettingsSchemas.test.js.map +1 -1
  695. package/lib/esm/test/standalone/SnapshotDb.test.js +3 -1
  696. package/lib/esm/test/standalone/SnapshotDb.test.js.map +1 -1
  697. package/lib/esm/test/standalone/StandaloneDb.test.js +27 -26
  698. package/lib/esm/test/standalone/StandaloneDb.test.js.map +1 -1
  699. package/lib/esm/test/standalone/Texture.test.js +5 -4
  700. package/lib/esm/test/standalone/Texture.test.js.map +1 -1
  701. package/lib/esm/test/standalone/TileCache.test.d.ts.map +1 -1
  702. package/lib/esm/test/standalone/TileCache.test.js +5 -3
  703. package/lib/esm/test/standalone/TileCache.test.js.map +1 -1
  704. package/lib/esm/test/standalone/TileTree.test.js +35 -31
  705. package/lib/esm/test/standalone/TileTree.test.js.map +1 -1
  706. package/lib/esm/test/standalone/TxnManager.test.js +700 -653
  707. package/lib/esm/test/standalone/TxnManager.test.js.map +1 -1
  708. package/lib/esm/test/standalone/ViewDefinition.test.js +295 -229
  709. package/lib/esm/test/standalone/ViewDefinition.test.js.map +1 -1
  710. package/lib/esm/test/standalone/ViewStoreDb.test.js.map +1 -1
  711. package/lib/esm/test/standalone/Workspace.test.js +72 -22
  712. package/lib/esm/test/standalone/Workspace.test.js.map +1 -1
  713. package/lib/esm/test/standalone/iModelDb.test.js.map +1 -1
  714. package/lib/esm/test/workspace/SettingsDb.test.js +28 -456
  715. package/lib/esm/test/workspace/SettingsDb.test.js.map +1 -1
  716. package/lib/esm/workspace/Settings.d.ts +11 -5
  717. package/lib/esm/workspace/Settings.d.ts.map +1 -1
  718. package/lib/esm/workspace/Settings.js.map +1 -1
  719. package/lib/esm/workspace/SettingsDb.d.ts +20 -99
  720. package/lib/esm/workspace/SettingsDb.d.ts.map +1 -1
  721. package/lib/esm/workspace/SettingsDb.js +20 -6
  722. package/lib/esm/workspace/SettingsDb.js.map +1 -1
  723. package/lib/esm/workspace/SettingsEditor.d.ts +40 -226
  724. package/lib/esm/workspace/SettingsEditor.d.ts.map +1 -1
  725. package/lib/esm/workspace/SettingsEditor.js +85 -24
  726. package/lib/esm/workspace/SettingsEditor.js.map +1 -1
  727. package/lib/esm/workspace/SettingsSchemas.js.map +1 -1
  728. package/lib/esm/workspace/Workspace.d.ts +7 -11
  729. package/lib/esm/workspace/Workspace.d.ts.map +1 -1
  730. package/lib/esm/workspace/Workspace.js.map +1 -1
  731. package/lib/esm/workspace/WorkspaceEditor.d.ts +14 -0
  732. package/lib/esm/workspace/WorkspaceEditor.d.ts.map +1 -1
  733. package/lib/esm/workspace/WorkspaceEditor.js +1 -1
  734. package/lib/esm/workspace/WorkspaceEditor.js.map +1 -1
  735. package/package.json +13 -13
  736. package/lib/cjs/internal/workspace/SettingsDbImpl.d.ts +0 -38
  737. package/lib/cjs/internal/workspace/SettingsDbImpl.d.ts.map +0 -1
  738. package/lib/cjs/internal/workspace/SettingsDbImpl.js +0 -108
  739. package/lib/cjs/internal/workspace/SettingsDbImpl.js.map +0 -1
  740. package/lib/cjs/internal/workspace/SettingsSqliteDb.d.ts +0 -14
  741. package/lib/cjs/internal/workspace/SettingsSqliteDb.d.ts.map +0 -1
  742. package/lib/cjs/internal/workspace/SettingsSqliteDb.js +0 -40
  743. package/lib/cjs/internal/workspace/SettingsSqliteDb.js.map +0 -1
  744. package/lib/esm/internal/workspace/SettingsDbImpl.d.ts +0 -38
  745. package/lib/esm/internal/workspace/SettingsDbImpl.d.ts.map +0 -1
  746. package/lib/esm/internal/workspace/SettingsDbImpl.js +0 -104
  747. package/lib/esm/internal/workspace/SettingsDbImpl.js.map +0 -1
  748. package/lib/esm/internal/workspace/SettingsSqliteDb.d.ts +0 -14
  749. package/lib/esm/internal/workspace/SettingsSqliteDb.d.ts.map +0 -1
  750. package/lib/esm/internal/workspace/SettingsSqliteDb.js +0 -36
  751. package/lib/esm/internal/workspace/SettingsSqliteDb.js.map +0 -1
@@ -4,8 +4,8 @@
4
4
  *--------------------------------------------------------------------------------------------*/
5
5
  import * as chai from "chai";
6
6
  import * as chaiAsPromised from "chai-as-promised";
7
- import { restore as sinonRestore, spy as sinonSpy } from "sinon";
8
- import { Guid, Id64 } from "@itwin/core-bentley";
7
+ import { match as sinonMatch, restore as sinonRestore, spy as sinonSpy, stub as sinonStub } from "sinon";
8
+ import { Guid, Id64, IModelStatus } from "@itwin/core-bentley";
9
9
  import { Code, IModel, IModelError, LockState } from "@itwin/core-common";
10
10
  import { BriefcaseManager } from "../../BriefcaseManager";
11
11
  import { PhysicalObject } from "../../domains/GenericElements";
@@ -15,8 +15,9 @@ import { ElementOwnsChildElements } from "../../NavigationRelationship";
15
15
  import { HubMock } from "../../internal/HubMock";
16
16
  import { ExtensiveTestScenario, IModelTestUtils } from "../IModelTestUtils";
17
17
  import { KnownTestLocations } from "../KnownTestLocations";
18
- import { ChannelControl } from "../../core-backend";
18
+ import { ChannelControl, LockConflict } from "../../core-backend";
19
19
  import { _hubAccess, _releaseAllLocks } from "../../internal/Symbols";
20
+ import { EditTxn, withEditTxn } from "../../EditTxn";
20
21
  const expect = chai.expect;
21
22
  const assert = chai.assert;
22
23
  chai.use(chaiAsPromised);
@@ -27,7 +28,6 @@ describe("Server-based locks", () => {
27
28
  assert.isFalse(sourceDb.locks.isServerBased);
28
29
  await ExtensiveTestScenario.prepareDb(sourceDb);
29
30
  await ExtensiveTestScenario.populateDb(sourceDb);
30
- sourceDb.saveChanges();
31
31
  sourceDb.close();
32
32
  return dbName;
33
33
  };
@@ -161,21 +161,24 @@ describe("Server-based locks", () => {
161
161
  category: childElJson.category,
162
162
  code: Code.createEmpty(),
163
163
  };
164
- assert.throws(() => bc1.elements.insertElement(physicalProps), IModelError, "shared lock"); // insert requires shared lock on model
164
+ assert.throws(() => withEditTxn(bc1, (txn) => txn.insertElement(physicalProps)), IModelError, "shared lock"); // insert requires shared lock on model
165
165
  await bc1Locks.acquireLocks({ shared: parentId }); // also acquires shared lock on model
166
- const newElId = bc1.elements.insertElement(physicalProps);
166
+ const newElId = withEditTxn(bc1, (txn) => txn.insertElement(physicalProps));
167
167
  assertExclusiveLocks(bc1Locks, newElId);
168
168
  childElJson.userLabel = "new user label";
169
- assert.throws(() => bc1.elements.updateElement(childElJson), "exclusive lock");
169
+ assert.throws(() => withEditTxn(bc1, (txn) => txn.updateElement(childElJson)), "exclusive lock");
170
170
  await bc1Locks.acquireLocks({ exclusive: child1 });
171
- bc1.elements.updateElement(childElJson);
172
- bc1.saveChanges();
173
- bc1.elements.deleteElement(child1); // make sure delete now works
174
- bc1.abandonChanges();
171
+ withEditTxn(bc1, (txn) => txn.updateElement(childElJson));
172
+ {
173
+ const txn = new EditTxn(bc1, "verify delete lock behavior");
174
+ txn.start();
175
+ txn.deleteElement(child1); // make sure delete now works
176
+ txn.end("abandon");
177
+ }
175
178
  assert.isTrue(bc1.locks.holdsSharedLock(IModel.repositoryModelId));
176
179
  await bc1.pushChanges({ accessToken: accessToken1, description: "my changes" });
177
180
  assert.isFalse(bc1.locks.holdsSharedLock(IModel.repositoryModelId));
178
- assert.throws(() => bc2.elements.deleteElement(child1), "exclusive lock"); // bc2 can't delete because it doesn't hold lock
181
+ assert.throws(() => withEditTxn(bc2, (txn) => txn.deleteElement(child1)), "exclusive lock"); // bc2 can't delete because it doesn't hold lock
179
182
  await expect(bc2Locks.acquireLocks({ exclusive: child1 })).rejectedWith(IModelError, "pull is required"); // can't get lock since other briefcase changed it
180
183
  await bc2.pullChanges({ accessToken: accessToken2 });
181
184
  await bc2Locks.acquireLocks({ exclusive: child1, shared: child1 });
@@ -207,10 +210,10 @@ describe("Server-based locks", () => {
207
210
  expect(locks.getLockCount(LockState.Exclusive)).to.equal(0);
208
211
  expect(locks.getLockCount(LockState.Shared)).to.equal(0);
209
212
  }
210
- function write() {
213
+ function write(txn) {
211
214
  const elem = bc.elements.getElement(elemId);
212
215
  elem.jsonProperties.testProp = Guid.createValue();
213
- elem.update();
216
+ elem.update(txn);
214
217
  }
215
218
  async function push(retainLocks) {
216
219
  return bc.pushChanges({ retainLocks, accessToken: "token", description: "changes" });
@@ -231,8 +234,7 @@ describe("Server-based locks", () => {
231
234
  it("is called when pushing changes", async () => {
232
235
  await bc.acquireSchemaLock();
233
236
  expectLocked();
234
- write();
235
- bc.saveChanges();
237
+ withEditTxn(bc, (txn) => write(txn));
236
238
  await push();
237
239
  expectUnlocked();
238
240
  });
@@ -247,8 +249,7 @@ describe("Server-based locks", () => {
247
249
  it("is not called when pushing changes if retainLocks is specified", async () => {
248
250
  await bc.acquireSchemaLock();
249
251
  expectLocked();
250
- write();
251
- bc.saveChanges();
252
+ withEditTxn(bc, (txn) => write(txn));
252
253
  await push(true);
253
254
  expectLocked();
254
255
  await locks.releaseAllLocks();
@@ -258,8 +259,7 @@ describe("Server-based locks", () => {
258
259
  expectUnlocked();
259
260
  await bc.acquireSchemaLock();
260
261
  expectLocked();
261
- write();
262
- bc.saveChanges();
262
+ withEditTxn(bc, (txn) => write(txn));
263
263
  await expect(locks.releaseAllLocks()).to.eventually.be.rejectedWith("local changes");
264
264
  await push();
265
265
  expectUnlocked();
@@ -267,13 +267,919 @@ describe("Server-based locks", () => {
267
267
  it("throws if briefcase has unsaved changes", async () => {
268
268
  expectUnlocked();
269
269
  await bc.acquireSchemaLock();
270
- write();
270
+ const txn = new EditTxn(bc, "releaseAllLocks unsaved changes");
271
+ txn.start();
272
+ write(txn);
271
273
  await expect(locks.releaseAllLocks()).to.eventually.be.rejectedWith("local changes");
272
274
  expectLocked();
273
- bc.abandonChanges();
275
+ txn.end("abandon");
274
276
  await locks.releaseAllLocks();
275
277
  expectUnlocked();
276
278
  });
277
279
  });
280
+ describe("abandonLocksForReversedTxn", () => {
281
+ let bc;
282
+ let bc2;
283
+ let locks;
284
+ beforeEach(async () => {
285
+ bc = await BriefcaseDb.open({ fileName: briefcase1Props.fileName });
286
+ expect(bc.locks.isServerBased).to.be.true;
287
+ locks = bc.locks;
288
+ bc.channels.addAllowedChannel(ChannelControl.sharedChannelName);
289
+ });
290
+ afterEach(async () => {
291
+ sinonRestore();
292
+ await locks[_releaseAllLocks]();
293
+ bc.close();
294
+ if (bc2 !== undefined) {
295
+ await bc2.locks.releaseAllLocks();
296
+ bc2.close();
297
+ bc2 = undefined;
298
+ }
299
+ });
300
+ it("abandons locks acquired in the current, unsaved txn", async () => {
301
+ const lockSpy = sinonSpy(IModelHost[_hubAccess], "abandonLocks");
302
+ const childId = IModelTestUtils.queryByUserLabel(bc, "ChildObject1B");
303
+ const txnId = bc.txns.getCurrentTxnId();
304
+ await locks.acquireLocks({ exclusive: childId });
305
+ expect(locks.holdsExclusiveLock(childId)).to.be.true;
306
+ expect(locks.getLockCount(LockState.Exclusive)).to.equal(1);
307
+ expect(locks.getLockCount(LockState.Shared)).to.be.greaterThan(0);
308
+ expect(await locks.abandonLocksForReversedTxn(txnId)).to.be.true;
309
+ expect(lockSpy.callCount).to.equal(1);
310
+ const releasedLocks = lockSpy.getCall(0).args[1];
311
+ expect(releasedLocks.size).to.be.greaterThan(0);
312
+ for (const state of releasedLocks.values())
313
+ expect(state).to.equal(LockState.None);
314
+ expect(locks.holdsExclusiveLock(childId)).to.be.false;
315
+ expect(locks.getLockCount(LockState.Exclusive)).to.equal(0);
316
+ expect(locks.getLockCount(LockState.Shared)).to.equal(0);
317
+ });
318
+ it("abandons locks acquired in the most recent saved txn", async () => {
319
+ const lockSpy = sinonSpy(IModelHost[_hubAccess], "abandonLocks");
320
+ const childId = IModelTestUtils.queryByUserLabel(bc, "ChildObject1B");
321
+ const txnId = bc.txns.getCurrentTxnId();
322
+ await withEditTxn(bc, async (txn) => {
323
+ await locks.acquireLocks({ exclusive: childId });
324
+ const element = bc.elements.getElement(childId);
325
+ element.setUserProperties("foo", Guid.createValue());
326
+ element.update(txn);
327
+ });
328
+ expect(locks.holdsExclusiveLock(childId)).to.be.true;
329
+ expect(locks.getLockCount(LockState.Exclusive)).to.equal(1);
330
+ expect(locks.getLockCount(LockState.Shared)).to.be.greaterThan(0);
331
+ bc.txns.reverseSingleTxn();
332
+ expect(await locks.abandonLocksForReversedTxn(txnId)).to.be.true;
333
+ expect(lockSpy.callCount).to.equal(1);
334
+ const releasedLocks = lockSpy.getCall(0).args[1];
335
+ expect(releasedLocks.size).to.be.greaterThan(0);
336
+ for (const state of releasedLocks.values())
337
+ expect(state).to.equal(LockState.None);
338
+ expect(locks.holdsExclusiveLock(childId)).to.be.false;
339
+ expect(locks.getLockCount(LockState.Exclusive)).to.equal(0);
340
+ expect(locks.getLockCount(LockState.Shared)).to.equal(0);
341
+ });
342
+ it("does not release locks acquired by a different txn", async () => {
343
+ const elementId1 = IModelTestUtils.queryByUserLabel(bc, "PhysicalObject2");
344
+ const elementId2 = IModelTestUtils.queryByUserLabel(bc, "ChildObject1B");
345
+ const txn1 = bc.txns.getCurrentTxnId();
346
+ await locks.acquireLocks({ exclusive: elementId1 });
347
+ await withEditTxn(bc, async (txn) => {
348
+ const element = bc.elements.getElement(elementId1);
349
+ element.setUserProperties("foo", Guid.createValue());
350
+ element.update(txn);
351
+ });
352
+ const txn2 = bc.txns.getCurrentTxnId();
353
+ expect(txn2).not.to.equal(txn1);
354
+ await withEditTxn(bc, async (txn) => {
355
+ await locks.acquireLocks({ exclusive: elementId2 });
356
+ const element2 = bc.elements.getElement(elementId2);
357
+ element2.setUserProperties("bar", Guid.createValue());
358
+ element2.update(txn);
359
+ });
360
+ expect(locks.holdsExclusiveLock(elementId1)).to.be.true;
361
+ expect(locks.holdsExclusiveLock(elementId2)).to.be.true;
362
+ bc.txns.reverseTxns(1);
363
+ expect(await locks.abandonLocksForReversedTxn(txn2)).to.be.true;
364
+ expect(locks.holdsExclusiveLock(elementId1)).to.be.true;
365
+ expect(locks.holdsExclusiveLock(elementId2)).to.be.false;
366
+ });
367
+ it("invalidates discovered locks", async () => {
368
+ const elementId = IModelTestUtils.queryByUserLabel(bc, "ChildObject1B");
369
+ const ownerModeltId = bc.elements.getElementProps(elementId).model;
370
+ const ownersOwnerModelId = bc.elements.getElementProps(ownerModeltId).model;
371
+ await locks.acquireLocks({ exclusive: ownersOwnerModelId });
372
+ expect(locks.holdsExclusiveLock(ownerModeltId)).to.be.true;
373
+ expect(locks.holdsExclusiveLock(elementId)).to.be.true;
374
+ const txnId = bc.txns.getCurrentTxnId();
375
+ bc.txns.reverseTxns(1);
376
+ expect(await locks.abandonLocksForReversedTxn(txnId)).to.be.true;
377
+ expect(locks.holdsExclusiveLock(ownerModeltId)).to.be.false;
378
+ expect(locks.holdsExclusiveLock(elementId)).to.be.false;
379
+ });
380
+ it("restores lock to its previous state if it was upgraded by the reversed txn", async () => {
381
+ const elementId1 = IModelTestUtils.queryByUserLabel(bc, "PhysicalObject2");
382
+ const elementId2 = IModelTestUtils.queryByUserLabel(bc, "ChildObject1B");
383
+ const firstTxnId = bc.txns.getCurrentTxnId();
384
+ await locks.acquireLocks({ exclusive: elementId1, shared: elementId2 });
385
+ expect(locks.holdsSharedLock(elementId2)).to.be.true;
386
+ expect(locks.holdsExclusiveLock(elementId2)).to.be.false;
387
+ // We must actually edit something in order to start a new Txn.
388
+ await withEditTxn(bc, async (txn) => {
389
+ const element = bc.elements.getElement(elementId1);
390
+ element.setUserProperties("foo", { test: true });
391
+ element.update(txn);
392
+ });
393
+ const secondTxnId = bc.txns.getCurrentTxnId();
394
+ expect(firstTxnId).not.to.equal(secondTxnId);
395
+ await locks.acquireLocks({ exclusive: elementId2 }); // upgrade lock from shared to exclusive
396
+ expect(locks.holdsSharedLock(elementId2)).to.be.true;
397
+ expect(locks.holdsExclusiveLock(elementId2)).to.be.true;
398
+ expect(await locks.abandonLocksForReversedTxn(secondTxnId)).to.be.true;
399
+ expect(locks.holdsSharedLock(elementId2)).to.be.true;
400
+ expect(locks.holdsExclusiveLock(elementId2)).to.be.false;
401
+ });
402
+ it("does not update changesetid when releasing locks", async () => {
403
+ bc2 = await BriefcaseDb.open({ fileName: briefcase2Props.fileName });
404
+ expect(bc2.locks.isServerBased).to.be.true;
405
+ bc2.channels.addAllowedChannel(ChannelControl.sharedChannelName);
406
+ // Make sure both briefcase initially have all changes.
407
+ await bc.pullChanges({ accessToken: "token" });
408
+ await bc2.pullChanges({ accessToken: "token" });
409
+ const elementId1 = IModelTestUtils.queryByUserLabel(bc, "PhysicalObject2");
410
+ const elementId2 = IModelTestUtils.queryByUserLabel(bc, "ChildObject1B");
411
+ // Edit an element in the first briefcase and push the change. This will
412
+ // create a new changeset.
413
+ await locks.acquireLocks({ exclusive: elementId1 });
414
+ await withEditTxn(bc, async (txn) => {
415
+ const element = bc.elements.getElement(elementId1);
416
+ element.setUserProperties("foo", { test: true });
417
+ element.update(txn);
418
+ });
419
+ await bc.pushChanges({ accessToken: "token", description: "changes" });
420
+ const secondTxnId = bc.txns.getCurrentTxnId();
421
+ // In that same briefcase, lock and edit a different element, but then reverse
422
+ // the change and release the lock.
423
+ await bc.locks.acquireLocks({ exclusive: elementId2 });
424
+ await withEditTxn(bc, async (txn) => {
425
+ const element2 = bc.elements.getElement(elementId2);
426
+ element2.setUserProperties("bar", { test: true });
427
+ element2.update(txn);
428
+ });
429
+ bc.txns.reverseTxns(1);
430
+ expect(await locks.abandonLocksForReversedTxn(secondTxnId)).to.be.true;
431
+ // Now, in a separate briefcase, which has not yet pulled the changes pushed by the first,
432
+ // attempt to lock the same element whose lock was just released. This should work because
433
+ // the lock release by releaseLocksForReversedTxn should not have updated the changeset
434
+ // associated with that lock.
435
+ await bc2.locks.acquireLocks({ exclusive: elementId2 });
436
+ });
437
+ it("does not release on the server an implicit lock held for a new element", async () => {
438
+ const childId = IModelTestUtils.queryByUserLabel(bc, "ChildObject1B");
439
+ const childElement = bc.elements.getElement(childId);
440
+ const parentId = childElement.parent.id;
441
+ const modelId = childElement.model;
442
+ const physicalProps = {
443
+ classFullName: PhysicalObject.classFullName,
444
+ model: modelId,
445
+ parent: new ElementOwnsChildElements(parentId),
446
+ category: childElement.category,
447
+ code: Code.createEmpty(),
448
+ };
449
+ const txnId = bc.txns.getCurrentTxnId();
450
+ await locks.acquireLocks({ shared: [modelId, parentId] });
451
+ const newElementId = await withEditTxn(bc, async (txn) => {
452
+ return txn.insertElement(physicalProps);
453
+ });
454
+ expect(locks.holdsExclusiveLock(newElementId)).to.be.true;
455
+ const lockSpy = sinonSpy(IModelHost[_hubAccess], "acquireLocks");
456
+ bc.txns.reverseTxns(1);
457
+ expect(await locks.abandonLocksForReversedTxn(txnId)).to.be.true;
458
+ expect(lockSpy.calledWithMatch(sinonMatch.any, sinonMatch((lockMap) => lockMap.has(newElementId)))).to.be.false;
459
+ });
460
+ it("releases locks for later txns, too", async () => {
461
+ const elementId1 = IModelTestUtils.queryByUserLabel(bc, "PhysicalObject2");
462
+ const elementId2 = IModelTestUtils.queryByUserLabel(bc, "ChildObject1B");
463
+ const txn1 = bc.txns.getCurrentTxnId();
464
+ await locks.acquireLocks({ exclusive: elementId1 });
465
+ const element1 = bc.elements.getElement(elementId1);
466
+ await withEditTxn(bc, async (txn) => {
467
+ element1.setUserProperties("foo", Guid.createValue());
468
+ element1.update(txn);
469
+ });
470
+ const txn2 = bc.txns.getCurrentTxnId();
471
+ expect(txn2).not.to.equal(txn1);
472
+ await locks.acquireLocks({ exclusive: elementId2 });
473
+ const element2 = bc.elements.getElement(elementId2);
474
+ await withEditTxn(bc, async (txn) => {
475
+ element2.setUserProperties("bar", Guid.createValue());
476
+ element2.update(txn);
477
+ });
478
+ expect(locks.holdsExclusiveLock(elementId1)).to.be.true;
479
+ expect(locks.holdsExclusiveLock(elementId2)).to.be.true;
480
+ // Reverse both txns, then abandon locks starting from the earlier one.
481
+ // This will release locks for the later one, too.
482
+ bc.txns.reverseTxns(2);
483
+ expect(await locks.abandonLocksForReversedTxn(txn1)).to.be.true;
484
+ expect(locks.holdsExclusiveLock(elementId1)).to.be.false;
485
+ expect(locks.holdsExclusiveLock(elementId2)).to.be.false;
486
+ });
487
+ it("throws if asked to abandon locks for a txn that has not been reversed", async () => {
488
+ const elementId = IModelTestUtils.queryByUserLabel(bc, "ChildObject1B");
489
+ const txnId = bc.txns.getCurrentTxnId();
490
+ await locks.acquireLocks({ exclusive: elementId });
491
+ const element = bc.elements.getElement(elementId);
492
+ await withEditTxn(bc, async (txn) => {
493
+ element.setUserProperties("foo", Guid.createValue());
494
+ element.update(txn);
495
+ });
496
+ // The txn has not been reversed, so abandonLocksForReversedTxn should throw.
497
+ await expect(locks.abandonLocksForReversedTxn(txnId)).to.eventually.be.rejectedWith("has not been reversed");
498
+ expect(locks.holdsExclusiveLock(elementId)).to.be.true;
499
+ });
500
+ it("throws if asked to abandon locks for the current txn and there are unsaved changes", async () => {
501
+ const elementId = IModelTestUtils.queryByUserLabel(bc, "ChildObject1B");
502
+ await locks.acquireLocks({ exclusive: elementId });
503
+ const element = bc.elements.getElement(elementId);
504
+ await withEditTxn(bc, async (txn) => {
505
+ element.setUserProperties("foo", Guid.createValue());
506
+ element.update(txn);
507
+ // The current txn has unsaved changes, so abandonLocksForReversedTxn should throw.
508
+ const txnId = bc.txns.getCurrentTxnId();
509
+ await expect(locks.abandonLocksForReversedTxn(txnId)).to.eventually.be.rejectedWith("unsaved changes");
510
+ expect(locks.holdsExclusiveLock(elementId)).to.be.true;
511
+ });
512
+ });
513
+ it("throws if asked to abandon locks for a nonexistent txn", async () => {
514
+ const elementId = IModelTestUtils.queryByUserLabel(bc, "ChildObject1B");
515
+ await locks.acquireLocks({ exclusive: elementId });
516
+ const element = bc.elements.getElement(elementId);
517
+ await withEditTxn(bc, async (txn) => {
518
+ element.setUserProperties("foo", Guid.createValue());
519
+ element.update(txn);
520
+ });
521
+ bc.txns.reverseSingleTxn();
522
+ // Use an ID that is not a valid txn.
523
+ await expect(locks.abandonLocksForReversedTxn("0xffffffffffff")).to.eventually.be.rejectedWith("does not exist");
524
+ // The lock should still be held.
525
+ expect(locks.holdsExclusiveLock(elementId)).to.be.true;
526
+ });
527
+ it("returns false when called a second time for an already-abandoned txn", async () => {
528
+ const elementId = IModelTestUtils.queryByUserLabel(bc, "ChildObject1B");
529
+ const txnId = bc.txns.getCurrentTxnId();
530
+ await locks.acquireLocks({ exclusive: elementId });
531
+ const element = bc.elements.getElement(elementId);
532
+ await withEditTxn(bc, async (txn) => {
533
+ element.setUserProperties("foo", Guid.createValue());
534
+ element.update(txn);
535
+ });
536
+ bc.txns.reverseSingleTxn();
537
+ expect(await locks.abandonLocksForReversedTxn(txnId)).to.be.true;
538
+ expect(locks.holdsExclusiveLock(elementId)).to.be.false;
539
+ // Calling again should be a no-op and return false because the locks are already abandoned.
540
+ expect(await locks.abandonLocksForReversedTxn(txnId)).to.be.false;
541
+ expect(locks.holdsExclusiveLock(elementId)).to.be.false;
542
+ });
543
+ });
544
+ describe("acquireLocksForReinstatingTxn", () => {
545
+ let bc;
546
+ let bc2;
547
+ let locks;
548
+ beforeEach(async () => {
549
+ bc = await BriefcaseDb.open({ fileName: briefcase1Props.fileName });
550
+ expect(bc.locks.isServerBased).to.be.true;
551
+ locks = bc.locks;
552
+ bc.channels.addAllowedChannel(ChannelControl.sharedChannelName);
553
+ });
554
+ afterEach(async () => {
555
+ await locks[_releaseAllLocks]();
556
+ bc.close();
557
+ if (bc2 !== undefined) {
558
+ await bc2.locks[_releaseAllLocks]();
559
+ bc2.close();
560
+ bc2 = undefined;
561
+ }
562
+ });
563
+ it("reacquires locks for reinstating a txn", async () => {
564
+ const childId = IModelTestUtils.queryByUserLabel(bc, "ChildObject1B");
565
+ const txnId = bc.txns.getCurrentTxnId();
566
+ await locks.acquireLocks({ exclusive: childId });
567
+ expect(locks.holdsExclusiveLock(childId)).to.be.true;
568
+ // We must actually edit something in order to start a new Txn.
569
+ const element = bc.elements.getElement(childId);
570
+ await withEditTxn(bc, async (txn) => {
571
+ element.setUserProperties("foo", { test: true });
572
+ element.update(txn);
573
+ });
574
+ bc.txns.reverseTxns(1);
575
+ await locks.abandonLocksForReversedTxn(txnId);
576
+ expect(locks.holdsExclusiveLock(childId)).to.be.false;
577
+ expect(await locks.acquireLocksForReinstatingTxn(txnId)).to.be.true;
578
+ bc.txns.reinstateTxn();
579
+ expect(locks.holdsExclusiveLock(childId)).to.be.true;
580
+ });
581
+ it("reupgrades a shared lock to exclusive", async () => {
582
+ const elementId1 = IModelTestUtils.queryByUserLabel(bc, "PhysicalObject2");
583
+ const elementId2 = IModelTestUtils.queryByUserLabel(bc, "ChildObject1B");
584
+ const firstTxnId = bc.txns.getCurrentTxnId();
585
+ await locks.acquireLocks({ exclusive: elementId1, shared: elementId2 });
586
+ expect(locks.holdsSharedLock(elementId2)).to.be.true;
587
+ expect(locks.holdsExclusiveLock(elementId2)).to.be.false;
588
+ // We must actually edit something in order to start a new Txn.
589
+ const element = bc.elements.getElement(elementId1);
590
+ await withEditTxn(bc, async (txn) => {
591
+ element.setUserProperties("foo", { test: true });
592
+ element.update(txn);
593
+ });
594
+ const secondTxnId = bc.txns.getCurrentTxnId();
595
+ expect(firstTxnId).not.to.equal(secondTxnId);
596
+ await locks.acquireLocks({ exclusive: elementId2 }); // upgrade lock from shared to exclusive
597
+ const element2 = bc.elements.getElement(elementId2);
598
+ await withEditTxn(bc, async (txn) => {
599
+ element2.setUserProperties("bar", { test: true });
600
+ element2.update(txn);
601
+ });
602
+ expect(locks.holdsSharedLock(elementId2)).to.be.true;
603
+ expect(locks.holdsExclusiveLock(elementId2)).to.be.true;
604
+ bc.txns.reverseSingleTxn();
605
+ await locks.abandonLocksForReversedTxn(secondTxnId);
606
+ expect(locks.holdsSharedLock(elementId2)).to.be.true;
607
+ expect(locks.holdsExclusiveLock(elementId2)).to.be.false;
608
+ expect(await locks.acquireLocksForReinstatingTxn(secondTxnId)).to.be.true;
609
+ bc.txns.reinstateTxn();
610
+ expect(locks.holdsSharedLock(elementId2)).to.be.true;
611
+ expect(locks.holdsExclusiveLock(elementId2)).to.be.true;
612
+ });
613
+ it("does not acquire on the server an implicit lock originally held for a new element", async () => {
614
+ const childId = IModelTestUtils.queryByUserLabel(bc, "ChildObject1B");
615
+ const childElement = bc.elements.getElement(childId);
616
+ const parentId = childElement.parent.id;
617
+ const modelId = childElement.model;
618
+ const physicalProps = {
619
+ classFullName: PhysicalObject.classFullName,
620
+ model: modelId,
621
+ parent: new ElementOwnsChildElements(parentId),
622
+ category: childElement.category,
623
+ code: Code.createEmpty(),
624
+ };
625
+ await locks.acquireLocks({ shared: [modelId, parentId] });
626
+ const txnId = bc.txns.getCurrentTxnId();
627
+ const newElementId = await withEditTxn(bc, async (txn) => {
628
+ return txn.insertElement(physicalProps);
629
+ });
630
+ bc.txns.reverseTxns(1);
631
+ expect(await locks.abandonLocksForReversedTxn(txnId)).to.be.true;
632
+ expect(await locks.acquireLocksForReinstatingTxn(txnId)).to.be.true;
633
+ bc.txns.reinstateTxn();
634
+ expect(locks.holdsExclusiveLock(newElementId)).to.be.true;
635
+ });
636
+ it("acquires locks for earlier txns, too", async () => {
637
+ const elementId1 = IModelTestUtils.queryByUserLabel(bc, "PhysicalObject2");
638
+ const elementId2 = IModelTestUtils.queryByUserLabel(bc, "ChildObject1B");
639
+ const txn1 = bc.txns.getCurrentTxnId();
640
+ await locks.acquireLocks({ exclusive: elementId1 });
641
+ const element1 = bc.elements.getElement(elementId1);
642
+ await withEditTxn(bc, async (txn) => {
643
+ element1.setUserProperties("foo", Guid.createValue());
644
+ element1.update(txn);
645
+ });
646
+ const txn2 = bc.txns.getCurrentTxnId();
647
+ expect(txn2).not.to.equal(txn1);
648
+ await locks.acquireLocks({ exclusive: elementId2 });
649
+ const element2 = bc.elements.getElement(elementId2);
650
+ await withEditTxn(bc, async (txn) => {
651
+ element2.setUserProperties("bar", Guid.createValue());
652
+ element2.update(txn);
653
+ });
654
+ expect(locks.holdsExclusiveLock(elementId1)).to.be.true;
655
+ expect(locks.holdsExclusiveLock(elementId2)).to.be.true;
656
+ // Reverse both txns and abandon locks starting from the earlier one.
657
+ bc.txns.reverseTxns(2);
658
+ expect(await locks.abandonLocksForReversedTxn(txn1)).to.be.true;
659
+ expect(locks.holdsExclusiveLock(elementId1)).to.be.false;
660
+ expect(locks.holdsExclusiveLock(elementId2)).to.be.false;
661
+ // Acquire locks for the later txn. This should also acquire locks for the earlier one.
662
+ expect(await locks.acquireLocksForReinstatingTxn(txn2)).to.be.true;
663
+ expect(locks.holdsExclusiveLock(elementId1)).to.be.true;
664
+ expect(locks.holdsExclusiveLock(elementId2)).to.be.true;
665
+ });
666
+ it("cannot acquire locks for a reversed txn after new changes are made", async () => {
667
+ const elementId1 = IModelTestUtils.queryByUserLabel(bc, "PhysicalObject2");
668
+ const elementId2 = IModelTestUtils.queryByUserLabel(bc, "ChildObject1B");
669
+ const txn1 = bc.txns.getCurrentTxnId();
670
+ await locks.acquireLocks({ exclusive: elementId1 });
671
+ const element1 = bc.elements.getElement(elementId1);
672
+ await withEditTxn(bc, async (txn) => {
673
+ element1.setUserProperties("foo", Guid.createValue());
674
+ element1.update(txn);
675
+ });
676
+ bc.txns.reverseTxns(1);
677
+ expect(await locks.abandonLocksForReversedTxn(txn1)).to.be.true;
678
+ // Make other changes, making the reversed txn inaccessible.
679
+ const txn2 = bc.txns.getCurrentTxnId();
680
+ expect(txn1).to.equal(txn2);
681
+ await locks.acquireLocks({ exclusive: elementId2 });
682
+ const element2 = bc.elements.getElement(elementId2);
683
+ await withEditTxn(bc, async (txn) => {
684
+ element2.setUserProperties("bar", Guid.createValue());
685
+ element2.update(txn);
686
+ });
687
+ // Attempting to reinstate the txn should not acquire any locks.
688
+ expect(await locks.acquireLocksForReinstatingTxn(txn1)).to.be.false;
689
+ // We should still not have a lock on elementId1, because txn1 is now a different txn after the original
690
+ // was reversed and we started making further changes under the reused txn id.
691
+ expect(locks.holdsExclusiveLock(elementId1)).to.be.false;
692
+ expect(locks.holdsExclusiveLock(elementId2)).to.be.true;
693
+ });
694
+ it("throws if another briefcase holds a conflicting lock", async () => {
695
+ const elementId = IModelTestUtils.queryByUserLabel(bc, "ChildObject1B");
696
+ const txnId = bc.txns.getCurrentTxnId();
697
+ await locks.acquireLocks({ exclusive: elementId });
698
+ const element = bc.elements.getElement(elementId);
699
+ await withEditTxn(bc, async (txn) => {
700
+ element.setUserProperties("foo", Guid.createValue());
701
+ element.update(txn);
702
+ });
703
+ // Reverse and abandon the lock so it's released on the server.
704
+ bc.txns.reverseSingleTxn();
705
+ expect(await locks.abandonLocksForReversedTxn(txnId)).to.be.true;
706
+ expect(locks.holdsExclusiveLock(elementId)).to.be.false;
707
+ // Have a second briefcase acquire the same lock.
708
+ bc2 = await BriefcaseDb.open({ fileName: briefcase2Props.fileName });
709
+ bc2.channels.addAllowedChannel(ChannelControl.sharedChannelName);
710
+ await bc2.pullChanges();
711
+ await bc2.locks.acquireLocks({ exclusive: elementId });
712
+ // Attempting to reacquire the lock for reinstatement should fail because bc2 holds it.
713
+ await expect(locks.acquireLocksForReinstatingTxn(txnId)).to.eventually.be.rejectedWith("lock is already held");
714
+ expect(locks.holdsExclusiveLock(elementId)).to.be.false;
715
+ });
716
+ it("is a no-op when locks were never abandoned", async () => {
717
+ const childId = IModelTestUtils.queryByUserLabel(bc, "ChildObject1B");
718
+ const txnId = bc.txns.getCurrentTxnId();
719
+ await locks.acquireLocks({ exclusive: childId });
720
+ const element = bc.elements.getElement(childId);
721
+ await withEditTxn(bc, async (txn) => {
722
+ element.setUserProperties("foo", Guid.createValue());
723
+ element.update(txn);
724
+ });
725
+ // Reverse the txn but do NOT abandon locks.
726
+ bc.txns.reverseSingleTxn();
727
+ expect(locks.holdsExclusiveLock(childId)).to.be.true;
728
+ // acquireLocksForReinstatingTxn should be a harmless no-op since locks were never abandoned.
729
+ expect(await locks.acquireLocksForReinstatingTxn(txnId)).to.be.false;
730
+ expect(locks.holdsExclusiveLock(childId)).to.be.true;
731
+ });
732
+ it("throws for an invalid txnId", async () => {
733
+ await expect(locks.acquireLocksForReinstatingTxn("0xffffffffffff")).to.eventually.be.rejectedWith("does not exist");
734
+ });
735
+ });
736
+ describe("TxnManager integration", () => {
737
+ let bc;
738
+ let locks;
739
+ beforeEach(async () => {
740
+ bc = await BriefcaseDb.open({ fileName: briefcase1Props.fileName });
741
+ expect(bc.locks.isServerBased).to.be.true;
742
+ locks = bc.locks;
743
+ bc.channels.addAllowedChannel(ChannelControl.sharedChannelName);
744
+ });
745
+ afterEach(async () => {
746
+ await locks[_releaseAllLocks]();
747
+ bc.close();
748
+ });
749
+ describe("reverseTxnsAsync", () => {
750
+ it("reverses a single txn and abandons its locks", async () => {
751
+ const elementId = IModelTestUtils.queryByUserLabel(bc, "ChildObject1B");
752
+ await locks.acquireLocks({ exclusive: elementId });
753
+ const element = bc.elements.getElement(elementId);
754
+ const originalProps = element.getUserProperties("foo");
755
+ await withEditTxn(bc, async (txn) => {
756
+ element.setUserProperties("foo", Guid.createValue());
757
+ element.update(txn);
758
+ });
759
+ expect(locks.holdsExclusiveLock(elementId)).to.be.true;
760
+ await bc.txns.reverseTxnsAsync(1);
761
+ expect(locks.holdsExclusiveLock(elementId)).to.be.false;
762
+ // Verify the element change was actually reversed.
763
+ const revertedElement = bc.elements.getElement(elementId);
764
+ expect(revertedElement.getUserProperties("foo")).to.deep.equal(originalProps);
765
+ });
766
+ it("reverses multiple txns and abandons all their locks", async () => {
767
+ const elementId1 = IModelTestUtils.queryByUserLabel(bc, "PhysicalObject2");
768
+ const elementId2 = IModelTestUtils.queryByUserLabel(bc, "ChildObject1B");
769
+ const orig1 = bc.elements.getElement(elementId1).getUserProperties("foo");
770
+ const orig2 = bc.elements.getElement(elementId2).getUserProperties("bar");
771
+ await locks.acquireLocks({ exclusive: elementId1 });
772
+ const element1 = bc.elements.getElement(elementId1);
773
+ await withEditTxn(bc, async (txn) => {
774
+ element1.setUserProperties("foo", Guid.createValue());
775
+ element1.update(txn);
776
+ });
777
+ await locks.acquireLocks({ exclusive: elementId2 });
778
+ const element2 = bc.elements.getElement(elementId2);
779
+ await withEditTxn(bc, async (txn) => {
780
+ element2.setUserProperties("bar", Guid.createValue());
781
+ element2.update(txn);
782
+ });
783
+ expect(locks.holdsExclusiveLock(elementId1)).to.be.true;
784
+ expect(locks.holdsExclusiveLock(elementId2)).to.be.true;
785
+ await bc.txns.reverseTxnsAsync(2);
786
+ expect(locks.holdsExclusiveLock(elementId1)).to.be.false;
787
+ expect(locks.holdsExclusiveLock(elementId2)).to.be.false;
788
+ // Verify the element changes were actually reversed.
789
+ expect(bc.elements.getElement(elementId1).getUserProperties("foo")).to.deep.equal(orig1);
790
+ expect(bc.elements.getElement(elementId2).getUserProperties("bar")).to.deep.equal(orig2);
791
+ });
792
+ it("when an earlier txn is reversed using reverseTxns, and a later one with reverseTxnsAsync, the latter call abandons the earlier locks, too", async () => {
793
+ const elementId1 = IModelTestUtils.queryByUserLabel(bc, "PhysicalObject2");
794
+ const elementId2 = IModelTestUtils.queryByUserLabel(bc, "ChildObject1B");
795
+ await locks.acquireLocks({ exclusive: elementId1 });
796
+ const element1 = bc.elements.getElement(elementId1);
797
+ await withEditTxn(bc, async (txn) => {
798
+ element1.setUserProperties("foo", Guid.createValue());
799
+ element1.update(txn);
800
+ });
801
+ await locks.acquireLocks({ exclusive: elementId2 });
802
+ const element2 = bc.elements.getElement(elementId2);
803
+ await withEditTxn(bc, async (txn) => {
804
+ element2.setUserProperties("bar", Guid.createValue());
805
+ element2.update(txn);
806
+ });
807
+ expect(locks.holdsExclusiveLock(elementId1)).to.be.true;
808
+ expect(locks.holdsExclusiveLock(elementId2)).to.be.true;
809
+ // Reverse the later txn using reverseTxns (no lock abandonment).
810
+ bc.txns.reverseTxns(1);
811
+ expect(locks.holdsExclusiveLock(elementId1)).to.be.true;
812
+ expect(locks.holdsExclusiveLock(elementId2)).to.be.true;
813
+ // Reverse the earlier txn using reverseTxnsAsync.
814
+ // This should also abandon locks for the already-reversed later txn.
815
+ await bc.txns.reverseTxnsAsync(1);
816
+ expect(locks.holdsExclusiveLock(elementId1)).to.be.false;
817
+ expect(locks.holdsExclusiveLock(elementId2)).to.be.false;
818
+ });
819
+ });
820
+ describe("reverseSingleTxnAsync", () => {
821
+ it("reverses a single txn and abandons its locks", async () => {
822
+ const elementId = IModelTestUtils.queryByUserLabel(bc, "ChildObject1B");
823
+ await locks.acquireLocks({ exclusive: elementId });
824
+ const element = bc.elements.getElement(elementId);
825
+ const originalProps = element.getUserProperties("foo");
826
+ await withEditTxn(bc, async (txn) => {
827
+ element.setUserProperties("foo", Guid.createValue());
828
+ element.update(txn);
829
+ });
830
+ expect(locks.holdsExclusiveLock(elementId)).to.be.true;
831
+ await bc.txns.reverseSingleTxnAsync();
832
+ expect(locks.holdsExclusiveLock(elementId)).to.be.false;
833
+ // Verify the element change was actually reversed.
834
+ const revertedElement = bc.elements.getElement(elementId);
835
+ expect(revertedElement.getUserProperties("foo")).to.deep.equal(originalProps);
836
+ });
837
+ });
838
+ describe("reverseAllTxnsAsync", () => {
839
+ it("reverses all txns and abandons all their locks", async () => {
840
+ const elementId1 = IModelTestUtils.queryByUserLabel(bc, "PhysicalObject2");
841
+ const elementId2 = IModelTestUtils.queryByUserLabel(bc, "ChildObject1B");
842
+ const orig1 = bc.elements.getElement(elementId1).getUserProperties("foo");
843
+ const orig2 = bc.elements.getElement(elementId2).getUserProperties("bar");
844
+ await locks.acquireLocks({ exclusive: elementId1 });
845
+ const element1 = bc.elements.getElement(elementId1);
846
+ await withEditTxn(bc, async (txn) => {
847
+ element1.setUserProperties("foo", Guid.createValue());
848
+ element1.update(txn);
849
+ });
850
+ await locks.acquireLocks({ exclusive: elementId2 });
851
+ const element2 = bc.elements.getElement(elementId2);
852
+ await withEditTxn(bc, async (txn) => {
853
+ element2.setUserProperties("bar", Guid.createValue());
854
+ element2.update(txn);
855
+ });
856
+ expect(locks.holdsExclusiveLock(elementId1)).to.be.true;
857
+ expect(locks.holdsExclusiveLock(elementId2)).to.be.true;
858
+ await bc.txns.reverseAllTxnsAsync();
859
+ expect(locks.holdsExclusiveLock(elementId1)).to.be.false;
860
+ expect(locks.holdsExclusiveLock(elementId2)).to.be.false;
861
+ // Verify the element changes were actually reversed.
862
+ expect(bc.elements.getElement(elementId1).getUserProperties("foo")).to.deep.equal(orig1);
863
+ expect(bc.elements.getElement(elementId2).getUserProperties("bar")).to.deep.equal(orig2);
864
+ });
865
+ });
866
+ describe("reverseToTxnAsync", () => {
867
+ it("reverses to a specific txn and abandons locks for all reversed txns", async () => {
868
+ const elementId1 = IModelTestUtils.queryByUserLabel(bc, "PhysicalObject2");
869
+ const elementId2 = IModelTestUtils.queryByUserLabel(bc, "ChildObject1B");
870
+ const origProps2 = bc.elements.getElement(elementId2).getUserProperties("bar");
871
+ await locks.acquireLocks({ exclusive: elementId1 });
872
+ const element1 = bc.elements.getElement(elementId1);
873
+ await withEditTxn(bc, async (txn) => {
874
+ element1.setUserProperties("foo", Guid.createValue());
875
+ element1.update(txn);
876
+ });
877
+ const txnAfterFirst = bc.txns.getCurrentTxnId();
878
+ await locks.acquireLocks({ exclusive: elementId2 });
879
+ const element2 = bc.elements.getElement(elementId2);
880
+ await withEditTxn(bc, async (txn) => {
881
+ element2.setUserProperties("bar", Guid.createValue());
882
+ element2.update(txn);
883
+ });
884
+ expect(locks.holdsExclusiveLock(elementId1)).to.be.true;
885
+ expect(locks.holdsExclusiveLock(elementId2)).to.be.true;
886
+ await bc.txns.reverseToTxnAsync(txnAfterFirst);
887
+ expect(locks.holdsExclusiveLock(elementId1)).to.be.true;
888
+ expect(locks.holdsExclusiveLock(elementId2)).to.be.false;
889
+ // Verify only the second element's changes were reversed.
890
+ expect(bc.elements.getElement(elementId2).getUserProperties("bar")).to.deep.equal(origProps2);
891
+ });
892
+ });
893
+ describe("cancelToTxnAsync", () => {
894
+ it("cancels to a specific txn and abandons locks for all cancelled txns", async () => {
895
+ const elementId1 = IModelTestUtils.queryByUserLabel(bc, "PhysicalObject2");
896
+ const elementId2 = IModelTestUtils.queryByUserLabel(bc, "ChildObject1B");
897
+ const origProps2 = bc.elements.getElement(elementId2).getUserProperties("bar");
898
+ await locks.acquireLocks({ exclusive: elementId1 });
899
+ const element1 = bc.elements.getElement(elementId1);
900
+ await withEditTxn(bc, async (txn) => {
901
+ element1.setUserProperties("foo", Guid.createValue());
902
+ element1.update(txn);
903
+ });
904
+ const txnAfterFirst = bc.txns.getCurrentTxnId();
905
+ await locks.acquireLocks({ exclusive: elementId2 });
906
+ const element2 = bc.elements.getElement(elementId2);
907
+ await withEditTxn(bc, async (txn) => {
908
+ element2.setUserProperties("bar", Guid.createValue());
909
+ element2.update(txn);
910
+ });
911
+ expect(locks.holdsExclusiveLock(elementId1)).to.be.true;
912
+ expect(locks.holdsExclusiveLock(elementId2)).to.be.true;
913
+ await bc.txns.cancelToTxnAsync(txnAfterFirst);
914
+ expect(locks.holdsExclusiveLock(elementId1)).to.be.true;
915
+ expect(locks.holdsExclusiveLock(elementId2)).to.be.false;
916
+ // Verify the second element's changes were cancelled.
917
+ expect(bc.elements.getElement(elementId2).getUserProperties("bar")).to.deep.equal(origProps2);
918
+ // cancelTo should not allow redo
919
+ expect(bc.txns.isRedoPossible).to.be.false;
920
+ });
921
+ it("after regular cancelTo, locks can be abandoned, but not re-acquired", async () => {
922
+ const elementId1 = IModelTestUtils.queryByUserLabel(bc, "PhysicalObject2");
923
+ const txnId = bc.txns.getCurrentTxnId();
924
+ await locks.acquireLocks({ exclusive: elementId1 });
925
+ const element1 = bc.elements.getElement(elementId1);
926
+ await withEditTxn(bc, async (txn) => {
927
+ element1.setUserProperties("foo", Guid.createValue());
928
+ element1.update(txn);
929
+ });
930
+ // Use the regular cancelTo which does not abandon locks.
931
+ bc.txns.cancelTo(txnId);
932
+ // Now try to abandon the locks, which should work.
933
+ expect(await locks.abandonLocksForReversedTxn(txnId)).to.be.true;
934
+ expect(locks.holdsExclusiveLock(elementId1)).to.be.false;
935
+ // However, it doesn't make sense to reacquire these locks because the Txn no longer exists.
936
+ await expect(locks.acquireLocksForReinstatingTxn(txnId)).to.eventually.be.rejectedWith("does not exist");
937
+ });
938
+ it("canceling a txn prevents subsequent reacquisition of that txn's locks", async () => {
939
+ const elementId = IModelTestUtils.queryByUserLabel(bc, "ChildObject1B");
940
+ const txnBefore = bc.txns.getCurrentTxnId();
941
+ await locks.acquireLocks({ exclusive: elementId });
942
+ const element = bc.elements.getElement(elementId);
943
+ await withEditTxn(bc, async (txn) => {
944
+ element.setUserProperties("foo", Guid.createValue());
945
+ element.update(txn);
946
+ });
947
+ await bc.txns.cancelToTxnAsync(txnBefore);
948
+ expect(locks.holdsExclusiveLock(elementId)).to.be.false;
949
+ // Attempting to acquire locks for the cancelled transaction should fail
950
+ // because the transaction itself no longer exists and its lock records have been cleared.
951
+ await expect(locks.acquireLocksForReinstatingTxn(txnBefore)).to.eventually.be.rejectedWith("does not exist");
952
+ });
953
+ it("reverses but does not cancel if lock abandonment fails", async () => {
954
+ const elementId = IModelTestUtils.queryByUserLabel(bc, "ChildObject1B");
955
+ const txnBefore = bc.txns.getCurrentTxnId();
956
+ await locks.acquireLocks({ exclusive: elementId });
957
+ const element = bc.elements.getElement(elementId);
958
+ await withEditTxn(bc, async (txn) => {
959
+ element.setUserProperties("foo", Guid.createValue());
960
+ element.update(txn);
961
+ });
962
+ const error = new IModelError(IModelStatus.BadRequest, "Lock abandonment failed");
963
+ sinonStub(locks, "abandonLocksForReversedTxn").rejects(error);
964
+ await expect(bc.txns.cancelToTxnAsync(txnBefore)).to.eventually.be.rejectedWith(IModelError, "Lock abandonment failed");
965
+ // The txn was reversed but not canceled, so we can reinstate. Locks are still held.
966
+ expect(bc.txns.isRedoPossible).to.be.true;
967
+ expect(locks.holdsExclusiveLock(elementId)).to.be.true;
968
+ // And now we can try releasing the locks again.
969
+ sinonRestore();
970
+ await bc.locks.abandonLocksForReversedTxn(txnBefore);
971
+ expect(locks.holdsExclusiveLock(elementId)).to.be.false;
972
+ // And cancel the already-reversed txn.
973
+ expect(bc.txns.cancelTo(txnBefore)).to.equal(IModelStatus.NothingToUndo);
974
+ expect(bc.txns.isRedoPossible).to.be.false;
975
+ });
976
+ });
977
+ describe("reinstateTxnAndAcquireLocks", () => {
978
+ it("reinstates a reversed txn and reacquires its locks", async () => {
979
+ const elementId = IModelTestUtils.queryByUserLabel(bc, "ChildObject1B");
980
+ await locks.acquireLocks({ exclusive: elementId });
981
+ const element = bc.elements.getElement(elementId);
982
+ const originalProps = element.getUserProperties("foo");
983
+ const newValue = Guid.createValue();
984
+ await withEditTxn(bc, async (txn) => {
985
+ element.setUserProperties("foo", newValue);
986
+ element.update(txn);
987
+ });
988
+ expect(locks.holdsExclusiveLock(elementId)).to.be.true;
989
+ await bc.txns.reverseTxnsAsync(1);
990
+ expect(locks.holdsExclusiveLock(elementId)).to.be.false;
991
+ // Verify the element change was reversed.
992
+ expect(bc.elements.getElement(elementId).getUserProperties("foo")).to.deep.equal(originalProps);
993
+ await bc.txns.reinstateTxnAsync();
994
+ expect(locks.holdsExclusiveLock(elementId)).to.be.true;
995
+ // Verify the element change was reinstated.
996
+ expect(bc.elements.getElement(elementId).getUserProperties("foo")).to.equal(newValue);
997
+ });
998
+ it("multiple txns reversed together are reinstated as one", async () => {
999
+ const elementId1 = IModelTestUtils.queryByUserLabel(bc, "PhysicalObject2");
1000
+ const elementId2 = IModelTestUtils.queryByUserLabel(bc, "ChildObject1B");
1001
+ const orig1 = bc.elements.getElement(elementId1).getUserProperties("foo");
1002
+ const orig2 = bc.elements.getElement(elementId2).getUserProperties("bar");
1003
+ await locks.acquireLocks({ exclusive: elementId1 });
1004
+ const element1 = bc.elements.getElement(elementId1);
1005
+ const newValue1 = Guid.createValue();
1006
+ await withEditTxn(bc, async (txn) => {
1007
+ element1.setUserProperties("foo", newValue1);
1008
+ element1.update(txn);
1009
+ });
1010
+ await locks.acquireLocks({ exclusive: elementId2 });
1011
+ const element2 = bc.elements.getElement(elementId2);
1012
+ const newValue2 = Guid.createValue();
1013
+ await withEditTxn(bc, async (txn) => {
1014
+ element2.setUserProperties("bar", newValue2);
1015
+ element2.update(txn);
1016
+ });
1017
+ await bc.txns.reverseTxnsAsync(2);
1018
+ expect(locks.holdsExclusiveLock(elementId1)).to.be.false;
1019
+ expect(locks.holdsExclusiveLock(elementId2)).to.be.false;
1020
+ // Verify both element changes were reversed.
1021
+ expect(bc.elements.getElement(elementId1).getUserProperties("foo")).to.deep.equal(orig1);
1022
+ expect(bc.elements.getElement(elementId2).getUserProperties("bar")).to.deep.equal(orig2);
1023
+ // A single reinstate should bring back both txns and reacquire all locks.
1024
+ await bc.txns.reinstateTxnAsync();
1025
+ expect(locks.holdsExclusiveLock(elementId1)).to.be.true;
1026
+ expect(locks.holdsExclusiveLock(elementId2)).to.be.true;
1027
+ // Verify both element changes are reinstated.
1028
+ expect(bc.elements.getElement(elementId1).getUserProperties("foo")).to.equal(newValue1);
1029
+ expect(bc.elements.getElement(elementId2).getUserProperties("bar")).to.equal(newValue2);
1030
+ });
1031
+ it("abandons unsaved changes before reinstatement", async () => {
1032
+ const elementId1 = IModelTestUtils.queryByUserLabel(bc, "PhysicalObject2");
1033
+ const elementId2 = IModelTestUtils.queryByUserLabel(bc, "ChildObject1B");
1034
+ // Make a change, save it, and reverse it.
1035
+ await locks.acquireLocks({ exclusive: elementId1 });
1036
+ const element1 = bc.elements.getElement(elementId1);
1037
+ const originalProps1 = element1.getUserProperties("foo");
1038
+ const newValue1 = Guid.createValue();
1039
+ await withEditTxn(bc, async (txn) => {
1040
+ element1.setUserProperties("foo", newValue1);
1041
+ element1.update(txn);
1042
+ });
1043
+ expect(locks.holdsExclusiveLock(elementId1)).to.be.true;
1044
+ await bc.txns.reverseTxnsAsync(1);
1045
+ expect(locks.holdsExclusiveLock(elementId1)).to.be.false;
1046
+ // Verify the element change was reversed.
1047
+ expect(bc.elements.getElement(elementId1).getUserProperties("foo")).to.deep.equal(originalProps1);
1048
+ // Now make an unsaved change to a different element.
1049
+ await locks.acquireLocks({ exclusive: elementId2 });
1050
+ const element2 = bc.elements.getElement(elementId2);
1051
+ const originalProps2 = element2.getUserProperties("bar");
1052
+ const newValue2 = Guid.createValue();
1053
+ await withEditTxn(bc, async (txn) => {
1054
+ element2.setUserProperties("bar", newValue2);
1055
+ element2.update(txn);
1056
+ // Verify the unsaved change is present and lock is held.
1057
+ expect(bc.txns.hasUnsavedChanges).to.be.true;
1058
+ expect(locks.holdsExclusiveLock(elementId2)).to.be.true;
1059
+ expect(bc.elements.getElement(elementId2).getUserProperties("bar")).to.equal(newValue2);
1060
+ // Reinstate the first txn. This should:
1061
+ // 1. Abandon the unsaved change to element2
1062
+ // 2. Abandon the lock on element2
1063
+ // 3. Reinstate the change to element1
1064
+ // 4. Reacquire the lock on element1
1065
+ await bc.txns.reinstateTxnAsync();
1066
+ // Verify the unsaved change was abandoned.
1067
+ expect(bc.txns.hasUnsavedChanges).to.be.false;
1068
+ expect(bc.elements.getElement(elementId2).getUserProperties("bar")).to.deep.equal(originalProps2);
1069
+ expect(locks.holdsExclusiveLock(elementId2)).to.be.false;
1070
+ // Verify the first change was reinstated and its lock reacquired.
1071
+ expect(bc.elements.getElement(elementId1).getUserProperties("foo")).to.equal(newValue1);
1072
+ expect(locks.holdsExclusiveLock(elementId1)).to.be.true;
1073
+ });
1074
+ });
1075
+ describe("throws and leaves locks acquired if reinstateTxn fails", async () => {
1076
+ let elementId;
1077
+ let fooValue;
1078
+ beforeEach(async () => {
1079
+ elementId = IModelTestUtils.queryByUserLabel(bc, "ChildObject1B");
1080
+ await locks.acquireLocks({ exclusive: elementId });
1081
+ const element = bc.elements.getElement(elementId);
1082
+ fooValue = Guid.createValue();
1083
+ await withEditTxn(bc, async (txn) => {
1084
+ element.setUserProperties("foo", fooValue);
1085
+ element.update(txn);
1086
+ });
1087
+ await bc.txns.reverseTxnsAsync(1);
1088
+ expect(locks.holdsExclusiveLock(elementId)).to.be.false;
1089
+ sinonStub(bc.txns, "reinstateTxn").returns(IModelStatus.BadRequest);
1090
+ await expect(bc.txns.reinstateTxnAsync()).to.eventually.be.rejectedWith(IModelError, "Bad Request");
1091
+ // Even though it failed to reinstate, it obtained the lock and did not release it.
1092
+ expect(locks.holdsExclusiveLock(elementId)).to.be.true;
1093
+ });
1094
+ it("and we can try reinstating again, without any problems caused by the locks already being acquired", async () => {
1095
+ sinonRestore();
1096
+ await bc.txns.reinstateTxnAsync();
1097
+ expect(locks.holdsExclusiveLock(elementId)).to.be.true;
1098
+ expect(bc.elements.getElement(elementId).getUserProperties("foo")).to.equal(fooValue);
1099
+ });
1100
+ it("and we can then release the locks", async () => {
1101
+ await locks.abandonLocksForReversedTxn(bc.txns.getCurrentTxnId());
1102
+ expect(locks.holdsExclusiveLock(elementId)).to.be.false;
1103
+ });
1104
+ });
1105
+ it("throws and does not reinstate if acquireLocksForReinstatingTxn fails", async () => {
1106
+ const elementId = IModelTestUtils.queryByUserLabel(bc, "ChildObject1B");
1107
+ await locks.acquireLocks({ exclusive: elementId });
1108
+ const element = bc.elements.getElement(elementId);
1109
+ const originalProps = element.getUserProperties("foo");
1110
+ const newValue = Guid.createValue();
1111
+ await withEditTxn(bc, async (txn) => {
1112
+ element.setUserProperties("foo", newValue);
1113
+ element.update(txn);
1114
+ });
1115
+ await bc.txns.reverseTxnsAsync(1);
1116
+ expect(locks.holdsExclusiveLock(elementId)).to.be.false;
1117
+ // Verify the element change was reversed.
1118
+ expect(bc.elements.getElement(elementId).getUserProperties("foo")).to.deep.equal(originalProps);
1119
+ // Simulate acquireLocksForReinstatingTxn failing (e.g. because another briefcase holds the lock)
1120
+ const error = new LockConflict(0x12345, "other briefcase alias", "exclusive lock is already held");
1121
+ sinonStub(locks, "acquireLocksForReinstatingTxn").rejects(error);
1122
+ await expect(bc.txns.reinstateTxnAsync()).to.eventually.be.rejectedWith("exclusive lock is already held");
1123
+ // Verify it was NOT reinstated
1124
+ expect(bc.elements.getElement(elementId).getUserProperties("foo")).to.deep.equal(originalProps);
1125
+ });
1126
+ it("new changes after reversal truncate the redo stack and clear reversible lock records", async () => {
1127
+ const elementId1 = IModelTestUtils.queryByUserLabel(bc, "PhysicalObject2");
1128
+ const elementId2 = IModelTestUtils.queryByUserLabel(bc, "ChildObject1B");
1129
+ // 1. Make a change to element 1 and save it.
1130
+ await locks.acquireLocks({ exclusive: elementId1 });
1131
+ const element1 = bc.elements.getElement(elementId1);
1132
+ await withEditTxn(bc, async (txn) => {
1133
+ element1.setUserProperties("foo", Guid.createValue());
1134
+ element1.update(txn);
1135
+ });
1136
+ const txn1Id = bc.txns.getCurrentTxnId();
1137
+ // 2. Reverse the txn and abandon locks.
1138
+ await bc.txns.reverseTxnsAsync(1);
1139
+ expect(locks.holdsExclusiveLock(elementId1)).to.be.false;
1140
+ expect(bc.txns.isRedoPossible).to.be.true;
1141
+ // 3. Make a change to element 2 and save it. This truncates the redo stack.
1142
+ await locks.acquireLocks({ exclusive: elementId2 });
1143
+ const element2 = bc.elements.getElement(elementId2);
1144
+ await withEditTxn(bc, async (txn) => {
1145
+ element2.setUserProperties("bar", Guid.createValue());
1146
+ element2.update(txn);
1147
+ });
1148
+ // The redo stack should now be truncated.
1149
+ expect(bc.txns.isRedoPossible).to.be.false;
1150
+ // 4. Try to reacquire locks for the truncated transaction.
1151
+ await expect(locks.acquireLocksForReinstatingTxn(txn1Id)).to.eventually.be.rejectedWith("does not exist");
1152
+ });
1153
+ it("abandoned changes after reversal do not prevent reinstatement", async () => {
1154
+ const elementId1 = IModelTestUtils.queryByUserLabel(bc, "PhysicalObject2");
1155
+ const elementId2 = IModelTestUtils.queryByUserLabel(bc, "ChildObject1B");
1156
+ // 1. Make a change to element 1 and save it.
1157
+ await locks.acquireLocks({ exclusive: elementId1 });
1158
+ const element1 = bc.elements.getElement(elementId1);
1159
+ const newValue1 = Guid.createValue();
1160
+ await withEditTxn(bc, async (txn) => {
1161
+ element1.setUserProperties("foo", newValue1);
1162
+ element1.update(txn);
1163
+ });
1164
+ // 2. Reverse the txn and abandon locks.
1165
+ await bc.txns.reverseTxnsAsync(1);
1166
+ expect(locks.holdsExclusiveLock(elementId1)).to.be.false;
1167
+ expect(bc.txns.isRedoPossible).to.be.true;
1168
+ // 3. Make a change to element 2 and abandon it.
1169
+ await locks.acquireLocks({ exclusive: elementId2 });
1170
+ const element2 = bc.elements.getElement(elementId2);
1171
+ await withEditTxn(bc, async (txn) => {
1172
+ element2.setUserProperties("bar", Guid.createValue());
1173
+ element2.update(txn);
1174
+ txn.abandonChanges();
1175
+ });
1176
+ expect(bc.txns.isRedoPossible).to.be.true;
1177
+ // 4. Reinstate should still work.
1178
+ await bc.txns.reinstateTxnAsync();
1179
+ expect(locks.holdsExclusiveLock(elementId1)).to.be.true;
1180
+ expect(bc.elements.getElement(elementId1).getUserProperties("foo")).to.equal(newValue1);
1181
+ });
1182
+ });
1183
+ });
278
1184
  });
279
1185
  //# sourceMappingURL=ServerBasedLocks.test.js.map