@rs-native-kit/version-check 0.1.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 (371) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +256 -0
  3. package/VersionCheck.podspec +20 -0
  4. package/android/build.gradle +56 -0
  5. package/android/src/main/AndroidManifest.xml +9 -0
  6. package/android/src/main/java/com/rsnativekit/versioncheck/SecureStorageCipher.kt +57 -0
  7. package/android/src/main/java/com/rsnativekit/versioncheck/VersionCheckHeadlessTaskService.kt +31 -0
  8. package/android/src/main/java/com/rsnativekit/versioncheck/VersionCheckModule.kt +215 -0
  9. package/android/src/main/java/com/rsnativekit/versioncheck/VersionCheckPackage.kt +31 -0
  10. package/android/src/main/java/com/rsnativekit/versioncheck/VersionCheckWorker.kt +29 -0
  11. package/ios/PlatformBridge/Ed25519Verifier.swift +19 -0
  12. package/ios/VersionCheck.h +5 -0
  13. package/ios/VersionCheck.mm +278 -0
  14. package/lib/module/data/cache/MemoryCacheStore.js +30 -0
  15. package/lib/module/data/cache/MemoryCacheStore.js.map +1 -0
  16. package/lib/module/data/cache/PersistentCacheStore.js +56 -0
  17. package/lib/module/data/cache/PersistentCacheStore.js.map +1 -0
  18. package/lib/module/data/config/ConfigCache.js +29 -0
  19. package/lib/module/data/config/ConfigCache.js.map +1 -0
  20. package/lib/module/data/config/ConfigDocumentValidator.js +185 -0
  21. package/lib/module/data/config/ConfigDocumentValidator.js.map +1 -0
  22. package/lib/module/data/config/ConfigLoader.js +82 -0
  23. package/lib/module/data/config/ConfigLoader.js.map +1 -0
  24. package/lib/module/data/config/ConfigProvider.js +58 -0
  25. package/lib/module/data/config/ConfigProvider.js.map +1 -0
  26. package/lib/module/data/config/ConfigResolutionPipeline.js +268 -0
  27. package/lib/module/data/config/ConfigResolutionPipeline.js.map +1 -0
  28. package/lib/module/data/config/ConfigValidator.js +69 -0
  29. package/lib/module/data/config/ConfigValidator.js.map +1 -0
  30. package/lib/module/data/config/SignatureVerifier.js +80 -0
  31. package/lib/module/data/config/SignatureVerifier.js.map +1 -0
  32. package/lib/module/data/config/canonicalize.js +88 -0
  33. package/lib/module/data/config/canonicalize.js.map +1 -0
  34. package/lib/module/data/config/sources/EnvironmentOverrideSource.js +20 -0
  35. package/lib/module/data/config/sources/EnvironmentOverrideSource.js.map +1 -0
  36. package/lib/module/data/config/sources/LocalConfigSource.js +22 -0
  37. package/lib/module/data/config/sources/LocalConfigSource.js.map +1 -0
  38. package/lib/module/data/config/sources/RemoteConfigSource.js +38 -0
  39. package/lib/module/data/config/sources/RemoteConfigSource.js.map +1 -0
  40. package/lib/module/data/providers/amazon/AmazonAppstoreProvider.js +13 -0
  41. package/lib/module/data/providers/amazon/AmazonAppstoreProvider.js.map +1 -0
  42. package/lib/module/data/providers/apple/AppleStoreProvider.js +67 -0
  43. package/lib/module/data/providers/apple/AppleStoreProvider.js.map +1 -0
  44. package/lib/module/data/providers/custom-api/CustomApiProvider.js +51 -0
  45. package/lib/module/data/providers/custom-api/CustomApiProvider.js.map +1 -0
  46. package/lib/module/data/providers/firebase-remote-config/FirebaseRemoteConfigProvider.js +13 -0
  47. package/lib/module/data/providers/firebase-remote-config/FirebaseRemoteConfigProvider.js.map +1 -0
  48. package/lib/module/data/providers/google-play/GooglePlayProvider.js +62 -0
  49. package/lib/module/data/providers/google-play/GooglePlayProvider.js.map +1 -0
  50. package/lib/module/data/providers/huawei/HuaweiAppGalleryProvider.js +18 -0
  51. package/lib/module/data/providers/huawei/HuaweiAppGalleryProvider.js.map +1 -0
  52. package/lib/module/data/repositories/VersionRepositoryImpl.js +69 -0
  53. package/lib/module/data/repositories/VersionRepositoryImpl.js.map +1 -0
  54. package/lib/module/di/container.js +80 -0
  55. package/lib/module/di/container.js.map +1 -0
  56. package/lib/module/domain/IVersionManagerCore.js +4 -0
  57. package/lib/module/domain/IVersionManagerCore.js.map +1 -0
  58. package/lib/module/domain/VersionManagerCore.js +276 -0
  59. package/lib/module/domain/VersionManagerCore.js.map +1 -0
  60. package/lib/module/domain/engines/decision/DecisionEngine.js +40 -0
  61. package/lib/module/domain/engines/decision/DecisionEngine.js.map +1 -0
  62. package/lib/module/domain/engines/policy/IUpdatePolicyEngine.js +4 -0
  63. package/lib/module/domain/engines/policy/IUpdatePolicyEngine.js.map +1 -0
  64. package/lib/module/domain/engines/policy/PolicyEngine.js +42 -0
  65. package/lib/module/domain/engines/policy/PolicyEngine.js.map +1 -0
  66. package/lib/module/domain/engines/semver/IVersionComparator.js +4 -0
  67. package/lib/module/domain/engines/semver/IVersionComparator.js.map +1 -0
  68. package/lib/module/domain/engines/semver/SemVerEngine.js +176 -0
  69. package/lib/module/domain/engines/semver/SemVerEngine.js.map +1 -0
  70. package/lib/module/domain/errors/VersionManagerException.js +104 -0
  71. package/lib/module/domain/errors/VersionManagerException.js.map +1 -0
  72. package/lib/module/domain/models/ActionPlan.js +9 -0
  73. package/lib/module/domain/models/ActionPlan.js.map +1 -0
  74. package/lib/module/domain/models/ConfigDocument.js +4 -0
  75. package/lib/module/domain/models/ConfigDocument.js.map +1 -0
  76. package/lib/module/domain/models/Events.js +4 -0
  77. package/lib/module/domain/models/Events.js.map +1 -0
  78. package/lib/module/domain/models/LifecycleState.js +29 -0
  79. package/lib/module/domain/models/LifecycleState.js.map +1 -0
  80. package/lib/module/domain/models/ParsedVersion.js +2 -0
  81. package/lib/module/domain/models/ParsedVersion.js.map +1 -0
  82. package/lib/module/domain/models/PlatformId.js +2 -0
  83. package/lib/module/domain/models/PlatformId.js.map +1 -0
  84. package/lib/module/domain/models/PublicApiOptions.js +2 -0
  85. package/lib/module/domain/models/PublicApiOptions.js.map +1 -0
  86. package/lib/module/domain/models/RemoteVersionInfo.js +4 -0
  87. package/lib/module/domain/models/RemoteVersionInfo.js.map +1 -0
  88. package/lib/module/domain/models/StoreLookup.js +2 -0
  89. package/lib/module/domain/models/StoreLookup.js.map +1 -0
  90. package/lib/module/domain/models/Unsubscribe.js +2 -0
  91. package/lib/module/domain/models/Unsubscribe.js.map +1 -0
  92. package/lib/module/domain/models/UpdateInfo.js +4 -0
  93. package/lib/module/domain/models/UpdateInfo.js.map +1 -0
  94. package/lib/module/domain/models/VersionManagerOptions.js +4 -0
  95. package/lib/module/domain/models/VersionManagerOptions.js.map +1 -0
  96. package/lib/module/domain/ports/ICacheStore.js +2 -0
  97. package/lib/module/domain/ports/ICacheStore.js.map +1 -0
  98. package/lib/module/domain/ports/IClock.js +2 -0
  99. package/lib/module/domain/ports/IClock.js.map +1 -0
  100. package/lib/module/domain/ports/IConfigProvider.js +4 -0
  101. package/lib/module/domain/ports/IConfigProvider.js.map +1 -0
  102. package/lib/module/domain/ports/IConfigSources.js +4 -0
  103. package/lib/module/domain/ports/IConfigSources.js.map +1 -0
  104. package/lib/module/domain/ports/IPlatformBridge.js +4 -0
  105. package/lib/module/domain/ports/IPlatformBridge.js.map +1 -0
  106. package/lib/module/domain/ports/IStoreProvider.js +4 -0
  107. package/lib/module/domain/ports/IStoreProvider.js.map +1 -0
  108. package/lib/module/domain/ports/IVersionRepository.js +4 -0
  109. package/lib/module/domain/ports/IVersionRepository.js.map +1 -0
  110. package/lib/module/domain/statemachine/LifecycleStateMachine.js +55 -0
  111. package/lib/module/domain/statemachine/LifecycleStateMachine.js.map +1 -0
  112. package/lib/module/domain/usecases/CheckForUpdatesUseCase.js +31 -0
  113. package/lib/module/domain/usecases/CheckForUpdatesUseCase.js.map +1 -0
  114. package/lib/module/domain/usecases/ForceTriggerUpdateUseCase.js +20 -0
  115. package/lib/module/domain/usecases/ForceTriggerUpdateUseCase.js.map +1 -0
  116. package/lib/module/domain/usecases/ResetIgnoredVersionsUseCase.js +24 -0
  117. package/lib/module/domain/usecases/ResetIgnoredVersionsUseCase.js.map +1 -0
  118. package/lib/module/index.js +10 -0
  119. package/lib/module/index.js.map +1 -0
  120. package/lib/module/package.json +1 -0
  121. package/lib/module/platform/contracts/IPlatformBridge.js +2 -0
  122. package/lib/module/platform/contracts/IPlatformBridge.js.map +1 -0
  123. package/lib/module/platform/createPlatformBridge.js +17 -0
  124. package/lib/module/platform/createPlatformBridge.js.map +1 -0
  125. package/lib/module/platform/createPlatformBridge.native.js +9 -0
  126. package/lib/module/platform/createPlatformBridge.native.js.map +1 -0
  127. package/lib/module/platform/native/NativePlatformBridge.js +143 -0
  128. package/lib/module/platform/native/NativePlatformBridge.js.map +1 -0
  129. package/lib/module/platform/native/NativeVersionCheck.js +33 -0
  130. package/lib/module/platform/native/NativeVersionCheck.js.map +1 -0
  131. package/lib/module/platform/web/WebPlatformBridge.js +228 -0
  132. package/lib/module/platform/web/WebPlatformBridge.js.map +1 -0
  133. package/lib/module/presentation/components/ForceUpdateScreen.js +68 -0
  134. package/lib/module/presentation/components/ForceUpdateScreen.js.map +1 -0
  135. package/lib/module/presentation/components/OptionalUpdateBanner.js +69 -0
  136. package/lib/module/presentation/components/OptionalUpdateBanner.js.map +1 -0
  137. package/lib/module/presentation/components/SoftUpdateDialog.js +101 -0
  138. package/lib/module/presentation/components/SoftUpdateDialog.js.map +1 -0
  139. package/lib/module/presentation/hooks/VersionManagerProvider.js +18 -0
  140. package/lib/module/presentation/hooks/VersionManagerProvider.js.map +1 -0
  141. package/lib/module/presentation/hooks/context.js +5 -0
  142. package/lib/module/presentation/hooks/context.js.map +1 -0
  143. package/lib/module/presentation/hooks/useUpdateState.js +26 -0
  144. package/lib/module/presentation/hooks/useUpdateState.js.map +1 -0
  145. package/lib/module/presentation/hooks/useVersionManager.js +33 -0
  146. package/lib/module/presentation/hooks/useVersionManager.js.map +1 -0
  147. package/lib/module/presentation/state/VersionManagerStore.js +47 -0
  148. package/lib/module/presentation/state/VersionManagerStore.js.map +1 -0
  149. package/lib/module/publicApi.js +114 -0
  150. package/lib/module/publicApi.js.map +1 -0
  151. package/lib/module/shared/eventbus/EventBus.js +34 -0
  152. package/lib/module/shared/eventbus/EventBus.js.map +1 -0
  153. package/lib/module/shared/logging/Logger.js +56 -0
  154. package/lib/module/shared/logging/Logger.js.map +1 -0
  155. package/lib/module/ui.js +13 -0
  156. package/lib/module/ui.js.map +1 -0
  157. package/lib/typescript/package.json +1 -0
  158. package/lib/typescript/src/data/cache/MemoryCacheStore.d.ts +12 -0
  159. package/lib/typescript/src/data/cache/MemoryCacheStore.d.ts.map +1 -0
  160. package/lib/typescript/src/data/cache/PersistentCacheStore.d.ts +14 -0
  161. package/lib/typescript/src/data/cache/PersistentCacheStore.d.ts.map +1 -0
  162. package/lib/typescript/src/data/config/ConfigCache.d.ts +15 -0
  163. package/lib/typescript/src/data/config/ConfigCache.d.ts.map +1 -0
  164. package/lib/typescript/src/data/config/ConfigDocumentValidator.d.ts +20 -0
  165. package/lib/typescript/src/data/config/ConfigDocumentValidator.d.ts.map +1 -0
  166. package/lib/typescript/src/data/config/ConfigLoader.d.ts +28 -0
  167. package/lib/typescript/src/data/config/ConfigLoader.d.ts.map +1 -0
  168. package/lib/typescript/src/data/config/ConfigProvider.d.ts +30 -0
  169. package/lib/typescript/src/data/config/ConfigProvider.d.ts.map +1 -0
  170. package/lib/typescript/src/data/config/ConfigResolutionPipeline.d.ts +49 -0
  171. package/lib/typescript/src/data/config/ConfigResolutionPipeline.d.ts.map +1 -0
  172. package/lib/typescript/src/data/config/ConfigValidator.d.ts +10 -0
  173. package/lib/typescript/src/data/config/ConfigValidator.d.ts.map +1 -0
  174. package/lib/typescript/src/data/config/SignatureVerifier.d.ts +16 -0
  175. package/lib/typescript/src/data/config/SignatureVerifier.d.ts.map +1 -0
  176. package/lib/typescript/src/data/config/canonicalize.d.ts +13 -0
  177. package/lib/typescript/src/data/config/canonicalize.d.ts.map +1 -0
  178. package/lib/typescript/src/data/config/sources/EnvironmentOverrideSource.d.ts +17 -0
  179. package/lib/typescript/src/data/config/sources/EnvironmentOverrideSource.d.ts.map +1 -0
  180. package/lib/typescript/src/data/config/sources/LocalConfigSource.d.ts +19 -0
  181. package/lib/typescript/src/data/config/sources/LocalConfigSource.d.ts.map +1 -0
  182. package/lib/typescript/src/data/config/sources/RemoteConfigSource.d.ts +10 -0
  183. package/lib/typescript/src/data/config/sources/RemoteConfigSource.d.ts.map +1 -0
  184. package/lib/typescript/src/data/providers/amazon/AmazonAppstoreProvider.d.ts +9 -0
  185. package/lib/typescript/src/data/providers/amazon/AmazonAppstoreProvider.d.ts.map +1 -0
  186. package/lib/typescript/src/data/providers/apple/AppleStoreProvider.d.ts +19 -0
  187. package/lib/typescript/src/data/providers/apple/AppleStoreProvider.d.ts.map +1 -0
  188. package/lib/typescript/src/data/providers/custom-api/CustomApiProvider.d.ts +14 -0
  189. package/lib/typescript/src/data/providers/custom-api/CustomApiProvider.d.ts.map +1 -0
  190. package/lib/typescript/src/data/providers/firebase-remote-config/FirebaseRemoteConfigProvider.d.ts +9 -0
  191. package/lib/typescript/src/data/providers/firebase-remote-config/FirebaseRemoteConfigProvider.d.ts.map +1 -0
  192. package/lib/typescript/src/data/providers/google-play/GooglePlayProvider.d.ts +22 -0
  193. package/lib/typescript/src/data/providers/google-play/GooglePlayProvider.d.ts.map +1 -0
  194. package/lib/typescript/src/data/providers/huawei/HuaweiAppGalleryProvider.d.ts +14 -0
  195. package/lib/typescript/src/data/providers/huawei/HuaweiAppGalleryProvider.d.ts.map +1 -0
  196. package/lib/typescript/src/data/repositories/VersionRepositoryImpl.d.ts +23 -0
  197. package/lib/typescript/src/data/repositories/VersionRepositoryImpl.d.ts.map +1 -0
  198. package/lib/typescript/src/di/container.d.ts +12 -0
  199. package/lib/typescript/src/di/container.d.ts.map +1 -0
  200. package/lib/typescript/src/domain/IVersionManagerCore.d.ts +30 -0
  201. package/lib/typescript/src/domain/IVersionManagerCore.d.ts.map +1 -0
  202. package/lib/typescript/src/domain/VersionManagerCore.d.ts +94 -0
  203. package/lib/typescript/src/domain/VersionManagerCore.d.ts.map +1 -0
  204. package/lib/typescript/src/domain/engines/decision/DecisionEngine.d.ts +16 -0
  205. package/lib/typescript/src/domain/engines/decision/DecisionEngine.d.ts.map +1 -0
  206. package/lib/typescript/src/domain/engines/policy/IUpdatePolicyEngine.d.ts +17 -0
  207. package/lib/typescript/src/domain/engines/policy/IUpdatePolicyEngine.d.ts.map +1 -0
  208. package/lib/typescript/src/domain/engines/policy/PolicyEngine.d.ts +16 -0
  209. package/lib/typescript/src/domain/engines/policy/PolicyEngine.d.ts.map +1 -0
  210. package/lib/typescript/src/domain/engines/semver/IVersionComparator.d.ts +7 -0
  211. package/lib/typescript/src/domain/engines/semver/IVersionComparator.d.ts.map +1 -0
  212. package/lib/typescript/src/domain/engines/semver/SemVerEngine.d.ts +11 -0
  213. package/lib/typescript/src/domain/engines/semver/SemVerEngine.d.ts.map +1 -0
  214. package/lib/typescript/src/domain/errors/VersionManagerException.d.ts +97 -0
  215. package/lib/typescript/src/domain/errors/VersionManagerException.d.ts.map +1 -0
  216. package/lib/typescript/src/domain/models/ActionPlan.d.ts +15 -0
  217. package/lib/typescript/src/domain/models/ActionPlan.d.ts.map +1 -0
  218. package/lib/typescript/src/domain/models/ConfigDocument.d.ts +86 -0
  219. package/lib/typescript/src/domain/models/ConfigDocument.d.ts.map +1 -0
  220. package/lib/typescript/src/domain/models/Events.d.ts +39 -0
  221. package/lib/typescript/src/domain/models/Events.d.ts.map +1 -0
  222. package/lib/typescript/src/domain/models/LifecycleState.d.ts +18 -0
  223. package/lib/typescript/src/domain/models/LifecycleState.d.ts.map +1 -0
  224. package/lib/typescript/src/domain/models/ParsedVersion.d.ts +9 -0
  225. package/lib/typescript/src/domain/models/ParsedVersion.d.ts.map +1 -0
  226. package/lib/typescript/src/domain/models/PlatformId.d.ts +3 -0
  227. package/lib/typescript/src/domain/models/PlatformId.d.ts.map +1 -0
  228. package/lib/typescript/src/domain/models/PublicApiOptions.d.ts +13 -0
  229. package/lib/typescript/src/domain/models/PublicApiOptions.d.ts.map +1 -0
  230. package/lib/typescript/src/domain/models/RemoteVersionInfo.d.ts +21 -0
  231. package/lib/typescript/src/domain/models/RemoteVersionInfo.d.ts.map +1 -0
  232. package/lib/typescript/src/domain/models/StoreLookup.d.ts +12 -0
  233. package/lib/typescript/src/domain/models/StoreLookup.d.ts.map +1 -0
  234. package/lib/typescript/src/domain/models/Unsubscribe.d.ts +2 -0
  235. package/lib/typescript/src/domain/models/Unsubscribe.d.ts.map +1 -0
  236. package/lib/typescript/src/domain/models/UpdateInfo.d.ts +11 -0
  237. package/lib/typescript/src/domain/models/UpdateInfo.d.ts.map +1 -0
  238. package/lib/typescript/src/domain/models/VersionManagerOptions.d.ts +149 -0
  239. package/lib/typescript/src/domain/models/VersionManagerOptions.d.ts.map +1 -0
  240. package/lib/typescript/src/domain/ports/ICacheStore.d.ts +6 -0
  241. package/lib/typescript/src/domain/ports/ICacheStore.d.ts.map +1 -0
  242. package/lib/typescript/src/domain/ports/IClock.d.ts +4 -0
  243. package/lib/typescript/src/domain/ports/IClock.d.ts.map +1 -0
  244. package/lib/typescript/src/domain/ports/IConfigProvider.d.ts +11 -0
  245. package/lib/typescript/src/domain/ports/IConfigProvider.d.ts.map +1 -0
  246. package/lib/typescript/src/domain/ports/IConfigSources.d.ts +25 -0
  247. package/lib/typescript/src/domain/ports/IConfigSources.d.ts.map +1 -0
  248. package/lib/typescript/src/domain/ports/IPlatformBridge.d.ts +77 -0
  249. package/lib/typescript/src/domain/ports/IPlatformBridge.d.ts.map +1 -0
  250. package/lib/typescript/src/domain/ports/IStoreProvider.d.ts +7 -0
  251. package/lib/typescript/src/domain/ports/IStoreProvider.d.ts.map +1 -0
  252. package/lib/typescript/src/domain/ports/IVersionRepository.d.ts +8 -0
  253. package/lib/typescript/src/domain/ports/IVersionRepository.d.ts.map +1 -0
  254. package/lib/typescript/src/domain/statemachine/LifecycleStateMachine.d.ts +25 -0
  255. package/lib/typescript/src/domain/statemachine/LifecycleStateMachine.d.ts.map +1 -0
  256. package/lib/typescript/src/domain/usecases/CheckForUpdatesUseCase.d.ts +30 -0
  257. package/lib/typescript/src/domain/usecases/CheckForUpdatesUseCase.d.ts.map +1 -0
  258. package/lib/typescript/src/domain/usecases/ForceTriggerUpdateUseCase.d.ts +17 -0
  259. package/lib/typescript/src/domain/usecases/ForceTriggerUpdateUseCase.d.ts.map +1 -0
  260. package/lib/typescript/src/domain/usecases/ResetIgnoredVersionsUseCase.d.ts +7 -0
  261. package/lib/typescript/src/domain/usecases/ResetIgnoredVersionsUseCase.d.ts.map +1 -0
  262. package/lib/typescript/src/index.d.ts +17 -0
  263. package/lib/typescript/src/index.d.ts.map +1 -0
  264. package/lib/typescript/src/platform/contracts/IPlatformBridge.d.ts +2 -0
  265. package/lib/typescript/src/platform/contracts/IPlatformBridge.d.ts.map +1 -0
  266. package/lib/typescript/src/platform/createPlatformBridge.d.ts +12 -0
  267. package/lib/typescript/src/platform/createPlatformBridge.d.ts.map +1 -0
  268. package/lib/typescript/src/platform/createPlatformBridge.native.d.ts +4 -0
  269. package/lib/typescript/src/platform/createPlatformBridge.native.d.ts.map +1 -0
  270. package/lib/typescript/src/platform/native/NativePlatformBridge.d.ts +17 -0
  271. package/lib/typescript/src/platform/native/NativePlatformBridge.d.ts.map +1 -0
  272. package/lib/typescript/src/platform/native/NativeVersionCheck.d.ts +45 -0
  273. package/lib/typescript/src/platform/native/NativeVersionCheck.d.ts.map +1 -0
  274. package/lib/typescript/src/platform/web/WebPlatformBridge.d.ts +17 -0
  275. package/lib/typescript/src/platform/web/WebPlatformBridge.d.ts.map +1 -0
  276. package/lib/typescript/src/presentation/components/ForceUpdateScreen.d.ts +12 -0
  277. package/lib/typescript/src/presentation/components/ForceUpdateScreen.d.ts.map +1 -0
  278. package/lib/typescript/src/presentation/components/OptionalUpdateBanner.d.ts +12 -0
  279. package/lib/typescript/src/presentation/components/OptionalUpdateBanner.d.ts.map +1 -0
  280. package/lib/typescript/src/presentation/components/SoftUpdateDialog.d.ts +14 -0
  281. package/lib/typescript/src/presentation/components/SoftUpdateDialog.d.ts.map +1 -0
  282. package/lib/typescript/src/presentation/hooks/VersionManagerProvider.d.ts +9 -0
  283. package/lib/typescript/src/presentation/hooks/VersionManagerProvider.d.ts.map +1 -0
  284. package/lib/typescript/src/presentation/hooks/context.d.ts +3 -0
  285. package/lib/typescript/src/presentation/hooks/context.d.ts.map +1 -0
  286. package/lib/typescript/src/presentation/hooks/useUpdateState.d.ts +17 -0
  287. package/lib/typescript/src/presentation/hooks/useUpdateState.d.ts.map +1 -0
  288. package/lib/typescript/src/presentation/hooks/useVersionManager.d.ts +22 -0
  289. package/lib/typescript/src/presentation/hooks/useVersionManager.d.ts.map +1 -0
  290. package/lib/typescript/src/presentation/state/VersionManagerStore.d.ts +28 -0
  291. package/lib/typescript/src/presentation/state/VersionManagerStore.d.ts.map +1 -0
  292. package/lib/typescript/src/publicApi.d.ts +24 -0
  293. package/lib/typescript/src/publicApi.d.ts.map +1 -0
  294. package/lib/typescript/src/shared/eventbus/EventBus.d.ts +21 -0
  295. package/lib/typescript/src/shared/eventbus/EventBus.d.ts.map +1 -0
  296. package/lib/typescript/src/shared/logging/Logger.d.ts +17 -0
  297. package/lib/typescript/src/shared/logging/Logger.d.ts.map +1 -0
  298. package/lib/typescript/src/ui.d.ts +15 -0
  299. package/lib/typescript/src/ui.d.ts.map +1 -0
  300. package/package.json +192 -0
  301. package/src/data/cache/MemoryCacheStore.ts +36 -0
  302. package/src/data/cache/PersistentCacheStore.ts +63 -0
  303. package/src/data/config/ConfigCache.ts +30 -0
  304. package/src/data/config/ConfigDocumentValidator.ts +309 -0
  305. package/src/data/config/ConfigLoader.ts +105 -0
  306. package/src/data/config/ConfigProvider.ts +84 -0
  307. package/src/data/config/ConfigResolutionPipeline.ts +424 -0
  308. package/src/data/config/ConfigValidator.ts +79 -0
  309. package/src/data/config/SignatureVerifier.ts +90 -0
  310. package/src/data/config/canonicalize.ts +111 -0
  311. package/src/data/config/sources/EnvironmentOverrideSource.ts +22 -0
  312. package/src/data/config/sources/LocalConfigSource.ts +24 -0
  313. package/src/data/config/sources/RemoteConfigSource.ts +41 -0
  314. package/src/data/providers/amazon/AmazonAppstoreProvider.ts +16 -0
  315. package/src/data/providers/apple/AppleStoreProvider.ts +94 -0
  316. package/src/data/providers/custom-api/CustomApiProvider.ts +75 -0
  317. package/src/data/providers/firebase-remote-config/FirebaseRemoteConfigProvider.ts +16 -0
  318. package/src/data/providers/google-play/GooglePlayProvider.ts +75 -0
  319. package/src/data/providers/huawei/HuaweiAppGalleryProvider.ts +21 -0
  320. package/src/data/repositories/VersionRepositoryImpl.ts +90 -0
  321. package/src/di/container.ts +128 -0
  322. package/src/domain/IVersionManagerCore.ts +54 -0
  323. package/src/domain/VersionManagerCore.ts +425 -0
  324. package/src/domain/engines/decision/DecisionEngine.ts +47 -0
  325. package/src/domain/engines/policy/IUpdatePolicyEngine.ts +18 -0
  326. package/src/domain/engines/policy/PolicyEngine.ts +60 -0
  327. package/src/domain/engines/semver/IVersionComparator.ts +7 -0
  328. package/src/domain/engines/semver/SemVerEngine.ts +200 -0
  329. package/src/domain/errors/VersionManagerException.ts +166 -0
  330. package/src/domain/models/ActionPlan.ts +17 -0
  331. package/src/domain/models/ConfigDocument.ts +97 -0
  332. package/src/domain/models/Events.ts +48 -0
  333. package/src/domain/models/LifecycleState.ts +50 -0
  334. package/src/domain/models/ParsedVersion.ts +8 -0
  335. package/src/domain/models/PlatformId.ts +9 -0
  336. package/src/domain/models/PublicApiOptions.ts +14 -0
  337. package/src/domain/models/RemoteVersionInfo.ts +23 -0
  338. package/src/domain/models/StoreLookup.ts +12 -0
  339. package/src/domain/models/Unsubscribe.ts +1 -0
  340. package/src/domain/models/UpdateInfo.ts +11 -0
  341. package/src/domain/models/VersionManagerOptions.ts +150 -0
  342. package/src/domain/ports/ICacheStore.ts +5 -0
  343. package/src/domain/ports/IClock.ts +3 -0
  344. package/src/domain/ports/IConfigProvider.ts +18 -0
  345. package/src/domain/ports/IConfigSources.ts +44 -0
  346. package/src/domain/ports/IPlatformBridge.ts +97 -0
  347. package/src/domain/ports/IStoreProvider.ts +12 -0
  348. package/src/domain/ports/IVersionRepository.ts +14 -0
  349. package/src/domain/statemachine/LifecycleStateMachine.ts +76 -0
  350. package/src/domain/usecases/CheckForUpdatesUseCase.ts +63 -0
  351. package/src/domain/usecases/ForceTriggerUpdateUseCase.ts +35 -0
  352. package/src/domain/usecases/ResetIgnoredVersionsUseCase.ts +26 -0
  353. package/src/index.tsx +84 -0
  354. package/src/platform/contracts/IPlatformBridge.ts +14 -0
  355. package/src/platform/createPlatformBridge.native.ts +7 -0
  356. package/src/platform/createPlatformBridge.ts +15 -0
  357. package/src/platform/native/NativePlatformBridge.ts +179 -0
  358. package/src/platform/native/NativeVersionCheck.ts +64 -0
  359. package/src/platform/web/WebPlatformBridge.ts +347 -0
  360. package/src/presentation/components/ForceUpdateScreen.tsx +64 -0
  361. package/src/presentation/components/OptionalUpdateBanner.tsx +53 -0
  362. package/src/presentation/components/SoftUpdateDialog.tsx +84 -0
  363. package/src/presentation/hooks/VersionManagerProvider.tsx +23 -0
  364. package/src/presentation/hooks/context.ts +6 -0
  365. package/src/presentation/hooks/useUpdateState.ts +50 -0
  366. package/src/presentation/hooks/useVersionManager.ts +68 -0
  367. package/src/presentation/state/VersionManagerStore.ts +72 -0
  368. package/src/publicApi.ts +126 -0
  369. package/src/shared/eventbus/EventBus.ts +56 -0
  370. package/src/shared/logging/Logger.ts +70 -0
  371. package/src/ui.tsx +19 -0
@@ -0,0 +1,150 @@
1
+ import type { IPlatformBridge } from '../ports/IPlatformBridge';
2
+ import type {
3
+ SignatureAlgorithm,
4
+ VersionManagerConfigDocument,
5
+ } from './ConfigDocument';
6
+ import type { RemoteVersionInfo } from './RemoteVersionInfo';
7
+
8
+ export type LogLevel =
9
+ 'silent' | 'error' | 'warn' | 'info' | 'debug' | 'verbose';
10
+
11
+ export interface LogEntry {
12
+ readonly level: LogLevel;
13
+ readonly message: string;
14
+ readonly timestamp: number;
15
+ readonly metadata?: Readonly<Record<string, unknown>>;
16
+ }
17
+
18
+ export interface ILogSink {
19
+ write(entry: LogEntry): void;
20
+ }
21
+
22
+ export interface LoggingOptions {
23
+ level?: LogLevel;
24
+ sink?: ILogSink;
25
+ }
26
+
27
+ export interface CacheOptions {
28
+ ttlMs?: number;
29
+ storage?: 'memory' | 'persistent';
30
+ bustOnManualCheck?: boolean;
31
+ }
32
+
33
+ export interface RetryOptions {
34
+ maxAttempts?: number;
35
+ backoff?: 'fixed' | 'exponential-jitter';
36
+ baseDelayMs?: number;
37
+ }
38
+
39
+ export interface FallbackOptions {
40
+ onNetworkError?: 'useCache' | 'useDefaultConfig' | 'noAction';
41
+ defaultConfig?: RemoteVersionInfo;
42
+ requestTimeoutMs?: number;
43
+ retry?: RetryOptions;
44
+ }
45
+
46
+ export interface StoreLinksOptions {
47
+ /**
48
+ * appStoreId is optional — when omitted, the App Store lookup falls back to the
49
+ * running app's bundle id (IAppInfoProvider.getBundleId(), read at check time)
50
+ * instead of the numeric App Store Connect id.
51
+ */
52
+ ios?: { appStoreId?: string; region?: string };
53
+ /**
54
+ * packageName is optional — when omitted, the Google Play lookup falls back to the
55
+ * running app's bundle id (which *is* the Android package name) at check time.
56
+ */
57
+ android?: { packageName?: string };
58
+ huawei?: { appId: string };
59
+ amazon?: { asin: string };
60
+ custom?: { url: string; headers?: Record<string, string> };
61
+ }
62
+
63
+ export interface PolicyOptions {
64
+ forceUpdateBelow?: string;
65
+ reminderIntervalMs?: number;
66
+ rolloutPercentage?: number;
67
+ }
68
+
69
+ /** Doc 03 §1.1 Security field group — fixed by the app developer, tier-4 only. */
70
+ export interface SecurityOptions {
71
+ signatureAlgorithm?: SignatureAlgorithm;
72
+ trustedKeyIds?: string[];
73
+ }
74
+
75
+ /**
76
+ * Doc 03 §0/§4 — optional loadable-config-document extension points layered on top of
77
+ * the VersionManagerOptions "default fallback" tier. All optional; an app that supplies
78
+ * none of these still works, driven entirely by configure() options (tier 4 only).
79
+ */
80
+ export interface ConfigSourcesOptions {
81
+ /**
82
+ * Bundled local config envelope. Metro/webpack natively supports JSON imports
83
+ * (`import localConfig from './vm-config.json'`), which already avoids the
84
+ * double-buffer-copy §5.1 is concerned about for a <=64KB document without requiring
85
+ * a dedicated native mmap reader — pass the imported envelope object directly.
86
+ */
87
+ local?: import('./ConfigDocument').SignedConfigEnvelope;
88
+ /** Extra headers/timeout for the remote fetch beyond FallbackOptions.requestTimeoutMs. */
89
+ remoteFetchHeaders?: Record<string, string>;
90
+ /** Explicit runtime overrides — highest-precedence tier (§4.2 tier 1). */
91
+ envOverrides?: Partial<VersionManagerConfigDocument>;
92
+ /** Registered customUiHookIds -> handler ids that a config document is allowed to activate (§1.2, §7.1 VM-1009). */
93
+ registeredUiHookIds?: string[];
94
+ }
95
+
96
+ export interface VersionManagerOptions {
97
+ appVersion?: string;
98
+ logging?: LoggingOptions;
99
+ cache?: CacheOptions;
100
+ fallback?: FallbackOptions;
101
+ stores: StoreLinksOptions;
102
+ policy?: PolicyOptions;
103
+ /** DI override, advanced/testing use only (Prompt 2 §1.1). */
104
+ platformBridge?: IPlatformBridge;
105
+ strictReadiness?: boolean;
106
+ /** Doc 03 §1.1 — if absent, the SDK operates in local-file/default-only mode. */
107
+ remoteConfigUrl?: string;
108
+ security?: SecurityOptions;
109
+ configSources?: ConfigSourcesOptions;
110
+ }
111
+
112
+ /**
113
+ * Fully-defaulted, immutable configuration actually consumed at runtime, produced by
114
+ * IConfigProvider.resolve() from a VersionManagerOptions "default fallback" tier
115
+ * (Prompt 3 §4.2). Local-file/remote/env overlay tiers are extension points on
116
+ * IConfigProvider, not yet wired into a signed-envelope pipeline in this pass —
117
+ * see docs/architecture/03-configuration-system.md §3 for that follow-up scope.
118
+ */
119
+ export interface ResolvedVersionManagerConfig {
120
+ readonly appVersion: string | null;
121
+ readonly logging: { readonly level: LogLevel; readonly sink: ILogSink };
122
+ readonly cache: {
123
+ readonly ttlMs: number;
124
+ readonly storage: 'memory' | 'persistent';
125
+ readonly bustOnManualCheck: boolean;
126
+ };
127
+ readonly fallback: {
128
+ readonly onNetworkError: 'useCache' | 'useDefaultConfig' | 'noAction';
129
+ readonly defaultConfig: RemoteVersionInfo | null;
130
+ readonly requestTimeoutMs: number;
131
+ readonly retry: {
132
+ readonly maxAttempts: number;
133
+ readonly backoff: 'fixed' | 'exponential-jitter';
134
+ readonly baseDelayMs: number;
135
+ };
136
+ };
137
+ readonly stores: StoreLinksOptions;
138
+ readonly policy: {
139
+ readonly forceUpdateBelow: string | null;
140
+ readonly reminderIntervalMs: number;
141
+ readonly rolloutPercentage: number;
142
+ };
143
+ readonly strictReadiness: boolean;
144
+ readonly remoteConfigUrl: string | null;
145
+ readonly security: {
146
+ readonly signatureAlgorithm: SignatureAlgorithm;
147
+ readonly trustedKeyIds: readonly string[];
148
+ };
149
+ readonly schemaVersion: string;
150
+ }
@@ -0,0 +1,5 @@
1
+ export interface ICacheStore<T> {
2
+ get(key: string): Promise<T | null>;
3
+ set(key: string, value: T, ttlMs?: number): Promise<void>;
4
+ invalidate(key: string): Promise<void>;
5
+ }
@@ -0,0 +1,3 @@
1
+ export interface IClock {
2
+ now(): number;
3
+ }
@@ -0,0 +1,18 @@
1
+ import type { ConfigLoadRequest } from '../models/ConfigDocument';
2
+ import type {
3
+ ResolvedVersionManagerConfig,
4
+ VersionManagerOptions,
5
+ } from '../models/VersionManagerOptions';
6
+ import type { Unsubscribe } from './IPlatformBridge';
7
+
8
+ export interface IConfigProvider {
9
+ resolve(
10
+ defaults: VersionManagerOptions
11
+ ): Promise<ResolvedVersionManagerConfig>;
12
+ /** Doc 03 §0's named surface (`load(request)`) — delegates to resolve(request.defaults). */
13
+ load(request: ConfigLoadRequest): Promise<ResolvedVersionManagerConfig>;
14
+ /** Fires when a later resolution (e.g. a remote refresh) produces a changed config. */
15
+ subscribe(
16
+ listener: (config: ResolvedVersionManagerConfig) => void
17
+ ): Unsubscribe;
18
+ }
@@ -0,0 +1,44 @@
1
+ import type {
2
+ BoundaryValidationResult,
3
+ FetchOptions,
4
+ RawConfigDocument,
5
+ SchemaValidationResult,
6
+ SignedConfigEnvelope,
7
+ SignatureVerificationResult,
8
+ TrustedKeySet,
9
+ } from '../models/ConfigDocument';
10
+ import type { ResolvedVersionManagerConfig } from '../models/VersionManagerOptions';
11
+
12
+ /** Doc 03 §0 — small pipeline of ports living under src/data/config/. */
13
+
14
+ export interface ILocalConfigSource {
15
+ /** null if no bundled config asset/envelope was supplied. */
16
+ read(): Promise<RawConfigDocument | null>;
17
+ }
18
+
19
+ export interface IRemoteConfigSource {
20
+ fetch(url: string, options: FetchOptions): Promise<RawConfigDocument>;
21
+ }
22
+
23
+ export interface IEnvironmentOverrideSource {
24
+ read(): Promise<
25
+ Partial<import('../models/ConfigDocument').VersionManagerConfigDocument>
26
+ >;
27
+ }
28
+
29
+ export interface IConfigCache {
30
+ getLastValid(): Promise<ResolvedVersionManagerConfig | null>;
31
+ setLastValid(config: ResolvedVersionManagerConfig): Promise<void>;
32
+ }
33
+
34
+ export interface IConfigValidator {
35
+ validateSchema(doc: RawConfigDocument): SchemaValidationResult;
36
+ validateBoundaries(doc: RawConfigDocument): BoundaryValidationResult;
37
+ }
38
+
39
+ export interface ISignatureVerifier {
40
+ verify(
41
+ envelope: SignedConfigEnvelope,
42
+ trustedKeys: TrustedKeySet
43
+ ): Promise<SignatureVerificationResult>;
44
+ }
@@ -0,0 +1,97 @@
1
+ import type { PlatformId } from '../models/PlatformId';
2
+ import type { Unsubscribe } from '../models/Unsubscribe';
3
+ import type { IClock } from './IClock';
4
+
5
+ export type { Unsubscribe };
6
+
7
+ export interface HttpRequest {
8
+ readonly url: string;
9
+ readonly method: 'GET' | 'POST';
10
+ readonly headers?: Readonly<Record<string, string>>;
11
+ readonly body?: string;
12
+ readonly timeoutMs: number;
13
+ }
14
+
15
+ export interface HttpResponse {
16
+ readonly status: number;
17
+ readonly headers: Readonly<Record<string, string>>;
18
+ readonly body: string;
19
+ }
20
+
21
+ export interface IHttpClient {
22
+ request(req: HttpRequest): Promise<HttpResponse>;
23
+ }
24
+
25
+ export interface IKeyValueStorage {
26
+ get(key: string): Promise<string | null>;
27
+ set(key: string, value: string): Promise<void>;
28
+ remove(key: string): Promise<void>;
29
+ }
30
+
31
+ export interface ISecureStorage {
32
+ getItem(key: string): Promise<string | null>;
33
+ setItem(key: string, value: string): Promise<void>;
34
+ removeItem(key: string): Promise<void>;
35
+ }
36
+
37
+ export interface IAppInfoProvider {
38
+ getCurrentVersion(): Promise<string>;
39
+ getBuildNumber(): Promise<string>;
40
+ getBundleId(): Promise<string>;
41
+ }
42
+
43
+ export interface IDeviceInfoProvider {
44
+ getOsVersion(): Promise<string>;
45
+ getDeviceModel(): Promise<string>;
46
+ getLocale(): Promise<string>;
47
+ }
48
+
49
+ export interface BackgroundTaskDescriptor {
50
+ readonly taskId: string;
51
+ readonly minIntervalMs: number;
52
+ }
53
+
54
+ export interface IBackgroundScheduler {
55
+ schedule(task: BackgroundTaskDescriptor): Promise<void>;
56
+ cancel(taskId: string): Promise<void>;
57
+ }
58
+
59
+ export interface IAppLifecycleObserver {
60
+ onForeground(cb: () => void): Unsubscribe;
61
+ onBackground(cb: () => void): Unsubscribe;
62
+ }
63
+
64
+ /**
65
+ * Additive port (not in doc 01 §4's original table) backing ISignatureVerifier
66
+ * (doc 03 §3.4): "OS-provided cryptography exclusively." Optional because it is only
67
+ * required when a consumer configures remote/local signed config documents with
68
+ * algorithm !== 'none'. `keyId` (not raw key material) crosses the JS/native boundary —
69
+ * per doc 03 §3.4 the actual public key / HMAC secret is embedded at build time on the
70
+ * native side (iOS Info.plist/Secrets.xcconfig, Android BuildConfig) and resolved from
71
+ * `keyId` inside the native implementation; JS never sees key material.
72
+ */
73
+ export interface ICryptoProvider {
74
+ verifyEd25519(
75
+ keyId: string,
76
+ messageBase64: string,
77
+ signatureBase64: string
78
+ ): Promise<boolean>;
79
+ verifyHmacSha256(
80
+ keyId: string,
81
+ messageBase64: string,
82
+ macBase64: string
83
+ ): Promise<boolean>;
84
+ }
85
+
86
+ export interface IPlatformBridge {
87
+ readonly platform: PlatformId;
88
+ readonly http: IHttpClient;
89
+ readonly storage: IKeyValueStorage;
90
+ readonly secureStorage: ISecureStorage;
91
+ readonly appInfo: IAppInfoProvider;
92
+ readonly deviceInfo: IDeviceInfoProvider;
93
+ readonly scheduler: IBackgroundScheduler;
94
+ readonly clock: IClock;
95
+ readonly lifecycle: IAppLifecycleObserver;
96
+ readonly crypto?: ICryptoProvider;
97
+ }
@@ -0,0 +1,12 @@
1
+ import type { StoreProviderId } from '../models/PlatformId';
2
+ import type {
3
+ StoreLookupRequest,
4
+ StoreLookupResult,
5
+ } from '../models/StoreLookup';
6
+
7
+ export interface IStoreProvider {
8
+ readonly id: StoreProviderId;
9
+ fetchLatestVersionInfo(
10
+ request: StoreLookupRequest
11
+ ): Promise<StoreLookupResult>;
12
+ }
@@ -0,0 +1,14 @@
1
+ import type {
2
+ RemoteVersionInfo,
3
+ UserVersionDecision,
4
+ VersionCheckRequest,
5
+ } from '../models/RemoteVersionInfo';
6
+
7
+ export interface IVersionRepository {
8
+ getRemoteVersionInfo(
9
+ request: VersionCheckRequest
10
+ ): Promise<RemoteVersionInfo>;
11
+ getCachedVersionInfo(): Promise<RemoteVersionInfo | null>;
12
+ persistUserDecision(decision: UserVersionDecision): Promise<void>;
13
+ getUserDecision(): Promise<UserVersionDecision | null>;
14
+ }
@@ -0,0 +1,76 @@
1
+ import {
2
+ LIFECYCLE_TRANSITIONS,
3
+ LifecycleState,
4
+ } from '../models/LifecycleState';
5
+ import type { Unsubscribe } from '../models/Unsubscribe';
6
+
7
+ /** Internal invariant violation — not part of the public VersionManagerException hierarchy. */
8
+ export class InvalidTransitionError extends Error {
9
+ constructor(from: LifecycleState, to: LifecycleState) {
10
+ super(`Invalid lifecycle transition: ${from} -> ${to}`);
11
+ this.name = 'InvalidTransitionError';
12
+ }
13
+ }
14
+
15
+ export interface ILifecycleStateMachine {
16
+ readonly current: LifecycleState;
17
+ transition(to: LifecycleState): void;
18
+ onEnter(state: LifecycleState, handler: () => void): Unsubscribe;
19
+ onExit(state: LifecycleState, handler: () => void): Unsubscribe;
20
+ }
21
+
22
+ type HandlerMap = Map<LifecycleState, Set<() => void>>;
23
+
24
+ export class LifecycleStateMachine implements ILifecycleStateMachine {
25
+ private state: LifecycleState = LifecycleState.UNINITIALIZED;
26
+ private readonly enterHandlers: HandlerMap = new Map();
27
+ private readonly exitHandlers: HandlerMap = new Map();
28
+
29
+ get current(): LifecycleState {
30
+ return this.state;
31
+ }
32
+
33
+ transition(to: LifecycleState): void {
34
+ const allowed = LIFECYCLE_TRANSITIONS[this.state];
35
+ if (!allowed.includes(to)) {
36
+ throw new InvalidTransitionError(this.state, to);
37
+ }
38
+ const from = this.state;
39
+ this.notify(this.exitHandlers, from);
40
+ this.state = to;
41
+ this.notify(this.enterHandlers, to);
42
+ }
43
+
44
+ onEnter(state: LifecycleState, handler: () => void): Unsubscribe {
45
+ return this.register(this.enterHandlers, state, handler);
46
+ }
47
+
48
+ onExit(state: LifecycleState, handler: () => void): Unsubscribe {
49
+ return this.register(this.exitHandlers, state, handler);
50
+ }
51
+
52
+ private register(
53
+ map: HandlerMap,
54
+ state: LifecycleState,
55
+ handler: () => void
56
+ ): Unsubscribe {
57
+ let set = map.get(state);
58
+ if (!set) {
59
+ set = new Set();
60
+ map.set(state, set);
61
+ }
62
+ set.add(handler);
63
+ return () => {
64
+ set?.delete(handler);
65
+ };
66
+ }
67
+
68
+ /** Copy-on-write snapshot dispatch (Prompt 1 §9.2) — safe if a handler unsubscribes mid-dispatch. */
69
+ private notify(map: HandlerMap, state: LifecycleState): void {
70
+ const set = map.get(state);
71
+ if (!set) return;
72
+ for (const handler of Array.from(set)) {
73
+ handler();
74
+ }
75
+ }
76
+ }
@@ -0,0 +1,63 @@
1
+ import type { DecisionEngine } from '../engines/decision/DecisionEngine';
2
+ import type { IUpdatePolicyEngine } from '../engines/policy/IUpdatePolicyEngine';
3
+ import type { IVersionComparator } from '../engines/semver/IVersionComparator';
4
+ import type { ActionPlan } from '../models/ActionPlan';
5
+ import type { PlatformId } from '../models/PlatformId';
6
+ import type { IClock } from '../ports/IClock';
7
+ import type { IVersionRepository } from '../ports/IVersionRepository';
8
+
9
+ export interface CheckForUpdatesUseCaseDeps {
10
+ readonly repository: IVersionRepository;
11
+ readonly comparator: IVersionComparator;
12
+ readonly policyEngine: IUpdatePolicyEngine;
13
+ readonly decisionEngine: DecisionEngine;
14
+ readonly clock: IClock;
15
+ }
16
+
17
+ export interface CheckForUpdatesInput {
18
+ readonly currentVersion: string;
19
+ readonly bundleId: string;
20
+ readonly platform: PlatformId;
21
+ readonly bypassCache: boolean;
22
+ readonly timeoutMs: number;
23
+ readonly forceUpdateBelow: string | null;
24
+ readonly rolloutPercentage: number;
25
+ readonly rolloutBucket: number;
26
+ }
27
+
28
+ export class CheckForUpdatesUseCase {
29
+ constructor(private readonly deps: CheckForUpdatesUseCaseDeps) {}
30
+
31
+ async execute(input: CheckForUpdatesInput): Promise<ActionPlan> {
32
+ const remote = await this.deps.repository.getRemoteVersionInfo({
33
+ currentVersion: input.currentVersion,
34
+ bundleId: input.bundleId,
35
+ platform: input.platform,
36
+ bypassCache: input.bypassCache,
37
+ timeoutMs: input.timeoutMs,
38
+ });
39
+
40
+ const currentParsed = this.deps.comparator.parse(input.currentVersion);
41
+ const remoteParsed = this.deps.comparator.parse(remote.latestVersion);
42
+ const forceUpdateBelowParsed = input.forceUpdateBelow
43
+ ? this.deps.comparator.parse(input.forceUpdateBelow)
44
+ : null;
45
+ const userDecision = await this.deps.repository.getUserDecision();
46
+
47
+ const actionType = this.deps.policyEngine.evaluate({
48
+ currentVersion: currentParsed,
49
+ remoteVersion: remoteParsed,
50
+ forceUpdateBelow: forceUpdateBelowParsed,
51
+ userDecision,
52
+ now: this.deps.clock.now(),
53
+ rolloutPercentage: input.rolloutPercentage,
54
+ rolloutBucket: input.rolloutBucket,
55
+ });
56
+
57
+ return this.deps.decisionEngine.buildActionPlan(
58
+ actionType,
59
+ input.currentVersion,
60
+ remote
61
+ );
62
+ }
63
+ }
@@ -0,0 +1,35 @@
1
+ import { ActionType } from '../models/ActionPlan';
2
+ import type { ActionPlan } from '../models/ActionPlan';
3
+ import type { DecisionEngine } from '../engines/decision/DecisionEngine';
4
+ import type { PlatformId } from '../models/PlatformId';
5
+ import type { IVersionRepository } from '../ports/IVersionRepository';
6
+
7
+ export interface ForceTriggerUpdateInput {
8
+ readonly currentVersion: string;
9
+ readonly bundleId: string;
10
+ readonly platform: PlatformId;
11
+ readonly timeoutMs: number;
12
+ }
13
+
14
+ export class ForceTriggerUpdateUseCase {
15
+ constructor(
16
+ private readonly repository: IVersionRepository,
17
+ private readonly decisionEngine: DecisionEngine
18
+ ) {}
19
+
20
+ async execute(input: ForceTriggerUpdateInput): Promise<ActionPlan> {
21
+ const remote = await this.repository.getRemoteVersionInfo({
22
+ currentVersion: input.currentVersion,
23
+ bundleId: input.bundleId,
24
+ platform: input.platform,
25
+ bypassCache: true,
26
+ timeoutMs: input.timeoutMs,
27
+ });
28
+
29
+ return this.decisionEngine.buildActionPlan(
30
+ ActionType.FORCE_UPDATE,
31
+ input.currentVersion,
32
+ remote
33
+ );
34
+ }
35
+ }
@@ -0,0 +1,26 @@
1
+ import type { IVersionRepository } from '../ports/IVersionRepository';
2
+
3
+ export class ResetIgnoredVersionsUseCase {
4
+ constructor(private readonly repository: IVersionRepository) {}
5
+
6
+ async execute(versions?: readonly string[]): Promise<void> {
7
+ const current = await this.repository.getUserDecision();
8
+ const remindMeLaterUntil = current?.remindMeLaterUntil ?? null;
9
+
10
+ if (!versions || versions.length === 0) {
11
+ await this.repository.persistUserDecision({
12
+ ignoredVersions: [],
13
+ remindMeLaterUntil,
14
+ });
15
+ return;
16
+ }
17
+
18
+ const remaining = (current?.ignoredVersions ?? []).filter(
19
+ (v) => !versions.includes(v)
20
+ );
21
+ await this.repository.persistUserDecision({
22
+ ignoredVersions: remaining,
23
+ remindMeLaterUntil,
24
+ });
25
+ }
26
+ }
package/src/index.tsx ADDED
@@ -0,0 +1,84 @@
1
+ // Public API entry point (core only — no React/UI code reachable from this path,
2
+ // see src/ui.tsx for the Hooks adapter). Prompt 2.
3
+
4
+ export { VersionManager, VersionManagerBuilder } from './publicApi';
5
+
6
+ export type {
7
+ IVersionManagerCore,
8
+ IVersionManagerEvents,
9
+ } from './domain/IVersionManagerCore';
10
+
11
+ export type { ActionPlan } from './domain/models/ActionPlan';
12
+ export { ActionType } from './domain/models/ActionPlan';
13
+ export type { ParsedVersion } from './domain/models/ParsedVersion';
14
+ export type { UpdateInfo } from './domain/models/UpdateInfo';
15
+ export { LifecycleState } from './domain/models/LifecycleState';
16
+ export type { PlatformId, StoreProviderId } from './domain/models/PlatformId';
17
+ export type {
18
+ RemoteVersionInfo,
19
+ UserVersionDecision,
20
+ VersionCheckRequest,
21
+ } from './domain/models/RemoteVersionInfo';
22
+ export type { Unsubscribe } from './domain/models/Unsubscribe';
23
+ export type {
24
+ CheckForUpdatesOptions,
25
+ ForceTriggerOptions,
26
+ ResetIgnoredVersionsOptions,
27
+ } from './domain/models/PublicApiOptions';
28
+ export type {
29
+ CacheOptions,
30
+ FallbackOptions,
31
+ ILogSink,
32
+ LogEntry,
33
+ LoggingOptions,
34
+ LogLevel,
35
+ PolicyOptions,
36
+ ResolvedVersionManagerConfig,
37
+ RetryOptions,
38
+ StoreLinksOptions,
39
+ VersionManagerOptions,
40
+ } from './domain/models/VersionManagerOptions';
41
+ export type {
42
+ ErrorPhase,
43
+ StateChangedEvent,
44
+ UpdateDetectedEvent,
45
+ UpdateNotAvailableEvent,
46
+ UserActionEvent,
47
+ UserActionType,
48
+ VersionManagerErrorEvent,
49
+ VersionManagerEventMap,
50
+ VersionManagerEventType,
51
+ } from './domain/models/Events';
52
+
53
+ export type { IPlatformBridge } from './domain/ports/IPlatformBridge';
54
+
55
+ export {
56
+ AppNotFoundException,
57
+ BoundaryValidationException,
58
+ CacheCorruptionException,
59
+ CacheException,
60
+ CacheWriteException,
61
+ ConfigSizeLimitExceededException,
62
+ EnvironmentOverrideConflictException,
63
+ InvalidConfigException,
64
+ InvalidVersionFormatException,
65
+ NetworkException,
66
+ NotInitializedException,
67
+ NotReadyException,
68
+ OfflineException,
69
+ PlatformBridgeException,
70
+ PolicyEvaluationException,
71
+ RateLimitException,
72
+ RequestTimeoutException,
73
+ SchemaValidationException,
74
+ SignatureVerificationException,
75
+ StorePermissionException,
76
+ StoreProviderException,
77
+ StoreResponseParseException,
78
+ TlsHandshakeException,
79
+ UnknownVersionManagerException,
80
+ UnsupportedStoreException,
81
+ UntrustedKeyIdException,
82
+ VersionManagerException,
83
+ } from './domain/errors/VersionManagerException';
84
+ export type { VersionManagerErrorCode } from './domain/errors/VersionManagerException';
@@ -0,0 +1,14 @@
1
+ export type {
2
+ IPlatformBridge,
3
+ IHttpClient,
4
+ IKeyValueStorage,
5
+ ISecureStorage,
6
+ IAppInfoProvider,
7
+ IDeviceInfoProvider,
8
+ IBackgroundScheduler,
9
+ IAppLifecycleObserver,
10
+ ICryptoProvider,
11
+ BackgroundTaskDescriptor,
12
+ HttpRequest,
13
+ HttpResponse,
14
+ } from '../../domain/ports/IPlatformBridge';
@@ -0,0 +1,7 @@
1
+ import type { IPlatformBridge } from '../domain/ports/IPlatformBridge';
2
+ import { NativePlatformBridge } from './native/NativePlatformBridge';
3
+
4
+ /** iOS/Android implementation — see createPlatformBridge.ts for why this is a separate file. */
5
+ export function createPlatformBridge(): IPlatformBridge {
6
+ return new NativePlatformBridge();
7
+ }
@@ -0,0 +1,15 @@
1
+ import type { IPlatformBridge } from '../domain/ports/IPlatformBridge';
2
+ import { WebPlatformBridge } from './web/WebPlatformBridge';
3
+
4
+ /**
5
+ * Web/default implementation. Metro (React Native's bundler) prefers
6
+ * createPlatformBridge.native.ts for iOS/Android builds; Vite (the web build, see
7
+ * example/vite.config.mjs) has no such resolution rule and always resolves this file
8
+ * — the same convention already used by src/multiply.tsx / multiply.native.tsx. This
9
+ * indirection matters: NativePlatformBridge.ts imports NativeVersionCheck, whose
10
+ * top-level TurboModuleRegistry.getEnforcing() call would throw if ever evaluated on
11
+ * Web, so the native module must never even be imported into a web bundle.
12
+ */
13
+ export function createPlatformBridge(): IPlatformBridge {
14
+ return new WebPlatformBridge();
15
+ }