@itwin/core-backend 5.5.0-dev.1 → 5.5.0-dev.2

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 (381) hide show
  1. package/lib/cjs/BackendHubAccess.js.map +1 -1
  2. package/lib/cjs/BackendLoggerCategory.js.map +1 -1
  3. package/lib/cjs/BisCoreSchema.js.map +1 -1
  4. package/lib/cjs/BlobContainerService.js.map +1 -1
  5. package/lib/cjs/BriefcaseManager.js.map +1 -1
  6. package/lib/cjs/CatalogDb.js.map +1 -1
  7. package/lib/cjs/Category.js.map +1 -1
  8. package/lib/cjs/ChangeSummaryManager.js +2 -2
  9. package/lib/cjs/ChangeSummaryManager.js.map +1 -1
  10. package/lib/cjs/ChangedElementsDb.js.map +1 -1
  11. package/lib/cjs/ChangesetECAdaptor.js +248 -248
  12. package/lib/cjs/ChangesetECAdaptor.js.map +1 -1
  13. package/lib/cjs/ChannelControl.js.map +1 -1
  14. package/lib/cjs/CheckpointManager.js.map +1 -1
  15. package/lib/cjs/ClassRegistry.js +5 -5
  16. package/lib/cjs/ClassRegistry.js.map +1 -1
  17. package/lib/cjs/CloudSqlite.js.map +1 -1
  18. package/lib/cjs/CodeService.js.map +1 -1
  19. package/lib/cjs/CodeSpecs.js.map +1 -1
  20. package/lib/cjs/ConcurrentQuery.js.map +1 -1
  21. package/lib/cjs/CustomViewState3dCreator.js.map +1 -1
  22. package/lib/cjs/DevTools.js.map +1 -1
  23. package/lib/cjs/DisplayStyle.js.map +1 -1
  24. package/lib/cjs/ECDb.js.map +1 -1
  25. package/lib/cjs/ECSchemaXmlContext.js.map +1 -1
  26. package/lib/cjs/ECSqlStatement.js.map +1 -1
  27. package/lib/cjs/Element.js.map +1 -1
  28. package/lib/cjs/ElementAspect.js.map +1 -1
  29. package/lib/cjs/ElementGraphics.js.map +1 -1
  30. package/lib/cjs/ElementTreeWalker.js.map +1 -1
  31. package/lib/cjs/Entity.js.map +1 -1
  32. package/lib/cjs/EntityReferences.js.map +1 -1
  33. package/lib/cjs/ExportGraphics.js.map +1 -1
  34. package/lib/cjs/ExternalSource.js.map +1 -1
  35. package/lib/cjs/FontFile.js.map +1 -1
  36. package/lib/cjs/GeoCoordConfig.js.map +1 -1
  37. package/lib/cjs/GeographicCRSServices.js.map +1 -1
  38. package/lib/cjs/GeometrySummary.js +47 -47
  39. package/lib/cjs/GeometrySummary.js.map +1 -1
  40. package/lib/cjs/IModelDb.js +8 -8
  41. package/lib/cjs/IModelDb.js.map +1 -1
  42. package/lib/cjs/IModelDbFonts.js.map +1 -1
  43. package/lib/cjs/IModelElementCloneContext.js.map +1 -1
  44. package/lib/cjs/IModelHost.js.map +1 -1
  45. package/lib/cjs/IModelIncrementalSchemaLocater.js.map +1 -1
  46. package/lib/cjs/IModelJsFs.js.map +1 -1
  47. package/lib/cjs/ImageSourceConversion.js.map +1 -1
  48. package/lib/cjs/IpcHost.js.map +1 -1
  49. package/lib/cjs/LineStyle.js.map +1 -1
  50. package/lib/cjs/LocalHub.js +1 -1
  51. package/lib/cjs/LocalHub.js.map +1 -1
  52. package/lib/cjs/LocalhostIpcHost.js.map +1 -1
  53. package/lib/cjs/LockControl.js.map +1 -1
  54. package/lib/cjs/Material.js.map +1 -1
  55. package/lib/cjs/Model.js.map +1 -1
  56. package/lib/cjs/NativeAppStorage.js.map +1 -1
  57. package/lib/cjs/NativeHost.js.map +1 -1
  58. package/lib/cjs/NavigationRelationship.js.map +1 -1
  59. package/lib/cjs/PromiseMemoizer.js.map +1 -1
  60. package/lib/cjs/PropertyStore.js.map +1 -1
  61. package/lib/cjs/Relationship.js.map +1 -1
  62. package/lib/cjs/RpcBackend.js.map +1 -1
  63. package/lib/cjs/SQLiteDb.js.map +1 -1
  64. package/lib/cjs/Schema.js.map +1 -1
  65. package/lib/cjs/SchemaSync.js.map +1 -1
  66. package/lib/cjs/SchemaUtils.js.map +1 -1
  67. package/lib/cjs/SheetIndex.js.map +1 -1
  68. package/lib/cjs/SqliteChangesetReader.js.map +1 -1
  69. package/lib/cjs/SqliteStatement.js.map +1 -1
  70. package/lib/cjs/StashManager.js.map +1 -1
  71. package/lib/cjs/Texture.js.map +1 -1
  72. package/lib/cjs/TileStorage.js.map +1 -1
  73. package/lib/cjs/TxnManager.js.map +1 -1
  74. package/lib/cjs/ViewDefinition.js.map +1 -1
  75. package/lib/cjs/ViewStateHydrator.js.map +1 -1
  76. package/lib/cjs/ViewStore.js.map +1 -1
  77. package/lib/cjs/annotations/ElementDrivesTextAnnotation.js.map +1 -1
  78. package/lib/cjs/annotations/FrameGeometry.js.map +1 -1
  79. package/lib/cjs/annotations/LeaderGeometry.js.map +1 -1
  80. package/lib/cjs/annotations/TextAnnotationElement.js.map +1 -1
  81. package/lib/cjs/annotations/TextAnnotationGeometry.js.map +1 -1
  82. package/lib/cjs/annotations/TextBlockGeometry.js.map +1 -1
  83. package/lib/cjs/annotations/TextBlockLayout.js.map +1 -1
  84. package/lib/cjs/assets/IModelChange.02.00.00.ecschema.xml +90 -90
  85. package/lib/cjs/assets/Settings/Schemas/Base.Schema.json +32 -32
  86. package/lib/cjs/assets/Settings/Schemas/Gcs.schema.json +27 -27
  87. package/lib/cjs/assets/Settings/Schemas/Workspace.Schema.json +94 -94
  88. package/lib/cjs/assets/Settings/backend.setting.json5 +21 -21
  89. package/lib/cjs/core-backend.js.map +1 -1
  90. package/lib/cjs/domains/FunctionalElements.js.map +1 -1
  91. package/lib/cjs/domains/FunctionalSchema.js.map +1 -1
  92. package/lib/cjs/domains/GenericElements.js.map +1 -1
  93. package/lib/cjs/domains/GenericSchema.js.map +1 -1
  94. package/lib/cjs/internal/ChangesetConflictArgs.js.map +1 -1
  95. package/lib/cjs/internal/ChannelAdmin.js.map +1 -1
  96. package/lib/cjs/internal/ElementLRUCache.js.map +1 -1
  97. package/lib/cjs/internal/FontFileImpl.js.map +1 -1
  98. package/lib/cjs/internal/HubMock.js.map +1 -1
  99. package/lib/cjs/internal/IModelDbFontsImpl.js.map +1 -1
  100. package/lib/cjs/internal/NativePlatform.js.map +1 -1
  101. package/lib/cjs/internal/NoLocks.js.map +1 -1
  102. package/lib/cjs/internal/OnlineStatus.js.map +1 -1
  103. package/lib/cjs/internal/ServerBasedLocks.js.map +1 -1
  104. package/lib/cjs/internal/Symbols.js.map +1 -1
  105. package/lib/cjs/internal/annotations/fields.js.map +1 -1
  106. package/lib/cjs/internal/cross-package.js.map +1 -1
  107. package/lib/cjs/internal/workspace/SettingsImpl.js.map +1 -1
  108. package/lib/cjs/internal/workspace/SettingsSchemasImpl.js.map +1 -1
  109. package/lib/cjs/internal/workspace/WorkspaceImpl.js.map +1 -1
  110. package/lib/cjs/internal/workspace/WorkspaceSqliteDb.js.map +1 -1
  111. package/lib/cjs/rpc/multipart.js.map +1 -1
  112. package/lib/cjs/rpc/tracing.js.map +1 -1
  113. package/lib/cjs/rpc/web/logging.js.map +1 -1
  114. package/lib/cjs/rpc/web/request.js.map +1 -1
  115. package/lib/cjs/rpc/web/response.js.map +1 -1
  116. package/lib/cjs/rpc-impl/DevToolsRpcImpl.js.map +1 -1
  117. package/lib/cjs/rpc-impl/IModelReadRpcImpl.js.map +1 -1
  118. package/lib/cjs/rpc-impl/IModelTileRpcImpl.js.map +1 -1
  119. package/lib/cjs/rpc-impl/RpcBriefcaseUtility.js.map +1 -1
  120. package/lib/cjs/rpc-impl/SnapshotIModelRpcImpl.js.map +1 -1
  121. package/lib/cjs/workspace/Settings.js.map +1 -1
  122. package/lib/cjs/workspace/SettingsSchemas.js.map +1 -1
  123. package/lib/cjs/workspace/Workspace.js.map +1 -1
  124. package/lib/cjs/workspace/WorkspaceEditor.js.map +1 -1
  125. package/lib/esm/BackendHubAccess.js.map +1 -1
  126. package/lib/esm/BackendLoggerCategory.js.map +1 -1
  127. package/lib/esm/BisCoreSchema.js.map +1 -1
  128. package/lib/esm/BlobContainerService.js.map +1 -1
  129. package/lib/esm/BriefcaseManager.js.map +1 -1
  130. package/lib/esm/CatalogDb.js.map +1 -1
  131. package/lib/esm/Category.js.map +1 -1
  132. package/lib/esm/ChangeSummaryManager.js +2 -2
  133. package/lib/esm/ChangeSummaryManager.js.map +1 -1
  134. package/lib/esm/ChangedElementsDb.js.map +1 -1
  135. package/lib/esm/ChangesetECAdaptor.js +248 -248
  136. package/lib/esm/ChangesetECAdaptor.js.map +1 -1
  137. package/lib/esm/ChannelControl.js.map +1 -1
  138. package/lib/esm/CheckpointManager.js.map +1 -1
  139. package/lib/esm/ClassRegistry.js +5 -5
  140. package/lib/esm/ClassRegistry.js.map +1 -1
  141. package/lib/esm/CloudSqlite.js.map +1 -1
  142. package/lib/esm/CodeService.js.map +1 -1
  143. package/lib/esm/CodeSpecs.js.map +1 -1
  144. package/lib/esm/ConcurrentQuery.js.map +1 -1
  145. package/lib/esm/CustomViewState3dCreator.js.map +1 -1
  146. package/lib/esm/DevTools.js.map +1 -1
  147. package/lib/esm/DisplayStyle.js.map +1 -1
  148. package/lib/esm/ECDb.js.map +1 -1
  149. package/lib/esm/ECSchemaXmlContext.js.map +1 -1
  150. package/lib/esm/ECSqlStatement.js.map +1 -1
  151. package/lib/esm/Element.js.map +1 -1
  152. package/lib/esm/ElementAspect.js.map +1 -1
  153. package/lib/esm/ElementGraphics.js.map +1 -1
  154. package/lib/esm/ElementTreeWalker.js.map +1 -1
  155. package/lib/esm/Entity.js.map +1 -1
  156. package/lib/esm/EntityReferences.js.map +1 -1
  157. package/lib/esm/ExportGraphics.js.map +1 -1
  158. package/lib/esm/ExternalSource.js.map +1 -1
  159. package/lib/esm/FontFile.js.map +1 -1
  160. package/lib/esm/GeoCoordConfig.js.map +1 -1
  161. package/lib/esm/GeographicCRSServices.js.map +1 -1
  162. package/lib/esm/GeometrySummary.js +47 -47
  163. package/lib/esm/GeometrySummary.js.map +1 -1
  164. package/lib/esm/IModelDb.js +8 -8
  165. package/lib/esm/IModelDb.js.map +1 -1
  166. package/lib/esm/IModelDbFonts.js.map +1 -1
  167. package/lib/esm/IModelElementCloneContext.js.map +1 -1
  168. package/lib/esm/IModelHost.js.map +1 -1
  169. package/lib/esm/IModelIncrementalSchemaLocater.js.map +1 -1
  170. package/lib/esm/IModelJsFs.js.map +1 -1
  171. package/lib/esm/ImageSourceConversion.js.map +1 -1
  172. package/lib/esm/IpcHost.js.map +1 -1
  173. package/lib/esm/LineStyle.js.map +1 -1
  174. package/lib/esm/LocalHub.js +1 -1
  175. package/lib/esm/LocalHub.js.map +1 -1
  176. package/lib/esm/LocalhostIpcHost.js.map +1 -1
  177. package/lib/esm/LockControl.js.map +1 -1
  178. package/lib/esm/Material.js.map +1 -1
  179. package/lib/esm/Model.js.map +1 -1
  180. package/lib/esm/NativeAppStorage.js.map +1 -1
  181. package/lib/esm/NativeHost.js.map +1 -1
  182. package/lib/esm/NavigationRelationship.js.map +1 -1
  183. package/lib/esm/PromiseMemoizer.js.map +1 -1
  184. package/lib/esm/PropertyStore.js.map +1 -1
  185. package/lib/esm/Relationship.js.map +1 -1
  186. package/lib/esm/RpcBackend.js.map +1 -1
  187. package/lib/esm/SQLiteDb.js.map +1 -1
  188. package/lib/esm/Schema.js.map +1 -1
  189. package/lib/esm/SchemaSync.js.map +1 -1
  190. package/lib/esm/SchemaUtils.js.map +1 -1
  191. package/lib/esm/SheetIndex.js.map +1 -1
  192. package/lib/esm/SqliteChangesetReader.js.map +1 -1
  193. package/lib/esm/SqliteStatement.js.map +1 -1
  194. package/lib/esm/StashManager.js.map +1 -1
  195. package/lib/esm/Texture.js.map +1 -1
  196. package/lib/esm/TileStorage.js.map +1 -1
  197. package/lib/esm/TxnManager.js.map +1 -1
  198. package/lib/esm/ViewDefinition.js.map +1 -1
  199. package/lib/esm/ViewStateHydrator.js.map +1 -1
  200. package/lib/esm/ViewStore.js.map +1 -1
  201. package/lib/esm/annotations/ElementDrivesTextAnnotation.js.map +1 -1
  202. package/lib/esm/annotations/FrameGeometry.js.map +1 -1
  203. package/lib/esm/annotations/LeaderGeometry.js.map +1 -1
  204. package/lib/esm/annotations/TextAnnotationElement.js.map +1 -1
  205. package/lib/esm/annotations/TextAnnotationGeometry.js.map +1 -1
  206. package/lib/esm/annotations/TextBlockGeometry.js.map +1 -1
  207. package/lib/esm/annotations/TextBlockLayout.js.map +1 -1
  208. package/lib/esm/core-backend.js.map +1 -1
  209. package/lib/esm/domains/FunctionalElements.js.map +1 -1
  210. package/lib/esm/domains/FunctionalSchema.js.map +1 -1
  211. package/lib/esm/domains/GenericElements.js.map +1 -1
  212. package/lib/esm/domains/GenericSchema.js.map +1 -1
  213. package/lib/esm/internal/ChangesetConflictArgs.js.map +1 -1
  214. package/lib/esm/internal/ChannelAdmin.js.map +1 -1
  215. package/lib/esm/internal/ElementLRUCache.js.map +1 -1
  216. package/lib/esm/internal/FontFileImpl.js.map +1 -1
  217. package/lib/esm/internal/HubMock.js.map +1 -1
  218. package/lib/esm/internal/IModelDbFontsImpl.js.map +1 -1
  219. package/lib/esm/internal/NativePlatform.js.map +1 -1
  220. package/lib/esm/internal/NoLocks.js.map +1 -1
  221. package/lib/esm/internal/OnlineStatus.js.map +1 -1
  222. package/lib/esm/internal/ServerBasedLocks.js.map +1 -1
  223. package/lib/esm/internal/Symbols.js.map +1 -1
  224. package/lib/esm/internal/annotations/fields.js.map +1 -1
  225. package/lib/esm/internal/cross-package.js.map +1 -1
  226. package/lib/esm/internal/workspace/SettingsImpl.js.map +1 -1
  227. package/lib/esm/internal/workspace/SettingsSchemasImpl.js.map +1 -1
  228. package/lib/esm/internal/workspace/WorkspaceImpl.js.map +1 -1
  229. package/lib/esm/internal/workspace/WorkspaceSqliteDb.js.map +1 -1
  230. package/lib/esm/rpc/multipart.js.map +1 -1
  231. package/lib/esm/rpc/tracing.js.map +1 -1
  232. package/lib/esm/rpc/web/logging.js.map +1 -1
  233. package/lib/esm/rpc/web/request.js.map +1 -1
  234. package/lib/esm/rpc/web/response.js.map +1 -1
  235. package/lib/esm/rpc-impl/DevToolsRpcImpl.js.map +1 -1
  236. package/lib/esm/rpc-impl/IModelReadRpcImpl.js.map +1 -1
  237. package/lib/esm/rpc-impl/IModelTileRpcImpl.js.map +1 -1
  238. package/lib/esm/rpc-impl/RpcBriefcaseUtility.js.map +1 -1
  239. package/lib/esm/rpc-impl/SnapshotIModelRpcImpl.js.map +1 -1
  240. package/lib/esm/test/AdvancedEqual.js.map +1 -1
  241. package/lib/esm/test/AnnotationTestUtils.js.map +1 -1
  242. package/lib/esm/test/AttachDb.test.js +11 -11
  243. package/lib/esm/test/AttachDb.test.js.map +1 -1
  244. package/lib/esm/test/ElementDrivesElement.test.js +23 -23
  245. package/lib/esm/test/ElementDrivesElement.test.js.map +1 -1
  246. package/lib/esm/test/ElementLRUCache.test.js.map +1 -1
  247. package/lib/esm/test/GeometryTestUtil.js.map +1 -1
  248. package/lib/esm/test/IModelHost.test.js.map +1 -1
  249. package/lib/esm/test/IModelTestUtils.js.map +1 -1
  250. package/lib/esm/test/ImageSourceConversion.test.js.map +1 -1
  251. package/lib/esm/test/IpcHost.test.js.map +1 -1
  252. package/lib/esm/test/KnownTestLocations.js.map +1 -1
  253. package/lib/esm/test/PrintElementTree.js.map +1 -1
  254. package/lib/esm/test/PropertyDb.test.js.map +1 -1
  255. package/lib/esm/test/RevisionUtility.js.map +1 -1
  256. package/lib/esm/test/SchemaUtils.test.js +25 -25
  257. package/lib/esm/test/SchemaUtils.test.js.map +1 -1
  258. package/lib/esm/test/SequentialLogMatcher.js.map +1 -1
  259. package/lib/esm/test/TestChangeSetUtility.js.map +1 -1
  260. package/lib/esm/test/TestUtils.js.map +1 -1
  261. package/lib/esm/test/annotations/Fields.test.js +53 -53
  262. package/lib/esm/test/annotations/Fields.test.js.map +1 -1
  263. package/lib/esm/test/annotations/FrameGeometry.test.js.map +1 -1
  264. package/lib/esm/test/annotations/LeaderGeometry.test.js.map +1 -1
  265. package/lib/esm/test/annotations/TextAnnotation.test.js.map +1 -1
  266. package/lib/esm/test/annotations/TextBlock.test.js.map +1 -1
  267. package/lib/esm/test/assets/IncrementalSchemaLocater/configs/old.config.js.map +1 -1
  268. package/lib/esm/test/assets/IncrementalSchemaLocater/configs/simple.config.js.map +1 -1
  269. package/lib/esm/test/categories/Category.test.js.map +1 -1
  270. package/lib/esm/test/codespec/CodeSpec.test.js.map +1 -1
  271. package/lib/esm/test/ecdb/CTE.test.js +88 -88
  272. package/lib/esm/test/ecdb/CTE.test.js.map +1 -1
  273. package/lib/esm/test/ecdb/ConcurrentQuery.test.js +15 -15
  274. package/lib/esm/test/ecdb/ConcurrentQuery.test.js.map +1 -1
  275. package/lib/esm/test/ecdb/ConcurrentQueryLoad.test.js +15 -15
  276. package/lib/esm/test/ecdb/ConcurrentQueryLoad.test.js.map +1 -1
  277. package/lib/esm/test/ecdb/ECDb.test.js +72 -72
  278. package/lib/esm/test/ecdb/ECDb.test.js.map +1 -1
  279. package/lib/esm/test/ecdb/ECDbTestHelper.js.map +1 -1
  280. package/lib/esm/test/ecdb/ECSchemaXmlContext.test.js.map +1 -1
  281. package/lib/esm/test/ecdb/ECSqlAst.test.js +65 -65
  282. package/lib/esm/test/ecdb/ECSqlAst.test.js.map +1 -1
  283. package/lib/esm/test/ecdb/ECSqlQuery.test.js.map +1 -1
  284. package/lib/esm/test/ecdb/ECSqlReader.test.js +16 -16
  285. package/lib/esm/test/ecdb/ECSqlReader.test.js.map +1 -1
  286. package/lib/esm/test/ecdb/ECSqlStatement.test.js +332 -332
  287. package/lib/esm/test/ecdb/ECSqlStatement.test.js.map +1 -1
  288. package/lib/esm/test/ecdb/SqliteStatement.test.js.map +1 -1
  289. package/lib/esm/test/ecsql/dataset/ECSqlDatasets.js.map +1 -1
  290. package/lib/esm/test/ecsql/src/ECSqlTestGenerator.js +21 -21
  291. package/lib/esm/test/ecsql/src/ECSqlTestGenerator.js.map +1 -1
  292. package/lib/esm/test/ecsql/src/ECSqlTestParser.js.map +1 -1
  293. package/lib/esm/test/ecsql/src/ECSqlTestRunner.test.js.map +1 -1
  294. package/lib/esm/test/element/DeleteDefinitionElements.test.js.map +1 -1
  295. package/lib/esm/test/element/ElementAspect.test.js +22 -22
  296. package/lib/esm/test/element/ElementAspect.test.js.map +1 -1
  297. package/lib/esm/test/element/ElementDependencyGraph.test.js.map +1 -1
  298. package/lib/esm/test/element/ElementRoundTrip.test.js +139 -139
  299. package/lib/esm/test/element/ElementRoundTrip.test.js.map +1 -1
  300. package/lib/esm/test/element/ExcludedElements.test.js.map +1 -1
  301. package/lib/esm/test/element/ExternalSource.test.js.map +1 -1
  302. package/lib/esm/test/element/NullStructArray.test.js +13 -13
  303. package/lib/esm/test/element/NullStructArray.test.js.map +1 -1
  304. package/lib/esm/test/element/ProjectInformationRecord.test.js.map +1 -1
  305. package/lib/esm/test/element/SheetInformationAspect.test.js.map +1 -1
  306. package/lib/esm/test/element/UrlLink.test.js.map +1 -1
  307. package/lib/esm/test/font/FontFile.test.js.map +1 -1
  308. package/lib/esm/test/font/IModelDbFonts.test.js.map +1 -1
  309. package/lib/esm/test/hubaccess/ApplyChangeset.test.js +32 -32
  310. package/lib/esm/test/hubaccess/ApplyChangeset.test.js.map +1 -1
  311. package/lib/esm/test/hubaccess/BriefcaseManager.test.js.map +1 -1
  312. package/lib/esm/test/hubaccess/CheckpointManager.test.js.map +1 -1
  313. package/lib/esm/test/hubaccess/Rebase.test.js +40 -40
  314. package/lib/esm/test/hubaccess/Rebase.test.js.map +1 -1
  315. package/lib/esm/test/imageData.js.map +1 -1
  316. package/lib/esm/test/imodel/Code.test.js.map +1 -1
  317. package/lib/esm/test/imodel/ElementTreeWalker.test.js.map +1 -1
  318. package/lib/esm/test/imodel/GetTextureImage.test.js.map +1 -1
  319. package/lib/esm/test/imodel/IModel.test.js +44 -44
  320. package/lib/esm/test/imodel/IModel.test.js.map +1 -1
  321. package/lib/esm/test/imodel/ProjectExtents.test.js.map +1 -1
  322. package/lib/esm/test/imodel/SchemaXmlImport.test.js.map +1 -1
  323. package/lib/esm/test/incrementalSchemaLocater/ECSqlQueries.test.js.map +1 -1
  324. package/lib/esm/test/incrementalSchemaLocater/IncrementalLoading.test.js.map +1 -1
  325. package/lib/esm/test/incrementalSchemaLocater/utils/IModelSchemaLocater.js.map +1 -1
  326. package/lib/esm/test/incrementalSchemaLocater/utils/IncrementalTestHelper.js.map +1 -1
  327. package/lib/esm/test/incrementalSchemaLocater/utils/TestSqlSchemaLocater.js.map +1 -1
  328. package/lib/esm/test/index.js.map +1 -1
  329. package/lib/esm/test/misc/DevTools.test.js.map +1 -1
  330. package/lib/esm/test/misc/EntitySubClasses.test.js.map +1 -1
  331. package/lib/esm/test/misc/GeoServices.test.js.map +1 -1
  332. package/lib/esm/test/misc/PromiseMemoizer.test.js.map +1 -1
  333. package/lib/esm/test/native/DgnDbWorker.test.js.map +1 -1
  334. package/lib/esm/test/rpc/response.test.js.map +1 -1
  335. package/lib/esm/test/schema/ClassRegistry.test.js +99 -99
  336. package/lib/esm/test/schema/ClassRegistry.test.js.map +1 -1
  337. package/lib/esm/test/schema/FunctionalDomain.test.js.map +1 -1
  338. package/lib/esm/test/schema/GenericDomain.test.js.map +1 -1
  339. package/lib/esm/test/schema/IModelSchemaContext.test.js.map +1 -1
  340. package/lib/esm/test/sheetindex/SheetIndex.test.js.map +1 -1
  341. package/lib/esm/test/standalone/ChangeMerge.test.js.map +1 -1
  342. package/lib/esm/test/standalone/ChangesetReader.test.js +124 -124
  343. package/lib/esm/test/standalone/ChangesetReader.test.js.map +1 -1
  344. package/lib/esm/test/standalone/CustomViewState3dCreator.test.js.map +1 -1
  345. package/lib/esm/test/standalone/DisplayStyle.test.js.map +1 -1
  346. package/lib/esm/test/standalone/Drawing.test.js.map +1 -1
  347. package/lib/esm/test/standalone/ElementGraphics.test.js.map +1 -1
  348. package/lib/esm/test/standalone/ElementMesh.test.js.map +1 -1
  349. package/lib/esm/test/standalone/ExportGraphics.test.js +14 -14
  350. package/lib/esm/test/standalone/ExportGraphics.test.js.map +1 -1
  351. package/lib/esm/test/standalone/GeometryChangeEvents.test.js.map +1 -1
  352. package/lib/esm/test/standalone/GeometryStream.test.js.map +1 -1
  353. package/lib/esm/test/standalone/HubMock.test.js.map +1 -1
  354. package/lib/esm/test/standalone/IModelLimits.test.js.map +1 -1
  355. package/lib/esm/test/standalone/IModelWrite.test.js +27 -27
  356. package/lib/esm/test/standalone/IModelWrite.test.js.map +1 -1
  357. package/lib/esm/test/standalone/InlineGeometryPartReferences.test.js.map +1 -1
  358. package/lib/esm/test/standalone/MergeConflict.test.js.map +1 -1
  359. package/lib/esm/test/standalone/NativeAppStorage.test.js.map +1 -1
  360. package/lib/esm/test/standalone/RenderMaterialElement.test.js.map +1 -1
  361. package/lib/esm/test/standalone/RenderTimeline.test.js.map +1 -1
  362. package/lib/esm/test/standalone/SQLiteDb.test.js.map +1 -1
  363. package/lib/esm/test/standalone/SchemaUtils.test.js.map +1 -1
  364. package/lib/esm/test/standalone/SectionDrawing.test.js.map +1 -1
  365. package/lib/esm/test/standalone/ServerBasedLocks.test.js.map +1 -1
  366. package/lib/esm/test/standalone/Setting.test.js.map +1 -1
  367. package/lib/esm/test/standalone/Settings.test.js.map +1 -1
  368. package/lib/esm/test/standalone/SettingsSchemas.test.js.map +1 -1
  369. package/lib/esm/test/standalone/SnapshotDb.test.js.map +1 -1
  370. package/lib/esm/test/standalone/Texture.test.js.map +1 -1
  371. package/lib/esm/test/standalone/TileCache.test.js.map +1 -1
  372. package/lib/esm/test/standalone/TileTree.test.js.map +1 -1
  373. package/lib/esm/test/standalone/TxnManager.test.js.map +1 -1
  374. package/lib/esm/test/standalone/ViewDefinition.test.js.map +1 -1
  375. package/lib/esm/test/standalone/ViewStoreDb.test.js.map +1 -1
  376. package/lib/esm/test/standalone/Workspace.test.js.map +1 -1
  377. package/lib/esm/workspace/Settings.js.map +1 -1
  378. package/lib/esm/workspace/SettingsSchemas.js.map +1 -1
  379. package/lib/esm/workspace/Workspace.js.map +1 -1
  380. package/lib/esm/workspace/WorkspaceEditor.js.map +1 -1
  381. package/package.json +14 -14
@@ -1 +1 @@
1
- {"version":3,"file":"ClassRegistry.js","sourceRoot":"","sources":["../../src/ClassRegistry.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n/** @packageDocumentation\r\n * @module Schema\r\n */\r\n\r\nimport { DbResult, Id64, Id64String, IModelStatus, Logger } from \"@itwin/core-bentley\";\r\nimport { EntityMetaData, EntityReferenceSet, IModelError, RelatedElement } from \"@itwin/core-common\";\r\nimport { Entity } from \"./Entity\";\r\nimport { IModelDb } from \"./IModelDb\";\r\nimport { Schema, Schemas } from \"./Schema\";\r\nimport { EntityReferences } from \"./EntityReferences\";\r\nimport * as assert from \"assert\";\r\nimport { _nativeDb } from \"./internal/Symbols\";\r\n\r\nconst isGeneratedClassTag = Symbol(\"isGeneratedClassTag\");\r\n\r\n/** Maintains the mapping between the name of a BIS [ECClass]($ecschema-metadata) (in \"schema:class\" format) and the JavaScript [[Entity]] class that implements it.\r\n * @public\r\n */\r\nexport class EntityJsClassMap {\r\n private readonly _classMap = new Map<string, typeof Entity>();\r\n\r\n /** @internal */\r\n public has(classFullName: string): boolean {\r\n return this._classMap.has(classFullName.toLowerCase());\r\n }\r\n\r\n /** @internal */\r\n public get(classFullName: string): typeof Entity | undefined {\r\n return this._classMap.get(classFullName.toLowerCase());\r\n }\r\n\r\n /** @internal */\r\n public set(classFullName: string, entityClass: typeof Entity): void {\r\n this._classMap.set(classFullName.toLowerCase(), entityClass);\r\n }\r\n\r\n /** @internal */\r\n public delete(classFullName: string): boolean {\r\n return this._classMap.delete(classFullName.toLowerCase());\r\n }\r\n\r\n /** @internal */\r\n public clear(): void {\r\n this._classMap.clear();\r\n }\r\n\r\n /** @internal */\r\n public [Symbol.iterator](): IterableIterator<[string, typeof Entity]> {\r\n return this._classMap[Symbol.iterator]();\r\n }\r\n\r\n /**\r\n * Registers a single `entityClass` defined in the specified `schema`.\r\n * This method registers the class globally. To register a class for a specific iModel, use [[IModelDb.jsClassMap]].\r\n *\r\n * @param entityClass - The JavaScript class that implements the BIS [ECClass](@itwin/core-common) to be registered.\r\n * @param schema - The schema that contains the `entityClass`.\r\n *\r\n * @throws Error if the class is already registered.\r\n *\r\n * @public\r\n */\r\n public register(entityClass: typeof Entity, schema: typeof Schema): void {\r\n const key = (`${schema.schemaName}:${entityClass.className}`).toLowerCase();\r\n if (this.has(key)) {\r\n const errMsg = `Class ${key} is already registered. Make sure static className member is correct on JavaScript class ${entityClass.name}`;\r\n Logger.logError(\"core-frontend.classRegistry\", errMsg);\r\n throw new Error(errMsg);\r\n }\r\n entityClass.schema = schema;\r\n this.set(key, entityClass);\r\n }\r\n}\r\n\r\n/** Maintains the mapping between the name of a BIS [ECClass]($ecschema-metadata) (in \"schema:class\" format) and the JavaScript [[Entity]] class that implements it.\r\n * Applications or modules that supply their own Entity subclasses should use [[registerModule]] or [[register]] at startup\r\n * to establish their mappings.\r\n *\r\n * When creating custom Entity subclasses for registration, you should:\r\n * - Override the `className` property to match your ECClass name:\r\n * ```typescript\r\n * public static override get className() { return \"TestElement\"; }\r\n * ```\r\n * - Do NOT override `schemaName` or `schema` - these will be wired up automatically during registration\r\n *\r\n * @public\r\n */\r\nexport class ClassRegistry {\r\n private static readonly _globalClassMap = new EntityJsClassMap();\r\n /** @internal */\r\n public static isNotFoundError(err: any) { return (err instanceof IModelError) && (err.errorNumber === IModelStatus.NotFound); }\r\n /** @internal */\r\n public static makeMetaDataNotFoundError(className: string): IModelError { return new IModelError(IModelStatus.NotFound, `metadata not found for ${className}`); }\r\n /** Register a single `entityClass` defined in the specified `schema`.\r\n * @see [[registerModule]] to register multiple classes.\r\n * @public\r\n */\r\n public static register(entityClass: typeof Entity, schema: typeof Schema) {\r\n this._globalClassMap.register(entityClass, schema);\r\n }\r\n\r\n /** Generate a proxy Schema for a domain that has not been registered. */\r\n private static generateProxySchema(domain: string, iModel: IModelDb): typeof Schema {\r\n const hasBehavior = iModel.withPreparedSqliteStatement(`\r\n SELECT NULL FROM [ec_CustomAttribute] [c]\r\n JOIN [ec_schema] [s] ON [s].[Id] = [c].[ContainerId]\r\n JOIN [ec_class] [e] ON [e].[Id] = [c].[ClassId]\r\n JOIN [ec_schema] [b] ON [e].[SchemaId] = [b].[Id]\r\n WHERE [c].[ContainerType] = 1 AND [s].[Name] = ? AND [b].[Name] || '.' || [e].[name] = ?`, (stmt) => {\r\n stmt.bindString(1, domain);\r\n stmt.bindString(2, \"BisCore.SchemaHasBehavior\");\r\n return stmt.step() === DbResult.BE_SQLITE_ROW;\r\n });\r\n\r\n const schemaClass = class extends Schema {\r\n public static override get schemaName() { return domain; }\r\n public static override get missingRequiredBehavior() { return hasBehavior; }\r\n };\r\n\r\n iModel.schemaMap.registerSchema(schemaClass); // register the class before we return it.\r\n return schemaClass;\r\n }\r\n\r\n /** First, finds the root BisCore entity class for an entity, by traversing base classes and mixin targets (AppliesTo).\r\n * Then, gets its metadata and returns that.\r\n * @param iModel - iModel containing the metadata for this type\r\n * @param ecTypeQualifier - a full name of an ECEntityClass to find the root of\r\n * @returns the qualified full name of an ECEntityClass\r\n * @internal public for testing only\r\n */\r\n public static getRootEntity(iModel: IModelDb, ecTypeQualifier: string): string {\r\n const [classSchema, className] = ecTypeQualifier.split(\".\");\r\n const schemaItemJson = iModel[_nativeDb].getSchemaItem(classSchema, className);\r\n if (schemaItemJson.error)\r\n throw new IModelError(schemaItemJson.error.status, `failed to get schema item '${ecTypeQualifier}'`);\r\n\r\n assert(undefined !== schemaItemJson.result);\r\n const schemaItem = JSON.parse(schemaItemJson.result);\r\n if (!(\"appliesTo\" in schemaItem) && schemaItem.baseClass === undefined) {\r\n return ecTypeQualifier;\r\n }\r\n\r\n // typescript doesn't understand that the inverse of the above condition is\r\n // (\"appliesTo\" in rootclassMetaData || rootClassMetaData.baseClass !== undefined)\r\n const parentItemQualifier = schemaItem.appliesTo ?? schemaItem.baseClass as string;\r\n return this.getRootEntity(iModel, parentItemQualifier);\r\n }\r\n\r\n /** Generate a JavaScript class from Entity metadata.\r\n * @param entityMetaData The Entity metadata that defines the class\r\n */\r\n // eslint-disable-next-line @typescript-eslint/no-deprecated\r\n private static generateClassForEntity(entityMetaData: EntityMetaData, iModel: IModelDb): typeof Entity {\r\n const name = entityMetaData.ecclass.split(\":\");\r\n const domainName = name[0];\r\n const className = name[1];\r\n\r\n if (0 === entityMetaData.baseClasses.length) // metadata must contain a superclass\r\n throw new IModelError(IModelStatus.BadArg, `class ${entityMetaData.ecclass} has no superclass`);\r\n\r\n // make sure schema exists\r\n let schema = iModel.schemaMap.get(domainName) ?? Schemas.getRegisteredSchema(domainName);\r\n if (undefined === schema)\r\n schema = this.generateProxySchema(domainName, iModel); // no schema found, create it too\r\n\r\n const superClassFullName = entityMetaData.baseClasses[0].toLowerCase();\r\n const superclass = iModel.jsClassMap.get(superClassFullName) ?? this._globalClassMap.get(superClassFullName);\r\n if (undefined === superclass)\r\n throw new IModelError(IModelStatus.NotFound, `cannot find superclass for class ${entityMetaData.ecclass}`);\r\n\r\n // user defined class hierarchies may skip a class in the hierarchy, and therefore their JS base class cannot\r\n // be used to tell if there are any generated classes in the hierarchy\r\n let generatedClassHasNonGeneratedNonCoreAncestor = false;\r\n let currentSuperclass = superclass;\r\n const MAX_ITERS = 1000;\r\n for (let i = 0; i < MAX_ITERS; ++i) {\r\n if (currentSuperclass.schema.schemaName === \"BisCore\")\r\n break;\r\n\r\n if (!currentSuperclass.isGeneratedClass) {\r\n generatedClassHasNonGeneratedNonCoreAncestor = true;\r\n break;\r\n }\r\n // eslint-disable-next-line @typescript-eslint/no-deprecated\r\n const superclassMetaData = iModel.classMetaDataRegistry.find(currentSuperclass.classFullName);\r\n if (superclassMetaData === undefined)\r\n throw new IModelError(IModelStatus.BadSchema, `could not find the metadata for class '${currentSuperclass.name}', class metadata should be loaded by now`);\r\n const maybeNextSuperclass = this.getClass(superclassMetaData.baseClasses[0], iModel);\r\n if (maybeNextSuperclass === undefined)\r\n throw new IModelError(IModelStatus.BadSchema, `could not find the base class of '${currentSuperclass.name}', all generated classes must have a base class`);\r\n currentSuperclass = maybeNextSuperclass;\r\n }\r\n\r\n const generatedClass = class extends superclass {\r\n public static override get className() { return className; }\r\n private static [isGeneratedClassTag] = true;\r\n public static override get isGeneratedClass() { return this.hasOwnProperty(isGeneratedClassTag); }\r\n };\r\n\r\n // the above creates an anonymous class. For help debugging, set the \"constructor.name\" property to be the same as the bisClassName.\r\n Object.defineProperty(generatedClass, \"name\", { get: () => className }); // this is the (only) way to change that readonly property.\r\n\r\n // a class only gets an automatic `collectReferenceIds` implementation if:\r\n // - it is not in the `BisCore` schema\r\n // - there are no ancestors with manually registered JS implementations, (excluding BisCore base classes)\r\n if (!generatedClassHasNonGeneratedNonCoreAncestor) {\r\n const navigationProps = Object.entries(entityMetaData.properties)\r\n .filter(([_name, prop]) => prop.isNavigation)\r\n // eslint-disable-next-line @typescript-eslint/no-shadow\r\n .map(([name, prop]) => {\r\n assert(prop.relationshipClass);\r\n const maybeMetaData = iModel[_nativeDb].getSchemaItem(...prop.relationshipClass.split(\":\") as [string, string]);\r\n assert(maybeMetaData.result !== undefined, \"The nav props relationship metadata was not found\");\r\n const relMetaData = JSON.parse(maybeMetaData.result);\r\n const rootClassMetaData = ClassRegistry.getRootEntity(iModel, relMetaData.target.constraintClasses[0]);\r\n // root class must be in BisCore so should be loaded since biscore classes will never get this\r\n // generated implementation\r\n const normalizeClassName = (clsName: string) => clsName.replace(\".\", \":\");\r\n const rootClass = ClassRegistry.findRegisteredClass(normalizeClassName(rootClassMetaData));\r\n assert(rootClass, `The root class for ${prop.relationshipClass} was not in BisCore.`);\r\n return { name, concreteEntityType: EntityReferences.typeFromClass(rootClass) };\r\n });\r\n\r\n Object.defineProperty(\r\n generatedClass.prototype,\r\n \"collectReferenceIds\",\r\n {\r\n value(this: typeof generatedClass, referenceIds: EntityReferenceSet) {\r\n // eslint-disable-next-line @typescript-eslint/dot-notation\r\n const superImpl = superclass.prototype[\"collectReferenceIds\"];\r\n superImpl.call(this, referenceIds);\r\n for (const navProp of navigationProps) {\r\n const relatedElem: RelatedElement | undefined = (this as any)[navProp.name]; // cast to any since subclass can have any extensions\r\n if (!relatedElem || !Id64.isValid(relatedElem.id))\r\n continue;\r\n const referenceId = EntityReferences.fromEntityType(relatedElem.id, navProp.concreteEntityType);\r\n referenceIds.add(referenceId);\r\n }\r\n },\r\n // defaults for methods on a prototype (required for sinon to stub out methods on tests)\r\n writable: true,\r\n configurable: true,\r\n },\r\n );\r\n }\r\n\r\n // if the schema is a proxy for a domain with behavior, throw exceptions for all protected operations\r\n if (schema.missingRequiredBehavior) {\r\n const throwError = () => {\r\n throw new IModelError(IModelStatus.WrongHandler, `Schema [${domainName}] not registered, but is marked with SchemaHasBehavior`);\r\n };\r\n\r\n superclass.protectedOperations.forEach((operation) => (generatedClass as any)[operation] = throwError);\r\n }\r\n\r\n iModel.jsClassMap.register(generatedClass, schema); // register it before returning\r\n return generatedClass;\r\n }\r\n\r\n /** Register all of the classes found in the given module that derive from [[Entity]].\r\n * [[register]] will be invoked for each subclass of `Entity` exported by `moduleObj`.\r\n * @param moduleObj The module to search for subclasses of Entity\r\n * @param schema The schema that contains all of the [ECClass]($ecschema-metadata)es exported by `moduleObj`.\r\n */\r\n public static registerModule(moduleObj: any, schema: typeof Schema) {\r\n for (const thisMember in moduleObj) { // eslint-disable-line guard-for-in\r\n const thisClass = moduleObj[thisMember];\r\n if (thisClass.prototype instanceof Entity)\r\n this.register(thisClass, schema);\r\n }\r\n }\r\n\r\n /**\r\n * This function fetches the specified Entity from the imodel, generates a JavaScript class for it, and registers the generated\r\n * class. This function also ensures that all of the base classes of the Entity exist and are registered.\r\n */\r\n private static generateClass(classFullName: string, iModel: IModelDb): typeof Entity {\r\n // eslint-disable-next-line @typescript-eslint/no-deprecated\r\n const metadata: EntityMetaData | undefined = iModel.classMetaDataRegistry.find(classFullName);\r\n if (metadata === undefined || metadata.ecclass === undefined)\r\n throw this.makeMetaDataNotFoundError(classFullName);\r\n\r\n // Make sure we have all base classes registered.\r\n if (metadata.baseClasses && (0 !== metadata.baseClasses.length))\r\n this.getClass(metadata.baseClasses[0], iModel);\r\n\r\n // Now we can generate the class from the classDef.\r\n return this.generateClassForEntity(metadata, iModel);\r\n }\r\n\r\n /** Find a registered class by classFullName.\r\n * @param classFullName class to find\r\n * @param iModel The IModel that contains the class definitions\r\n * @returns The Entity class or undefined\r\n */\r\n public static findRegisteredClass(classFullName: string): typeof Entity | undefined {\r\n return this._globalClassMap.get(classFullName.toLowerCase());\r\n }\r\n\r\n /** Get the Entity class for the specified Entity className.\r\n * @param classFullName The full BIS class name of the Entity\r\n * @param iModel The IModel that contains the class definitions\r\n * @returns The Entity class\r\n */\r\n public static getClass(classFullName: string, iModel: IModelDb): typeof Entity {\r\n const key = classFullName.toLowerCase();\r\n return iModel.jsClassMap.get(key) ?? this._globalClassMap.get(key) ?? this.generateClass(key, iModel);\r\n }\r\n\r\n /** Unregister a class, by name, if one is already registered.\r\n * This function is not normally needed, but is useful for cases where a generated *proxy* class needs to be replaced by the *real* class.\r\n * @param classFullName Name of the class to unregister\r\n * @return true if the class was unregistered\r\n * @internal\r\n */\r\n public static unregisterClass(classFullName: string) { return this._globalClassMap.delete(classFullName.toLowerCase()); }\r\n\r\n /** Unregister all classes from a schema.\r\n * This function is not normally needed, but is useful for cases where a generated *proxy* schema needs to be replaced by the *real* schema.\r\n * @param schema Name of the schema to unregister\r\n * @internal\r\n */\r\n public static unregisterClassesFrom(schema: typeof Schema) {\r\n for (const entry of Array.from(this._globalClassMap)) {\r\n if (entry[1].schema === schema)\r\n this.unregisterClass(entry[0]);\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * A cache that records the mapping between class names and class metadata.\r\n * @see [[IModelDb.classMetaDataRegistry]] to access the registry for a specific iModel.\r\n * @internal\r\n * @deprecated in 5.0 - will not be removed until after 2026-06-13. Please use `schemaContext` from the `iModel` instead.\r\n *\r\n * @example\r\n * @\r\n * Current Usage:\r\n * ```ts\r\n * const metaData: EntityMetaData | undefined = iModel.classMetaDataRegistry.find(\"SchemaName:ClassName\");\r\n * ```\r\n *\r\n * Replacement:\r\n * ```ts\r\n * const entityMetaData: EntityClass | undefined = iModel.schemaContext.getSchemaItemSync(\"SchemaName.ClassName\", EntityClass);\r\n * const relationshipMetaData: RelationshipClass | undefined = iModel.schemaContext.getSchemaItemSync(\"SchemaName\", \"ClassName\", RelationshipClass);\r\n * ```\r\n */\r\nexport class MetaDataRegistry {\r\n // eslint-disable-next-line @typescript-eslint/no-deprecated\r\n private _registry = new Map<string, EntityMetaData>();\r\n private _classIdToName = new Map<Id64String, string>();\r\n\r\n /** Get the specified Entity metadata */\r\n // eslint-disable-next-line @typescript-eslint/no-deprecated\r\n public find(classFullName: string): EntityMetaData | undefined {\r\n return this._registry.get(classFullName.toLowerCase());\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-deprecated\r\n public findByClassId(classId: Id64String): EntityMetaData | undefined {\r\n const name = this._classIdToName.get(classId);\r\n return undefined !== name ? this.find(name) : undefined;\r\n }\r\n\r\n /** Add metadata to the cache */\r\n // eslint-disable-next-line @typescript-eslint/no-deprecated\r\n public add(classFullName: string, metaData: EntityMetaData): void {\r\n const name = classFullName.toLowerCase();\r\n this._registry.set(name, metaData);\r\n this._classIdToName.set(metaData.classId, name);\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"ClassRegistry.js","sourceRoot":"","sources":["../../src/ClassRegistry.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\n/** @packageDocumentation\n * @module Schema\n */\n\nimport { DbResult, Id64, Id64String, IModelStatus, Logger } from \"@itwin/core-bentley\";\nimport { EntityMetaData, EntityReferenceSet, IModelError, RelatedElement } from \"@itwin/core-common\";\nimport { Entity } from \"./Entity\";\nimport { IModelDb } from \"./IModelDb\";\nimport { Schema, Schemas } from \"./Schema\";\nimport { EntityReferences } from \"./EntityReferences\";\nimport * as assert from \"assert\";\nimport { _nativeDb } from \"./internal/Symbols\";\n\nconst isGeneratedClassTag = Symbol(\"isGeneratedClassTag\");\n\n/** Maintains the mapping between the name of a BIS [ECClass]($ecschema-metadata) (in \"schema:class\" format) and the JavaScript [[Entity]] class that implements it.\n * @public\n */\nexport class EntityJsClassMap {\n private readonly _classMap = new Map<string, typeof Entity>();\n\n /** @internal */\n public has(classFullName: string): boolean {\n return this._classMap.has(classFullName.toLowerCase());\n }\n\n /** @internal */\n public get(classFullName: string): typeof Entity | undefined {\n return this._classMap.get(classFullName.toLowerCase());\n }\n\n /** @internal */\n public set(classFullName: string, entityClass: typeof Entity): void {\n this._classMap.set(classFullName.toLowerCase(), entityClass);\n }\n\n /** @internal */\n public delete(classFullName: string): boolean {\n return this._classMap.delete(classFullName.toLowerCase());\n }\n\n /** @internal */\n public clear(): void {\n this._classMap.clear();\n }\n\n /** @internal */\n public [Symbol.iterator](): IterableIterator<[string, typeof Entity]> {\n return this._classMap[Symbol.iterator]();\n }\n\n /**\n * Registers a single `entityClass` defined in the specified `schema`.\n * This method registers the class globally. To register a class for a specific iModel, use [[IModelDb.jsClassMap]].\n *\n * @param entityClass - The JavaScript class that implements the BIS [ECClass](@itwin/core-common) to be registered.\n * @param schema - The schema that contains the `entityClass`.\n *\n * @throws Error if the class is already registered.\n *\n * @public\n */\n public register(entityClass: typeof Entity, schema: typeof Schema): void {\n const key = (`${schema.schemaName}:${entityClass.className}`).toLowerCase();\n if (this.has(key)) {\n const errMsg = `Class ${key} is already registered. Make sure static className member is correct on JavaScript class ${entityClass.name}`;\n Logger.logError(\"core-frontend.classRegistry\", errMsg);\n throw new Error(errMsg);\n }\n entityClass.schema = schema;\n this.set(key, entityClass);\n }\n}\n\n/** Maintains the mapping between the name of a BIS [ECClass]($ecschema-metadata) (in \"schema:class\" format) and the JavaScript [[Entity]] class that implements it.\n * Applications or modules that supply their own Entity subclasses should use [[registerModule]] or [[register]] at startup\n * to establish their mappings.\n *\n * When creating custom Entity subclasses for registration, you should:\n * - Override the `className` property to match your ECClass name:\n * ```typescript\n * public static override get className() { return \"TestElement\"; }\n * ```\n * - Do NOT override `schemaName` or `schema` - these will be wired up automatically during registration\n *\n * @public\n */\nexport class ClassRegistry {\n private static readonly _globalClassMap = new EntityJsClassMap();\n /** @internal */\n public static isNotFoundError(err: any) { return (err instanceof IModelError) && (err.errorNumber === IModelStatus.NotFound); }\n /** @internal */\n public static makeMetaDataNotFoundError(className: string): IModelError { return new IModelError(IModelStatus.NotFound, `metadata not found for ${className}`); }\n /** Register a single `entityClass` defined in the specified `schema`.\n * @see [[registerModule]] to register multiple classes.\n * @public\n */\n public static register(entityClass: typeof Entity, schema: typeof Schema) {\n this._globalClassMap.register(entityClass, schema);\n }\n\n /** Generate a proxy Schema for a domain that has not been registered. */\n private static generateProxySchema(domain: string, iModel: IModelDb): typeof Schema {\n const hasBehavior = iModel.withPreparedSqliteStatement(`\n SELECT NULL FROM [ec_CustomAttribute] [c]\n JOIN [ec_schema] [s] ON [s].[Id] = [c].[ContainerId]\n JOIN [ec_class] [e] ON [e].[Id] = [c].[ClassId]\n JOIN [ec_schema] [b] ON [e].[SchemaId] = [b].[Id]\n WHERE [c].[ContainerType] = 1 AND [s].[Name] = ? AND [b].[Name] || '.' || [e].[name] = ?`, (stmt) => {\n stmt.bindString(1, domain);\n stmt.bindString(2, \"BisCore.SchemaHasBehavior\");\n return stmt.step() === DbResult.BE_SQLITE_ROW;\n });\n\n const schemaClass = class extends Schema {\n public static override get schemaName() { return domain; }\n public static override get missingRequiredBehavior() { return hasBehavior; }\n };\n\n iModel.schemaMap.registerSchema(schemaClass); // register the class before we return it.\n return schemaClass;\n }\n\n /** First, finds the root BisCore entity class for an entity, by traversing base classes and mixin targets (AppliesTo).\n * Then, gets its metadata and returns that.\n * @param iModel - iModel containing the metadata for this type\n * @param ecTypeQualifier - a full name of an ECEntityClass to find the root of\n * @returns the qualified full name of an ECEntityClass\n * @internal public for testing only\n */\n public static getRootEntity(iModel: IModelDb, ecTypeQualifier: string): string {\n const [classSchema, className] = ecTypeQualifier.split(\".\");\n const schemaItemJson = iModel[_nativeDb].getSchemaItem(classSchema, className);\n if (schemaItemJson.error)\n throw new IModelError(schemaItemJson.error.status, `failed to get schema item '${ecTypeQualifier}'`);\n\n assert(undefined !== schemaItemJson.result);\n const schemaItem = JSON.parse(schemaItemJson.result);\n if (!(\"appliesTo\" in schemaItem) && schemaItem.baseClass === undefined) {\n return ecTypeQualifier;\n }\n\n // typescript doesn't understand that the inverse of the above condition is\n // (\"appliesTo\" in rootclassMetaData || rootClassMetaData.baseClass !== undefined)\n const parentItemQualifier = schemaItem.appliesTo ?? schemaItem.baseClass as string;\n return this.getRootEntity(iModel, parentItemQualifier);\n }\n\n /** Generate a JavaScript class from Entity metadata.\n * @param entityMetaData The Entity metadata that defines the class\n */\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n private static generateClassForEntity(entityMetaData: EntityMetaData, iModel: IModelDb): typeof Entity {\n const name = entityMetaData.ecclass.split(\":\");\n const domainName = name[0];\n const className = name[1];\n\n if (0 === entityMetaData.baseClasses.length) // metadata must contain a superclass\n throw new IModelError(IModelStatus.BadArg, `class ${entityMetaData.ecclass} has no superclass`);\n\n // make sure schema exists\n let schema = iModel.schemaMap.get(domainName) ?? Schemas.getRegisteredSchema(domainName);\n if (undefined === schema)\n schema = this.generateProxySchema(domainName, iModel); // no schema found, create it too\n\n const superClassFullName = entityMetaData.baseClasses[0].toLowerCase();\n const superclass = iModel.jsClassMap.get(superClassFullName) ?? this._globalClassMap.get(superClassFullName);\n if (undefined === superclass)\n throw new IModelError(IModelStatus.NotFound, `cannot find superclass for class ${entityMetaData.ecclass}`);\n\n // user defined class hierarchies may skip a class in the hierarchy, and therefore their JS base class cannot\n // be used to tell if there are any generated classes in the hierarchy\n let generatedClassHasNonGeneratedNonCoreAncestor = false;\n let currentSuperclass = superclass;\n const MAX_ITERS = 1000;\n for (let i = 0; i < MAX_ITERS; ++i) {\n if (currentSuperclass.schema.schemaName === \"BisCore\")\n break;\n\n if (!currentSuperclass.isGeneratedClass) {\n generatedClassHasNonGeneratedNonCoreAncestor = true;\n break;\n }\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n const superclassMetaData = iModel.classMetaDataRegistry.find(currentSuperclass.classFullName);\n if (superclassMetaData === undefined)\n throw new IModelError(IModelStatus.BadSchema, `could not find the metadata for class '${currentSuperclass.name}', class metadata should be loaded by now`);\n const maybeNextSuperclass = this.getClass(superclassMetaData.baseClasses[0], iModel);\n if (maybeNextSuperclass === undefined)\n throw new IModelError(IModelStatus.BadSchema, `could not find the base class of '${currentSuperclass.name}', all generated classes must have a base class`);\n currentSuperclass = maybeNextSuperclass;\n }\n\n const generatedClass = class extends superclass {\n public static override get className() { return className; }\n private static [isGeneratedClassTag] = true;\n public static override get isGeneratedClass() { return this.hasOwnProperty(isGeneratedClassTag); }\n };\n\n // the above creates an anonymous class. For help debugging, set the \"constructor.name\" property to be the same as the bisClassName.\n Object.defineProperty(generatedClass, \"name\", { get: () => className }); // this is the (only) way to change that readonly property.\n\n // a class only gets an automatic `collectReferenceIds` implementation if:\n // - it is not in the `BisCore` schema\n // - there are no ancestors with manually registered JS implementations, (excluding BisCore base classes)\n if (!generatedClassHasNonGeneratedNonCoreAncestor) {\n const navigationProps = Object.entries(entityMetaData.properties)\n .filter(([_name, prop]) => prop.isNavigation)\n // eslint-disable-next-line @typescript-eslint/no-shadow\n .map(([name, prop]) => {\n assert(prop.relationshipClass);\n const maybeMetaData = iModel[_nativeDb].getSchemaItem(...prop.relationshipClass.split(\":\") as [string, string]);\n assert(maybeMetaData.result !== undefined, \"The nav props relationship metadata was not found\");\n const relMetaData = JSON.parse(maybeMetaData.result);\n const rootClassMetaData = ClassRegistry.getRootEntity(iModel, relMetaData.target.constraintClasses[0]);\n // root class must be in BisCore so should be loaded since biscore classes will never get this\n // generated implementation\n const normalizeClassName = (clsName: string) => clsName.replace(\".\", \":\");\n const rootClass = ClassRegistry.findRegisteredClass(normalizeClassName(rootClassMetaData));\n assert(rootClass, `The root class for ${prop.relationshipClass} was not in BisCore.`);\n return { name, concreteEntityType: EntityReferences.typeFromClass(rootClass) };\n });\n\n Object.defineProperty(\n generatedClass.prototype,\n \"collectReferenceIds\",\n {\n value(this: typeof generatedClass, referenceIds: EntityReferenceSet) {\n // eslint-disable-next-line @typescript-eslint/dot-notation\n const superImpl = superclass.prototype[\"collectReferenceIds\"];\n superImpl.call(this, referenceIds);\n for (const navProp of navigationProps) {\n const relatedElem: RelatedElement | undefined = (this as any)[navProp.name]; // cast to any since subclass can have any extensions\n if (!relatedElem || !Id64.isValid(relatedElem.id))\n continue;\n const referenceId = EntityReferences.fromEntityType(relatedElem.id, navProp.concreteEntityType);\n referenceIds.add(referenceId);\n }\n },\n // defaults for methods on a prototype (required for sinon to stub out methods on tests)\n writable: true,\n configurable: true,\n },\n );\n }\n\n // if the schema is a proxy for a domain with behavior, throw exceptions for all protected operations\n if (schema.missingRequiredBehavior) {\n const throwError = () => {\n throw new IModelError(IModelStatus.WrongHandler, `Schema [${domainName}] not registered, but is marked with SchemaHasBehavior`);\n };\n\n superclass.protectedOperations.forEach((operation) => (generatedClass as any)[operation] = throwError);\n }\n\n iModel.jsClassMap.register(generatedClass, schema); // register it before returning\n return generatedClass;\n }\n\n /** Register all of the classes found in the given module that derive from [[Entity]].\n * [[register]] will be invoked for each subclass of `Entity` exported by `moduleObj`.\n * @param moduleObj The module to search for subclasses of Entity\n * @param schema The schema that contains all of the [ECClass]($ecschema-metadata)es exported by `moduleObj`.\n */\n public static registerModule(moduleObj: any, schema: typeof Schema) {\n for (const thisMember in moduleObj) { // eslint-disable-line guard-for-in\n const thisClass = moduleObj[thisMember];\n if (thisClass.prototype instanceof Entity)\n this.register(thisClass, schema);\n }\n }\n\n /**\n * This function fetches the specified Entity from the imodel, generates a JavaScript class for it, and registers the generated\n * class. This function also ensures that all of the base classes of the Entity exist and are registered.\n */\n private static generateClass(classFullName: string, iModel: IModelDb): typeof Entity {\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n const metadata: EntityMetaData | undefined = iModel.classMetaDataRegistry.find(classFullName);\n if (metadata === undefined || metadata.ecclass === undefined)\n throw this.makeMetaDataNotFoundError(classFullName);\n\n // Make sure we have all base classes registered.\n if (metadata.baseClasses && (0 !== metadata.baseClasses.length))\n this.getClass(metadata.baseClasses[0], iModel);\n\n // Now we can generate the class from the classDef.\n return this.generateClassForEntity(metadata, iModel);\n }\n\n /** Find a registered class by classFullName.\n * @param classFullName class to find\n * @param iModel The IModel that contains the class definitions\n * @returns The Entity class or undefined\n */\n public static findRegisteredClass(classFullName: string): typeof Entity | undefined {\n return this._globalClassMap.get(classFullName.toLowerCase());\n }\n\n /** Get the Entity class for the specified Entity className.\n * @param classFullName The full BIS class name of the Entity\n * @param iModel The IModel that contains the class definitions\n * @returns The Entity class\n */\n public static getClass(classFullName: string, iModel: IModelDb): typeof Entity {\n const key = classFullName.toLowerCase();\n return iModel.jsClassMap.get(key) ?? this._globalClassMap.get(key) ?? this.generateClass(key, iModel);\n }\n\n /** Unregister a class, by name, if one is already registered.\n * This function is not normally needed, but is useful for cases where a generated *proxy* class needs to be replaced by the *real* class.\n * @param classFullName Name of the class to unregister\n * @return true if the class was unregistered\n * @internal\n */\n public static unregisterClass(classFullName: string) { return this._globalClassMap.delete(classFullName.toLowerCase()); }\n\n /** Unregister all classes from a schema.\n * This function is not normally needed, but is useful for cases where a generated *proxy* schema needs to be replaced by the *real* schema.\n * @param schema Name of the schema to unregister\n * @internal\n */\n public static unregisterClassesFrom(schema: typeof Schema) {\n for (const entry of Array.from(this._globalClassMap)) {\n if (entry[1].schema === schema)\n this.unregisterClass(entry[0]);\n }\n }\n}\n\n/**\n * A cache that records the mapping between class names and class metadata.\n * @see [[IModelDb.classMetaDataRegistry]] to access the registry for a specific iModel.\n * @internal\n * @deprecated in 5.0 - will not be removed until after 2026-06-13. Please use `schemaContext` from the `iModel` instead.\n *\n * @example\n * @\n * Current Usage:\n * ```ts\n * const metaData: EntityMetaData | undefined = iModel.classMetaDataRegistry.find(\"SchemaName:ClassName\");\n * ```\n *\n * Replacement:\n * ```ts\n * const entityMetaData: EntityClass | undefined = iModel.schemaContext.getSchemaItemSync(\"SchemaName.ClassName\", EntityClass);\n * const relationshipMetaData: RelationshipClass | undefined = iModel.schemaContext.getSchemaItemSync(\"SchemaName\", \"ClassName\", RelationshipClass);\n * ```\n */\nexport class MetaDataRegistry {\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n private _registry = new Map<string, EntityMetaData>();\n private _classIdToName = new Map<Id64String, string>();\n\n /** Get the specified Entity metadata */\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n public find(classFullName: string): EntityMetaData | undefined {\n return this._registry.get(classFullName.toLowerCase());\n }\n\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n public findByClassId(classId: Id64String): EntityMetaData | undefined {\n const name = this._classIdToName.get(classId);\n return undefined !== name ? this.find(name) : undefined;\n }\n\n /** Add metadata to the cache */\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n public add(classFullName: string, metaData: EntityMetaData): void {\n const name = classFullName.toLowerCase();\n this._registry.set(name, metaData);\n this._classIdToName.set(metaData.classId, name);\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"CloudSqlite.js","sourceRoot":"","sources":["../../src/CloudSqlite.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n/** @packageDocumentation\r\n * @module SQLiteDb\r\n */\r\n\r\nimport * as semver from \"semver\";\r\nimport { mkdirSync, unlinkSync } from \"fs\";\r\nimport { dirname, join } from \"path\";\r\nimport { NativeLibrary } from \"@bentley/imodeljs-native\";\r\nimport {\r\n AccessToken, BeDuration, BriefcaseStatus, Constructor, GuidString, Logger, LogLevel, OpenMode, Optional, PickAsyncMethods, PickMethods, StopWatch,\r\n} from \"@itwin/core-bentley\";\r\nimport { CloudSqliteError, LocalDirName, LocalFileName } from \"@itwin/core-common\";\r\nimport { BlobContainer } from \"./BlobContainerService\";\r\nimport { IModelHost, KnownLocations } from \"./IModelHost\";\r\nimport { IModelJsFs } from \"./IModelJsFs\";\r\nimport { RpcTrace } from \"./rpc/tracing\";\r\n\r\nimport type { SQLiteDb, VersionedSqliteDb } from \"./SQLiteDb\";\r\n\r\n// spell:ignore logmsg httpcode daemonless cachefile cacheslots ddthh cloudsqlite premajor preminor prepatch\r\n\r\n/**\r\n * Types for accessing SQLite databases stored in cloud containers.\r\n * @beta\r\n */\r\nexport namespace CloudSqlite {\r\n\r\n const logInfo = (msg: string) => Logger.logInfo(\"CloudSqlite\", msg);\r\n const logError = (msg: string) => Logger.logError(\"CloudSqlite\", msg);\r\n\r\n export type RequestTokenArgs = Optional<BlobContainer.RequestTokenProps, \"userToken\">;\r\n\r\n /** Add (or replace) a property to an object that is not enumerable.\r\n * This is important so this member will be skipped when the object is the target of\r\n * [structuredClone](https://developer.mozilla.org/docs/Web/API/Web_Workers_API/Structured_clone_algorithm)\r\n * (e.g. when the object is part of an exception that is marshalled across process boundaries.)\r\n */\r\n export function addHiddenProperty<T>(o: T, p: PropertyKey, value?: any): T {\r\n return Object.defineProperty(o, p, { enumerable: false, writable: true, value })\r\n }\r\n\r\n function verifyService<T>(serviceName: string, service: T | undefined): T {\r\n if (undefined === service)\r\n CloudSqliteError.throwError(\"service-not-available\", { message: `${serviceName} service is not available` });\r\n return service;\r\n }\r\n\r\n export function getBlobService(): BlobContainer.ContainerService {\r\n return verifyService(\"BlobContainer\", BlobContainer.service);\r\n }\r\n\r\n /**\r\n * Request a new AccessToken for a cloud container using the [[BlobContainer]] service.\r\n * If the service is unavailable or returns an error, an empty token is returned.\r\n */\r\n export async function requestToken(args: RequestTokenArgs): Promise<AccessToken> {\r\n // allow the userToken to be supplied via args. If not supplied, or blank, use the backend's accessToken. If that fails, use the value from the current RPC request\r\n let userToken = args.userToken ? args.userToken : await IModelHost.getAccessToken();\r\n if (userToken === \"\")\r\n userToken = RpcTrace.currentActivity?.accessToken ?? \"\";\r\n const response = await getBlobService().requestToken({ ...args, userToken });\r\n return response?.token ?? \"\";\r\n }\r\n\r\n interface CloudContainerInternal extends CloudContainer {\r\n timer?: NodeJS.Timeout;\r\n refreshPromise?: Promise<void>;\r\n lockExpireSeconds: number;\r\n writeLockHeldBy?: string;\r\n }\r\n\r\n export function noLeadingOrTrailingSpaces(name: string, msg: string) {\r\n if (name.trim() !== name)\r\n CloudSqliteError.throwError(\"invalid-name\", { message: `${msg} [${name}] may not have leading or trailing spaces` });\r\n }\r\n\r\n export function validateDbName(dbName: DbName) {\r\n if (dbName === \"\" || dbName.length > 255 || /[#\\.<>:\"/\\\\\"`'|?*\\u0000-\\u001F]/g.test(dbName) || /^(con|prn|aux|nul|com\\d|lpt\\d)$/i.test(dbName))\r\n CloudSqliteError.throwError(\"invalid-name\", { message: \"invalid dbName\", dbName });\r\n\r\n noLeadingOrTrailingSpaces(dbName, \"dbName\");\r\n }\r\n\r\n /**\r\n * Create a new CloudContainer from a ContainerAccessProps. For non-public containers, a valid accessToken must be provided before the container\r\n * can be used (e.g. via [[CloudSqlite.requestToken]]).\r\n * @note After the container is successfully connected to a CloudCache, it will begin auto-refreshing its accessToken every `tokenRefreshSeconds` seconds (default is 1 hour)\r\n * until it is disconnected. However, if the container is public, or if `tokenRefreshSeconds` is <=0, auto-refresh is not enabled.\r\n */\r\n export function createCloudContainer(args: ContainerAccessProps & { accessLevel?: BlobContainer.RequestAccessLevel, tokenFn?: (args: RequestTokenArgs) => Promise<AccessToken> }): CloudContainer {\r\n const container = new NativeLibrary.nativeLib.CloudContainer(args) as CloudContainerInternal;\r\n // we're going to add these fields to the newly created object. They should *not* be enumerable so they are not copied\r\n // when the object is cloned (e.g. when included in an exception across processes).\r\n addHiddenProperty(container, \"timer\");\r\n addHiddenProperty(container, \"refreshPromise\");\r\n\r\n const refreshSeconds = (undefined !== args.tokenRefreshSeconds) ? args.tokenRefreshSeconds : 60 * 60; // default is 1 hour\r\n container.lockExpireSeconds = args.lockExpireSeconds ?? 60 * 60; // default is 1 hour\r\n\r\n // don't refresh tokens for public containers or if refreshSeconds<=0\r\n if (!args.isPublic && refreshSeconds > 0) {\r\n const tokenProps = { baseUri: args.baseUri, containerId: args.containerId, accessLevel: args.accessLevel };\r\n const doRefresh = async () => {\r\n let newToken: AccessToken | undefined;\r\n const url = `[${tokenProps.baseUri}/${tokenProps.containerId}]`;\r\n try {\r\n newToken = await (args.tokenFn ?? CloudSqlite.requestToken)(tokenProps);\r\n logInfo(`Refreshed token for container ${url}`);\r\n } catch (err: any) {\r\n logError(`Error refreshing token for container ${url}: ${err.message}`);\r\n }\r\n container.accessToken = newToken ?? \"\";\r\n };\r\n const tokenRefreshFn = () => {\r\n container.timer = setTimeout(async () => {\r\n container.refreshPromise = doRefresh(); // this promise is stored on the container so it can be awaited in tests\r\n await container.refreshPromise;\r\n container.refreshPromise = undefined;\r\n tokenRefreshFn(); // schedule next refresh\r\n }, refreshSeconds * 1000).unref(); // unref so it doesn't keep the process alive\r\n };\r\n addHiddenProperty(container, \"onConnected\", tokenRefreshFn); // schedule the first refresh when the container is connected\r\n addHiddenProperty(container, \"onDisconnect\", () => { // clear the refresh timer when the container is disconnected\r\n if (container.timer !== undefined) {\r\n clearTimeout(container.timer);\r\n container.timer = undefined;\r\n }\r\n });\r\n }\r\n return container;\r\n }\r\n\r\n /** Begin prefetching all blocks for a database in a CloudContainer in the background. */\r\n export function startCloudPrefetch(container: CloudContainer, dbName: string, args?: PrefetchProps): CloudPrefetch {\r\n return new NativeLibrary.nativeLib.CloudPrefetch(container, dbName, args);\r\n }\r\n export interface ContainerProps {\r\n /** The type of storage provider. */\r\n readonly storageType: \"azure\" | \"google\";\r\n /** The base URI for the container. */\r\n readonly baseUri: string;\r\n /** The name of the container. */\r\n readonly containerId: string;\r\n /** true if the container is public (doesn't require authorization) */\r\n readonly isPublic?: boolean;\r\n /** access token for container. If not present uses `CloudSqlite.requestToken` */\r\n accessToken?: string;\r\n }\r\n\r\n /** Properties to access a CloudContainer. */\r\n export interface ContainerAccessProps extends ContainerProps {\r\n /** an alias for the container. Defaults to `containerId` */\r\n readonly alias?: string;\r\n /** SAS token that grants access to the container. */\r\n accessToken: string;\r\n /** if true, container is allowed to request the write lock. */\r\n readonly writeable?: boolean;\r\n /** if true, container is attached in \"secure\" mode (blocks are encrypted). Only supported in daemon mode. */\r\n readonly secure?: boolean;\r\n /** string attached to log messages from CloudSQLite. This is most useful for identifying usage from daemon mode. */\r\n readonly logId?: string;\r\n /** Duration for holding write lock, in seconds. After this time the write lock expires if not refreshed. Default is one hour. */\r\n readonly lockExpireSeconds?: number;\r\n /** number of seconds between auto-refresh of access token. If <=0 no auto-refresh. Default is 1 hour (60*60) */\r\n readonly tokenRefreshSeconds?: number;\r\n }\r\n\r\n /** Returned from `CloudContainer.queryDatabase` describing one database in the container */\r\n export interface CachedDbProps {\r\n /** The total number of blocks in the database. */\r\n readonly totalBlocks: number;\r\n /** the number of blocks of the database that have been downloaded into the CloudCache */\r\n readonly localBlocks: number;\r\n /** the number of blocks from this database that have been modified in the CloudCache and need to be uploaded. */\r\n readonly dirtyBlocks: number;\r\n /** If true, the database currently has transactions in the WAL file and may not be uploaded until they have been checkPointed. */\r\n readonly transactions: boolean;\r\n /** the state of this database. Indicates whether the database is new or deleted since last upload */\r\n readonly state: \"\" | \"copied\" | \"deleted\";\r\n /** current number of clients that have this database open. */\r\n readonly nClient: number;\r\n /** current number of ongoing prefetches on this database. */\r\n readonly nPrefetch: number;\r\n }\r\n\r\n /** Filter options passed to CloudContainer.queryHttpLog\r\n * @internal\r\n */\r\n export interface BcvHttpLogFilterOptions {\r\n /** only return rows whose ID is >= the provided id */\r\n startFromId?: number;\r\n /** only return rows whose endTime is null OR >= the provided endTime. */\r\n finishedAtOrAfterTime?: string;\r\n /** only return rows with a non-null end_time. */\r\n showOnlyFinished?: boolean;\r\n }\r\n\r\n /** Returned from 'CloudContainer.queryHttpLog' describing a row in the bcv_http_log table.\r\n * @internal\r\n */\r\n export interface BcvHttpLog {\r\n /** Unique, monotonically increasing id value */\r\n readonly id: number;\r\n /** Time request was made, as iso-8601 */\r\n readonly startTime: string;\r\n /** Time reply received, as iso-8601 (may be undefined) */\r\n readonly endTime: string | undefined;\r\n /** \"PUT\", \"GET\", etc. */\r\n readonly method: string;\r\n /** LogId of client that caused this request. Will be \"prefetch\" for prefetch requests. */\r\n readonly logId: string;\r\n /** Log message associated with request */\r\n readonly logmsg: string;\r\n /** URI of request */\r\n readonly uri: string;\r\n /** HTTP response code (e.g. 200) */\r\n readonly httpcode: number;\r\n }\r\n\r\n /** Filter options passed to 'CloudContainer.queryBcvStats'\r\n * @internal\r\n */\r\n interface BcvStatsFilterOptions {\r\n /** if true, adds activeClients, totalClients, ongoingPrefetches, and attachedContainers to the result. */\r\n addClientInformation?: boolean;\r\n }\r\n\r\n /** Returned from 'CloudContainer.queryBcvStats' describing the rows in the bcv_stat table.\r\n * Also gathers additional statistics using the other virtual tables bcv_container, bcv_database such as totalClients, ongoingPrefetches, activeClients and attachedContainers.\r\n * @internal\r\n */\r\n export interface BcvStats {\r\n /** The total number of cache slots that are currently in use or 'locked' by ongoing client read transactions. In daemonless mode, this value is always 0.\r\n * A locked cache slot implies that it is not eligible for eviction in the event of a full cachefile.\r\n * NOTE: All values are returned as hex strings to avoid any possibility of overflow.\r\n */\r\n readonly lockedCacheslots: string;\r\n /** The current number of slots with data in them in the cache. */\r\n readonly populatedCacheslots: string;\r\n /** The configured size of the cache, in number of slots. */\r\n readonly totalCacheslots: string;\r\n /** The total number of clients opened on this cache */\r\n readonly totalClients?: string;\r\n /** The total number of ongoing prefetches on this cache */\r\n readonly ongoingPrefetches?: string;\r\n /** The total number of active clients on this cache. An active client is one which has an open read txn. */\r\n readonly activeClients?: string;\r\n /** The total number of attached containers on this cache. */\r\n readonly attachedContainers?: string;\r\n /** The total amount of memory used by sqlite, in bytes. */\r\n readonly memoryUsed?: string;\r\n /** The maximum value of memoryUsed since high-water mark was last reset, in bytes. */\r\n readonly memoryHighwater?: string;\r\n /** The total amount of memory used for the manifests for each attached container, in bytes. */\r\n readonly memoryManifest?: string;\r\n /** Memory used for arrays of block references held in the daemon on behalf of clients, in bytes.\r\n * @note this value is only present when running in daemon mode.\r\n */\r\n readonly memoryClientArray?: string;\r\n /** Memory used by manifests that are kept in memory only for clients use - not the newest manifest\r\n * available held by the container object, in bytes.\r\n * @note this value is only present when running in daemon mode.\r\n */\r\n readonly memoryClientManifest?: string;\r\n }\r\n\r\n /** The base name of a CloudSqlite database, without any version information.\r\n * The name must conform to the following constraints:\r\n * - Case-insensitively unique among all databases in the same [[CloudSqlite.CloudContainer]]\r\n * - Between 1 and 255 characters in length.\r\n * - A legal filename on both [Windows](https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file#naming-conventions) and UNIX.\r\n * - Contain none of the following characters: forward or backward slash, period, single or double quote, backtick, colon, and \"#\".\r\n * - Begin or end with a whitespace character.\r\n * @see [[CloudSqlite.DbFullName]] for the fully-specified name, including version information.\r\n */\r\n export type DbName = string;\r\n\r\n /** The fully-specified name of a CloudSqlite database, combining its [[CloudSqlite.DbName]] and [[CloudSqlite.DbVersion]] in the format \"name:version\".\r\n */\r\n export type DbFullName = string;\r\n\r\n /** A [semver](https://github.com/npm/node-semver) string describing the version of a database, e.g., \"4.2.11\".\r\n */\r\n export type DbVersion = string;\r\n\r\n /** A [semver string](https://github.com/npm/node-semver?tab=readme-ov-file#ranges) describing a range of acceptable versions,\r\n * e.g., \">=1.2.7 <1.3.0\".\r\n */\r\n export type DbVersionRange = string;\r\n\r\n /** Specifies the name and version of a CloudSqlite database.\r\n */\r\n export interface DbNameAndVersion {\r\n /** The name of the database */\r\n readonly dbName: DbName;\r\n /** The range of acceptable versions of the database of the specified [[dbName]].\r\n * If omitted, it defaults to the newest available version.\r\n */\r\n readonly version?: DbVersionRange;\r\n }\r\n\r\n export interface LoadProps extends DbNameAndVersion {\r\n readonly container: CloudContainer;\r\n /** If true, allow semver [prerelease versions](https://github.com/npm/node-semver?tab=readme-ov-file#prerelease-tags), e.g., \"1.4.2-beta.0\".\r\n * By default, only released version are allowed.\r\n */\r\n readonly includePrerelease?: boolean;\r\n /** If true, start a prefetch operation whenever this database is opened, to begin downloading pages of the database before they are needed. */\r\n readonly prefetch?: boolean;\r\n }\r\n\r\n /**\r\n * The release increment for a version number, used as part of [[CloudSqlite.CreateNewDbVersionArgs]] to specify the kind of version to create.\r\n * @see [semver.ReleaseType](https://www.npmjs.com/package/semver)\r\n */\r\n export type SemverIncrement = \"major\" | \"minor\" | \"patch\" | \"premajor\" | \"preminor\" | \"prepatch\" | \"prerelease\";\r\n\r\n /**\r\n * Arguments supplied to [[CloudSqlite.createNewDbVersion]].\r\n */\r\n export interface CreateNewDbVersionArgs {\r\n readonly fromDb: DbNameAndVersion;\r\n /** The type of version increment to apply to the source version. */\r\n readonly versionType: SemverIncrement;\r\n /** For prerelease versions, a string that becomes part of the version name. */\r\n readonly identifier?: string;\r\n }\r\n\r\n /** The name of a CloudSqlite database within a CloudContainer. */\r\n export interface DbNameProp {\r\n /** the name of the database within the CloudContainer.\r\n * @note names of databases within a CloudContainer are always **case sensitive** on all platforms.*/\r\n dbName: DbFullName;\r\n }\r\n\r\n export type TransferDirection = \"upload\" | \"download\";\r\n export interface TransferProgress {\r\n /** a user-supplied progress function called during the transfer operation. Return a non-0 value to abort the transfer. */\r\n onProgress?: (loaded: number, total: number) => number;\r\n }\r\n\r\n export interface CloudHttpProps {\r\n /** The number of simultaneous HTTP requests. Default is 6. */\r\n nRequests?: number;\r\n }\r\n\r\n export interface PrefetchProps extends CloudHttpProps {\r\n /** timeout between requests, in milliseconds. Default is 100. */\r\n timeout?: number;\r\n /** The number of prefetch requests to issue while there is foreground activity. Default is 3. */\r\n minRequests?: number;\r\n }\r\n\r\n export interface TransferDbProps extends DbNameProp, TransferProgress, CloudHttpProps {\r\n /** the name of the local file to access the database for uploading and downloading */\r\n localFileName: LocalFileName;\r\n };\r\n\r\n /** Properties for creating a CloudCache. */\r\n export interface CacheProps extends CloudHttpProps {\r\n /** full path of directory for cache to store its files. Must be on a (preferably fast) local drive, and must be empty when the cache is first created. */\r\n rootDir: string;\r\n /** name of this cache. It is possible to have more than one CloudCache in the same session, but each must have a unique name. */\r\n name: string;\r\n /** maximum cache Size. Must be a number followed by either M (for megabytes) or G (for gigabytes.) Default is 1G */\r\n cacheSize?: string;\r\n /** turn on diagnostics for `curl` (outputs to stderr) */\r\n curlDiagnostics?: boolean;\r\n }\r\n\r\n /** Parameters used to obtain the write lock on a cloud container */\r\n export interface ObtainLockParams {\r\n /** a string that identifies me to others if I hold the lock while they attempt to acquire it. */\r\n user?: string;\r\n /** number of times to retry in the event the lock currently held by someone else.\r\n * After this number of attempts, `onFailure` is called. Default is 20.\r\n */\r\n nRetries: number;\r\n /** Delay between retries, in milliseconds. Default is 100. */\r\n retryDelayMs: number;\r\n /** function called if lock cannot be obtained after all retries. It is called with the name of the user currently holding the lock and\r\n * generally is expected that the user will be consulted whether to wait further.\r\n * If this function returns \"stop\", an exception will be thrown. Otherwise the retry cycle is restarted.\r\n */\r\n onFailure?: WriteLockBusyHandler;\r\n }\r\n\r\n /** @internal */\r\n export interface LockAndOpenArgs extends SQLiteDb.WithOpenDbArgs {\r\n /** a string that identifies me to others if I hold the lock while they attempt to acquire it. */\r\n user: string;\r\n /** the name of the database within the container */\r\n dbName: string;\r\n /** the CloudContainer on which the operation will be performed */\r\n container: CloudContainer;\r\n /** if present, function called when the write lock is currently held by another user. */\r\n busyHandler?: WriteLockBusyHandler;\r\n /** if present, open mode for Db. Default is ReadWrite */\r\n openMode?: OpenMode;\r\n }\r\n\r\n /** Logging categories for `CloudCache.setLogMask` */\r\n export enum LoggingMask {\r\n /** log all HTTP requests and responses */\r\n HTTP = 0x01,\r\n /** log as blocks become dirty and must be uploaded */\r\n DirtyBlocks = 0x02,\r\n /** log as blocks are added to the delete list */\r\n AddToDelete = 0x04,\r\n /** log container lifecycle events (e.g. authorization requests, disconnects, and state transitions) */\r\n LifecycleEvents = 0x08,\r\n /** Turn on all logging categories */\r\n All = 0xff,\r\n /** Disable logging */\r\n None = 0,\r\n }\r\n\r\n /**\r\n * A local cache for storing data downloaded from many CloudSqlite databases. This object refers to a directory on the local filesystem\r\n * and is used to **connect** CloudContainers so they may be accessed. It maintains the state of the local copy of\r\n * the downloaded data from SQLiteDbs in CloudContainers across sessions.\r\n *\r\n * Notes:\r\n * - CloudCaches have a name, used internally by CloudSqlite, that must be unique. CloudCaches are created and maintained via [[CloudCaches.getCache]].\r\n * - All CloudContainers connected to a given CloudCache must have the same block size, as determined by the first CloudContainer connected.\r\n * - they have a maximum size that limits the amount of disk space they can consume. When the maximum size of a CloudCache is reached,\r\n * the least recently used blocks are removed to make room for new blocks.\r\n * - CloudCaches may only be used by a single process at a time. An exception is thrown if you attempt to access a CloudCache from a\r\n * second process if it is already in use by another process. Note: for a readonly CloudCache, a \"daemon\" process can be used to\r\n * share a CloudCache across processes. See its documentation for details.\r\n * - Generally, it is expected that there only be a few CloudCaches and they be shared by all applications. Each CloudCache can consume\r\n * its maximum disk space, so controlling system-wide disk usage is complicated. The only reason to make a new CloudCache is either\r\n * for containers with a different block size, or to purposely control local disk space usage for a specific set of containers.\r\n * - The contents of the cache directory are entirely controlled by CloudSqlite and should be empty when the cache is\r\n * first created and never modified directly thereafter.\r\n */\r\n export interface CloudCache {\r\n /** `true` if this CloudCache is connected to a daemon process */\r\n get isDaemon(): boolean;\r\n /** The name for this CloudCache. */\r\n get name(): string;\r\n /** The root directory of this CloudCache on a local drive. */\r\n get rootDir(): LocalDirName;\r\n /** A guid for this CloudCache. It is assigned when the CloudCache is first created and used for acquiring write locks. */\r\n get guid(): GuidString;\r\n /** Configure logging for this CloudCache.\r\n * @param mask A bitmask of `LoggingMask` values\r\n * @note this method does nothing if [[isDaemon]] is true. Daemon logging is configured when the daemon is started.\r\n * @note HTTP logging can be happen on multiple threads and may be buffered. To see buffered log messages, periodically call\r\n * `[[IModelHost.flushLog]]\r\n */\r\n setLogMask(mask: number): void;\r\n /**\r\n * destroy this CloudCache to end this session. All currently connected CloudContainers are disconnected first.\r\n * @note this does *not* delete the local directory. Its contents are maintained so it can be used in future sessions.\r\n * @note this function is automatically called on [[IModelHost.shutdown]], so it is only called directly for tests.\r\n * @internal\r\n */\r\n destroy(): void;\r\n }\r\n\r\n export interface CleanDeletedBlocksOptions {\r\n /**\r\n * Any block that was marked as unused before this number of seconds ago will be deleted. Specifying a non-zero\r\n * value gives a period of time for other clients to refresh their manifests and stop using the now-garbage blocks. Otherwise they may get\r\n * a 404 error. Default is 1 hour.\r\n */\r\n nSeconds?: number;\r\n /** if enabled, outputs verbose logs about the cleanup process. Output includes blocks determined eligible for deletion.\r\n * @default false\r\n */\r\n debugLogging?: boolean;\r\n /** If true, iterates over all blobs in the cloud container to add blocks that are 'orphaned' to the delete list in the manifest.\r\n * Orphaned blocks are created when a client abruptly halts, is disconnected, or encounters an error while uploading a change.\r\n * If false, the search for 'orphaned' blocks is skipped and only any blocks which are already on the delete list are deleted.\r\n * @default true\r\n */\r\n findOrphanedBlocks?: boolean;\r\n /**\r\n * a user-supplied progress function called during the cleanup operation. While the search for orphaned blocks occurs, nDeleted will be 0 and nTotalToDelete will be 1.\r\n * Once the search is complete and orphaned blocks begin being deleted, nDeleted will be the number of blocks deleted and nTotalToDelete will be the total number of blocks to delete.\r\n * If the return value is 1, the job will be cancelled and progress will be saved. If one or more blocks have already been deleted, then a new manifest file is uploaded saving the progress of the delete job.\r\n * Return any other non-0 value to cancel the job without saving progress.\r\n */\r\n onProgress?: (nDeleted: number, nTotalToDelete: number) => Promise<number>;\r\n }\r\n\r\n /**\r\n * A CloudSqlite container that may be connected to a CloudCache. A CloudContainer maps a container in a cloud blob-storage\r\n * account to a local cache, so that the contents of a database in the container may be accessed as if it were a local file.\r\n *\r\n * Notes:\r\n * - all methods and accessors of this interface (other than `initializeContainer`) require that the `connect` method be successfully called first.\r\n * Otherwise they will throw an exception or return meaningless values.\r\n * - before a SQLiteDb in a container may be opened for write access, the container's write lock must be held (see [[acquireWriteLock]].)\r\n * - a single CloudContainer may hold more than one SQLiteDb, but often they are 1:1.\r\n * - the write lock is per-Container, not per-SQLiteDb (which is the reason they are often 1:1)\r\n * - the accessToken (a SAS key) member provides time limited, restricted, access to the container. It must be refreshed before it expires.\r\n * - when a CloudContainer is created, it may either be readonly or writeable. If a container is never meant to be used for writes,\r\n * it is slightly more efficient to indicate that by passing `writeable: false`\r\n */\r\n export interface CloudContainer {\r\n onConnect?: (container: CloudContainer, cache: CloudCache) => void;\r\n onConnected?: (container: CloudContainer) => void;\r\n onDisconnect?: (container: CloudContainer, detach: boolean) => void;\r\n onDisconnected?: (container: CloudContainer, detach: boolean) => void;\r\n\r\n readonly cache?: CloudCache;\r\n /** the baseUri of this container */\r\n get baseUri(): string;\r\n /** the storageType of this container */\r\n get storageType(): string;\r\n /** The ContainerId within a storage account. */\r\n get containerId(): string;\r\n /** The *alias* to identify this CloudContainer in a CloudCache. Usually just the ContainerId. */\r\n get alias(): string;\r\n /** The logId. */\r\n get logId(): string;\r\n /** The time that the write lock expires. Of the form 'YYYY-MM-DDTHH:MM:SS.000Z' in UTC.\r\n * Returns empty string if write lock is not held.\r\n */\r\n get writeLockExpires(): string;\r\n /** true if this CloudContainer is currently connected to a CloudCache via the `connect` method. */\r\n get isConnected(): boolean;\r\n /** true if this CloudContainer was created with the `writeable` flag (and its `accessToken` supplies write access). */\r\n get isWriteable(): boolean;\r\n /** true if this container is public (doesn't require authorization ). */\r\n get isPublic(): boolean;\r\n /** true if this CloudContainer currently holds the write lock for its container in the cloud. */\r\n get hasWriteLock(): boolean;\r\n /** true if this CloudContainer has local changes that have not be uploaded to its container in the cloud. */\r\n get hasLocalChanges(): boolean;\r\n /** The current accessToken providing access to the cloud container */\r\n get accessToken(): string;\r\n set accessToken(val: string);\r\n /** Get the number of garbage blocks in this container that can be purged. */\r\n get garbageBlocks(): number;\r\n /** The block size for this CloudContainer. */\r\n get blockSize(): number;\r\n\r\n /**\r\n * initialize a cloud blob-store container to be used as a new CloudContainer. This creates the container's manifest of its contents, and should be\r\n * performed on an empty container. If an existing manifest is present, it is destroyed and a new one is created (essentially emptying the container.)\r\n */\r\n initializeContainer(args: { checksumBlockNames?: boolean, blockSize: number }): void;\r\n\r\n /**\r\n * Connect this CloudContainer to a CloudCache for accessing and/or modifying its contents.\r\n * @note A CloudCache is a local directory holding copies of information from the cloud. It is persistent across sessions,\r\n * but this method must be called each session to (re)establish the connection to the CloudCache. If the CloudCache was previously populated,\r\n * this method may be called and will succeed *even when offline* or without a valid `accessToken`.\r\n */\r\n connect(cache: CloudCache): void;\r\n\r\n /**\r\n * Attempt to acquire the write lock for this CloudContainer. For this to succeed:\r\n * 1. it must be connected to a `CloudCache`\r\n * 2. this CloudContainer must have been constructed with `writeable: true`\r\n * 3. the `accessToken` must authorize write access\r\n * 4. no other process may be holding an unexpired write lock\r\n * @throws if any of the above conditions fail\r\n * @note Write locks *expire* after the duration specified in the `durationSeconds` property of the constructor argument, in case a process\r\n * crashes or otherwise fails to release the lock. Calling `acquireWriteLock` with the lock already held resets the lock duration from the current time,\r\n * so long running processes should call this method periodically to ensure their lock doesn't expire (they should also make sure their accessToken is refreshed\r\n * before it expires.)\r\n * @note on success, the container is synchronized with its contents in the cloud before the promise resolves.\r\n * @param user An identifier of the process/user locking the CloudContainer. In the event of a write lock\r\n * collision, this string will be included in the exception string of the *other* process attempting to obtain a write lock so that users may identify who currently holds\r\n * the lock.\r\n */\r\n acquireWriteLock(user: string): void;\r\n\r\n /**\r\n * Release the write lock if it is currently held.\r\n *\r\n * Notes:\r\n * - if there are local changes that have not been uploaded, they are automatically uploaded before the write lock is released.\r\n * - if the write lock is not held, this method does nothing.\r\n */\r\n releaseWriteLock(): void;\r\n\r\n /**\r\n * Destroy any currently valid write lock from this or any other process. This is obviously very dangerous and defeats the purpose of write locking.\r\n * This method exists only for administrator tools to clear a failed process without waiting for the expiration period. It can also be useful for tests.\r\n * For this to succeed, all of the conditions of `acquireWriteLock` must be true other than #4.\r\n */\r\n clearWriteLock(): void;\r\n\r\n /**\r\n * Abandon any local changes in this container. If the write lock is currently held, it is released.\r\n * This function fails with BE_SQLITE_BUSY if there are any open read or write transactions on *any* database in the container.\r\n */\r\n abandonChanges(): void;\r\n\r\n /**\r\n * Disconnect this CloudContainer from its CloudCache. There must be no open databases from this container. Leaves the container's contents in the\r\n * CloudCache so it is available for future sessions.\r\n * @note This function does nothing (and does not throw) if the CloudContainer is not connected to a CloudCache.\r\n */\r\n disconnect(args?: {\r\n /** if true removes the container from the CloudCache, otherwise Leaves the container in the CloudCache so it is available for future sessions. */\r\n detach?: boolean;\r\n }): void;\r\n\r\n /**\r\n * Poll cloud storage for changes from other processes.\r\n *\r\n * Notes:\r\n * - no changes made by other processes are visible to this CloudContainer unless/until this method is called.\r\n * - this is automatically called whenever the write lock is obtained to ensure all changes are against the latest version.\r\n * - any existing transactions on databases within the container will continue to use the old version of the manifest and therefore see no new changes pulled in.\r\n */\r\n checkForChanges(): void;\r\n\r\n /**\r\n * Upload any changed blocks from the databases in this CloudContainer.\r\n * @note this is called automatically from `releaseWriteLock` before the write lock is released. It is only necessary to call this directly if you\r\n * wish to upload changes while the write lock is still held.\r\n * @see hasLocalChanges\r\n */\r\n uploadChanges(): Promise<void>;\r\n\r\n /**\r\n * Create a copy of an existing database within this CloudContainer with a new name.\r\n * @note CloudSqlite uses copy-on-write semantics for this operation. That is, this method merely makes a\r\n * new entry in the manifest with the new name that *shares* all of its blocks with the original database.\r\n * If either database subsequently changes, the only modified blocks are not shared.\r\n */\r\n copyDatabase(dbName: string, toAlias: string): Promise<void>;\r\n\r\n /** Remove a database from this CloudContainer. Unused blocks are moved to the delete list in the manifest.\r\n * @see [[CloudSqlite.cleanDeletedBlocks]] to actually delete the blocks from the delete list.\r\n */\r\n deleteDatabase(dbName: string): Promise<void>;\r\n\r\n /** Get the list of database names in this CloudContainer.\r\n * @param globArg if present, filter the results with SQLite [GLOB](https://www.sqlite.org/lang_expr.html#glob) operator.\r\n */\r\n queryDatabases(globArg?: string): string[];\r\n\r\n /**\r\n * Get the status of a specific database in this CloudContainer.\r\n * @param dbName the name of the database of interest\r\n */\r\n queryDatabase(dbName: string): CachedDbProps | undefined;\r\n\r\n /**\r\n * query the bcv_http_log table\r\n * @note the bcv_http_log table contains one row for each HTTP request made by the VFS or connected daemon.\r\n * @note Entries are automatically removed from the table on a FIFO basis. By default entries which are 1 hr old will be removed.\r\n * @internal\r\n */\r\n queryHttpLog(filterOptions?: BcvHttpLogFilterOptions): CloudSqlite.BcvHttpLog[];\r\n\r\n /**\r\n * query the bcv_stat table.\r\n * @internal\r\n */\r\n queryBcvStats(filterOptions?: BcvStatsFilterOptions): CloudSqlite.BcvStats;\r\n\r\n /**\r\n * Get the SHA1 hash of the content of a database.\r\n * @param dbName the name of the database of interest\r\n * @note the hash will be empty if the database does not exist\r\n */\r\n queryDatabaseHash(dbName: string): string;\r\n }\r\n\r\n /**\r\n * Object returned by [[CloudSqlite.startCloudPrefetch]].\r\n * It holds a promise that is fulfilled when a Prefetch is completed. May also be used to cancel an in-progress prefetch.\r\n */\r\n export interface CloudPrefetch {\r\n readonly cloudContainer: CloudContainer;\r\n readonly dbName: string;\r\n\r\n /** Cancel a currently pending prefetch. The promise will be resolved immediately after this call. */\r\n cancel(): void;\r\n\r\n /**\r\n * Promise that is resolved when the prefetch completes or is cancelled. Await this promise to ensure that the\r\n * database has been fully downloaded before going offline, for example.\r\n *\r\n * Notes:\r\n * - resolves to `true` if the prefetch completed and the entire database is local, or `false` if it was aborted or failed.\r\n * - it is *not* rejected on `cancel`. Some progress may (or may not) have been made by the request.\r\n * - To monitor the progress being made during prefetch, call `CloudContainer.queryDatabase` periodically.\r\n */\r\n promise: Promise<boolean>;\r\n }\r\n\r\n /**\r\n * Clean any unused deleted blocks from cloud storage. Unused deleted blocks can accumulate in cloud storage in a couple of ways:\r\n * 1) When a database is updated, a subset of its blocks are replaced by new versions, sometimes leaving the originals unused.\r\n * 2) A database is deleted with [[CloudContainer.deleteDatabase]]\r\n * In both cases, the blocks are not deleted immediately. Instead, they are scheduled for deletion at some later time.\r\n * Calling this method deletes all blocks in the cloud container for which the scheduled deletion time has passed.\r\n * @param container the CloudContainer to be cleaned. Must be connected and hold the write lock.\r\n * @param options options for the cleanup operation. @see CloudSqlite.CleanDeletedBlocksOptions\r\n */\r\n export async function cleanDeletedBlocks(container: CloudContainer, options: CleanDeletedBlocksOptions): Promise<void> {\r\n let timer: NodeJS.Timeout | undefined;\r\n try {\r\n const cleanJob = new NativeLibrary.nativeLib.CancellableCloudSqliteJob(\"cleanup\", container, options);\r\n let total = 0;\r\n const onProgress = options?.onProgress;\r\n if (onProgress) {\r\n timer = setInterval(async () => { // set an interval timer to show progress every 250ms\r\n const progress = cleanJob.getProgress();\r\n total = progress.total;\r\n const result = await onProgress(progress.loaded, progress.total);\r\n if (result === 1)\r\n cleanJob.stopAndSaveProgress();\r\n else if (result !== 0)\r\n cleanJob.cancelTransfer();\r\n }, 250);\r\n }\r\n await cleanJob.promise;\r\n await onProgress?.(total, total); // make sure we call progress func one last time when download completes\r\n container.checkForChanges(); // re-read the manifest so the number of garbage blocks is updated.\r\n } catch (err: any) {\r\n if (err.message === \"cancelled\")\r\n err.errorNumber = BriefcaseStatus.DownloadCancelled;\r\n\r\n throw err;\r\n } finally {\r\n if (timer)\r\n clearInterval(timer);\r\n }\r\n }\r\n\r\n /** @internal */\r\n export async function transferDb(direction: TransferDirection, container: CloudContainer, props: TransferDbProps) {\r\n if (direction === \"download\")\r\n mkdirSync(dirname(props.localFileName), { recursive: true }); // make sure the directory exists before starting download\r\n\r\n let timer: NodeJS.Timeout | undefined;\r\n try {\r\n const transfer = new NativeLibrary.nativeLib.CancellableCloudSqliteJob(direction, container, props);\r\n let total = 0;\r\n const onProgress = props.onProgress;\r\n if (onProgress) {\r\n timer = setInterval(async () => { // set an interval timer to show progress every 250ms\r\n const progress = transfer.getProgress();\r\n total = progress.total;\r\n if (onProgress(progress.loaded, progress.total))\r\n transfer.cancelTransfer();\r\n }, 250);\r\n }\r\n await transfer.promise;\r\n onProgress?.(total, total); // make sure we call progress func one last time when download completes\r\n } catch (err: any) {\r\n if (err.message === \"cancelled\")\r\n err.errorNumber = BriefcaseStatus.DownloadCancelled;\r\n\r\n throw err;\r\n } finally {\r\n if (timer)\r\n clearInterval(timer);\r\n\r\n }\r\n }\r\n\r\n /** Upload a local SQLite database file into a CloudContainer.\r\n * @param container the CloudContainer holding the database. Must be connected.\r\n * @param props the properties that describe the database to be downloaded, plus optionally an `onProgress` function.\r\n * @note this function requires that the write lock be held on the container\r\n */\r\n export async function uploadDb(container: CloudContainer, props: TransferDbProps): Promise<void> {\r\n await transferDb(\"upload\", container, props);\r\n container.checkForChanges(); // re-read the manifest so the database is available locally.\r\n }\r\n\r\n /** Download a database from a CloudContainer.\r\n * @param container the CloudContainer holding the database. Must be connected.\r\n * @param props the properties that describe the database to be downloaded, plus optionally an `onProgress` function.\r\n * @returns a Promise that is resolved when the download completes.\r\n * @note the download is \"restartable.\" If the transfer is aborted and then re-requested, it will continue from where\r\n * it left off rather than re-downloading the entire file.\r\n */\r\n export async function downloadDb(container: CloudContainer, props: TransferDbProps): Promise<void> {\r\n await transferDb(\"download\", container, props);\r\n }\r\n\r\n /** Optional method to be called when an attempt to acquire the write lock fails because another user currently holds it.\r\n * @param lockedBy The identifier supplied by the application/user that currently holds the lock.\r\n * @param expires a stringified Date (in local time) indicating when the lock will expire.\r\n * @return \"stop\" to give up and stop retrying. Generally, it's a good idea to wait for some time before returning.\r\n */\r\n export type WriteLockBusyHandler = (lockedBy: string, expires: string) => Promise<void | \"stop\">;\r\n\r\n /**\r\n * Attempt to acquire the write lock for a container, with retries.\r\n * If write lock is held by another user, call busyHandler if supplied. If no busyHandler, or handler returns \"stop\", throw. Otherwise try again.\r\n * @note if write lock is already held by the same user, this function will refresh the write lock's expiry time.\r\n * @param user the name to be displayed to other users in the event they attempt to obtain the lock while it is held by us\r\n * @param container the CloudContainer for which the lock is to be acquired\r\n * @param busyHandler if present, function called when the write lock is currently held by another user.\r\n * @throws if [[container]] is not connected to a CloudCache.\r\n */\r\n export async function acquireWriteLock(args: { user: string, container: CloudContainer, busyHandler?: WriteLockBusyHandler }) {\r\n const container = args.container as CloudContainerInternal;\r\n while (true) {\r\n try {\r\n // if the write is already held:\r\n // - by the same user, just update the write lock expiry (by calling acquireWriteLock).\r\n // - by another user, throw an error\r\n if (container.hasWriteLock && container.writeLockHeldBy !== args.user)\r\n CloudSqliteError.throwError<CloudSqliteError.WriteLockHeld>(\"write-lock-held\", {\r\n message: \"lock in use\", errorNumber: 5,\r\n lockedBy: container.writeLockHeldBy ?? \"\",\r\n expires: container.writeLockExpires\r\n });\r\n\r\n container.acquireWriteLock(args.user);\r\n container.writeLockHeldBy = args.user;\r\n return;\r\n } catch (e: any) {\r\n if (e.errorNumber === 5 && args.busyHandler && \"stop\" !== await args.busyHandler(e.lockedBy, e.expires)) // 5 === BE_SQLITE_BUSY\r\n continue; // busy handler wants to try again\r\n\r\n CloudSqliteError.throwError(\"write-lock-held\", { message: e.message, ...e });\r\n }\r\n }\r\n }\r\n\r\n export function getWriteLockHeldBy(container: CloudContainer) {\r\n return (container as CloudContainerInternal).writeLockHeldBy;\r\n }\r\n\r\n /** release the write lock on a container. */\r\n export function releaseWriteLock(container: CloudContainer) {\r\n container.releaseWriteLock();\r\n (container as CloudContainerInternal).writeLockHeldBy = undefined;\r\n }\r\n\r\n /**\r\n * Perform an asynchronous write operation on a CloudContainer with the write lock held.\r\n * 1. if write lock is already held by the current user, refresh write lock's expiry time, call operation and return.\r\n * 2. attempt to acquire the write lock, with retries. Throw if unable to obtain write lock.\r\n * 3. perform the operation\r\n * 3.a if the operation throws, abandon all changes and re-throw\r\n * 4. release the write lock.\r\n * 5. return value from operation\r\n * @param user the name to be displayed to other users in the event they attempt to obtain the lock while it is held by us\r\n * @param container the CloudContainer for which the lock is to be acquired\r\n * @param operation an asynchronous operation performed with the write lock held.\r\n * @param busyHandler if present, function called when the write lock is currently held by another user.\r\n * @returns a Promise with the result of `operation`\r\n */\r\n export async function withWriteLock<T>(args: { user: string, container: CloudContainer, busyHandler?: WriteLockBusyHandler }, operation: () => Promise<T>): Promise<T> {\r\n const containerInternal = args.container as CloudContainerInternal;\r\n const wasLockedBy = containerInternal.writeLockHeldBy;\r\n await acquireWriteLock(args);\r\n try {\r\n if (wasLockedBy === args.user) // If the user already had the write lock, then don't release it.\r\n return await operation();\r\n const val = await operation(); // wait for work to finish or fail\r\n releaseWriteLock(containerInternal);\r\n return val;\r\n } catch (e) {\r\n args.container.abandonChanges(); // if operation threw, abandon all changes\r\n containerInternal.writeLockHeldBy = undefined;\r\n throw e;\r\n }\r\n }\r\n\r\n /**\r\n * Parse the name of a Db stored in a CloudContainer into the dbName and version number. A single CloudContainer may hold\r\n * many versions of the same Db. The name of the Db in the CloudContainer is in the format \"name:version\". This\r\n * function splits them into separate strings.\r\n */\r\n export function parseDbFileName(dbFileName: DbFullName): { dbName: DbName, version: DbVersion } {\r\n const parts = dbFileName.split(\":\");\r\n return { dbName: parts[0], version: parts[1] ?? \"\" };\r\n }\r\n\r\n export function validateDbVersion(version?: DbVersion) {\r\n version = version ?? \"0.0.0\";\r\n const opts = { loose: true, includePrerelease: true };\r\n // clean allows prerelease, so try it first. If that fails attempt to coerce it (coerce strips prerelease even if you say not to.)\r\n const semVersion = semver.clean(version, opts) ?? semver.coerce(version, opts)?.version;\r\n if (!semVersion)\r\n CloudSqliteError.throwError(\"invalid-name\", { message: \"invalid version specification\" });\r\n version = semVersion;\r\n return version;\r\n }\r\n\r\n export function isSemverPrerelease(version: string) {\r\n return semver.major(version) === 0 || semver.prerelease(version);\r\n }\r\n\r\n export function isSemverEditable(dbFullName: string, container: CloudContainer) {\r\n return isSemverPrerelease(parseDbFileName(dbFullName).version) || container.queryDatabase(dbFullName)?.state === \"copied\";\r\n }\r\n\r\n /** Create a dbName for a database from its base name and version. This will be in the format \"name:version\" */\r\n export function makeSemverName(dbName: DbName, version?: DbVersion): DbName {\r\n return `${dbName}:${validateDbVersion(version)}`;\r\n }\r\n\r\n /** query the databases in the supplied container for the highest SemVer match according to the version range. Throws if no version available for the range. */\r\n export function querySemverMatch(props: LoadProps): DbFullName {\r\n const dbName = props.dbName;\r\n const dbs = props.container.queryDatabases(`${dbName}*`); // get all databases that start with dbName\r\n\r\n const versions = [];\r\n for (const db of dbs) {\r\n const thisDb = parseDbFileName(db);\r\n if (thisDb.dbName === dbName && \"string\" === typeof thisDb.version && thisDb.version.length > 0)\r\n versions.push(thisDb.version);\r\n }\r\n\r\n if (versions.length === 0)\r\n versions[0] = \"0.0.0\";\r\n\r\n const range = props.version ?? \"*\";\r\n try {\r\n const version = semver.maxSatisfying(versions, range, { loose: true, includePrerelease: props.includePrerelease });\r\n if (version)\r\n return `${dbName}:${version}`;\r\n } catch { }\r\n\r\n CloudSqliteError.throwError(\"no-version-available\", { message: `No version of '${dbName}' available for \"${range}\"`, ...props });\r\n }\r\n\r\n export async function createNewDbVersion(container: CloudContainer, args: CreateNewDbVersionArgs): Promise<{ oldDb: DbNameAndVersion, newDb: DbNameAndVersion }> {\r\n const oldFullName = CloudSqlite.querySemverMatch({ container, ...args.fromDb });\r\n const oldDb = CloudSqlite.parseDbFileName(oldFullName);\r\n const newVersion = semver.inc(oldDb.version, args.versionType, args.identifier);\r\n if (!newVersion)\r\n CloudSqliteError.throwError(\"invalid-name\", { message: `cannot create new version for ${oldFullName}`, dbName: oldFullName, ...args });\r\n\r\n const newName = makeSemverName(oldDb.dbName, newVersion);\r\n try {\r\n await container.copyDatabase(oldFullName, newName);\r\n } catch (e: unknown) {\r\n CloudSqliteError.throwError(\"copy-error\", { message: `Error attempting to create new version ${newName} from ${oldFullName}`, ...args, cause: e });\r\n }\r\n // return the old and new db names and versions\r\n return { oldDb, newDb: { dbName: oldDb.dbName, version: newVersion } };\r\n }\r\n\r\n /** Arguments to create or find a CloudCache */\r\n export interface CreateCloudCacheArg {\r\n /** The name of the CloudCache. CloudCache names must be unique. */\r\n cacheName: string;\r\n /** A string that specifies the maximum size of the CloudCache. It should be a number followed by \"K\",\r\n * \"M\" \"G\", or \"T\". Default is \"10G\". */\r\n cacheSize?: string;\r\n /** A local directory in temporary storage for the CloudCache. If not supplied, it is a subdirectory called `cacheName`\r\n * in the `CloudCaches` temporary directory.\r\n * If the directory does not exist, it is created. */\r\n cacheDir?: string;\r\n }\r\n\r\n /** The collection of currently extant `CloudCache`s, by name. */\r\n export class CloudCaches {\r\n private static readonly cloudCaches = new Map<string, CloudCache>();\r\n\r\n /** create a new CloudCache */\r\n private static makeCache(args: CreateCloudCacheArg): CloudCache {\r\n const cacheName = args.cacheName;\r\n const rootDir = args.cacheDir ?? join(IModelHost.profileDir, \"CloudCaches\", cacheName);\r\n IModelJsFs.recursiveMkDirSync(rootDir);\r\n const cache = new NativeLibrary.nativeLib.CloudCache({ rootDir, name: cacheName, cacheSize: args.cacheSize ?? \"10G\" });\r\n if (Logger.getLevel(\"CloudSqlite\") === LogLevel.Trace) {\r\n cache.setLogMask(CloudSqlite.LoggingMask.All);\r\n }\r\n this.cloudCaches.set(cacheName, cache);\r\n return cache;\r\n }\r\n\r\n /** find a CloudCache by name, if it exists */\r\n public static findCache(cacheName: string): CloudCache | undefined {\r\n return this.cloudCaches.get(cacheName);\r\n }\r\n /** @internal */\r\n public static dropCache(cacheName: string): CloudCache | undefined {\r\n const cache = this.cloudCaches.get(cacheName);\r\n this.cloudCaches.delete(cacheName);\r\n return cache;\r\n }\r\n /** called by IModelHost after shutdown.\r\n * @internal\r\n */\r\n public static destroy() {\r\n this.cloudCaches.forEach((cache) => cache.destroy());\r\n this.cloudCaches.clear();\r\n }\r\n\r\n /** Get a CloudCache by name. If the CloudCache doesn't yet exist, it is created. */\r\n public static getCache(args: CreateCloudCacheArg): CloudCache {\r\n return this.cloudCaches.get(args.cacheName) ?? this.makeCache(args);\r\n }\r\n }\r\n\r\n /** Class that provides convenient local access to a SQLite database in a CloudContainer. */\r\n export class DbAccess<DbType extends VersionedSqliteDb, ReadMethods = DbType, WriteMethods = DbType> {\r\n /** The name of the database within the cloud container. */\r\n public readonly dbName: string;\r\n /** Parameters for obtaining the write lock for this container. */\r\n public readonly lockParams: ObtainLockParams = {\r\n user: \"\",\r\n nRetries: 20,\r\n retryDelayMs: 100,\r\n };\r\n protected static _cacheName = \"default-64k\";\r\n protected _container: CloudContainer;\r\n protected _cloudDb: DbType;\r\n private _writeLockProxy?: PickAsyncMethods<WriteMethods>;\r\n private _readerProxy?: PickMethods<ReadMethods>;\r\n private get _ctor() { return this.constructor as typeof DbAccess; }\r\n\r\n /** @internal */\r\n public static getCacheForClass() {\r\n return CloudCaches.getCache({ cacheName: this._cacheName });\r\n }\r\n private _cache?: CloudCache;\r\n /** only for tests\r\n * @internal\r\n */\r\n public setCache(cache: CloudCache) {\r\n this._cache = cache;\r\n }\r\n /** @internal */\r\n public getCache(): CloudCache {\r\n return this._cache ??= this._ctor.getCacheForClass();\r\n }\r\n /** @internal */\r\n public getCloudDb(): DbType {\r\n return this._cloudDb;\r\n }\r\n\r\n /**\r\n * The token that grants access to the cloud container for this DbAccess. If it does not grant write permissions, all\r\n * write operations will fail. It should be refreshed (via a timer) before it expires.\r\n */\r\n public get sasToken() { return this._container.accessToken; }\r\n public set sasToken(token: AccessToken) { this._container.accessToken = token; }\r\n\r\n /** the container for this DbAccess. It is automatically connected to the CloudCache whenever it is accessed. */\r\n public get container(): CloudContainer {\r\n const container = this._container;\r\n if (!container.isConnected)\r\n container.connect(this.getCache());\r\n return container;\r\n }\r\n\r\n /** Start a prefetch operation to download all the blocks for the VersionedSqliteDb */\r\n public startPrefetch(): CloudPrefetch {\r\n return startCloudPrefetch(this.container, this.dbName);\r\n }\r\n\r\n /** Create a new DbAccess for a database stored in a cloud container. */\r\n public constructor(args: {\r\n /** The Constructor for DbType. */\r\n dbType: Constructor<DbType>;\r\n /** The properties of the cloud container holding the database. */\r\n props: ContainerAccessProps;\r\n /** The name of the database within the container. */\r\n dbName: string;\r\n }) {\r\n this._container = createCloudContainer({ writeable: true, ...args.props });\r\n this._cloudDb = new args.dbType(args.props);\r\n this.dbName = args.dbName;\r\n this.lockParams.user = IModelHost.userMoniker;\r\n }\r\n\r\n /** Close the database for this DbAccess, if it is open */\r\n public closeDb() {\r\n if (this._cloudDb.isOpen)\r\n this._cloudDb.closeDb();\r\n }\r\n\r\n /** Close the database for this DbAccess if it is opened, and disconnect this `DbAccess from its CloudContainer. */\r\n public close() {\r\n this.closeDb();\r\n this._container.disconnect();\r\n }\r\n\r\n /**\r\n * Initialize a cloud container to hold VersionedSqliteDbs. The container must first be created by [[createBlobContainer]].\r\n * This function creates and uploads an empty database into the container.\r\n * @note this deletes any existing content in the container.\r\n */\r\n protected static async _initializeDb(args: { dbType: typeof VersionedSqliteDb, props: ContainerProps, dbName: string, blockSize?: \"64K\" | \"4M\" }) {\r\n const container = createCloudContainer({ ...args.props, writeable: true, accessToken: args.props.accessToken ?? await CloudSqlite.requestToken(args.props) });\r\n container.initializeContainer({ blockSize: args.blockSize === \"4M\" ? 4 * 1024 * 1024 : 64 * 1024 });\r\n container.connect(CloudCaches.getCache({ cacheName: this._cacheName }));\r\n await withWriteLock({ user: \"initialize\", container }, async () => {\r\n const localFileName = join(KnownLocations.tmpdir, \"blank.db\");\r\n args.dbType.createNewDb(localFileName, args);\r\n await transferDb(\"upload\", container, { dbName: args.dbName, localFileName });\r\n unlinkSync(localFileName);\r\n });\r\n container.disconnect({ detach: true });\r\n }\r\n\r\n /**\r\n * Create a new BlobContainer from the BlobContainer service to hold one or more VersionedSqliteDbs.\r\n * @returns A ContainerProps that describes the newly created container.\r\n * @note the current user must have administrator rights to create containers.\r\n */\r\n protected static async createBlobContainer(args: Omit<BlobContainer.CreateNewContainerProps, \"userToken\">): Promise<CloudSqlite.ContainerProps> {\r\n const auth = verifyService(\"Authorization Client\", IModelHost.authorizationClient);\r\n const userToken = await auth.getAccessToken();\r\n const cloudContainer = await getBlobService().create({ scope: args.scope, metadata: args.metadata, userToken });\r\n return { baseUri: cloudContainer.baseUri, containerId: cloudContainer.containerId, storageType: cloudContainer.provider };\r\n }\r\n\r\n /**\r\n * Synchronize the local cache of this database with any changes by made by others.\r\n * @note This is called automatically whenever any write operation is performed on this DbAccess. It is only necessary to\r\n * call this directly if you have not changed the database recently, but wish to perform a readonly operation and want to\r\n * ensure it is up-to-date as of now.\r\n * @note There is no guarantee that the database is up-to-date even immediately after calling this method, since others\r\n * may be modifying it at any time.\r\n */\r\n public synchronizeWithCloud() {\r\n this.closeDb();\r\n this.container.checkForChanges();\r\n }\r\n\r\n /**\r\n * Ensure that the database controlled by this `DbAccess` is open for read access and return the database object.\r\n * @note if the database is already open (either for read or write), this method merely returns the database object.\r\n */\r\n public openForRead(): DbType {\r\n if (!this._cloudDb.isOpen)\r\n this._cloudDb.openDb(this.dbName, OpenMode.Readonly, this.container);\r\n return this._cloudDb;\r\n }\r\n\r\n /**\r\n * Perform an operation on this database with the lock held and the database opened for write\r\n * @param operationName the name of the operation. Only used for logging.\r\n * @param operation a function called with the lock held and the database open for write.\r\n * @returns A promise that resolves to the the return value of `operation`.\r\n * @see `SQLiteDb.withLockedContainer`\r\n * @note Most uses of `CloudSqliteDbAccess` require that the lock not be held by any operation for long. Make sure you don't\r\n * do any avoidable or time consuming work in your operation function.\r\n */\r\n public async withLockedDb<T>(args: { operationName: string, openMode?: OpenMode, user?: string }, operation: () => Promise<T>): Promise<T> {\r\n let nRetries = this.lockParams.nRetries;\r\n const cacheGuid = this.container.cache!.guid; // eslint-disable-line @typescript-eslint/no-non-null-assertion\r\n const user = args.user ?? this.lockParams.user ?? cacheGuid;\r\n const timer = new StopWatch(undefined, true);\r\n const showMs = () => `(${timer.elapsed.milliseconds}ms)`;\r\n\r\n const busyHandler = async (lockedBy: string, expires: string): Promise<void | \"stop\"> => {\r\n if (--nRetries <= 0) {\r\n if (\"stop\" === await this.lockParams.onFailure?.(lockedBy, expires))\r\n return \"stop\";\r\n nRetries = this.lockParams.nRetries;\r\n }\r\n const delay = this.lockParams.retryDelayMs;\r\n logInfo(`lock retry for ${cacheGuid} after ${showMs()}, waiting ${delay}`);\r\n await BeDuration.fromMilliseconds(delay).wait();\r\n };\r\n\r\n this.closeDb(); // in case it is currently open for read.\r\n let lockObtained = false;\r\n const operationName = args.operationName;\r\n try {\r\n return await this._cloudDb.withLockedContainer({ user, dbName: this.dbName, container: this.container, busyHandler, openMode: args.openMode }, async () => {\r\n lockObtained = true;\r\n logInfo(`lock acquired by ${cacheGuid} for ${operationName} ${showMs()}`);\r\n return operation();\r\n });\r\n } finally {\r\n if (lockObtained)\r\n logInfo(`lock released by ${cacheGuid} after ${operationName} ${showMs()} `);\r\n else\r\n logError(`could not obtain lock for ${cacheGuid} to perform ${operationName} ${showMs()} `);\r\n }\r\n }\r\n\r\n /** get a method member, by name, from the database object. Throws if not a Function. */\r\n private getDbMethod(methodName: string): (...args: any[]) => any {\r\n const fn = (this._cloudDb as any)[methodName];\r\n if (typeof fn !== \"function\")\r\n CloudSqliteError.throwError(\"not-a-function\", { message: `illegal method name ${methodName}`, dbName: this.dbName });\r\n return fn;\r\n }\r\n\r\n /**\r\n * A Proxy Object to call a writeable async method on the cloud database controlled by this `DbAccess`.\r\n *\r\n * Whenever a method is called through this Proxy, it will:\r\n * - attempt to acquire the write lock on the container\r\n * - open the database for write\r\n * - call the method\r\n * - close the database\r\n * - upload changes\r\n * - release the write lock.\r\n *\r\n * @see [[withLockedDb]]\r\n */\r\n public get writeLocker() {\r\n return this._writeLockProxy ??= new Proxy(this, {\r\n get(access, operationName: string) {\r\n const fn = access.getDbMethod(operationName);\r\n return async (...args: any[]) => access.withLockedDb({ operationName, user: RpcTrace.currentActivity?.user }, fn.bind(access._cloudDb, ...args));\r\n },\r\n }) as PickAsyncMethods<WriteMethods>;\r\n }\r\n\r\n /**\r\n * A Proxy Object to call a synchronous readonly method on the database controlled by this `DbAccess`.\r\n * Whenever a method is called through this Proxy, it will first ensure that the database is opened for at least read access.\r\n */\r\n public get reader() {\r\n return this._readerProxy ??= new Proxy(this, {\r\n get(access, methodName: string) {\r\n const fn = access.getDbMethod(methodName);\r\n return (...args: any[]) => fn.call(access.openForRead(), ...args);\r\n },\r\n }) as PickMethods<ReadMethods>;\r\n }\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"CloudSqlite.js","sourceRoot":"","sources":["../../src/CloudSqlite.ts"],"names":[],"mappings":";AAAA;;;+FAG+F;AAC/F;;GAEG;;;AAEH,iCAAiC;AACjC,2BAA2C;AAC3C,+BAAqC;AACrC,8DAAyD;AACzD,sDAE6B;AAC7B,oDAAmF;AACnF,iEAAuD;AACvD,6CAA0D;AAC1D,6CAA0C;AAC1C,2CAAyC;AAIzC,4GAA4G;AAE5G;;;GAGG;AACH,IAAiB,WAAW,CA4qC3B;AA5qCD,WAAiB,WAAW;IAE1B,MAAM,OAAO,GAAG,CAAC,GAAW,EAAE,EAAE,CAAC,qBAAM,CAAC,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC;IACpE,MAAM,QAAQ,GAAG,CAAC,GAAW,EAAE,EAAE,CAAC,qBAAM,CAAC,QAAQ,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC;IAItE;;;;OAIG;IACH,SAAgB,iBAAiB,CAAI,CAAI,EAAE,CAAc,EAAE,KAAW;QACpE,OAAO,MAAM,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;IAClF,CAAC;IAFe,6BAAiB,oBAEhC,CAAA;IAED,SAAS,aAAa,CAAI,WAAmB,EAAE,OAAsB;QACnE,IAAI,SAAS,KAAK,OAAO;YACvB,8BAAgB,CAAC,UAAU,CAAC,uBAAuB,EAAE,EAAE,OAAO,EAAE,GAAG,WAAW,2BAA2B,EAAE,CAAC,CAAC;QAC/G,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,SAAgB,cAAc;QAC5B,OAAO,aAAa,CAAC,eAAe,EAAE,oCAAa,CAAC,OAAO,CAAC,CAAC;IAC/D,CAAC;IAFe,0BAAc,iBAE7B,CAAA;IAED;;;OAGG;IACI,KAAK,UAAU,YAAY,CAAC,IAAsB;QACvD,mKAAmK;QACnK,IAAI,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,uBAAU,CAAC,cAAc,EAAE,CAAC;QACpF,IAAI,SAAS,KAAK,EAAE;YAClB,SAAS,GAAG,kBAAQ,CAAC,eAAe,EAAE,WAAW,IAAI,EAAE,CAAC;QAC1D,MAAM,QAAQ,GAAG,MAAM,cAAc,EAAE,CAAC,YAAY,CAAC,EAAE,GAAG,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;QAC7E,OAAO,QAAQ,EAAE,KAAK,IAAI,EAAE,CAAC;IAC/B,CAAC;IAPqB,wBAAY,eAOjC,CAAA;IASD,SAAgB,yBAAyB,CAAC,IAAY,EAAE,GAAW;QACjE,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,IAAI;YACtB,8BAAgB,CAAC,UAAU,CAAC,cAAc,EAAE,EAAE,OAAO,EAAE,GAAG,GAAG,KAAK,IAAI,2CAA2C,EAAE,CAAC,CAAC;IACzH,CAAC;IAHe,qCAAyB,4BAGxC,CAAA;IAED,SAAgB,cAAc,CAAC,MAAc;QAC3C,IAAI,MAAM,KAAK,EAAE,IAAI,MAAM,CAAC,MAAM,GAAG,GAAG,IAAI,kCAAkC,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,kCAAkC,CAAC,IAAI,CAAC,MAAM,CAAC;YAC5I,8BAAgB,CAAC,UAAU,CAAC,cAAc,EAAE,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,EAAE,CAAC,CAAC;QAErF,yBAAyB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC9C,CAAC;IALe,0BAAc,iBAK7B,CAAA;IAED;;;;;OAKG;IACH,SAAgB,oBAAoB,CAAC,IAA2I;QAC9K,MAAM,SAAS,GAAG,IAAI,+BAAa,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAA2B,CAAC;QAC7F,sHAAsH;QACtH,mFAAmF;QACnF,iBAAiB,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QACtC,iBAAiB,CAAC,SAAS,EAAE,gBAAgB,CAAC,CAAC;QAE/C,MAAM,cAAc,GAAG,CAAC,SAAS,KAAK,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,oBAAoB;QAC1H,SAAS,CAAC,iBAAiB,GAAG,IAAI,CAAC,iBAAiB,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC,oBAAoB;QAErF,qEAAqE;QACrE,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,cAAc,GAAG,CAAC,EAAE,CAAC;YACzC,MAAM,UAAU,GAAG,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC;YAC3G,MAAM,SAAS,GAAG,KAAK,IAAI,EAAE;gBAC3B,IAAI,QAAiC,CAAC;gBACtC,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,OAAO,IAAI,UAAU,CAAC,WAAW,GAAG,CAAC;gBAChE,IAAI,CAAC;oBACH,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,IAAI,WAAW,CAAC,YAAY,CAAC,CAAC,UAAU,CAAC,CAAC;oBACxE,OAAO,CAAC,iCAAiC,GAAG,EAAE,CAAC,CAAC;gBAClD,CAAC;gBAAC,OAAO,GAAQ,EAAE,CAAC;oBAClB,QAAQ,CAAC,wCAAwC,GAAG,KAAK,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;gBAC1E,CAAC;gBACD,SAAS,CAAC,WAAW,GAAG,QAAQ,IAAI,EAAE,CAAC;YACzC,CAAC,CAAC;YACF,MAAM,cAAc,GAAG,GAAG,EAAE;gBAC1B,SAAS,CAAC,KAAK,GAAG,UAAU,CAAC,KAAK,IAAI,EAAE;oBACtC,SAAS,CAAC,cAAc,GAAG,SAAS,EAAE,CAAC,CAAC,wEAAwE;oBAChH,MAAM,SAAS,CAAC,cAAc,CAAC;oBAC/B,SAAS,CAAC,cAAc,GAAG,SAAS,CAAC;oBACrC,cAAc,EAAE,CAAC,CAAC,wBAAwB;gBAC5C,CAAC,EAAE,cAAc,GAAG,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,6CAA6C;YAClF,CAAC,CAAC;YACF,iBAAiB,CAAC,SAAS,EAAE,aAAa,EAAE,cAAc,CAAC,CAAC,CAAC,6DAA6D;YAC1H,iBAAiB,CAAC,SAAS,EAAE,cAAc,EAAE,GAAG,EAAE;gBAChD,IAAI,SAAS,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;oBAClC,YAAY,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;oBAC9B,SAAS,CAAC,KAAK,GAAG,SAAS,CAAC;gBAC9B,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAzCe,gCAAoB,uBAyCnC,CAAA;IAED,yFAAyF;IACzF,SAAgB,kBAAkB,CAAC,SAAyB,EAAE,MAAc,EAAE,IAAoB;QAChG,OAAO,IAAI,+BAAa,CAAC,SAAS,CAAC,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;IAC5E,CAAC;IAFe,8BAAkB,qBAEjC,CAAA;IA6NA,CAAC;IA6CF,qDAAqD;IACrD,IAAY,WAaX;IAbD,WAAY,WAAW;QACrB,0CAA0C;QAC1C,6CAAW,CAAA;QACX,sDAAsD;QACtD,2DAAkB,CAAA;QAClB,iDAAiD;QACjD,2DAAkB,CAAA;QAClB,uGAAuG;QACvG,mEAAsB,CAAA;QACtB,qCAAqC;QACrC,6CAAU,CAAA;QACV,sBAAsB;QACtB,6CAAQ,CAAA;IACV,CAAC,EAbW,WAAW,GAAX,uBAAW,KAAX,uBAAW,QAatB;IAoRD;;;;;;;;OAQG;IACI,KAAK,UAAU,kBAAkB,CAAC,SAAyB,EAAE,OAAkC;QACpG,IAAI,KAAiC,CAAC;QACtC,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,IAAI,+BAAa,CAAC,SAAS,CAAC,yBAAyB,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;YACtG,IAAI,KAAK,GAAG,CAAC,CAAC;YACd,MAAM,UAAU,GAAG,OAAO,EAAE,UAAU,CAAC;YACvC,IAAI,UAAU,EAAE,CAAC;gBACf,KAAK,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;oBAC7B,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;oBACxC,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC;oBACvB,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC;oBACjE,IAAI,MAAM,KAAK,CAAC;wBACd,QAAQ,CAAC,mBAAmB,EAAE,CAAC;yBAC5B,IAAI,MAAM,KAAK,CAAC;wBACnB,QAAQ,CAAC,cAAc,EAAE,CAAC;gBAC9B,CAAC,EAAE,GAAG,CAAC,CAAC;YACV,CAAC;YACD,MAAM,QAAQ,CAAC,OAAO,CAAC;YACvB,MAAM,UAAU,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,wEAAwE;YAC1G,SAAS,CAAC,eAAe,EAAE,CAAC,CAAC,mEAAmE;QAClG,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,IAAI,GAAG,CAAC,OAAO,KAAK,WAAW;gBAC7B,GAAG,CAAC,WAAW,GAAG,8BAAe,CAAC,iBAAiB,CAAC;YAEtD,MAAM,GAAG,CAAC;QACZ,CAAC;gBAAS,CAAC;YACT,IAAI,KAAK;gBACP,aAAa,CAAC,KAAK,CAAC,CAAC;QACzB,CAAC;IACH,CAAC;IA7BqB,8BAAkB,qBA6BvC,CAAA;IAED,gBAAgB;IACT,KAAK,UAAU,UAAU,CAAC,SAA4B,EAAE,SAAyB,EAAE,KAAsB;QAC9G,IAAI,SAAS,KAAK,UAAU;YAC1B,IAAA,cAAS,EAAC,IAAA,cAAO,EAAC,KAAK,CAAC,aAAa,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,0DAA0D;QAE1H,IAAI,KAAiC,CAAC;QACtC,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,IAAI,+BAAa,CAAC,SAAS,CAAC,yBAAyB,CAAC,SAAS,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;YACpG,IAAI,KAAK,GAAG,CAAC,CAAC;YACd,MAAM,UAAU,GAAG,KAAK,CAAC,UAAU,CAAC;YACpC,IAAI,UAAU,EAAE,CAAC;gBACf,KAAK,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;oBAC7B,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;oBACxC,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC;oBACvB,IAAI,UAAU,CAAC,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,KAAK,CAAC;wBAC7C,QAAQ,CAAC,cAAc,EAAE,CAAC;gBAC9B,CAAC,EAAE,GAAG,CAAC,CAAC;YACV,CAAC;YACD,MAAM,QAAQ,CAAC,OAAO,CAAC;YACvB,UAAU,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,wEAAwE;QACtG,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,IAAI,GAAG,CAAC,OAAO,KAAK,WAAW;gBAC7B,GAAG,CAAC,WAAW,GAAG,8BAAe,CAAC,iBAAiB,CAAC;YAEtD,MAAM,GAAG,CAAC;QACZ,CAAC;gBAAS,CAAC;YACT,IAAI,KAAK;gBACP,aAAa,CAAC,KAAK,CAAC,CAAC;QAEzB,CAAC;IACH,CAAC;IA7BqB,sBAAU,aA6B/B,CAAA;IAED;;;;OAIG;IACI,KAAK,UAAU,QAAQ,CAAC,SAAyB,EAAE,KAAsB;QAC9E,MAAM,UAAU,CAAC,QAAQ,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;QAC7C,SAAS,CAAC,eAAe,EAAE,CAAC,CAAC,6DAA6D;IAC5F,CAAC;IAHqB,oBAAQ,WAG7B,CAAA;IAED;;;;;;OAMG;IACI,KAAK,UAAU,UAAU,CAAC,SAAyB,EAAE,KAAsB;QAChF,MAAM,UAAU,CAAC,UAAU,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;IACjD,CAAC;IAFqB,sBAAU,aAE/B,CAAA;IASD;;;;;;;;QAQI;IACG,KAAK,UAAU,gBAAgB,CAAC,IAAqF;QAC1H,MAAM,SAAS,GAAG,IAAI,CAAC,SAAmC,CAAC;QAC3D,OAAO,IAAI,EAAE,CAAC;YACZ,IAAI,CAAC;gBACH,gCAAgC;gBAChC,uFAAuF;gBACvF,oCAAoC;gBACpC,IAAI,SAAS,CAAC,YAAY,IAAI,SAAS,CAAC,eAAe,KAAK,IAAI,CAAC,IAAI;oBACnE,8BAAgB,CAAC,UAAU,CAAiC,iBAAiB,EAAE;wBAC7E,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,CAAC;wBACtC,QAAQ,EAAE,SAAS,CAAC,eAAe,IAAI,EAAE;wBACzC,OAAO,EAAE,SAAS,CAAC,gBAAgB;qBACpC,CAAC,CAAC;gBAEL,SAAS,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACtC,SAAS,CAAC,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC;gBACtC,OAAO;YACT,CAAC;YAAC,OAAO,CAAM,EAAE,CAAC;gBAChB,IAAI,CAAC,CAAC,WAAW,KAAK,CAAC,IAAI,IAAI,CAAC,WAAW,IAAI,MAAM,KAAK,MAAM,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,uBAAuB;oBAC9H,SAAS,CAAC,kCAAkC;gBAE9C,8BAAgB,CAAC,UAAU,CAAC,iBAAiB,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;YAC/E,CAAC;QACH,CAAC;IACH,CAAC;IAxBqB,4BAAgB,mBAwBrC,CAAA;IAED,SAAgB,kBAAkB,CAAC,SAAyB;QAC1D,OAAQ,SAAoC,CAAC,eAAe,CAAC;IAC/D,CAAC;IAFe,8BAAkB,qBAEjC,CAAA;IAED,6CAA6C;IAC7C,SAAgB,gBAAgB,CAAC,SAAyB;QACxD,SAAS,CAAC,gBAAgB,EAAE,CAAC;QAC5B,SAAoC,CAAC,eAAe,GAAG,SAAS,CAAC;IACpE,CAAC;IAHe,4BAAgB,mBAG/B,CAAA;IAED;;;;;;;;;;;;;MAaE;IACK,KAAK,UAAU,aAAa,CAAI,IAAqF,EAAE,SAA2B;QACvJ,MAAM,iBAAiB,GAAG,IAAI,CAAC,SAAmC,CAAC;QACnE,MAAM,WAAW,GAAG,iBAAiB,CAAC,eAAe,CAAC;QACtD,MAAM,gBAAgB,CAAC,IAAI,CAAC,CAAC;QAC7B,IAAI,CAAC;YACH,IAAI,WAAW,KAAK,IAAI,CAAC,IAAI,EAAE,iEAAiE;gBAC9F,OAAO,MAAM,SAAS,EAAE,CAAC;YAC3B,MAAM,GAAG,GAAG,MAAM,SAAS,EAAE,CAAC,CAAC,kCAAkC;YACjE,gBAAgB,CAAC,iBAAiB,CAAC,CAAC;YACpC,OAAO,GAAG,CAAC;QACb,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,IAAI,CAAC,SAAS,CAAC,cAAc,EAAE,CAAC,CAAE,0CAA0C;YAC5E,iBAAiB,CAAC,eAAe,GAAG,SAAS,CAAC;YAC9C,MAAM,CAAC,CAAC;QACV,CAAC;IACH,CAAC;IAfqB,yBAAa,gBAelC,CAAA;IAED;;;;OAIG;IACH,SAAgB,eAAe,CAAC,UAAsB;QACpD,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACpC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;IACvD,CAAC;IAHe,2BAAe,kBAG9B,CAAA;IAED,SAAgB,iBAAiB,CAAC,OAAmB;QACnD,OAAO,GAAG,OAAO,IAAI,OAAO,CAAC;QAC7B,MAAM,IAAI,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAAC;QACtD,kIAAkI;QAClI,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,OAAO,CAAC;QACxF,IAAI,CAAC,UAAU;YACb,8BAAgB,CAAC,UAAU,CAAC,cAAc,EAAE,EAAE,OAAO,EAAE,+BAA+B,EAAE,CAAC,CAAC;QAC5F,OAAO,GAAG,UAAU,CAAC;QACrB,OAAO,OAAO,CAAC;IACjB,CAAC;IATe,6BAAiB,oBAShC,CAAA;IAED,SAAgB,kBAAkB,CAAC,OAAe;QAChD,OAAO,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;IACnE,CAAC;IAFe,8BAAkB,qBAEjC,CAAA;IAED,SAAgB,gBAAgB,CAAC,UAAkB,EAAE,SAAyB;QAC5E,OAAO,kBAAkB,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,IAAI,SAAS,CAAC,aAAa,CAAC,UAAU,CAAC,EAAE,KAAK,KAAK,QAAQ,CAAC;IAC5H,CAAC;IAFe,4BAAgB,mBAE/B,CAAA;IAED,+GAA+G;IAC/G,SAAgB,cAAc,CAAC,MAAc,EAAE,OAAmB;QAChE,OAAO,GAAG,MAAM,IAAI,iBAAiB,CAAC,OAAO,CAAC,EAAE,CAAC;IACnD,CAAC;IAFe,0BAAc,iBAE7B,CAAA;IAED,+JAA+J;IAC/J,SAAgB,gBAAgB,CAAC,KAAgB;QAC/C,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;QAC5B,MAAM,GAAG,GAAG,KAAK,CAAC,SAAS,CAAC,cAAc,CAAC,GAAG,MAAM,GAAG,CAAC,CAAC,CAAC,2CAA2C;QAErG,MAAM,QAAQ,GAAG,EAAE,CAAC;QACpB,KAAK,MAAM,EAAE,IAAI,GAAG,EAAE,CAAC;YACrB,MAAM,MAAM,GAAG,eAAe,CAAC,EAAE,CAAC,CAAC;YACnC,IAAI,MAAM,CAAC,MAAM,KAAK,MAAM,IAAI,QAAQ,KAAK,OAAO,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC;gBAC7F,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAClC,CAAC;QAED,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;YACvB,QAAQ,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC;QAExB,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,IAAI,GAAG,CAAC;QACnC,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,CAAC,aAAa,CAAC,QAAQ,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,iBAAiB,EAAE,KAAK,CAAC,iBAAiB,EAAE,CAAC,CAAC;YACnH,IAAI,OAAO;gBACT,OAAO,GAAG,MAAM,IAAI,OAAO,EAAE,CAAC;QAClC,CAAC;QAAC,MAAM,CAAC,CAAC,CAAC;QAEX,8BAAgB,CAAC,UAAU,CAAC,sBAAsB,EAAE,EAAE,OAAO,EAAE,kBAAkB,MAAM,oBAAoB,KAAK,GAAG,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC;IACnI,CAAC;IAtBe,4BAAgB,mBAsB/B,CAAA;IAEM,KAAK,UAAU,kBAAkB,CAAC,SAAyB,EAAE,IAA4B;QAC9F,MAAM,WAAW,GAAG,WAAW,CAAC,gBAAgB,CAAC,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QAChF,MAAM,KAAK,GAAG,WAAW,CAAC,eAAe,CAAC,WAAW,CAAC,CAAC;QACvD,MAAM,UAAU,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QAChF,IAAI,CAAC,UAAU;YACb,8BAAgB,CAAC,UAAU,CAAC,cAAc,EAAE,EAAE,OAAO,EAAE,iCAAiC,WAAW,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC;QAEzI,MAAM,OAAO,GAAG,cAAc,CAAC,KAAK,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;QACzD,IAAI,CAAC;YACH,MAAM,SAAS,CAAC,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QACrD,CAAC;QAAC,OAAO,CAAU,EAAE,CAAC;YACpB,8BAAgB,CAAC,UAAU,CAAC,YAAY,EAAE,EAAE,OAAO,EAAE,0CAA0C,OAAO,SAAS,WAAW,EAAE,EAAE,GAAG,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;QACrJ,CAAC;QACD,+CAA+C;QAC/C,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,EAAE,CAAC;IACzE,CAAC;IAfqB,8BAAkB,qBAevC,CAAA;IAeD,iEAAiE;IACjE,MAAa,WAAW;QACd,MAAM,CAAU,WAAW,GAAG,IAAI,GAAG,EAAsB,CAAC;QAEpE,8BAA8B;QACtB,MAAM,CAAC,SAAS,CAAC,IAAyB;YAChD,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;YACjC,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,IAAI,IAAA,WAAI,EAAC,uBAAU,CAAC,UAAU,EAAE,aAAa,EAAE,SAAS,CAAC,CAAC;YACvF,uBAAU,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC;YACvC,MAAM,KAAK,GAAG,IAAI,+BAAa,CAAC,SAAS,CAAC,UAAU,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,IAAI,KAAK,EAAE,CAAC,CAAC;YACvH,IAAI,qBAAM,CAAC,QAAQ,CAAC,aAAa,CAAC,KAAK,uBAAQ,CAAC,KAAK,EAAE,CAAC;gBACtD,KAAK,CAAC,UAAU,CAAC,WAAW,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;YAChD,CAAC;YACD,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;YACvC,OAAO,KAAK,CAAC;QACf,CAAC;QAED,8CAA8C;QACvC,MAAM,CAAC,SAAS,CAAC,SAAiB;YACvC,OAAO,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACzC,CAAC;QACD,gBAAgB;QACT,MAAM,CAAC,SAAS,CAAC,SAAiB;YACvC,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YAC9C,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;YACnC,OAAO,KAAK,CAAC;QACf,CAAC;QACD;;WAEG;QACI,MAAM,CAAC,OAAO;YACnB,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;YACrD,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;QAC3B,CAAC;QAED,oFAAoF;QAC7E,MAAM,CAAC,QAAQ,CAAC,IAAyB;YAC9C,OAAO,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QACtE,CAAC;;IArCU,uBAAW,cAsCvB,CAAA;IAED,6FAA6F;IAC7F,MAAa,QAAQ;QACnB,2DAA2D;QAC3C,MAAM,CAAS;QAC/B,mEAAmE;QACnD,UAAU,GAAqB;YAC7C,IAAI,EAAE,EAAE;YACR,QAAQ,EAAE,EAAE;YACZ,YAAY,EAAE,GAAG;SAClB,CAAC;QACQ,MAAM,CAAC,UAAU,GAAG,aAAa,CAAC;QAClC,UAAU,CAAiB;QAC3B,QAAQ,CAAS;QACnB,eAAe,CAAkC;QACjD,YAAY,CAA4B;QAChD,IAAY,KAAK,KAAK,OAAO,IAAI,CAAC,WAA8B,CAAC,CAAC,CAAC;QAEnE,gBAAgB;QACT,MAAM,CAAC,gBAAgB;YAC5B,OAAO,WAAW,CAAC,QAAQ,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;QAC9D,CAAC;QACO,MAAM,CAAc;QAC5B;;WAEG;QACI,QAAQ,CAAC,KAAiB;YAC/B,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACtB,CAAC;QACD,gBAAgB;QACT,QAAQ;YACb,OAAO,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,KAAK,CAAC,gBAAgB,EAAE,CAAC;QACvD,CAAC;QACD,gBAAgB;QACT,UAAU;YACf,OAAO,IAAI,CAAC,QAAQ,CAAC;QACvB,CAAC;QAED;;;WAGG;QACH,IAAW,QAAQ,KAAK,OAAO,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC;QAC7D,IAAW,QAAQ,CAAC,KAAkB,IAAI,IAAI,CAAC,UAAU,CAAC,WAAW,GAAG,KAAK,CAAC,CAAC,CAAC;QAEhF,gHAAgH;QAChH,IAAW,SAAS;YAClB,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC;YAClC,IAAI,CAAC,SAAS,CAAC,WAAW;gBACxB,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;YACrC,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,sFAAsF;QAC/E,aAAa;YAClB,OAAO,kBAAkB,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QACzD,CAAC;QAED,wEAAwE;QACxE,YAAmB,IAOlB;YACC,IAAI,CAAC,UAAU,GAAG,oBAAoB,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;YAC3E,IAAI,CAAC,QAAQ,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC5C,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;YAC1B,IAAI,CAAC,UAAU,CAAC,IAAI,GAAG,uBAAU,CAAC,WAAW,CAAC;QAChD,CAAC;QAED,0DAA0D;QACnD,OAAO;YACZ,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM;gBACtB,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;QAC5B,CAAC;QAED,mHAAmH;QAC5G,KAAK;YACV,IAAI,CAAC,OAAO,EAAE,CAAC;YACf,IAAI,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC;QAC/B,CAAC;QAED;;;;WAIG;QACO,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,IAA2G;YAC9I,MAAM,SAAS,GAAG,oBAAoB,CAAC,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW,IAAI,MAAM,WAAW,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAC9J,SAAS,CAAC,mBAAmB,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC;YACpG,SAAS,CAAC,OAAO,CAAC,WAAW,CAAC,QAAQ,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;YACxE,MAAM,aAAa,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,SAAS,EAAE,EAAE,KAAK,IAAI,EAAE;gBAChE,MAAM,aAAa,GAAG,IAAA,WAAI,EAAC,2BAAc,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;gBAC9D,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;gBAC7C,MAAM,UAAU,CAAC,QAAQ,EAAE,SAAS,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,aAAa,EAAE,CAAC,CAAC;gBAC9E,IAAA,eAAU,EAAC,aAAa,CAAC,CAAC;YAC5B,CAAC,CAAC,CAAC;YACH,SAAS,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QACzC,CAAC;QAED;;;;WAIG;QACO,MAAM,CAAC,KAAK,CAAC,mBAAmB,CAAC,IAA8D;YACvG,MAAM,IAAI,GAAG,aAAa,CAAC,sBAAsB,EAAE,uBAAU,CAAC,mBAAmB,CAAC,CAAC;YACnF,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,cAAc,EAAE,CAAC;YAC9C,MAAM,cAAc,GAAG,MAAM,cAAc,EAAE,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,SAAS,EAAE,CAAC,CAAC;YAChH,OAAO,EAAE,OAAO,EAAE,cAAc,CAAC,OAAO,EAAE,WAAW,EAAE,cAAc,CAAC,WAAW,EAAE,WAAW,EAAE,cAAc,CAAC,QAAQ,EAAE,CAAC;QAC5H,CAAC;QAED;;;;;;;WAOG;QACI,oBAAoB;YACzB,IAAI,CAAC,OAAO,EAAE,CAAC;YACf,IAAI,CAAC,SAAS,CAAC,eAAe,EAAE,CAAC;QACnC,CAAC;QAED;;;WAGG;QACI,WAAW;YAChB,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM;gBACvB,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,uBAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;YACvE,OAAO,IAAI,CAAC,QAAQ,CAAC;QACvB,CAAC;QAED;;;;;;;;WAQG;QACI,KAAK,CAAC,YAAY,CAAI,IAAmE,EAAE,SAA2B;YAC3H,IAAI,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;YACxC,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,KAAM,CAAC,IAAI,CAAC,CAAC,+DAA+D;YAC7G,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,IAAI,SAAS,CAAC;YAC5D,MAAM,KAAK,GAAG,IAAI,wBAAS,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;YAC7C,MAAM,MAAM,GAAG,GAAG,EAAE,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,YAAY,KAAK,CAAC;YAEzD,MAAM,WAAW,GAAG,KAAK,EAAE,QAAgB,EAAE,OAAe,EAA0B,EAAE;gBACtF,IAAI,EAAE,QAAQ,IAAI,CAAC,EAAE,CAAC;oBACpB,IAAI,MAAM,KAAK,MAAM,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC;wBACjE,OAAO,MAAM,CAAC;oBAChB,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;gBACtC,CAAC;gBACD,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC;gBAC3C,OAAO,CAAC,kBAAkB,SAAS,UAAU,MAAM,EAAE,aAAa,KAAK,EAAE,CAAC,CAAC;gBAC3E,MAAM,yBAAU,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;YAClD,CAAC,CAAC;YAEF,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,yCAAyC;YACzD,IAAI,YAAY,GAAG,KAAK,CAAC;YACzB,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC;YACzC,IAAI,CAAC;gBACH,OAAO,MAAM,IAAI,CAAC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,WAAW,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,EAAE,KAAK,IAAI,EAAE;oBACxJ,YAAY,GAAG,IAAI,CAAC;oBACpB,OAAO,CAAC,oBAAoB,SAAS,QAAQ,aAAa,IAAI,MAAM,EAAE,EAAE,CAAC,CAAC;oBAC1E,OAAO,SAAS,EAAE,CAAC;gBACrB,CAAC,CAAC,CAAC;YACL,CAAC;oBAAS,CAAC;gBACT,IAAI,YAAY;oBACd,OAAO,CAAC,oBAAoB,SAAS,UAAU,aAAa,IAAI,MAAM,EAAE,GAAG,CAAC,CAAC;;oBAE7E,QAAQ,CAAC,6BAA6B,SAAS,eAAe,aAAa,IAAI,MAAM,EAAE,GAAG,CAAC,CAAC;YAChG,CAAC;QACH,CAAC;QAED,wFAAwF;QAChF,WAAW,CAAC,UAAkB;YACpC,MAAM,EAAE,GAAI,IAAI,CAAC,QAAgB,CAAC,UAAU,CAAC,CAAC;YAC9C,IAAI,OAAO,EAAE,KAAK,UAAU;gBAC1B,8BAAgB,CAAC,UAAU,CAAC,gBAAgB,EAAE,EAAE,OAAO,EAAE,uBAAuB,UAAU,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;YACvH,OAAO,EAAE,CAAC;QACZ,CAAC;QAED;;;;;;;;;;;;WAYG;QACH,IAAW,WAAW;YACpB,OAAO,IAAI,CAAC,eAAe,KAAK,IAAI,KAAK,CAAC,IAAI,EAAE;gBAC9C,GAAG,CAAC,MAAM,EAAE,aAAqB;oBAC/B,MAAM,EAAE,GAAG,MAAM,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC;oBAC7C,OAAO,KAAK,EAAE,GAAG,IAAW,EAAE,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,aAAa,EAAE,IAAI,EAAE,kBAAQ,CAAC,eAAe,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC;gBACnJ,CAAC;aACF,CAAmC,CAAC;QACvC,CAAC;QAED;;;WAGG;QACH,IAAW,MAAM;YACf,OAAO,IAAI,CAAC,YAAY,KAAK,IAAI,KAAK,CAAC,IAAI,EAAE;gBAC3C,GAAG,CAAC,MAAM,EAAE,UAAkB;oBAC5B,MAAM,EAAE,GAAG,MAAM,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;oBAC1C,OAAO,CAAC,GAAG,IAAW,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;gBACpE,CAAC;aACF,CAA6B,CAAC;QACjC,CAAC;;IA7NU,oBAAQ,WA8NpB,CAAA;AACH,CAAC,EA5qCgB,WAAW,2BAAX,WAAW,QA4qC3B","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\n/** @packageDocumentation\n * @module SQLiteDb\n */\n\nimport * as semver from \"semver\";\nimport { mkdirSync, unlinkSync } from \"fs\";\nimport { dirname, join } from \"path\";\nimport { NativeLibrary } from \"@bentley/imodeljs-native\";\nimport {\n AccessToken, BeDuration, BriefcaseStatus, Constructor, GuidString, Logger, LogLevel, OpenMode, Optional, PickAsyncMethods, PickMethods, StopWatch,\n} from \"@itwin/core-bentley\";\nimport { CloudSqliteError, LocalDirName, LocalFileName } from \"@itwin/core-common\";\nimport { BlobContainer } from \"./BlobContainerService\";\nimport { IModelHost, KnownLocations } from \"./IModelHost\";\nimport { IModelJsFs } from \"./IModelJsFs\";\nimport { RpcTrace } from \"./rpc/tracing\";\n\nimport type { SQLiteDb, VersionedSqliteDb } from \"./SQLiteDb\";\n\n// spell:ignore logmsg httpcode daemonless cachefile cacheslots ddthh cloudsqlite premajor preminor prepatch\n\n/**\n * Types for accessing SQLite databases stored in cloud containers.\n * @beta\n */\nexport namespace CloudSqlite {\n\n const logInfo = (msg: string) => Logger.logInfo(\"CloudSqlite\", msg);\n const logError = (msg: string) => Logger.logError(\"CloudSqlite\", msg);\n\n export type RequestTokenArgs = Optional<BlobContainer.RequestTokenProps, \"userToken\">;\n\n /** Add (or replace) a property to an object that is not enumerable.\n * This is important so this member will be skipped when the object is the target of\n * [structuredClone](https://developer.mozilla.org/docs/Web/API/Web_Workers_API/Structured_clone_algorithm)\n * (e.g. when the object is part of an exception that is marshalled across process boundaries.)\n */\n export function addHiddenProperty<T>(o: T, p: PropertyKey, value?: any): T {\n return Object.defineProperty(o, p, { enumerable: false, writable: true, value })\n }\n\n function verifyService<T>(serviceName: string, service: T | undefined): T {\n if (undefined === service)\n CloudSqliteError.throwError(\"service-not-available\", { message: `${serviceName} service is not available` });\n return service;\n }\n\n export function getBlobService(): BlobContainer.ContainerService {\n return verifyService(\"BlobContainer\", BlobContainer.service);\n }\n\n /**\n * Request a new AccessToken for a cloud container using the [[BlobContainer]] service.\n * If the service is unavailable or returns an error, an empty token is returned.\n */\n export async function requestToken(args: RequestTokenArgs): Promise<AccessToken> {\n // allow the userToken to be supplied via args. If not supplied, or blank, use the backend's accessToken. If that fails, use the value from the current RPC request\n let userToken = args.userToken ? args.userToken : await IModelHost.getAccessToken();\n if (userToken === \"\")\n userToken = RpcTrace.currentActivity?.accessToken ?? \"\";\n const response = await getBlobService().requestToken({ ...args, userToken });\n return response?.token ?? \"\";\n }\n\n interface CloudContainerInternal extends CloudContainer {\n timer?: NodeJS.Timeout;\n refreshPromise?: Promise<void>;\n lockExpireSeconds: number;\n writeLockHeldBy?: string;\n }\n\n export function noLeadingOrTrailingSpaces(name: string, msg: string) {\n if (name.trim() !== name)\n CloudSqliteError.throwError(\"invalid-name\", { message: `${msg} [${name}] may not have leading or trailing spaces` });\n }\n\n export function validateDbName(dbName: DbName) {\n if (dbName === \"\" || dbName.length > 255 || /[#\\.<>:\"/\\\\\"`'|?*\\u0000-\\u001F]/g.test(dbName) || /^(con|prn|aux|nul|com\\d|lpt\\d)$/i.test(dbName))\n CloudSqliteError.throwError(\"invalid-name\", { message: \"invalid dbName\", dbName });\n\n noLeadingOrTrailingSpaces(dbName, \"dbName\");\n }\n\n /**\n * Create a new CloudContainer from a ContainerAccessProps. For non-public containers, a valid accessToken must be provided before the container\n * can be used (e.g. via [[CloudSqlite.requestToken]]).\n * @note After the container is successfully connected to a CloudCache, it will begin auto-refreshing its accessToken every `tokenRefreshSeconds` seconds (default is 1 hour)\n * until it is disconnected. However, if the container is public, or if `tokenRefreshSeconds` is <=0, auto-refresh is not enabled.\n */\n export function createCloudContainer(args: ContainerAccessProps & { accessLevel?: BlobContainer.RequestAccessLevel, tokenFn?: (args: RequestTokenArgs) => Promise<AccessToken> }): CloudContainer {\n const container = new NativeLibrary.nativeLib.CloudContainer(args) as CloudContainerInternal;\n // we're going to add these fields to the newly created object. They should *not* be enumerable so they are not copied\n // when the object is cloned (e.g. when included in an exception across processes).\n addHiddenProperty(container, \"timer\");\n addHiddenProperty(container, \"refreshPromise\");\n\n const refreshSeconds = (undefined !== args.tokenRefreshSeconds) ? args.tokenRefreshSeconds : 60 * 60; // default is 1 hour\n container.lockExpireSeconds = args.lockExpireSeconds ?? 60 * 60; // default is 1 hour\n\n // don't refresh tokens for public containers or if refreshSeconds<=0\n if (!args.isPublic && refreshSeconds > 0) {\n const tokenProps = { baseUri: args.baseUri, containerId: args.containerId, accessLevel: args.accessLevel };\n const doRefresh = async () => {\n let newToken: AccessToken | undefined;\n const url = `[${tokenProps.baseUri}/${tokenProps.containerId}]`;\n try {\n newToken = await (args.tokenFn ?? CloudSqlite.requestToken)(tokenProps);\n logInfo(`Refreshed token for container ${url}`);\n } catch (err: any) {\n logError(`Error refreshing token for container ${url}: ${err.message}`);\n }\n container.accessToken = newToken ?? \"\";\n };\n const tokenRefreshFn = () => {\n container.timer = setTimeout(async () => {\n container.refreshPromise = doRefresh(); // this promise is stored on the container so it can be awaited in tests\n await container.refreshPromise;\n container.refreshPromise = undefined;\n tokenRefreshFn(); // schedule next refresh\n }, refreshSeconds * 1000).unref(); // unref so it doesn't keep the process alive\n };\n addHiddenProperty(container, \"onConnected\", tokenRefreshFn); // schedule the first refresh when the container is connected\n addHiddenProperty(container, \"onDisconnect\", () => { // clear the refresh timer when the container is disconnected\n if (container.timer !== undefined) {\n clearTimeout(container.timer);\n container.timer = undefined;\n }\n });\n }\n return container;\n }\n\n /** Begin prefetching all blocks for a database in a CloudContainer in the background. */\n export function startCloudPrefetch(container: CloudContainer, dbName: string, args?: PrefetchProps): CloudPrefetch {\n return new NativeLibrary.nativeLib.CloudPrefetch(container, dbName, args);\n }\n export interface ContainerProps {\n /** The type of storage provider. */\n readonly storageType: \"azure\" | \"google\";\n /** The base URI for the container. */\n readonly baseUri: string;\n /** The name of the container. */\n readonly containerId: string;\n /** true if the container is public (doesn't require authorization) */\n readonly isPublic?: boolean;\n /** access token for container. If not present uses `CloudSqlite.requestToken` */\n accessToken?: string;\n }\n\n /** Properties to access a CloudContainer. */\n export interface ContainerAccessProps extends ContainerProps {\n /** an alias for the container. Defaults to `containerId` */\n readonly alias?: string;\n /** SAS token that grants access to the container. */\n accessToken: string;\n /** if true, container is allowed to request the write lock. */\n readonly writeable?: boolean;\n /** if true, container is attached in \"secure\" mode (blocks are encrypted). Only supported in daemon mode. */\n readonly secure?: boolean;\n /** string attached to log messages from CloudSQLite. This is most useful for identifying usage from daemon mode. */\n readonly logId?: string;\n /** Duration for holding write lock, in seconds. After this time the write lock expires if not refreshed. Default is one hour. */\n readonly lockExpireSeconds?: number;\n /** number of seconds between auto-refresh of access token. If <=0 no auto-refresh. Default is 1 hour (60*60) */\n readonly tokenRefreshSeconds?: number;\n }\n\n /** Returned from `CloudContainer.queryDatabase` describing one database in the container */\n export interface CachedDbProps {\n /** The total number of blocks in the database. */\n readonly totalBlocks: number;\n /** the number of blocks of the database that have been downloaded into the CloudCache */\n readonly localBlocks: number;\n /** the number of blocks from this database that have been modified in the CloudCache and need to be uploaded. */\n readonly dirtyBlocks: number;\n /** If true, the database currently has transactions in the WAL file and may not be uploaded until they have been checkPointed. */\n readonly transactions: boolean;\n /** the state of this database. Indicates whether the database is new or deleted since last upload */\n readonly state: \"\" | \"copied\" | \"deleted\";\n /** current number of clients that have this database open. */\n readonly nClient: number;\n /** current number of ongoing prefetches on this database. */\n readonly nPrefetch: number;\n }\n\n /** Filter options passed to CloudContainer.queryHttpLog\n * @internal\n */\n export interface BcvHttpLogFilterOptions {\n /** only return rows whose ID is >= the provided id */\n startFromId?: number;\n /** only return rows whose endTime is null OR >= the provided endTime. */\n finishedAtOrAfterTime?: string;\n /** only return rows with a non-null end_time. */\n showOnlyFinished?: boolean;\n }\n\n /** Returned from 'CloudContainer.queryHttpLog' describing a row in the bcv_http_log table.\n * @internal\n */\n export interface BcvHttpLog {\n /** Unique, monotonically increasing id value */\n readonly id: number;\n /** Time request was made, as iso-8601 */\n readonly startTime: string;\n /** Time reply received, as iso-8601 (may be undefined) */\n readonly endTime: string | undefined;\n /** \"PUT\", \"GET\", etc. */\n readonly method: string;\n /** LogId of client that caused this request. Will be \"prefetch\" for prefetch requests. */\n readonly logId: string;\n /** Log message associated with request */\n readonly logmsg: string;\n /** URI of request */\n readonly uri: string;\n /** HTTP response code (e.g. 200) */\n readonly httpcode: number;\n }\n\n /** Filter options passed to 'CloudContainer.queryBcvStats'\n * @internal\n */\n interface BcvStatsFilterOptions {\n /** if true, adds activeClients, totalClients, ongoingPrefetches, and attachedContainers to the result. */\n addClientInformation?: boolean;\n }\n\n /** Returned from 'CloudContainer.queryBcvStats' describing the rows in the bcv_stat table.\n * Also gathers additional statistics using the other virtual tables bcv_container, bcv_database such as totalClients, ongoingPrefetches, activeClients and attachedContainers.\n * @internal\n */\n export interface BcvStats {\n /** The total number of cache slots that are currently in use or 'locked' by ongoing client read transactions. In daemonless mode, this value is always 0.\n * A locked cache slot implies that it is not eligible for eviction in the event of a full cachefile.\n * NOTE: All values are returned as hex strings to avoid any possibility of overflow.\n */\n readonly lockedCacheslots: string;\n /** The current number of slots with data in them in the cache. */\n readonly populatedCacheslots: string;\n /** The configured size of the cache, in number of slots. */\n readonly totalCacheslots: string;\n /** The total number of clients opened on this cache */\n readonly totalClients?: string;\n /** The total number of ongoing prefetches on this cache */\n readonly ongoingPrefetches?: string;\n /** The total number of active clients on this cache. An active client is one which has an open read txn. */\n readonly activeClients?: string;\n /** The total number of attached containers on this cache. */\n readonly attachedContainers?: string;\n /** The total amount of memory used by sqlite, in bytes. */\n readonly memoryUsed?: string;\n /** The maximum value of memoryUsed since high-water mark was last reset, in bytes. */\n readonly memoryHighwater?: string;\n /** The total amount of memory used for the manifests for each attached container, in bytes. */\n readonly memoryManifest?: string;\n /** Memory used for arrays of block references held in the daemon on behalf of clients, in bytes.\n * @note this value is only present when running in daemon mode.\n */\n readonly memoryClientArray?: string;\n /** Memory used by manifests that are kept in memory only for clients use - not the newest manifest\n * available held by the container object, in bytes.\n * @note this value is only present when running in daemon mode.\n */\n readonly memoryClientManifest?: string;\n }\n\n /** The base name of a CloudSqlite database, without any version information.\n * The name must conform to the following constraints:\n * - Case-insensitively unique among all databases in the same [[CloudSqlite.CloudContainer]]\n * - Between 1 and 255 characters in length.\n * - A legal filename on both [Windows](https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file#naming-conventions) and UNIX.\n * - Contain none of the following characters: forward or backward slash, period, single or double quote, backtick, colon, and \"#\".\n * - Begin or end with a whitespace character.\n * @see [[CloudSqlite.DbFullName]] for the fully-specified name, including version information.\n */\n export type DbName = string;\n\n /** The fully-specified name of a CloudSqlite database, combining its [[CloudSqlite.DbName]] and [[CloudSqlite.DbVersion]] in the format \"name:version\".\n */\n export type DbFullName = string;\n\n /** A [semver](https://github.com/npm/node-semver) string describing the version of a database, e.g., \"4.2.11\".\n */\n export type DbVersion = string;\n\n /** A [semver string](https://github.com/npm/node-semver?tab=readme-ov-file#ranges) describing a range of acceptable versions,\n * e.g., \">=1.2.7 <1.3.0\".\n */\n export type DbVersionRange = string;\n\n /** Specifies the name and version of a CloudSqlite database.\n */\n export interface DbNameAndVersion {\n /** The name of the database */\n readonly dbName: DbName;\n /** The range of acceptable versions of the database of the specified [[dbName]].\n * If omitted, it defaults to the newest available version.\n */\n readonly version?: DbVersionRange;\n }\n\n export interface LoadProps extends DbNameAndVersion {\n readonly container: CloudContainer;\n /** If true, allow semver [prerelease versions](https://github.com/npm/node-semver?tab=readme-ov-file#prerelease-tags), e.g., \"1.4.2-beta.0\".\n * By default, only released version are allowed.\n */\n readonly includePrerelease?: boolean;\n /** If true, start a prefetch operation whenever this database is opened, to begin downloading pages of the database before they are needed. */\n readonly prefetch?: boolean;\n }\n\n /**\n * The release increment for a version number, used as part of [[CloudSqlite.CreateNewDbVersionArgs]] to specify the kind of version to create.\n * @see [semver.ReleaseType](https://www.npmjs.com/package/semver)\n */\n export type SemverIncrement = \"major\" | \"minor\" | \"patch\" | \"premajor\" | \"preminor\" | \"prepatch\" | \"prerelease\";\n\n /**\n * Arguments supplied to [[CloudSqlite.createNewDbVersion]].\n */\n export interface CreateNewDbVersionArgs {\n readonly fromDb: DbNameAndVersion;\n /** The type of version increment to apply to the source version. */\n readonly versionType: SemverIncrement;\n /** For prerelease versions, a string that becomes part of the version name. */\n readonly identifier?: string;\n }\n\n /** The name of a CloudSqlite database within a CloudContainer. */\n export interface DbNameProp {\n /** the name of the database within the CloudContainer.\n * @note names of databases within a CloudContainer are always **case sensitive** on all platforms.*/\n dbName: DbFullName;\n }\n\n export type TransferDirection = \"upload\" | \"download\";\n export interface TransferProgress {\n /** a user-supplied progress function called during the transfer operation. Return a non-0 value to abort the transfer. */\n onProgress?: (loaded: number, total: number) => number;\n }\n\n export interface CloudHttpProps {\n /** The number of simultaneous HTTP requests. Default is 6. */\n nRequests?: number;\n }\n\n export interface PrefetchProps extends CloudHttpProps {\n /** timeout between requests, in milliseconds. Default is 100. */\n timeout?: number;\n /** The number of prefetch requests to issue while there is foreground activity. Default is 3. */\n minRequests?: number;\n }\n\n export interface TransferDbProps extends DbNameProp, TransferProgress, CloudHttpProps {\n /** the name of the local file to access the database for uploading and downloading */\n localFileName: LocalFileName;\n };\n\n /** Properties for creating a CloudCache. */\n export interface CacheProps extends CloudHttpProps {\n /** full path of directory for cache to store its files. Must be on a (preferably fast) local drive, and must be empty when the cache is first created. */\n rootDir: string;\n /** name of this cache. It is possible to have more than one CloudCache in the same session, but each must have a unique name. */\n name: string;\n /** maximum cache Size. Must be a number followed by either M (for megabytes) or G (for gigabytes.) Default is 1G */\n cacheSize?: string;\n /** turn on diagnostics for `curl` (outputs to stderr) */\n curlDiagnostics?: boolean;\n }\n\n /** Parameters used to obtain the write lock on a cloud container */\n export interface ObtainLockParams {\n /** a string that identifies me to others if I hold the lock while they attempt to acquire it. */\n user?: string;\n /** number of times to retry in the event the lock currently held by someone else.\n * After this number of attempts, `onFailure` is called. Default is 20.\n */\n nRetries: number;\n /** Delay between retries, in milliseconds. Default is 100. */\n retryDelayMs: number;\n /** function called if lock cannot be obtained after all retries. It is called with the name of the user currently holding the lock and\n * generally is expected that the user will be consulted whether to wait further.\n * If this function returns \"stop\", an exception will be thrown. Otherwise the retry cycle is restarted.\n */\n onFailure?: WriteLockBusyHandler;\n }\n\n /** @internal */\n export interface LockAndOpenArgs extends SQLiteDb.WithOpenDbArgs {\n /** a string that identifies me to others if I hold the lock while they attempt to acquire it. */\n user: string;\n /** the name of the database within the container */\n dbName: string;\n /** the CloudContainer on which the operation will be performed */\n container: CloudContainer;\n /** if present, function called when the write lock is currently held by another user. */\n busyHandler?: WriteLockBusyHandler;\n /** if present, open mode for Db. Default is ReadWrite */\n openMode?: OpenMode;\n }\n\n /** Logging categories for `CloudCache.setLogMask` */\n export enum LoggingMask {\n /** log all HTTP requests and responses */\n HTTP = 0x01,\n /** log as blocks become dirty and must be uploaded */\n DirtyBlocks = 0x02,\n /** log as blocks are added to the delete list */\n AddToDelete = 0x04,\n /** log container lifecycle events (e.g. authorization requests, disconnects, and state transitions) */\n LifecycleEvents = 0x08,\n /** Turn on all logging categories */\n All = 0xff,\n /** Disable logging */\n None = 0,\n }\n\n /**\n * A local cache for storing data downloaded from many CloudSqlite databases. This object refers to a directory on the local filesystem\n * and is used to **connect** CloudContainers so they may be accessed. It maintains the state of the local copy of\n * the downloaded data from SQLiteDbs in CloudContainers across sessions.\n *\n * Notes:\n * - CloudCaches have a name, used internally by CloudSqlite, that must be unique. CloudCaches are created and maintained via [[CloudCaches.getCache]].\n * - All CloudContainers connected to a given CloudCache must have the same block size, as determined by the first CloudContainer connected.\n * - they have a maximum size that limits the amount of disk space they can consume. When the maximum size of a CloudCache is reached,\n * the least recently used blocks are removed to make room for new blocks.\n * - CloudCaches may only be used by a single process at a time. An exception is thrown if you attempt to access a CloudCache from a\n * second process if it is already in use by another process. Note: for a readonly CloudCache, a \"daemon\" process can be used to\n * share a CloudCache across processes. See its documentation for details.\n * - Generally, it is expected that there only be a few CloudCaches and they be shared by all applications. Each CloudCache can consume\n * its maximum disk space, so controlling system-wide disk usage is complicated. The only reason to make a new CloudCache is either\n * for containers with a different block size, or to purposely control local disk space usage for a specific set of containers.\n * - The contents of the cache directory are entirely controlled by CloudSqlite and should be empty when the cache is\n * first created and never modified directly thereafter.\n */\n export interface CloudCache {\n /** `true` if this CloudCache is connected to a daemon process */\n get isDaemon(): boolean;\n /** The name for this CloudCache. */\n get name(): string;\n /** The root directory of this CloudCache on a local drive. */\n get rootDir(): LocalDirName;\n /** A guid for this CloudCache. It is assigned when the CloudCache is first created and used for acquiring write locks. */\n get guid(): GuidString;\n /** Configure logging for this CloudCache.\n * @param mask A bitmask of `LoggingMask` values\n * @note this method does nothing if [[isDaemon]] is true. Daemon logging is configured when the daemon is started.\n * @note HTTP logging can be happen on multiple threads and may be buffered. To see buffered log messages, periodically call\n * `[[IModelHost.flushLog]]\n */\n setLogMask(mask: number): void;\n /**\n * destroy this CloudCache to end this session. All currently connected CloudContainers are disconnected first.\n * @note this does *not* delete the local directory. Its contents are maintained so it can be used in future sessions.\n * @note this function is automatically called on [[IModelHost.shutdown]], so it is only called directly for tests.\n * @internal\n */\n destroy(): void;\n }\n\n export interface CleanDeletedBlocksOptions {\n /**\n * Any block that was marked as unused before this number of seconds ago will be deleted. Specifying a non-zero\n * value gives a period of time for other clients to refresh their manifests and stop using the now-garbage blocks. Otherwise they may get\n * a 404 error. Default is 1 hour.\n */\n nSeconds?: number;\n /** if enabled, outputs verbose logs about the cleanup process. Output includes blocks determined eligible for deletion.\n * @default false\n */\n debugLogging?: boolean;\n /** If true, iterates over all blobs in the cloud container to add blocks that are 'orphaned' to the delete list in the manifest.\n * Orphaned blocks are created when a client abruptly halts, is disconnected, or encounters an error while uploading a change.\n * If false, the search for 'orphaned' blocks is skipped and only any blocks which are already on the delete list are deleted.\n * @default true\n */\n findOrphanedBlocks?: boolean;\n /**\n * a user-supplied progress function called during the cleanup operation. While the search for orphaned blocks occurs, nDeleted will be 0 and nTotalToDelete will be 1.\n * Once the search is complete and orphaned blocks begin being deleted, nDeleted will be the number of blocks deleted and nTotalToDelete will be the total number of blocks to delete.\n * If the return value is 1, the job will be cancelled and progress will be saved. If one or more blocks have already been deleted, then a new manifest file is uploaded saving the progress of the delete job.\n * Return any other non-0 value to cancel the job without saving progress.\n */\n onProgress?: (nDeleted: number, nTotalToDelete: number) => Promise<number>;\n }\n\n /**\n * A CloudSqlite container that may be connected to a CloudCache. A CloudContainer maps a container in a cloud blob-storage\n * account to a local cache, so that the contents of a database in the container may be accessed as if it were a local file.\n *\n * Notes:\n * - all methods and accessors of this interface (other than `initializeContainer`) require that the `connect` method be successfully called first.\n * Otherwise they will throw an exception or return meaningless values.\n * - before a SQLiteDb in a container may be opened for write access, the container's write lock must be held (see [[acquireWriteLock]].)\n * - a single CloudContainer may hold more than one SQLiteDb, but often they are 1:1.\n * - the write lock is per-Container, not per-SQLiteDb (which is the reason they are often 1:1)\n * - the accessToken (a SAS key) member provides time limited, restricted, access to the container. It must be refreshed before it expires.\n * - when a CloudContainer is created, it may either be readonly or writeable. If a container is never meant to be used for writes,\n * it is slightly more efficient to indicate that by passing `writeable: false`\n */\n export interface CloudContainer {\n onConnect?: (container: CloudContainer, cache: CloudCache) => void;\n onConnected?: (container: CloudContainer) => void;\n onDisconnect?: (container: CloudContainer, detach: boolean) => void;\n onDisconnected?: (container: CloudContainer, detach: boolean) => void;\n\n readonly cache?: CloudCache;\n /** the baseUri of this container */\n get baseUri(): string;\n /** the storageType of this container */\n get storageType(): string;\n /** The ContainerId within a storage account. */\n get containerId(): string;\n /** The *alias* to identify this CloudContainer in a CloudCache. Usually just the ContainerId. */\n get alias(): string;\n /** The logId. */\n get logId(): string;\n /** The time that the write lock expires. Of the form 'YYYY-MM-DDTHH:MM:SS.000Z' in UTC.\n * Returns empty string if write lock is not held.\n */\n get writeLockExpires(): string;\n /** true if this CloudContainer is currently connected to a CloudCache via the `connect` method. */\n get isConnected(): boolean;\n /** true if this CloudContainer was created with the `writeable` flag (and its `accessToken` supplies write access). */\n get isWriteable(): boolean;\n /** true if this container is public (doesn't require authorization ). */\n get isPublic(): boolean;\n /** true if this CloudContainer currently holds the write lock for its container in the cloud. */\n get hasWriteLock(): boolean;\n /** true if this CloudContainer has local changes that have not be uploaded to its container in the cloud. */\n get hasLocalChanges(): boolean;\n /** The current accessToken providing access to the cloud container */\n get accessToken(): string;\n set accessToken(val: string);\n /** Get the number of garbage blocks in this container that can be purged. */\n get garbageBlocks(): number;\n /** The block size for this CloudContainer. */\n get blockSize(): number;\n\n /**\n * initialize a cloud blob-store container to be used as a new CloudContainer. This creates the container's manifest of its contents, and should be\n * performed on an empty container. If an existing manifest is present, it is destroyed and a new one is created (essentially emptying the container.)\n */\n initializeContainer(args: { checksumBlockNames?: boolean, blockSize: number }): void;\n\n /**\n * Connect this CloudContainer to a CloudCache for accessing and/or modifying its contents.\n * @note A CloudCache is a local directory holding copies of information from the cloud. It is persistent across sessions,\n * but this method must be called each session to (re)establish the connection to the CloudCache. If the CloudCache was previously populated,\n * this method may be called and will succeed *even when offline* or without a valid `accessToken`.\n */\n connect(cache: CloudCache): void;\n\n /**\n * Attempt to acquire the write lock for this CloudContainer. For this to succeed:\n * 1. it must be connected to a `CloudCache`\n * 2. this CloudContainer must have been constructed with `writeable: true`\n * 3. the `accessToken` must authorize write access\n * 4. no other process may be holding an unexpired write lock\n * @throws if any of the above conditions fail\n * @note Write locks *expire* after the duration specified in the `durationSeconds` property of the constructor argument, in case a process\n * crashes or otherwise fails to release the lock. Calling `acquireWriteLock` with the lock already held resets the lock duration from the current time,\n * so long running processes should call this method periodically to ensure their lock doesn't expire (they should also make sure their accessToken is refreshed\n * before it expires.)\n * @note on success, the container is synchronized with its contents in the cloud before the promise resolves.\n * @param user An identifier of the process/user locking the CloudContainer. In the event of a write lock\n * collision, this string will be included in the exception string of the *other* process attempting to obtain a write lock so that users may identify who currently holds\n * the lock.\n */\n acquireWriteLock(user: string): void;\n\n /**\n * Release the write lock if it is currently held.\n *\n * Notes:\n * - if there are local changes that have not been uploaded, they are automatically uploaded before the write lock is released.\n * - if the write lock is not held, this method does nothing.\n */\n releaseWriteLock(): void;\n\n /**\n * Destroy any currently valid write lock from this or any other process. This is obviously very dangerous and defeats the purpose of write locking.\n * This method exists only for administrator tools to clear a failed process without waiting for the expiration period. It can also be useful for tests.\n * For this to succeed, all of the conditions of `acquireWriteLock` must be true other than #4.\n */\n clearWriteLock(): void;\n\n /**\n * Abandon any local changes in this container. If the write lock is currently held, it is released.\n * This function fails with BE_SQLITE_BUSY if there are any open read or write transactions on *any* database in the container.\n */\n abandonChanges(): void;\n\n /**\n * Disconnect this CloudContainer from its CloudCache. There must be no open databases from this container. Leaves the container's contents in the\n * CloudCache so it is available for future sessions.\n * @note This function does nothing (and does not throw) if the CloudContainer is not connected to a CloudCache.\n */\n disconnect(args?: {\n /** if true removes the container from the CloudCache, otherwise Leaves the container in the CloudCache so it is available for future sessions. */\n detach?: boolean;\n }): void;\n\n /**\n * Poll cloud storage for changes from other processes.\n *\n * Notes:\n * - no changes made by other processes are visible to this CloudContainer unless/until this method is called.\n * - this is automatically called whenever the write lock is obtained to ensure all changes are against the latest version.\n * - any existing transactions on databases within the container will continue to use the old version of the manifest and therefore see no new changes pulled in.\n */\n checkForChanges(): void;\n\n /**\n * Upload any changed blocks from the databases in this CloudContainer.\n * @note this is called automatically from `releaseWriteLock` before the write lock is released. It is only necessary to call this directly if you\n * wish to upload changes while the write lock is still held.\n * @see hasLocalChanges\n */\n uploadChanges(): Promise<void>;\n\n /**\n * Create a copy of an existing database within this CloudContainer with a new name.\n * @note CloudSqlite uses copy-on-write semantics for this operation. That is, this method merely makes a\n * new entry in the manifest with the new name that *shares* all of its blocks with the original database.\n * If either database subsequently changes, the only modified blocks are not shared.\n */\n copyDatabase(dbName: string, toAlias: string): Promise<void>;\n\n /** Remove a database from this CloudContainer. Unused blocks are moved to the delete list in the manifest.\n * @see [[CloudSqlite.cleanDeletedBlocks]] to actually delete the blocks from the delete list.\n */\n deleteDatabase(dbName: string): Promise<void>;\n\n /** Get the list of database names in this CloudContainer.\n * @param globArg if present, filter the results with SQLite [GLOB](https://www.sqlite.org/lang_expr.html#glob) operator.\n */\n queryDatabases(globArg?: string): string[];\n\n /**\n * Get the status of a specific database in this CloudContainer.\n * @param dbName the name of the database of interest\n */\n queryDatabase(dbName: string): CachedDbProps | undefined;\n\n /**\n * query the bcv_http_log table\n * @note the bcv_http_log table contains one row for each HTTP request made by the VFS or connected daemon.\n * @note Entries are automatically removed from the table on a FIFO basis. By default entries which are 1 hr old will be removed.\n * @internal\n */\n queryHttpLog(filterOptions?: BcvHttpLogFilterOptions): CloudSqlite.BcvHttpLog[];\n\n /**\n * query the bcv_stat table.\n * @internal\n */\n queryBcvStats(filterOptions?: BcvStatsFilterOptions): CloudSqlite.BcvStats;\n\n /**\n * Get the SHA1 hash of the content of a database.\n * @param dbName the name of the database of interest\n * @note the hash will be empty if the database does not exist\n */\n queryDatabaseHash(dbName: string): string;\n }\n\n /**\n * Object returned by [[CloudSqlite.startCloudPrefetch]].\n * It holds a promise that is fulfilled when a Prefetch is completed. May also be used to cancel an in-progress prefetch.\n */\n export interface CloudPrefetch {\n readonly cloudContainer: CloudContainer;\n readonly dbName: string;\n\n /** Cancel a currently pending prefetch. The promise will be resolved immediately after this call. */\n cancel(): void;\n\n /**\n * Promise that is resolved when the prefetch completes or is cancelled. Await this promise to ensure that the\n * database has been fully downloaded before going offline, for example.\n *\n * Notes:\n * - resolves to `true` if the prefetch completed and the entire database is local, or `false` if it was aborted or failed.\n * - it is *not* rejected on `cancel`. Some progress may (or may not) have been made by the request.\n * - To monitor the progress being made during prefetch, call `CloudContainer.queryDatabase` periodically.\n */\n promise: Promise<boolean>;\n }\n\n /**\n * Clean any unused deleted blocks from cloud storage. Unused deleted blocks can accumulate in cloud storage in a couple of ways:\n * 1) When a database is updated, a subset of its blocks are replaced by new versions, sometimes leaving the originals unused.\n * 2) A database is deleted with [[CloudContainer.deleteDatabase]]\n * In both cases, the blocks are not deleted immediately. Instead, they are scheduled for deletion at some later time.\n * Calling this method deletes all blocks in the cloud container for which the scheduled deletion time has passed.\n * @param container the CloudContainer to be cleaned. Must be connected and hold the write lock.\n * @param options options for the cleanup operation. @see CloudSqlite.CleanDeletedBlocksOptions\n */\n export async function cleanDeletedBlocks(container: CloudContainer, options: CleanDeletedBlocksOptions): Promise<void> {\n let timer: NodeJS.Timeout | undefined;\n try {\n const cleanJob = new NativeLibrary.nativeLib.CancellableCloudSqliteJob(\"cleanup\", container, options);\n let total = 0;\n const onProgress = options?.onProgress;\n if (onProgress) {\n timer = setInterval(async () => { // set an interval timer to show progress every 250ms\n const progress = cleanJob.getProgress();\n total = progress.total;\n const result = await onProgress(progress.loaded, progress.total);\n if (result === 1)\n cleanJob.stopAndSaveProgress();\n else if (result !== 0)\n cleanJob.cancelTransfer();\n }, 250);\n }\n await cleanJob.promise;\n await onProgress?.(total, total); // make sure we call progress func one last time when download completes\n container.checkForChanges(); // re-read the manifest so the number of garbage blocks is updated.\n } catch (err: any) {\n if (err.message === \"cancelled\")\n err.errorNumber = BriefcaseStatus.DownloadCancelled;\n\n throw err;\n } finally {\n if (timer)\n clearInterval(timer);\n }\n }\n\n /** @internal */\n export async function transferDb(direction: TransferDirection, container: CloudContainer, props: TransferDbProps) {\n if (direction === \"download\")\n mkdirSync(dirname(props.localFileName), { recursive: true }); // make sure the directory exists before starting download\n\n let timer: NodeJS.Timeout | undefined;\n try {\n const transfer = new NativeLibrary.nativeLib.CancellableCloudSqliteJob(direction, container, props);\n let total = 0;\n const onProgress = props.onProgress;\n if (onProgress) {\n timer = setInterval(async () => { // set an interval timer to show progress every 250ms\n const progress = transfer.getProgress();\n total = progress.total;\n if (onProgress(progress.loaded, progress.total))\n transfer.cancelTransfer();\n }, 250);\n }\n await transfer.promise;\n onProgress?.(total, total); // make sure we call progress func one last time when download completes\n } catch (err: any) {\n if (err.message === \"cancelled\")\n err.errorNumber = BriefcaseStatus.DownloadCancelled;\n\n throw err;\n } finally {\n if (timer)\n clearInterval(timer);\n\n }\n }\n\n /** Upload a local SQLite database file into a CloudContainer.\n * @param container the CloudContainer holding the database. Must be connected.\n * @param props the properties that describe the database to be downloaded, plus optionally an `onProgress` function.\n * @note this function requires that the write lock be held on the container\n */\n export async function uploadDb(container: CloudContainer, props: TransferDbProps): Promise<void> {\n await transferDb(\"upload\", container, props);\n container.checkForChanges(); // re-read the manifest so the database is available locally.\n }\n\n /** Download a database from a CloudContainer.\n * @param container the CloudContainer holding the database. Must be connected.\n * @param props the properties that describe the database to be downloaded, plus optionally an `onProgress` function.\n * @returns a Promise that is resolved when the download completes.\n * @note the download is \"restartable.\" If the transfer is aborted and then re-requested, it will continue from where\n * it left off rather than re-downloading the entire file.\n */\n export async function downloadDb(container: CloudContainer, props: TransferDbProps): Promise<void> {\n await transferDb(\"download\", container, props);\n }\n\n /** Optional method to be called when an attempt to acquire the write lock fails because another user currently holds it.\n * @param lockedBy The identifier supplied by the application/user that currently holds the lock.\n * @param expires a stringified Date (in local time) indicating when the lock will expire.\n * @return \"stop\" to give up and stop retrying. Generally, it's a good idea to wait for some time before returning.\n */\n export type WriteLockBusyHandler = (lockedBy: string, expires: string) => Promise<void | \"stop\">;\n\n /**\n * Attempt to acquire the write lock for a container, with retries.\n * If write lock is held by another user, call busyHandler if supplied. If no busyHandler, or handler returns \"stop\", throw. Otherwise try again.\n * @note if write lock is already held by the same user, this function will refresh the write lock's expiry time.\n * @param user the name to be displayed to other users in the event they attempt to obtain the lock while it is held by us\n * @param container the CloudContainer for which the lock is to be acquired\n * @param busyHandler if present, function called when the write lock is currently held by another user.\n * @throws if [[container]] is not connected to a CloudCache.\n */\n export async function acquireWriteLock(args: { user: string, container: CloudContainer, busyHandler?: WriteLockBusyHandler }) {\n const container = args.container as CloudContainerInternal;\n while (true) {\n try {\n // if the write is already held:\n // - by the same user, just update the write lock expiry (by calling acquireWriteLock).\n // - by another user, throw an error\n if (container.hasWriteLock && container.writeLockHeldBy !== args.user)\n CloudSqliteError.throwError<CloudSqliteError.WriteLockHeld>(\"write-lock-held\", {\n message: \"lock in use\", errorNumber: 5,\n lockedBy: container.writeLockHeldBy ?? \"\",\n expires: container.writeLockExpires\n });\n\n container.acquireWriteLock(args.user);\n container.writeLockHeldBy = args.user;\n return;\n } catch (e: any) {\n if (e.errorNumber === 5 && args.busyHandler && \"stop\" !== await args.busyHandler(e.lockedBy, e.expires)) // 5 === BE_SQLITE_BUSY\n continue; // busy handler wants to try again\n\n CloudSqliteError.throwError(\"write-lock-held\", { message: e.message, ...e });\n }\n }\n }\n\n export function getWriteLockHeldBy(container: CloudContainer) {\n return (container as CloudContainerInternal).writeLockHeldBy;\n }\n\n /** release the write lock on a container. */\n export function releaseWriteLock(container: CloudContainer) {\n container.releaseWriteLock();\n (container as CloudContainerInternal).writeLockHeldBy = undefined;\n }\n\n /**\n * Perform an asynchronous write operation on a CloudContainer with the write lock held.\n * 1. if write lock is already held by the current user, refresh write lock's expiry time, call operation and return.\n * 2. attempt to acquire the write lock, with retries. Throw if unable to obtain write lock.\n * 3. perform the operation\n * 3.a if the operation throws, abandon all changes and re-throw\n * 4. release the write lock.\n * 5. return value from operation\n * @param user the name to be displayed to other users in the event they attempt to obtain the lock while it is held by us\n * @param container the CloudContainer for which the lock is to be acquired\n * @param operation an asynchronous operation performed with the write lock held.\n * @param busyHandler if present, function called when the write lock is currently held by another user.\n * @returns a Promise with the result of `operation`\n */\n export async function withWriteLock<T>(args: { user: string, container: CloudContainer, busyHandler?: WriteLockBusyHandler }, operation: () => Promise<T>): Promise<T> {\n const containerInternal = args.container as CloudContainerInternal;\n const wasLockedBy = containerInternal.writeLockHeldBy;\n await acquireWriteLock(args);\n try {\n if (wasLockedBy === args.user) // If the user already had the write lock, then don't release it.\n return await operation();\n const val = await operation(); // wait for work to finish or fail\n releaseWriteLock(containerInternal);\n return val;\n } catch (e) {\n args.container.abandonChanges(); // if operation threw, abandon all changes\n containerInternal.writeLockHeldBy = undefined;\n throw e;\n }\n }\n\n /**\n * Parse the name of a Db stored in a CloudContainer into the dbName and version number. A single CloudContainer may hold\n * many versions of the same Db. The name of the Db in the CloudContainer is in the format \"name:version\". This\n * function splits them into separate strings.\n */\n export function parseDbFileName(dbFileName: DbFullName): { dbName: DbName, version: DbVersion } {\n const parts = dbFileName.split(\":\");\n return { dbName: parts[0], version: parts[1] ?? \"\" };\n }\n\n export function validateDbVersion(version?: DbVersion) {\n version = version ?? \"0.0.0\";\n const opts = { loose: true, includePrerelease: true };\n // clean allows prerelease, so try it first. If that fails attempt to coerce it (coerce strips prerelease even if you say not to.)\n const semVersion = semver.clean(version, opts) ?? semver.coerce(version, opts)?.version;\n if (!semVersion)\n CloudSqliteError.throwError(\"invalid-name\", { message: \"invalid version specification\" });\n version = semVersion;\n return version;\n }\n\n export function isSemverPrerelease(version: string) {\n return semver.major(version) === 0 || semver.prerelease(version);\n }\n\n export function isSemverEditable(dbFullName: string, container: CloudContainer) {\n return isSemverPrerelease(parseDbFileName(dbFullName).version) || container.queryDatabase(dbFullName)?.state === \"copied\";\n }\n\n /** Create a dbName for a database from its base name and version. This will be in the format \"name:version\" */\n export function makeSemverName(dbName: DbName, version?: DbVersion): DbName {\n return `${dbName}:${validateDbVersion(version)}`;\n }\n\n /** query the databases in the supplied container for the highest SemVer match according to the version range. Throws if no version available for the range. */\n export function querySemverMatch(props: LoadProps): DbFullName {\n const dbName = props.dbName;\n const dbs = props.container.queryDatabases(`${dbName}*`); // get all databases that start with dbName\n\n const versions = [];\n for (const db of dbs) {\n const thisDb = parseDbFileName(db);\n if (thisDb.dbName === dbName && \"string\" === typeof thisDb.version && thisDb.version.length > 0)\n versions.push(thisDb.version);\n }\n\n if (versions.length === 0)\n versions[0] = \"0.0.0\";\n\n const range = props.version ?? \"*\";\n try {\n const version = semver.maxSatisfying(versions, range, { loose: true, includePrerelease: props.includePrerelease });\n if (version)\n return `${dbName}:${version}`;\n } catch { }\n\n CloudSqliteError.throwError(\"no-version-available\", { message: `No version of '${dbName}' available for \"${range}\"`, ...props });\n }\n\n export async function createNewDbVersion(container: CloudContainer, args: CreateNewDbVersionArgs): Promise<{ oldDb: DbNameAndVersion, newDb: DbNameAndVersion }> {\n const oldFullName = CloudSqlite.querySemverMatch({ container, ...args.fromDb });\n const oldDb = CloudSqlite.parseDbFileName(oldFullName);\n const newVersion = semver.inc(oldDb.version, args.versionType, args.identifier);\n if (!newVersion)\n CloudSqliteError.throwError(\"invalid-name\", { message: `cannot create new version for ${oldFullName}`, dbName: oldFullName, ...args });\n\n const newName = makeSemverName(oldDb.dbName, newVersion);\n try {\n await container.copyDatabase(oldFullName, newName);\n } catch (e: unknown) {\n CloudSqliteError.throwError(\"copy-error\", { message: `Error attempting to create new version ${newName} from ${oldFullName}`, ...args, cause: e });\n }\n // return the old and new db names and versions\n return { oldDb, newDb: { dbName: oldDb.dbName, version: newVersion } };\n }\n\n /** Arguments to create or find a CloudCache */\n export interface CreateCloudCacheArg {\n /** The name of the CloudCache. CloudCache names must be unique. */\n cacheName: string;\n /** A string that specifies the maximum size of the CloudCache. It should be a number followed by \"K\",\n * \"M\" \"G\", or \"T\". Default is \"10G\". */\n cacheSize?: string;\n /** A local directory in temporary storage for the CloudCache. If not supplied, it is a subdirectory called `cacheName`\n * in the `CloudCaches` temporary directory.\n * If the directory does not exist, it is created. */\n cacheDir?: string;\n }\n\n /** The collection of currently extant `CloudCache`s, by name. */\n export class CloudCaches {\n private static readonly cloudCaches = new Map<string, CloudCache>();\n\n /** create a new CloudCache */\n private static makeCache(args: CreateCloudCacheArg): CloudCache {\n const cacheName = args.cacheName;\n const rootDir = args.cacheDir ?? join(IModelHost.profileDir, \"CloudCaches\", cacheName);\n IModelJsFs.recursiveMkDirSync(rootDir);\n const cache = new NativeLibrary.nativeLib.CloudCache({ rootDir, name: cacheName, cacheSize: args.cacheSize ?? \"10G\" });\n if (Logger.getLevel(\"CloudSqlite\") === LogLevel.Trace) {\n cache.setLogMask(CloudSqlite.LoggingMask.All);\n }\n this.cloudCaches.set(cacheName, cache);\n return cache;\n }\n\n /** find a CloudCache by name, if it exists */\n public static findCache(cacheName: string): CloudCache | undefined {\n return this.cloudCaches.get(cacheName);\n }\n /** @internal */\n public static dropCache(cacheName: string): CloudCache | undefined {\n const cache = this.cloudCaches.get(cacheName);\n this.cloudCaches.delete(cacheName);\n return cache;\n }\n /** called by IModelHost after shutdown.\n * @internal\n */\n public static destroy() {\n this.cloudCaches.forEach((cache) => cache.destroy());\n this.cloudCaches.clear();\n }\n\n /** Get a CloudCache by name. If the CloudCache doesn't yet exist, it is created. */\n public static getCache(args: CreateCloudCacheArg): CloudCache {\n return this.cloudCaches.get(args.cacheName) ?? this.makeCache(args);\n }\n }\n\n /** Class that provides convenient local access to a SQLite database in a CloudContainer. */\n export class DbAccess<DbType extends VersionedSqliteDb, ReadMethods = DbType, WriteMethods = DbType> {\n /** The name of the database within the cloud container. */\n public readonly dbName: string;\n /** Parameters for obtaining the write lock for this container. */\n public readonly lockParams: ObtainLockParams = {\n user: \"\",\n nRetries: 20,\n retryDelayMs: 100,\n };\n protected static _cacheName = \"default-64k\";\n protected _container: CloudContainer;\n protected _cloudDb: DbType;\n private _writeLockProxy?: PickAsyncMethods<WriteMethods>;\n private _readerProxy?: PickMethods<ReadMethods>;\n private get _ctor() { return this.constructor as typeof DbAccess; }\n\n /** @internal */\n public static getCacheForClass() {\n return CloudCaches.getCache({ cacheName: this._cacheName });\n }\n private _cache?: CloudCache;\n /** only for tests\n * @internal\n */\n public setCache(cache: CloudCache) {\n this._cache = cache;\n }\n /** @internal */\n public getCache(): CloudCache {\n return this._cache ??= this._ctor.getCacheForClass();\n }\n /** @internal */\n public getCloudDb(): DbType {\n return this._cloudDb;\n }\n\n /**\n * The token that grants access to the cloud container for this DbAccess. If it does not grant write permissions, all\n * write operations will fail. It should be refreshed (via a timer) before it expires.\n */\n public get sasToken() { return this._container.accessToken; }\n public set sasToken(token: AccessToken) { this._container.accessToken = token; }\n\n /** the container for this DbAccess. It is automatically connected to the CloudCache whenever it is accessed. */\n public get container(): CloudContainer {\n const container = this._container;\n if (!container.isConnected)\n container.connect(this.getCache());\n return container;\n }\n\n /** Start a prefetch operation to download all the blocks for the VersionedSqliteDb */\n public startPrefetch(): CloudPrefetch {\n return startCloudPrefetch(this.container, this.dbName);\n }\n\n /** Create a new DbAccess for a database stored in a cloud container. */\n public constructor(args: {\n /** The Constructor for DbType. */\n dbType: Constructor<DbType>;\n /** The properties of the cloud container holding the database. */\n props: ContainerAccessProps;\n /** The name of the database within the container. */\n dbName: string;\n }) {\n this._container = createCloudContainer({ writeable: true, ...args.props });\n this._cloudDb = new args.dbType(args.props);\n this.dbName = args.dbName;\n this.lockParams.user = IModelHost.userMoniker;\n }\n\n /** Close the database for this DbAccess, if it is open */\n public closeDb() {\n if (this._cloudDb.isOpen)\n this._cloudDb.closeDb();\n }\n\n /** Close the database for this DbAccess if it is opened, and disconnect this `DbAccess from its CloudContainer. */\n public close() {\n this.closeDb();\n this._container.disconnect();\n }\n\n /**\n * Initialize a cloud container to hold VersionedSqliteDbs. The container must first be created by [[createBlobContainer]].\n * This function creates and uploads an empty database into the container.\n * @note this deletes any existing content in the container.\n */\n protected static async _initializeDb(args: { dbType: typeof VersionedSqliteDb, props: ContainerProps, dbName: string, blockSize?: \"64K\" | \"4M\" }) {\n const container = createCloudContainer({ ...args.props, writeable: true, accessToken: args.props.accessToken ?? await CloudSqlite.requestToken(args.props) });\n container.initializeContainer({ blockSize: args.blockSize === \"4M\" ? 4 * 1024 * 1024 : 64 * 1024 });\n container.connect(CloudCaches.getCache({ cacheName: this._cacheName }));\n await withWriteLock({ user: \"initialize\", container }, async () => {\n const localFileName = join(KnownLocations.tmpdir, \"blank.db\");\n args.dbType.createNewDb(localFileName, args);\n await transferDb(\"upload\", container, { dbName: args.dbName, localFileName });\n unlinkSync(localFileName);\n });\n container.disconnect({ detach: true });\n }\n\n /**\n * Create a new BlobContainer from the BlobContainer service to hold one or more VersionedSqliteDbs.\n * @returns A ContainerProps that describes the newly created container.\n * @note the current user must have administrator rights to create containers.\n */\n protected static async createBlobContainer(args: Omit<BlobContainer.CreateNewContainerProps, \"userToken\">): Promise<CloudSqlite.ContainerProps> {\n const auth = verifyService(\"Authorization Client\", IModelHost.authorizationClient);\n const userToken = await auth.getAccessToken();\n const cloudContainer = await getBlobService().create({ scope: args.scope, metadata: args.metadata, userToken });\n return { baseUri: cloudContainer.baseUri, containerId: cloudContainer.containerId, storageType: cloudContainer.provider };\n }\n\n /**\n * Synchronize the local cache of this database with any changes by made by others.\n * @note This is called automatically whenever any write operation is performed on this DbAccess. It is only necessary to\n * call this directly if you have not changed the database recently, but wish to perform a readonly operation and want to\n * ensure it is up-to-date as of now.\n * @note There is no guarantee that the database is up-to-date even immediately after calling this method, since others\n * may be modifying it at any time.\n */\n public synchronizeWithCloud() {\n this.closeDb();\n this.container.checkForChanges();\n }\n\n /**\n * Ensure that the database controlled by this `DbAccess` is open for read access and return the database object.\n * @note if the database is already open (either for read or write), this method merely returns the database object.\n */\n public openForRead(): DbType {\n if (!this._cloudDb.isOpen)\n this._cloudDb.openDb(this.dbName, OpenMode.Readonly, this.container);\n return this._cloudDb;\n }\n\n /**\n * Perform an operation on this database with the lock held and the database opened for write\n * @param operationName the name of the operation. Only used for logging.\n * @param operation a function called with the lock held and the database open for write.\n * @returns A promise that resolves to the the return value of `operation`.\n * @see `SQLiteDb.withLockedContainer`\n * @note Most uses of `CloudSqliteDbAccess` require that the lock not be held by any operation for long. Make sure you don't\n * do any avoidable or time consuming work in your operation function.\n */\n public async withLockedDb<T>(args: { operationName: string, openMode?: OpenMode, user?: string }, operation: () => Promise<T>): Promise<T> {\n let nRetries = this.lockParams.nRetries;\n const cacheGuid = this.container.cache!.guid; // eslint-disable-line @typescript-eslint/no-non-null-assertion\n const user = args.user ?? this.lockParams.user ?? cacheGuid;\n const timer = new StopWatch(undefined, true);\n const showMs = () => `(${timer.elapsed.milliseconds}ms)`;\n\n const busyHandler = async (lockedBy: string, expires: string): Promise<void | \"stop\"> => {\n if (--nRetries <= 0) {\n if (\"stop\" === await this.lockParams.onFailure?.(lockedBy, expires))\n return \"stop\";\n nRetries = this.lockParams.nRetries;\n }\n const delay = this.lockParams.retryDelayMs;\n logInfo(`lock retry for ${cacheGuid} after ${showMs()}, waiting ${delay}`);\n await BeDuration.fromMilliseconds(delay).wait();\n };\n\n this.closeDb(); // in case it is currently open for read.\n let lockObtained = false;\n const operationName = args.operationName;\n try {\n return await this._cloudDb.withLockedContainer({ user, dbName: this.dbName, container: this.container, busyHandler, openMode: args.openMode }, async () => {\n lockObtained = true;\n logInfo(`lock acquired by ${cacheGuid} for ${operationName} ${showMs()}`);\n return operation();\n });\n } finally {\n if (lockObtained)\n logInfo(`lock released by ${cacheGuid} after ${operationName} ${showMs()} `);\n else\n logError(`could not obtain lock for ${cacheGuid} to perform ${operationName} ${showMs()} `);\n }\n }\n\n /** get a method member, by name, from the database object. Throws if not a Function. */\n private getDbMethod(methodName: string): (...args: any[]) => any {\n const fn = (this._cloudDb as any)[methodName];\n if (typeof fn !== \"function\")\n CloudSqliteError.throwError(\"not-a-function\", { message: `illegal method name ${methodName}`, dbName: this.dbName });\n return fn;\n }\n\n /**\n * A Proxy Object to call a writeable async method on the cloud database controlled by this `DbAccess`.\n *\n * Whenever a method is called through this Proxy, it will:\n * - attempt to acquire the write lock on the container\n * - open the database for write\n * - call the method\n * - close the database\n * - upload changes\n * - release the write lock.\n *\n * @see [[withLockedDb]]\n */\n public get writeLocker() {\n return this._writeLockProxy ??= new Proxy(this, {\n get(access, operationName: string) {\n const fn = access.getDbMethod(operationName);\n return async (...args: any[]) => access.withLockedDb({ operationName, user: RpcTrace.currentActivity?.user }, fn.bind(access._cloudDb, ...args));\n },\n }) as PickAsyncMethods<WriteMethods>;\n }\n\n /**\n * A Proxy Object to call a synchronous readonly method on the database controlled by this `DbAccess`.\n * Whenever a method is called through this Proxy, it will first ensure that the database is opened for at least read access.\n */\n public get reader() {\n return this._readerProxy ??= new Proxy(this, {\n get(access, methodName: string) {\n const fn = access.getDbMethod(methodName);\n return (...args: any[]) => fn.call(access.openForRead(), ...args);\n },\n }) as PickMethods<ReadMethods>;\n }\n }\n}\n"]}