@amplitude/session-replay-browser 1.47.0-sr-trc-debug-log.3 → 1.47.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/README.md +203 -0
- package/lib/cjs/beacon-transport.d.ts +2 -0
- package/lib/cjs/beacon-transport.d.ts.map +1 -1
- package/lib/cjs/beacon-transport.js +39 -1
- package/lib/cjs/beacon-transport.js.map +1 -1
- package/lib/cjs/config/joined-config.d.ts +1 -6
- package/lib/cjs/config/joined-config.d.ts.map +1 -1
- package/lib/cjs/config/joined-config.js +23 -64
- package/lib/cjs/config/joined-config.js.map +1 -1
- package/lib/cjs/config/local-config.d.ts +4 -6
- package/lib/cjs/config/local-config.d.ts.map +1 -1
- package/lib/cjs/config/local-config.js +3 -19
- package/lib/cjs/config/local-config.js.map +1 -1
- package/lib/cjs/config/types.d.ts +74 -19
- package/lib/cjs/config/types.d.ts.map +1 -1
- package/lib/cjs/config/types.js.map +1 -1
- package/lib/cjs/index.d.ts +1 -0
- package/lib/cjs/index.d.ts.map +1 -1
- package/lib/cjs/index.js.map +1 -1
- package/lib/cjs/plugins/url-tracking-plugin.d.ts +0 -13
- package/lib/cjs/plugins/url-tracking-plugin.d.ts.map +1 -1
- package/lib/cjs/plugins/url-tracking-plugin.js +2 -6
- package/lib/cjs/plugins/url-tracking-plugin.js.map +1 -1
- package/lib/cjs/session-replay.d.ts +0 -33
- package/lib/cjs/session-replay.d.ts.map +1 -1
- package/lib/cjs/session-replay.js +40 -335
- package/lib/cjs/session-replay.js.map +1 -1
- package/lib/cjs/targeting/targeting-manager.d.ts +1 -4
- package/lib/cjs/targeting/targeting-manager.d.ts.map +1 -1
- package/lib/cjs/targeting/targeting-manager.js +10 -56
- package/lib/cjs/targeting/targeting-manager.js.map +1 -1
- package/lib/cjs/track-destination.d.ts +5 -1
- package/lib/cjs/track-destination.d.ts.map +1 -1
- package/lib/cjs/track-destination.js +212 -55
- package/lib/cjs/track-destination.js.map +1 -1
- package/lib/cjs/version.d.ts +1 -1
- package/lib/cjs/version.d.ts.map +1 -1
- package/lib/cjs/version.js +1 -1
- package/lib/cjs/version.js.map +1 -1
- package/lib/cjs/worker/index.js +1 -1
- package/lib/esm/beacon-transport.d.ts +2 -0
- package/lib/esm/beacon-transport.d.ts.map +1 -1
- package/lib/esm/beacon-transport.js +39 -1
- package/lib/esm/beacon-transport.js.map +1 -1
- package/lib/esm/config/joined-config.d.ts +1 -6
- package/lib/esm/config/joined-config.d.ts.map +1 -1
- package/lib/esm/config/joined-config.js +23 -64
- package/lib/esm/config/joined-config.js.map +1 -1
- package/lib/esm/config/local-config.d.ts +4 -6
- package/lib/esm/config/local-config.d.ts.map +1 -1
- package/lib/esm/config/local-config.js +4 -20
- package/lib/esm/config/local-config.js.map +1 -1
- package/lib/esm/config/types.d.ts +74 -19
- package/lib/esm/config/types.d.ts.map +1 -1
- package/lib/esm/config/types.js.map +1 -1
- package/lib/esm/index.d.ts +1 -0
- package/lib/esm/index.d.ts.map +1 -1
- package/lib/esm/index.js.map +1 -1
- package/lib/esm/plugins/url-tracking-plugin.d.ts +0 -13
- package/lib/esm/plugins/url-tracking-plugin.d.ts.map +1 -1
- package/lib/esm/plugins/url-tracking-plugin.js +2 -6
- package/lib/esm/plugins/url-tracking-plugin.js.map +1 -1
- package/lib/esm/session-replay.d.ts +0 -33
- package/lib/esm/session-replay.d.ts.map +1 -1
- package/lib/esm/session-replay.js +40 -335
- package/lib/esm/session-replay.js.map +1 -1
- package/lib/esm/targeting/targeting-manager.d.ts +1 -4
- package/lib/esm/targeting/targeting-manager.d.ts.map +1 -1
- package/lib/esm/targeting/targeting-manager.js +10 -56
- package/lib/esm/targeting/targeting-manager.js.map +1 -1
- package/lib/esm/track-destination.d.ts +5 -1
- package/lib/esm/track-destination.d.ts.map +1 -1
- package/lib/esm/track-destination.js +212 -55
- package/lib/esm/track-destination.js.map +1 -1
- package/lib/esm/version.d.ts +1 -1
- package/lib/esm/version.d.ts.map +1 -1
- package/lib/esm/version.js +1 -1
- package/lib/esm/version.js.map +1 -1
- package/lib/esm/worker/index.js +1 -1
- package/lib/scripts/index-min.js +1 -1
- package/lib/scripts/index-min.js.gz +0 -0
- package/lib/scripts/index-min.js.map +1 -1
- package/lib/scripts/observers-min.js +1 -1
- package/lib/scripts/observers-min.js.gz +0 -0
- package/lib/scripts/session-replay-browser-min.js +1 -1
- package/lib/scripts/session-replay-browser-min.js.gz +0 -0
- package/lib/scripts/session-replay-browser-min.js.map +1 -1
- package/lib/scripts/targeting-min.js +1 -1
- package/lib/scripts/targeting-min.js.gz +0 -0
- package/lib/scripts/worker-min.js +1 -1
- package/lib/scripts/worker-min.js.gz +0 -0
- package/package.json +4 -4
- package/lib/cjs/diagnostics.d.ts +0 -50
- package/lib/cjs/diagnostics.d.ts.map +0 -1
- package/lib/cjs/diagnostics.js +0 -67
- package/lib/cjs/diagnostics.js.map +0 -1
- package/lib/esm/diagnostics.d.ts +0 -50
- package/lib/esm/diagnostics.d.ts.map +0 -1
- package/lib/esm/diagnostics.js +0 -64
- package/lib/esm/diagnostics.js.map +0 -1
|
@@ -1,74 +1,44 @@
|
|
|
1
1
|
import { __assign, __awaiter, __generator } from "tslib";
|
|
2
2
|
import { targetingIDBStore } from './targeting-idb-store';
|
|
3
|
-
import { SrDiagnostic } from '../diagnostics';
|
|
4
3
|
export var evaluateTargetingAndStore = function (_a) {
|
|
5
|
-
var sessionId = _a.sessionId, targetingConfig = _a.targetingConfig, loggerProvider = _a.loggerProvider, apiKey = _a.apiKey, targetingParams = _a.targetingParams, _b = _a.urlChange, urlChange = _b === void 0 ? false : _b
|
|
4
|
+
var sessionId = _a.sessionId, targetingConfig = _a.targetingConfig, loggerProvider = _a.loggerProvider, apiKey = _a.apiKey, targetingParams = _a.targetingParams, _b = _a.urlChange, urlChange = _b === void 0 ? false : _b;
|
|
6
5
|
return __awaiter(void 0, void 0, void 0, function () {
|
|
7
6
|
var idbTargetingMatch, sessionTargetingMatch, evaluateTargetingPackage, params, targetingResult, err_1, knownError;
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
switch (_k.label) {
|
|
7
|
+
return __generator(this, function (_c) {
|
|
8
|
+
switch (_c.label) {
|
|
11
9
|
case 0: return [4 /*yield*/, targetingIDBStore.clearStoreOfOldSessions({
|
|
12
10
|
loggerProvider: loggerProvider,
|
|
13
11
|
apiKey: apiKey,
|
|
14
12
|
currentSessionId: sessionId,
|
|
15
13
|
})];
|
|
16
14
|
case 1:
|
|
17
|
-
|
|
15
|
+
_c.sent();
|
|
18
16
|
return [4 /*yield*/, targetingIDBStore.getTargetingMatchForSession({
|
|
19
17
|
loggerProvider: loggerProvider,
|
|
20
18
|
apiKey: apiKey,
|
|
21
19
|
sessionId: sessionId,
|
|
22
20
|
})];
|
|
23
21
|
case 2:
|
|
24
|
-
idbTargetingMatch =
|
|
22
|
+
idbTargetingMatch = _c.sent();
|
|
25
23
|
// Skip IDB cache when re-evaluating with a new page (e.g. URL change); otherwise we'd never
|
|
26
24
|
// re-evaluate and would keep returning true after navigating to a non-matching page.
|
|
27
25
|
if (idbTargetingMatch === true && !urlChange) {
|
|
28
26
|
return [2 /*return*/, true];
|
|
29
27
|
}
|
|
30
28
|
sessionTargetingMatch = true;
|
|
31
|
-
|
|
29
|
+
_c.label = 3;
|
|
32
30
|
case 3:
|
|
33
|
-
|
|
31
|
+
_c.trys.push([3, 6, , 7]);
|
|
34
32
|
return [4 /*yield*/, import('@amplitude/targeting')];
|
|
35
33
|
case 4:
|
|
36
|
-
evaluateTargetingPackage = (
|
|
34
|
+
evaluateTargetingPackage = (_c.sent()).evaluateTargeting;
|
|
37
35
|
params = __assign(__assign({}, targetingParams), { flag: targetingConfig, sessionId: typeof sessionId === 'string' ? parseInt(sessionId, 10) : sessionId, apiKey: apiKey, loggerProvider: loggerProvider });
|
|
38
|
-
diagnosticsClient === null || diagnosticsClient === void 0 ? void 0 : diagnosticsClient.recordEvent(SrDiagnostic.targetingTrigger, {
|
|
39
|
-
sessionId: sessionId,
|
|
40
|
-
deviceId: deviceId,
|
|
41
|
-
srId: deviceId != null && sessionId != null ? "".concat(deviceId, "/").concat(sessionId) : undefined,
|
|
42
|
-
pageUrl: (_c = targetingParams === null || targetingParams === void 0 ? void 0 : targetingParams.page) === null || _c === void 0 ? void 0 : _c.url,
|
|
43
|
-
matched: sessionTargetingMatch,
|
|
44
|
-
targetingConfig: targetingConfig,
|
|
45
|
-
});
|
|
46
36
|
return [4 /*yield*/, evaluateTargetingPackage(params)];
|
|
47
37
|
case 5:
|
|
48
|
-
targetingResult =
|
|
38
|
+
targetingResult = _c.sent();
|
|
49
39
|
if (targetingResult && targetingResult.sr_targeting_config) {
|
|
50
40
|
sessionTargetingMatch = targetingResult.sr_targeting_config.key === 'on';
|
|
51
41
|
}
|
|
52
|
-
// gap #2: the raw engine verdict. variantKey 'on' => matched; 'off'/undefined => not.
|
|
53
|
-
// Pair with the eval event's pageUrl to tell "URL condition didn't match" from "URL matched
|
|
54
|
-
// but the segment bucket (capture %) didn't allocate this session".
|
|
55
|
-
try {
|
|
56
|
-
diagnosticsClient === null || diagnosticsClient === void 0 ? void 0 : diagnosticsClient.recordEvent(SrDiagnostic.evalResult, {
|
|
57
|
-
sessionId: sessionId,
|
|
58
|
-
deviceId: deviceId,
|
|
59
|
-
srId: deviceId != null && sessionId != null ? "".concat(deviceId, "/").concat(sessionId) : undefined,
|
|
60
|
-
pageUrl: (_d = targetingParams === null || targetingParams === void 0 ? void 0 : targetingParams.page) === null || _d === void 0 ? void 0 : _d.url,
|
|
61
|
-
variantKey: (_f = (_e = targetingResult === null || targetingResult === void 0 ? void 0 : targetingResult.sr_targeting_config) === null || _e === void 0 ? void 0 : _e.key) !== null && _f !== void 0 ? _f : null,
|
|
62
|
-
matched: sessionTargetingMatch,
|
|
63
|
-
targetingConfig: targetingConfig,
|
|
64
|
-
});
|
|
65
|
-
// Flush now so the verdict ships immediately (vs the client's ~5-min timer). One capture
|
|
66
|
-
// POST per event — higher volume; revisit/gate before production.
|
|
67
|
-
void ((_g = diagnosticsClient === null || diagnosticsClient === void 0 ? void 0 : diagnosticsClient._flush) === null || _g === void 0 ? void 0 : _g.call(diagnosticsClient));
|
|
68
|
-
}
|
|
69
|
-
catch (_l) {
|
|
70
|
-
// diagnostics is best-effort
|
|
71
|
-
}
|
|
72
42
|
void targetingIDBStore.storeTargetingMatchForSession({
|
|
73
43
|
loggerProvider: loggerProvider,
|
|
74
44
|
apiKey: apiKey,
|
|
@@ -77,24 +47,8 @@ export var evaluateTargetingAndStore = function (_a) {
|
|
|
77
47
|
});
|
|
78
48
|
return [3 /*break*/, 7];
|
|
79
49
|
case 6:
|
|
80
|
-
err_1 =
|
|
50
|
+
err_1 = _c.sent();
|
|
81
51
|
knownError = err_1;
|
|
82
|
-
// Q3 "is the TRC failing?": the targeting engine threw — record it so the team sees TRC
|
|
83
|
-
// errors in DataDog (this exception is otherwise swallowed). Best-effort, never re-throws.
|
|
84
|
-
try {
|
|
85
|
-
diagnosticsClient === null || diagnosticsClient === void 0 ? void 0 : diagnosticsClient.increment(SrDiagnostic.evalError);
|
|
86
|
-
diagnosticsClient === null || diagnosticsClient === void 0 ? void 0 : diagnosticsClient.recordEvent(SrDiagnostic.evalError, {
|
|
87
|
-
sessionId: sessionId,
|
|
88
|
-
deviceId: deviceId,
|
|
89
|
-
srId: deviceId != null && sessionId != null ? "".concat(deviceId, "/").concat(sessionId) : undefined,
|
|
90
|
-
pageUrl: (_h = targetingParams === null || targetingParams === void 0 ? void 0 : targetingParams.page) === null || _h === void 0 ? void 0 : _h.url,
|
|
91
|
-
message: knownError.message,
|
|
92
|
-
});
|
|
93
|
-
void ((_j = diagnosticsClient === null || diagnosticsClient === void 0 ? void 0 : diagnosticsClient._flush) === null || _j === void 0 ? void 0 : _j.call(diagnosticsClient));
|
|
94
|
-
}
|
|
95
|
-
catch (_m) {
|
|
96
|
-
// diagnostics is best-effort
|
|
97
|
-
}
|
|
98
52
|
loggerProvider.warn(knownError.message);
|
|
99
53
|
return [3 /*break*/, 7];
|
|
100
54
|
case 7: return [2 /*return*/, sessionTargetingMatch];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"targeting-manager.js","sourceRoot":"","sources":["../../../src/targeting/targeting-manager.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"targeting-manager.js","sourceRoot":"","sources":["../../../src/targeting/targeting-manager.ts"],"names":[],"mappings":";AAIA,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE1D,MAAM,CAAC,IAAM,yBAAyB,GAAG,UAAO,EAc/C;QAbC,SAAS,eAAA,EACT,eAAe,qBAAA,EACf,cAAc,oBAAA,EACd,MAAM,YAAA,EACN,eAAe,qBAAA,EACf,iBAAiB,EAAjB,SAAS,mBAAG,KAAK,KAAA;;;;;wBASjB,qBAAM,iBAAiB,CAAC,uBAAuB,CAAC;wBAC9C,cAAc,EAAE,cAAc;wBAC9B,MAAM,EAAE,MAAM;wBACd,gBAAgB,EAAE,SAAS;qBAC5B,CAAC,EAAA;;oBAJF,SAIE,CAAC;oBAEuB,qBAAM,iBAAiB,CAAC,2BAA2B,CAAC;4BAC5E,cAAc,EAAE,cAAc;4BAC9B,MAAM,EAAE,MAAM;4BACd,SAAS,EAAE,SAAS;yBACrB,CAAC,EAAA;;oBAJI,iBAAiB,GAAG,SAIxB;oBACF,4FAA4F;oBAC5F,qFAAqF;oBACrF,IAAI,iBAAiB,KAAK,IAAI,IAAI,CAAC,SAAS,EAAE;wBAC5C,sBAAO,IAAI,EAAC;qBACb;oBAKG,qBAAqB,GAAG,IAAI,CAAC;;;;oBAGyB,qBAAM,MAAM,CAAC,sBAAsB,CAAC,EAAA;;oBAAjE,wBAAwB,GAAK,CAAA,SAAoC,CAAA,kBAAzC;oBAE7C,MAAM,yBACP,eAAe,KAClB,IAAI,EAAE,eAAe,EACrB,SAAS,EAAE,OAAO,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,EAC9E,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,cAAc,GAC/B,CAAC;oBACsB,qBAAM,wBAAwB,CAAC,MAAM,CAAC,EAAA;;oBAAxD,eAAe,GAAG,SAAsC;oBAC9D,IAAI,eAAe,IAAI,eAAe,CAAC,mBAAmB,EAAE;wBAC1D,qBAAqB,GAAG,eAAe,CAAC,mBAAmB,CAAC,GAAG,KAAK,IAAI,CAAC;qBAC1E;oBAED,KAAK,iBAAiB,CAAC,6BAA6B,CAAC;wBACnD,cAAc,EAAE,cAAc;wBAC9B,MAAM,EAAE,MAAM;wBACd,SAAS,EAAE,SAAS;wBACpB,cAAc,EAAE,qBAAqB;qBACtC,CAAC,CAAC;;;;oBAEG,UAAU,GAAG,KAAY,CAAC;oBAChC,cAAc,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;;wBAE1C,sBAAO,qBAAqB,EAAC;;;;CAC9B,CAAC","sourcesContent":["import type { TargetingParameters } from '@amplitude/targeting';\nimport { TargetingConfig } from '../config/types';\nimport { Logger } from '@amplitude/analytics-types';\nimport { SessionReplayTargetingInput } from '../typings/session-replay';\nimport { targetingIDBStore } from './targeting-idb-store';\n\nexport const evaluateTargetingAndStore = async ({\n sessionId,\n targetingConfig,\n loggerProvider,\n apiKey,\n targetingParams,\n urlChange = false,\n}: {\n sessionId: string | number;\n targetingConfig: TargetingConfig;\n loggerProvider: Logger;\n apiKey: string;\n targetingParams?: SessionReplayTargetingInput;\n urlChange?: boolean;\n}) => {\n await targetingIDBStore.clearStoreOfOldSessions({\n loggerProvider: loggerProvider,\n apiKey: apiKey,\n currentSessionId: sessionId,\n });\n\n const idbTargetingMatch = await targetingIDBStore.getTargetingMatchForSession({\n loggerProvider: loggerProvider,\n apiKey: apiKey,\n sessionId: sessionId,\n });\n // Skip IDB cache when re-evaluating with a new page (e.g. URL change); otherwise we'd never\n // re-evaluate and would keep returning true after navigating to a non-matching page.\n if (idbTargetingMatch === true && !urlChange) {\n return true;\n }\n\n // If the targeting config is undefined or an empty object,\n // assume the response was valid but no conditions were set,\n // so all users match targeting\n let sessionTargetingMatch = true;\n try {\n // Dynamic import of the targeting package\n const { evaluateTargeting: evaluateTargetingPackage } = await import('@amplitude/targeting');\n\n const params: TargetingParameters = {\n ...targetingParams,\n flag: targetingConfig,\n sessionId: typeof sessionId === 'string' ? parseInt(sessionId, 10) : sessionId,\n apiKey: apiKey,\n loggerProvider: loggerProvider,\n };\n const targetingResult = await evaluateTargetingPackage(params);\n if (targetingResult && targetingResult.sr_targeting_config) {\n sessionTargetingMatch = targetingResult.sr_targeting_config.key === 'on';\n }\n\n void targetingIDBStore.storeTargetingMatchForSession({\n loggerProvider: loggerProvider,\n apiKey: apiKey,\n sessionId: sessionId,\n targetingMatch: sessionTargetingMatch,\n });\n } catch (err: unknown) {\n const knownError = err as Error;\n loggerProvider.warn(knownError.message);\n }\n return sessionTargetingMatch;\n};\n"]}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ILogger, ServerZone } from '@amplitude/analytics-core';
|
|
2
2
|
import { SessionReplayTrackDestination as AmplitudeSessionReplayTrackDestination, SessionReplayDestination, SessionReplayDestinationContext } from './typings/session-replay';
|
|
3
|
+
import { SessionReplaySendEventsHandler } from './config/types';
|
|
3
4
|
export type PayloadBatcher = ({ version, events }: {
|
|
4
5
|
version: number;
|
|
5
6
|
events: string[];
|
|
@@ -26,13 +27,15 @@ export declare class SessionReplayTrackDestination implements AmplitudeSessionRe
|
|
|
26
27
|
private coalesceNextFlush;
|
|
27
28
|
private mergeLogFiredThisPause;
|
|
28
29
|
private killedSessions;
|
|
29
|
-
|
|
30
|
+
private handleSendEvents?;
|
|
31
|
+
constructor({ trackServerUrl, loggerProvider, payloadBatcher, workerScript, enableTransportCompression, sendTimeoutMs, handleSendEvents, }: {
|
|
30
32
|
trackServerUrl?: string;
|
|
31
33
|
loggerProvider: ILogger;
|
|
32
34
|
payloadBatcher?: PayloadBatcher;
|
|
33
35
|
workerScript?: string;
|
|
34
36
|
enableTransportCompression?: boolean;
|
|
35
37
|
sendTimeoutMs?: number;
|
|
38
|
+
handleSendEvents?: SessionReplaySendEventsHandler;
|
|
36
39
|
});
|
|
37
40
|
sendEventsList(destinationData: SessionReplayDestination): void;
|
|
38
41
|
/**
|
|
@@ -99,6 +102,7 @@ export declare class SessionReplayTrackDestination implements AmplitudeSessionRe
|
|
|
99
102
|
send(context: SessionReplayDestinationContext, useRetry?: boolean): Promise<void>;
|
|
100
103
|
private sendViaWorker;
|
|
101
104
|
private rememberTimedOutRequest;
|
|
105
|
+
private handleDelegatedFetch;
|
|
102
106
|
private sendOnMainThread;
|
|
103
107
|
handleReponse(status: number, context: SessionReplayDestinationContext, responseBody?: string): Promise<void>;
|
|
104
108
|
handlePayloadTooLargeResponse(context: SessionReplayDestinationContext, isWaf: boolean): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"track-destination.d.ts","sourceRoot":"","sources":["../../src/track-destination.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiC,OAAO,EAAE,UAAU,EAAU,MAAM,2BAA2B,CAAC;AAUvG,OAAO,EACL,6BAA6B,IAAI,sCAAsC,EACvE,wBAAwB,EACxB,+BAA+B,EAChC,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"track-destination.d.ts","sourceRoot":"","sources":["../../src/track-destination.ts"],"names":[],"mappings":"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"}
|
|
@@ -12,9 +12,33 @@ var MAX_KILLED_SESSIONS = 256;
|
|
|
12
12
|
// In normal operation each entry is removed when the worker's late message arrives; this
|
|
13
13
|
// cap only guards the pathological case of a wedged worker that never replies at all.
|
|
14
14
|
var MAX_TIMED_OUT_WORKER_REQUESTS = 256;
|
|
15
|
+
// Settles with `promise`, but rejects early with an AbortError when `signal` fires. Used to apply
|
|
16
|
+
// the send timeout to a custom transport whose own promise can't be cancelled: a hung transport
|
|
17
|
+
// then surfaces as a retryable timeout (matching the built-in fetch and worker delegation paths)
|
|
18
|
+
// instead of blocking the serial flush loop. The transport's promise keeps running; we just stop
|
|
19
|
+
// awaiting it. `signal` is always supplied with the send-timeout controller's signal.
|
|
20
|
+
function abortable(promise, signal) {
|
|
21
|
+
return new Promise(function (resolve, reject) {
|
|
22
|
+
var onAbort = function () {
|
|
23
|
+
// Match how browsers reject an aborted fetch (DOMException 'AbortError'); sendOnMainThread's
|
|
24
|
+
// catch keys off the name to route it through the retry budget rather than failing fatally.
|
|
25
|
+
var err = new Error('Custom session replay transport aborted by send timeout');
|
|
26
|
+
err.name = 'AbortError';
|
|
27
|
+
reject(err);
|
|
28
|
+
};
|
|
29
|
+
signal.addEventListener('abort', onAbort, { once: true });
|
|
30
|
+
promise.then(function (value) {
|
|
31
|
+
signal.removeEventListener('abort', onAbort);
|
|
32
|
+
resolve(value);
|
|
33
|
+
}, function (err) {
|
|
34
|
+
signal.removeEventListener('abort', onAbort);
|
|
35
|
+
reject(err);
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
}
|
|
15
39
|
var SessionReplayTrackDestination = /** @class */ (function () {
|
|
16
40
|
function SessionReplayTrackDestination(_a) {
|
|
17
|
-
var trackServerUrl = _a.trackServerUrl, loggerProvider = _a.loggerProvider, payloadBatcher = _a.payloadBatcher, workerScript = _a.workerScript, enableTransportCompression = _a.enableTransportCompression, sendTimeoutMs = _a.sendTimeoutMs;
|
|
41
|
+
var trackServerUrl = _a.trackServerUrl, loggerProvider = _a.loggerProvider, payloadBatcher = _a.payloadBatcher, workerScript = _a.workerScript, enableTransportCompression = _a.enableTransportCompression, sendTimeoutMs = _a.sendTimeoutMs, handleSendEvents = _a.handleSendEvents;
|
|
18
42
|
var _this = this;
|
|
19
43
|
this.storageKey = '';
|
|
20
44
|
this.retryTimeout = 1000;
|
|
@@ -50,6 +74,7 @@ var SessionReplayTrackDestination = /** @class */ (function () {
|
|
|
50
74
|
this.trackServerUrl = trackServerUrl;
|
|
51
75
|
this.enableTransportCompression = enableTransportCompression !== null && enableTransportCompression !== void 0 ? enableTransportCompression : true;
|
|
52
76
|
this.sendTimeoutMs = sendTimeoutMs !== null && sendTimeoutMs !== void 0 ? sendTimeoutMs : SEND_TIMEOUT_MS;
|
|
77
|
+
this.handleSendEvents = handleSendEvents;
|
|
53
78
|
if (workerScript) {
|
|
54
79
|
try {
|
|
55
80
|
var blob = new Blob([workerScript], { type: 'application/javascript' });
|
|
@@ -141,6 +166,16 @@ var SessionReplayTrackDestination = /** @class */ (function () {
|
|
|
141
166
|
}
|
|
142
167
|
}
|
|
143
168
|
}
|
|
169
|
+
else if (msg.type === 'fetch-request') {
|
|
170
|
+
// Worker is delegating one network attempt to the custom transport (which lives on
|
|
171
|
+
// the main thread). Run it and post the result back into the worker's retry loop.
|
|
172
|
+
// Guard the fire-and-forget call: if posting the result back fails (e.g. the worker
|
|
173
|
+
// was terminated mid-flight), surface it to the logger instead of leaving an
|
|
174
|
+
// unhandled rejection.
|
|
175
|
+
void _this.handleDelegatedFetch(worker_1, msg).catch(function (e) {
|
|
176
|
+
loggerProvider.warn('Failed to handle delegated session replay fetch:', e);
|
|
177
|
+
});
|
|
178
|
+
}
|
|
144
179
|
};
|
|
145
180
|
this.worker = worker_1;
|
|
146
181
|
}
|
|
@@ -178,6 +213,7 @@ var SessionReplayTrackDestination = /** @class */ (function () {
|
|
|
178
213
|
* to cover the remaining incremental events since the last fetch flush.
|
|
179
214
|
*/
|
|
180
215
|
SessionReplayTrackDestination.prototype.sendBeacon = function (_a) {
|
|
216
|
+
var _this = this;
|
|
181
217
|
var _b, _c;
|
|
182
218
|
var events = _a.events, sessionId = _a.sessionId, deviceId = _a.deviceId, apiKey = _a.apiKey, serverZone = _a.serverZone;
|
|
183
219
|
var MAX_BEACON_BYTES = 64 * 1024;
|
|
@@ -205,6 +241,37 @@ var SessionReplayTrackDestination = /** @class */ (function () {
|
|
|
205
241
|
if (trimmedEvents.length === 0) {
|
|
206
242
|
return;
|
|
207
243
|
}
|
|
244
|
+
// Custom-transport page-exit path: navigator.sendBeacon cannot carry custom headers, so a
|
|
245
|
+
// JWT customer's exit batch would go out unauthenticated and be rejected by their proxy.
|
|
246
|
+
// Instead, route it through the callback with keepalive (which survives unload AND carries
|
|
247
|
+
// headers). Mirrors the main-send request shape: Authorization header + device_id/session_id/
|
|
248
|
+
// type params (api_key is NOT placed in the URL, unlike the legacy beacon path below).
|
|
249
|
+
if (this.handleSendEvents) {
|
|
250
|
+
var exitParams = new URLSearchParams({
|
|
251
|
+
device_id: deviceId,
|
|
252
|
+
session_id: String(sessionId),
|
|
253
|
+
type: 'replay',
|
|
254
|
+
});
|
|
255
|
+
var exitUrl = "".concat(getServerUrl(serverZone, this.trackServerUrl), "?").concat(exitParams.toString());
|
|
256
|
+
var headers = {
|
|
257
|
+
'Content-Type': 'application/json',
|
|
258
|
+
Accept: '*/*',
|
|
259
|
+
Authorization: "Bearer ".concat(apiKey),
|
|
260
|
+
};
|
|
261
|
+
this.loggerProvider.debug("Routing session replay exit batch (".concat(trimmedEvents.length, " events) through custom transport for session id ").concat(sessionId, "."));
|
|
262
|
+
try {
|
|
263
|
+
// Fire-and-forget: we cannot await during unload. The request is well under 64 KB
|
|
264
|
+
// (trimmed above) and keepalive: true is requested so it survives page teardown.
|
|
265
|
+
void this.handleSendEvents({ url: exitUrl, method: 'POST', headers: headers, body: payload, keepalive: true }).catch(function (e) {
|
|
266
|
+
// best effort on exit, but still surface the failure so it's diagnosable in logs.
|
|
267
|
+
_this.loggerProvider.warn('Custom transport failed to send session replay exit batch:', e);
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
catch (e) {
|
|
271
|
+
this.loggerProvider.warn('Custom transport threw while sending session replay exit batch:', e);
|
|
272
|
+
}
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
208
275
|
var urlParams = new URLSearchParams({
|
|
209
276
|
device_id: deviceId,
|
|
210
277
|
session_id: String(sessionId),
|
|
@@ -573,6 +640,10 @@ var SessionReplayTrackDestination = /** @class */ (function () {
|
|
|
573
640
|
id: id,
|
|
574
641
|
payload: payload,
|
|
575
642
|
useRetry: useRetry,
|
|
643
|
+
// Tell the worker to delegate each network attempt back to the main thread, where the
|
|
644
|
+
// custom transport callback lives (functions can't cross postMessage). Absent/false
|
|
645
|
+
// keeps the worker's own internal fetch — the unchanged path for existing integrations.
|
|
646
|
+
useCustomTransport: !!_this.handleSendEvents,
|
|
576
647
|
context: {
|
|
577
648
|
apiKey: context.apiKey,
|
|
578
649
|
deviceId: context.deviceId,
|
|
@@ -616,12 +687,82 @@ var SessionReplayTrackDestination = /** @class */ (function () {
|
|
|
616
687
|
}
|
|
617
688
|
}
|
|
618
689
|
};
|
|
690
|
+
// Runs the custom transport on the main thread for a single attempt the worker delegated,
|
|
691
|
+
// then posts the result back into the worker's retry loop as a 'fetch-response'. We read only
|
|
692
|
+
// what the worker's status handling needs: the skip header on a 2xx and the body text on a
|
|
693
|
+
// 413 (for WAF detection). A thrown/rejected transport is reported as an error so the worker
|
|
694
|
+
// surfaces it the same way a thrown fetch would (no retry) — matching the main-thread path.
|
|
695
|
+
SessionReplayTrackDestination.prototype.handleDelegatedFetch = function (worker, msg) {
|
|
696
|
+
var _a, _b, _c;
|
|
697
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
698
|
+
var requestId, url, method, headers, body, keepalive, res, status_1, skipHeader, responseBody, _d, e_7;
|
|
699
|
+
return __generator(this, function (_e) {
|
|
700
|
+
switch (_e.label) {
|
|
701
|
+
case 0:
|
|
702
|
+
requestId = msg.requestId, url = msg.url, method = msg.method, headers = msg.headers, body = msg.body, keepalive = msg.keepalive;
|
|
703
|
+
_e.label = 1;
|
|
704
|
+
case 1:
|
|
705
|
+
_e.trys.push([1, 10, , 11]);
|
|
706
|
+
res = void 0;
|
|
707
|
+
if (!this.handleSendEvents) return [3 /*break*/, 3];
|
|
708
|
+
return [4 /*yield*/, this.handleSendEvents({ url: url, method: method, headers: headers, body: body, keepalive: keepalive })];
|
|
709
|
+
case 2:
|
|
710
|
+
res = _e.sent();
|
|
711
|
+
return [3 /*break*/, 5];
|
|
712
|
+
case 3:
|
|
713
|
+
// Defensive only: the worker emits 'fetch-request' solely when useCustomTransport is set,
|
|
714
|
+
// so this branch shouldn't be reachable. Warn so a regression that delegates without a
|
|
715
|
+
// transport is diagnosable rather than silently routing to the built-in fetch.
|
|
716
|
+
this.loggerProvider.warn('Delegated session replay fetch received without a custom transport configured; falling back to built-in fetch.');
|
|
717
|
+
return [4 /*yield*/, fetch(url, { method: method, headers: headers, body: body, keepalive: keepalive })];
|
|
718
|
+
case 4:
|
|
719
|
+
res = _e.sent();
|
|
720
|
+
_e.label = 5;
|
|
721
|
+
case 5:
|
|
722
|
+
status_1 = res.status;
|
|
723
|
+
skipHeader = null;
|
|
724
|
+
responseBody = '';
|
|
725
|
+
if (status_1 >= 200 && status_1 < 300) {
|
|
726
|
+
skipHeader = (_c = (_b = (_a = res.headers) === null || _a === void 0 ? void 0 : _a.get) === null || _b === void 0 ? void 0 : _b.call(_a, EVENT_SKIPPED_HEADER)) !== null && _c !== void 0 ? _c : null;
|
|
727
|
+
}
|
|
728
|
+
if (!(status_1 === 413)) return [3 /*break*/, 9];
|
|
729
|
+
_e.label = 6;
|
|
730
|
+
case 6:
|
|
731
|
+
_e.trys.push([6, 8, , 9]);
|
|
732
|
+
return [4 /*yield*/, res.text()];
|
|
733
|
+
case 7:
|
|
734
|
+
responseBody = _e.sent();
|
|
735
|
+
return [3 /*break*/, 9];
|
|
736
|
+
case 8:
|
|
737
|
+
_d = _e.sent();
|
|
738
|
+
return [3 /*break*/, 9];
|
|
739
|
+
case 9:
|
|
740
|
+
this.loggerProvider.debug("Delegated session replay fetch (request ".concat(requestId, ") returned status ").concat(status_1, "."));
|
|
741
|
+
worker.postMessage({ type: 'fetch-response', requestId: requestId, status: status_1, skipHeader: skipHeader, body: responseBody });
|
|
742
|
+
return [3 /*break*/, 11];
|
|
743
|
+
case 10:
|
|
744
|
+
e_7 = _e.sent();
|
|
745
|
+
this.loggerProvider.debug("Delegated session replay fetch (request ".concat(requestId, ") failed:"), e_7);
|
|
746
|
+
worker.postMessage({
|
|
747
|
+
type: 'fetch-response',
|
|
748
|
+
requestId: requestId,
|
|
749
|
+
status: 0,
|
|
750
|
+
skipHeader: null,
|
|
751
|
+
body: String(e_7),
|
|
752
|
+
error: true,
|
|
753
|
+
});
|
|
754
|
+
return [3 /*break*/, 11];
|
|
755
|
+
case 11: return [2 /*return*/];
|
|
756
|
+
}
|
|
757
|
+
});
|
|
758
|
+
});
|
|
759
|
+
};
|
|
619
760
|
SessionReplayTrackDestination.prototype.sendOnMainThread = function (apiKey, deviceId, context, payload, useRetry) {
|
|
620
761
|
var _a, _b, _c, _d, _e, _f, _g;
|
|
621
762
|
return __awaiter(this, void 0, void 0, function () {
|
|
622
|
-
var url, version, sampleRate, urlParams, sessionReplayLibrary, payloadJson, globalScope, gzipped, _h, payloadSize, controller_1, options, serverUrl, sendTimeout, res, skipCode, responseBody, responseBody,
|
|
623
|
-
return __generator(this, function (
|
|
624
|
-
switch (
|
|
763
|
+
var url, version, sampleRate, urlParams, sessionReplayLibrary, payloadJson, globalScope, gzipped, _h, payloadSize, controller_1, headers, body, keepalive, options, serverUrl, sendTimeout, res, _j, skipCode, responseBody, responseBody, _k, e_8, isAbort;
|
|
764
|
+
return __generator(this, function (_l) {
|
|
765
|
+
switch (_l.label) {
|
|
625
766
|
case 0:
|
|
626
767
|
url = getCurrentUrl();
|
|
627
768
|
version = VERSION;
|
|
@@ -632,30 +773,31 @@ var SessionReplayTrackDestination = /** @class */ (function () {
|
|
|
632
773
|
type: "".concat(context.type),
|
|
633
774
|
});
|
|
634
775
|
sessionReplayLibrary = "".concat((_b = (_a = context.version) === null || _a === void 0 ? void 0 : _a.type) !== null && _b !== void 0 ? _b : 'standalone', "/").concat((_d = (_c = context.version) === null || _c === void 0 ? void 0 : _c.version) !== null && _d !== void 0 ? _d : version);
|
|
635
|
-
|
|
776
|
+
_l.label = 1;
|
|
636
777
|
case 1:
|
|
637
|
-
|
|
778
|
+
_l.trys.push([1, 19, , 23]);
|
|
638
779
|
payloadJson = JSON.stringify(payload);
|
|
639
780
|
globalScope = getGlobalScope();
|
|
640
781
|
if (!(this.enableTransportCompression && globalScope && 'CompressionStream' in globalScope)) return [3 /*break*/, 3];
|
|
641
782
|
return [4 /*yield*/, gzipJson(payloadJson, globalScope)];
|
|
642
783
|
case 2:
|
|
643
|
-
_h =
|
|
784
|
+
_h = _l.sent();
|
|
644
785
|
return [3 /*break*/, 4];
|
|
645
786
|
case 3:
|
|
646
787
|
_h = null;
|
|
647
|
-
|
|
788
|
+
_l.label = 4;
|
|
648
789
|
case 4:
|
|
649
790
|
gzipped = _h;
|
|
650
791
|
payloadSize = gzipped ? gzipped.byteLength : new Blob([payloadJson]).size;
|
|
651
792
|
controller_1 = new AbortController();
|
|
793
|
+
headers = __assign({ 'Content-Type': 'application/json', Accept: '*/*', Authorization: "Bearer ".concat(apiKey), 'X-Client-Version': version, 'X-Client-Library': sessionReplayLibrary, 'X-Client-Url': url.substring(0, MAX_URL_LENGTH), 'X-Client-Sample-Rate': "".concat(sampleRate), 'X-Sampling-Hash-Alg': 'xxhash32' }, (gzipped ? { 'Content-Encoding': 'gzip' } : {}));
|
|
794
|
+
body = gzipped !== null && gzipped !== void 0 ? gzipped : payloadJson;
|
|
795
|
+
keepalive = payloadSize <= MAX_KEEPALIVE_BYTES;
|
|
652
796
|
options = {
|
|
653
|
-
headers:
|
|
654
|
-
body:
|
|
797
|
+
headers: headers,
|
|
798
|
+
body: body,
|
|
655
799
|
method: 'POST',
|
|
656
|
-
|
|
657
|
-
// Must stay under the browser's 64 KB keepalive budget; large payloads skip it.
|
|
658
|
-
keepalive: payloadSize <= MAX_KEEPALIVE_BYTES,
|
|
800
|
+
keepalive: keepalive,
|
|
659
801
|
signal: controller_1.signal,
|
|
660
802
|
};
|
|
661
803
|
serverUrl = "".concat(getServerUrl(context.serverZone, this.trackServerUrl), "?").concat(urlParams.toString());
|
|
@@ -674,20 +816,35 @@ var SessionReplayTrackDestination = /** @class */ (function () {
|
|
|
674
816
|
}, this.sendTimeoutMs)
|
|
675
817
|
: undefined;
|
|
676
818
|
res = void 0;
|
|
677
|
-
|
|
819
|
+
_l.label = 5;
|
|
678
820
|
case 5:
|
|
679
|
-
|
|
680
|
-
return [
|
|
821
|
+
_l.trys.push([5, , 10, 11]);
|
|
822
|
+
if (!this.handleSendEvents) return [3 /*break*/, 7];
|
|
823
|
+
return [4 /*yield*/, abortable(this.handleSendEvents({ url: serverUrl, method: 'POST', headers: headers, body: body, keepalive: keepalive }), controller_1.signal)];
|
|
681
824
|
case 6:
|
|
682
|
-
|
|
683
|
-
return [3 /*break*/,
|
|
684
|
-
case 7:
|
|
825
|
+
_j = _l.sent();
|
|
826
|
+
return [3 /*break*/, 9];
|
|
827
|
+
case 7: return [4 /*yield*/, fetch(serverUrl, options)];
|
|
828
|
+
case 8:
|
|
829
|
+
_j = _l.sent();
|
|
830
|
+
_l.label = 9;
|
|
831
|
+
case 9:
|
|
832
|
+
// When a custom transport is configured, hand it the fully-formed request and let it own
|
|
833
|
+
// the network call (e.g. to attach a JWT and route through a proxy). Otherwise use the
|
|
834
|
+
// built-in fetch. Retry/response handling below is identical for both paths. The built-in
|
|
835
|
+
// fetch cancels directly on controller.signal; the custom callback can't be cancelled, so
|
|
836
|
+
// we race it against the abort — a hung/never-settling transport then rejects with an
|
|
837
|
+
// AbortError (retryable, like the worker delegation path) instead of blocking the serial
|
|
838
|
+
// flush loop forever. The callback's own promise keeps running; we just stop awaiting it.
|
|
839
|
+
res = _j;
|
|
840
|
+
return [3 /*break*/, 11];
|
|
841
|
+
case 10:
|
|
685
842
|
// Clear on success and on error alike so a settled request never leaves an armed
|
|
686
843
|
// timer that would abort a later reused controller or fire a stray callback.
|
|
687
844
|
if (sendTimeout)
|
|
688
845
|
clearTimeout(sendTimeout);
|
|
689
846
|
return [7 /*endfinally*/];
|
|
690
|
-
case
|
|
847
|
+
case 11:
|
|
691
848
|
if (res === null) {
|
|
692
849
|
this.completeRequest({ context: context, err: UNEXPECTED_ERROR_MESSAGE });
|
|
693
850
|
return [2 /*return*/];
|
|
@@ -696,47 +853,47 @@ var SessionReplayTrackDestination = /** @class */ (function () {
|
|
|
696
853
|
skipCode = (_g = (_f = (_e = res.headers) === null || _e === void 0 ? void 0 : _e.get) === null || _f === void 0 ? void 0 : _f.call(_e, EVENT_SKIPPED_HEADER)) !== null && _g !== void 0 ? _g : null;
|
|
697
854
|
this.applyServerDirective(context.sessionId, skipCode);
|
|
698
855
|
}
|
|
699
|
-
if (!!useRetry) return [3 /*break*/,
|
|
856
|
+
if (!!useRetry) return [3 /*break*/, 12];
|
|
700
857
|
responseBody = '';
|
|
701
858
|
try {
|
|
702
859
|
responseBody = JSON.stringify(res.body, null, 2);
|
|
703
860
|
}
|
|
704
|
-
catch (
|
|
861
|
+
catch (_m) {
|
|
705
862
|
// to avoid crash, but don't care about the error, add comment to avoid empty block lint error
|
|
706
863
|
}
|
|
707
864
|
this.completeRequest({ context: context, success: "".concat(res.status, ": ").concat(responseBody) });
|
|
708
|
-
return [3 /*break*/,
|
|
709
|
-
case
|
|
865
|
+
return [3 /*break*/, 18];
|
|
866
|
+
case 12:
|
|
710
867
|
responseBody = '';
|
|
711
|
-
if (!(res.status === 413)) return [3 /*break*/,
|
|
712
|
-
|
|
713
|
-
case
|
|
714
|
-
|
|
868
|
+
if (!(res.status === 413)) return [3 /*break*/, 16];
|
|
869
|
+
_l.label = 13;
|
|
870
|
+
case 13:
|
|
871
|
+
_l.trys.push([13, 15, , 16]);
|
|
715
872
|
return [4 /*yield*/, res.text()];
|
|
716
|
-
case 11:
|
|
717
|
-
responseBody = _k.sent();
|
|
718
|
-
return [3 /*break*/, 13];
|
|
719
|
-
case 12:
|
|
720
|
-
_j = _k.sent();
|
|
721
|
-
return [3 /*break*/, 13];
|
|
722
|
-
case 13: return [4 /*yield*/, this.handleReponse(res.status, context, responseBody)];
|
|
723
873
|
case 14:
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
case 15:
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
if (!(isAbort && useRetry)) return [3 /*break*/, 18];
|
|
731
|
-
return [4 /*yield*/, this.handleOtherResponse(context)];
|
|
874
|
+
responseBody = _l.sent();
|
|
875
|
+
return [3 /*break*/, 16];
|
|
876
|
+
case 15:
|
|
877
|
+
_k = _l.sent();
|
|
878
|
+
return [3 /*break*/, 16];
|
|
879
|
+
case 16: return [4 /*yield*/, this.handleReponse(res.status, context, responseBody)];
|
|
732
880
|
case 17:
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
case 18:
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
881
|
+
_l.sent();
|
|
882
|
+
_l.label = 18;
|
|
883
|
+
case 18: return [3 /*break*/, 23];
|
|
884
|
+
case 19:
|
|
885
|
+
e_8 = _l.sent();
|
|
886
|
+
isAbort = !!e_8 && typeof e_8 === 'object' && e_8.name === 'AbortError';
|
|
887
|
+
if (!(isAbort && useRetry)) return [3 /*break*/, 21];
|
|
888
|
+
return [4 /*yield*/, this.handleOtherResponse(context)];
|
|
889
|
+
case 20:
|
|
890
|
+
_l.sent();
|
|
891
|
+
return [3 /*break*/, 22];
|
|
892
|
+
case 21:
|
|
893
|
+
this.completeRequest({ context: context, err: e_8 });
|
|
894
|
+
_l.label = 22;
|
|
895
|
+
case 22: return [3 /*break*/, 23];
|
|
896
|
+
case 23: return [2 /*return*/];
|
|
740
897
|
}
|
|
741
898
|
});
|
|
742
899
|
});
|
|
@@ -890,7 +1047,7 @@ var SessionReplayTrackDestination = /** @class */ (function () {
|
|
|
890
1047
|
// session for a code we don't recognize.
|
|
891
1048
|
};
|
|
892
1049
|
SessionReplayTrackDestination.prototype.killSession = function (sessionId, skipCode) {
|
|
893
|
-
var
|
|
1050
|
+
var e_9, _a, e_10, _b;
|
|
894
1051
|
if (this.killedSessions.has(sessionId))
|
|
895
1052
|
return;
|
|
896
1053
|
this.killedSessions.add(sessionId);
|
|
@@ -903,12 +1060,12 @@ var SessionReplayTrackDestination = /** @class */ (function () {
|
|
|
903
1060
|
break;
|
|
904
1061
|
}
|
|
905
1062
|
}
|
|
906
|
-
catch (
|
|
1063
|
+
catch (e_9_1) { e_9 = { error: e_9_1 }; }
|
|
907
1064
|
finally {
|
|
908
1065
|
try {
|
|
909
1066
|
if (_d && !_d.done && (_a = _c.return)) _a.call(_c);
|
|
910
1067
|
}
|
|
911
|
-
finally { if (
|
|
1068
|
+
finally { if (e_9) throw e_9.error; }
|
|
912
1069
|
}
|
|
913
1070
|
}
|
|
914
1071
|
this.loggerProvider.log("Session replay capture stopped for session ".concat(sessionId, " by server directive ").concat(skipCode, "; remaining events will be dropped"));
|
|
@@ -926,12 +1083,12 @@ var SessionReplayTrackDestination = /** @class */ (function () {
|
|
|
926
1083
|
}
|
|
927
1084
|
}
|
|
928
1085
|
}
|
|
929
|
-
catch (
|
|
1086
|
+
catch (e_10_1) { e_10 = { error: e_10_1 }; }
|
|
930
1087
|
finally {
|
|
931
1088
|
try {
|
|
932
1089
|
if (_f && !_f.done && (_b = _e.return)) _b.call(_e);
|
|
933
1090
|
}
|
|
934
|
-
finally { if (
|
|
1091
|
+
finally { if (e_10) throw e_10.error; }
|
|
935
1092
|
}
|
|
936
1093
|
this.queue = remaining;
|
|
937
1094
|
};
|