@vkontakte/calls-sdk 2.8.13-dev.47735529.0 → 2.8.13-dev.49da331a.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.
- package/calls-sdk.cjs.js +5 -5
- package/calls-sdk.esm.js +598 -737
- package/classes/stat/CallLifecycleStats.d.ts +8 -8
- package/classes/stat/CallStatTail.d.ts +76 -0
- package/classes/stat/CodecStatsAggregator.d.ts +4 -1
- package/classes/stat/ConversationStats.d.ts +9 -4
- package/classes/stat/StatDrainScheduler.d.ts +13 -10
- package/classes/stat/StatEventCollector.d.ts +5 -8
- package/classes/stat/StatPings.d.ts +3 -1
- package/classes/stat/StatQueue.d.ts +35 -7
- package/classes/stat/StatSignalingCommands.d.ts +3 -1
- package/package.json +1 -1
- package/classes/stat/ProvisionalFinish.d.ts +0 -37
- package/classes/stat/ProvisionalFinishStore.d.ts +0 -104
- package/classes/stat/StatUnloadJournal.d.ts +0 -27
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import StatEventCollector from './StatEventCollector';
|
|
2
|
-
import {
|
|
2
|
+
import { CallStatTail } from './CallStatTail';
|
|
3
3
|
export type CallLifecycleSource = 'outgoing' | 'incoming' | 'join' | 'anonym_join';
|
|
4
4
|
export interface CallLifecycleInitializationParams {
|
|
5
5
|
source: CallLifecycleSource;
|
|
@@ -12,8 +12,8 @@ export interface CallLifecycleClock {
|
|
|
12
12
|
export declare class CallLifecycleStats {
|
|
13
13
|
private readonly _logger;
|
|
14
14
|
private readonly _clock;
|
|
15
|
-
/**
|
|
16
|
-
private readonly
|
|
15
|
+
/** Хвост звонка в очереди; null — выключен */
|
|
16
|
+
private readonly _tail;
|
|
17
17
|
private _conversationId;
|
|
18
18
|
private _callStartLabel;
|
|
19
19
|
private _lifecycleStartedAtMonotonic;
|
|
@@ -23,7 +23,7 @@ export declare class CallLifecycleStats {
|
|
|
23
23
|
private _firstMediaSent;
|
|
24
24
|
private _finished;
|
|
25
25
|
private _destroyed;
|
|
26
|
-
constructor(logger: StatEventCollector, clock?: CallLifecycleClock,
|
|
26
|
+
constructor(logger: StatEventCollector, clock?: CallLifecycleClock, tail?: CallStatTail | null);
|
|
27
27
|
get firstMediaSentReported(): boolean;
|
|
28
28
|
get terminated(): boolean;
|
|
29
29
|
markInitializationStarted({ source, conversationId }: CallLifecycleInitializationParams): void;
|
|
@@ -34,15 +34,15 @@ export declare class CallLifecycleStats {
|
|
|
34
34
|
markFirstMediaSent(): void;
|
|
35
35
|
markFinished(reason: unknown): void;
|
|
36
36
|
markTerminated(): void;
|
|
37
|
-
/** Вкладка скрыта: обновляет время в
|
|
37
|
+
/** Вкладка скрыта: обновляет время в хвосте звонка. */
|
|
38
38
|
markHidden(): void;
|
|
39
|
-
/** Вкладка снова видна: обновляет время в
|
|
39
|
+
/** Вкладка снова видна: обновляет время в хвосте звонка. */
|
|
40
40
|
markVisible(): void;
|
|
41
41
|
destroy(): void;
|
|
42
42
|
private _canRecord;
|
|
43
43
|
private _durationSince;
|
|
44
|
-
/** Ведёт
|
|
45
|
-
private
|
|
44
|
+
/** Ведёт хвост звонка, когда известен conversationId. */
|
|
45
|
+
private _startTail;
|
|
46
46
|
private _finish;
|
|
47
47
|
private _ensureConversationId;
|
|
48
48
|
private _record;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type StatEventCollector from './StatEventCollector';
|
|
2
|
+
import type { ClientStatsPayload } from './StatEventCollector';
|
|
3
|
+
export interface CallStatTailClock {
|
|
4
|
+
wallNow(): number;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Хвост звонка: call_finish с причиной terminated и итоги звонка, которые
|
|
8
|
+
* лежат в очереди статистики, пока звонок идёт. Время в хвосте — последний
|
|
9
|
+
* момент, когда вкладка была жива. Если вкладка умрёт, не закончив звонок,
|
|
10
|
+
* хвост перенесёт в очередь другая вкладка или следующий старт SDK.
|
|
11
|
+
*
|
|
12
|
+
* Пока хвост ведётся, вкладка держит замок звонка: свободный замок значит,
|
|
13
|
+
* что вкладки больше нет или она выгружена.
|
|
14
|
+
*/
|
|
15
|
+
export declare class CallStatTail {
|
|
16
|
+
private static _tabId;
|
|
17
|
+
/** id вкладки, создаётся при первом обращении */
|
|
18
|
+
static get tabId(): string;
|
|
19
|
+
static lockName(key: string): string;
|
|
20
|
+
static isSupported(): boolean;
|
|
21
|
+
private readonly _logger;
|
|
22
|
+
private readonly _summaries;
|
|
23
|
+
private readonly _clock;
|
|
24
|
+
private _status;
|
|
25
|
+
private _vcid;
|
|
26
|
+
private _key;
|
|
27
|
+
/** Первая запись хвоста; null — ещё не было или не удалась */
|
|
28
|
+
private _creation;
|
|
29
|
+
/** Последний снимок итогов звонка */
|
|
30
|
+
private _summaryCache;
|
|
31
|
+
private _touches;
|
|
32
|
+
private _timer;
|
|
33
|
+
/** Отпускает замок звонка */
|
|
34
|
+
private _releaseLock;
|
|
35
|
+
/** Запросы замка подряд, которые закончились без выдачи */
|
|
36
|
+
private _lockFailures;
|
|
37
|
+
/** Вызывается, когда хвост забрала другая вкладка */
|
|
38
|
+
private _onAdopted;
|
|
39
|
+
/** @param summaries итоги звонка на текущий момент: codec_usage и сводки сигналинга */
|
|
40
|
+
constructor(logger: StatEventCollector, summaries: () => ClientStatsPayload[], clock?: CallStatTailClock);
|
|
41
|
+
/** Начинает вести хвост звонка: сначала замок, потом запись. */
|
|
42
|
+
start(vcid: string, onAdopted: () => void): void;
|
|
43
|
+
/** Перезаписывает хвост с текущим временем. */
|
|
44
|
+
touch(): void;
|
|
45
|
+
/**
|
|
46
|
+
* Звонок закончился: снимает хвост и вызывает write, который пишет
|
|
47
|
+
* настоящий финиш. Если хвост уже забрала другая вкладка, write не
|
|
48
|
+
* вызывается.
|
|
49
|
+
*/
|
|
50
|
+
complete(write: () => void): void;
|
|
51
|
+
/** Снимает хвост без финиша. */
|
|
52
|
+
stop(): void;
|
|
53
|
+
/**
|
|
54
|
+
* Вкладка выгружается: хвост остаётся на диске, замок отпускается. Из
|
|
55
|
+
* pagehide запись в IndexedDB не коммитится, поэтому хвост и есть финиш.
|
|
56
|
+
*/
|
|
57
|
+
abandon(): void;
|
|
58
|
+
private _requestLock;
|
|
59
|
+
/** Замок держится, пока не разрешён возвращённый промис. */
|
|
60
|
+
private _onLockGranted;
|
|
61
|
+
/**
|
|
62
|
+
* Замок отпустили мы, его отняли (Safari при приостановке страницы) или
|
|
63
|
+
* не выдали. Отнятый просим снова: пока его нет, хвост может забрать
|
|
64
|
+
* другая вкладка, и следующая запись это заметит.
|
|
65
|
+
*/
|
|
66
|
+
private _onLockGone;
|
|
67
|
+
private _onTimer;
|
|
68
|
+
/** Первая запись создаёт хвост, остальные обновляют его, только если он ещё лежит. */
|
|
69
|
+
private _write;
|
|
70
|
+
private _buildTail;
|
|
71
|
+
private _collectSummaries;
|
|
72
|
+
private _adopt;
|
|
73
|
+
private _finish;
|
|
74
|
+
private _release;
|
|
75
|
+
private _clearTimer;
|
|
76
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { StatItem } from '../../types/Statistics';
|
|
2
|
-
import StatEventCollector from './StatEventCollector';
|
|
2
|
+
import StatEventCollector, { ClientStatsPayload } from './StatEventCollector';
|
|
3
3
|
import TransportTopology from '../../enums/TransportTopology';
|
|
4
4
|
export type CodecKind = 'audio' | 'video';
|
|
5
5
|
/**
|
|
@@ -13,7 +13,10 @@ export declare class CodecStatsAggregator {
|
|
|
13
13
|
private readonly getCurrentTransportTopology;
|
|
14
14
|
constructor(logger: StatEventCollector, getCurrentTransportTopology: () => TransportTopology | undefined);
|
|
15
15
|
reportUsage(stat: StatItem): void;
|
|
16
|
+
/** События codec_usage, которые ушли бы сейчас при конце звонка: по текущему кодеку аудио и видео. */
|
|
17
|
+
usageReports(): ClientStatsPayload[];
|
|
16
18
|
private saveUsage;
|
|
17
19
|
private report;
|
|
20
|
+
private _toLog;
|
|
18
21
|
destroy(): void;
|
|
19
22
|
}
|
|
@@ -22,15 +22,18 @@ export declare class ConversationStats {
|
|
|
22
22
|
readonly resources: ClientResourceStats;
|
|
23
23
|
readonly battery: BatteryStats;
|
|
24
24
|
private readonly _api;
|
|
25
|
+
/** Хвост звонка в очереди; null — выключен */
|
|
26
|
+
private readonly _tail;
|
|
25
27
|
private _unloading;
|
|
26
28
|
constructor(api: BaseApi, externalLogger: BaseLogger | null, getConversationId: () => string | null, getTopology: () => TransportTopology | undefined, resourceSources: ClientResourceSources);
|
|
27
29
|
/**
|
|
28
|
-
* Вызывается из pagehide
|
|
29
|
-
*
|
|
30
|
-
*
|
|
30
|
+
* Вызывается из pagehide-обработчика. Запись в IndexedDB оттуда не
|
|
31
|
+
* коммитится, поэтому финиш и итоги звонка доставит его хвост, а
|
|
32
|
+
* коллектор перестаёт писать в очередь. Сводки пингов и команд
|
|
33
|
+
* логируем ради onClientStats: destroy() их только очищает.
|
|
31
34
|
*/
|
|
32
35
|
prepareForUnload(): void;
|
|
33
|
-
/** Вкладка пережила pagehide:
|
|
36
|
+
/** Вкладка пережила pagehide: снова пишем в очередь. */
|
|
34
37
|
restoreAfterUnload(): void;
|
|
35
38
|
resetPingBaseline(): void;
|
|
36
39
|
markHidden(): void;
|
|
@@ -38,4 +41,6 @@ export declare class ConversationStats {
|
|
|
38
41
|
logHangup(reason: HangupReason): void;
|
|
39
42
|
flushCallMetrics(): void;
|
|
40
43
|
destroy(): void;
|
|
44
|
+
/** Итоги звонка, которые уйдут в хвосте, если вкладка умрёт посреди звонка. */
|
|
45
|
+
private _callSummaries;
|
|
41
46
|
}
|
|
@@ -15,17 +15,10 @@ export default abstract class StatDrainScheduler {
|
|
|
15
15
|
/** Буфер прямой отправки: события, которые не легли в хранилище. */
|
|
16
16
|
private static _directBuffer;
|
|
17
17
|
private static _directTimer;
|
|
18
|
+
private static _tailRecheckTimer;
|
|
18
19
|
static setApi(value: BaseApi): void;
|
|
19
20
|
/** Первый дрейн подбирает хвосты прошлых сессий и закрытых вкладок. */
|
|
20
21
|
static start(value: BaseApi): void;
|
|
21
|
-
/**
|
|
22
|
-
* Переносит журналы закрытых вкладок в очередь под замком отправки:
|
|
23
|
-
* перенос предварительных финишей сверяется с очередью и не должен
|
|
24
|
-
* застать журнал забранным, но ещё не записанным.
|
|
25
|
-
*
|
|
26
|
-
* @returns число перенесённых событий.
|
|
27
|
-
*/
|
|
28
|
-
static importUnloadJournal(): Promise<number>;
|
|
29
22
|
/** Вызывается коллектором после записи события в очередь. */
|
|
30
23
|
static notifyAppended(): void;
|
|
31
24
|
/**
|
|
@@ -49,8 +42,18 @@ export default abstract class StatDrainScheduler {
|
|
|
49
42
|
*/
|
|
50
43
|
static sendDirect(entry: StatQueueEntry): void;
|
|
51
44
|
private static _currentUserId;
|
|
52
|
-
/**
|
|
53
|
-
|
|
45
|
+
/**
|
|
46
|
+
* Переносит в очередь хвосты звонков умерших и выгруженных вкладок:
|
|
47
|
+
* свободный замок звонка значит, что вести хвост больше некому. Хвосты
|
|
48
|
+
* живых вкладок проверяются снова через TAIL_RECHECK_DELAY_MS, иначе
|
|
49
|
+
* простаивающая вкладка подобрала бы их только на своей отправке.
|
|
50
|
+
* Вызывается под замком отправки. Не бросает.
|
|
51
|
+
*
|
|
52
|
+
* @returns число перенесённых хвостов.
|
|
53
|
+
*/
|
|
54
|
+
private static _adoptCallTails;
|
|
55
|
+
private static _armTailRecheck;
|
|
56
|
+
private static _clearTailRecheckTimer;
|
|
54
57
|
/** @returns число записей в батче. */
|
|
55
58
|
private static _drainCurrent;
|
|
56
59
|
/**
|
|
@@ -3,7 +3,7 @@ import BaseLogger from '../../abstract/BaseLogger';
|
|
|
3
3
|
import StatLog from '../../enums/StatLog';
|
|
4
4
|
import TransportTopology from '../../enums/TransportTopology';
|
|
5
5
|
import { StatQueueEntry } from './StatQueue';
|
|
6
|
-
type ClientStatsPayload = Record<string, string | string[] | number | boolean | undefined | null>;
|
|
6
|
+
export type ClientStatsPayload = Record<string, string | string[] | number | boolean | undefined | null>;
|
|
7
7
|
export type LogClientStatsOptions = {
|
|
8
8
|
/** Время наступления события. По умолчанию — момент записи. */
|
|
9
9
|
occurredAt?: number;
|
|
@@ -33,14 +33,12 @@ export default class StatEventCollector extends BaseLogger {
|
|
|
33
33
|
constructor(api: BaseApi, externalLogger: BaseLogger | null, conversationIdProvider: () => string | null, topologyProvider?: () => TransportTopology | undefined);
|
|
34
34
|
log(name: StatLog, value?: string, immediately?: boolean): void;
|
|
35
35
|
/**
|
|
36
|
-
*
|
|
37
|
-
*
|
|
36
|
+
* После pagehide события не пишутся в очередь: запись в IndexedDB оттуда
|
|
37
|
+
* не коммитится, а в bfcache закоммитилась бы позже и задвоила хвост
|
|
38
|
+
* звонка. Конец звонка доставит его хвост.
|
|
38
39
|
*/
|
|
39
40
|
enterUnloadMode(): void;
|
|
40
|
-
/**
|
|
41
|
-
* Вкладка пережила pagehide (bfcache, отменённая навигация): возвращаемся
|
|
42
|
-
* на очередь и переносим в неё уже записанное в журнал.
|
|
43
|
-
*/
|
|
41
|
+
/** Вкладка пережила pagehide (bfcache, отменённая навигация): снова пишем в очередь. */
|
|
44
42
|
exitUnloadMode(): void;
|
|
45
43
|
logClientStats(data: ClientStatsPayload, options?: LogClientStatsOptions): void;
|
|
46
44
|
/**
|
|
@@ -55,4 +53,3 @@ export default class StatEventCollector extends BaseLogger {
|
|
|
55
53
|
private _getConversationId;
|
|
56
54
|
private _getCallTopology;
|
|
57
55
|
}
|
|
58
|
-
export {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { SignalingTransportType } from '../../enums/SignalingTransportStat';
|
|
2
|
-
import StatEventCollector from './StatEventCollector';
|
|
2
|
+
import StatEventCollector, { ClientStatsPayload } from './StatEventCollector';
|
|
3
3
|
export declare class StatPings {
|
|
4
4
|
private readonly _logger;
|
|
5
5
|
private trackerByTransport;
|
|
@@ -12,6 +12,8 @@ export declare class StatPings {
|
|
|
12
12
|
mark(transport: SignalingTransportType): void;
|
|
13
13
|
/** Отправляем данные в стату */
|
|
14
14
|
logMetrics(): void;
|
|
15
|
+
/** Сводки на текущий момент, без отправки и без сброса. */
|
|
16
|
+
summaries(): ClientStatsPayload[];
|
|
15
17
|
/** Сбрасываем baseline после скрытия страницы, чтобы фоновой простой не стал интервалом ping. */
|
|
16
18
|
resetBaseline(): void;
|
|
17
19
|
destroy(): void;
|
|
@@ -21,6 +21,19 @@ export type StatQueueRecord = StatQueueEntry & {
|
|
|
21
21
|
/** Автоинкремент. Единственный источник истины для порядка событий. */
|
|
22
22
|
id: number;
|
|
23
23
|
};
|
|
24
|
+
/**
|
|
25
|
+
* Хвост идущего звонка: события, которые уйдут, если вкладка умрёт, не
|
|
26
|
+
* закончив звонок, — call_finish с причиной terminated и итоги звонка.
|
|
27
|
+
*/
|
|
28
|
+
export type StatTail = {
|
|
29
|
+
/** `<id вкладки>.<conversationId>` */
|
|
30
|
+
key: string;
|
|
31
|
+
uid: number;
|
|
32
|
+
vcid: string;
|
|
33
|
+
/** Момент записи хвоста в device-time. */
|
|
34
|
+
ts: number;
|
|
35
|
+
entries: StatQueueEntry[];
|
|
36
|
+
};
|
|
24
37
|
/**
|
|
25
38
|
* Персистентная очередь событий статистики поверх IndexedDB.
|
|
26
39
|
*
|
|
@@ -39,15 +52,24 @@ export default abstract class StatQueue {
|
|
|
39
52
|
static isSupported(): boolean;
|
|
40
53
|
/** @returns ключ записи или null, если хранилище не приняло её. */
|
|
41
54
|
static append(entry: StatQueueEntry): Promise<number | null>;
|
|
55
|
+
/** Создаёт или перезаписывает хвост звонка. @returns false — хранилище недоступно. */
|
|
56
|
+
static putTail(tail: StatTail): Promise<boolean>;
|
|
42
57
|
/**
|
|
43
|
-
*
|
|
44
|
-
*
|
|
58
|
+
* Обновляет хвост, только если он ещё лежит: пропавший хвост забрала
|
|
59
|
+
* другая вкладка, воскрешать его нельзя.
|
|
60
|
+
*/
|
|
61
|
+
static updateTail(tail: StatTail): Promise<'updated' | 'missing' | 'failed'>;
|
|
62
|
+
/** Удаляет хвост. 'missing' — его уже забрала другая вкладка. */
|
|
63
|
+
static removeTail(key: string): Promise<'removed' | 'missing' | 'failed'>;
|
|
64
|
+
static listTailKeys(): Promise<string[]>;
|
|
65
|
+
/**
|
|
66
|
+
* Переносит хвост в очередь одной транзакцией. Если у звонка этого
|
|
67
|
+
* пользователя call_finish уже есть, хвост просто удаляется.
|
|
45
68
|
*
|
|
46
|
-
* @returns 'added' —
|
|
69
|
+
* @returns 'added' — события хвоста в очереди, 'exists' — финиш уже был,
|
|
70
|
+
* 'missing' — хвоста нет, 'failed' — хранилище недоступно.
|
|
47
71
|
*/
|
|
48
|
-
static
|
|
49
|
-
vcid: string;
|
|
50
|
-
}): Promise<'added' | 'exists' | 'failed'>;
|
|
72
|
+
static adoptTail(key: string): Promise<'added' | 'exists' | 'missing' | 'failed'>;
|
|
51
73
|
/**
|
|
52
74
|
* Проставляет delta перечисленным записям, у которых её ещё нет.
|
|
53
75
|
*
|
|
@@ -78,9 +100,15 @@ export default abstract class StatQueue {
|
|
|
78
100
|
/** Раз в EVICT_CHECK_EVERY записей подрезает хранилище до лимита. */
|
|
79
101
|
private static _countAppend;
|
|
80
102
|
private static _close;
|
|
103
|
+
/** Создаёт недостающие таблицы: и новую базу, и базу версии 1 с событиями. */
|
|
81
104
|
private static _createSchema;
|
|
82
|
-
/**
|
|
105
|
+
/**
|
|
106
|
+
* Обёртка над транзакцией: резолвится после успешного коммита. body
|
|
107
|
+
* получает первую из таблиц и саму транзакцию — для остальных.
|
|
108
|
+
*/
|
|
83
109
|
private static _runTransaction;
|
|
110
|
+
/** Результат запроса внутри транзакции. */
|
|
111
|
+
private static _request;
|
|
84
112
|
/** Читает запись с минимальным id, то есть самую старую в хранилище. */
|
|
85
113
|
private static _readOldestRecord;
|
|
86
114
|
/**
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { SignalingTransportType } from '../../enums/SignalingTransportStat';
|
|
2
|
-
import StatEventCollector from './StatEventCollector';
|
|
2
|
+
import StatEventCollector, { ClientStatsPayload } from './StatEventCollector';
|
|
3
3
|
export declare class StatSignalingCommands {
|
|
4
4
|
private readonly _logger;
|
|
5
5
|
private trackerByCommand;
|
|
@@ -7,5 +7,7 @@ export declare class StatSignalingCommands {
|
|
|
7
7
|
mark(command: string, time: number, transport: SignalingTransportType): void;
|
|
8
8
|
/** Отправляем данные в стату */
|
|
9
9
|
logMetrics(): void;
|
|
10
|
+
/** Сводки на текущий момент, без отправки и без сброса. */
|
|
11
|
+
summaries(): ClientStatsPayload[];
|
|
10
12
|
destroy(): void;
|
|
11
13
|
}
|
package/package.json
CHANGED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import { ProvisionalFinishStore } from './ProvisionalFinishStore';
|
|
2
|
-
import StatEventCollector from './StatEventCollector';
|
|
3
|
-
export interface ProvisionalFinishClock {
|
|
4
|
-
wallNow(): number;
|
|
5
|
-
}
|
|
6
|
-
/**
|
|
7
|
-
* Предварительный финиш одного звонка: call_finish с причиной terminated,
|
|
8
|
-
* который лежит в localStorage, пока звонок идёт. Время в нём — последний
|
|
9
|
-
* момент, когда вкладка была жива. Если вкладка умрёт без финиша, запись
|
|
10
|
-
* перенесёт в очередь другая вкладка или следующий старт SDK.
|
|
11
|
-
*/
|
|
12
|
-
export declare class ProvisionalFinish {
|
|
13
|
-
private readonly _logger;
|
|
14
|
-
private readonly _store;
|
|
15
|
-
private readonly _clock;
|
|
16
|
-
private _status;
|
|
17
|
-
/** conversationId звонка */
|
|
18
|
-
private _vcid;
|
|
19
|
-
/** Вызывается, когда финиш звонка отправила другая вкладка */
|
|
20
|
-
private _onAdopted;
|
|
21
|
-
private _timer;
|
|
22
|
-
constructor(logger: StatEventCollector, store?: ProvisionalFinishStore, clock?: ProvisionalFinishClock);
|
|
23
|
-
/** Начинает вести запись звонка. */
|
|
24
|
-
start(vcid: string, onAdopted: () => void): void;
|
|
25
|
-
/** Перезаписывает запись с текущим временем. */
|
|
26
|
-
update(): void;
|
|
27
|
-
/**
|
|
28
|
-
* Звонок закончился: снимает запись и вызывает write, который пишет
|
|
29
|
-
* настоящий финиш. При своём замке всё идёт синхронно, в том же тике.
|
|
30
|
-
* Финиш, уже отправленный другой вкладкой, не пишется.
|
|
31
|
-
*/
|
|
32
|
-
complete(write: () => void): void;
|
|
33
|
-
/** Снимает запись без финиша. */
|
|
34
|
-
stop(): void;
|
|
35
|
-
private _adopt;
|
|
36
|
-
private _clearTimer;
|
|
37
|
-
}
|
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
import { StatQueueEntry } from './StatQueue';
|
|
2
|
-
/** Запись старше не переносим: до предела очереди нужен запас на отправку. */
|
|
3
|
-
export declare const MAX_RECORD_AGE_MS: number;
|
|
4
|
-
/** Предварительный финиш: запись очереди и id вкладки-владельца. */
|
|
5
|
-
export type ProvisionalFinishRecord = StatQueueEntry & {
|
|
6
|
-
/** conversationId звонка */
|
|
7
|
-
vcid: string;
|
|
8
|
-
/** id вкладки, которая ведёт звонок */
|
|
9
|
-
tab: string;
|
|
10
|
-
};
|
|
11
|
-
export type ProvisionalFinishStoreOptions = {
|
|
12
|
-
/** Префикс ключей в localStorage */
|
|
13
|
-
keyPrefix?: string;
|
|
14
|
-
/** Префикс имени замка вкладки */
|
|
15
|
-
lockPrefix?: string;
|
|
16
|
-
};
|
|
17
|
-
/**
|
|
18
|
-
* Предварительные финиши звонков вкладки в localStorage. Пока у вкладки есть
|
|
19
|
-
* звонки, она держит Web Lock со своим id и пишет свои записи только под ним.
|
|
20
|
-
* Записи вкладок, чей замок свободен, переносит в очередь adoptOrphans().
|
|
21
|
-
*/
|
|
22
|
-
export declare class ProvisionalFinishStore {
|
|
23
|
-
private readonly _keyPrefix;
|
|
24
|
-
private readonly _lockPrefix;
|
|
25
|
-
/** id документа, создаётся при первом обращении */
|
|
26
|
-
private _tabId;
|
|
27
|
-
/** Число звонков вкладки с предварительным финишем */
|
|
28
|
-
private _holders;
|
|
29
|
-
private _lockState;
|
|
30
|
-
/** Номер текущего запроса замка */
|
|
31
|
-
private _generation;
|
|
32
|
-
/** Отпускает выданный замок */
|
|
33
|
-
private _releaseLock;
|
|
34
|
-
/** Записи, которые ждут первой выдачи замка, по vcid */
|
|
35
|
-
private _waiting;
|
|
36
|
-
/** vcid своих записей, лежащих в localStorage */
|
|
37
|
-
private _written;
|
|
38
|
-
/** vcid, чьи записи забрала другая вкладка */
|
|
39
|
-
private _adopted;
|
|
40
|
-
/** Ждут возврата замка */
|
|
41
|
-
private _whenOwned;
|
|
42
|
-
constructor({ keyPrefix, lockPrefix }?: ProvisionalFinishStoreOptions);
|
|
43
|
-
/** id документа */
|
|
44
|
-
get tabId(): string;
|
|
45
|
-
isSupported(): boolean;
|
|
46
|
-
/** Звонок начал держать запись: при первом звонке вкладка просит замок. */
|
|
47
|
-
hold(): void;
|
|
48
|
-
/** Звонок больше не держит запись: после последнего замок отпускается. */
|
|
49
|
-
unhold(): void;
|
|
50
|
-
/** Пишет запись звонка. Пока замок не выдан или не возвращён, запись ждёт в памяти. */
|
|
51
|
-
save(record: ProvisionalFinishRecord): void;
|
|
52
|
-
remove(vcid: string): void;
|
|
53
|
-
/** Запись звонка забрала другая вкладка, пока у этой не было замка. */
|
|
54
|
-
isAdopted(vcid: string): boolean;
|
|
55
|
-
/** Вызывает callback, когда записи вкладки снова под её замком; если замок не отнимали — сразу. */
|
|
56
|
-
whenOwned(callback: () => void): void;
|
|
57
|
-
/**
|
|
58
|
-
* Переносит в очередь записи вкладок, чей замок свободен. Вызывается под
|
|
59
|
-
* замком отправки. Не бросает.
|
|
60
|
-
*
|
|
61
|
-
* @returns число добавленных финишей.
|
|
62
|
-
*/
|
|
63
|
-
adoptOrphans(now?: number): Promise<number>;
|
|
64
|
-
private _requestLock;
|
|
65
|
-
/** Колбэк выдачи замка. Замок держится, пока не разрешён возвращённый промис. */
|
|
66
|
-
private _onGranted;
|
|
67
|
-
/** Промис запроса замка завершился: замок отпустили мы, его отняли или не выдали. */
|
|
68
|
-
private _onLockGone;
|
|
69
|
-
private _fail;
|
|
70
|
-
private _release;
|
|
71
|
-
/** Сверяет все свои записи после возврата замка. */
|
|
72
|
-
private _markAdopted;
|
|
73
|
-
/**
|
|
74
|
-
* Чужие вкладки трогают наши ключи только под нашим замком. Поэтому
|
|
75
|
-
* пропавший свой ключ значит, что запись забрала другая вкладка: замок
|
|
76
|
-
* у нас отнимали, даже если уведомление об этом ещё не пришло. Ошибку
|
|
77
|
-
* чтения переносом не считаем: лишний финиш лучше потерянного.
|
|
78
|
-
*
|
|
79
|
-
* @returns true, если запись звонка забрали.
|
|
80
|
-
*/
|
|
81
|
-
private _detectAdopted;
|
|
82
|
-
private _writeWaiting;
|
|
83
|
-
private _flushWhenOwned;
|
|
84
|
-
private _run;
|
|
85
|
-
private _write;
|
|
86
|
-
/** Ключи записей других вкладок, сгруппированные по вкладке. Битые и протухшие записи удаляет. */
|
|
87
|
-
private _findOrphans;
|
|
88
|
-
/**
|
|
89
|
-
* Переносит одну запись под замком её вкладки. Порядок «добавить, потом
|
|
90
|
-
* удалить ключ»: при обрыве между шагами следующий перенос получит exists.
|
|
91
|
-
*
|
|
92
|
-
* @returns true, если финиш добавлен в очередь.
|
|
93
|
-
*/
|
|
94
|
-
private _adoptOne;
|
|
95
|
-
/** Разбирает запись. null — битый JSON или не та форма. */
|
|
96
|
-
private _parse;
|
|
97
|
-
private _key;
|
|
98
|
-
private _getItem;
|
|
99
|
-
private _removeKey;
|
|
100
|
-
private _storage;
|
|
101
|
-
private _locks;
|
|
102
|
-
}
|
|
103
|
-
declare const _default: ProvisionalFinishStore;
|
|
104
|
-
export default _default;
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { StatQueueEntry } from './StatQueue';
|
|
2
|
-
/**
|
|
3
|
-
* Синхронный журнал умирающей вкладки поверх localStorage: транзакция
|
|
4
|
-
* IndexedDB из pagehide не успевает закоммититься. Следующий старт SDK
|
|
5
|
-
* переносит журнал в очередь. Ключ уникален на вкладку.
|
|
6
|
-
*/
|
|
7
|
-
export default abstract class StatUnloadJournal {
|
|
8
|
-
private static _tabKey;
|
|
9
|
-
private static _entries;
|
|
10
|
-
/**
|
|
11
|
-
* Открывает новый журнал для этой вкладки. Без сброса пережившая pagehide
|
|
12
|
-
* вкладка записала бы во второй журнал уже перенесённые события.
|
|
13
|
-
*/
|
|
14
|
-
static beginTabSession(): void;
|
|
15
|
-
static writeSync(entry: StatQueueEntry): boolean;
|
|
16
|
-
/**
|
|
17
|
-
* Переносит журналы всех закрытых вкладок в очередь. Журнал стирается
|
|
18
|
-
* независимо от исхода: повторные попытки дали бы дубли.
|
|
19
|
-
*
|
|
20
|
-
* @returns число перенесённых событий.
|
|
21
|
-
*/
|
|
22
|
-
static drainToQueue(): Promise<number>;
|
|
23
|
-
/** Читает журнал и сразу удаляет его. null — ключа уже нет или хранилище недоступно. */
|
|
24
|
-
private static _take;
|
|
25
|
-
private static _storage;
|
|
26
|
-
private static _isValidEntry;
|
|
27
|
-
}
|