@tma.js/sdk 1.0.2 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/dist/dts/bridge/events/parsers/phoneRequested.d.ts +1 -1
  2. package/dist/dts/bridge/index.d.ts +1 -0
  3. package/dist/dts/bridge/invoke-custom-method.d.ts +18 -0
  4. package/dist/dts/bridge/methods/custom-methods.d.ts +56 -0
  5. package/dist/dts/bridge/methods/index.d.ts +1 -1
  6. package/dist/dts/bridge/methods/methods.d.ts +1 -1
  7. package/dist/dts/bridge/request.d.ts +3 -12
  8. package/dist/dts/cloud-storage/CloudStorage.d.ts +7 -16
  9. package/dist/dts/index.d.ts +8 -6
  10. package/dist/dts/init/creators/createMiniApp.d.ts +3 -1
  11. package/dist/dts/init/creators/createSettingsButton.d.ts +10 -0
  12. package/dist/dts/init/creators/index.d.ts +1 -0
  13. package/dist/dts/init/init.d.ts +1 -0
  14. package/dist/dts/init/types.d.ts +2 -0
  15. package/dist/dts/mini-app/MiniApp.d.ts +34 -4
  16. package/dist/dts/mini-app/contactParser.d.ts +2 -0
  17. package/dist/dts/mini-app/types.d.ts +12 -0
  18. package/dist/dts/settings-button/SettingsButton.d.ts +42 -0
  19. package/dist/dts/settings-button/index.d.ts +2 -0
  20. package/dist/dts/settings-button/types.d.ts +10 -0
  21. package/dist/dts/storage.d.ts +3 -0
  22. package/dist/dts/timeout/index.d.ts +1 -0
  23. package/dist/dts/timeout/sleep.d.ts +5 -0
  24. package/dist/dts/timeout/withTimeout.d.ts +5 -12
  25. package/dist/dts/types/index.d.ts +1 -0
  26. package/dist/dts/types/methods.d.ts +15 -0
  27. package/dist/index.cjs +1 -1
  28. package/dist/index.cjs.map +1 -1
  29. package/dist/index.iife.js +1 -1
  30. package/dist/index.iife.js.map +1 -1
  31. package/dist/index.mjs +854 -670
  32. package/dist/index.mjs.map +1 -1
  33. package/package.json +1 -1
  34. package/src/bridge/events/parsers/phoneRequested.ts +1 -1
  35. package/src/bridge/index.ts +1 -0
  36. package/src/bridge/invoke-custom-method.ts +56 -0
  37. package/src/bridge/methods/custom-methods.ts +68 -0
  38. package/src/bridge/methods/index.ts +1 -1
  39. package/src/bridge/methods/methods.ts +3 -5
  40. package/src/bridge/request.ts +35 -44
  41. package/src/cloud-storage/CloudStorage.ts +36 -53
  42. package/src/index.ts +14 -20
  43. package/src/init/creators/createMiniApp.ts +4 -0
  44. package/src/init/creators/createSettingsButton.ts +25 -0
  45. package/src/init/creators/createViewport.ts +16 -5
  46. package/src/init/creators/index.ts +1 -0
  47. package/src/init/init.ts +9 -5
  48. package/src/init/types.ts +2 -0
  49. package/src/mini-app/MiniApp.ts +131 -20
  50. package/src/mini-app/contactParser.ts +29 -0
  51. package/src/mini-app/types.ts +13 -0
  52. package/src/settings-button/SettingsButton.ts +85 -0
  53. package/src/settings-button/index.ts +2 -0
  54. package/src/settings-button/types.ts +15 -0
  55. package/src/storage.ts +3 -0
  56. package/src/timeout/index.ts +1 -0
  57. package/src/timeout/sleep.ts +10 -0
  58. package/src/timeout/withTimeout.ts +10 -22
  59. package/src/types/index.ts +1 -0
  60. package/src/types/methods.ts +18 -0
  61. package/dist/dts/bridge/methods/invoke-custom-method.d.ts +0 -24
  62. package/src/bridge/methods/invoke-custom-method.ts +0 -25
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tma.js/sdk",
3
- "version": "1.0.2",
3
+ "version": "1.2.0",
4
4
  "description": "TypeScript Source Development Kit for Telegram Mini Apps client application.",
5
5
  "author": "Vladislav Kibenko <wolfram.deus@gmail.com>",
6
6
  "homepage": "https://github.com/Telegram-Mini-Apps/tma.js#readme",
@@ -1,6 +1,6 @@
1
1
  import { json, string } from '~/parsing/index.js';
2
2
 
3
- export type PhoneRequestedStatus = 'sent' | string;
3
+ export type PhoneRequestedStatus = 'sent' | 'cancelled' | string;
4
4
 
5
5
  export interface PhoneRequestedPayload {
6
6
  /**
@@ -2,4 +2,5 @@ export * from './env/index.js';
2
2
  export * from './errors/index.js';
3
3
  export * from './events/index.js';
4
4
  export * from './methods/index.js';
5
+ export * from './invoke-custom-method.js';
5
6
  export * from './request.js';
@@ -0,0 +1,56 @@
1
+ import type { ExecuteWithOptions } from '~/types/index.js';
2
+
3
+ import type { CustomMethodName, CustomMethodParams } from './methods/index.js';
4
+ import { request } from './request.js';
5
+
6
+ /**
7
+ * Invokes known custom method. Returns method execution result.
8
+ * @param method - method name.
9
+ * @param params - method parameters.
10
+ * @param requestId - request identifier.
11
+ * @param options - additional options.
12
+ */
13
+ export async function invokeCustomMethod<M extends CustomMethodName>(
14
+ method: M,
15
+ params: CustomMethodParams<M>,
16
+ requestId: string,
17
+ options?: ExecuteWithOptions,
18
+ ): Promise<unknown>;
19
+
20
+ /**
21
+ * Invokes unknown custom method. Returns method execution result.
22
+ * @param method - method name.
23
+ * @param params - method parameters.
24
+ * @param requestId - request identifier.
25
+ * @param options - additional options.
26
+ */
27
+ export function invokeCustomMethod(
28
+ method: string,
29
+ params: object,
30
+ requestId: string,
31
+ options?: ExecuteWithOptions,
32
+ ): Promise<unknown>;
33
+
34
+ export async function invokeCustomMethod(
35
+ method: string,
36
+ params: object,
37
+ requestId: string,
38
+ options: ExecuteWithOptions = {},
39
+ ): Promise<unknown> {
40
+ const { result, error } = await request(
41
+ 'web_app_invoke_custom_method',
42
+ {
43
+ method,
44
+ params,
45
+ req_id: requestId,
46
+ },
47
+ 'custom_method_invoked',
48
+ options,
49
+ );
50
+
51
+ if (error) {
52
+ throw new Error(error);
53
+ }
54
+
55
+ return result;
56
+ }
@@ -0,0 +1,68 @@
1
+ import type { RequestId } from '~/types/index.js';
2
+
3
+ interface CreateInvokeCustomMethodParams<M extends string, Params extends object> {
4
+ /**
5
+ * Unique request identifier.
6
+ */
7
+ req_id: RequestId;
8
+
9
+ /**
10
+ * Method name.
11
+ */
12
+ method: M;
13
+
14
+ /**
15
+ * Method specific parameters.
16
+ */
17
+ params: Params;
18
+ }
19
+
20
+ export interface CustomMethodsParams {
21
+ /**
22
+ * Deletes storage values by their keys.
23
+ */
24
+ deleteStorageValues: {
25
+ keys: string | string[]
26
+ };
27
+
28
+ /**
29
+ * Gets current user contact in case, Mini has access to it.
30
+ */
31
+ getRequestedContact: {};
32
+
33
+ /**
34
+ * Gets all registered storage keys.
35
+ */
36
+ getStorageKeys: {};
37
+
38
+ /**
39
+ * Gets storage values by their keys.
40
+ */
41
+ getStorageValues: {
42
+ keys: string | string[]
43
+ };
44
+
45
+ /**
46
+ * Saves value by specified key in the storage.
47
+ */
48
+ saveStorageValue: {
49
+ key: string;
50
+ value: string;
51
+ };
52
+ }
53
+
54
+ /**
55
+ * Known custom method name.
56
+ */
57
+ export type CustomMethodName = keyof CustomMethodsParams;
58
+
59
+ /**
60
+ * Custom method parameters.
61
+ */
62
+ export type CustomMethodParams<M extends CustomMethodName> = CustomMethodsParams[M];
63
+
64
+ export type AnyInvokeCustomMethodParams =
65
+ | CreateInvokeCustomMethodParams<string, any>
66
+ | {
67
+ [M in CustomMethodName]: CreateInvokeCustomMethodParams<M, CustomMethodParams<M>>
68
+ }[CustomMethodName];
@@ -1,6 +1,6 @@
1
1
  export * from './createPostEvent.js';
2
+ export * from './custom-methods.js';
2
3
  export * from './haptic.js';
3
- export * from './invoke-custom-method.js';
4
4
  export * from './methods.js';
5
5
  export * from './popup.js';
6
6
  export * from './postEvent.js';
@@ -1,8 +1,8 @@
1
1
  import type { RGB } from '~/colors/index.js';
2
2
  import type { IsNever, Not, RequestId, UnionKeys } from '~/types/index.js';
3
3
 
4
+ import type { AnyInvokeCustomMethodParams } from './custom-methods.js';
4
5
  import type { AnyHapticFeedbackParams } from './haptic.js';
5
- import type { AnyInvokeCustomMethodParams } from './invoke-custom-method.js';
6
6
  import type { PopupParams } from './popup.js';
7
7
 
8
8
  /**
@@ -78,7 +78,6 @@ export interface MiniAppsMethods {
78
78
  */
79
79
  web_app_expand: CreateParams;
80
80
 
81
- // TODO: 'getRequestedContact'. https://telegram.org/js/telegram-web-app.js
82
81
  /**
83
82
  * Invokes custom method.
84
83
  * @since v6.9
@@ -173,7 +172,6 @@ export interface MiniAppsMethods {
173
172
  */
174
173
  web_app_ready: CreateParams;
175
174
 
176
- // TODO: Check if it is right. It probably requests other user phone.
177
175
  /**
178
176
  * Requests access to current user's phone.
179
177
  * @since v6.9
@@ -219,13 +217,13 @@ export interface MiniAppsMethods {
219
217
  * @see https://docs.telegram-mini-apps.com/platform/apps-communication/methods#web-app-set-header-color
220
218
  */
221
219
  web_app_set_header_color: CreateParams<
222
- | {
220
+ | {
223
221
  /**
224
222
  * The Mini App header color key.
225
223
  */
226
224
  color_key: HeaderColorKey
227
225
  }
228
- | {
226
+ | {
229
227
  /**
230
228
  * Color in RGB format.
231
229
  * @since v6.9
@@ -1,6 +1,6 @@
1
1
  import { isRecord } from '~/misc/index.js';
2
2
  import { withTimeout } from '~/timeout/index.js';
3
- import type { And, If, IsNever } from '~/types/index.js';
3
+ import type { And, ExecuteWithOptions, If, IsNever } from '~/types/index.js';
4
4
 
5
5
  import {
6
6
  type MiniAppsEventHasParams,
@@ -14,7 +14,6 @@ import {
14
14
  type MiniAppsMethodName,
15
15
  type MiniAppsMethodParams,
16
16
  type MiniAppsNonEmptyMethodName,
17
- type PostEvent,
18
17
  postEvent as defaultPostEvent,
19
18
  } from './methods/index.js';
20
19
 
@@ -45,17 +44,7 @@ type EventWithRequestId = {
45
44
  >;
46
45
  }[MiniAppsEventName];
47
46
 
48
- export interface RequestOptions {
49
- /**
50
- * Bridge postEvent method.
51
- * @default Global postEvent method.
52
- */
53
- postEvent?: PostEvent;
54
-
55
- /**
56
- * Execution timeout.
57
- */
58
- timeout?: number;
47
+ export interface RequestOptions extends ExecuteWithOptions {
59
48
  }
60
49
 
61
50
  export interface RequestOptionsAdvanced<EventPayload> extends RequestOptions {
@@ -149,37 +138,39 @@ export function request(
149
138
  ? executionOptions.capture
150
139
  : null;
151
140
 
152
- const promise = new Promise((res, rej) => {
153
- // Iterate over each event and create event listener.
154
- const stoppers = events.map((ev) => on(ev, (data?) => {
155
- // If request identifier was specified, we are waiting for event with the same value
156
- // to occur.
157
- if (typeof requestId === 'string' && (!isRecord(data) || data.req_id !== requestId)) {
158
- return;
159
- }
160
-
161
- if (typeof capture === 'function' && !capture(data)) {
162
- return;
141
+ const execute = () => {
142
+ return new Promise((res, rej) => {
143
+ // Iterate over each event and create event listener.
144
+ const stoppers = events.map((ev) => on(ev, (data?) => {
145
+ // If request identifier was specified, we are waiting for event with the same value
146
+ // to occur.
147
+ if (requestId && (!isRecord(data) || data.req_id !== requestId)) {
148
+ return;
149
+ }
150
+
151
+ if (typeof capture === 'function' && !capture(data)) {
152
+ return;
153
+ }
154
+
155
+ // eslint-disable-next-line @typescript-eslint/no-use-before-define
156
+ stopListening();
157
+ res(data);
158
+ }));
159
+
160
+ // Function which removes all event listeners.
161
+ const stopListening = () => stoppers.forEach((stop) => stop());
162
+
163
+ try {
164
+ // We are wrapping this call in try catch, because it can throw errors in case,
165
+ // compatibility check was enabled. We want an error to be captured by promise, not by
166
+ // another one external try catch.
167
+ postEvent(method as any, methodParams);
168
+ } catch (e) {
169
+ stopListening();
170
+ rej(e);
163
171
  }
172
+ });
173
+ };
164
174
 
165
- // eslint-disable-next-line @typescript-eslint/no-use-before-define
166
- stopListening();
167
- res(data);
168
- }));
169
-
170
- // Function which removes all event listeners.
171
- const stopListening = () => stoppers.forEach((stop) => stop());
172
-
173
- try {
174
- // We are wrapping this call in try catch, because it can throw errors in case,
175
- // compatibility check was enabled. We want an error to be captured by promise, not by
176
- // another one external try catch.
177
- postEvent(method as any, methodParams);
178
- } catch (e) {
179
- stopListening();
180
- rej(e);
181
- }
182
- });
183
-
184
- return typeof timeout === 'number' ? withTimeout(promise, timeout) : promise;
175
+ return typeof timeout === 'number' ? withTimeout(execute, timeout) : execute();
185
176
  }
@@ -1,7 +1,6 @@
1
1
  import {
2
+ invokeCustomMethod,
2
3
  postEvent as defaultPostEvent,
3
- request,
4
- type RequestOptions,
5
4
  } from '~/bridge/index.js';
6
5
  import {
7
6
  array,
@@ -12,18 +11,9 @@ import {
12
11
  createSupportsFunc,
13
12
  type SupportsFunc,
14
13
  } from '~/supports/index.js';
15
- import type { CreateRequestIdFunc } from '~/types/index.js';
14
+ import type { CreateRequestIdFunc, ExecuteWithTimeout } from '~/types/index.js';
16
15
  import type { Version } from '~/version/index.js';
17
16
 
18
- type WiredRequestOptions = Omit<RequestOptions, 'postEvent'>;
19
-
20
- interface Methods {
21
- deleteStorageValues: { keys: string | string[] };
22
- getStorageValues: { keys: string | string[] };
23
- getStorageKeys: {};
24
- saveStorageValue: { key: string; value: string };
25
- }
26
-
27
17
  function objectFromKeys<K extends string, V>(keys: K[], value: V): Record<K, V> {
28
18
  return keys.reduce<Record<K, V>>((acc, key) => {
29
19
  acc[key] = value;
@@ -45,51 +35,36 @@ export class CloudStorage {
45
35
  });
46
36
  }
47
37
 
48
- /**
49
- * Invokes custom method related to CloudStorage.
50
- * @param method - method name.
51
- * @param params - method parameters.
52
- * @param options - execution options.
53
- */
54
- private async invokeCustomMethod<M extends keyof Methods>(
55
- method: M,
56
- params: Methods[M],
57
- options: WiredRequestOptions = {},
58
- ): Promise<unknown> {
59
- const { result, error } = await request(
60
- 'web_app_invoke_custom_method',
61
- { method, params, req_id: this.createRequestId() },
62
- 'custom_method_invoked',
63
- { ...options, postEvent: this.postEvent },
64
- );
65
-
66
- if (error) {
67
- throw new Error(error);
68
- }
69
-
70
- return result;
71
- }
72
-
73
38
  /**
74
39
  * Deletes specified key or keys from the cloud storage.
75
40
  * @param keyOrKeys - key or keys to delete.
76
41
  * @param options - request execution options.
77
42
  */
78
- async delete(keyOrKeys: string | string[], options?: WiredRequestOptions): Promise<void> {
43
+ async delete(keyOrKeys: string | string[], options: ExecuteWithTimeout = {}): Promise<void> {
79
44
  const keys = Array.isArray(keyOrKeys) ? keyOrKeys : [keyOrKeys];
80
45
  if (keys.length === 0) {
81
46
  return;
82
47
  }
83
48
 
84
- await this.invokeCustomMethod('deleteStorageValues', { keys }, options);
49
+ await invokeCustomMethod(
50
+ 'deleteStorageValues',
51
+ { keys },
52
+ this.createRequestId(),
53
+ { ...options, postEvent: this.postEvent },
54
+ );
85
55
  }
86
56
 
87
57
  /**
88
58
  * Returns list of all keys presented in the cloud storage.
89
59
  * @param options - request execution options.
90
60
  */
91
- async getKeys(options?: WiredRequestOptions): Promise<string[]> {
92
- const result = await this.invokeCustomMethod('getStorageKeys', {}, options);
61
+ async getKeys(options: ExecuteWithTimeout = {}): Promise<string[]> {
62
+ const result = await invokeCustomMethod(
63
+ 'getStorageKeys',
64
+ {},
65
+ this.createRequestId(),
66
+ { ...options, postEvent: this.postEvent },
67
+ );
93
68
 
94
69
  return array().of(string()).parse(result);
95
70
  }
@@ -102,7 +77,7 @@ export class CloudStorage {
102
77
  */
103
78
  get<K extends string>(
104
79
  keys: K[],
105
- options?: WiredRequestOptions,
80
+ options?: ExecuteWithTimeout,
106
81
  ): Promise<Record<K, string>>;
107
82
 
108
83
  /**
@@ -112,11 +87,11 @@ export class CloudStorage {
112
87
  * @return Value of the specified key. In case, key was not created previously, function
113
88
  * will return empty string.
114
89
  */
115
- get(key: string, options?: WiredRequestOptions): Promise<string>;
90
+ get(key: string, options?: ExecuteWithTimeout): Promise<string>;
116
91
 
117
92
  async get(
118
93
  keyOrKeys: string | string[],
119
- options?: WiredRequestOptions,
94
+ options: ExecuteWithTimeout = {},
120
95
  ): Promise<string | Record<string, string>> {
121
96
  const keys = Array.isArray(keyOrKeys) ? keyOrKeys : [keyOrKeys];
122
97
  if (keys.length === 0) {
@@ -126,9 +101,12 @@ export class CloudStorage {
126
101
  const schema = json(
127
102
  objectFromKeys(keys, string()),
128
103
  );
129
- const result = await this
130
- .invokeCustomMethod('getStorageValues', { keys }, options)
131
- .then((data) => schema.parse(data));
104
+ const result = await invokeCustomMethod(
105
+ 'getStorageValues',
106
+ { keys },
107
+ this.createRequestId(),
108
+ { ...options, postEvent: this.postEvent },
109
+ ).then((data) => schema.parse(data));
132
110
 
133
111
  return Array.isArray(keyOrKeys) ? result : result[keyOrKeys];
134
112
  }
@@ -139,17 +117,22 @@ export class CloudStorage {
139
117
  * @param value - storage value.
140
118
  * @param options - request execution options.
141
119
  */
142
- async set(key: string, value: string, options?: WiredRequestOptions): Promise<void> {
143
- await this.invokeCustomMethod('saveStorageValue', { key, value }, options);
120
+ async set(key: string, value: string, options: ExecuteWithTimeout = {}): Promise<void> {
121
+ await invokeCustomMethod(
122
+ 'saveStorageValue',
123
+ { key, value },
124
+ this.createRequestId(),
125
+ { ...options, postEvent: this.postEvent },
126
+ );
144
127
  }
145
128
 
146
129
  /**
147
130
  * Checks if specified method is supported by current component.
148
131
  */
149
132
  supports: SupportsFunc<
150
- | 'delete'
151
- | 'get'
152
- | 'getKeys'
153
- | 'set'
133
+ | 'delete'
134
+ | 'get'
135
+ | 'getKeys'
136
+ | 'set'
154
137
  >;
155
138
  }
package/src/index.ts CHANGED
@@ -6,6 +6,7 @@ export {
6
6
  export {
7
7
  createPostEvent,
8
8
  isIframe,
9
+ invokeCustomMethod,
9
10
  on,
10
11
  off,
11
12
  once,
@@ -35,13 +36,11 @@ export {
35
36
  type PhoneRequestedStatus,
36
37
  type PostEvent,
37
38
  type RequestOptions,
39
+ type RequestOptionsAdvanced,
38
40
  type SwitchInlineQueryChatType,
39
41
  type WriteAccessRequestedStatus,
40
42
  } from './bridge/index.js';
41
- export {
42
- classNames,
43
- mergeClassNames,
44
- } from './classnames/index.js';
43
+ export { classNames, mergeClassNames } from './classnames/index.js';
45
44
  export {
46
45
  ClosingBehavior,
47
46
  type ClosingBehaviorEventListener,
@@ -104,10 +103,7 @@ export {
104
103
  type MiniAppEvents,
105
104
  type MiniAppProps,
106
105
  } from './mini-app/index.js';
107
- export {
108
- isTMA,
109
- isRecord,
110
- } from './misc/index.js';
106
+ export { isTMA, isRecord } from './misc/index.js';
111
107
  export {
112
108
  getHash,
113
109
  HashNavigator,
@@ -134,6 +130,12 @@ export {
134
130
  type QRScannerEventName,
135
131
  type QRScannerEvents,
136
132
  } from './qr-scanner/index.js';
133
+ export {
134
+ SettingsButton,
135
+ type SettingsButtonEventName,
136
+ type SettingsButtonEventListener,
137
+ type SettingsButtonEvents,
138
+ } from './settings-button/index.js';
137
139
  export { supports } from './supports/index.js';
138
140
  export {
139
141
  parseThemeParams,
@@ -147,15 +149,10 @@ export {
147
149
  type ThemeParamsKey,
148
150
  type ThemeParamsParsed,
149
151
  } from './theme-params/index.js';
150
- export type {
151
- RequestId,
152
- CreateRequestIdFunc,
153
- } from './types/index.js';
152
+ export { withTimeout, TimeoutError, isTimeoutError } from './timeout/index.js';
153
+ export type { RequestId, CreateRequestIdFunc } from './types/index.js';
154
154
  export { Utils } from './utils/index.js';
155
- export {
156
- compareVersions,
157
- type Version,
158
- } from './version/index.js';
155
+ export { compareVersions, type Version } from './version/index.js';
159
156
  export {
160
157
  requestViewport,
161
158
  Viewport,
@@ -165,7 +162,4 @@ export {
165
162
  type ViewportEventListener,
166
163
  type ViewportEvents,
167
164
  } from './viewport/index.js';
168
- export {
169
- setTargetOrigin,
170
- setDebug,
171
- } from './globals.js';
165
+ export { setTargetOrigin, setDebug } from './globals.js';
@@ -2,6 +2,7 @@ import { MiniApp } from '~/mini-app/index.js';
2
2
  import { getStorageValue, saveStorageValue } from '~/storage.js';
3
3
  import type { PostEvent } from '~/bridge/index.js';
4
4
  import type { RGB } from '~/colors/index.js';
5
+ import type { CreateRequestIdFunc } from '~/types/index.js';
5
6
  import type { Version } from '~/version/index.js';
6
7
 
7
8
  /**
@@ -11,6 +12,7 @@ import type { Version } from '~/version/index.js';
11
12
  * @param backgroundColor - web app background color.
12
13
  * @param version - platform version.
13
14
  * @param botInline - is Mini App launched in inline mode.
15
+ * @param createRequestId - function which generates request identifiers.
14
16
  * @param postEvent - Bridge postEvent function
15
17
  */
16
18
  export function createMiniApp(
@@ -18,6 +20,7 @@ export function createMiniApp(
18
20
  backgroundColor: RGB,
19
21
  version: Version,
20
22
  botInline: boolean,
23
+ createRequestId: CreateRequestIdFunc,
21
24
  postEvent: PostEvent,
22
25
  ): MiniApp {
23
26
  const {
@@ -30,6 +33,7 @@ export function createMiniApp(
30
33
  backgroundColor: stateBackgroundColor,
31
34
  version,
32
35
  botInline,
36
+ createRequestId,
33
37
  postEvent,
34
38
  });
35
39
 
@@ -0,0 +1,25 @@
1
+ import { SettingsButton } from '~/settings-button/index.js';
2
+ import { getStorageValue, saveStorageValue } from '~/storage.js';
3
+ import type { PostEvent } from '~/bridge/index.js';
4
+
5
+ /**
6
+ * Creates SettingsButton instance using last locally saved data also saving each state in
7
+ * the storage.
8
+ * @param isPageReload - was current page reloaded.
9
+ * @param version - platform version.
10
+ * @param postEvent - Bridge postEvent function
11
+ */
12
+ export function createSettingsButton(
13
+ isPageReload: boolean,
14
+ version: string,
15
+ postEvent: PostEvent,
16
+ ): SettingsButton {
17
+ const { isVisible = false } = isPageReload ? getStorageValue('settings-button') || {} : {};
18
+ const component = new SettingsButton(isVisible, version, postEvent);
19
+
20
+ component.on('change', () => {
21
+ saveStorageValue('settings-button', { isVisible: component.isVisible });
22
+ });
23
+
24
+ return component;
25
+ }
@@ -3,6 +3,15 @@ import { requestViewport, Viewport } from '~/viewport/index.js';
3
3
  import type { PostEvent } from '~/bridge/index.js';
4
4
  import type { Platform } from '~/types/index.js';
5
5
 
6
+ /**
7
+ * Returns true in case, specified platform supports calling Mini Apps
8
+ * "web_app_request_viewport" method.
9
+ * @param platform - platform identifier.
10
+ */
11
+ function isRequestSupportedPlatform(platform: Platform): boolean {
12
+ return !['macos', 'web', 'weba'].includes(platform);
13
+ }
14
+
6
15
  /**
7
16
  * Attempts to create Viewport instance using known parameters and local storage.
8
17
  * @param isPageReload - was page reloaded.
@@ -14,7 +23,7 @@ function tryCreate(
14
23
  platform: Platform,
15
24
  postEvent: PostEvent,
16
25
  ): Viewport | null {
17
- if (isPageReload || platform === 'macos' || platform === 'web' || platform === 'weba') {
26
+ if (isPageReload || !isRequestSupportedPlatform(platform)) {
18
27
  return new Viewport({
19
28
  height: window.innerHeight,
20
29
  isExpanded: true,
@@ -73,10 +82,12 @@ export function createViewportSync(
73
82
  }),
74
83
  );
75
84
 
76
- viewport.sync({ postEvent, timeout: 100 }).catch((e) => {
77
- // eslint-disable-next-line no-console
78
- console.error('Unable to actualize viewport state', e);
79
- });
85
+ if (isRequestSupportedPlatform(platform)) {
86
+ viewport.sync({ postEvent, timeout: 100 }).catch((e) => {
87
+ // eslint-disable-next-line no-console
88
+ console.error('Unable to actualize viewport state', e);
89
+ });
90
+ }
80
91
 
81
92
  return viewport;
82
93
  }
@@ -3,5 +3,6 @@ export * from './createClosingBehavior.js';
3
3
  export * from './createMainButton.js';
4
4
  export * from './createMiniApp.js';
5
5
  export * from './createRequestIdGenerator.js';
6
+ export * from './createSettingsButton.js';
6
7
  export * from './createThemeParams.js';
7
8
  export * from './createViewport.js';