@alfalab/bridge-to-native 1.5.0 → 1.5.1-beta.50a07d1

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.
@@ -1,5 +1,5 @@
1
1
 
2
- import { type BrowserHistoryApiWrappers, type HistoryPushStateParams, type HistoryReplaceStateParams, type LocationAssignParam, type LogError, type NativeFeatureKey, type PdfType } from './types';
2
+ import { type BrowserHistoryApiWrappers, type HistoryPushStateParams, type HistoryReplaceStateParams, type LocationAssignParam, type LogError, type NativeFeatureKey, type NoopOptions, type PdfType } from './types';
3
3
  /**
4
4
  * Сервис, предоставляет методы для WA, работающего внутри NA.
5
5
  */
@@ -13,12 +13,15 @@ export declare class BridgeToNative {
13
13
  * будут использованы стандартные `History: pushState()` и `History: go()`.
14
14
  * @param options.logError Функция с помощью которой B2N может залогировать ошибку,
15
15
  * если не передать, B2N не будет логировать ошибки.
16
+ * @param options.noop ....
16
17
  */
17
18
  constructor(options?: {
18
19
  browserHistoryApiWrappers?: BrowserHistoryApiWrappers;
19
20
  logError?: LogError;
21
+ noop?: NoopOptions;
20
22
  } | undefined);
21
23
  private nativeParamsService;
24
+ private nativeLogService;
22
25
  private externalLinksService;
23
26
  private nativeNavigationAndTitleService;
24
27
  /**
@@ -3,6 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  exports.BridgeToNative = void 0;
5
5
  const external_links_service_1 = require("./services-and-utils/external-links-service");
6
+ const native_log_service_1 = require("./services-and-utils/native-log-service");
6
7
  const native_navigation_and_title_service_1 = require("./services-and-utils/native-navigation-and-title-service");
7
8
  const native_params_service_1 = require("./services-and-utils/native-params-service");
8
9
  /**
@@ -17,13 +18,15 @@ class BridgeToNative {
17
18
  * будут использованы стандартные `History: pushState()` и `History: go()`.
18
19
  * @param options.logError Функция с помощью которой B2N может залогировать ошибку,
19
20
  * если не передать, B2N не будет логировать ошибки.
21
+ * @param options.noop ....
20
22
  */
21
23
  constructor(options) {
22
- var _a, _b, _c, _d;
24
+ var _a, _b, _c, _d, _e, _f, _g;
23
25
  this.options = options;
24
- this.nativeParamsService = new native_params_service_1.NativeParamsService((_a = this.options) === null || _a === void 0 ? void 0 : _a.logError);
25
- this.externalLinksService = new external_links_service_1.ExternalLinksService(this.nativeParamsService, (_b = this.options) === null || _b === void 0 ? void 0 : _b.logError);
26
- this.nativeNavigationAndTitleService = new native_navigation_and_title_service_1.NativeNavigationAndTitleService(this.nativeParamsService, (_c = this.options) === null || _c === void 0 ? void 0 : _c.browserHistoryApiWrappers, (_d = this.options) === null || _d === void 0 ? void 0 : _d.logError);
26
+ this.nativeParamsService = new native_params_service_1.NativeParamsService((_a = this.options) === null || _a === void 0 ? void 0 : _a.noop, (_b = this.options) === null || _b === void 0 ? void 0 : _b.logError);
27
+ this.nativeLogService = new native_log_service_1.NativeLogService(this.nativeParamsService.environment, this.nativeParamsService.appVersion, (_d = (_c = this.options) === null || _c === void 0 ? void 0 : _c.noop) === null || _d === void 0 ? void 0 : _d.enabled);
28
+ this.externalLinksService = new external_links_service_1.ExternalLinksService(this.nativeParamsService, this.nativeLogService, (_e = this.options) === null || _e === void 0 ? void 0 : _e.logError);
29
+ this.nativeNavigationAndTitleService = new native_navigation_and_title_service_1.NativeNavigationAndTitleService(this.nativeParamsService, this.nativeLogService, (_f = this.options) === null || _f === void 0 ? void 0 : _f.browserHistoryApiWrappers, (_g = this.options) === null || _g === void 0 ? void 0 : _g.logError);
27
30
  }
28
31
  /**
29
32
  * Схема NA.
package/client/index.d.ts CHANGED
@@ -1,4 +1,3 @@
1
1
  export { BridgeToNative } from './bridge-to-native';
2
- export { canUseNativeFeature } from './services-and-utils/native-features';
3
- export { prepareNativeDeeplinkUrl, prepareOpenInBrowserUrl, prepareOpenInNewWebviewDeeplink, preparePdfUrl, } from './services-and-utils/native-links';
2
+ export { canUseNativeFeature, isVersionHigherOrEqual, prepareNativeDeeplinkUrl, prepareOpenInBrowserUrl, prepareOpenInNewWebviewDeeplink, preparePdfUrl, } from './primitives';
4
3
  export type { Environment, NativeAppTarget, NativeFeatureKey, PdfType } from './types';
package/client/index.js CHANGED
@@ -1,12 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.preparePdfUrl = exports.prepareOpenInNewWebviewDeeplink = exports.prepareOpenInBrowserUrl = exports.prepareNativeDeeplinkUrl = exports.canUseNativeFeature = exports.BridgeToNative = void 0;
3
+ exports.preparePdfUrl = exports.prepareOpenInNewWebviewDeeplink = exports.prepareOpenInBrowserUrl = exports.prepareNativeDeeplinkUrl = exports.isVersionHigherOrEqual = exports.canUseNativeFeature = exports.BridgeToNative = void 0;
4
4
  var bridge_to_native_1 = require("./bridge-to-native");
5
5
  Object.defineProperty(exports, "BridgeToNative", { enumerable: true, get: function () { return bridge_to_native_1.BridgeToNative; } });
6
- var native_features_1 = require("./services-and-utils/native-features");
7
- Object.defineProperty(exports, "canUseNativeFeature", { enumerable: true, get: function () { return native_features_1.canUseNativeFeature; } });
8
- var native_links_1 = require("./services-and-utils/native-links");
9
- Object.defineProperty(exports, "prepareNativeDeeplinkUrl", { enumerable: true, get: function () { return native_links_1.prepareNativeDeeplinkUrl; } });
10
- Object.defineProperty(exports, "prepareOpenInBrowserUrl", { enumerable: true, get: function () { return native_links_1.prepareOpenInBrowserUrl; } });
11
- Object.defineProperty(exports, "prepareOpenInNewWebviewDeeplink", { enumerable: true, get: function () { return native_links_1.prepareOpenInNewWebviewDeeplink; } });
12
- Object.defineProperty(exports, "preparePdfUrl", { enumerable: true, get: function () { return native_links_1.preparePdfUrl; } });
6
+ var primitives_1 = require("./primitives");
7
+ Object.defineProperty(exports, "canUseNativeFeature", { enumerable: true, get: function () { return primitives_1.canUseNativeFeature; } });
8
+ Object.defineProperty(exports, "isVersionHigherOrEqual", { enumerable: true, get: function () { return primitives_1.isVersionHigherOrEqual; } });
9
+ Object.defineProperty(exports, "prepareNativeDeeplinkUrl", { enumerable: true, get: function () { return primitives_1.prepareNativeDeeplinkUrl; } });
10
+ Object.defineProperty(exports, "prepareOpenInBrowserUrl", { enumerable: true, get: function () { return primitives_1.prepareOpenInBrowserUrl; } });
11
+ Object.defineProperty(exports, "prepareOpenInNewWebviewDeeplink", { enumerable: true, get: function () { return primitives_1.prepareOpenInNewWebviewDeeplink; } });
12
+ Object.defineProperty(exports, "preparePdfUrl", { enumerable: true, get: function () { return primitives_1.preparePdfUrl; } });
@@ -0,0 +1,3 @@
1
+ export { canUseNativeFeature, isVersionHigherOrEqual } from './services-and-utils/native-features';
2
+ export { prepareNativeDeeplinkUrl, prepareOpenInBrowserUrl, prepareOpenInNewWebviewDeeplink, preparePdfUrl, } from './services-and-utils/native-links';
3
+ export type { Environment, NativeAppTarget, NativeFeatureKey, PdfType } from './types';
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.preparePdfUrl = exports.prepareOpenInNewWebviewDeeplink = exports.prepareOpenInBrowserUrl = exports.prepareNativeDeeplinkUrl = exports.isVersionHigherOrEqual = exports.canUseNativeFeature = void 0;
4
+ var native_features_1 = require("./services-and-utils/native-features");
5
+ Object.defineProperty(exports, "canUseNativeFeature", { enumerable: true, get: function () { return native_features_1.canUseNativeFeature; } });
6
+ Object.defineProperty(exports, "isVersionHigherOrEqual", { enumerable: true, get: function () { return native_features_1.isVersionHigherOrEqual; } });
7
+ var native_links_1 = require("./services-and-utils/native-links");
8
+ Object.defineProperty(exports, "prepareNativeDeeplinkUrl", { enumerable: true, get: function () { return native_links_1.prepareNativeDeeplinkUrl; } });
9
+ Object.defineProperty(exports, "prepareOpenInBrowserUrl", { enumerable: true, get: function () { return native_links_1.prepareOpenInBrowserUrl; } });
10
+ Object.defineProperty(exports, "prepareOpenInNewWebviewDeeplink", { enumerable: true, get: function () { return native_links_1.prepareOpenInNewWebviewDeeplink; } });
11
+ Object.defineProperty(exports, "preparePdfUrl", { enumerable: true, get: function () { return native_links_1.preparePdfUrl; } });
@@ -1,4 +1,5 @@
1
1
  import { type LogError, type PdfType } from '../types';
2
+ import { type NativeLogService } from './native-log-service';
2
3
  import { type NativeParamsService } from './native-params-service';
3
4
  /**
4
5
  * Сервис, предоставляющий методы для открытия внешних для текущего WA экранов
@@ -6,9 +7,10 @@ import { type NativeParamsService } from './native-params-service';
6
7
  */
7
8
  export declare class ExternalLinksService {
8
9
  private nativeParamsService;
10
+ private nativeLogService;
9
11
  private logError?;
10
12
  private navigationByNativeAppInProgress;
11
- constructor(nativeParamsService: NativeParamsService, logError?: LogError | undefined);
13
+ constructor(nativeParamsService: NativeParamsService, nativeLogService: NativeLogService, logError?: LogError | undefined);
12
14
  handleNativeDeeplink(deeplink: string, closeWebviewBeforeCallNativeDeeplinkHandler?: boolean): void;
13
15
  getHrefToOpenInBrowser(link: string): string;
14
16
  openInBrowser(link: string): void;
@@ -20,5 +22,6 @@ export declare class ExternalLinksService {
20
22
  * Чистые функции сборки URL бросают ту же ошибку, но без логирования.
21
23
  */
22
24
  private validateUrlOrThrow;
25
+ private logBrowserFallback;
23
26
  private navigateByNativeApp;
24
27
  }
@@ -9,8 +9,9 @@ const CANCEL_NEW_CALLS_TO_NA_TIME = 150;
9
9
  * и связанных с этим действий.
10
10
  */
11
11
  class ExternalLinksService {
12
- constructor(nativeParamsService, logError) {
12
+ constructor(nativeParamsService, nativeLogService, logError) {
13
13
  this.nativeParamsService = nativeParamsService;
14
+ this.nativeLogService = nativeLogService;
14
15
  this.logError = logError;
15
16
  this.navigationByNativeAppInProgress = false;
16
17
  }
@@ -21,16 +22,19 @@ class ExternalLinksService {
21
22
  const preparedNativeUrl = (0, native_links_1.prepareNativeDeeplinkUrl)(this.nativeAppTarget, deeplink);
22
23
  if (closeWebviewBeforeCallNativeDeeplinkHandler &&
23
24
  this.nativeParamsService.canUseNativeFeature('savedBackStack')) {
24
- (0, utils_1.closeWebviewUtil)();
25
+ this.nativeLogService.execute('closeWebview', () => (0, utils_1.closeWebviewUtil)());
25
26
  // Проверено, ОС получает диплинк и передаёт его NA, не смотря на то,
26
27
  // что это происходит в следующей макрозадаче после команды на закрытие WV.
27
- setTimeout(() => window.location.replace(preparedNativeUrl), 0);
28
+ this.nativeLogService.execute('nativeDeeplink', () => {
29
+ setTimeout(() => window.location.replace(preparedNativeUrl), 0);
30
+ }, { payload: { deeplink: preparedNativeUrl } });
28
31
  return;
29
32
  }
30
- this.navigateByNativeApp(preparedNativeUrl);
33
+ this.navigateByNativeApp(preparedNativeUrl, 'nativeDeeplink');
31
34
  }
32
35
  getHrefToOpenInBrowser(link) {
33
36
  if (!this.nativeParamsService.canUseNativeFeature('linksInBrowser')) {
37
+ this.logBrowserFallback(link);
34
38
  return `${this.nativeParamsService.appId}://webFeature?type=recommendation&url=${encodeURIComponent(link)}`;
35
39
  }
36
40
  this.validateUrlOrThrow(link);
@@ -41,17 +45,29 @@ class ExternalLinksService {
41
45
  return;
42
46
  }
43
47
  this.validateUrlOrThrow(link);
44
- this.navigateByNativeApp((0, native_links_1.prepareOpenInBrowserUrl)(this.nativeAppTarget, link, this.nativeParamsService.canUseNativeFeature('linksInBrowser')));
48
+ const linksInBrowser = this.nativeParamsService.canUseNativeFeature('linksInBrowser');
49
+ if (!linksInBrowser) {
50
+ this.logBrowserFallback(link);
51
+ }
52
+ this.navigateByNativeApp((0, native_links_1.prepareOpenInBrowserUrl)(this.nativeAppTarget, link, linksInBrowser), 'openInBrowser');
45
53
  }
46
54
  openInNewWebview(link, nativeTitle = '', closeCurrentWebview = false) {
47
55
  this.validateUrlOrThrow(link);
56
+ if (this.nativeParamsService.environment === 'android' &&
57
+ !this.nativeParamsService.canUseNativeFeature('savedBackStack')) {
58
+ this.nativeLogService.logFeatureFallback({
59
+ feature: 'savedBackStack',
60
+ fallbackReason: 'Открытие нового webview в Android приведет к закрытию текущего',
61
+ payload: { link },
62
+ });
63
+ }
48
64
  this.handleNativeDeeplink((0, native_links_1.prepareOpenInNewWebviewDeeplink)(link, nativeTitle), closeCurrentWebview);
49
65
  }
50
66
  openPdf(url, type = 'pdfFile', title) {
51
67
  if (this.navigationByNativeAppInProgress) {
52
68
  return;
53
69
  }
54
- this.navigateByNativeApp((0, native_links_1.preparePdfUrl)(this.nativeAppTarget, url, type, title));
70
+ this.navigateByNativeApp((0, native_links_1.preparePdfUrl)(this.nativeAppTarget, url, type, title), 'openPdf');
55
71
  }
56
72
  get nativeAppTarget() {
57
73
  return {
@@ -68,12 +84,21 @@ class ExternalLinksService {
68
84
  throw new Error(`invalid url: ${link}`);
69
85
  }
70
86
  }
71
- navigateByNativeApp(url) {
72
- this.navigationByNativeAppInProgress = true;
73
- window.location.replace(url);
74
- setTimeout(() => {
75
- this.navigationByNativeAppInProgress = false;
76
- }, CANCEL_NEW_CALLS_TO_NA_TIME);
87
+ logBrowserFallback(link) {
88
+ this.nativeLogService.logFeatureFallback({
89
+ feature: 'linksInBrowser',
90
+ fallbackReason: 'Открытие в браузере технически недоступно, будет открыто в новом webview',
91
+ payload: { link },
92
+ });
93
+ }
94
+ navigateByNativeApp(url, action) {
95
+ this.nativeLogService.execute(action, () => {
96
+ this.navigationByNativeAppInProgress = true;
97
+ window.location.replace(url);
98
+ setTimeout(() => {
99
+ this.navigationByNativeAppInProgress = false;
100
+ }, CANCEL_NEW_CALLS_TO_NA_TIME);
101
+ }, { payload: { url } });
77
102
  }
78
103
  }
79
104
  exports.ExternalLinksService = ExternalLinksService;
@@ -0,0 +1,26 @@
1
+ import { type Environment, type NativeFeatureContext, type NativeFeatureKey, type NoopOptions } from '../types';
2
+ /**
3
+ * Обёртка для выполнения нативных вызовов с noop-режимом и логированием версионных фич
4
+ */
5
+ export declare class NativeLogService {
6
+ private environment;
7
+ private appVersion;
8
+ private isNoop?;
9
+ constructor(environment: Environment, appVersion: string, isNoop?: NoopOptions["enabled"] | undefined);
10
+ /**
11
+ * Метод для вывода в консоль информации о недоступности фич,
12
+ * перечисленных в `NATIVE_FEATURES_FROM_VERSION` src/client/constants.ts
13
+ */
14
+ logFeatureFallback(params: {
15
+ feature: NativeFeatureKey;
16
+ fallbackReason: string;
17
+ payload?: unknown;
18
+ }): void;
19
+ /**
20
+ * Метод подменяющий нативный вызов и логирующий его, для работы в noop режиме
21
+ */
22
+ execute(action: string, fn: () => void, meta?: {
23
+ featureContext?: NativeFeatureContext | null;
24
+ payload?: unknown;
25
+ }): void;
26
+ }
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NativeLogService = void 0;
4
+ const constants_1 = require("../constants");
5
+ /**
6
+ * Обёртка для выполнения нативных вызовов с noop-режимом и логированием версионных фич
7
+ */
8
+ class NativeLogService {
9
+ constructor(environment, appVersion, isNoop) {
10
+ this.environment = environment;
11
+ this.appVersion = appVersion;
12
+ this.isNoop = isNoop;
13
+ }
14
+ /**
15
+ * Метод для вывода в консоль информации о недоступности фич,
16
+ * перечисленных в `NATIVE_FEATURES_FROM_VERSION` src/client/constants.ts
17
+ */
18
+ logFeatureFallback(params) {
19
+ if (!this.isNoop)
20
+ return;
21
+ const { fromVersion } = constants_1.NATIVE_FEATURES_FROM_VERSION[this.environment][params.feature];
22
+ console.info([
23
+ `[B2N noop][${this.environment}][v${this.appVersion}]`,
24
+ `Feature: ${params.feature}`,
25
+ `${params.fallbackReason}`,
26
+ `Будет исправлено в версии: ${fromVersion}`,
27
+ ].join('\n'), params.payload);
28
+ }
29
+ /**
30
+ * Метод подменяющий нативный вызов и логирующий его, для работы в noop режиме
31
+ */
32
+ execute(action, fn, meta) {
33
+ var _a;
34
+ if (this.isNoop) {
35
+ if (meta === null || meta === void 0 ? void 0 : meta.featureContext) {
36
+ this.logFeatureFallback({
37
+ feature: meta.featureContext.feature,
38
+ fallbackReason: (_a = meta.featureContext.fallbackReason) !== null && _a !== void 0 ? _a : '',
39
+ payload: meta.payload,
40
+ });
41
+ }
42
+ else {
43
+ console.info(`[B2N noop][${this.environment}][v${this.appVersion}] ${action}`, ...((meta === null || meta === void 0 ? void 0 : meta.payload) !== undefined ? [meta.payload] : []));
44
+ }
45
+ return;
46
+ }
47
+ fn();
48
+ }
49
+ }
50
+ exports.NativeLogService = NativeLogService;
@@ -1,4 +1,5 @@
1
1
  import { type BrowserHistoryApiWrappers, type HistoryPushStateParams, type LocationAssignParam, type LogError } from '../types';
2
+ import { type NativeLogService } from './native-log-service';
2
3
  import { type NativeParamsService } from './native-params-service';
3
4
  /**
4
5
  * Сервис, отвечающий за взаимодействие WA с WV компонентами NA —
@@ -9,6 +10,7 @@ import { type NativeParamsService } from './native-params-service';
9
10
  */
10
11
  export declare class NativeNavigationAndTitleService {
11
12
  private nativeParamsService;
13
+ private nativeLogService;
12
14
  private browserHistoryApiWrappers?;
13
15
  private logError?;
14
16
  private lastSetPageSettingsParams;
@@ -16,7 +18,7 @@ export declare class NativeNavigationAndTitleService {
16
18
  private numOfBackSteps;
17
19
  private isGoBackLocked;
18
20
  private isNavigateServerSideLocked;
19
- constructor(nativeParamsService: NativeParamsService, browserHistoryApiWrappers?: BrowserHistoryApiWrappers | undefined, logError?: LogError | undefined);
21
+ constructor(nativeParamsService: NativeParamsService, nativeLogService: NativeLogService, browserHistoryApiWrappers?: BrowserHistoryApiWrappers | undefined, logError?: LogError | undefined);
20
22
  closeWebview(): void;
21
23
  goBack(): void;
22
24
  goBackAFewSteps(stepsNumber: number, autoCloseWebview?: boolean): void;
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
- /* eslint max-lines: ["error", {"max": 360, "skipComments": true}] */
3
2
  Object.defineProperty(exports, "__esModule", { value: true });
4
3
  exports.NativeNavigationAndTitleService = void 0;
4
+ /* eslint max-lines: ["error", {"max": 370, "skipComments": true}] */
5
5
  const query_and_headers_keys_1 = require("../../query-and-headers-keys");
6
6
  const utils_1 = require("./utils");
7
7
  const NativeHistoryStackStub = 0;
@@ -13,8 +13,9 @@ const NativeHistoryStackStub = 0;
13
13
  * см. в документе {@link ./NAVIGATION_SCENARIOS.md}.
14
14
  */
15
15
  class NativeNavigationAndTitleService {
16
- constructor(nativeParamsService, browserHistoryApiWrappers, logError) {
16
+ constructor(nativeParamsService, nativeLogService, browserHistoryApiWrappers, logError) {
17
17
  this.nativeParamsService = nativeParamsService;
18
+ this.nativeLogService = nativeLogService;
18
19
  this.browserHistoryApiWrappers = browserHistoryApiWrappers;
19
20
  this.logError = logError;
20
21
  // Здесь сохраняются параметры, которые в последний раз были отправлены
@@ -39,7 +40,7 @@ class NativeNavigationAndTitleService {
39
40
  }
40
41
  // eslint-disable-next-line class-methods-use-this -- удобней использовать метод в контексте экземпляра.
41
42
  closeWebview() {
42
- (0, utils_1.closeWebviewUtil)();
43
+ this.nativeLogService.execute('closeWebview', () => (0, utils_1.closeWebviewUtil)());
43
44
  }
44
45
  goBack() {
45
46
  if (this.isGoBackLocked) {
@@ -57,7 +58,7 @@ class NativeNavigationAndTitleService {
57
58
  const maxStepsToBack = this.nativeHistoryStack.length - 1;
58
59
  if (stepsToBack > maxStepsToBack) {
59
60
  if (autoCloseWebview) {
60
- (0, utils_1.closeWebviewUtil)();
61
+ this.nativeLogService.execute('closeWebview', () => (0, utils_1.closeWebviewUtil)());
61
62
  return;
62
63
  }
63
64
  this.numOfBackSteps = maxStepsToBack;
@@ -165,7 +166,7 @@ class NativeNavigationAndTitleService {
165
166
  }
166
167
  this.numOfBackSteps = 1;
167
168
  if (this.nativeHistoryStack.length < 1) {
168
- (0, utils_1.closeWebviewUtil)();
169
+ this.nativeLogService.execute('closeWebview', () => (0, utils_1.closeWebviewUtil)());
169
170
  return;
170
171
  }
171
172
  this.saveNativeHistoryStack();
@@ -282,13 +283,12 @@ class NativeNavigationAndTitleService {
282
283
  * с `nativeHistoryStack`.
283
284
  */
284
285
  syncHistoryWithNative() {
285
- var _a;
286
286
  const { pageId, pageTitle } = this.getNativePageIdAndTitle();
287
287
  if (this.nativeParamsService.environment === 'android') {
288
288
  const narrowedPageId = pageId !== null && pageId !== void 0 ? pageId : 1;
289
289
  const paramsToSend = JSON.stringify({ pageId: narrowedPageId, pageTitle });
290
290
  if (this.lastSetPageSettingsParams !== paramsToSend) {
291
- (_a = this.nativeParamsService.AndroidBridge) === null || _a === void 0 ? void 0 : _a.setPageSettings(paramsToSend);
291
+ this.nativeLogService.execute('syncHistoryWithNative', () => { var _a; return (_a = this.nativeParamsService.AndroidBridge) === null || _a === void 0 ? void 0 : _a.setPageSettings(paramsToSend); }, { payload: paramsToSend });
292
292
  this.lastSetPageSettingsParams = paramsToSend;
293
293
  }
294
294
  }
@@ -297,7 +297,7 @@ class NativeNavigationAndTitleService {
297
297
  const pageIdStr = pageId ? `&pageId=${pageId}` : '';
298
298
  const paramsToSend = `ios:setPageSettings/${pageTitleStr + pageIdStr}`;
299
299
  if (this.lastSetPageSettingsParams !== paramsToSend) {
300
- window.location.replace(paramsToSend);
300
+ this.nativeLogService.execute('syncHistoryWithNative', () => window.location.replace(paramsToSend), { payload: paramsToSend });
301
301
  this.lastSetPageSettingsParams = paramsToSend;
302
302
  }
303
303
  }
@@ -1,8 +1,9 @@
1
- import { type Environment, type LogError, type NativeFeatureKey, type Theme } from '../types';
1
+ import { type Environment, type LogError, type NativeFeatureKey, type NoopOptions, type Theme } from '../types';
2
2
  /**
3
3
  * Сервис, аккумулирующий детали о NA и предоставляющий методы, связанные с этим.
4
4
  */
5
5
  export declare class NativeParamsService {
6
+ private noop?;
6
7
  private logError?;
7
8
  AndroidBridge: {
8
9
  setPageSettings: (params: string) => void;
@@ -16,10 +17,12 @@ export declare class NativeParamsService {
16
17
  theme: Theme;
17
18
  title: string;
18
19
  webviewLaunchTime: number | null;
19
- constructor(logError?: LogError | undefined);
20
+ constructor(noop?: NoopOptions | undefined, logError?: LogError | undefined);
20
21
  canUseNativeFeature(feature: NativeFeatureKey): boolean;
21
22
  isCurrentVersionHigherOrEqual(versionToCompare: string): boolean;
22
23
  private static isValidVersionFormat;
23
24
  private getAppId;
24
25
  private readNativeParamsCookie;
26
+ private resolveEnvironment;
27
+ private resolveAppVersion;
25
28
  }
@@ -8,15 +8,14 @@ const native_features_1 = require("./native-features");
8
8
  * Сервис, аккумулирующий детали о NA и предоставляющий методы, связанные с этим.
9
9
  */
10
10
  class NativeParamsService {
11
- constructor(logError) {
11
+ constructor(noop, logError) {
12
+ this.noop = noop;
12
13
  this.logError = logError;
13
14
  this.AndroidBridge = window.Android;
14
- this.environment = window.Android ? 'android' : 'ios';
15
15
  this.nativeParamsReadErrorFlag = false;
16
16
  const nativeParams = this.readNativeParamsCookie();
17
- this.appVersion = NativeParamsService.isValidVersionFormat(nativeParams === null || nativeParams === void 0 ? void 0 : nativeParams.appVersion)
18
- ? nativeParams.appVersion
19
- : '0.0.0';
17
+ this.environment = this.resolveEnvironment();
18
+ this.appVersion = this.resolveAppVersion(nativeParams === null || nativeParams === void 0 ? void 0 : nativeParams.appVersion);
20
19
  this.appId = this.getAppId(nativeParams === null || nativeParams === void 0 ? void 0 : nativeParams.iosAppId);
21
20
  this.nextPageId = (nativeParams === null || nativeParams === void 0 ? void 0 : nativeParams.nextPageId) || null;
22
21
  this.originalWebviewParams = (nativeParams === null || nativeParams === void 0 ? void 0 : nativeParams.originalWebviewParams) || null;
@@ -62,5 +61,21 @@ class NativeParamsService {
62
61
  return null;
63
62
  }
64
63
  }
64
+ resolveEnvironment() {
65
+ var _a;
66
+ if (((_a = this.noop) === null || _a === void 0 ? void 0 : _a.enabled) && this.noop.environment) {
67
+ return this.noop.environment;
68
+ }
69
+ return window.Android ? 'android' : 'ios';
70
+ }
71
+ resolveAppVersion(versionFromCookie) {
72
+ var _a;
73
+ if (((_a = this.noop) === null || _a === void 0 ? void 0 : _a.enabled) && NativeParamsService.isValidVersionFormat(this.noop.appVersion)) {
74
+ return this.noop.appVersion;
75
+ }
76
+ return NativeParamsService.isValidVersionFormat(versionFromCookie)
77
+ ? versionFromCookie
78
+ : '0.0.0';
79
+ }
65
80
  }
66
81
  exports.NativeParamsService = NativeParamsService;
package/client/types.d.ts CHANGED
@@ -13,6 +13,10 @@ export type HistoryReplaceStateParams = Parameters<typeof window.history.replace
13
13
  export type LocationAssignParam = Parameters<typeof window.location.assign>[0];
14
14
  export type LogError = (b2nErrorMessage: string, originalError: unknown) => void;
15
15
  export type NativeFeatureKey = 'geolocation' | 'linksInBrowser' | 'savedBackStack';
16
+ export type NativeFeatureContext = {
17
+ feature: NativeFeatureKey;
18
+ fallbackReason?: string;
19
+ };
16
20
  type NativeFeaturesParams = Readonly<Record<NativeFeatureKey, {
17
21
  fromVersion: string;
18
22
  }>>;
@@ -22,4 +26,9 @@ export type NativeFeaturesFromVersion = Readonly<{
22
26
  }>;
23
27
  export type PdfType = 'pdfFile' | 'base64' | 'binary';
24
28
  export type Theme = 'light' | 'dark';
29
+ export type NoopOptions = {
30
+ enabled: boolean;
31
+ environment?: Environment;
32
+ appVersion?: string;
33
+ };
25
34
  export {};
package/package.json CHANGED
@@ -1,121 +1,127 @@
1
1
  {
2
- "name": "@alfalab/bridge-to-native",
3
- "version": "1.5.0",
4
- "license": "MIT",
5
- "description": "Утилита для удобной работы веб приложения внутри нативного приложения и коммуникации с ним.",
6
- "engines": {
7
- "node": ">=20.19.2",
8
- "npm": "please-use-yarn"
2
+ "name": "@alfalab/bridge-to-native",
3
+ "version": "1.5.1-beta.50a07d1",
4
+ "license": "MIT",
5
+ "description": "Утилита для удобной работы веб приложения внутри нативного приложения и коммуникации с ним.",
6
+ "engines": {
7
+ "node": ">=20.19.2",
8
+ "npm": "please-use-yarn"
9
+ },
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "git+https://github.com/core-ds/bridge-to-native.git"
13
+ },
14
+ "exports": {
15
+ "./client": {
16
+ "import": "./client/index.js",
17
+ "require": "./client/index.js",
18
+ "types": "./client/index.d.ts"
9
19
  },
10
- "repository": {
11
- "type": "git",
12
- "url": "git+https://github.com/core-ds/bridge-to-native.git"
20
+ "./client/primitives": {
21
+ "import": "./client/primitives.js",
22
+ "require": "./client/primitives.js",
23
+ "types": "./client/primitives.d.ts"
13
24
  },
14
- "exports": {
15
- "./client": {
16
- "import": "./client/index.js",
17
- "require": "./client/index.js",
18
- "types": "./client/index.d.ts"
19
- },
20
- "./server": {
21
- "import": "./server/index.js",
22
- "require": "./server/index.js",
23
- "types": "./server/index.d.ts"
24
- }
25
- },
26
- "sideEffects": false,
27
- "bugs": {
28
- "url": "https://github.com/core-ds/bridge-to-native/issues"
29
- },
30
- "scripts": {
31
- "build": "yarn build:clean && yarn build:ts",
32
- "build:clean": "shx rm -rf .publish",
33
- "build:copy-package-json": "shx cp package.json .publish/package.json",
34
- "build:ts": "tsc --build",
35
- "format": "arui-presets-lint format",
36
- "format:check": "arui-presets-lint format:check",
37
- "lint": "yarn lint:scripts && yarn format:check",
38
- "lint:fix": "yarn lint:scripts --fix && yarn format",
39
- "lint:scripts": "arui-presets-lint scripts",
40
- "pub": "npm publish .publish --userconfig \"../.npmrc\" --tag \"$TAG\"",
41
- "release": "yarn build && yarn build:copy-package-json && yarn pub",
42
- "test": "arui-scripts test --silent --collect-coverage"
43
- },
44
- "devDependencies": {
45
- "@happy-dom/jest-environment": "18.0.1",
46
- "@types/jest": "29.5.14",
47
- "@types/node": "20.19.1",
48
- "arui-presets-lint": "8.7.0",
49
- "arui-scripts": "19.0.7",
50
- "copyfiles": "2.4.1",
51
- "jest-junit": "10.0.0",
52
- "lint-staged": "^12.5.0",
53
- "promisify-child-process": "4.1.1",
54
- "shx": "0.3.4",
55
- "typescript": "5.5.4"
56
- },
57
- "commitlint": {
58
- "extends": "./node_modules/arui-presets-lint/commitlint"
59
- },
60
- "eslintConfig": {
61
- "extends": "./node_modules/arui-presets-lint/eslint",
62
- "parserOptions": {
63
- "project": [
64
- "./__tests__/tsconfig.json",
65
- "./src/client/tsconfig.json",
66
- "./src/server/tsconfig.json"
67
- ]
68
- },
69
- "overrides": [
70
- {
71
- "files": [
72
- "__tests__/**/*"
73
- ],
74
- "rules": {
75
- "max-lines": "off"
76
- }
77
- }
78
- ]
25
+ "./server": {
26
+ "import": "./server/index.js",
27
+ "require": "./server/index.js",
28
+ "types": "./server/index.d.ts"
29
+ }
30
+ },
31
+ "sideEffects": false,
32
+ "bugs": {
33
+ "url": "https://github.com/core-ds/bridge-to-native/issues"
34
+ },
35
+ "scripts": {
36
+ "build": "yarn build:clean && yarn build:ts",
37
+ "build:clean": "shx rm -rf .publish",
38
+ "build:copy-package-json": "shx cp package.json .publish/package.json",
39
+ "build:ts": "tsc --build",
40
+ "format": "arui-presets-lint format",
41
+ "format:check": "arui-presets-lint format:check",
42
+ "lint": "yarn lint:scripts && yarn format:check",
43
+ "lint:fix": "yarn lint:scripts --fix && yarn format",
44
+ "lint:scripts": "arui-presets-lint scripts",
45
+ "pub": "npm publish .publish --userconfig \"../.npmrc\" --tag \"$TAG\"",
46
+ "release": "yarn build && yarn build:copy-package-json && yarn pub",
47
+ "test": "arui-scripts test --silent --collect-coverage"
48
+ },
49
+ "devDependencies": {
50
+ "@happy-dom/jest-environment": "18.0.1",
51
+ "@types/jest": "29.5.14",
52
+ "@types/node": "20.19.1",
53
+ "arui-presets-lint": "8.7.0",
54
+ "arui-scripts": "19.0.7",
55
+ "copyfiles": "2.4.1",
56
+ "jest-junit": "10.0.0",
57
+ "lint-staged": "^12.5.0",
58
+ "promisify-child-process": "4.1.1",
59
+ "shx": "0.3.4",
60
+ "typescript": "5.5.4"
61
+ },
62
+ "commitlint": {
63
+ "extends": "./node_modules/arui-presets-lint/commitlint"
64
+ },
65
+ "eslintConfig": {
66
+ "extends": "./node_modules/arui-presets-lint/eslint",
67
+ "parserOptions": {
68
+ "project": [
69
+ "./__tests__/tsconfig.json",
70
+ "./src/client/tsconfig.json",
71
+ "./src/server/tsconfig.json"
72
+ ]
79
73
  },
80
- "jest": {
81
- "projects": [
82
- {
83
- "displayName": "client-tests",
84
- "testEnvironment": "@happy-dom/jest-environment",
85
- "testPathIgnorePatterns": [
86
- "/__tests__/server/"
87
- ]
88
- },
89
- {
90
- "displayName": "server-tests",
91
- "testEnvironment": "node",
92
- "testPathIgnorePatterns": [
93
- "/__tests__/client/"
94
- ]
95
- }
74
+ "overrides": [
75
+ {
76
+ "files": [
77
+ "__tests__/**/*"
96
78
  ],
97
- "testRegex": [
98
- "__tests__/.*\\.test\\.ts"
99
- ],
100
- "coveragePathIgnorePatterns": [
101
- "/node_modules/",
102
- "/src/(client|server)/index.ts"
103
- ],
104
- "reporters": [
105
- "default",
106
- "jest-junit"
79
+ "rules": {
80
+ "max-lines": "off"
81
+ }
82
+ }
83
+ ]
84
+ },
85
+ "jest": {
86
+ "projects": [
87
+ {
88
+ "displayName": "client-tests",
89
+ "testEnvironment": "@happy-dom/jest-environment",
90
+ "testPathIgnorePatterns": [
91
+ "/__tests__/server/"
107
92
  ]
108
- },
109
- "prettier": "arui-presets-lint/prettier",
110
- "stylelint": {
111
- "extends": "arui-presets-lint/stylelint",
112
- "ignoreFiles": [
113
- "coverage/**/*.js",
114
- ".yarn/releases/*"
93
+ },
94
+ {
95
+ "displayName": "server-tests",
96
+ "testEnvironment": "node",
97
+ "testPathIgnorePatterns": [
98
+ "/__tests__/client/"
115
99
  ]
116
- },
117
- "publishConfig": {
118
- "registry": "https://registry.npmjs.org"
119
- },
120
- "packageManager": "yarn@4.12.0"
100
+ }
101
+ ],
102
+ "testRegex": [
103
+ "__tests__/.*\\.test\\.ts"
104
+ ],
105
+ "coveragePathIgnorePatterns": [
106
+ "/node_modules/",
107
+ "/src/(client|server)/index.ts",
108
+ "/src/client/primitives.ts"
109
+ ],
110
+ "reporters": [
111
+ "default",
112
+ "jest-junit"
113
+ ]
114
+ },
115
+ "prettier": "arui-presets-lint/prettier",
116
+ "stylelint": {
117
+ "extends": "arui-presets-lint/stylelint",
118
+ "ignoreFiles": [
119
+ "coverage/**/*.js",
120
+ ".yarn/releases/*"
121
+ ]
122
+ },
123
+ "publishConfig": {
124
+ "registry": "https://registry.npmjs.org"
125
+ },
126
+ "packageManager": "yarn@4.12.0"
121
127
  }
@@ -11,6 +11,8 @@ exports.HEADER_KEY_USER_AGENT = 'user-agent';
11
11
  */
12
12
  // Ключ cookie, с помощью которого серверная часть B2N передаст на клиент информацию об NA.
13
13
  exports.COOKIE_KEY_BRIDGE_TO_NATIVE_DATA = 'bridgeToNativeData';
14
+ // Ключ cookie, с помощью которого серверная часть B2N передаст на клиент информацию об NA.
15
+ // export const B2N_MODE = 'b2n_mode';
14
16
  // NA на обеих платформах подмешивает этот заголовок к запросу за HTML.
15
17
  // TODO:
16
18
  // * Исследовать, делает ли оно это при запросах к прочим ресурсам;