@tma.js/sdk 0.13.3 → 1.0.1

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 (426) hide show
  1. package/dist/dts/{components/BackButton → back-button}/BackButton.d.ts +12 -9
  2. package/dist/dts/back-button/index.d.ts +2 -0
  3. package/dist/dts/{components/BackButton → back-button}/types.d.ts +3 -2
  4. package/dist/dts/bridge/env/hasExternalNotify.d.ts +12 -0
  5. package/dist/dts/bridge/env/hasWebviewProxy.d.ts +12 -0
  6. package/dist/dts/bridge/env/index.d.ts +3 -0
  7. package/dist/dts/bridge/env/isIframe.d.ts +5 -0
  8. package/dist/dts/bridge/errors/MethodUnsupportedError.d.ts +8 -0
  9. package/dist/dts/bridge/errors/ParameterUnsupportedError.d.ts +8 -0
  10. package/dist/dts/bridge/errors/index.d.ts +2 -0
  11. package/dist/dts/bridge/events/createEmitter.d.ts +6 -0
  12. package/dist/dts/bridge/events/events.d.ts +130 -0
  13. package/dist/dts/bridge/events/index.d.ts +9 -0
  14. package/dist/dts/bridge/events/off.d.ts +7 -0
  15. package/dist/dts/bridge/events/on.d.ts +10 -0
  16. package/dist/dts/bridge/events/onTelegramEvent.d.ts +7 -0
  17. package/dist/dts/bridge/events/once.d.ts +9 -0
  18. package/dist/dts/bridge/events/parsers/clipboardTextReceived.d.ts +13 -0
  19. package/dist/dts/bridge/events/parsers/customMethodInvoked.d.ts +16 -0
  20. package/dist/dts/bridge/events/parsers/index.d.ts +9 -0
  21. package/dist/dts/bridge/events/parsers/invoiceClosed.d.ts +12 -0
  22. package/dist/dts/bridge/events/parsers/phoneRequested.d.ts +8 -0
  23. package/dist/dts/bridge/events/parsers/popupClosed.d.ts +8 -0
  24. package/dist/dts/bridge/events/parsers/qrTextReceived.d.ts +7 -0
  25. package/dist/dts/bridge/events/parsers/theme-changed.d.ts +42 -0
  26. package/dist/dts/bridge/events/parsers/viewportChanged.d.ts +19 -0
  27. package/dist/dts/bridge/events/parsers/writeAccessRequested.d.ts +8 -0
  28. package/dist/dts/bridge/events/singletonEmitter.d.ts +6 -0
  29. package/dist/dts/bridge/events/subscribe.d.ts +9 -0
  30. package/dist/dts/bridge/events/unsubscribe.d.ts +6 -0
  31. package/dist/dts/bridge/index.d.ts +5 -0
  32. package/dist/dts/bridge/methods/createPostEvent.d.ts +10 -0
  33. package/dist/dts/bridge/methods/haptic.d.ts +40 -0
  34. package/dist/dts/bridge/methods/index.d.ts +6 -0
  35. package/dist/dts/bridge/methods/invoke-custom-method.d.ts +24 -0
  36. package/dist/dts/bridge/methods/methods.d.ts +329 -0
  37. package/dist/dts/bridge/methods/popup.d.ts +49 -0
  38. package/dist/dts/bridge/methods/postEvent.d.ts +29 -0
  39. package/dist/dts/bridge/request.d.ts +65 -0
  40. package/dist/dts/classnames/classNames.d.ts +10 -0
  41. package/dist/dts/classnames/index.d.ts +2 -0
  42. package/dist/dts/classnames/mergeClassNames.d.ts +32 -0
  43. package/dist/dts/{components/ClosingBehaviour/ClosingBehaviour.d.ts → closing-behavior/ClosingBehavior.d.ts} +5 -4
  44. package/dist/dts/closing-behavior/index.d.ts +2 -0
  45. package/dist/dts/closing-behavior/types.d.ts +7 -0
  46. package/dist/dts/{components/CloudStorage → cloud-storage}/CloudStorage.d.ts +19 -11
  47. package/dist/dts/colors/index.d.ts +5 -0
  48. package/dist/dts/colors/isColorDark.d.ts +6 -0
  49. package/dist/dts/colors/isRGB.d.ts +6 -0
  50. package/dist/dts/colors/isRGBShort.d.ts +6 -0
  51. package/dist/dts/colors/toRGB.d.ts +11 -0
  52. package/dist/dts/colors/types.d.ts +8 -0
  53. package/dist/dts/event-emitter/EventEmitter.d.ts +64 -0
  54. package/dist/dts/event-emitter/index.d.ts +2 -0
  55. package/dist/dts/event-emitter/types.d.ts +44 -0
  56. package/dist/dts/globals.d.ts +22 -0
  57. package/dist/dts/{components/HapticFeedback → haptic-feedback}/HapticFeedback.d.ts +3 -3
  58. package/dist/dts/index.d.ts +24 -6
  59. package/dist/dts/init/catchCustomStyles.d.ts +4 -0
  60. package/dist/dts/init/creators/createBackButton.d.ts +2 -2
  61. package/dist/dts/init/creators/createClosingBehavior.d.ts +3 -3
  62. package/dist/dts/init/creators/createMainButton.d.ts +3 -3
  63. package/dist/dts/init/creators/createMiniApp.d.ts +14 -0
  64. package/dist/dts/init/creators/createRequestIdGenerator.d.ts +1 -1
  65. package/dist/dts/init/creators/createThemeParams.d.ts +2 -3
  66. package/dist/dts/init/creators/createViewport.d.ts +16 -9
  67. package/dist/dts/init/creators/index.d.ts +1 -1
  68. package/dist/dts/init/css/bindMiniAppCSSVars.d.ts +16 -0
  69. package/dist/dts/init/css/bindThemeCSSVars.d.ts +12 -0
  70. package/dist/dts/init/css/bindViewportCSSVars.d.ts +20 -0
  71. package/dist/dts/init/css/index.d.ts +1 -0
  72. package/dist/dts/init/css/processCSSVarsOption.d.ts +12 -0
  73. package/dist/dts/init/css/setCSSVar.d.ts +6 -0
  74. package/dist/dts/init/init.d.ts +5 -5
  75. package/dist/dts/init/types.d.ts +42 -69
  76. package/dist/dts/init-data/InitData.d.ts +53 -0
  77. package/dist/dts/init-data/chatParser.d.ts +5 -0
  78. package/dist/dts/init-data/index.d.ts +6 -0
  79. package/dist/dts/init-data/initDataParser.d.ts +5 -0
  80. package/dist/dts/init-data/parseInitData.d.ts +6 -0
  81. package/dist/dts/init-data/types.d.ts +133 -0
  82. package/dist/dts/init-data/userParser.d.ts +5 -0
  83. package/dist/dts/invoice/Invoice.d.ts +43 -0
  84. package/dist/dts/invoice/index.d.ts +2 -0
  85. package/dist/dts/invoice/types.d.ts +7 -0
  86. package/dist/dts/launch-params/computeLaunchData.d.ts +6 -0
  87. package/dist/dts/launch-params/computePageReload.d.ts +6 -0
  88. package/dist/dts/launch-params/getFirstNavigationEntry.d.ts +6 -0
  89. package/dist/dts/launch-params/index.d.ts +12 -0
  90. package/dist/dts/launch-params/launchParamsParser.d.ts +5 -0
  91. package/dist/dts/launch-params/parseLaunchParams.d.ts +6 -0
  92. package/dist/dts/launch-params/retrieveCurrent.d.ts +5 -0
  93. package/dist/dts/launch-params/retrieveFromLocation.d.ts +6 -0
  94. package/dist/dts/launch-params/retrieveFromPerformance.d.ts +8 -0
  95. package/dist/dts/launch-params/retrieveLaunchData.d.ts +6 -0
  96. package/dist/dts/launch-params/serializeLaunchParams.d.ts +6 -0
  97. package/dist/dts/launch-params/storage.d.ts +13 -0
  98. package/dist/dts/launch-params/types.d.ts +48 -0
  99. package/dist/dts/logger/Logger.d.ts +38 -0
  100. package/dist/dts/logger/index.d.ts +1 -0
  101. package/dist/dts/main-button/MainButton.d.ts +104 -0
  102. package/dist/dts/main-button/index.d.ts +2 -0
  103. package/dist/dts/main-button/types.d.ts +20 -0
  104. package/dist/dts/mini-app/MiniApp.d.ts +99 -0
  105. package/dist/dts/mini-app/index.d.ts +2 -0
  106. package/dist/dts/mini-app/types.d.ts +19 -0
  107. package/dist/dts/misc/index.d.ts +2 -0
  108. package/dist/dts/misc/isRecord.d.ts +5 -0
  109. package/dist/dts/misc/isTMA.d.ts +4 -0
  110. package/dist/dts/navigation/HashNavigator/HashNavigator.d.ts +43 -0
  111. package/dist/dts/navigation/HashNavigator/drop.d.ts +4 -0
  112. package/dist/dts/navigation/HashNavigator/go.d.ts +5 -0
  113. package/dist/dts/navigation/HashNavigator/index.d.ts +2 -0
  114. package/dist/dts/navigation/HashNavigator/types.d.ts +34 -0
  115. package/dist/dts/navigation/Navigator/Navigator.d.ts +104 -0
  116. package/dist/dts/navigation/Navigator/index.d.ts +2 -0
  117. package/dist/dts/navigation/Navigator/types.d.ts +44 -0
  118. package/dist/dts/navigation/ensurePrefix.d.ts +7 -0
  119. package/dist/dts/navigation/getHash.d.ts +14 -0
  120. package/dist/dts/navigation/index.d.ts +4 -0
  121. package/dist/dts/parsing/ArrayValueParser.d.ts +18 -0
  122. package/dist/dts/parsing/ParseError.d.ts +22 -0
  123. package/dist/dts/parsing/ParseSchemaFieldError.d.ts +17 -0
  124. package/dist/dts/parsing/ValueParser.d.ts +36 -0
  125. package/dist/dts/parsing/createValueParserGenerator.d.ts +9 -0
  126. package/dist/dts/parsing/index.d.ts +10 -0
  127. package/dist/dts/parsing/parseBySchema.d.ts +8 -0
  128. package/dist/dts/parsing/parsers/array.d.ts +6 -0
  129. package/dist/dts/parsing/parsers/boolean.d.ts +4 -0
  130. package/dist/dts/parsing/parsers/date.d.ts +4 -0
  131. package/dist/dts/parsing/parsers/index.d.ts +8 -0
  132. package/dist/dts/parsing/parsers/json.d.ts +8 -0
  133. package/dist/dts/parsing/parsers/number.d.ts +4 -0
  134. package/dist/dts/parsing/parsers/rgb.d.ts +4 -0
  135. package/dist/dts/parsing/parsers/searchParams.d.ts +8 -0
  136. package/dist/dts/parsing/parsers/string.d.ts +4 -0
  137. package/dist/dts/parsing/toRecord.d.ts +7 -0
  138. package/dist/dts/parsing/types.d.ts +30 -0
  139. package/dist/dts/parsing/unexpectedTypeError.d.ts +4 -0
  140. package/dist/dts/{components/Popup → popup}/Popup.d.ts +10 -9
  141. package/dist/dts/popup/index.d.ts +2 -0
  142. package/dist/dts/popup/preparePopupParams.d.ts +7 -0
  143. package/dist/dts/{components/Popup → popup}/types.d.ts +4 -4
  144. package/dist/dts/{components/QRScanner → qr-scanner}/QRScanner.d.ts +6 -5
  145. package/dist/dts/qr-scanner/index.d.ts +2 -0
  146. package/dist/dts/{components/QRScanner → qr-scanner}/types.d.ts +1 -1
  147. package/dist/dts/state/State.d.ts +19 -7
  148. package/dist/dts/state/types.d.ts +4 -7
  149. package/dist/dts/storage.d.ts +4 -4
  150. package/dist/dts/supports/createSupportsFunc.d.ts +10 -0
  151. package/dist/dts/supports/createSupportsParamFunc.d.ts +15 -0
  152. package/dist/dts/supports/index.d.ts +4 -0
  153. package/dist/dts/supports/supports.d.ts +15 -0
  154. package/dist/dts/supports/types.d.ts +1 -0
  155. package/dist/dts/theme-params/ThemeParams.d.ts +62 -0
  156. package/dist/dts/theme-params/index.d.ts +6 -0
  157. package/dist/dts/theme-params/keys.d.ts +11 -0
  158. package/dist/dts/theme-params/parseThemeParams.d.ts +6 -0
  159. package/dist/dts/theme-params/requestThemeParams.d.ts +7 -0
  160. package/dist/dts/theme-params/serializeThemeParams.d.ts +5 -0
  161. package/dist/dts/theme-params/themeParamsParser.d.ts +2 -0
  162. package/dist/dts/theme-params/types.d.ts +14 -0
  163. package/dist/dts/timeout/TimeoutError.d.ts +3 -0
  164. package/dist/dts/timeout/index.d.ts +3 -0
  165. package/dist/dts/timeout/isTimeoutError.d.ts +6 -0
  166. package/dist/dts/timeout/withTimeout.d.ts +14 -0
  167. package/dist/dts/types/index.d.ts +3 -0
  168. package/dist/dts/types/platform.d.ts +4 -0
  169. package/dist/dts/types/request-id.d.ts +9 -0
  170. package/dist/dts/types/utils.d.ts +36 -0
  171. package/dist/dts/utils/Utils.d.ts +45 -0
  172. package/dist/dts/utils/index.d.ts +1 -0
  173. package/dist/dts/version/compareVersions.d.ts +8 -0
  174. package/dist/dts/version/index.d.ts +2 -0
  175. package/dist/dts/version/types.d.ts +4 -0
  176. package/dist/dts/{components/Viewport → viewport}/Viewport.d.ts +16 -38
  177. package/dist/dts/viewport/index.d.ts +3 -0
  178. package/dist/dts/viewport/requestViewport.d.ts +12 -0
  179. package/dist/dts/{components/Viewport → viewport}/types.d.ts +9 -1
  180. package/dist/dts/viewport/utils.d.ts +5 -0
  181. package/dist/index.cjs +1 -1
  182. package/dist/index.cjs.map +1 -1
  183. package/dist/index.iife.js +1 -1
  184. package/dist/index.iife.js.map +1 -1
  185. package/dist/index.mjs +2254 -1027
  186. package/dist/index.mjs.map +1 -1
  187. package/package.json +7 -16
  188. package/src/{components/BackButton → back-button}/BackButton.ts +23 -21
  189. package/src/back-button/index.ts +2 -0
  190. package/src/{components/BackButton → back-button}/types.ts +3 -2
  191. package/src/bridge/env/hasExternalNotify.ts +19 -0
  192. package/src/bridge/env/hasWebviewProxy.ts +19 -0
  193. package/src/bridge/env/index.ts +3 -0
  194. package/src/bridge/env/isIframe.ts +11 -0
  195. package/src/bridge/errors/MethodUnsupportedError.ts +13 -0
  196. package/src/bridge/errors/ParameterUnsupportedError.ts +13 -0
  197. package/src/bridge/errors/index.ts +2 -0
  198. package/src/bridge/events/createEmitter.ts +108 -0
  199. package/src/bridge/events/events.ts +170 -0
  200. package/src/bridge/events/index.ts +9 -0
  201. package/src/bridge/events/off.ts +14 -0
  202. package/src/bridge/events/on.ts +19 -0
  203. package/src/bridge/events/onTelegramEvent.ts +83 -0
  204. package/src/bridge/events/once.ts +18 -0
  205. package/src/bridge/events/parsers/clipboardTextReceived.ts +26 -0
  206. package/src/bridge/events/parsers/customMethodInvoked.ts +25 -0
  207. package/src/bridge/events/parsers/index.ts +9 -0
  208. package/src/bridge/events/parsers/invoiceClosed.ts +26 -0
  209. package/src/bridge/events/parsers/phoneRequested.ts +14 -0
  210. package/src/bridge/events/parsers/popupClosed.ts +19 -0
  211. package/src/bridge/events/parsers/qrTextReceived.ts +14 -0
  212. package/src/bridge/events/parsers/theme-changed.ts +58 -0
  213. package/src/bridge/events/parsers/viewportChanged.ts +33 -0
  214. package/src/bridge/events/parsers/writeAccessRequested.ts +14 -0
  215. package/src/bridge/events/singletonEmitter.ts +19 -0
  216. package/src/bridge/events/subscribe.ts +15 -0
  217. package/src/bridge/events/unsubscribe.ts +10 -0
  218. package/src/bridge/index.ts +5 -0
  219. package/src/bridge/methods/createPostEvent.ts +40 -0
  220. package/src/bridge/methods/haptic.ts +52 -0
  221. package/src/bridge/methods/index.ts +6 -0
  222. package/src/bridge/methods/invoke-custom-method.ts +25 -0
  223. package/src/bridge/methods/methods.ts +372 -0
  224. package/src/bridge/methods/popup.ts +53 -0
  225. package/src/bridge/methods/postEvent.ts +101 -0
  226. package/src/bridge/request.ts +185 -0
  227. package/src/classnames/classNames.ts +34 -0
  228. package/src/classnames/index.ts +2 -0
  229. package/src/classnames/mergeClassNames.ts +68 -0
  230. package/src/{components/ClosingBehaviour/ClosingBehaviour.ts → closing-behavior/ClosingBehavior.ts} +12 -10
  231. package/src/closing-behavior/index.ts +2 -0
  232. package/src/closing-behavior/types.ts +12 -0
  233. package/src/{components/CloudStorage → cloud-storage}/CloudStorage.ts +50 -28
  234. package/src/colors/index.ts +5 -0
  235. package/src/colors/isColorDark.ts +22 -0
  236. package/src/colors/isRGB.ts +9 -0
  237. package/src/colors/isRGBShort.ts +9 -0
  238. package/src/colors/toRGB.ts +49 -0
  239. package/src/colors/types.ts +9 -0
  240. package/src/event-emitter/EventEmitter.ts +146 -0
  241. package/src/event-emitter/index.ts +2 -0
  242. package/src/event-emitter/types.ts +60 -0
  243. package/src/globals.ts +38 -0
  244. package/src/{components/HapticFeedback → haptic-feedback}/HapticFeedback.ts +16 -8
  245. package/src/index.ts +171 -6
  246. package/src/init/catchCustomStyles.ts +17 -0
  247. package/src/init/creators/createBackButton.ts +4 -6
  248. package/src/init/creators/createClosingBehavior.ts +6 -8
  249. package/src/init/creators/createMainButton.ts +13 -20
  250. package/src/init/creators/createMiniApp.ts +44 -0
  251. package/src/init/creators/createRequestIdGenerator.ts +1 -1
  252. package/src/init/creators/createThemeParams.ts +3 -6
  253. package/src/init/creators/createViewport.ts +92 -42
  254. package/src/init/creators/index.ts +1 -1
  255. package/src/init/css/bindMiniAppCSSVars.ts +48 -0
  256. package/src/init/css/bindThemeCSSVars.ts +31 -0
  257. package/src/init/css/bindViewportCSSVars.ts +36 -0
  258. package/src/init/css/index.ts +1 -0
  259. package/src/init/css/processCSSVarsOption.ts +57 -0
  260. package/src/init/css/setCSSVar.ts +8 -0
  261. package/src/init/init.ts +119 -154
  262. package/src/init/types.ts +42 -87
  263. package/src/init-data/InitData.ts +96 -0
  264. package/src/init-data/chatParser.ts +19 -0
  265. package/src/init-data/index.ts +6 -0
  266. package/src/init-data/initDataParser.ts +41 -0
  267. package/src/init-data/parseInitData.ts +10 -0
  268. package/src/init-data/types.ts +164 -0
  269. package/src/init-data/userParser.ts +45 -0
  270. package/src/invoice/Invoice.ts +123 -0
  271. package/src/invoice/index.ts +2 -0
  272. package/src/invoice/types.ts +11 -0
  273. package/src/launch-params/computeLaunchData.ts +81 -0
  274. package/src/launch-params/computePageReload.ts +13 -0
  275. package/src/launch-params/getFirstNavigationEntry.ts +10 -0
  276. package/src/launch-params/index.ts +12 -0
  277. package/src/launch-params/launchParamsParser.ts +41 -0
  278. package/src/launch-params/parseLaunchParams.ts +10 -0
  279. package/src/launch-params/retrieveCurrent.ts +27 -0
  280. package/src/launch-params/retrieveFromLocation.ts +10 -0
  281. package/src/launch-params/retrieveFromPerformance.ts +23 -0
  282. package/src/launch-params/retrieveLaunchData.ts +30 -0
  283. package/src/launch-params/serializeLaunchParams.ts +37 -0
  284. package/src/launch-params/storage.ts +33 -0
  285. package/src/launch-params/types.ts +57 -0
  286. package/src/logger/Logger.ts +72 -0
  287. package/src/logger/index.ts +1 -0
  288. package/src/main-button/MainButton.ts +239 -0
  289. package/src/main-button/index.ts +2 -0
  290. package/src/main-button/types.ts +26 -0
  291. package/src/mini-app/MiniApp.ts +237 -0
  292. package/src/mini-app/index.ts +2 -0
  293. package/src/mini-app/types.ts +25 -0
  294. package/src/misc/index.ts +2 -0
  295. package/src/misc/isRecord.ts +7 -0
  296. package/src/misc/isTMA.ts +13 -0
  297. package/src/navigation/HashNavigator/HashNavigator.ts +220 -0
  298. package/src/navigation/HashNavigator/drop.ts +36 -0
  299. package/src/navigation/HashNavigator/go.ts +28 -0
  300. package/src/navigation/HashNavigator/index.ts +2 -0
  301. package/src/navigation/HashNavigator/types.ts +41 -0
  302. package/src/navigation/Navigator/Navigator.ts +282 -0
  303. package/src/navigation/Navigator/index.ts +2 -0
  304. package/src/navigation/Navigator/types.ts +55 -0
  305. package/src/navigation/ensurePrefix.ts +9 -0
  306. package/src/navigation/getHash.ts +17 -0
  307. package/src/navigation/index.ts +4 -0
  308. package/src/parsing/ArrayValueParser.ts +79 -0
  309. package/src/parsing/ParseError.ts +27 -0
  310. package/src/parsing/ParseSchemaFieldError.ts +21 -0
  311. package/src/parsing/ValueParser.ts +71 -0
  312. package/src/parsing/createValueParserGenerator.ts +16 -0
  313. package/src/parsing/index.ts +10 -0
  314. package/src/parsing/parseBySchema.ts +65 -0
  315. package/src/parsing/parsers/array.ts +9 -0
  316. package/src/parsing/parsers/boolean.ts +22 -0
  317. package/src/parsing/parsers/date.ts +13 -0
  318. package/src/parsing/parsers/index.ts +8 -0
  319. package/src/parsing/parsers/json.ts +17 -0
  320. package/src/parsing/parsers/number.ts +21 -0
  321. package/src/parsing/parsers/rgb.ts +12 -0
  322. package/src/parsing/parsers/searchParams.ts +24 -0
  323. package/src/parsing/parsers/string.ts +12 -0
  324. package/src/parsing/toRecord.ts +27 -0
  325. package/src/parsing/types.ts +32 -0
  326. package/src/parsing/unexpectedTypeError.ts +6 -0
  327. package/src/{components/Popup → popup}/Popup.ts +38 -28
  328. package/src/popup/index.ts +2 -0
  329. package/src/{components/Popup/utils.ts → popup/preparePopupParams.ts} +3 -3
  330. package/src/{components/Popup → popup}/types.ts +4 -4
  331. package/src/{components/QRScanner → qr-scanner}/QRScanner.ts +18 -10
  332. package/src/qr-scanner/index.ts +2 -0
  333. package/src/{components/QRScanner → qr-scanner}/types.ts +1 -1
  334. package/src/state/State.ts +31 -21
  335. package/src/state/types.ts +5 -8
  336. package/src/storage.ts +6 -4
  337. package/src/supports/createSupportsFunc.ts +18 -0
  338. package/src/supports/createSupportsParamFunc.ts +27 -0
  339. package/src/supports/index.ts +4 -0
  340. package/src/supports/supports.ts +84 -0
  341. package/src/supports/types.ts +1 -0
  342. package/src/theme-params/ThemeParams.ts +131 -0
  343. package/src/theme-params/index.ts +6 -0
  344. package/src/theme-params/keys.ts +24 -0
  345. package/src/theme-params/parseThemeParams.ts +10 -0
  346. package/src/theme-params/requestThemeParams.ts +13 -0
  347. package/src/theme-params/serializeThemeParams.ts +20 -0
  348. package/src/theme-params/themeParamsParser.ts +20 -0
  349. package/src/theme-params/types.ts +33 -0
  350. package/src/timeout/TimeoutError.ts +6 -0
  351. package/src/timeout/index.ts +3 -0
  352. package/src/timeout/isTimeoutError.ts +9 -0
  353. package/src/timeout/withTimeout.ts +36 -0
  354. package/src/types/index.ts +3 -0
  355. package/src/types/platform.ts +14 -0
  356. package/src/types/request-id.ts +10 -0
  357. package/src/types/utils.ts +50 -0
  358. package/src/utils/Utils.ts +107 -0
  359. package/src/utils/index.ts +1 -0
  360. package/src/version/compareVersions.ts +28 -0
  361. package/src/version/index.ts +2 -0
  362. package/src/version/types.ts +4 -0
  363. package/src/{components/Viewport → viewport}/Viewport.ts +72 -98
  364. package/src/viewport/index.ts +3 -0
  365. package/src/viewport/requestViewport.ts +23 -0
  366. package/src/{components/Viewport → viewport}/types.ts +10 -1
  367. package/src/viewport/utils.ts +7 -0
  368. package/dist/dts/components/BackButton/index.d.ts +0 -2
  369. package/dist/dts/components/ClosingBehaviour/index.d.ts +0 -2
  370. package/dist/dts/components/ClosingBehaviour/types.d.ts +0 -7
  371. package/dist/dts/components/InitData/InitData.d.ts +0 -60
  372. package/dist/dts/components/InitData/index.d.ts +0 -1
  373. package/dist/dts/components/MainButton/MainButton.d.ts +0 -114
  374. package/dist/dts/components/MainButton/index.d.ts +0 -2
  375. package/dist/dts/components/MainButton/types.d.ts +0 -15
  376. package/dist/dts/components/Popup/index.d.ts +0 -2
  377. package/dist/dts/components/Popup/utils.d.ts +0 -7
  378. package/dist/dts/components/QRScanner/index.d.ts +0 -2
  379. package/dist/dts/components/ThemeParams/ThemeParams.d.ts +0 -85
  380. package/dist/dts/components/ThemeParams/index.d.ts +0 -2
  381. package/dist/dts/components/ThemeParams/types.d.ts +0 -6
  382. package/dist/dts/components/Viewport/index.d.ts +0 -2
  383. package/dist/dts/components/WebApp/WebApp.d.ts +0 -146
  384. package/dist/dts/components/WebApp/index.d.ts +0 -2
  385. package/dist/dts/components/WebApp/types.d.ts +0 -11
  386. package/dist/dts/components/index.d.ts +0 -11
  387. package/dist/dts/env.d.ts +0 -10
  388. package/dist/dts/errors/MethodNotSupportedError.d.ts +0 -6
  389. package/dist/dts/errors/ParameterNotSupportedError.d.ts +0 -6
  390. package/dist/dts/errors/index.d.ts +0 -2
  391. package/dist/dts/init/creators/createWebApp.d.ts +0 -16
  392. package/dist/dts/init/css.d.ts +0 -50
  393. package/dist/dts/supports.d.ts +0 -22
  394. package/dist/dts/types.d.ts +0 -10
  395. package/dist/dts/url.d.ts +0 -7
  396. package/src/components/BackButton/index.ts +0 -2
  397. package/src/components/ClosingBehaviour/index.ts +0 -6
  398. package/src/components/ClosingBehaviour/types.ts +0 -12
  399. package/src/components/InitData/InitData.ts +0 -139
  400. package/src/components/InitData/index.ts +0 -1
  401. package/src/components/MainButton/MainButton.ts +0 -242
  402. package/src/components/MainButton/index.ts +0 -2
  403. package/src/components/MainButton/types.ts +0 -20
  404. package/src/components/Popup/index.ts +0 -8
  405. package/src/components/QRScanner/index.ts +0 -2
  406. package/src/components/ThemeParams/ThemeParams.ts +0 -168
  407. package/src/components/ThemeParams/index.ts +0 -2
  408. package/src/components/ThemeParams/types.ts +0 -11
  409. package/src/components/Viewport/index.ts +0 -2
  410. package/src/components/WebApp/WebApp.ts +0 -311
  411. package/src/components/WebApp/index.ts +0 -2
  412. package/src/components/WebApp/types.ts +0 -17
  413. package/src/components/index.ts +0 -11
  414. package/src/env.ts +0 -22
  415. package/src/errors/MethodNotSupportedError.ts +0 -9
  416. package/src/errors/ParameterNotSupportedError.ts +0 -9
  417. package/src/errors/index.ts +0 -2
  418. package/src/init/creators/createWebApp.ts +0 -52
  419. package/src/init/css.ts +0 -142
  420. package/src/supports.ts +0 -44
  421. package/src/types.ts +0 -13
  422. package/src/url.ts +0 -23
  423. /package/dist/dts/{components/CloudStorage → cloud-storage}/index.d.ts +0 -0
  424. /package/dist/dts/{components/HapticFeedback → haptic-feedback}/index.d.ts +0 -0
  425. /package/src/{components/CloudStorage → cloud-storage}/index.ts +0 -0
  426. /package/src/{components/HapticFeedback → haptic-feedback}/index.ts +0 -0
package/dist/index.mjs CHANGED
@@ -1,851 +1,1739 @@
1
- var st = Object.defineProperty;
2
- var rt = (s, t, e) => t in s ? st(s, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : s[t] = e;
3
- var i = (s, t, e) => (rt(s, typeof t != "symbol" ? t + "" : t, e), e);
4
- import { retrieveLaunchData as N, parse as ot } from "@tma.js/launch-params";
5
- import { EventEmitter as f } from "@tma.js/event-emitter";
6
- import { supports as S, postEvent as g, on as E, off as z, request as _, setDebug as nt, setTargetOrigin as it, createPostEvent as at, isIframe as ct } from "@tma.js/bridge";
7
- import { array as ht, string as W, json as ut } from "@tma.js/parsing";
8
- import { parse as D } from "@tma.js/theme-params";
9
- import { isColorDark as U, isRGB as pt } from "@tma.js/colors";
10
- import { compareVersions as lt, withTimeout as dt } from "@tma.js/utils";
11
- function m(s, t) {
12
- return (e) => S(t[e], s);
13
- }
14
- function gt(s, t) {
15
- return (e) => {
16
- const [r, o] = t[e];
17
- return S(r, o, s);
18
- };
1
+ var $t = Object.defineProperty;
2
+ var Vt = (r, t, e) => t in r ? $t(r, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : r[t] = e;
3
+ var o = (r, t, e) => (Vt(r, typeof t != "symbol" ? t + "" : t, e), e);
4
+ function D(r) {
5
+ return typeof r == "object" && r !== null && !Array.isArray(r);
19
6
  }
20
- class b {
21
- constructor(t, e) {
22
- this.state = t, this.ee = e;
23
- }
24
- emit(t, e) {
25
- this.ee && this.ee.emit(t, e);
26
- }
27
- internalSet(t, e) {
28
- return this.state[t] === e ? !1 : (this.state[t] = e, this.emit(`${String(t)}Changed`, e), !0);
29
- }
30
- set(t, e) {
31
- let r = !1;
32
- if (typeof t == "string")
33
- r = this.internalSet(t, e);
34
- else
35
- for (const o in t)
36
- this.internalSet(o, t[o]) && (r = !0);
37
- r && this.emit("changed");
38
- }
39
- get(t) {
40
- return this.state[t];
41
- }
42
- getState() {
43
- return { ...this.state };
44
- }
7
+ function ct() {
8
+ return performance.getEntriesByType("navigation")[0] || null;
45
9
  }
46
- class _t {
47
- constructor(t, e, r = g) {
48
- i(this, "ee", new f());
49
- i(this, "state");
50
- /**
51
- * Adds event listener.
52
- * @param event - event name.
53
- * @param listener - event listener.
54
- */
55
- i(this, "on", (t, e) => t === "click" ? E("back_button_pressed", e) : this.ee.on(t, e));
56
- /**
57
- * Removes event listener.
58
- * @param event - event name.
59
- * @param listener - event listener.
60
- */
61
- i(this, "off", (t, e) => {
62
- if (t === "click")
63
- return z("back_button_pressed", e);
64
- this.ee.off(t, e);
65
- });
10
+ function Tt() {
11
+ const r = ct();
12
+ return r ? r.type === "reload" : null;
13
+ }
14
+ function L() {
15
+ return new TypeError("Value has unexpected type");
16
+ }
17
+ class G extends Error {
18
+ constructor(e, { cause: n, type: s } = {}) {
19
+ super(`Unable to parse value${s ? ` as ${s}` : ""}`, { cause: n });
66
20
  /**
67
- * Checks if specified method is supported by current component.
21
+ * Parser name.
68
22
  */
69
- i(this, "supports");
70
- this.postEvent = r, this.state = new b({ isVisible: t }, this.ee), this.supports = m(e, {
71
- show: "web_app_setup_back_button",
72
- hide: "web_app_setup_back_button"
73
- });
23
+ o(this, "type");
24
+ this.value = e, Object.setPrototypeOf(this, G.prototype), this.type = s;
74
25
  }
75
- set isVisible(t) {
76
- this.state.set("isVisible", t), this.postEvent("web_app_setup_back_button", { is_visible: t });
26
+ }
27
+ class F {
28
+ constructor(t, e, n) {
29
+ this.parser = t, this.isOptional = e, this.type = n;
30
+ }
31
+ parse(t) {
32
+ if (!(this.isOptional && t === void 0))
33
+ try {
34
+ return this.parser(t);
35
+ } catch (e) {
36
+ throw new G(t, { type: this.type, cause: e });
37
+ }
77
38
  }
78
- /**
79
- * True if BackButton is currently visible.
80
- */
81
- get isVisible() {
82
- return this.state.get("isVisible");
39
+ optional() {
40
+ return this.isOptional = !0, this;
83
41
  }
84
- /**
85
- * Hides the BackButton.
86
- */
87
- hide() {
88
- this.isVisible = !1;
42
+ }
43
+ function It(r) {
44
+ if (Array.isArray(r))
45
+ return r;
46
+ if (typeof r == "string")
47
+ try {
48
+ const t = JSON.parse(r);
49
+ if (Array.isArray(t))
50
+ return t;
51
+ } catch {
52
+ }
53
+ throw L();
54
+ }
55
+ class Rt extends F {
56
+ constructor(e, n, s) {
57
+ super(It, n, s);
58
+ o(this, "itemParser");
59
+ this.itemParser = typeof e == "function" ? e : e.parse.bind(e);
89
60
  }
90
- /**
91
- * Shows the BackButton.
92
- */
93
- show() {
94
- this.isVisible = !0;
61
+ parse(e) {
62
+ const n = super.parse(e);
63
+ return n === void 0 ? n : n.map(this.itemParser);
64
+ }
65
+ of(e) {
66
+ return this.itemParser = typeof e == "function" ? e : e.parse.bind(e), this;
95
67
  }
96
68
  }
97
- class bt {
98
- constructor(t, e = g) {
99
- i(this, "ee", new f());
100
- i(this, "state");
101
- /**
102
- * Adds new event listener.
103
- */
104
- i(this, "on", this.ee.on.bind(this.ee));
105
- /**
106
- * Removes event listener.
107
- */
108
- i(this, "off", this.ee.off.bind(this.ee));
109
- this.postEvent = e, this.state = new b({ isConfirmationNeeded: t }, this.ee);
69
+ function $(r, t) {
70
+ return () => new F(r, !1, t);
71
+ }
72
+ class U extends Error {
73
+ constructor(t, { cause: e, type: n } = {}) {
74
+ super(`Unable to parse field "${t}"${n ? ` as ${n}` : ""}`, { cause: e }), Object.setPrototypeOf(this, U.prototype);
110
75
  }
111
- set isConfirmationNeeded(t) {
112
- this.state.set("isConfirmationNeeded", t), this.postEvent("web_app_setup_closing_behavior", { need_confirmation: t });
76
+ }
77
+ function ht(r, t) {
78
+ const e = {};
79
+ for (const n in r) {
80
+ const s = r[n];
81
+ if (!s)
82
+ continue;
83
+ let i, a;
84
+ if (typeof s == "function" || "parse" in s)
85
+ i = n, a = typeof s == "function" ? s : s.parse.bind(s);
86
+ else {
87
+ const { type: l } = s;
88
+ i = s.from || n, a = typeof l == "function" ? l : l.parse.bind(l);
89
+ }
90
+ let c;
91
+ const u = t(i);
92
+ try {
93
+ c = a(u);
94
+ } catch (l) {
95
+ throw l instanceof G ? new U(i, {
96
+ type: l.type,
97
+ cause: l
98
+ }) : new U(i, { cause: l });
99
+ }
100
+ c !== void 0 && (e[n] = c);
101
+ }
102
+ return e;
103
+ }
104
+ function Bt(r) {
105
+ return new Rt((t) => t, !1, r);
106
+ }
107
+ const C = $((r) => {
108
+ if (typeof r == "boolean")
109
+ return r;
110
+ const t = String(r);
111
+ if (t === "1" || t === "true")
112
+ return !0;
113
+ if (t === "0" || t === "false")
114
+ return !1;
115
+ throw L();
116
+ }, "boolean"), A = $((r) => {
117
+ if (typeof r == "number")
118
+ return r;
119
+ if (typeof r == "string") {
120
+ const t = Number(r);
121
+ if (!Number.isNaN(t))
122
+ return t;
123
+ }
124
+ throw L();
125
+ }, "number"), Dt = A(), Ht = $((r) => r instanceof Date ? r : new Date(Dt.parse(r) * 1e3), "Date");
126
+ function Z(r) {
127
+ let t = r;
128
+ if (typeof t == "string" && (t = JSON.parse(t)), typeof t != "object" || t === null || Array.isArray(t))
129
+ throw L();
130
+ return t;
131
+ }
132
+ function g(r, t) {
133
+ return new F((e) => {
134
+ const n = Z(e);
135
+ return ht(r, (s) => n[s]);
136
+ }, !1, t);
137
+ }
138
+ function ut(r) {
139
+ return /^#[\da-f]{6}$/i.test(r);
140
+ }
141
+ function Nt(r) {
142
+ return /^#[\da-f]{3}$/i.test(r);
143
+ }
144
+ function pt(r) {
145
+ const t = r.replace(/\s/g, "").toLowerCase();
146
+ if (ut(t))
147
+ return t;
148
+ if (Nt(t)) {
149
+ let n = "#";
150
+ for (let s = 0; s < 3; s += 1)
151
+ n += t[1 + s].repeat(2);
152
+ return n;
153
+ }
154
+ const e = t.match(/^rgb\((\d{1,3}),(\d{1,3}),(\d{1,3})\)$/) || t.match(/^rgba\((\d{1,3}),(\d{1,3}),(\d{1,3}),\d{1,3}\)$/);
155
+ if (e === null)
156
+ throw new Error(`Value "${r}" does not satisfy any of known RGB formats.`);
157
+ return e.slice(1).reduce((n, s) => {
158
+ const i = parseInt(s, 10).toString(16);
159
+ return n + (i.length === 1 ? "0" : "") + i;
160
+ }, "#");
161
+ }
162
+ function lt(r) {
163
+ const t = pt(r);
164
+ return Math.sqrt(
165
+ [0.299, 0.587, 0.114].reduce((n, s, i) => {
166
+ const a = parseInt(t.slice(1 + i * 2, 1 + (i + 1) * 2), 16);
167
+ return n + a * a * s;
168
+ }, 0)
169
+ ) < 120;
170
+ }
171
+ const h = $((r) => {
172
+ if (typeof r == "string" || typeof r == "number")
173
+ return r.toString();
174
+ throw L();
175
+ }, "string"), Ot = h(), dt = $((r) => pt(Ot.parse(r)), "rgb");
176
+ function ft(r, t) {
177
+ return new F((e) => {
178
+ if (typeof e != "string" && !(e instanceof URLSearchParams))
179
+ throw L();
180
+ const n = typeof e == "string" ? new URLSearchParams(e) : e;
181
+ return ht(r, (s) => {
182
+ const i = n.get(s);
183
+ return i === null ? void 0 : i;
184
+ });
185
+ }, !1, t);
186
+ }
187
+ function Wt() {
188
+ return g({
189
+ id: A(),
190
+ type: h(),
191
+ title: h(),
192
+ photoUrl: {
193
+ type: h().optional(),
194
+ from: "photo_url"
195
+ },
196
+ username: h().optional()
197
+ }, "Chat");
198
+ }
199
+ class Mt {
200
+ constructor(t) {
201
+ this.initData = t;
113
202
  }
114
203
  /**
115
- * Returns true, if the confirmation dialog enabled while the user is trying
116
- * to close the Mini App.
204
+ * @see InitDataParsed.authDate
117
205
  */
118
- get isConfirmationNeeded() {
119
- return this.state.get("isConfirmationNeeded");
206
+ get authDate() {
207
+ return this.initData.authDate;
120
208
  }
121
209
  /**
122
- * Disables the confirmation dialog while the user is trying to close the
123
- * Mini App.
210
+ * @see InitDataParsed.canSendAfter
124
211
  */
125
- disableConfirmation() {
126
- this.isConfirmationNeeded = !1;
212
+ get canSendAfter() {
213
+ return this.initData.canSendAfter;
127
214
  }
128
215
  /**
129
- * Enables the confirmation dialog while the user is trying to close the
130
- * Mini App.
216
+ * Date after which it is allowed to call
217
+ * the [answerWebAppQuery](https://core.telegram.org/bots/api#answerwebappquery) method.
131
218
  */
132
- enableConfirmation() {
133
- this.isConfirmationNeeded = !0;
134
- }
135
- }
136
- const ft = ht().of(W());
137
- function L(s, t) {
138
- return s.reduce((e, r) => (e[r] = t, e), {});
139
- }
140
- class wt {
141
- constructor(t, e, r = g) {
142
- /**
143
- * Checks if specified method is supported by current component.
144
- */
145
- i(this, "supports");
146
- this.createRequestId = e, this.postEvent = r, this.supports = m(t, {
147
- deleteKeys: "web_app_invoke_custom_method",
148
- getKeys: "web_app_invoke_custom_method",
149
- getValues: "web_app_invoke_custom_method",
150
- saveValue: "web_app_invoke_custom_method"
151
- });
219
+ get canSendAfterDate() {
220
+ const { canSendAfter: t } = this;
221
+ return t === void 0 ? void 0 : new Date(this.authDate.getTime() + t * 1e3);
152
222
  }
153
223
  /**
154
- * Invokes custom method related to CloudStorage.
155
- * @param method - method name.
156
- * @param params - method parameters.
157
- * @param options - execution options.
224
+ * @see InitDataParsed.chat
158
225
  */
159
- async invokeCustomMethod(t, e, r = {}) {
160
- const { result: o, error: n } = await _(
161
- "web_app_invoke_custom_method",
162
- { method: t, params: e, req_id: this.createRequestId() },
163
- "custom_method_invoked",
164
- { ...r, postEvent: this.postEvent }
165
- );
166
- if (n)
167
- throw new Error(typeof n == "string" ? n : `Unknown error: ${JSON.stringify(n)}`);
168
- return o;
226
+ get chat() {
227
+ return this.initData.chat;
169
228
  }
170
229
  /**
171
- * Deletes specified keys from the CloudStorage.
172
- * @param keys - keys list.
173
- * @param options - request execution options.
230
+ * @see InitDataParsed.chatType
174
231
  */
175
- async deleteKeys(t, e) {
176
- t.length !== 0 && await this.invokeCustomMethod("deleteStorageValues", { keys: t }, e);
232
+ get chatType() {
233
+ return this.initData.chatType;
177
234
  }
178
235
  /**
179
- * Returns list of all keys presented in CloudStorage.
180
- * @param options - request execution options.
236
+ * @see InitDataParsed.chatInstance
181
237
  */
182
- async getKeys(t) {
183
- const e = await this.invokeCustomMethod("getStorageKeys", {}, t);
184
- return ft.parse(e);
238
+ get chatInstance() {
239
+ return this.initData.chatInstance;
185
240
  }
186
241
  /**
187
- * Returns map, where key is one of the specified in keys argument, and value is according
188
- * storage value.
189
- * @param keys - keys list.
190
- * @param options - request execution options.
242
+ * @see InitDataParsed.hash
191
243
  */
192
- async getValues(t, e) {
193
- if (t.length === 0)
194
- return L(t, "");
195
- const r = ut(
196
- L(t, W())
197
- // fixme
198
- ), o = await this.invokeCustomMethod("getStorageValues", { keys: t }, e);
199
- return r.parse(o);
244
+ get hash() {
245
+ return this.initData.hash;
200
246
  }
201
247
  /**
202
- * Saves specified value by key.
203
- * @param key - storage key.
204
- * @param value - storage value.
205
- * @param options - request execution options.
248
+ * @see InitDataParsed.queryId
206
249
  */
207
- async saveValue(t, e, r) {
208
- await this.invokeCustomMethod("saveStorageValue", { key: t, value: e }, r);
209
- }
210
- }
211
- class mt {
212
- constructor(t, e = g) {
213
- /**
214
- * Checks if specified method is supported by current component.
215
- */
216
- i(this, "supports");
217
- this.postEvent = e, this.supports = m(t, {
218
- impactOccurred: "web_app_trigger_haptic_feedback",
219
- notificationOccurred: "web_app_trigger_haptic_feedback",
220
- selectionChanged: "web_app_trigger_haptic_feedback"
221
- });
250
+ get queryId() {
251
+ return this.initData.queryId;
222
252
  }
223
253
  /**
224
- * A method tells that an impact occurred. The Telegram app may play the
225
- * appropriate haptics based on style value passed.
226
- * @param style - impact style.
254
+ * @see InitDataParsed.receiver
227
255
  */
228
- impactOccurred(t) {
229
- this.postEvent("web_app_trigger_haptic_feedback", { type: "impact", impact_style: t });
256
+ get receiver() {
257
+ return this.initData.receiver;
230
258
  }
231
259
  /**
232
- * A method tells that a task or action has succeeded, failed, or produced
233
- * a warning. The Telegram app may play the appropriate haptics based on
234
- * type value passed.
235
- * @param type - notification type.
260
+ * @see InitDataParsed.startParam
236
261
  */
237
- notificationOccurred(t) {
238
- this.postEvent("web_app_trigger_haptic_feedback", {
239
- type: "notification",
240
- notification_type: t
241
- });
262
+ get startParam() {
263
+ return this.initData.startParam;
242
264
  }
243
265
  /**
244
- * A method tells that the user has changed a selection. The Telegram app
245
- * may play the appropriate haptics.
246
- *
247
- * Do not use this feedback when the user makes or confirms a selection;
248
- * use it only when the selection changes.
266
+ * @see InitDataParsed.user
249
267
  */
250
- selectionChanged() {
251
- this.postEvent("web_app_trigger_haptic_feedback", { type: "selection_change" });
268
+ get user() {
269
+ return this.initData.user;
252
270
  }
253
271
  }
254
- class Ct {
255
- constructor(t, e, r = {}) {
256
- i(this, "state");
257
- const {
258
- chat: o = null,
259
- canSendAfter: n = null,
260
- chatType: a = null,
261
- chatInstance: u = null,
262
- user: c = null,
263
- queryId: p = null,
264
- receiver: h = null,
265
- startParam: d = null
266
- } = r;
267
- this.state = new b({
268
- authDate: t,
269
- canSendAfter: n === null ? null : new Date(t.getTime() + n * 1e3),
270
- chat: o,
271
- chatType: a,
272
- chatInstance: u,
273
- user: c,
274
- queryId: p,
275
- receiver: h,
276
- startParam: d,
277
- hash: e
272
+ function tt() {
273
+ return g({
274
+ addedToAttachmentMenu: {
275
+ type: C().optional(),
276
+ from: "added_to_attachment_menu"
277
+ },
278
+ allowsWriteToPm: {
279
+ type: C().optional(),
280
+ from: "allows_write_to_pm"
281
+ },
282
+ firstName: {
283
+ type: h(),
284
+ from: "first_name"
285
+ },
286
+ id: A(),
287
+ isBot: {
288
+ type: C().optional(),
289
+ from: "is_bot"
290
+ },
291
+ isPremium: {
292
+ type: C().optional(),
293
+ from: "is_premium"
294
+ },
295
+ languageCode: {
296
+ type: h().optional(),
297
+ from: "language_code"
298
+ },
299
+ lastName: {
300
+ type: h().optional(),
301
+ from: "last_name"
302
+ },
303
+ photoUrl: {
304
+ type: h().optional(),
305
+ from: "photo_url"
306
+ },
307
+ username: h().optional()
308
+ }, "User");
309
+ }
310
+ function gt() {
311
+ return ft({
312
+ authDate: {
313
+ type: Ht(),
314
+ from: "auth_date"
315
+ },
316
+ canSendAfter: {
317
+ type: A().optional(),
318
+ from: "can_send_after"
319
+ },
320
+ chat: Wt().optional(),
321
+ chatInstance: {
322
+ type: h().optional(),
323
+ from: "chat_instance"
324
+ },
325
+ chatType: {
326
+ type: h().optional(),
327
+ from: "chat_type"
328
+ },
329
+ hash: h(),
330
+ queryId: {
331
+ type: h().optional(),
332
+ from: "query_id"
333
+ },
334
+ receiver: tt().optional(),
335
+ startParam: {
336
+ type: h().optional(),
337
+ from: "start_param"
338
+ },
339
+ user: tt().optional()
340
+ }, "InitData");
341
+ }
342
+ function Xe(r) {
343
+ return gt().parse(r);
344
+ }
345
+ function Ut(r) {
346
+ return r.replace(/(^|_)bg/, (t, e) => `${e}background`).replace(/_([a-z])/g, (t, e) => e.toUpperCase());
347
+ }
348
+ function jt(r) {
349
+ return r.replace(/[A-Z]/g, (t) => `_${t.toLowerCase()}`).replace(/(^|_)background/, (t, e) => `${e}bg`);
350
+ }
351
+ const Gt = dt().optional(), wt = $(
352
+ (r) => Object.entries(Z(r)).reduce((t, [e, n]) => (t[Ut(e)] = Gt.parse(n), t), {}),
353
+ "ThemeParams"
354
+ );
355
+ function _t(r) {
356
+ return wt().parse(r);
357
+ }
358
+ function tr(r = {}) {
359
+ return _("web_app_request_theme", "theme_changed", r).then(_t);
360
+ }
361
+ function Ft(r) {
362
+ return JSON.stringify(
363
+ Object.entries(r).reduce((t, [e, n]) => (n && (t[jt(e)] = n), t), {})
364
+ );
365
+ }
366
+ class w {
367
+ constructor() {
368
+ o(this, "listeners", /* @__PURE__ */ new Map());
369
+ o(this, "subscribeListeners", []);
370
+ }
371
+ /**
372
+ * Adds specified event listener.
373
+ * @param event - event name.
374
+ * @param listener - event listener.
375
+ * @param once - should listener called only once.
376
+ */
377
+ addListener(t, e, n) {
378
+ let s = this.listeners.get(t);
379
+ return s || (s = [], this.listeners.set(t, s)), s.push([e, n]), () => this.off(t, e);
380
+ }
381
+ emit(t, ...e) {
382
+ this.subscribeListeners.forEach((s) => s(t, ...e));
383
+ const n = this.listeners.get(t);
384
+ n && n.forEach(([s, i], a) => {
385
+ s(...e), i && n.splice(a, 1);
278
386
  });
279
387
  }
280
388
  /**
281
- * Init data generation date.
389
+ * Adds event listener.
390
+ * @param event - event name.
391
+ * @param listener - event listener.
392
+ * @returns Function to remove event listener.
282
393
  */
283
- get authDate() {
284
- return this.state.get("authDate");
394
+ on(t, e) {
395
+ return this.addListener(t, e, !1);
285
396
  }
286
397
  /**
287
- * Date after which a message can be sent via the
288
- * [answerWebAppQuery](https://core.telegram.org/bots/api#answerwebappquery) method.
398
+ * Adds event listener following the logic, described in `on` method, but calls specified
399
+ * listener only once, removing it after.
400
+ * @param event - event name.
401
+ * @param listener - event listener.
402
+ * @returns Function to remove event listener.
403
+ * @see on
289
404
  */
290
- get canSendAfter() {
291
- return this.state.get("canSendAfter");
405
+ once(t, e) {
406
+ return this.addListener(t, e, !0);
292
407
  }
293
408
  /**
294
- * An object containing data about the chat where the bot was launched via the attachment
295
- * menu. Returned for supergroups, channels and group chats – only for Mini Apps launched via
296
- * the attachment menu.
409
+ * Removes event listener. In case, specified listener was bound several times, it removes
410
+ * only a single one.
411
+ * @param event - event name.
412
+ * @param listener - event listener.
297
413
  */
298
- get chat() {
299
- return this.state.get("chat");
414
+ off(t, e) {
415
+ const n = this.listeners.get(t);
416
+ if (n) {
417
+ for (let s = 0; s < n.length; s += 1)
418
+ if (e === n[s][0]) {
419
+ n.splice(s, 1);
420
+ return;
421
+ }
422
+ }
300
423
  }
301
424
  /**
302
- * The type of chat from which Mini App was opened.
425
+ * Adds event listener to all events.
426
+ * @param listener - events listener.
427
+ * @returns Function to remove event listener.
428
+ * @see on
429
+ * @see once
303
430
  */
304
- get chatType() {
305
- return this.state.get("chatType");
431
+ subscribe(t) {
432
+ return this.subscribeListeners.push(t), () => this.unsubscribe(t);
306
433
  }
307
434
  /**
308
- * A global identifier indicating the chat from which Mini App was opened. Returned only for
309
- * applications opened by direct link.
435
+ * Removes global event listener. In case, specified listener was bound several times, it removes
436
+ * only a single one.
437
+ * @param listener - events listener.
438
+ * @returns Function to remove event listener.
310
439
  */
311
- get chatInstance() {
312
- return this.state.get("chatInstance");
440
+ unsubscribe(t) {
441
+ for (let e = 0; e < this.subscribeListeners.length; e += 1)
442
+ if (this.subscribeListeners[e] === t) {
443
+ this.subscribeListeners.splice(e, 1);
444
+ return;
445
+ }
313
446
  }
314
- /**
315
- * A hash of all passed parameters, which the bot server can use to
316
- * check their validity.
317
- * @see https://core.telegram.org/bots/webapps#validating-data-received-via-the-web-app
318
- */
319
- get hash() {
320
- return this.state.get("hash");
447
+ }
448
+ class b {
449
+ constructor(t, e) {
450
+ this.state = t, this.ee = e;
321
451
  }
322
- /**
323
- * A unique identifier for the Mini App session, required for sending
324
- * messages via the `answerWebAppQuery` method.
325
- * @see https://core.telegram.org/bots/api#answerwebappquery
326
- */
327
- get queryId() {
328
- return this.state.get("queryId");
452
+ internalSet(t, e) {
453
+ return this.state[t] === e || e === void 0 ? !1 : (this.state[t] = e, this.ee.emit(`change:${t}`, e), !0);
329
454
  }
330
455
  /**
331
- * An object containing data about the chat partner of the current
332
- * user in the chat where the bot was launched via the attachment menu.
333
- * Returned only for private chats and only for Mini Apps launched
334
- * via the attachment menu.
456
+ * Returns copy of current state.
335
457
  */
336
- get receiver() {
337
- return this.state.get("receiver");
458
+ clone() {
459
+ return { ...this.state };
338
460
  }
339
- /**
340
- * The value of the `startattach` parameter, passed via link. Only
341
- * returned for Mini Apps when launched from the attachment menu via link.
342
- */
343
- get startParam() {
344
- return this.state.get("startParam");
461
+ set(t, e) {
462
+ let n = !1;
463
+ if (typeof t == "string")
464
+ n = this.internalSet(t, e);
465
+ else
466
+ for (const s in t)
467
+ this.internalSet(s, t[s]) && (n = !0);
468
+ n && this.ee.emit("change");
345
469
  }
346
470
  /**
347
- * An object containing data about the current user.
471
+ * Returns value by specified key.
472
+ * @param key - state key.
348
473
  */
349
- get user() {
350
- return this.state.get("user");
474
+ get(t) {
475
+ return this.state[t];
351
476
  }
352
477
  }
353
- class vt {
354
- constructor(t, e, r, o, n, a, u = g) {
355
- i(this, "ee", new f());
356
- i(this, "state");
478
+ class zt {
479
+ constructor(t) {
480
+ o(this, "ee", new w());
481
+ o(this, "state");
357
482
  /**
358
483
  * Adds new event listener.
359
- * FIXME: Event 'main_button_pressed' is still being received on Android
360
- * even if the main button is disabled.
361
- * Issue: https://github.com/Telegram-Mini-Apps/tma.js/issues/3
362
- * @param event - event name.
363
- * @param listener - event listener.
364
484
  */
365
- i(this, "on", (t, e) => t === "click" ? E("main_button_pressed", e) : this.ee.on(t, e));
485
+ o(this, "on", this.ee.on.bind(this.ee));
366
486
  /**
367
487
  * Removes event listener.
368
- * @param event - event name.
369
- * @param listener - event listener.
370
488
  */
371
- i(this, "off", (t, e) => {
372
- if (t === "click")
373
- return z("main_button_pressed", e);
374
- this.ee.off(t, e);
375
- });
376
- this.postEvent = u, this.state = new b({
377
- backgroundColor: t,
378
- isEnabled: e,
379
- isVisible: r,
380
- isProgressVisible: o,
381
- text: n,
382
- textColor: a
383
- }, this.ee);
384
- }
385
- set isEnabled(t) {
386
- this.state.set("isEnabled", t), this.commit();
489
+ o(this, "off", this.ee.off.bind(this.ee));
490
+ this.state = new b(t, this.ee);
387
491
  }
388
492
  /**
389
- * Returns true in case, MainButton is currently enabled.
493
+ * @since v6.10
390
494
  */
391
- get isEnabled() {
392
- return this.state.get("isEnabled");
495
+ get accentTextColor() {
496
+ return this.get("accentTextColor");
393
497
  }
394
- set isProgressVisible(t) {
395
- this.state.set("isProgressVisible", t), this.commit();
498
+ get backgroundColor() {
499
+ return this.get("backgroundColor");
396
500
  }
397
- /**
398
- * Returns true in case, MainButton loading progress is currently visible.
399
- */
400
- get isProgressVisible() {
401
- return this.state.get("isProgressVisible");
501
+ get buttonColor() {
502
+ return this.get("buttonColor");
402
503
  }
403
- set isVisible(t) {
404
- this.state.set("isVisible", t), this.commit();
504
+ get buttonTextColor() {
505
+ return this.get("buttonTextColor");
405
506
  }
406
- /**
407
- * Returns true in case, MainButton is currently visible.
408
- */
409
- get isVisible() {
410
- return this.state.get("isVisible");
507
+ get destructiveTextColor() {
508
+ return this.get("destructiveTextColor");
411
509
  }
412
510
  /**
413
- * Sends current local button state to Telegram application.
511
+ * Retrieves palette color value by its name.
512
+ * @param key - palette key name.
414
513
  */
415
- commit() {
416
- this.text !== "" && this.postEvent("web_app_setup_main_button", {
417
- is_visible: this.isVisible,
418
- is_active: this.isEnabled,
419
- is_progress_visible: this.isProgressVisible,
420
- text: this.text,
421
- color: this.backgroundColor,
422
- text_color: this.textColor
423
- });
514
+ get(t) {
515
+ return this.state.get(t);
424
516
  }
425
517
  /**
426
- * Returns current main button background color.
518
+ * Returns the copy of the internal state of the current component instance.
427
519
  */
428
- get backgroundColor() {
429
- return this.state.get("backgroundColor");
520
+ getState() {
521
+ return this.state.clone();
430
522
  }
431
523
  /**
432
- * Returns current main button text.
524
+ * @since v6.10
433
525
  */
434
- get text() {
435
- return this.state.get("text");
526
+ get headerBackgroundColor() {
527
+ return this.get("headerBackgroundColor");
528
+ }
529
+ get hintColor() {
530
+ return this.get("hintColor");
436
531
  }
437
532
  /**
438
- * Returns current main button text color.
439
- */
440
- get textColor() {
441
- return this.state.get("textColor");
533
+ * Returns true in case, current color scheme is recognized as dark. This
534
+ * value is calculated according to theme background color.
535
+ */
536
+ get isDark() {
537
+ return !this.backgroundColor || lt(this.backgroundColor);
538
+ }
539
+ get linkColor() {
540
+ return this.get("linkColor");
541
+ }
542
+ get secondaryBackgroundColor() {
543
+ return this.get("secondaryBackgroundColor");
442
544
  }
443
545
  /**
444
- * Disables button. Returns current button instance for chaining.
546
+ * @since v6.10
445
547
  */
446
- disable() {
447
- return this.isEnabled = !1, this;
548
+ get sectionBackgroundColor() {
549
+ return this.get("sectionBackgroundColor");
448
550
  }
449
551
  /**
450
- * Enables button. Returns current button instance for chaining.
552
+ * @since v6.10
451
553
  */
452
- enable() {
453
- return this.isEnabled = !0, this;
554
+ get sectionHeaderTextColor() {
555
+ return this.get("sectionHeaderTextColor");
454
556
  }
455
557
  /**
456
- * Hides button. Returns current button instance for chaining.
558
+ * Starts listening to theme changes and applies them.
559
+ * @returns Function to stop listening.
457
560
  */
458
- hide() {
459
- return this.isVisible = !1, this;
561
+ listen() {
562
+ return k("theme_changed", (t) => {
563
+ this.state.set(_t(t.theme_params));
564
+ });
460
565
  }
461
566
  /**
462
- * Hides button progress. Returns current button instance for chaining.
567
+ * @since v6.10
463
568
  */
464
- hideProgress() {
465
- return this.isProgressVisible = !1, this;
569
+ get subtitleTextColor() {
570
+ return this.get("subtitleTextColor");
571
+ }
572
+ get textColor() {
573
+ return this.get("textColor");
574
+ }
575
+ }
576
+ function bt() {
577
+ return ft({
578
+ botInline: {
579
+ type: C().optional(),
580
+ from: "tgWebAppBotInline"
581
+ },
582
+ initData: {
583
+ type: gt().optional(),
584
+ from: "tgWebAppData"
585
+ },
586
+ initDataRaw: {
587
+ type: h().optional(),
588
+ from: "tgWebAppData"
589
+ },
590
+ platform: {
591
+ type: h(),
592
+ from: "tgWebAppPlatform"
593
+ },
594
+ showSettings: {
595
+ type: C().optional(),
596
+ from: "tgWebAppShowSettings"
597
+ },
598
+ themeParams: {
599
+ type: wt(),
600
+ from: "tgWebAppThemeParams"
601
+ },
602
+ version: {
603
+ type: h(),
604
+ from: "tgWebAppVersion"
605
+ }
606
+ }, "LaunchParams");
607
+ }
608
+ function mt(r) {
609
+ return bt().parse(r);
610
+ }
611
+ function Jt() {
612
+ return mt(window.location.hash.slice(1));
613
+ }
614
+ function Qt() {
615
+ const r = ct();
616
+ if (!r)
617
+ throw new Error("Unable to get first navigation entry.");
618
+ const t = r.name.match(/#(.*)/);
619
+ if (!t)
620
+ throw new Error("First navigation entry does not contain hash part.");
621
+ return mt(t[1]);
622
+ }
623
+ function Zt() {
624
+ try {
625
+ return Qt();
626
+ } catch {
627
+ }
628
+ try {
629
+ return Jt();
630
+ } catch {
631
+ }
632
+ return null;
633
+ }
634
+ function Kt(r) {
635
+ const {
636
+ initDataRaw: t,
637
+ themeParams: e,
638
+ platform: n,
639
+ version: s,
640
+ showSettings: i,
641
+ botInline: a
642
+ } = r, c = new URLSearchParams();
643
+ return t && c.set("tgWebAppData", t), c.set("tgWebAppPlatform", n), c.set("tgWebAppThemeParams", Ft(e)), c.set("tgWebAppVersion", s), typeof i == "boolean" && c.set("tgWebAppShowSettings", i ? "1" : "0"), typeof a == "boolean" && c.set("tgWebAppBotInline", a ? "1" : "0"), c.toString();
644
+ }
645
+ const yt = "telegram-mini-apps-launch-params";
646
+ function Yt() {
647
+ const r = sessionStorage.getItem(yt);
648
+ return r ? bt().parse(r) : null;
649
+ }
650
+ function Xt(r) {
651
+ sessionStorage.setItem(yt, Kt(r));
652
+ }
653
+ function te() {
654
+ try {
655
+ return window.self !== window.top;
656
+ } catch {
657
+ return !0;
658
+ }
659
+ }
660
+ function ee() {
661
+ const r = Yt(), t = Zt(), e = Tt();
662
+ if (r) {
663
+ if (t)
664
+ return {
665
+ launchParams: t,
666
+ isPageReload: te() ? e || r.initDataRaw === t.initDataRaw : !0
667
+ };
668
+ if (e)
669
+ return {
670
+ launchParams: r,
671
+ isPageReload: e
672
+ };
673
+ throw new Error("Unable to retrieve current launch parameters, which must exist.");
674
+ }
675
+ if (t)
676
+ return {
677
+ launchParams: t,
678
+ isPageReload: !1
679
+ };
680
+ throw new Error("Unable to retrieve any launch parameters.");
681
+ }
682
+ const et = "tmajsLaunchData";
683
+ function Et() {
684
+ const r = window[et];
685
+ if (r)
686
+ return r;
687
+ const t = ee();
688
+ return window[et] = t, Xt(t.launchParams), t;
689
+ }
690
+ function er() {
691
+ try {
692
+ return Et(), !0;
693
+ } catch {
694
+ return !1;
695
+ }
696
+ }
697
+ function re(r) {
698
+ return "external" in r && D(r.external) && "notify" in r.external && typeof r.external.notify == "function";
699
+ }
700
+ function ne(r) {
701
+ return "TelegramWebviewProxy" in r && D(r.TelegramWebviewProxy) && "postEvent" in r.TelegramWebviewProxy && typeof r.TelegramWebviewProxy.postEvent == "function";
702
+ }
703
+ function Ct() {
704
+ try {
705
+ return window.self !== window.top;
706
+ } catch {
707
+ return !0;
708
+ }
709
+ }
710
+ class K extends Error {
711
+ constructor(t, e) {
712
+ super(`Method "${t}" is unsupported in the Mini Apps version ${e}.`), Object.setPrototypeOf(this, K.prototype);
713
+ }
714
+ }
715
+ class Y extends Error {
716
+ constructor(t, e, n) {
717
+ super(`Parameter "${e}" in method "${t}" is unsupported in the Mini Apps version ${n}.`), Object.setPrototypeOf(this, Y.prototype);
718
+ }
719
+ }
720
+ class vt {
721
+ constructor(t, e) {
722
+ this.prefix = t, this.enabled = e;
466
723
  }
467
724
  /**
468
- * Shows the button. Note that opening the Mini App from the attachment
469
- * menu hides the main button until the user interacts with the Mini App
470
- * interface.
471
- *
472
- * Returns current button instance for chaining.
725
+ * Prints message into a console in case, logger is currently enabled.
726
+ * @param level - log level.
727
+ * @param args - arguments.
473
728
  */
474
- show() {
475
- return this.isVisible = !0, this;
729
+ print(t, ...e) {
730
+ if (!this.enabled)
731
+ return;
732
+ const n = /* @__PURE__ */ new Date(), s = Intl.DateTimeFormat("en-GB", {
733
+ hour: "2-digit",
734
+ minute: "2-digit",
735
+ second: "2-digit",
736
+ fractionalSecondDigits: 3,
737
+ timeZone: "UTC"
738
+ }).format(n);
739
+ console[t](`[${s}]`, this.prefix, ...e);
476
740
  }
477
741
  /**
478
- * A method to show a loading indicator on the button.
479
- * It is recommended to display loading progress if the action tied to the
480
- * button may take a long time.
481
- *
482
- * Returns current button instance for chaining.
742
+ * Disables the logger.
483
743
  */
484
- showProgress() {
485
- return this.isProgressVisible = !0, this;
744
+ disable() {
745
+ this.enabled = !1;
486
746
  }
487
747
  /**
488
- * Sets new main button text. Returns current button instance for chaining.
489
- * Minimal length for text is 1 symbol, and maximum is 64 symbols.
490
- *
491
- * Returns current button instance for chaining.
492
- * @param value - new text.
748
+ * Prints error message into a console.
749
+ * @param args
493
750
  */
494
- setText(t) {
495
- return this.state.set("text", t), this.commit(), this;
751
+ error(...t) {
752
+ this.print("error", ...t);
496
753
  }
497
754
  /**
498
- * Sets new main button text color. Returns current button instance for
499
- * chaining.
500
- *
501
- * Returns current button instance for chaining.
502
- * @param value - new text color.
755
+ * Enables the logger.
503
756
  */
504
- setTextColor(t) {
505
- return this.state.set("textColor", t), this.commit(), this;
757
+ enable() {
758
+ this.enabled = !0;
506
759
  }
507
760
  /**
508
- * Updates current button color. Returns current button instance for
509
- * chaining.
510
- *
511
- * Returns current button instance for chaining.
512
- * @param value - color to set.
761
+ * Prints log message into a console.
762
+ * @param args
513
763
  */
514
- setBackgroundColor(t) {
515
- return this.state.set("backgroundColor", t), this.commit(), this;
764
+ log(...t) {
765
+ this.print("log", ...t);
766
+ }
767
+ /**
768
+ * Prints warning message into a console.
769
+ * @param args
770
+ */
771
+ warn(...t) {
772
+ this.print("warn", ...t);
516
773
  }
517
774
  }
518
- function yt(s) {
519
- const t = s.message.trim(), e = (s.title || "").trim(), r = s.buttons || [];
520
- let o;
521
- if (e.length > 64)
522
- throw new Error(`Title has incorrect size: ${e.length}`);
523
- if (t.length === 0 || t.length > 256)
524
- throw new Error(`Message has incorrect size: ${t.length}`);
525
- if (r.length > 3)
526
- throw new Error(`Buttons have incorrect size: ${r.length}`);
527
- return r.length === 0 ? o = [{ type: "close", id: "" }] : o = r.map((n) => {
528
- const { id: a = "" } = n;
529
- if (a.length > 64)
530
- throw new Error(`Button ID has incorrect size: ${a}`);
531
- if (n.type === void 0 || n.type === "default" || n.type === "destructive") {
532
- const u = n.text.trim();
533
- if (u.length === 0 || u.length > 64) {
534
- const c = n.type || "default";
535
- throw new Error(`Button text with type "${c}" has incorrect size: ${n.text.length}`);
775
+ let kt = "https://web.telegram.org";
776
+ const P = new vt("[SDK]", !1);
777
+ function rr(r) {
778
+ if (r) {
779
+ P.enable();
780
+ return;
781
+ }
782
+ P.disable();
783
+ }
784
+ function nr(r) {
785
+ kt = r;
786
+ }
787
+ function se() {
788
+ return kt;
789
+ }
790
+ const ie = g({
791
+ eventType: h(),
792
+ eventData: (r) => r
793
+ });
794
+ function oe(r, t) {
795
+ window.dispatchEvent(new MessageEvent("message", {
796
+ data: JSON.stringify({ eventType: r, eventData: t })
797
+ }));
798
+ }
799
+ function ae() {
800
+ const r = window;
801
+ "TelegramGameProxy_receiveEvent" in r || [
802
+ ["TelegramGameProxy_receiveEvent"],
803
+ // Windows Phone.
804
+ ["TelegramGameProxy", "receiveEvent"],
805
+ // Desktop.
806
+ ["Telegram", "WebView", "receiveEvent"]
807
+ // Android and iOS.
808
+ ].forEach((t) => {
809
+ let e = r;
810
+ t.forEach((n, s, i) => {
811
+ if (s === i.length - 1) {
812
+ e[n] = oe;
813
+ return;
536
814
  }
537
- return { ...n, text: u, id: a };
815
+ n in e || (e[n] = {}), e = e[n];
816
+ });
817
+ });
818
+ }
819
+ function ce(r) {
820
+ ae(), window.addEventListener("message", (t) => {
821
+ try {
822
+ const { eventType: e, eventData: n } = ie.parse(t.data);
823
+ r(e, n);
824
+ } catch {
825
+ }
826
+ });
827
+ }
828
+ function he() {
829
+ return g({
830
+ req_id: h(),
831
+ data: (r) => r === null ? r : h().optional().parse(r)
832
+ });
833
+ }
834
+ function ue() {
835
+ return g({
836
+ req_id: h(),
837
+ result: (r) => r,
838
+ error: h().optional()
839
+ });
840
+ }
841
+ function pe() {
842
+ return g({
843
+ slug: h(),
844
+ status: h()
845
+ });
846
+ }
847
+ function le() {
848
+ return g({ status: h() });
849
+ }
850
+ function de() {
851
+ return g({
852
+ button_id: (r) => r == null ? void 0 : h().parse(r)
853
+ });
854
+ }
855
+ function fe() {
856
+ return g({
857
+ data: h().optional()
858
+ });
859
+ }
860
+ function ge() {
861
+ return g({
862
+ theme_params: (r) => {
863
+ const t = dt().optional();
864
+ return Object.entries(Z(r)).reduce((e, [n, s]) => (e[n] = t.parse(s), e), {});
865
+ }
866
+ });
867
+ }
868
+ function we() {
869
+ return g({
870
+ height: A(),
871
+ width: (r) => r == null ? window.innerWidth : A().parse(r),
872
+ is_state_stable: C(),
873
+ is_expanded: C()
874
+ });
875
+ }
876
+ function _e() {
877
+ return g({ status: h() });
878
+ }
879
+ function be() {
880
+ const r = new w(), t = (e, ...n) => {
881
+ P.log("Emitting processed event:", e, ...n), r.emit(e, ...n);
882
+ };
883
+ return window.addEventListener("resize", () => {
884
+ t("viewport_changed", {
885
+ width: window.innerWidth,
886
+ height: window.innerHeight,
887
+ is_state_stable: !0,
888
+ is_expanded: !0
889
+ });
890
+ }), ce((e, n) => {
891
+ P.log("Received raw event:", e, n);
892
+ try {
893
+ switch (e) {
894
+ case "viewport_changed":
895
+ return t(e, we().parse(n));
896
+ case "theme_changed":
897
+ return t(e, ge().parse(n));
898
+ case "popup_closed":
899
+ return (
900
+ // Sent on desktop.
901
+ n == null ? t(e, {}) : t(e, de().parse(n))
902
+ );
903
+ case "set_custom_style":
904
+ return t(e, h().parse(n));
905
+ case "qr_text_received":
906
+ return t(e, fe().parse(n));
907
+ case "clipboard_text_received":
908
+ return t(e, he().parse(n));
909
+ case "invoice_closed":
910
+ return t(e, pe().parse(n));
911
+ case "phone_requested":
912
+ return t("phone_requested", le().parse(n));
913
+ case "custom_method_invoked":
914
+ return t("custom_method_invoked", ue().parse(n));
915
+ case "write_access_requested":
916
+ return t("write_access_requested", _e().parse(n));
917
+ case "main_button_pressed":
918
+ case "back_button_pressed":
919
+ case "settings_button_pressed":
920
+ case "scan_qr_popup_closed":
921
+ case "reload_iframe":
922
+ return t(e);
923
+ default:
924
+ return t(e, n);
925
+ }
926
+ } catch (s) {
927
+ P.error("Error processing event:", s);
928
+ }
929
+ }), r;
930
+ }
931
+ const z = "telegram-mini-apps-cached-emitter";
932
+ function H() {
933
+ const r = window;
934
+ return r[z] === void 0 && (r[z] = be()), r[z];
935
+ }
936
+ function N(r, t) {
937
+ H().off(r, t);
938
+ }
939
+ function k(r, t) {
940
+ return H().on(r, t), () => N(r, t);
941
+ }
942
+ function sr(r, t) {
943
+ return H().once(r, t), () => N(r, t);
944
+ }
945
+ function me(r) {
946
+ H().unsubscribe(r);
947
+ }
948
+ function ir(r) {
949
+ return H().subscribe(r), () => me(r);
950
+ }
951
+ function ye(r, t) {
952
+ const e = r.split("."), n = t.split("."), s = Math.max(e.length, n.length);
953
+ for (let i = 0; i < s; i += 1) {
954
+ const a = parseInt(e[i] || "0", 10), c = parseInt(n[i] || "0", 10);
955
+ if (a !== c)
956
+ return a > c ? 1 : -1;
957
+ }
958
+ return 0;
959
+ }
960
+ function E(r, t) {
961
+ return ye(r, t) <= 0;
962
+ }
963
+ function q(r, t, e) {
964
+ if (typeof e == "string") {
965
+ if (r === "web_app_open_link" && t === "try_instant_view")
966
+ return E("6.4", e);
967
+ if (r === "web_app_set_header_color" && t === "color")
968
+ return E("6.9", e);
969
+ }
970
+ switch (r) {
971
+ case "web_app_open_tg_link":
972
+ case "web_app_open_invoice":
973
+ case "web_app_setup_back_button":
974
+ case "web_app_set_background_color":
975
+ case "web_app_set_header_color":
976
+ case "web_app_trigger_haptic_feedback":
977
+ return E("6.1", t);
978
+ case "web_app_open_popup":
979
+ return E("6.2", t);
980
+ case "web_app_close_scan_qr_popup":
981
+ case "web_app_open_scan_qr_popup":
982
+ case "web_app_read_text_from_clipboard":
983
+ return E("6.4", t);
984
+ case "web_app_switch_inline_query":
985
+ return E("6.7", t);
986
+ case "web_app_invoke_custom_method":
987
+ case "web_app_request_write_access":
988
+ case "web_app_request_phone":
989
+ return E("6.9", t);
990
+ case "web_app_setup_settings_button":
991
+ return E("6.10", t);
992
+ default:
993
+ return !0;
994
+ }
995
+ }
996
+ function S(r, t) {
997
+ return (e) => q(t[e], r);
998
+ }
999
+ function St(r, t) {
1000
+ return (e) => {
1001
+ const [n, s] = t[e];
1002
+ return q(n, s, r);
1003
+ };
1004
+ }
1005
+ function f(r, t, e) {
1006
+ let n = {}, s;
1007
+ t === void 0 && e === void 0 ? n = {} : t !== void 0 && e !== void 0 ? (n = e, s = t) : t !== void 0 && ("targetOrigin" in t ? n = t : s = t);
1008
+ const { targetOrigin: i = se() } = n;
1009
+ if (P.log(`Calling method "${r}"`, s), Ct()) {
1010
+ window.parent.postMessage(JSON.stringify({
1011
+ eventType: r,
1012
+ eventData: s
1013
+ }), i);
1014
+ return;
1015
+ }
1016
+ if (re(window)) {
1017
+ window.external.notify(JSON.stringify({ eventType: r, eventData: s }));
1018
+ return;
1019
+ }
1020
+ if (ne(window)) {
1021
+ window.TelegramWebviewProxy.postEvent(r, JSON.stringify(s));
1022
+ return;
1023
+ }
1024
+ throw new Error(
1025
+ "Unable to determine current environment and possible way to send event."
1026
+ );
1027
+ }
1028
+ function Ee(r) {
1029
+ return (t, e) => {
1030
+ if (!q(t, r))
1031
+ throw new K(t, r);
1032
+ if (D(e)) {
1033
+ let n;
1034
+ if (t === "web_app_open_link" && "try_instant_view" in e ? n = "try_instant_view" : t === "web_app_set_header_color" && "color" in e && (n = "color"), n && !q(t, n, r))
1035
+ throw new Y(t, n, r);
1036
+ }
1037
+ return f(t, e);
1038
+ };
1039
+ }
1040
+ class X extends Error {
1041
+ constructor(t) {
1042
+ super(`Async call timeout exceeded. Timeout: ${t}`), Object.setPrototypeOf(this, X.prototype);
1043
+ }
1044
+ }
1045
+ function rt(r) {
1046
+ return new Promise((t, e) => {
1047
+ setTimeout(e, r, new X(r));
1048
+ });
1049
+ }
1050
+ function Ce(r, t) {
1051
+ return typeof r == "function" ? (...e) => Promise.race([
1052
+ r(...e),
1053
+ rt(t)
1054
+ ]) : Promise.race([r, rt(t)]);
1055
+ }
1056
+ function _(r, t, e, n) {
1057
+ let s, i, a, c;
1058
+ typeof t == "string" || Array.isArray(t) ? (a = Array.isArray(t) ? t : [t], s = e) : (i = t, a = Array.isArray(e) ? e : [e], s = n), D(i) && typeof i.req_id == "string" && (c = i.req_id);
1059
+ const { postEvent: u = f, timeout: l } = s || {}, p = s && "capture" in s ? s.capture : null, m = new Promise((d, y) => {
1060
+ const x = a.map((T) => k(T, (M) => {
1061
+ typeof c == "string" && (!D(M) || M.req_id !== c) || typeof p == "function" && !p(M) || (V(), d(M));
1062
+ })), V = () => x.forEach((T) => T());
1063
+ try {
1064
+ u(r, i);
1065
+ } catch (T) {
1066
+ V(), y(T);
538
1067
  }
539
- return { ...n, id: a };
540
- }), { title: e, message: t, buttons: o };
1068
+ });
1069
+ return typeof l == "number" ? Ce(m, l) : m;
1070
+ }
1071
+ class ve {
1072
+ constructor(t, e, n = f) {
1073
+ o(this, "ee", new w());
1074
+ o(this, "state");
1075
+ /**
1076
+ * Adds event listener.
1077
+ * @param event - event name.
1078
+ * @param listener - event listener.
1079
+ */
1080
+ o(this, "on", (t, e) => t === "click" ? k("back_button_pressed", e) : this.ee.on(t, e));
1081
+ /**
1082
+ * Removes event listener.
1083
+ * @param event - event name.
1084
+ * @param listener - event listener.
1085
+ */
1086
+ o(this, "off", (t, e) => t === "click" ? N("back_button_pressed", e) : this.ee.off(t, e));
1087
+ /**
1088
+ * Checks if specified method is supported by current component.
1089
+ */
1090
+ o(this, "supports");
1091
+ this.postEvent = n, this.state = new b({ isVisible: t }, this.ee), this.supports = S(e, {
1092
+ show: "web_app_setup_back_button",
1093
+ hide: "web_app_setup_back_button"
1094
+ });
1095
+ }
1096
+ set isVisible(t) {
1097
+ this.state.set("isVisible", t), this.postEvent("web_app_setup_back_button", { is_visible: t });
1098
+ }
1099
+ /**
1100
+ * True if BackButton is currently visible.
1101
+ */
1102
+ get isVisible() {
1103
+ return this.state.get("isVisible");
1104
+ }
1105
+ /**
1106
+ * Hides the BackButton.
1107
+ */
1108
+ hide() {
1109
+ this.isVisible = !1;
1110
+ }
1111
+ /**
1112
+ * Shows the BackButton.
1113
+ */
1114
+ show() {
1115
+ this.isVisible = !0;
1116
+ }
1117
+ }
1118
+ function nt(r, t) {
1119
+ return r + (r.length > 0 && t.length > 0 ? ` ${t}` : t);
541
1120
  }
542
- class Et {
543
- constructor(t, e = g) {
544
- i(this, "ee", new f());
545
- i(this, "state");
1121
+ function ke(...r) {
1122
+ return r.reduce((t, e) => {
1123
+ let n = "";
1124
+ return typeof e == "string" ? n = e : typeof e == "object" && e !== null && (n = Object.entries(e).reduce((s, [i, a]) => a ? nt(s, i) : s, "")), nt(t, n);
1125
+ }, "");
1126
+ }
1127
+ function Se(r) {
1128
+ return typeof r == "object" && r !== null && !Array.isArray(null);
1129
+ }
1130
+ function or(...r) {
1131
+ return r.reduce((t, e) => (Se(e) && Object.entries(e).forEach(([n, s]) => {
1132
+ const i = ke(t[n], s);
1133
+ i.length > 0 && (t[n] = i);
1134
+ }), t), {});
1135
+ }
1136
+ class xe {
1137
+ constructor(t, e = f) {
1138
+ o(this, "ee", new w());
1139
+ o(this, "state");
546
1140
  /**
547
1141
  * Adds new event listener.
548
1142
  */
549
- i(this, "on", this.ee.on.bind(this.ee));
1143
+ o(this, "on", this.ee.on.bind(this.ee));
550
1144
  /**
551
1145
  * Removes event listener.
552
1146
  */
553
- i(this, "off", this.ee.off.bind(this.ee));
1147
+ o(this, "off", this.ee.off.bind(this.ee));
1148
+ this.postEvent = e, this.state = new b({ isConfirmationNeeded: t }, this.ee);
1149
+ }
1150
+ set isConfirmationNeeded(t) {
1151
+ this.state.set("isConfirmationNeeded", t), this.postEvent("web_app_setup_closing_behavior", { need_confirmation: t });
1152
+ }
1153
+ /**
1154
+ * Returns true, if the confirmation dialog enabled while the user is trying
1155
+ * to close the Mini App.
1156
+ */
1157
+ get isConfirmationNeeded() {
1158
+ return this.state.get("isConfirmationNeeded");
1159
+ }
1160
+ /**
1161
+ * Disables the confirmation dialog while the user is trying to close the
1162
+ * Mini App.
1163
+ */
1164
+ disableConfirmation() {
1165
+ this.isConfirmationNeeded = !1;
1166
+ }
1167
+ /**
1168
+ * Enables the confirmation dialog while the user is trying to close the
1169
+ * Mini App.
1170
+ */
1171
+ enableConfirmation() {
1172
+ this.isConfirmationNeeded = !0;
1173
+ }
1174
+ }
1175
+ const Pe = Bt().of(h());
1176
+ function st(r, t) {
1177
+ return r.reduce((e, n) => (e[n] = t, e), {});
1178
+ }
1179
+ class Ae {
1180
+ constructor(t, e, n = f) {
554
1181
  /**
555
1182
  * Checks if specified method is supported by current component.
556
1183
  */
557
- i(this, "supports");
558
- this.postEvent = e, this.state = new b({ isOpened: !1 }, this.ee), this.supports = m(t, { open: "web_app_open_popup" });
1184
+ o(this, "supports");
1185
+ this.createRequestId = e, this.postEvent = n, this.supports = S(t, {
1186
+ delete: "web_app_invoke_custom_method",
1187
+ get: "web_app_invoke_custom_method",
1188
+ getKeys: "web_app_invoke_custom_method",
1189
+ set: "web_app_invoke_custom_method"
1190
+ });
1191
+ }
1192
+ /**
1193
+ * Invokes custom method related to CloudStorage.
1194
+ * @param method - method name.
1195
+ * @param params - method parameters.
1196
+ * @param options - execution options.
1197
+ */
1198
+ async invokeCustomMethod(t, e, n = {}) {
1199
+ const { result: s, error: i } = await _(
1200
+ "web_app_invoke_custom_method",
1201
+ { method: t, params: e, req_id: this.createRequestId() },
1202
+ "custom_method_invoked",
1203
+ { ...n, postEvent: this.postEvent }
1204
+ );
1205
+ if (i)
1206
+ throw new Error(i);
1207
+ return s;
559
1208
  }
560
1209
  /**
561
- * Shows whether popup is currently opened.
1210
+ * Deletes specified key or keys from the cloud storage.
1211
+ * @param keyOrKeys - key or keys to delete.
1212
+ * @param options - request execution options.
562
1213
  */
563
- get isOpened() {
564
- return this.state.get("isOpened");
1214
+ async delete(t, e) {
1215
+ const n = Array.isArray(t) ? t : [t];
1216
+ n.length !== 0 && await this.invokeCustomMethod("deleteStorageValues", { keys: n }, e);
1217
+ }
1218
+ /**
1219
+ * Returns list of all keys presented in the cloud storage.
1220
+ * @param options - request execution options.
1221
+ */
1222
+ async getKeys(t) {
1223
+ const e = await this.invokeCustomMethod("getStorageKeys", {}, t);
1224
+ return Pe.parse(e);
1225
+ }
1226
+ async get(t, e) {
1227
+ const n = Array.isArray(t) ? t : [t];
1228
+ if (n.length === 0)
1229
+ return st(n, "");
1230
+ const s = g(
1231
+ st(n, h())
1232
+ ), i = await this.invokeCustomMethod("getStorageValues", { keys: n }, e).then((a) => s.parse(a));
1233
+ return Array.isArray(t) ? i : i[t];
1234
+ }
1235
+ /**
1236
+ * Saves specified value by key.
1237
+ * @param key - storage key.
1238
+ * @param value - storage value.
1239
+ * @param options - request execution options.
1240
+ */
1241
+ async set(t, e, n) {
1242
+ await this.invokeCustomMethod("saveStorageValue", { key: t, value: e }, n);
1243
+ }
1244
+ }
1245
+ class qe {
1246
+ constructor(t, e = f) {
1247
+ /**
1248
+ * Checks if specified method is supported by current component.
1249
+ */
1250
+ o(this, "supports");
1251
+ this.postEvent = e, this.supports = S(t, {
1252
+ impactOccurred: "web_app_trigger_haptic_feedback",
1253
+ notificationOccurred: "web_app_trigger_haptic_feedback",
1254
+ selectionChanged: "web_app_trigger_haptic_feedback"
1255
+ });
1256
+ }
1257
+ /**
1258
+ * A method tells that an impact occurred. The Telegram app may play the
1259
+ * appropriate haptics based on style value passed.
1260
+ * @param style - impact style.
1261
+ */
1262
+ impactOccurred(t) {
1263
+ this.postEvent("web_app_trigger_haptic_feedback", {
1264
+ type: "impact",
1265
+ impact_style: t
1266
+ });
1267
+ }
1268
+ /**
1269
+ * A method tells that a task or action has succeeded, failed, or produced
1270
+ * a warning. The Telegram app may play the appropriate haptics based on
1271
+ * type value passed.
1272
+ * @param type - notification type.
1273
+ */
1274
+ notificationOccurred(t) {
1275
+ this.postEvent("web_app_trigger_haptic_feedback", {
1276
+ type: "notification",
1277
+ notification_type: t
1278
+ });
1279
+ }
1280
+ /**
1281
+ * A method tells that the user has changed a selection. The Telegram app
1282
+ * may play the appropriate haptics.
1283
+ *
1284
+ * Do not use this feedback when the user makes or confirms a selection;
1285
+ * use it only when the selection changes.
1286
+ */
1287
+ selectionChanged() {
1288
+ this.postEvent("web_app_trigger_haptic_feedback", { type: "selection_change" });
1289
+ }
1290
+ }
1291
+ function Le() {
1292
+ const r = document.createElement("style");
1293
+ r.id = "telegram-custom-styles", document.head.appendChild(r), k("set_custom_style", (t) => {
1294
+ r.innerHTML = t;
1295
+ });
1296
+ }
1297
+ function xt(r) {
1298
+ return `telegram-mini-apps-${r}`;
1299
+ }
1300
+ function O(r, t) {
1301
+ sessionStorage.setItem(xt(r), JSON.stringify(t));
1302
+ }
1303
+ function W(r) {
1304
+ const t = sessionStorage.getItem(xt(r));
1305
+ return t ? JSON.parse(t) : null;
1306
+ }
1307
+ function $e(r, t, e) {
1308
+ const { isVisible: n = !1 } = r ? W("back-button") || {} : {}, s = new ve(n, t, e);
1309
+ return s.on("change", () => {
1310
+ O("back-button", { isVisible: s.isVisible });
1311
+ }), s;
1312
+ }
1313
+ function Ve(r, t) {
1314
+ const { isConfirmationNeeded: e = !1 } = r ? W("closing-behavior") || {} : {}, n = new xe(e, t);
1315
+ return n.on("change", () => O("closing-behavior", {
1316
+ isConfirmationNeeded: n.isConfirmationNeeded
1317
+ })), n;
1318
+ }
1319
+ class Te {
1320
+ constructor(t) {
1321
+ o(this, "ee", new w());
1322
+ o(this, "state");
1323
+ o(this, "postEvent");
1324
+ /**
1325
+ * Adds new event listener.
1326
+ * @param event - event name.
1327
+ * @param listener - event listener.
1328
+ */
1329
+ o(this, "on", (t, e) => (
1330
+ // FIXME: Event 'main_button_pressed' is still being received on Android
1331
+ // even if the main button is disabled.
1332
+ // Issue: https://github.com/Telegram-Mini-Apps/tma.js/issues/3
1333
+ t === "click" ? k("main_button_pressed", e) : this.ee.on(t, e)
1334
+ ));
1335
+ /**
1336
+ * Removes event listener.
1337
+ * @param event - event name.
1338
+ * @param listener - event listener.
1339
+ */
1340
+ o(this, "off", (t, e) => t === "click" ? N("main_button_pressed", e) : this.ee.off(t, e));
1341
+ const {
1342
+ postEvent: e = f,
1343
+ text: n,
1344
+ textColor: s,
1345
+ backgroundColor: i,
1346
+ isEnabled: a,
1347
+ isVisible: c,
1348
+ isLoaderVisible: u
1349
+ } = t;
1350
+ this.postEvent = e, this.state = new b({
1351
+ backgroundColor: i,
1352
+ isEnabled: a,
1353
+ isVisible: c,
1354
+ isLoaderVisible: u,
1355
+ text: n,
1356
+ textColor: s
1357
+ }, this.ee);
1358
+ }
1359
+ /**
1360
+ * Sends current local state to Telegram application.
1361
+ */
1362
+ commit() {
1363
+ this.text !== "" && this.postEvent("web_app_setup_main_button", {
1364
+ is_visible: this.isVisible,
1365
+ is_active: this.isEnabled,
1366
+ is_progress_visible: this.isLoaderVisible,
1367
+ text: this.text,
1368
+ color: this.backgroundColor,
1369
+ text_color: this.textColor
1370
+ });
1371
+ }
1372
+ set isEnabled(t) {
1373
+ this.setParams({ isEnabled: t });
1374
+ }
1375
+ /**
1376
+ * True if the Main Button is currently enabled.
1377
+ */
1378
+ get isEnabled() {
1379
+ return this.state.get("isEnabled");
1380
+ }
1381
+ set isLoaderVisible(t) {
1382
+ this.setParams({ isLoaderVisible: t });
1383
+ }
1384
+ /**
1385
+ * True if the Main Button loader is currently visible.
1386
+ */
1387
+ get isLoaderVisible() {
1388
+ return this.state.get("isLoaderVisible");
1389
+ }
1390
+ set isVisible(t) {
1391
+ this.setParams({ isVisible: t });
1392
+ }
1393
+ /**
1394
+ * True if the Main Button is currently visible.
1395
+ */
1396
+ get isVisible() {
1397
+ return this.state.get("isVisible");
1398
+ }
1399
+ /**
1400
+ * The Main Button background color.
1401
+ */
1402
+ get backgroundColor() {
1403
+ return this.state.get("backgroundColor");
1404
+ }
1405
+ /**
1406
+ * The Main Button text.
1407
+ */
1408
+ get text() {
1409
+ return this.state.get("text");
1410
+ }
1411
+ /**
1412
+ * The Main Button text color.
1413
+ */
1414
+ get textColor() {
1415
+ return this.state.get("textColor");
1416
+ }
1417
+ /**
1418
+ * Disables the Main Button.
1419
+ */
1420
+ disable() {
1421
+ return this.isEnabled = !1, this;
1422
+ }
1423
+ /**
1424
+ * Enables the Main Button.
1425
+ */
1426
+ enable() {
1427
+ return this.isEnabled = !0, this;
1428
+ }
1429
+ /**
1430
+ * Hides the Main Button.
1431
+ */
1432
+ hide() {
1433
+ return this.isVisible = !1, this;
1434
+ }
1435
+ /**
1436
+ * Hides the Main Button loader.
1437
+ */
1438
+ hideLoader() {
1439
+ return this.isLoaderVisible = !1, this;
1440
+ }
1441
+ /**
1442
+ * Shows the Main Button. Note that opening the Mini App from the attachment menu hides the
1443
+ * main button until the user interacts with the Mini App interface.
1444
+ */
1445
+ show() {
1446
+ return this.isVisible = !0, this;
565
1447
  }
566
1448
  /**
567
- * A method that shows a native popup described by the `params` argument.
568
- * Promise will be resolved when popup is closed. Resolved value will have
569
- * an identifier of pressed button.
570
- *
571
- * In case, user clicked outside the popup or clicked top right popup close
572
- * button, null will be returned.
573
- *
574
- * FIXME: In desktop, this function may work incorrectly.
575
- * Issue: https://github.com/Telegram-Mini-Apps/tma.js/issues/7
576
- * @param params - popup parameters.
577
- * @throws {Error} Popup is already opened.
1449
+ * A method to show a loading indicator on the Main Button. It is recommended to display
1450
+ * loader if the action tied to the button may take a long time.
578
1451
  */
579
- async open(t) {
580
- if (this.isOpened)
581
- throw new Error("Popup is already opened.");
582
- this.state.set("isOpened", !0);
583
- try {
584
- const { button_id: e = null } = await _(
585
- "web_app_open_popup",
586
- yt(t),
587
- "popup_closed",
588
- { postEvent: this.postEvent }
589
- );
590
- return e;
591
- } finally {
592
- this.state.set("isOpened", !1);
593
- }
594
- }
595
- }
596
- class kt {
597
- constructor(t, e = g) {
598
- i(this, "ee", new f());
599
- i(this, "state");
600
- /**
601
- * Adds new event listener.
602
- */
603
- i(this, "on", this.ee.on.bind(this.ee));
604
- /**
605
- * Removes event listener.
606
- */
607
- i(this, "off", this.ee.off.bind(this.ee));
608
- /**
609
- * Checks if specified method is supported by current component.
610
- */
611
- i(this, "supports");
612
- this.postEvent = e, this.state = new b({ isOpened: !1 }, this.ee), this.supports = m(t, {
613
- close: "web_app_close_scan_qr_popup",
614
- open: "web_app_open_scan_qr_popup"
615
- });
1452
+ showLoader() {
1453
+ return this.isLoaderVisible = !0, this;
616
1454
  }
617
1455
  /**
618
- * Closes scanner.
1456
+ * Sets new Main Button text. Minimal length for text is 1 symbol, and maximum is 64 symbols.
1457
+ * @param text - new text.
619
1458
  */
620
- close() {
621
- this.postEvent("web_app_close_scan_qr_popup"), this.isOpened = !1;
1459
+ setText(t) {
1460
+ return this.setParams({ text: t });
622
1461
  }
623
- set isOpened(t) {
624
- this.state.set("isOpened", t);
1462
+ /**
1463
+ * Sets new Main Button text color.
1464
+ * @param textColor - new text color.
1465
+ */
1466
+ setTextColor(t) {
1467
+ return this.setParams({ textColor: t });
625
1468
  }
626
1469
  /**
627
- * Returns true in case, QR scanner is currently opened.
1470
+ * Updates current Main Button color.
1471
+ * @param backgroundColor - color to set.
628
1472
  */
629
- get isOpened() {
630
- return this.state.get("isOpened");
1473
+ setBackgroundColor(t) {
1474
+ return this.setParams({ backgroundColor: t });
631
1475
  }
632
1476
  /**
633
- * Opens scanner with specified title shown to user. Method returns promise
634
- * with scanned QR content in case, it was scanned. It will contain null in
635
- * case, scanner was closed.
636
- * @param text - title to display.
1477
+ * Allows setting multiple Main Button parameters.
1478
+ * @param params - Main Button parameters.
637
1479
  */
638
- async open(t) {
639
- if (this.isOpened)
640
- throw new Error("QR scanner is already opened.");
641
- this.isOpened = !0;
642
- try {
643
- const e = await _(
644
- "web_app_open_scan_qr_popup",
645
- { text: t },
646
- ["qr_text_received", "scan_qr_popup_closed"],
647
- { postEvent: this.postEvent }
648
- );
649
- return typeof e == "object" && typeof e.data == "string" ? e.data : null;
650
- } finally {
651
- this.isOpened = !1;
652
- }
1480
+ setParams(t) {
1481
+ return this.state.set(t), this.commit(), this;
653
1482
  }
654
1483
  }
655
- class V {
1484
+ function Ie(r, t, e, n) {
1485
+ const {
1486
+ backgroundColor: s = t,
1487
+ isEnabled: i = !1,
1488
+ isVisible: a = !1,
1489
+ isLoaderVisible: c = !1,
1490
+ textColor: u = e,
1491
+ text: l = ""
1492
+ } = r ? W("main-button") || {} : {}, p = new Te({
1493
+ backgroundColor: s,
1494
+ isEnabled: i,
1495
+ isLoaderVisible: c,
1496
+ isVisible: a,
1497
+ postEvent: n,
1498
+ text: l,
1499
+ textColor: u
1500
+ }), m = () => O("main-button", {
1501
+ backgroundColor: p.backgroundColor,
1502
+ isEnabled: p.isEnabled,
1503
+ isLoaderVisible: p.isLoaderVisible,
1504
+ isVisible: p.isVisible,
1505
+ text: p.text,
1506
+ textColor: p.textColor
1507
+ });
1508
+ return p.on("change", m), p;
1509
+ }
1510
+ class Re {
656
1511
  constructor(t) {
657
- i(this, "ee", new f());
658
- i(this, "state");
1512
+ o(this, "ee", new w());
1513
+ o(this, "state");
1514
+ o(this, "botInline");
1515
+ o(this, "postEvent");
659
1516
  /**
660
1517
  * Adds new event listener.
661
1518
  */
662
- i(this, "on", this.ee.on.bind(this.ee));
1519
+ o(this, "on", this.ee.on.bind(this.ee));
663
1520
  /**
664
1521
  * Removes event listener.
665
1522
  */
666
- i(this, "off", this.ee.off.bind(this.ee));
667
- this.state = new b(t, this.ee);
1523
+ o(this, "off", this.ee.off.bind(this.ee));
1524
+ /**
1525
+ * Checks if specified method is supported by current component.
1526
+ */
1527
+ o(this, "supports");
1528
+ /**
1529
+ * Checks if specified method parameter is supported by current component.
1530
+ */
1531
+ o(this, "supportsParam");
1532
+ const {
1533
+ postEvent: e = f,
1534
+ headerColor: n,
1535
+ backgroundColor: s,
1536
+ version: i,
1537
+ botInline: a
1538
+ } = t, c = S(i, {
1539
+ requestPhoneAccess: "web_app_request_phone",
1540
+ requestWriteAccess: "web_app_request_write_access",
1541
+ switchInlineQuery: "web_app_switch_inline_query",
1542
+ setHeaderColor: "web_app_set_header_color",
1543
+ setBackgroundColor: "web_app_set_background_color"
1544
+ });
1545
+ this.postEvent = e, this.botInline = a, this.supports = (u) => !(!c(u) || u === "switchInlineQuery" && !a), this.state = new b({ backgroundColor: s, headerColor: n }, this.ee), this.supportsParam = St(i, {
1546
+ "setHeaderColor.color": ["web_app_set_header_color", "color"]
1547
+ });
668
1548
  }
669
1549
  /**
670
- * Requests fresh information about current theme.
671
- * FIXME: Be careful using this function in desktop version of Telegram as
672
- * long as method web_app_request_theme does not work on `macos` platform.
673
- * @param options - method options.
1550
+ * The Mini App background color.
674
1551
  */
675
- static async request(t = {}) {
676
- const { timeout: e = 1e3, ...r } = t, o = await _("web_app_request_theme", "theme_changed", {
677
- ...r,
678
- timeout: e
679
- });
680
- return D(o.theme_params);
1552
+ get backgroundColor() {
1553
+ return this.state.get("backgroundColor");
681
1554
  }
682
1555
  /**
683
- * Synchronizes specified instance of ThemeParams with the actual value in the native
684
- * application.
685
- * @param themeParams - ThemeParams instance.
1556
+ * Closes the Mini App.
686
1557
  */
687
- static sync(t) {
688
- E("theme_changed", (e) => {
689
- t.state.set(D(e.theme_params));
690
- });
1558
+ close() {
1559
+ this.postEvent("web_app_close");
691
1560
  }
692
1561
  /**
693
- * Returns instance of ThemeParams which is synchronized with external
694
- * environment.
695
- * @param options - method options.
1562
+ * The Mini App header color. Could either be a header color key or RGB color.
696
1563
  */
697
- static async synced(t) {
698
- const e = await this.request(t), r = new V(e);
699
- return this.sync(r), r;
700
- }
701
- get accentTextColor() {
702
- return this.get("accentTextColor");
1564
+ get headerColor() {
1565
+ return this.state.get("headerColor");
703
1566
  }
704
1567
  /**
705
- * Returns background color.
1568
+ * True if Mini App is currently launched in bot inline mode.
706
1569
  */
707
- get backgroundColor() {
708
- return this.get("backgroundColor");
1570
+ get isBotInline() {
1571
+ return this.botInline;
709
1572
  }
710
1573
  /**
711
- * Returns button color.
1574
+ * True if current Mini App background color recognized as dark.
712
1575
  */
713
- get buttonColor() {
714
- return this.get("buttonColor");
1576
+ get isDark() {
1577
+ return lt(this.backgroundColor);
715
1578
  }
716
1579
  /**
717
- * Returns button text color.
1580
+ * Informs the Telegram app that the Mini App is ready to be displayed.
1581
+ *
1582
+ * It is recommended to call this method as early as possible, as soon as all essential
1583
+ * interface elements loaded. Once this method called, the loading placeholder is hidden
1584
+ * and the Mini App shown.
1585
+ *
1586
+ * If the method not called, the placeholder will be hidden only when the page fully loaded.
718
1587
  */
719
- get buttonTextColor() {
720
- return this.get("buttonTextColor");
721
- }
722
- get destructiveTextColor() {
723
- return this.get("destructiveTextColor");
1588
+ ready() {
1589
+ this.postEvent("web_app_ready");
724
1590
  }
725
1591
  /**
726
- * Retrieves palette color value by its name.
727
- * @param key - palette key name.
1592
+ * Requests current user phone access.
728
1593
  */
729
- get(t) {
730
- return this.state.get(t) || null;
731
- }
732
- getState() {
733
- return this.state.getState();
734
- }
735
- get headerBackgroundColor() {
736
- return this.get("headerBackgroundColor");
1594
+ requestPhoneAccess() {
1595
+ return _(
1596
+ "web_app_request_phone",
1597
+ "phone_requested",
1598
+ { postEvent: this.postEvent }
1599
+ ).then((t) => t.status);
737
1600
  }
738
1601
  /**
739
- * Returns hint color.
1602
+ * Requests write message access to current user.
740
1603
  */
741
- get hintColor() {
742
- return this.get("hintColor");
1604
+ requestWriteAccess() {
1605
+ return _(
1606
+ "web_app_request_write_access",
1607
+ "write_access_requested",
1608
+ { postEvent: this.postEvent }
1609
+ ).then((t) => t.status);
743
1610
  }
744
1611
  /**
745
- * Returns true in case, current color scheme is recognized as dark. This
746
- * value is calculated according to theme background color.
1612
+ * A method used to send data to the bot. When this method called, a service message sent to
1613
+ * the bot containing the data of the length up to 4096 bytes, and the Mini App closed. See the
1614
+ * field `web_app_data` in the class [Message](https://core.telegram.org/bots/api#message).
1615
+ *
1616
+ * This method is only available for Mini Apps launched via a Keyboard button.
1617
+ * @param data - data to send to bot.
1618
+ * @throws {Error} data has incorrect size.
747
1619
  */
748
- get isDark() {
749
- return this.backgroundColor === null || U(this.backgroundColor);
1620
+ sendData(t) {
1621
+ const { size: e } = new Blob([t]);
1622
+ if (e === 0 || e > 4096)
1623
+ throw new Error(`Passed data has incorrect size: ${e}`);
1624
+ this.postEvent("web_app_data_send", { data: t });
750
1625
  }
751
1626
  /**
752
- * Returns current link color.
1627
+ * Updates current Mini App header color.
1628
+ * @param color - color key or RGB color.
753
1629
  */
754
- get linkColor() {
755
- return this.get("linkColor");
1630
+ setHeaderColor(t) {
1631
+ this.postEvent("web_app_set_header_color", ut(t) ? { color: t } : { color_key: t }), this.state.set("headerColor", t);
756
1632
  }
757
1633
  /**
758
- * Returns secondary background color.
1634
+ * Updates current Mini App background color.
1635
+ * @param color - RGB color.
759
1636
  */
760
- get secondaryBackgroundColor() {
761
- return this.get("secondaryBackgroundColor");
762
- }
763
- get sectionBackgroundColor() {
764
- return this.get("sectionBackgroundColor");
765
- }
766
- get sectionHeaderTextColor() {
767
- return this.get("sectionHeaderTextColor");
768
- }
769
- get subtitleTextColor() {
770
- return this.get("subtitleTextColor");
1637
+ setBackgroundColor(t) {
1638
+ this.postEvent("web_app_set_background_color", { color: t }), this.state.set("backgroundColor", t);
771
1639
  }
772
1640
  /**
773
- * Returns text color.
774
- */
775
- get textColor() {
776
- return this.get("textColor");
1641
+ * Inserts the bot's username and the specified inline query in the current chat's input field.
1642
+ * Query may be empty, in which case only the bot's username will be inserted. The client prompts
1643
+ * the user to choose a specific chat, then opens that chat and inserts the bot's username and
1644
+ * the specified inline query in the input field.
1645
+ * @param text - text which should be inserted in the input after the current bot name. Max
1646
+ * length is 256 symbols.
1647
+ * @param chatTypes - List of chat types which could be chosen to send the message. Could be
1648
+ * empty list.
1649
+ */
1650
+ switchInlineQuery(t, e = []) {
1651
+ if (!this.supports("switchInlineQuery") && !this.isBotInline)
1652
+ throw new Error("Method is unsupported because Mini App should be launched in inline mode.");
1653
+ this.postEvent("web_app_switch_inline_query", {
1654
+ query: t,
1655
+ chat_types: e
1656
+ });
777
1657
  }
778
1658
  }
779
- function v(s) {
780
- return s < 0 ? 0 : s;
1659
+ function Be(r, t, e, n, s) {
1660
+ const {
1661
+ backgroundColor: i = t,
1662
+ headerColor: a = "bg_color"
1663
+ } = r ? W("mini-app") || {} : {}, c = new Re({
1664
+ headerColor: a,
1665
+ backgroundColor: i,
1666
+ version: e,
1667
+ botInline: n,
1668
+ postEvent: s
1669
+ }), u = () => O("mini-app", {
1670
+ backgroundColor: c.backgroundColor,
1671
+ headerColor: c.headerColor
1672
+ });
1673
+ return c.on("change", u), c;
1674
+ }
1675
+ function De() {
1676
+ let r = 0;
1677
+ return () => (r += 1, r.toString());
781
1678
  }
782
- class y {
783
- constructor(t, e, r, o, n = g) {
784
- i(this, "ee", new f());
785
- i(this, "state");
1679
+ function He(r) {
1680
+ const t = new zt(r);
1681
+ return t.listen(), t;
1682
+ }
1683
+ async function Pt(r) {
1684
+ const t = await _("web_app_request_viewport", "viewport_changed", r);
1685
+ return {
1686
+ height: t.height,
1687
+ width: t.width,
1688
+ isExpanded: t.is_expanded,
1689
+ isStateStable: t.is_state_stable
1690
+ };
1691
+ }
1692
+ function I(r) {
1693
+ return r < 0 ? 0 : r;
1694
+ }
1695
+ class j {
1696
+ constructor(t) {
1697
+ o(this, "ee", new w());
1698
+ o(this, "state");
1699
+ o(this, "postEvent");
786
1700
  /**
787
1701
  * Adds new event listener.
788
1702
  */
789
- i(this, "on", this.ee.on.bind(this.ee));
1703
+ o(this, "on", this.ee.on.bind(this.ee));
790
1704
  /**
791
1705
  * Removes event listener.
792
1706
  */
793
- i(this, "off", this.ee.off.bind(this.ee));
794
- this.postEvent = n, this.state = new b({
795
- height: v(t),
796
- isExpanded: o,
797
- stableHeight: v(r),
798
- width: v(e)
1707
+ o(this, "off", this.ee.off.bind(this.ee));
1708
+ const {
1709
+ height: e,
1710
+ isExpanded: n,
1711
+ width: s,
1712
+ stableHeight: i,
1713
+ postEvent: a = f
1714
+ } = t;
1715
+ this.postEvent = a, this.state = new b({
1716
+ height: I(e),
1717
+ isExpanded: n,
1718
+ stableHeight: I(i),
1719
+ width: I(s)
799
1720
  }, this.ee);
800
1721
  }
801
1722
  /**
802
- * Requests fresh information about current viewport.
803
- * FIXME: Be careful using this function in desktop version of Telegram as
804
- * long as method web_app_request_viewport does not work on `macos` platform.
805
- * @see Issue: https://github.com/Telegram-Mini-Apps/tma.js/issues/5
806
- * @param options - method options.
807
- */
808
- static async request(t = {}) {
809
- const { timeout: e = 1e3, ...r } = t, {
810
- is_expanded: o,
811
- is_state_stable: n,
812
- ...a
813
- } = await _("web_app_request_viewport", "viewport_changed", {
814
- ...r,
815
- timeout: e
816
- });
817
- return { ...a, isExpanded: o, isStateStable: n };
818
- }
819
- /**
820
- * Synchronizes specified instance of Viewport with the actual value in the native
821
- * application.
822
- * @param viewport - Viewport instance.
1723
+ * Request viewport information from the Telegram application and updates current Viewport
1724
+ * instance.
1725
+ * @param options - options to request fresh data.
823
1726
  */
824
- static sync(t) {
825
- E("viewport_changed", (e) => {
826
- const {
827
- height: r,
828
- width: o,
829
- is_expanded: n,
830
- is_state_stable: a
831
- } = e, u = v(r);
832
- t.state.set({
833
- height: u,
1727
+ sync(t) {
1728
+ return Pt(t).then(({ height: e, isExpanded: n, width: s, isStateStable: i }) => {
1729
+ this.state.set({
1730
+ height: e,
1731
+ width: s,
834
1732
  isExpanded: n,
835
- width: v(o),
836
- stableHeight: a ? u : void 0
1733
+ stableHeight: i ? e : this.state.get("stableHeight")
837
1734
  });
838
1735
  });
839
1736
  }
840
- /**
841
- * Returns initialized instance of Viewport which is synchronized with
842
- * its actual state in Mini Apps.
843
- * @param options - method options.
844
- */
845
- static async synced(t = {}) {
846
- const { height: e, isExpanded: r, width: o } = await this.request(t), n = new y(e, o, e, r, t.postEvent);
847
- return this.sync(n), n;
848
- }
849
1737
  /**
850
1738
  * The current height of the visible area of the Mini App.
851
1739
  *
@@ -861,10 +1749,6 @@ class y {
861
1749
  * used to pin interface elements to the bottom of the visible area. It's
862
1750
  * more appropriate to use the value of the `stableHeight`
863
1751
  * field for this purpose.
864
- *
865
- * @see init
866
- * @see expand
867
- * @see stableHeight
868
1752
  */
869
1753
  get height() {
870
1754
  return this.state.get("height");
@@ -882,14 +1766,29 @@ class y {
882
1766
  * gestures or during animations. The value of `stableHeight`
883
1767
  * will be updated after all gestures and animations are completed and
884
1768
  * the Mini App reaches its final size.
885
- *
886
- * @see init
887
- * @see expand
888
- * @see height
889
1769
  */
890
1770
  get stableHeight() {
891
1771
  return this.state.get("stableHeight");
892
1772
  }
1773
+ /**
1774
+ * Starts listening to viewport changes and applies them.
1775
+ * @returns Function to stop listening.
1776
+ */
1777
+ listen() {
1778
+ return k("viewport_changed", (t) => {
1779
+ const {
1780
+ height: e,
1781
+ width: n,
1782
+ is_expanded: s,
1783
+ is_state_stable: i
1784
+ } = t, a = {
1785
+ height: I(e),
1786
+ isExpanded: s,
1787
+ width: I(n)
1788
+ };
1789
+ i && (a.stableHeight = a.height), this.state.set(a);
1790
+ });
1791
+ }
893
1792
  /**
894
1793
  * Returns true if the Mini App is expanded to the maximum available height.
895
1794
  * Otherwise, if the Mini App occupies part of the screen and can be expanded
@@ -899,104 +1798,323 @@ class y {
899
1798
  get isExpanded() {
900
1799
  return this.state.get("isExpanded");
901
1800
  }
902
- /**
903
- * Current viewport width.
904
- */
905
- get width() {
906
- return this.state.get("width");
1801
+ /**
1802
+ * Current viewport width.
1803
+ */
1804
+ get width() {
1805
+ return this.state.get("width");
1806
+ }
1807
+ /**
1808
+ * A method that expands the Mini App to the maximum available height. To
1809
+ * find out if the Mini App is expanded to the maximum height, refer to the
1810
+ * value of the `isExpanded`.
1811
+ * @see isExpanded
1812
+ */
1813
+ expand() {
1814
+ this.postEvent("web_app_expand"), this.state.set("isExpanded", !0);
1815
+ }
1816
+ /**
1817
+ * Returns true in case current viewport height is stable and is not going to
1818
+ * change in the next moment.
1819
+ */
1820
+ get isStable() {
1821
+ return this.stableHeight === this.height;
1822
+ }
1823
+ }
1824
+ function At(r, t, e) {
1825
+ if (r || t === "macos" || t === "web" || t === "weba")
1826
+ return new j({
1827
+ height: window.innerHeight,
1828
+ isExpanded: !0,
1829
+ postEvent: e,
1830
+ stableHeight: window.innerHeight,
1831
+ width: window.innerWidth
1832
+ });
1833
+ const n = W("viewport");
1834
+ return n ? new j({ ...n, postEvent: e }) : null;
1835
+ }
1836
+ function qt(r) {
1837
+ return r.listen(), r.on("change", () => O("viewport", {
1838
+ height: r.height,
1839
+ isExpanded: r.isExpanded,
1840
+ stableHeight: r.stableHeight,
1841
+ width: r.width
1842
+ })), r;
1843
+ }
1844
+ function Ne(r, t, e) {
1845
+ const n = qt(
1846
+ At(r, t, e) || new j({
1847
+ width: 0,
1848
+ height: 0,
1849
+ isExpanded: !1,
1850
+ postEvent: e,
1851
+ stableHeight: 0
1852
+ })
1853
+ );
1854
+ return n.sync({ postEvent: e, timeout: 100 }).catch((s) => {
1855
+ console.error("Unable to actualize viewport state", s);
1856
+ }), n;
1857
+ }
1858
+ async function Oe(r, t, e) {
1859
+ return qt(
1860
+ At(r, t, e) || await Pt({ postEvent: e, timeout: 100 }).then(({ height: n, isStateStable: s, ...i }) => new j({
1861
+ ...i,
1862
+ height: n,
1863
+ stableHeight: s ? n : 0
1864
+ }))
1865
+ );
1866
+ }
1867
+ function v(r, t) {
1868
+ document.documentElement.style.setProperty(r, t);
1869
+ }
1870
+ function We(r, t) {
1871
+ const e = () => {
1872
+ v("--tg-background-color", r.backgroundColor);
1873
+ }, n = () => {
1874
+ const {
1875
+ backgroundColor: s,
1876
+ secondaryBackgroundColor: i
1877
+ } = t;
1878
+ r.headerColor === "bg_color" ? s && v("--tg-header-color", s) : r.headerColor === "secondary_bg_color" ? i && v("--tg-header-color", i) : v("--tg-header-color", r.headerColor);
1879
+ };
1880
+ t.on("change", n), r.on("change:backgroundColor", e), r.on("change:headerColor", n), e(), n();
1881
+ }
1882
+ function Me(r) {
1883
+ const t = () => {
1884
+ const e = r.getState();
1885
+ Object.entries(e).forEach(([n, s]) => {
1886
+ if (s) {
1887
+ const i = n.replace(/[A-Z]/g, (a) => `-${a.toLowerCase()}`);
1888
+ v(`--tg-theme-${i}`, s);
1889
+ }
1890
+ });
1891
+ };
1892
+ r.on("change", t), t();
1893
+ }
1894
+ function it(r) {
1895
+ const t = () => v("--tg-viewport-height", `${r.height}px`), e = () => v("--tg-viewport-width", `${r.width}px`), n = () => v("--tg-viewport-height", `${r.stableHeight}px`);
1896
+ r.on("change:height", t), r.on("change:width", e), r.on("change:stableHeight", n), t(), e(), n();
1897
+ }
1898
+ function Ue(r) {
1899
+ return typeof r == "object" ? r : r ? {
1900
+ themeParams: !0,
1901
+ viewport: !0,
1902
+ miniApp: !0
1903
+ } : {};
1904
+ }
1905
+ function ot(r, t, e, n) {
1906
+ const s = Ue(r);
1907
+ s.miniApp && We(t, e), s.themeParams && Me(e), s.viewport && (n instanceof Promise ? n.then(it) : it(n));
1908
+ }
1909
+ function je(r) {
1910
+ const { hostname: t, pathname: e } = new URL(r, window.location.href);
1911
+ if (t !== "t.me")
1912
+ throw new Error(`Incorrect hostname: ${t}`);
1913
+ const n = e.match(/^\/(\$|invoice\/)([A-Za-z0-9\-_=]+)$/);
1914
+ if (n === null)
1915
+ throw new Error('Link pathname has incorrect format. Expected to receive "/invoice/{slug}" or "/${slug}"');
1916
+ return n[2];
1917
+ }
1918
+ class Ge {
1919
+ constructor(t, e = f) {
1920
+ o(this, "ee", new w());
1921
+ o(this, "state");
1922
+ /**
1923
+ * Adds new event listener.
1924
+ */
1925
+ o(this, "on", this.ee.on.bind(this.ee));
1926
+ /**
1927
+ * Removes event listener.
1928
+ */
1929
+ o(this, "off", this.ee.off.bind(this.ee));
1930
+ /**
1931
+ * Checks if specified method is supported by current component.
1932
+ */
1933
+ o(this, "supports");
1934
+ this.postEvent = e, this.state = new b({ isOpened: !1 }, this.ee), this.supports = S(t, { open: "web_app_open_invoice" });
1935
+ }
1936
+ set isOpened(t) {
1937
+ this.state.set("isOpened", t);
1938
+ }
1939
+ /**
1940
+ * True if invoice is currently opened.
1941
+ */
1942
+ get isOpened() {
1943
+ return this.state.get("isOpened");
1944
+ }
1945
+ async open(t, e) {
1946
+ if (this.isOpened)
1947
+ throw new Error("Invoice is already opened");
1948
+ const n = e ? je(t) : t;
1949
+ this.isOpened = !0;
1950
+ try {
1951
+ return (await _(
1952
+ "web_app_open_invoice",
1953
+ { slug: n },
1954
+ "invoice_closed",
1955
+ {
1956
+ postEvent: this.postEvent,
1957
+ capture(i) {
1958
+ return n === i.slug;
1959
+ }
1960
+ }
1961
+ )).status;
1962
+ } finally {
1963
+ this.isOpened = !1;
1964
+ }
1965
+ }
1966
+ }
1967
+ function Fe(r) {
1968
+ const t = r.message.trim(), e = (r.title || "").trim(), n = r.buttons || [];
1969
+ let s;
1970
+ if (e.length > 64)
1971
+ throw new Error(`Title has incorrect size: ${e.length}`);
1972
+ if (t.length === 0 || t.length > 256)
1973
+ throw new Error(`Message has incorrect size: ${t.length}`);
1974
+ if (n.length > 3)
1975
+ throw new Error(`Buttons have incorrect size: ${n.length}`);
1976
+ return n.length === 0 ? s = [{ type: "close", id: "" }] : s = n.map((i) => {
1977
+ const { id: a = "" } = i;
1978
+ if (a.length > 64)
1979
+ throw new Error(`Button ID has incorrect size: ${a}`);
1980
+ if (i.type === void 0 || i.type === "default" || i.type === "destructive") {
1981
+ const c = i.text.trim();
1982
+ if (c.length === 0 || c.length > 64) {
1983
+ const u = i.type || "default";
1984
+ throw new Error(`Button text with type "${u}" has incorrect size: ${i.text.length}`);
1985
+ }
1986
+ return { ...i, text: c, id: a };
1987
+ }
1988
+ return { ...i, id: a };
1989
+ }), { title: e, message: t, buttons: s };
1990
+ }
1991
+ class ze {
1992
+ constructor(t, e = f) {
1993
+ o(this, "ee", new w());
1994
+ o(this, "state");
1995
+ /**
1996
+ * Adds new event listener.
1997
+ */
1998
+ o(this, "on", this.ee.on.bind(this.ee));
1999
+ /**
2000
+ * Removes event listener.
2001
+ */
2002
+ o(this, "off", this.ee.off.bind(this.ee));
2003
+ /**
2004
+ * Checks if specified method is supported by current component.
2005
+ */
2006
+ o(this, "supports");
2007
+ this.postEvent = e, this.state = new b({ isOpened: !1 }, this.ee), this.supports = S(t, { open: "web_app_open_popup" });
2008
+ }
2009
+ set isOpened(t) {
2010
+ this.state.set("isOpened", t);
907
2011
  }
908
2012
  /**
909
- * A method that expands the Mini App to the maximum available height. To
910
- * find out if the Mini App is expanded to the maximum height, refer to the
911
- * value of the `isExpanded`.
912
- * @see isExpanded
2013
+ * True if popup is currently opened.
913
2014
  */
914
- expand() {
915
- this.state.set("isExpanded", !0), this.postEvent("web_app_expand");
2015
+ get isOpened() {
2016
+ return this.state.get("isOpened");
916
2017
  }
917
2018
  /**
918
- * Returns true in case current viewport height is stable and is not going to
919
- * change in the next moment.
2019
+ * A method that shows a native popup described by the `params` argument.
2020
+ * Promise will be resolved when popup is closed. Resolved value will have
2021
+ * an identifier of pressed button.
2022
+ *
2023
+ * In case, user clicked outside the popup or clicked top right popup close
2024
+ * button, null will be returned.
2025
+ *
2026
+ * FIXME: In desktop, this function may work incorrectly.
2027
+ * Issue: https://github.com/Telegram-Mini-Apps/tma.js/issues/7
2028
+ * @param options - popup parameters.
2029
+ * @throws {Error} Popup is already opened.
920
2030
  */
921
- get isStable() {
922
- return this.stableHeight === this.height;
2031
+ open(t) {
2032
+ if (this.isOpened)
2033
+ throw new Error("Popup is already opened.");
2034
+ return this.isOpened = !0, _(
2035
+ "web_app_open_popup",
2036
+ Fe(t),
2037
+ "popup_closed",
2038
+ { postEvent: this.postEvent }
2039
+ ).then(({ button_id: e = null }) => e).finally(() => {
2040
+ this.isOpened = !1;
2041
+ });
923
2042
  }
924
2043
  }
925
- function T(s) {
926
- const t = document.createElement("a");
927
- if (t.href = s, t.protocol !== "http:" && t.protocol !== "https:")
928
- throw Error(
929
- `URL protocol is not supported by OS, or link has not allowed protocol: ${t.protocol}`
930
- );
931
- return t.href;
932
- }
933
- class xt {
934
- constructor(t, e, r, o, n, a = g) {
935
- i(this, "ee", new f());
936
- i(this, "state");
2044
+ class Je {
2045
+ constructor(t, e = f) {
2046
+ o(this, "ee", new w());
2047
+ o(this, "state");
937
2048
  /**
938
2049
  * Adds new event listener.
939
2050
  */
940
- i(this, "on", this.ee.on.bind(this.ee));
2051
+ o(this, "on", this.ee.on.bind(this.ee));
941
2052
  /**
942
2053
  * Removes event listener.
943
2054
  */
944
- i(this, "off", this.ee.off.bind(this.ee));
2055
+ o(this, "off", this.ee.off.bind(this.ee));
945
2056
  /**
946
2057
  * Checks if specified method is supported by current component.
947
2058
  */
948
- i(this, "supports");
949
- /**
950
- * Checks if specified method parameter is supported by current component.
951
- */
952
- i(this, "supportsParam");
953
- this.currentVersion = r, this.currentPlatform = o, this.createRequestId = n, this.postEvent = a, this.state = new b({
954
- backgroundColor: e,
955
- headerColor: t
956
- }, this.ee), this.supports = m(r, {
957
- openInvoice: "web_app_open_invoice",
958
- readTextFromClipboard: "web_app_read_text_from_clipboard",
959
- setHeaderColor: "web_app_set_header_color",
960
- setBackgroundColor: "web_app_set_background_color",
961
- requestPhoneAccess: "web_app_request_phone",
962
- requestWriteAccess: "web_app_request_write_access"
963
- }), this.supportsParam = gt(r, {
964
- "setHeaderColor.color": ["web_app_set_header_color", "color"],
965
- "openLink.tryInstantView": ["web_app_open_link", "try_instant_view"]
2059
+ o(this, "supports");
2060
+ this.postEvent = e, this.state = new b({ isOpened: !1 }, this.ee), this.supports = S(t, {
2061
+ close: "web_app_close_scan_qr_popup",
2062
+ open: "web_app_open_scan_qr_popup"
966
2063
  });
967
2064
  }
968
2065
  /**
969
- * Returns current application background color.
2066
+ * Closes scanner.
970
2067
  */
971
- get backgroundColor() {
972
- return this.state.get("backgroundColor");
2068
+ close() {
2069
+ this.postEvent("web_app_close_scan_qr_popup"), this.isOpened = !1;
973
2070
  }
974
- /**
975
- * Returns current application color scheme. This value is
976
- * computed based on the current background color.
977
- */
978
- get colorScheme() {
979
- return U(this.backgroundColor) ? "dark" : "light";
2071
+ set isOpened(t) {
2072
+ this.state.set("isOpened", t);
980
2073
  }
981
2074
  /**
982
- * Closes the Mini App.
2075
+ * Returns true in case, QR scanner is currently opened.
983
2076
  */
984
- close() {
985
- this.postEvent("web_app_close");
2077
+ get isOpened() {
2078
+ return this.state.get("isOpened");
986
2079
  }
987
2080
  /**
988
- * Returns current application header color.
2081
+ * Opens scanner with specified title shown to user. Method returns promise
2082
+ * with scanned QR content in case, it was scanned. It will contain null in
2083
+ * case, scanner was closed.
2084
+ * @param text - title to display.
989
2085
  */
990
- get headerColor() {
991
- return this.state.get("headerColor");
2086
+ async open(t) {
2087
+ if (this.isOpened)
2088
+ throw new Error("QR scanner is already opened.");
2089
+ this.isOpened = !0;
2090
+ try {
2091
+ const e = await _(
2092
+ "web_app_open_scan_qr_popup",
2093
+ { text: t },
2094
+ ["qr_text_received", "scan_qr_popup_closed"],
2095
+ { postEvent: this.postEvent }
2096
+ );
2097
+ return typeof e == "object" && typeof e.data == "string" ? e.data : null;
2098
+ } finally {
2099
+ this.isOpened = !1;
2100
+ }
992
2101
  }
993
- /**
994
- * Returns true if passed version is more than or equal to current
995
- * Mini App version.
996
- * @param version - compared version.
997
- */
998
- isVersionAtLeast(t) {
999
- return lt(t, this.version) >= 0;
2102
+ }
2103
+ class Qe {
2104
+ constructor(t, e, n = f) {
2105
+ /**
2106
+ * Checks if specified method is supported by current component.
2107
+ */
2108
+ o(this, "supports");
2109
+ /**
2110
+ * Checks if specified method parameter is supported by current component.
2111
+ */
2112
+ o(this, "supportsParam");
2113
+ this.version = t, this.createRequestId = e, this.postEvent = n, this.supports = S(t, {
2114
+ readTextFromClipboard: "web_app_read_text_from_clipboard"
2115
+ }), this.supportsParam = St(t, {
2116
+ "openLink.tryInstantView": ["web_app_open_link", "try_instant_view"]
2117
+ });
1000
2118
  }
1001
2119
  /**
1002
2120
  * Opens a link in an external browser. The Mini App will not be closed.
@@ -1008,378 +2126,487 @@ class xt {
1008
2126
  * @param tryInstantView
1009
2127
  */
1010
2128
  openLink(t, e) {
1011
- const r = T(t);
1012
- if (!S("web_app_open_link", this.version)) {
1013
- window.open(r, "_blank");
2129
+ const n = new URL(t, window.location.href).toString();
2130
+ if (!q("web_app_open_link", this.version)) {
2131
+ window.open(n, "_blank");
1014
2132
  return;
1015
2133
  }
1016
- return this.postEvent("web_app_open_link", {
1017
- url: r,
2134
+ this.postEvent("web_app_open_link", {
2135
+ url: n,
1018
2136
  ...typeof e == "boolean" ? { try_instant_view: e } : {}
1019
2137
  });
1020
2138
  }
1021
2139
  /**
1022
- * Opens a Telegram link inside Telegram app. The Mini App will be closed.
1023
- * It expects passing link in full format, with hostname "t.me".
2140
+ * Opens a Telegram link inside Telegram app. The Mini App will be closed. It expects passing
2141
+ * link in full format, with hostname "t.me".
1024
2142
  * @param url - URL to be opened.
1025
2143
  * @throws {Error} URL has not allowed hostname.
1026
2144
  */
1027
2145
  openTelegramLink(t) {
1028
- const { hostname: e, pathname: r, search: o } = new URL(T(t));
2146
+ const {
2147
+ hostname: e,
2148
+ pathname: n,
2149
+ search: s
2150
+ } = new URL(t, window.location.href);
1029
2151
  if (e !== "t.me")
1030
2152
  throw new Error(`URL has not allowed hostname: ${e}. Only "t.me" is allowed`);
1031
- if (!S("web_app_open_tg_link", this.version)) {
2153
+ if (!q("web_app_open_tg_link", this.version)) {
1032
2154
  window.location.href = t;
1033
2155
  return;
1034
2156
  }
1035
- return this.postEvent("web_app_open_tg_link", { path_full: r + o });
2157
+ this.postEvent("web_app_open_tg_link", { path_full: n + s });
1036
2158
  }
1037
2159
  /**
1038
- * Opens an invoice using its url. It expects passing link in full format,
1039
- * with hostname "t.me".
1040
- * @param url - invoice URL.
2160
+ * Reads text from clipboard and returns string or null. null is returned
2161
+ * in cases:
2162
+ * - Value in clipboard is not text
2163
+ * - Access to clipboard is not allowed
1041
2164
  */
1042
- async openInvoice(t) {
1043
- const { hostname: e, pathname: r } = new URL(T(t));
1044
- if (e !== "t.me")
1045
- throw new Error(`Incorrect hostname: ${e}`);
1046
- const o = r.match(/^\/(\$|invoice\/)([A-Za-z0-9\-_=]+)$/);
1047
- if (o === null)
1048
- throw new Error('Link pathname has incorrect format. Expected to receive "/invoice/slug" or "/$slug"');
1049
- const [, , n] = o;
1050
- return (await _("web_app_open_invoice", { slug: n }, "invoice_closed", {
1051
- postEvent: this.postEvent,
1052
- capture: ({ slug: u }) => n === u
1053
- })).status;
2165
+ readTextFromClipboard() {
2166
+ return _(
2167
+ "web_app_read_text_from_clipboard",
2168
+ { req_id: this.createRequestId() },
2169
+ "clipboard_text_received",
2170
+ { postEvent: this.postEvent }
2171
+ ).then(({ data: t = null }) => t);
2172
+ }
2173
+ }
2174
+ function ar(r) {
2175
+ const {
2176
+ async: t = !1,
2177
+ cssVars: e = !1,
2178
+ acceptCustomStyles: n = !1
2179
+ } = r;
2180
+ try {
2181
+ const {
2182
+ launchParams: {
2183
+ initData: s,
2184
+ initDataRaw: i,
2185
+ version: a,
2186
+ platform: c,
2187
+ themeParams: u,
2188
+ botInline: l = !1
2189
+ },
2190
+ isPageReload: p
2191
+ } = Et(), m = De(), d = Ee(a);
2192
+ Ct() && (n && Le(), d("iframe_ready", { reload_supported: !0 }), k("reload_iframe", () => window.location.reload()));
2193
+ const y = {
2194
+ backButton: $e(p, a, d),
2195
+ closingBehavior: Ve(p, d),
2196
+ cloudStorage: new Ae(a, m, d),
2197
+ createRequestId: m,
2198
+ hapticFeedback: new qe(a, d),
2199
+ invoice: new Ge(a, d),
2200
+ mainButton: Ie(
2201
+ p,
2202
+ u.buttonColor || "#000000",
2203
+ u.buttonTextColor || "#ffffff",
2204
+ d
2205
+ ),
2206
+ miniApp: Be(
2207
+ p,
2208
+ u.backgroundColor || "#ffffff",
2209
+ a,
2210
+ l,
2211
+ d
2212
+ ),
2213
+ popup: new ze(a, d),
2214
+ postEvent: d,
2215
+ qrScanner: new Je(a, d),
2216
+ themeParams: He(u),
2217
+ utils: new Qe(a, m, d),
2218
+ ...s ? {
2219
+ initData: new Mt(s),
2220
+ initDataRaw: i
2221
+ } : {}
2222
+ }, x = t ? Oe(p, c, d) : Ne(p, c, d);
2223
+ return x instanceof Promise ? x.then((V) => (ot(
2224
+ e,
2225
+ y.miniApp,
2226
+ y.themeParams,
2227
+ V
2228
+ ), {
2229
+ ...y,
2230
+ viewport: V
2231
+ })) : (ot(
2232
+ e,
2233
+ y.miniApp,
2234
+ y.themeParams,
2235
+ x
2236
+ ), { ...y, viewport: x });
2237
+ } catch (s) {
2238
+ if (t)
2239
+ return Promise.reject(s);
2240
+ throw s;
2241
+ }
2242
+ }
2243
+ function R(r, t) {
2244
+ return r.startsWith(t) ? r : `${t}${r}`;
2245
+ }
2246
+ function cr(r) {
2247
+ const t = r.match(/#(.+)/);
2248
+ return t ? t[1] : null;
2249
+ }
2250
+ async function B(r) {
2251
+ return r === 0 ? !0 : Promise.race([
2252
+ new Promise((t) => {
2253
+ window.addEventListener("popstate", function e() {
2254
+ window.removeEventListener("popstate", e), t(!0);
2255
+ }), window.history.go(r);
2256
+ }),
2257
+ // Usually, it takes about 1ms to emit this event, but we use some buffer.
2258
+ new Promise((t) => {
2259
+ setTimeout(t, 50, !1);
2260
+ })
2261
+ ]);
2262
+ }
2263
+ async function Ze() {
2264
+ if (window.history.length <= 1 || (window.history.pushState(null, ""), await B(1 - window.history.length)))
2265
+ return;
2266
+ let t = await B(-1);
2267
+ for (; t; )
2268
+ t = await B(-1);
2269
+ }
2270
+ class Ke {
2271
+ constructor(t, e, {
2272
+ debug: n = !1,
2273
+ loggerPrefix: s = "Navigator"
2274
+ }) {
2275
+ o(this, "logger");
2276
+ o(this, "entries");
2277
+ if (this.entriesCursor = e, t.length === 0)
2278
+ throw new Error("Entries list should not be empty.");
2279
+ if (e >= t.length)
2280
+ throw new Error("Cursor should be less than entries count.");
2281
+ this.entries = t.map(({ pathname: i = "", search: a, hash: c }) => {
2282
+ if (!i.startsWith("/") && i.length > 0)
2283
+ throw new Error('Pathname should start with "/"');
2284
+ return {
2285
+ pathname: R(i, "/"),
2286
+ search: a ? R(a, "?") : "",
2287
+ hash: c ? R(c, "#") : ""
2288
+ };
2289
+ }), this.logger = new vt(`[${s}]`, n);
2290
+ }
2291
+ /**
2292
+ * Converts entry to the navigation entry.
2293
+ * @param entry - entry data
2294
+ */
2295
+ formatEntry(t) {
2296
+ let e;
2297
+ if (typeof t == "string")
2298
+ e = t;
2299
+ else {
2300
+ const {
2301
+ pathname: a = "",
2302
+ search: c,
2303
+ hash: u
2304
+ } = t;
2305
+ e = a + (c ? R(c, "?") : "") + (u ? R(u, "#") : "");
2306
+ }
2307
+ const {
2308
+ pathname: n,
2309
+ search: s,
2310
+ hash: i
2311
+ } = new URL(e, `https://localhost${this.path}`);
2312
+ return {
2313
+ pathname: n,
2314
+ search: s,
2315
+ hash: i
2316
+ };
1054
2317
  }
1055
2318
  /**
1056
- * Returns current Mini App platform.
2319
+ * Current entry.
1057
2320
  */
1058
- get platform() {
1059
- return this.currentPlatform;
2321
+ get entry() {
2322
+ return this.entries[this.entriesCursor];
1060
2323
  }
1061
2324
  /**
1062
- * Informs the Telegram app that the Mini App is ready to be displayed.
1063
- *
1064
- * It is recommended to call this method as early as possible, as soon as
1065
- * all essential interface elements loaded. Once this method called,
1066
- * the loading placeholder is hidden and the Mini App shown.
1067
- *
1068
- * If the method not called, the placeholder will be hidden only when
1069
- * the page fully loaded.
2325
+ * Goes back in history.
1070
2326
  */
1071
- ready() {
1072
- this.postEvent("web_app_ready");
2327
+ back() {
2328
+ return this.go(-1);
1073
2329
  }
1074
2330
  /**
1075
- * Reads text from clipboard and returns string or null. null is returned
1076
- * in cases:
1077
- * - Value in clipboard is not text
1078
- * - Access to clipboard is not allowed
2331
+ * Current entries cursor.
1079
2332
  */
1080
- async readTextFromClipboard() {
1081
- const { data: t = null } = await _(
1082
- "web_app_read_text_from_clipboard",
1083
- { req_id: this.createRequestId() },
1084
- "clipboard_text_received",
1085
- { postEvent: this.postEvent }
1086
- );
1087
- return t;
2333
+ get cursor() {
2334
+ return this.entriesCursor;
1088
2335
  }
1089
2336
  /**
1090
- * Requests current user phone access.
2337
+ * True if navigator can go back.
1091
2338
  */
1092
- async requestPhoneAccess() {
1093
- const { status: t } = await _("web_app_request_phone", "phone_requested", {
1094
- postEvent: this.postEvent
1095
- });
1096
- return t;
2339
+ get canGoBack() {
2340
+ return this.entriesCursor > 0;
1097
2341
  }
1098
2342
  /**
1099
- * Requests write message access to current user.
2343
+ * True if navigator can go forward.
2344
+ */
2345
+ get canGoForward() {
2346
+ return this.entriesCursor !== this.entries.length - 1;
2347
+ }
2348
+ /**
2349
+ * Goes forward in history.
2350
+ */
2351
+ forward() {
2352
+ return this.go(1);
2353
+ }
2354
+ /**
2355
+ * Moves entries cursor by specified delta.
2356
+ * @param delta - cursor delta.
1100
2357
  */
1101
- async requestWriteAccess() {
1102
- const { status: t } = await _("web_app_request_write_access", "write_access_requested", {
1103
- postEvent: this.postEvent
2358
+ go(t) {
2359
+ this.logger.log(`called go(${t})`);
2360
+ const e = Math.min(
2361
+ this.entries.length - 1,
2362
+ Math.max(this.entriesCursor + t, 0)
2363
+ );
2364
+ if (this.entriesCursor === e)
2365
+ return this.performGo({
2366
+ updated: !1,
2367
+ delta: t
2368
+ });
2369
+ const n = this.entry;
2370
+ this.entriesCursor = e;
2371
+ const s = this.entry;
2372
+ return this.logger.log("State changed", { before: n, after: s }), this.performGo({
2373
+ updated: !0,
2374
+ delta: t,
2375
+ before: n,
2376
+ after: s
1104
2377
  });
1105
- return t;
1106
2378
  }
1107
2379
  /**
1108
- * A method used to send data to the bot. When this method called, a
1109
- * service message sent to the bot containing the data of the
1110
- * length up to 4096 bytes, and the Mini App closed. See the field
1111
- * `web_app_data` in the class Message.
2380
+ * Returns copy of navigator entries.
2381
+ */
2382
+ getEntries() {
2383
+ return this.entries.map((t) => ({ ...t }));
2384
+ }
2385
+ /**
2386
+ * Current hash.
2387
+ * @example
2388
+ * "", "#", "#hash"
2389
+ */
2390
+ get hash() {
2391
+ return this.entry.hash;
2392
+ }
2393
+ /**
2394
+ * Pushes new entry. Method replaces all entries after the current one with the inserted.
2395
+ * @param entry - entry data.
1112
2396
  *
1113
- * This method is only available for Mini Apps launched via a Keyboard button.
1114
- * @param data - data to send to bot.
1115
- * @throws {Error} data has incorrect size.
2397
+ * @example Pushing absolute pathname.
2398
+ * push("/absolute-path"); // "/absolute-path"
2399
+ *
2400
+ * @example Pushing relative pathname.
2401
+ * // Pushing relative path replaces N last path parts, where N is pushed pathname parts count.
2402
+ * // Pushing empty path is recognized as relative, but not replacing the last pathname part.
2403
+ * push("relative"); // "/home/root" -> "/home/relative"
2404
+ *
2405
+ * @example Pushing query parameters.
2406
+ * push("/absolute?my-param=1"); // "/home" -> "/absolute?my-param=1"
2407
+ * push("relative?my-param=1"); // "/home/root" -> "/home/relative?my-param=1"
2408
+ * push("?my-param=1"); // "/home" -> "/home?my-param=1"
2409
+ *
2410
+ * @example Pushing hash.
2411
+ * push("#my-hash"); // "/home" -> "/home#my-hash"
2412
+ * push("johny#my-hash"); // "/home/root" -> "/home/johny#my-hash"
2413
+ */
2414
+ push(t) {
2415
+ this.entriesCursor !== this.entries.length - 1 && this.entries.splice(this.entriesCursor + 1);
2416
+ const e = this.formatEntry(t), n = this.entry;
2417
+ this.entriesCursor += 1, this.entries[this.entriesCursor] = e;
2418
+ const s = this.entry;
2419
+ return this.logger.log("State changed", { before: n, after: s }), this.performPush({
2420
+ before: n,
2421
+ after: s
2422
+ });
2423
+ }
2424
+ /**
2425
+ * Current full path including pathname, query parameters and hash.
1116
2426
  */
1117
- sendData(t) {
1118
- const { size: e } = new Blob([t]);
1119
- if (e === 0 || e > 4096)
1120
- throw new Error(`Passed data has incorrect size: ${e}`);
1121
- this.postEvent("web_app_data_send", { data: t });
2427
+ get path() {
2428
+ return `${this.pathname}${this.search}${this.hash}`;
1122
2429
  }
1123
2430
  /**
1124
- * Updates current application header color.
1125
- * FIXME: Has no effect on desktop, works incorrectly on Android.
1126
- * Issues:
1127
- * https://github.com/Telegram-Mini-Apps/tma.js/issues/9
1128
- * https://github.com/Telegram-Mini-Apps/tma.js/issues/8
1129
- * @param color - color key or RGB color.
2431
+ * Current pathname.
2432
+ * @example
2433
+ * "/", "/abc"
1130
2434
  */
1131
- setHeaderColor(t) {
1132
- this.postEvent("web_app_set_header_color", pt(t) ? { color: t } : { color_key: t }), this.state.set("headerColor", t);
2435
+ get pathname() {
2436
+ return this.entry.pathname;
1133
2437
  }
1134
2438
  /**
1135
- * Updates current application background color.
1136
- * FIXME: Has no effect on desktop, works incorrectly in Android.
1137
- * Issues:
1138
- * https://github.com/Telegram-Mini-Apps/tma.js/issues/9
1139
- * https://github.com/Telegram-Mini-Apps/tma.js/issues/8
1140
- * @param color - RGB color.
2439
+ * Replaces current entry. Has the same logic as `push` method.
2440
+ * @param entry - entry data.
2441
+ * @see push
2442
+ * @returns True if changes were done.
1141
2443
  */
1142
- setBackgroundColor(t) {
1143
- this.postEvent("web_app_set_background_color", { color: t }), this.state.set("backgroundColor", t);
2444
+ replace(t) {
2445
+ const e = this.formatEntry(t);
2446
+ if (this.search === e.search && this.pathname === e.pathname && this.hash === e.hash)
2447
+ return this.performReplace({
2448
+ updated: !1,
2449
+ entry: e
2450
+ });
2451
+ const n = this.entry;
2452
+ this.entries[this.entriesCursor] = e;
2453
+ const s = this.entry;
2454
+ return this.logger.log("State changed", { before: n, after: s }), this.performReplace({
2455
+ updated: !0,
2456
+ before: n,
2457
+ after: s
2458
+ });
1144
2459
  }
1145
2460
  /**
1146
- * Current Mini App version. This property is used by other components to check if
1147
- * some functionality is available on current device.
2461
+ * Current query parameters.
2462
+ * @example
2463
+ * "", "?", "?a=1"
1148
2464
  */
1149
- get version() {
1150
- return this.currentVersion;
2465
+ get search() {
2466
+ return this.entry.search;
1151
2467
  }
1152
2468
  }
1153
- class K extends Error {
1154
- constructor(t, e) {
1155
- super(`Method "${t}" is not supported in the Mini Apps version ${e}.`), Object.setPrototypeOf(this, K.prototype);
2469
+ const at = 0, J = 1, Q = 2;
2470
+ class Lt extends Ke {
2471
+ constructor(e, n, s = {}) {
2472
+ super(e, n, {
2473
+ ...s,
2474
+ loggerPrefix: "HashNavigator"
2475
+ });
2476
+ o(this, "ee", new w());
2477
+ o(this, "attached", !1);
2478
+ /**
2479
+ * Handles window "popstate" event.
2480
+ * @param state - event state.
2481
+ */
2482
+ o(this, "onPopState", async ({ state: e }) => {
2483
+ if (this.logger.log('"popstate" event received. State:', e), e === null)
2484
+ return this.push(window.location.hash.slice(1));
2485
+ if (e === at) {
2486
+ this.logger.log("Void reached. Moving history forward"), window.history.forward();
2487
+ return;
2488
+ }
2489
+ if (e === J)
2490
+ return this.back();
2491
+ if (e === Q)
2492
+ return this.forward();
2493
+ });
2494
+ o(this, "back", () => super.back());
2495
+ /**
2496
+ * Adds new event listener.
2497
+ */
2498
+ o(this, "on", this.ee.on.bind(this.ee));
2499
+ /**
2500
+ * Removes event listener.
2501
+ */
2502
+ o(this, "off", this.ee.off.bind(this.ee));
1156
2503
  }
1157
- }
1158
- class j extends Error {
1159
- constructor(t, e, r) {
1160
- super(`Parameter "${e}" in method "${t}" is not supported in the Mini Apps version ${r}.`), Object.setPrototypeOf(this, j.prototype);
2504
+ /**
2505
+ * Creates navigator from current window location hash.
2506
+ * @param options - options passed to constructor.
2507
+ */
2508
+ static fromLocation(e) {
2509
+ const {
2510
+ search: n,
2511
+ pathname: s,
2512
+ hash: i
2513
+ } = new URL(
2514
+ window.location.hash.slice(1),
2515
+ window.location.href
2516
+ );
2517
+ return new Lt([{ search: n, pathname: s, hash: i }], 0, e);
1161
2518
  }
1162
- }
1163
- function F(s, t) {
1164
- document.documentElement.style.setProperty(s, t);
1165
- }
1166
- function B(s, t) {
1167
- t !== null && F(s, t);
1168
- }
1169
- function M(s, t) {
1170
- F(s, `${t}px`);
1171
- }
1172
- function St(s, t) {
1173
- const { backgroundColor: e, secondaryBackgroundColor: r } = t, { backgroundColor: o, headerColor: n } = s;
1174
- B("--tg-bg-color", o), B("--tg-header-color", n === "bg_color" ? e : r);
1175
- }
1176
- function Vt(s) {
1177
- const t = () => {
1178
- const e = s.getState();
1179
- Object.entries(e).forEach(([r, o]) => {
1180
- const n = r.replace(/[A-Z]/g, (a) => `-${a.toLowerCase()}`);
1181
- B(`--tg-theme-${n}`, o || null);
2519
+ async performGo(e) {
2520
+ e.updated && (this.attached && await this.syncHistory(), this.emitChanged(e.before, e.after));
2521
+ }
2522
+ async performPush({ before: e, after: n }) {
2523
+ this.attached && await this.syncHistory(), this.emitChanged(e, n);
2524
+ }
2525
+ async performReplace(e) {
2526
+ e.updated && (this.attached && window.history.replaceState(null, "", `#${this.path}`), this.emitChanged(e.before, e.after));
2527
+ }
2528
+ /**
2529
+ * Synchronizes current navigator state with browser history.
2530
+ */
2531
+ async syncHistory() {
2532
+ window.removeEventListener("popstate", this.onPopState);
2533
+ const e = `#${this.path}`;
2534
+ await Ze(), f("web_app_setup_back_button", { is_visible: this.canGoBack }), this.canGoBack && this.canGoForward ? (this.logger.log("Setting up history: [<-, *, ->]"), window.history.replaceState(J, ""), window.history.pushState(null, "", e), window.history.pushState(Q, ""), await B(-1)) : this.canGoBack ? (this.logger.log("Setting up history: [<-, *]"), window.history.replaceState(J, ""), window.history.pushState(null, "", e)) : this.canGoForward ? (this.logger.log("Setting up history: [*, ->]"), window.history.replaceState(null, e), window.history.pushState(Q, ""), await B(-1)) : (this.logger.log("Setting up history: [~, *]"), window.history.replaceState(at, ""), window.history.pushState(null, "", e)), window.addEventListener("popstate", this.onPopState);
2535
+ }
2536
+ emitChanged(e, n) {
2537
+ this.ee.emit("change", {
2538
+ navigator: this,
2539
+ from: e,
2540
+ to: n
1182
2541
  });
1183
- };
1184
- s.on("changed", t), t();
1185
- }
1186
- function Pt(s, t) {
1187
- const e = () => St(s, t);
1188
- t.on("changed", e), s.on("backgroundColorChanged", e), s.on("headerColorChanged", e), e();
1189
- }
1190
- function qt(s) {
1191
- const t = () => {
1192
- M("--tg-viewport-height", s.height);
1193
- }, e = () => {
1194
- M("--tg-viewport-stable-height", s.stableHeight);
1195
- };
1196
- s.on("heightChanged", t), s.on("stableHeightChanged", e), t(), e();
1197
- }
1198
- function Ot(s) {
1199
- return typeof s == "boolean" ? s ? { themeParams: !0, viewport: !0, webApp: !0 } : {} : s;
1200
- }
1201
- function J(s) {
1202
- return `telegram-mini-apps-${s}`;
1203
- }
1204
- function k(s, t) {
1205
- sessionStorage.setItem(J(s), JSON.stringify(t));
1206
- }
1207
- function x(s) {
1208
- const t = sessionStorage.getItem(J(s));
1209
- return t ? JSON.parse(t) : null;
1210
- }
1211
- function Tt(s, t, e) {
1212
- const { isVisible: r = !1 } = s ? x("back-button") || {} : {}, o = new _t(r, t, e);
1213
- return o.on("isVisibleChanged", () => {
1214
- k("back-button", { isVisible: o.isVisible });
1215
- }), o;
1216
- }
1217
- function Bt(s, t) {
1218
- const { isConfirmationNeeded: e = !1 } = s ? x("closing-behavior") || {} : {}, r = new bt(e, t);
1219
- return r.on("isConfirmationNeededChanged", () => k("closing-behavior", {
1220
- isConfirmationNeeded: r.isConfirmationNeeded
1221
- })), r;
1222
- }
1223
- function $t(s, t, e, r) {
1224
- const {
1225
- backgroundColor: o = t,
1226
- isEnabled: n = !1,
1227
- isVisible: a = !1,
1228
- isProgressVisible: u = !1,
1229
- textColor: c = e,
1230
- text: p = ""
1231
- } = s ? x("main-button") || {} : {}, h = new vt(
1232
- o,
1233
- n,
1234
- a,
1235
- u,
1236
- p,
1237
- c,
1238
- r
1239
- ), d = () => k("main-button", {
1240
- backgroundColor: h.backgroundColor,
1241
- isEnabled: h.isEnabled,
1242
- isVisible: h.isVisible,
1243
- isProgressVisible: h.isProgressVisible,
1244
- text: h.text,
1245
- textColor: h.textColor
1246
- });
1247
- return h.on("backgroundColorChanged", d), h.on("isEnabledChanged", d), h.on("isVisibleChanged", d), h.on("isProgressVisibleChanged", d), h.on("textColorChanged", d), h.on("textChanged", d), h;
1248
- }
1249
- function It() {
1250
- let s = 0;
1251
- return () => (s += 1, s.toString());
1252
- }
1253
- function At(s) {
1254
- const t = new V(s);
1255
- return V.sync(t), t;
1256
- }
1257
- async function Ht(s, t, e) {
1258
- const {
1259
- height: r = window.innerHeight,
1260
- stableHeight: o = window.innerHeight,
1261
- width: n = window.innerWidth,
1262
- isExpanded: a = !1
1263
- } = s ? x("viewport") || {} : {}, c = t === "macos" || t === "web" ? (() => {
1264
- const h = new y(r, n, o, a, e);
1265
- return y.sync(h), h;
1266
- })() : await y.synced({ postEvent: e }), p = () => k("viewport", {
1267
- height: c.height,
1268
- isExpanded: c.isExpanded,
1269
- stableHeight: c.stableHeight,
1270
- width: c.width
1271
- });
1272
- return c.on("heightChanged", p), c.on("isExpandedChanged", p), c.on("stableHeightChanged", p), c.on("widthChanged", p), c;
1273
- }
1274
- function Rt(s, t, e, r, o, n) {
1275
- const {
1276
- backgroundColor: a = t,
1277
- headerColor: u = "bg_color"
1278
- } = s ? x("web-app") || {} : {}, c = new xt(
1279
- u,
1280
- a,
1281
- e,
1282
- r,
1283
- o,
1284
- n
1285
- ), p = () => k("web-app", {
1286
- backgroundColor: c.backgroundColor,
1287
- headerColor: c.headerColor
1288
- });
1289
- return c.on("backgroundColorChanged", p), c.on("headerColorChanged", p), c;
1290
- }
1291
- async function Dt(s = {}) {
1292
- const {
1293
- checkCompat: t = !0,
1294
- cssVars: e = !1,
1295
- acceptScrollbarStyle: r = !0,
1296
- acceptCustomStyles: o = r,
1297
- targetOrigin: n,
1298
- launchParams: a,
1299
- debug: u = !1
1300
- } = s;
1301
- u && nt(u), typeof n == "string" && it(n);
1302
- const { launchParams: c, isPageReload: p } = N({
1303
- currentLaunchParams: typeof a == "string" || a instanceof URLSearchParams ? ot(a) : a
1304
- }), {
1305
- initData: h,
1306
- initDataRaw: d,
1307
- version: w,
1308
- platform: $,
1309
- themeParams: I
1310
- } = c, {
1311
- backgroundColor: G = "#ffffff",
1312
- buttonColor: Q = "#000000",
1313
- buttonTextColor: Z = "#ffffff"
1314
- } = I, A = It(), l = t ? at(w) : g, P = At(I), H = Rt(
1315
- p,
1316
- G,
1317
- w,
1318
- $,
1319
- A,
1320
- l
1321
- ), {
1322
- themeParams: X,
1323
- viewport: Y,
1324
- webApp: tt
1325
- } = Ot(e);
1326
- tt && Pt(H, P), X && Vt(P);
1327
- const R = await Ht(p, $, l);
1328
- if (Y && qt(R), o && ct()) {
1329
- const C = document.createElement("style");
1330
- C.id = "telegram-custom-styles", document.head.appendChild(C), E("set_custom_style", (O) => {
1331
- C.innerHTML = O;
1332
- }), l("iframe_ready");
1333
- }
1334
- const q = {
1335
- backButton: Tt(p, w, l),
1336
- closingBehavior: Bt(p, l),
1337
- cloudStorage: new wt(w, A, l),
1338
- haptic: new mt(w, l),
1339
- mainButton: $t(p, Q, Z, l),
1340
- popup: new Et(w, l),
1341
- postEvent: l,
1342
- qrScanner: new kt(w, l),
1343
- themeParams: P,
1344
- viewport: R,
1345
- webApp: H
1346
- };
1347
- if (h !== void 0) {
1348
- const { authDate: C, hash: O, ...et } = h;
1349
- q.initData = new Ct(C, O, et), q.initDataRaw = d;
1350
2542
  }
1351
- return q;
1352
- }
1353
- function Jt(s = {}) {
1354
- return dt(Dt(s), s.timeout || 1e3);
1355
- }
1356
- function Lt() {
1357
- try {
1358
- return N(), !0;
1359
- } catch {
1360
- return !1;
2543
+ /**
2544
+ * Attaches current navigator to the browser history allowing navigator to manipulate it.
2545
+ */
2546
+ async attach() {
2547
+ if (!this.attached)
2548
+ return this.logger.log("Attaching", this), this.attached = !0, k("back_button_pressed", this.back), this.syncHistory();
2549
+ }
2550
+ /**
2551
+ * Detaches current navigator from the browser history.
2552
+ */
2553
+ detach() {
2554
+ this.attached && (this.logger.log("Detaching", this), this.attached = !1, window.removeEventListener("popstate", this.onPopState), N("back_button_pressed", this.back));
1361
2555
  }
1362
- }
1363
- function Gt() {
1364
- return Lt();
1365
2556
  }
1366
2557
  export {
1367
- _t as BackButton,
1368
- bt as ClosingBehaviour,
1369
- wt as CloudStorage,
1370
- mt as HapticFeedback,
1371
- Ct as InitData,
1372
- vt as MainButton,
1373
- K as MethodNotSupportedError,
1374
- j as ParameterUnsupportedError,
1375
- Et as Popup,
1376
- kt as QRScanner,
1377
- V as ThemeParams,
1378
- y as Viewport,
1379
- xt as WebApp,
1380
- T as formatURL,
1381
- Jt as init,
1382
- Lt as isTMA,
1383
- Gt as isTWA
2558
+ ve as BackButton,
2559
+ xe as ClosingBehavior,
2560
+ Ae as CloudStorage,
2561
+ qe as HapticFeedback,
2562
+ Lt as HashNavigator,
2563
+ Mt as InitData,
2564
+ Ge as Invoice,
2565
+ Te as MainButton,
2566
+ K as MethodUnsupportedError,
2567
+ Re as MiniApp,
2568
+ Ke as Navigator,
2569
+ Y as ParameterUnsupportedError,
2570
+ ze as Popup,
2571
+ Je as QRScanner,
2572
+ zt as ThemeParams,
2573
+ Qe as Utils,
2574
+ j as Viewport,
2575
+ Wt as chatParser,
2576
+ ke as classNames,
2577
+ ye as compareVersions,
2578
+ Ee as createPostEvent,
2579
+ cr as getHash,
2580
+ ar as init,
2581
+ gt as initDataParser,
2582
+ lt as isColorDark,
2583
+ Ct as isIframe,
2584
+ ut as isRGB,
2585
+ Nt as isRGBShort,
2586
+ D as isRecord,
2587
+ er as isTMA,
2588
+ bt as launchParamsParser,
2589
+ or as mergeClassNames,
2590
+ N as off,
2591
+ k as on,
2592
+ sr as once,
2593
+ Xe as parseInitData,
2594
+ mt as parseLaunchParams,
2595
+ _t as parseThemeParams,
2596
+ f as postEvent,
2597
+ _ as request,
2598
+ tr as requestThemeParams,
2599
+ Pt as requestViewport,
2600
+ Et as retrieveLaunchData,
2601
+ Kt as serializeLaunchParams,
2602
+ Ft as serializeThemeParams,
2603
+ rr as setDebug,
2604
+ nr as setTargetOrigin,
2605
+ ir as subscribe,
2606
+ q as supports,
2607
+ wt as themeParamsParser,
2608
+ pt as toRGB,
2609
+ me as unsubscribe,
2610
+ tt as userParser
1384
2611
  };
1385
2612
  //# sourceMappingURL=index.mjs.map