@alfalab/bridge-to-native 1.3.2-beta.6ebe433 → 1.3.2-beta.aecff8b

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.
@@ -89,11 +89,28 @@ export declare class BridgeToNative {
89
89
  * Делает несколько шагов назад по браузерной истории и модифицирует внутреннее состояние,
90
90
  * чтобы в дальнейшем зарегистрировать этот переход в NA.
91
91
  *
92
+ * ВАЖНО!
93
+ * До версии `1.4.0` метод назывался `goBackAFewStepsClientSide` и его можно
94
+ * было использовать только в рамках SPA истории.
95
+ *
96
+ * После переименования этот метод можно использовать без ограничей, НО С УСЛОВИЕМ,
97
+ * что в потребителях B2N нет прямых вызовов `history.replaceState` (или оберток над ним,
98
+ * типа `history.replace` из ReactRouter). А вместо прямых вызовов используется
99
+ * метод B2N `replaceHistoryState`. Который под капотом вызывает `history.replaceState`
100
+ * или вашу собственную «обертку» над ним (см. `browserHistoryApiWrappers` в конструкторе).
101
+ *
102
+ * Если это условие не соблюдается, как и раньше, метод можно использовать
103
+ * только в рамках истории по SPA WA.
104
+ *
92
105
  * @param stepsNumber Количество шагов назад.
93
106
  * Возможно передача как положительного, так и отрицательного числа. `0` будет проигнорирован.
94
107
  * @param autoCloseWebview Флаг — закрывать ли WV автоматически,
95
108
  * если переданное кол-во шагов будет больше, чем записей в истории.
96
109
  */
110
+ goBackAFewSteps(stepsNumber: number, autoCloseWebview?: boolean): void;
111
+ /**
112
+ * @deprecated Используйте `goBackAFewSteps`.
113
+ */
97
114
  goBackAFewStepsClientSide(stepsNumber: number, autoCloseWebview?: boolean): void;
98
115
  /**
99
116
  * Вызывает обработчик диплинков NA для обработки переданного диплинка.
@@ -141,6 +158,15 @@ export declare class BridgeToNative {
141
158
  * чтобы корректно передать информацию экземпляру B2N следующего WA или
142
159
  * экзепляру B2N следующей страницы текущего WA (в случае multi-page application).
143
160
  *
161
+ * ВАЖНО!
162
+ * С версии `1.4.0` появилась возможность использовать `goBackAFewSteps`
163
+ * через границу server-side (hard) навигации (включая переходы на другие origin).
164
+ * Но с условием, см. описание `goBackAFewSteps`.
165
+ *
166
+ * ВАЖНО!
167
+ * До версии `1.4.0` метод имел ограничения, которые останутся, если переходить на WA,
168
+ * которое использует B2N версии < `1.4.0`.
169
+ *
144
170
  * @param url URL для перехода внутри WA server-side навигацией.
145
171
  * @param nativeTitle Текст заголовка, для «нативной» части WV, пустая строка — отсутствие заголовка.
146
172
  */
@@ -188,11 +214,8 @@ export declare class BridgeToNative {
188
214
  */
189
215
  openPdf(url: string, type?: PdfType, title?: string): void;
190
216
  /**
191
- * Для перезагрузки страницы необходимо использовать этот метод.
192
- * Иначе синхронизация состояния с NA будет потеряна.
193
- *
194
- * @param skipReload По умолчанию метод сам делает `location.reload`,
195
- * но с помощью аргумента можно отключить этот вызов, если нужно.
217
+ * @deprecated Используйте `window.location.reload()` напрямую.
218
+ * B2N больше не требует специального метода для перезагрузки.
196
219
  */
197
220
  reload(skipReload?: boolean): void;
198
221
  /**
@@ -115,13 +115,32 @@ class BridgeToNative {
115
115
  * Делает несколько шагов назад по браузерной истории и модифицирует внутреннее состояние,
116
116
  * чтобы в дальнейшем зарегистрировать этот переход в NA.
117
117
  *
118
+ * ВАЖНО!
119
+ * До версии `1.4.0` метод назывался `goBackAFewStepsClientSide` и его можно
120
+ * было использовать только в рамках SPA истории.
121
+ *
122
+ * После переименования этот метод можно использовать без ограничей, НО С УСЛОВИЕМ,
123
+ * что в потребителях B2N нет прямых вызовов `history.replaceState` (или оберток над ним,
124
+ * типа `history.replace` из ReactRouter). А вместо прямых вызовов используется
125
+ * метод B2N `replaceHistoryState`. Который под капотом вызывает `history.replaceState`
126
+ * или вашу собственную «обертку» над ним (см. `browserHistoryApiWrappers` в конструкторе).
127
+ *
128
+ * Если это условие не соблюдается, как и раньше, метод можно использовать
129
+ * только в рамках истории по SPA WA.
130
+ *
118
131
  * @param stepsNumber Количество шагов назад.
119
132
  * Возможно передача как положительного, так и отрицательного числа. `0` будет проигнорирован.
120
133
  * @param autoCloseWebview Флаг — закрывать ли WV автоматически,
121
134
  * если переданное кол-во шагов будет больше, чем записей в истории.
122
135
  */
136
+ goBackAFewSteps(stepsNumber, autoCloseWebview = false) {
137
+ this.nativeNavigationAndTitleService.goBackAFewSteps(stepsNumber, autoCloseWebview);
138
+ }
139
+ /**
140
+ * @deprecated Используйте `goBackAFewSteps`.
141
+ */
123
142
  goBackAFewStepsClientSide(stepsNumber, autoCloseWebview = false) {
124
- this.nativeNavigationAndTitleService.goBackAFewStepsClientSide(stepsNumber, autoCloseWebview);
143
+ this.goBackAFewSteps(stepsNumber, autoCloseWebview);
125
144
  }
126
145
  /**
127
146
  * Вызывает обработчик диплинков NA для обработки переданного диплинка.
@@ -175,6 +194,15 @@ class BridgeToNative {
175
194
  * чтобы корректно передать информацию экземпляру B2N следующего WA или
176
195
  * экзепляру B2N следующей страницы текущего WA (в случае multi-page application).
177
196
  *
197
+ * ВАЖНО!
198
+ * С версии `1.4.0` появилась возможность использовать `goBackAFewSteps`
199
+ * через границу server-side (hard) навигации (включая переходы на другие origin).
200
+ * Но с условием, см. описание `goBackAFewSteps`.
201
+ *
202
+ * ВАЖНО!
203
+ * До версии `1.4.0` метод имел ограничения, которые останутся, если переходить на WA,
204
+ * которое использует B2N версии < `1.4.0`.
205
+ *
178
206
  * @param url URL для перехода внутри WA server-side навигацией.
179
207
  * @param nativeTitle Текст заголовка, для «нативной» части WV, пустая строка — отсутствие заголовка.
180
208
  */
@@ -230,14 +258,14 @@ class BridgeToNative {
230
258
  this.externalLinksService.openPdf(url, type, title);
231
259
  }
232
260
  /**
233
- * Для перезагрузки страницы необходимо использовать этот метод.
234
- * Иначе синхронизация состояния с NA будет потеряна.
235
- *
236
- * @param skipReload По умолчанию метод сам делает `location.reload`,
237
- * но с помощью аргумента можно отключить этот вызов, если нужно.
261
+ * @deprecated Используйте `window.location.reload()` напрямую.
262
+ * B2N больше не требует специального метода для перезагрузки.
238
263
  */
264
+ // eslint-disable-next-line class-methods-use-this -- метод оставлен для обратной совместимости.
239
265
  reload(skipReload) {
240
- this.nativeNavigationAndTitleService.reload(skipReload);
266
+ if (!skipReload) {
267
+ window.location.reload();
268
+ }
241
269
  }
242
270
  /**
243
271
  * Позволяет изменить `history.state` и/или URL текущей записи без потери служебного свойства B2N.
@@ -11,22 +11,20 @@ export declare class NativeNavigationAndTitleService {
11
11
  private nativeParamsService;
12
12
  private browserHistoryApiWrappers?;
13
13
  private logError?;
14
- private nativeHistoryStack;
15
14
  private lastSetPageSettingsParams;
15
+ private nativeHistoryStack;
16
+ private numOfBackSteps;
16
17
  private isGoBackLocked;
17
18
  private isNavigateServerSideLocked;
18
19
  constructor(nativeParamsService: NativeParamsService, browserHistoryApiWrappers?: BrowserHistoryApiWrappers | undefined, logError?: LogError | undefined);
19
20
  closeWebview(): void;
20
21
  goBack(): void;
21
- goBackAFewStepsClientSide(stepsNumber: number, autoCloseWebview?: boolean): void;
22
+ goBackAFewSteps(stepsNumber: number, autoCloseWebview?: boolean): void;
22
23
  navigateClientSide(url: HistoryPushStateParams[2], state?: HistoryPushStateParams[0], nativeTitle?: string): void;
23
24
  navigateServerSide(link: LocationAssignParam, nativeTitle?: string): void;
24
- reload(skipReload?: boolean): void;
25
+ replaceHistoryState(url?: HistoryPushStateParams[2], state?: HistoryPushStateParams[0]): void;
25
26
  setInitialView(nativeTitle?: string): void;
26
27
  setTitle(nativeTitle: string): void;
27
- replaceHistoryState(url?: HistoryPushStateParams[2], state?: HistoryPushStateParams[0]): void;
28
- private createStateWithPageId;
29
- private setHistoryStatePageId;
30
28
  /**
31
29
  * Метод, вычисляющий `pageId`, который нужно послать в NA
32
30
  * для правильной синхронизации с кнопкой "Назад". Также вычисляет `pageTitle`
@@ -41,19 +39,10 @@ export declare class NativeNavigationAndTitleService {
41
39
  */
42
40
  private handleClientSideNavigationBack;
43
41
  private hasSavedHistoryStack;
44
- /**
45
- * Инициализирует `nativeHistoryStack`.
46
- *
47
- * Подробное описание каждого сценария см. в {@link ./NAVIGATION_SCENARIOS.md}.
48
- */
49
42
  private initializeNativeHistoryStack;
43
+ private initializeForBackward;
50
44
  private initializeForNewOrigin;
51
45
  private initializeForForward;
52
- /**
53
- * Читает и парсит `nativeHistoryStack` из SessionStorage.
54
- * При ошибке чтения или парсинга логирует через `logError` и пробрасывает исключение.
55
- */
56
- private readSavedHistoryStack;
57
46
  /**
58
47
  * Подготавливает ссылку для корректного перехода server-side навигацией.
59
48
  *
@@ -63,12 +52,16 @@ export declare class NativeNavigationAndTitleService {
63
52
  */
64
53
  private prepareExternalLinkBeforeOpen;
65
54
  /**
66
- * Сохраняет `nativeHistoryStack` в SessionStorage.
55
+ * Читает и парсит `nativeHistoryStack` из SessionStorage.
56
+ * При ошибке чтения или парсинга логирует через `logError` и пробрасывает исключение.
67
57
  */
58
+ private readSavedHistoryStack;
68
59
  private saveNativeHistoryStack;
69
60
  /**
70
61
  * Синхронизирует состояние истории переходов и заголовок с NA в соответствии
71
62
  * с `nativeHistoryStack`.
72
63
  */
73
64
  private syncHistoryWithNative;
65
+ private setHistoryStatePageId;
66
+ private createStateWithPageId;
74
67
  }
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
- /* eslint max-lines: ["error", {"max": 400, "skipComments": true}] */
2
+ /* eslint max-lines: ["error", {"max": 350, "skipComments": true}] */
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  exports.NativeNavigationAndTitleService = void 0;
5
5
  const query_and_headers_keys_1 = require("../../query-and-headers-keys");
@@ -20,13 +20,18 @@ class NativeNavigationAndTitleService {
20
20
  // Здесь сохраняются параметры, которые в последний раз были отправлены
21
21
  // в NA. Помогает предотвратить повторную отправку одинаковых параметров.
22
22
  this.lastSetPageSettingsParams = '';
23
+ // Поле для фолбэк сценария, чтобы не ломать обратную совместимость в версии `1.4.0`.
24
+ // Фолбэк сцерий используется для потребителей B2N, которые используют
25
+ // прямые вызовы `history.replaceState` (или обертки над ним, типа `history.replace` из ReactRouter)
26
+ // вместо нового метода B2N `replaceHistoryState`
27
+ this.numOfBackSteps = 1;
23
28
  // Предотвращают повторный вызов навигации, пока текущая не завершена.
24
29
  // Без блокировки WV-браузер продолжит показывать исходную страницу,
25
30
  // и повторный вызов может инициировать нежелательную навигацию.
26
31
  // `isGoBackLocked` снимается в `handleClientSideNavigationBack` (popstate) для soft-навигации;
27
32
  // при hard-навигации блокировка снимется автоматически при новой инициализации.
28
- // `isNavigateServerSideLocked` не снимается — после server-side навигации всегда новая инициализация.
29
33
  this.isGoBackLocked = false;
34
+ // `isNavigateServerSideLocked` не снимается — после server-side навигации всегда новая инициализация.
30
35
  this.isNavigateServerSideLocked = false;
31
36
  this.handleClientSideNavigationBack = this.handleClientSideNavigationBack.bind(this);
32
37
  window.addEventListener('popstate', this.handleClientSideNavigationBack); // без отписки т.к. Сервис используется в течение всей жизни WA
@@ -41,9 +46,9 @@ class NativeNavigationAndTitleService {
41
46
  return;
42
47
  }
43
48
  this.isGoBackLocked = true;
44
- this.goBackAFewStepsClientSide(-1, true);
49
+ this.goBackAFewSteps(-1, true);
45
50
  }
46
- goBackAFewStepsClientSide(stepsNumber, autoCloseWebview = false) {
51
+ goBackAFewSteps(stepsNumber, autoCloseWebview = false) {
47
52
  var _a;
48
53
  if (!stepsNumber) {
49
54
  return;
@@ -55,8 +60,12 @@ class NativeNavigationAndTitleService {
55
60
  (0, close_webview_util_1.closeWebviewUtil)();
56
61
  return;
57
62
  }
63
+ this.numOfBackSteps = maxStepsToBack;
64
+ }
65
+ else {
66
+ this.numOfBackSteps = stepsToBack;
58
67
  }
59
- const steps = -Math.min(stepsToBack, maxStepsToBack);
68
+ const steps = -this.numOfBackSteps;
60
69
  if ((_a = this.browserHistoryApiWrappers) === null || _a === void 0 ? void 0 : _a.go) {
61
70
  this.browserHistoryApiWrappers.go(steps);
62
71
  }
@@ -91,23 +100,6 @@ class NativeNavigationAndTitleService {
91
100
  this.saveNativeHistoryStack();
92
101
  window.location.assign(this.prepareExternalLinkBeforeOpen(url));
93
102
  }
94
- // eslint-disable-next-line class-methods-use-this -- удобней использовать метод в контексте экземпляра.
95
- reload(skipReload = false) {
96
- document.cookie = `${query_and_headers_keys_1.COOKIE_KEY_BRIDGE_TO_NATIVE_RELOAD}=true; Path=/`;
97
- if (!skipReload) {
98
- window.location.reload();
99
- }
100
- }
101
- setInitialView(nativeTitle = '') {
102
- this.nativeHistoryStack = [nativeTitle];
103
- this.saveNativeHistoryStack();
104
- this.syncHistoryWithNative();
105
- }
106
- setTitle(nativeTitle) {
107
- this.nativeHistoryStack[this.nativeHistoryStack.length - 1] = nativeTitle;
108
- this.saveNativeHistoryStack();
109
- this.syncHistoryWithNative();
110
- }
111
103
  replaceHistoryState(url, state = null) {
112
104
  var _a;
113
105
  if ((_a = this.browserHistoryApiWrappers) === null || _a === void 0 ? void 0 : _a.replace) {
@@ -118,20 +110,15 @@ class NativeNavigationAndTitleService {
118
110
  }
119
111
  this.setHistoryStatePageId();
120
112
  }
121
- // eslint-disable-next-line class-methods-use-this -- удобней использовать метод в контексте экземпляра.
122
- createStateWithPageId(state, pageId) {
123
- const isPlainObject = (v) => v !== null && v !== undefined && typeof v === 'object' && !Array.isArray(v);
124
- return Object.assign(Object.assign({}, (isPlainObject(state) ? state : {})), { [query_and_headers_keys_1.HISTORY_STATE_KEY_B2N_PAGE_ID]: pageId });
113
+ setInitialView(nativeTitle = '') {
114
+ this.nativeHistoryStack = [nativeTitle];
115
+ this.saveNativeHistoryStack();
116
+ this.syncHistoryWithNative();
125
117
  }
126
- setHistoryStatePageId(useNextPageId = false) {
127
- const pageId = useNextPageId
128
- ? this.nativeHistoryStack.length + 1
129
- : this.nativeHistoryStack.length;
130
- const newState = this.createStateWithPageId(window.history.state, pageId);
131
- // `b2n-pageId` всегда записывается на верхний уровень через нативный `replaceState`,
132
- // а не через wrapper, чтобы wrapper (например, React Router / history) не мог обернуть
133
- // его внутрь своего формата и скрыть от B2N при чтении `history.state`.
134
- window.history.replaceState(newState, '');
118
+ setTitle(nativeTitle) {
119
+ this.nativeHistoryStack[this.nativeHistoryStack.length - 1] = nativeTitle;
120
+ this.saveNativeHistoryStack();
121
+ this.syncHistoryWithNative();
135
122
  }
136
123
  /**
137
124
  * Метод, вычисляющий `pageId`, который нужно послать в NA
@@ -163,8 +150,9 @@ class NativeNavigationAndTitleService {
163
150
  this.nativeHistoryStack = this.nativeHistoryStack.slice(0, statePageId);
164
151
  }
165
152
  else {
166
- this.nativeHistoryStack = this.nativeHistoryStack.slice(0, -1);
153
+ this.nativeHistoryStack = this.nativeHistoryStack.slice(0, -this.numOfBackSteps);
167
154
  }
155
+ this.numOfBackSteps = 1;
168
156
  if (this.nativeHistoryStack.length < 1) {
169
157
  (0, close_webview_util_1.closeWebviewUtil)();
170
158
  return;
@@ -176,11 +164,6 @@ class NativeNavigationAndTitleService {
176
164
  hasSavedHistoryStack() {
177
165
  return sessionStorage.getItem(query_and_headers_keys_1.SS_KEY_BRIDGE_TO_NATIVE_HISTORY_STACK) !== null;
178
166
  }
179
- /**
180
- * Инициализирует `nativeHistoryStack`.
181
- *
182
- * Подробное описание каждого сценария см. в {@link ./NAVIGATION_SCENARIOS.md}.
183
- */
184
167
  initializeNativeHistoryStack() {
185
168
  var _a;
186
169
  const { nextPageId, title } = this.nativeParamsService;
@@ -188,15 +171,7 @@ class NativeNavigationAndTitleService {
188
171
  const statePageId = (_a = window.history.state) === null || _a === void 0 ? void 0 : _a[query_and_headers_keys_1.HISTORY_STATE_KEY_B2N_PAGE_ID];
189
172
  try {
190
173
  if (typeof statePageId === 'number') {
191
- const pageId = statePageId;
192
- if (hasSS) {
193
- const savedStack = this.readSavedHistoryStack();
194
- this.nativeHistoryStack = savedStack.slice(0, pageId);
195
- this.nativeHistoryStack[this.nativeHistoryStack.length - 1] = title;
196
- }
197
- else {
198
- this.nativeHistoryStack = [title];
199
- }
174
+ this.nativeHistoryStack = this.initializeForBackward(statePageId, title);
200
175
  }
201
176
  else if (nextPageId && !hasSS) {
202
177
  this.nativeHistoryStack = this.initializeForNewOrigin(nextPageId, title);
@@ -215,6 +190,15 @@ class NativeNavigationAndTitleService {
215
190
  this.syncHistoryWithNative();
216
191
  this.setHistoryStatePageId();
217
192
  }
193
+ initializeForBackward(pageId, title) {
194
+ if (!this.hasSavedHistoryStack()) {
195
+ return [title];
196
+ }
197
+ const savedStack = this.readSavedHistoryStack();
198
+ const stack = savedStack.slice(0, pageId);
199
+ stack[stack.length - 1] = title;
200
+ return stack;
201
+ }
218
202
  // eslint-disable-next-line class-methods-use-this -- удобней использовать метод в контексте экземпляра.
219
203
  initializeForNewOrigin(nextPageId, title) {
220
204
  const stack = new Array(nextPageId).fill(NativeHistoryStackStub);
@@ -234,26 +218,6 @@ class NativeNavigationAndTitleService {
234
218
  stack[stack.length - 1] = title;
235
219
  return stack;
236
220
  }
237
- /**
238
- * Читает и парсит `nativeHistoryStack` из SessionStorage.
239
- * При ошибке чтения или парсинга логирует через `logError` и пробрасывает исключение.
240
- */
241
- readSavedHistoryStack() {
242
- const serialized = sessionStorage.getItem(query_and_headers_keys_1.SS_KEY_BRIDGE_TO_NATIVE_HISTORY_STACK);
243
- try {
244
- if (!serialized) {
245
- throw new Error(`${query_and_headers_keys_1.SS_KEY_BRIDGE_TO_NATIVE_HISTORY_STACK} sessionStorage expected not to be null`);
246
- }
247
- return JSON.parse(serialized);
248
- }
249
- catch (e) {
250
- if (this.logError) {
251
- this.logError(`Клиентский код B2N не смог получить ${query_and_headers_keys_1.SS_KEY_BRIDGE_TO_NATIVE_HISTORY_STACK} из sessionStorage
252
- Могут возникнуть проблемы с кнопкой «Назад» в NA.`, e);
253
- }
254
- throw e;
255
- }
256
- }
257
221
  /**
258
222
  * Подготавливает ссылку для корректного перехода server-side навигацией.
259
223
  *
@@ -279,8 +243,25 @@ class NativeNavigationAndTitleService {
279
243
  return modifiedUrl;
280
244
  }
281
245
  /**
282
- * Сохраняет `nativeHistoryStack` в SessionStorage.
246
+ * Читает и парсит `nativeHistoryStack` из SessionStorage.
247
+ * При ошибке чтения или парсинга логирует через `logError` и пробрасывает исключение.
283
248
  */
249
+ readSavedHistoryStack() {
250
+ const serialized = sessionStorage.getItem(query_and_headers_keys_1.SS_KEY_BRIDGE_TO_NATIVE_HISTORY_STACK);
251
+ try {
252
+ if (!serialized) {
253
+ throw new Error(`${query_and_headers_keys_1.SS_KEY_BRIDGE_TO_NATIVE_HISTORY_STACK} sessionStorage expected not to be null`);
254
+ }
255
+ return JSON.parse(serialized);
256
+ }
257
+ catch (e) {
258
+ if (this.logError) {
259
+ this.logError(`Клиентский код B2N не смог получить ${query_and_headers_keys_1.SS_KEY_BRIDGE_TO_NATIVE_HISTORY_STACK} из sessionStorage
260
+ Могут возникнуть проблемы с кнопкой «Назад» в NA.`, e);
261
+ }
262
+ throw e;
263
+ }
264
+ }
284
265
  saveNativeHistoryStack() {
285
266
  const serializedNativeHistoryStack = JSON.stringify(this.nativeHistoryStack);
286
267
  sessionStorage.setItem(query_and_headers_keys_1.SS_KEY_BRIDGE_TO_NATIVE_HISTORY_STACK, serializedNativeHistoryStack);
@@ -310,5 +291,20 @@ class NativeNavigationAndTitleService {
310
291
  }
311
292
  }
312
293
  }
294
+ setHistoryStatePageId(useNextPageId = false) {
295
+ const pageId = useNextPageId
296
+ ? this.nativeHistoryStack.length + 1
297
+ : this.nativeHistoryStack.length;
298
+ const newState = this.createStateWithPageId(window.history.state, pageId);
299
+ // `b2n-pageId` всегда записывается на верхний уровень через нативный `replaceState`,
300
+ // а не через wrapper, чтобы wrapper (например, React Router / history) не мог обернуть
301
+ // его внутрь своего формата и скрыть от B2N при чтении `history.state`.
302
+ window.history.replaceState(newState, '');
303
+ }
304
+ // eslint-disable-next-line class-methods-use-this -- удобней использовать метод в контексте экземпляра.
305
+ createStateWithPageId(state, pageId) {
306
+ const isPlainObject = (v) => v !== null && v !== undefined && typeof v === 'object' && !Array.isArray(v);
307
+ return Object.assign(Object.assign({}, (isPlainObject(state) ? state : {})), { [query_and_headers_keys_1.HISTORY_STATE_KEY_B2N_PAGE_ID]: pageId });
308
+ }
313
309
  }
314
310
  exports.NativeNavigationAndTitleService = NativeNavigationAndTitleService;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alfalab/bridge-to-native",
3
- "version": "1.3.2-beta.6ebe433",
3
+ "version": "1.3.2-beta.aecff8b",
4
4
  "license": "MIT",
5
5
  "description": "Утилита для удобной работы веб приложения внутри нативного приложения и коммуникации с ним.",
6
6
  "engines": {
@@ -1,7 +1,6 @@
1
1
  export declare const HEADER_KEY_COOKIE = "cookie";
2
2
  export declare const HEADER_KEY_USER_AGENT = "user-agent";
3
3
  export declare const COOKIE_KEY_BRIDGE_TO_NATIVE_DATA = "bridgeToNativeData";
4
- export declare const COOKIE_KEY_BRIDGE_TO_NATIVE_RELOAD = "bridgeToNativeReload";
5
4
  export declare const HEADER_KEY_NATIVE_APPVERSION = "app-version";
6
5
  export declare const HEADER_KEY_WV_LAUNCH_TIME = "webview-launch-time";
7
6
  export declare const HISTORY_STATE_KEY_B2N_PAGE_ID = "b2n-pageId";
@@ -3,7 +3,7 @@
3
3
  * Ключи стандартных заголовков.
4
4
  */
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.SS_KEY_BRIDGE_TO_NATIVE_HISTORY_STACK = exports.QUERY_NATIVE_THEME = exports.QUERY_NATIVE_IOS_APPVERSION = exports.QUERY_NATIVE_IOS_APPID = exports.QUERY_B2N_TITLE_DEPRECATED = exports.QUERY_B2N_TITLE = exports.QUERY_B2N_NEXT_PAGEID = exports.HISTORY_STATE_KEY_B2N_PAGE_ID = exports.HEADER_KEY_WV_LAUNCH_TIME = exports.HEADER_KEY_NATIVE_APPVERSION = exports.COOKIE_KEY_BRIDGE_TO_NATIVE_RELOAD = exports.COOKIE_KEY_BRIDGE_TO_NATIVE_DATA = exports.HEADER_KEY_USER_AGENT = exports.HEADER_KEY_COOKIE = void 0;
6
+ exports.SS_KEY_BRIDGE_TO_NATIVE_HISTORY_STACK = exports.QUERY_NATIVE_THEME = exports.QUERY_NATIVE_IOS_APPVERSION = exports.QUERY_NATIVE_IOS_APPID = exports.QUERY_B2N_TITLE_DEPRECATED = exports.QUERY_B2N_TITLE = exports.QUERY_B2N_NEXT_PAGEID = exports.HISTORY_STATE_KEY_B2N_PAGE_ID = exports.HEADER_KEY_WV_LAUNCH_TIME = exports.HEADER_KEY_NATIVE_APPVERSION = exports.COOKIE_KEY_BRIDGE_TO_NATIVE_DATA = exports.HEADER_KEY_USER_AGENT = exports.HEADER_KEY_COOKIE = void 0;
7
7
  exports.HEADER_KEY_COOKIE = 'cookie';
8
8
  exports.HEADER_KEY_USER_AGENT = 'user-agent';
9
9
  /*
@@ -11,26 +11,25 @@ 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, указывающий, что запрос выполнен после вызова `bridgeToNative.reload()`.
15
- // Используется для предотвращения перезаписи cookie bridgeToNativeData, чтобы сохранить
16
- // актуальные параметры нативного приложения
17
- exports.COOKIE_KEY_BRIDGE_TO_NATIVE_RELOAD = 'bridgeToNativeReload';
18
- // Нативное приложение на обеих платформах подмешивает этот заголовок к запросу за HTML.
14
+ // NA на обеих платформах подмешивает этот заголовок к запросу за HTML.
19
15
  // TODO:
20
16
  // * Исследовать, делает ли оно это при запросах к прочим ресурсам;
21
17
  // * Есть подозрение на некоторую нестабильность — возможно делает это
22
18
  // только для первого документа в вебвью-сессии. Исследовать.
23
19
  exports.HEADER_KEY_NATIVE_APPVERSION = 'app-version';
24
- // Ключ заголовка, в котором передается время старта открытия WV экрана в формате timestamp
20
+ // Ключ заголовка, в котором NA передаёт время старта открытия WV экрана в формате timestamp.
25
21
  exports.HEADER_KEY_WV_LAUNCH_TIME = 'webview-launch-time';
26
- // Ключ в history.state, хранящий текущий pageId для корректной back-навигации.
22
+ // Ключ в history.state, который B2N использует для хранения текущего `pageId`
23
+ // чтобы иметь возможность корректно синхронизироваться с NA после back-навигации.
27
24
  exports.HISTORY_STATE_KEY_B2N_PAGE_ID = 'b2n-pageId';
28
25
  // Флаг, предписывающий клиентскому коду B2N начать связь
29
26
  // с нативным приложением с указанного в этом параметре id, а не с 1.
30
- // Необходимо для server-side навигации.
27
+ // Необходимо для server-side (hard) навигации.
31
28
  exports.QUERY_B2N_NEXT_PAGEID = 'b2n-next-page-id';
32
- // Query-параметр, с помощью которого можно передать начальное значение
29
+ // Query-параметр, который можно подмешать к URL в диплинке на открытие WV,
30
+ // и с помощью которого можно передать начальное значение
33
31
  // для нативного заголовка — в область, которую не рендерит веб.
32
+ // Также некоторые методы навигации B2N используют эту сущность.
34
33
  exports.QUERY_B2N_TITLE = 'b2n-title';
35
34
  // Deprecated вариант query-параметра 'b2n-title'
36
35
  // (т.к. `title` часто может использоваться самим веб-приложением).
@@ -38,18 +37,18 @@ exports.QUERY_B2N_TITLE = 'b2n-title';
38
37
  exports.QUERY_B2N_TITLE_DEPRECATED = 'title';
39
38
  // NA на iOS передаёт в этом параметре схему,
40
39
  // под которым оно зарегистрировано в OS.
41
- // Известные проблемы:
42
- // * В старых версиях отсутствует, клиентский код использует хардкод (см. `src/client/constants.ts`);
43
- // * В тестовых сборках часто нарушена связь!!! Между фактической схемой
44
- // и схемой, которая приходит в этом параметре.
45
- // Нужно просить iOS разработчика собрать сборку нормально.
40
+ // Некоторые особенности:
41
+ // * В старых версиях отсутствует, клиентский код использует хардкод
42
+ // (см. `VERSION_TO_IOS_APP_ID` в `src/client/constants.ts`);
43
+ // * Тестить WV на iOS надо на группе «B»!!! Иначе NA будет присылать в WA неверную схему,
44
+ // что приведёт к неработоспособности методов, связанных с передачей диплинков в NA.
45
+ // * В сборках для Симулятора, схема всегда `aweassist`.
46
46
  exports.QUERY_NATIVE_IOS_APPID = 'applicationId';
47
- // Исторически NA на iOS передаёт в этом параметре свою версию.
48
- // B2N сознательно переиспользует этот query и для server-side переходов в Android,
47
+ // NA на iOS передаёт в этом параметре свою версию.
48
+ // B2N сознательно переиспользует этот query и для server-side (hard) переходов в Android,
49
49
  // чтобы не вводить отдельный служебный параметр только для переноса версии между WA.
50
50
  exports.QUERY_NATIVE_IOS_APPVERSION = 'device_app_version';
51
51
  // NA на обеих платформах в этом параметре передаёт активную тему (светлая/тёмная).
52
52
  exports.QUERY_NATIVE_THEME = 'theme';
53
- // Ключ sesseionStorage, с помощью которого клиентская часть B2N сохраняет своё состояние
54
- // при server-side навигации.
53
+ // Ключ sessionStorage,в котором клиентская часть B2N сохраняет состояние синхронизации с NA.
55
54
  exports.SS_KEY_BRIDGE_TO_NATIVE_HISTORY_STACK = 'bridgeToNativeHistoryStack';
@@ -19,21 +19,9 @@ const utils_1 = require("./utils");
19
19
  function prepareNativeAppDetailsForClient(request, setResponseHeader) {
20
20
  // Поскольку вебвью модули имеют особенность сохранять сессионную куку подолгу,
21
21
  // даже после перезагрузки устройства или обновления приложения/ОС, ее значение
22
- // актуализируется при каждом запросе на сервер. Исключением является вызов `reload()`.
23
- // В этом случае функция возвращает объект с параметрами, полученными из
24
- // ранее сохраненной куки, но перезаписываться кука не будет, потому что:
25
- // 1) Данных NA в запросе с большой вероятностью не будет;
26
- // 2) клиентская сторона сохранит всё, что нужно в SessionStorage
22
+ // актуализируется при каждом запросе на сервер.
27
23
  const cookieHeader = (0, utils_1.getHeaderValue)(request, query_and_headers_keys_1.HEADER_KEY_COOKIE);
28
24
  const nativeParamsFromCookie = (0, utils_1.readNativeParamsFromCookie)(cookieHeader);
29
- const hasReloadFlag = cookieHeader?.includes(`${query_and_headers_keys_1.COOKIE_KEY_BRIDGE_TO_NATIVE_RELOAD}=true`);
30
- if (hasReloadFlag) {
31
- setResponseHeader('Set-Cookie', `${query_and_headers_keys_1.COOKIE_KEY_BRIDGE_TO_NATIVE_RELOAD}=false; Max-Age=0; Path=/`);
32
- if (nativeParamsFromCookie) {
33
- return nativeParamsFromCookie;
34
- }
35
- return buildNativeParams(request);
36
- }
37
25
  const nativeParams = buildNativeParams(request, nativeParamsFromCookie);
38
26
  const serializedNativeParams = encodeURIComponent(JSON.stringify(nativeParams));
39
27
  setResponseHeader('Set-Cookie', `${query_and_headers_keys_1.COOKIE_KEY_BRIDGE_TO_NATIVE_DATA}=${serializedNativeParams}; Path=/`);