@amplitude/session-replay-browser 1.11.2 → 1.11.4
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/lib/cjs/config/joined-config.js +1 -1
- package/lib/cjs/config/joined-config.js.map +1 -1
- package/lib/cjs/session-replay.d.ts +2 -3
- package/lib/cjs/session-replay.d.ts.map +1 -1
- package/lib/cjs/session-replay.js +13 -29
- package/lib/cjs/session-replay.js.map +1 -1
- package/lib/esm/config/joined-config.js +1 -1
- package/lib/esm/config/joined-config.js.map +1 -1
- package/lib/esm/session-replay.d.ts +2 -3
- package/lib/esm/session-replay.d.ts.map +1 -1
- package/lib/esm/session-replay.js +13 -29
- package/lib/esm/session-replay.js.map +1 -1
- package/lib/scripts/amplitude-min.js +1 -1
- package/lib/scripts/amplitude-min.js.gz +0 -0
- package/lib/scripts/amplitude-min.umd.js +1 -1
- package/lib/scripts/amplitude-min.umd.js.gz +0 -0
- package/lib/scripts/session-replay.d.ts +2 -3
- package/lib/scripts/session-replay.d.ts.map +1 -1
- package/package.json +3 -3
|
@@ -87,7 +87,7 @@ var SessionReplayJoinedConfigGenerator = /** @class */ (function () {
|
|
|
87
87
|
else {
|
|
88
88
|
config.captureEnabled = false;
|
|
89
89
|
}
|
|
90
|
-
if (samplingConfig
|
|
90
|
+
if (Object.prototype.hasOwnProperty.call(samplingConfig, 'sample_rate')) {
|
|
91
91
|
config.sampleRate = samplingConfig.sample_rate;
|
|
92
92
|
}
|
|
93
93
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"joined-config.js","sourceRoot":"","sources":["../../../src/config/joined-config.ts"],"names":[],"mappings":"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","sourcesContent":["import { RemoteConfigFetch, createRemoteConfigFetch } from '@amplitude/analytics-remote-config';\nimport { SessionReplayOptions } from '../typings/session-replay';\nimport { SessionReplayLocalConfig } from './local-config';\nimport {\n SessionReplayLocalConfig as ISessionReplayLocalConfig,\n PrivacyConfig,\n SessionReplayJoinedConfig,\n SessionReplayRemoteConfig,\n} from './types';\n\nexport class SessionReplayJoinedConfigGenerator {\n localConfig: ISessionReplayLocalConfig;\n remoteConfigFetch: RemoteConfigFetch<SessionReplayRemoteConfig> | undefined;\n\n constructor(apiKey: string, options: SessionReplayOptions) {\n this.localConfig = new SessionReplayLocalConfig(apiKey, options);\n }\n\n async initialize() {\n this.remoteConfigFetch = await createRemoteConfigFetch<SessionReplayRemoteConfig>({\n localConfig: this.localConfig,\n configKeys: ['sessionReplay'],\n });\n }\n\n async generateJoinedConfig(sessionId?: number): Promise<SessionReplayJoinedConfig> {\n const config: SessionReplayJoinedConfig = { ...this.localConfig };\n // Special case here as optOut is implemented via getter/setter\n config.optOut = this.localConfig.optOut;\n // We always want captureEnabled to be true, unless there's an override\n // in the remote config.\n config.captureEnabled = true;\n let remoteConfig: SessionReplayRemoteConfig | undefined;\n try {\n if (!this.remoteConfigFetch) {\n config.captureEnabled = false;\n return config;\n }\n\n const samplingConfig = await this.remoteConfigFetch.getRemoteConfig(\n 'sessionReplay',\n 'sr_sampling_config',\n sessionId,\n );\n\n const privacyConfig = await this.remoteConfigFetch.getRemoteConfig(\n 'sessionReplay',\n 'sr_privacy_config',\n sessionId,\n );\n\n // This is intentionally forced to only be set through the remote config.\n config.interactionConfig = await this.remoteConfigFetch.getRemoteConfig(\n 'sessionReplay',\n 'sr_interaction_config',\n sessionId,\n );\n\n if (samplingConfig || privacyConfig) {\n remoteConfig = {};\n if (samplingConfig) {\n remoteConfig.sr_sampling_config = samplingConfig;\n }\n if (privacyConfig) {\n remoteConfig.sr_privacy_config = privacyConfig;\n }\n }\n } catch (err: unknown) {\n const knownError = err as Error;\n this.localConfig.loggerProvider.warn(knownError.message);\n config.captureEnabled = false;\n }\n\n if (!remoteConfig) {\n return config;\n }\n\n const { sr_sampling_config: samplingConfig, sr_privacy_config: remotePrivacyConfig } = remoteConfig;\n if (samplingConfig && Object.keys(samplingConfig).length > 0) {\n if (Object.prototype.hasOwnProperty.call(samplingConfig, 'capture_enabled')) {\n config.captureEnabled = samplingConfig.capture_enabled;\n } else {\n config.captureEnabled = false;\n }\n\n if (samplingConfig.sample_rate) {\n config.sampleRate = samplingConfig.sample_rate;\n }\n } else {\n // If config API response was valid (ie 200), but no config returned, assume that\n // customer has not yet set up config, and use sample rate from SDK options,\n // allowing for immediate replay capture\n config.captureEnabled = true;\n this.localConfig.loggerProvider.debug(\n 'Remote config successfully fetched, but no values set for project, Session Replay capture enabled.',\n );\n }\n\n // Remote config join acts somewhat like a left join between the remote and the local\n // config. That is, remote config has precedence over local values as with sampling.\n // However, non conflicting values will be added to the lists.\n // Here's an example to illustrate:\n //\n // Remote config: {'.selector1': 'MASK', '.selector2': 'UNMASK'}\n // Local config: {'.selector1': 'UNMASK', '.selector3': 'MASK'}\n //\n // Resolved config: {'.selector1': 'MASK', '.selector2': 'UNMASK', '.selector3': 'MASK'}\n // config.privacyConfig = {\n // ...(config.privacyConfig ?? {}),\n // ...remotePrivacyConfig,\n // };\n\n if (remotePrivacyConfig) {\n const localPrivacyConfig: PrivacyConfig = config.privacyConfig ?? {};\n\n const joinedPrivacyConfig: Required<PrivacyConfig> & { blockSelector: string[] } = {\n defaultMaskLevel: remotePrivacyConfig.defaultMaskLevel ?? localPrivacyConfig.defaultMaskLevel ?? 'medium',\n blockSelector: [],\n maskSelector: [],\n unmaskSelector: [],\n };\n\n const privacyConfigSelectorMap = (privacyConfig: PrivacyConfig): Record<string, 'mask' | 'unmask' | 'block'> => {\n const selectorMap: Record<string, 'mask' | 'unmask' | 'block'> = {};\n if (typeof privacyConfig.blockSelector === 'string') {\n privacyConfig.blockSelector = [privacyConfig.blockSelector];\n }\n\n for (const selector of privacyConfig.blockSelector ?? []) {\n selectorMap[selector] = 'block';\n }\n for (const selector of privacyConfig.maskSelector ?? []) {\n selectorMap[selector] = 'mask';\n }\n for (const selector of privacyConfig.unmaskSelector ?? []) {\n selectorMap[selector] = 'unmask';\n }\n return selectorMap;\n };\n\n const selectorMap: Record<string, 'mask' | 'unmask' | 'block'> = {\n ...privacyConfigSelectorMap(localPrivacyConfig),\n ...privacyConfigSelectorMap(remotePrivacyConfig),\n };\n\n for (const [selector, selectorType] of Object.entries(selectorMap)) {\n if (selectorType === 'mask') {\n joinedPrivacyConfig.maskSelector.push(selector);\n } else if (selectorType === 'block') {\n joinedPrivacyConfig.blockSelector.push(selector);\n } else if (selectorType === 'unmask') {\n joinedPrivacyConfig.unmaskSelector.push(selector);\n }\n }\n\n config.privacyConfig = joinedPrivacyConfig;\n }\n\n return config;\n }\n}\n\nexport const createSessionReplayJoinedConfigGenerator = async (apiKey: string, options: SessionReplayOptions) => {\n const joinedConfigGenerator = new SessionReplayJoinedConfigGenerator(apiKey, options);\n await joinedConfigGenerator.initialize();\n return joinedConfigGenerator;\n};\n"]}
|
|
1
|
+
{"version":3,"file":"joined-config.js","sourceRoot":"","sources":["../../../src/config/joined-config.ts"],"names":[],"mappings":"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","sourcesContent":["import { RemoteConfigFetch, createRemoteConfigFetch } from '@amplitude/analytics-remote-config';\nimport { SessionReplayOptions } from '../typings/session-replay';\nimport { SessionReplayLocalConfig } from './local-config';\nimport {\n SessionReplayLocalConfig as ISessionReplayLocalConfig,\n PrivacyConfig,\n SessionReplayJoinedConfig,\n SessionReplayRemoteConfig,\n} from './types';\n\nexport class SessionReplayJoinedConfigGenerator {\n localConfig: ISessionReplayLocalConfig;\n remoteConfigFetch: RemoteConfigFetch<SessionReplayRemoteConfig> | undefined;\n\n constructor(apiKey: string, options: SessionReplayOptions) {\n this.localConfig = new SessionReplayLocalConfig(apiKey, options);\n }\n\n async initialize() {\n this.remoteConfigFetch = await createRemoteConfigFetch<SessionReplayRemoteConfig>({\n localConfig: this.localConfig,\n configKeys: ['sessionReplay'],\n });\n }\n\n async generateJoinedConfig(sessionId?: number): Promise<SessionReplayJoinedConfig> {\n const config: SessionReplayJoinedConfig = { ...this.localConfig };\n // Special case here as optOut is implemented via getter/setter\n config.optOut = this.localConfig.optOut;\n // We always want captureEnabled to be true, unless there's an override\n // in the remote config.\n config.captureEnabled = true;\n let remoteConfig: SessionReplayRemoteConfig | undefined;\n try {\n if (!this.remoteConfigFetch) {\n config.captureEnabled = false;\n return config;\n }\n\n const samplingConfig = await this.remoteConfigFetch.getRemoteConfig(\n 'sessionReplay',\n 'sr_sampling_config',\n sessionId,\n );\n\n const privacyConfig = await this.remoteConfigFetch.getRemoteConfig(\n 'sessionReplay',\n 'sr_privacy_config',\n sessionId,\n );\n\n // This is intentionally forced to only be set through the remote config.\n config.interactionConfig = await this.remoteConfigFetch.getRemoteConfig(\n 'sessionReplay',\n 'sr_interaction_config',\n sessionId,\n );\n\n if (samplingConfig || privacyConfig) {\n remoteConfig = {};\n if (samplingConfig) {\n remoteConfig.sr_sampling_config = samplingConfig;\n }\n if (privacyConfig) {\n remoteConfig.sr_privacy_config = privacyConfig;\n }\n }\n } catch (err: unknown) {\n const knownError = err as Error;\n this.localConfig.loggerProvider.warn(knownError.message);\n config.captureEnabled = false;\n }\n\n if (!remoteConfig) {\n return config;\n }\n\n const { sr_sampling_config: samplingConfig, sr_privacy_config: remotePrivacyConfig } = remoteConfig;\n if (samplingConfig && Object.keys(samplingConfig).length > 0) {\n if (Object.prototype.hasOwnProperty.call(samplingConfig, 'capture_enabled')) {\n config.captureEnabled = samplingConfig.capture_enabled;\n } else {\n config.captureEnabled = false;\n }\n\n if (Object.prototype.hasOwnProperty.call(samplingConfig, 'sample_rate')) {\n config.sampleRate = samplingConfig.sample_rate;\n }\n } else {\n // If config API response was valid (ie 200), but no config returned, assume that\n // customer has not yet set up config, and use sample rate from SDK options,\n // allowing for immediate replay capture\n config.captureEnabled = true;\n this.localConfig.loggerProvider.debug(\n 'Remote config successfully fetched, but no values set for project, Session Replay capture enabled.',\n );\n }\n\n // Remote config join acts somewhat like a left join between the remote and the local\n // config. That is, remote config has precedence over local values as with sampling.\n // However, non conflicting values will be added to the lists.\n // Here's an example to illustrate:\n //\n // Remote config: {'.selector1': 'MASK', '.selector2': 'UNMASK'}\n // Local config: {'.selector1': 'UNMASK', '.selector3': 'MASK'}\n //\n // Resolved config: {'.selector1': 'MASK', '.selector2': 'UNMASK', '.selector3': 'MASK'}\n // config.privacyConfig = {\n // ...(config.privacyConfig ?? {}),\n // ...remotePrivacyConfig,\n // };\n\n if (remotePrivacyConfig) {\n const localPrivacyConfig: PrivacyConfig = config.privacyConfig ?? {};\n\n const joinedPrivacyConfig: Required<PrivacyConfig> & { blockSelector: string[] } = {\n defaultMaskLevel: remotePrivacyConfig.defaultMaskLevel ?? localPrivacyConfig.defaultMaskLevel ?? 'medium',\n blockSelector: [],\n maskSelector: [],\n unmaskSelector: [],\n };\n\n const privacyConfigSelectorMap = (privacyConfig: PrivacyConfig): Record<string, 'mask' | 'unmask' | 'block'> => {\n const selectorMap: Record<string, 'mask' | 'unmask' | 'block'> = {};\n if (typeof privacyConfig.blockSelector === 'string') {\n privacyConfig.blockSelector = [privacyConfig.blockSelector];\n }\n\n for (const selector of privacyConfig.blockSelector ?? []) {\n selectorMap[selector] = 'block';\n }\n for (const selector of privacyConfig.maskSelector ?? []) {\n selectorMap[selector] = 'mask';\n }\n for (const selector of privacyConfig.unmaskSelector ?? []) {\n selectorMap[selector] = 'unmask';\n }\n return selectorMap;\n };\n\n const selectorMap: Record<string, 'mask' | 'unmask' | 'block'> = {\n ...privacyConfigSelectorMap(localPrivacyConfig),\n ...privacyConfigSelectorMap(remotePrivacyConfig),\n };\n\n for (const [selector, selectorType] of Object.entries(selectorMap)) {\n if (selectorType === 'mask') {\n joinedPrivacyConfig.maskSelector.push(selector);\n } else if (selectorType === 'block') {\n joinedPrivacyConfig.blockSelector.push(selector);\n } else if (selectorType === 'unmask') {\n joinedPrivacyConfig.unmaskSelector.push(selector);\n }\n }\n\n config.privacyConfig = joinedPrivacyConfig;\n }\n\n return config;\n }\n}\n\nexport const createSessionReplayJoinedConfigGenerator = async (apiKey: string, options: SessionReplayOptions) => {\n const joinedConfigGenerator = new SessionReplayJoinedConfigGenerator(apiKey, options);\n await joinedConfigGenerator.initialize();\n return joinedConfigGenerator;\n};\n"]}
|
|
@@ -25,17 +25,16 @@ export declare class SessionReplay implements AmplitudeSessionReplay {
|
|
|
25
25
|
[key: string]: string | null;
|
|
26
26
|
};
|
|
27
27
|
blurListener: () => void;
|
|
28
|
-
focusListener: () => void;
|
|
29
28
|
/**
|
|
30
29
|
* This is an instance member so that if init is called multiple times
|
|
31
30
|
* it doesn't add another listener to the page leave event. This is to
|
|
32
31
|
* prevent duplicate listener actions from firing.
|
|
33
32
|
*/
|
|
34
33
|
private pageLeaveListener;
|
|
35
|
-
|
|
34
|
+
sendEvents(sessionId?: number): void;
|
|
36
35
|
initialize(shouldSendStoredEvents?: boolean): void;
|
|
37
36
|
shouldOptOut(): boolean | undefined;
|
|
38
|
-
getShouldRecord(
|
|
37
|
+
getShouldRecord(): boolean;
|
|
39
38
|
getBlockSelectors(): string | string[] | undefined;
|
|
40
39
|
getMaskTextSelectors(): string | undefined;
|
|
41
40
|
recordEvents(): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-replay.d.ts","sourceRoot":"","sources":["../../src/session-replay.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,IAAI,OAAO,EAAY,MAAM,4BAA4B,CAAC;AACzE,OAAO,EAAQ,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAGhD,OAAO,EAAE,yBAAyB,EAAE,kCAAkC,EAAE,MAAM,gBAAgB,CAAC;AAe/F,OAAO,EACL,sBAAsB,EACtB,0BAA0B,IAAI,mCAAmC,EAGjE,kBAAkB,IAAI,mBAAmB,EACzC,oBAAoB,EACrB,MAAM,0BAA0B,CAAC;AAElC,KAAK,WAAW,GAAG,CAAC,CAAC,EAAE,mBAAmB,GAAG,KAAK,KAAK,IAAI,CAAC;AAE5D,qBAAa,aAAc,YAAW,sBAAsB;IAC1D,IAAI,SAAuC;IAC3C,MAAM,EAAE,yBAAyB,GAAG,SAAS,CAAC;IAC9C,qBAAqB,EAAE,kCAAkC,GAAG,SAAS,CAAC;IACtE,WAAW,EAAE,mBAAmB,GAAG,SAAS,CAAC;IAC7C,aAAa,CAAC,EAAE,mCAAmC,CAAC,QAAQ,GAAG,aAAa,EAAE,MAAM,CAAC,CAAC;IACtF,cAAc,EAAE,OAAO,CAAC;IACxB,oBAAoB,EAAE,UAAU,CAAC,OAAO,MAAM,CAAC,GAAG,IAAI,CAAQ;IAG9D,YAAY,EAAE,WAAW,EAAE,CAAM;IACjC,OAAO,CAAC,UAAU,CAAC,CAAiB;;IAMpC,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,oBAAoB;IAIlD,sBAAsB;IA+BtB,OAAO,CAAC,sBAAsB,
|
|
1
|
+
{"version":3,"file":"session-replay.d.ts","sourceRoot":"","sources":["../../src/session-replay.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,IAAI,OAAO,EAAY,MAAM,4BAA4B,CAAC;AACzE,OAAO,EAAQ,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAGhD,OAAO,EAAE,yBAAyB,EAAE,kCAAkC,EAAE,MAAM,gBAAgB,CAAC;AAe/F,OAAO,EACL,sBAAsB,EACtB,0BAA0B,IAAI,mCAAmC,EAGjE,kBAAkB,IAAI,mBAAmB,EACzC,oBAAoB,EACrB,MAAM,0BAA0B,CAAC;AAElC,KAAK,WAAW,GAAG,CAAC,CAAC,EAAE,mBAAmB,GAAG,KAAK,KAAK,IAAI,CAAC;AAE5D,qBAAa,aAAc,YAAW,sBAAsB;IAC1D,IAAI,SAAuC;IAC3C,MAAM,EAAE,yBAAyB,GAAG,SAAS,CAAC;IAC9C,qBAAqB,EAAE,kCAAkC,GAAG,SAAS,CAAC;IACtE,WAAW,EAAE,mBAAmB,GAAG,SAAS,CAAC;IAC7C,aAAa,CAAC,EAAE,mCAAmC,CAAC,QAAQ,GAAG,aAAa,EAAE,MAAM,CAAC,CAAC;IACtF,cAAc,EAAE,OAAO,CAAC;IACxB,oBAAoB,EAAE,UAAU,CAAC,OAAO,MAAM,CAAC,GAAG,IAAI,CAAQ;IAG9D,YAAY,EAAE,WAAW,EAAE,CAAM;IACjC,OAAO,CAAC,UAAU,CAAC,CAAiB;;IAMpC,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,oBAAoB;IAIlD,sBAAsB;IA+BtB,OAAO,CAAC,sBAAsB,CAiB5B;cAEc,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,oBAAoB;IA0DnE,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM;IAI3C,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM;IAoB5D,kCAAkC;IAUlC,0BAA0B;;;IAqB1B,YAAY,aAEV;IAEF;;;;OAIG;IACH,OAAO,CAAC,iBAAiB,CAIvB;IAEF,UAAU,CAAC,SAAS,CAAC,EAAE,MAAM;IAS7B,UAAU,CAAC,sBAAsB,UAAQ;IAgBzC,YAAY;IAUZ,eAAe;IAwBf,iBAAiB,IAAI,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS;IAWlD,oBAAoB,IAAI,MAAM,GAAG,SAAS;IAa1C,YAAY;IAmEZ,mBAAmB,aAQjB;IAEF,WAAW;IAUX,YAAY;IAIN,KAAK,CAAC,QAAQ,UAAQ;IAI5B,QAAQ;CAKT"}
|
|
@@ -23,9 +23,7 @@ var SessionReplay = /** @class */ (function () {
|
|
|
23
23
|
var globalScope = (0, analytics_client_common_1.getGlobalScope)();
|
|
24
24
|
if (globalScope) {
|
|
25
25
|
globalScope.removeEventListener('blur', _this.blurListener);
|
|
26
|
-
globalScope.removeEventListener('focus', _this.focusListener);
|
|
27
26
|
!teardown && globalScope.addEventListener('blur', _this.blurListener);
|
|
28
|
-
!teardown && globalScope.addEventListener('focus', _this.focusListener);
|
|
29
27
|
// prefer pagehide to unload events, this is the standard going forward. it is not
|
|
30
28
|
// 100% reliable, but is bfcache-compatible.
|
|
31
29
|
if (globalScope.self && 'onpagehide' in globalScope.self) {
|
|
@@ -41,10 +39,7 @@ var SessionReplay = /** @class */ (function () {
|
|
|
41
39
|
}
|
|
42
40
|
};
|
|
43
41
|
this.blurListener = function () {
|
|
44
|
-
_this.
|
|
45
|
-
};
|
|
46
|
-
this.focusListener = function () {
|
|
47
|
-
_this.initialize();
|
|
42
|
+
_this.sendEvents();
|
|
48
43
|
};
|
|
49
44
|
/**
|
|
50
45
|
* This is an instance member so that if init is called multiple times
|
|
@@ -106,7 +101,7 @@ var SessionReplay = /** @class */ (function () {
|
|
|
106
101
|
SessionReplay.prototype._init = function (apiKey, options) {
|
|
107
102
|
var _a, _b, _c;
|
|
108
103
|
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
109
|
-
var _d, _e, scrollWatcher, managers, rrwebEventManager, interactionEventManager
|
|
104
|
+
var _d, _e, scrollWatcher, managers, rrwebEventManager, interactionEventManager;
|
|
110
105
|
return tslib_1.__generator(this, function (_f) {
|
|
111
106
|
switch (_f.label) {
|
|
112
107
|
case 0:
|
|
@@ -158,10 +153,7 @@ var SessionReplay = /** @class */ (function () {
|
|
|
158
153
|
this.eventsManager = new (multi_manager_1.MultiEventManager.bind.apply(multi_manager_1.MultiEventManager, tslib_1.__spreadArray([void 0], tslib_1.__read(managers), false)))();
|
|
159
154
|
this.loggerProvider.log('Installing @amplitude/session-replay-browser.');
|
|
160
155
|
this.teardownEventListeners(false);
|
|
161
|
-
|
|
162
|
-
if (globalScope && globalScope.document && globalScope.document.hasFocus()) {
|
|
163
|
-
this.initialize(true);
|
|
164
|
-
}
|
|
156
|
+
this.initialize(true);
|
|
165
157
|
return [2 /*return*/];
|
|
166
158
|
}
|
|
167
159
|
});
|
|
@@ -178,7 +170,7 @@ var SessionReplay = /** @class */ (function () {
|
|
|
178
170
|
case 0:
|
|
179
171
|
previousSessionId = this.identifiers && this.identifiers.sessionId;
|
|
180
172
|
if (previousSessionId) {
|
|
181
|
-
this.
|
|
173
|
+
this.sendEvents(previousSessionId);
|
|
182
174
|
}
|
|
183
175
|
deviceIdForReplayId = deviceId || this.getDeviceId();
|
|
184
176
|
this.identifiers = new identifiers_1.SessionIdentifiers({
|
|
@@ -213,10 +205,7 @@ var SessionReplay = /** @class */ (function () {
|
|
|
213
205
|
this.loggerProvider.error('Session replay init has not been called, cannot get session recording properties.');
|
|
214
206
|
return {};
|
|
215
207
|
}
|
|
216
|
-
|
|
217
|
-
// this is a common mishap when someone is developing locally and not seeing events getting tagged.
|
|
218
|
-
var ignoreFocus = !!this.config.debugMode;
|
|
219
|
-
var shouldRecord = this.getShouldRecord(ignoreFocus);
|
|
208
|
+
var shouldRecord = this.getShouldRecord();
|
|
220
209
|
if (shouldRecord) {
|
|
221
210
|
var eventProperties = (_a = {},
|
|
222
211
|
_a[constants_1.DEFAULT_SESSION_REPLAY_PROPERTY] = this.identifiers.sessionReplayId ? this.identifiers.sessionReplayId : null,
|
|
@@ -228,9 +217,8 @@ var SessionReplay = /** @class */ (function () {
|
|
|
228
217
|
}
|
|
229
218
|
return {};
|
|
230
219
|
};
|
|
231
|
-
SessionReplay.prototype.
|
|
220
|
+
SessionReplay.prototype.sendEvents = function (sessionId) {
|
|
232
221
|
var _a;
|
|
233
|
-
this.stopRecordingEvents();
|
|
234
222
|
var sessionIdToSend = sessionId || ((_a = this.identifiers) === null || _a === void 0 ? void 0 : _a.sessionId);
|
|
235
223
|
var deviceId = this.getDeviceId();
|
|
236
224
|
this.eventsManager &&
|
|
@@ -262,8 +250,7 @@ var SessionReplay = /** @class */ (function () {
|
|
|
262
250
|
}
|
|
263
251
|
return identityStoreOptOut !== undefined ? identityStoreOptOut : (_b = this.config) === null || _b === void 0 ? void 0 : _b.optOut;
|
|
264
252
|
};
|
|
265
|
-
SessionReplay.prototype.getShouldRecord = function (
|
|
266
|
-
if (ignoreFocus === void 0) { ignoreFocus = false; }
|
|
253
|
+
SessionReplay.prototype.getShouldRecord = function () {
|
|
267
254
|
if (!this.identifiers || !this.config || !this.identifiers.sessionId) {
|
|
268
255
|
this.loggerProvider.warn("Session is not being recorded due to lack of config, please call sessionReplay.init.");
|
|
269
256
|
return false;
|
|
@@ -272,11 +259,6 @@ var SessionReplay = /** @class */ (function () {
|
|
|
272
259
|
this.loggerProvider.log("Session ".concat(this.identifiers.sessionId, " not being captured due to capture being disabled for project or because the remote config could not be fetched."));
|
|
273
260
|
return false;
|
|
274
261
|
}
|
|
275
|
-
var globalScope = (0, analytics_client_common_1.getGlobalScope)();
|
|
276
|
-
if (!ignoreFocus && globalScope && globalScope.document && !globalScope.document.hasFocus()) {
|
|
277
|
-
this.loggerProvider.log("Session ".concat(this.identifiers.sessionId, " temporarily not recording due to lack of browser focus."));
|
|
278
|
-
return false;
|
|
279
|
-
}
|
|
280
262
|
if (this.shouldOptOut()) {
|
|
281
263
|
this.loggerProvider.log("Opting session ".concat(this.identifiers.sessionId, " out of recording due to optOut config."));
|
|
282
264
|
return false;
|
|
@@ -321,9 +303,10 @@ var SessionReplay = /** @class */ (function () {
|
|
|
321
303
|
var privacyConfig = this.config.privacyConfig;
|
|
322
304
|
this.recordCancelCallback = (0, rrweb_1.record)({
|
|
323
305
|
emit: function (event) {
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
_this.
|
|
306
|
+
if (_this.shouldOptOut()) {
|
|
307
|
+
_this.loggerProvider.log("Opting session ".concat(sessionId, " out of recording due to optOut config."));
|
|
308
|
+
_this.stopRecordingEvents();
|
|
309
|
+
_this.sendEvents();
|
|
327
310
|
return;
|
|
328
311
|
}
|
|
329
312
|
var eventString = JSON.stringify(event);
|
|
@@ -395,7 +378,8 @@ var SessionReplay = /** @class */ (function () {
|
|
|
395
378
|
};
|
|
396
379
|
SessionReplay.prototype.shutdown = function () {
|
|
397
380
|
this.teardownEventListeners(true);
|
|
398
|
-
this.
|
|
381
|
+
this.stopRecordingEvents();
|
|
382
|
+
this.sendEvents();
|
|
399
383
|
};
|
|
400
384
|
return SessionReplay;
|
|
401
385
|
}());
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-replay.js","sourceRoot":"","sources":["../../src/session-replay.ts"],"names":[],"mappings":"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","sourcesContent":["import { getAnalyticsConnector, getGlobalScope } from '@amplitude/analytics-client-common';\nimport { Logger, returnWrapper } from '@amplitude/analytics-core';\nimport { Logger as ILogger, LogLevel } from '@amplitude/analytics-types';\nimport { pack, record } from '@amplitude/rrweb';\nimport { scrollCallback } from '@amplitude/rrweb-types';\nimport { createSessionReplayJoinedConfigGenerator } from './config/joined-config';\nimport { SessionReplayJoinedConfig, SessionReplayJoinedConfigGenerator } from './config/types';\nimport {\n BLOCK_CLASS,\n DEFAULT_SESSION_REPLAY_PROPERTY,\n INTERACTION_MAX_INTERVAL,\n INTERACTION_MIN_INTERVAL,\n MASK_TEXT_CLASS,\n SESSION_REPLAY_DEBUG_PROPERTY,\n} from './constants';\nimport { createEventsManager } from './events/events-manager';\nimport { MultiEventManager } from './events/multi-manager';\nimport { generateHashCode, isSessionInSample, maskFn } from './helpers';\nimport { clickBatcher, clickHook } from './hooks/click';\nimport { ScrollWatcher } from './hooks/scroll';\nimport { SessionIdentifiers } from './identifiers';\nimport {\n AmplitudeSessionReplay,\n SessionReplayEventsManager as AmplitudeSessionReplayEventsManager,\n EventType,\n EventsManagerWithType,\n SessionIdentifiers as ISessionIdentifiers,\n SessionReplayOptions,\n} from './typings/session-replay';\n\ntype PageLeaveFn = (e: PageTransitionEvent | Event) => void;\n\nexport class SessionReplay implements AmplitudeSessionReplay {\n name = '@amplitude/session-replay-browser';\n config: SessionReplayJoinedConfig | undefined;\n joinedConfigGenerator: SessionReplayJoinedConfigGenerator | undefined;\n identifiers: ISessionIdentifiers | undefined;\n eventsManager?: AmplitudeSessionReplayEventsManager<'replay' | 'interaction', string>;\n loggerProvider: ILogger;\n recordCancelCallback: ReturnType<typeof record> | null = null;\n\n // Visible for testing\n pageLeaveFns: PageLeaveFn[] = [];\n private scrollHook?: scrollCallback;\n\n constructor() {\n this.loggerProvider = new Logger();\n }\n\n init(apiKey: string, options: SessionReplayOptions) {\n return returnWrapper(this._init(apiKey, options));\n }\n\n removeInvalidSelectors() {\n if (!this.config?.privacyConfig) {\n return;\n }\n\n // This allows us to not search the DOM.\n const fragment = document.createDocumentFragment();\n\n const dropInvalidSelectors = (selectors: string[] | string = []): string[] | undefined => {\n if (typeof selectors === 'string') {\n selectors = [selectors];\n }\n selectors = selectors.filter((selector: string) => {\n try {\n fragment.querySelector(selector);\n } catch {\n this.loggerProvider.warn(`[session-replay-browser] omitting selector \"${selector}\" because it is invalid`);\n return false;\n }\n return true;\n });\n if (selectors.length === 0) {\n return undefined;\n }\n return selectors;\n };\n this.config.privacyConfig.blockSelector = dropInvalidSelectors(this.config.privacyConfig.blockSelector);\n this.config.privacyConfig.maskSelector = dropInvalidSelectors(this.config.privacyConfig.maskSelector);\n this.config.privacyConfig.unmaskSelector = dropInvalidSelectors(this.config.privacyConfig.unmaskSelector);\n }\n\n private teardownEventListeners = (teardown: boolean) => {\n const globalScope = getGlobalScope();\n if (globalScope) {\n globalScope.removeEventListener('blur', this.blurListener);\n globalScope.removeEventListener('focus', this.focusListener);\n !teardown && globalScope.addEventListener('blur', this.blurListener);\n !teardown && globalScope.addEventListener('focus', this.focusListener);\n // prefer pagehide to unload events, this is the standard going forward. it is not\n // 100% reliable, but is bfcache-compatible.\n if (globalScope.self && 'onpagehide' in globalScope.self) {\n globalScope.removeEventListener('pagehide', this.pageLeaveListener);\n !teardown && globalScope.addEventListener('pagehide', this.pageLeaveListener);\n } else {\n // this has performance implications, but is the only way we can reliably send events\n // in browser that don't support pagehide.\n globalScope.removeEventListener('beforeunload', this.pageLeaveListener);\n !teardown && globalScope.addEventListener('beforeunload', this.pageLeaveListener);\n }\n }\n };\n\n protected async _init(apiKey: string, options: SessionReplayOptions) {\n this.loggerProvider = options.loggerProvider || new Logger();\n Object.prototype.hasOwnProperty.call(options, 'logLevel') &&\n this.loggerProvider.enable(options.logLevel as LogLevel);\n this.identifiers = new SessionIdentifiers({ sessionId: options.sessionId, deviceId: options.deviceId });\n this.joinedConfigGenerator = await createSessionReplayJoinedConfigGenerator(apiKey, options);\n this.config = await this.joinedConfigGenerator.generateJoinedConfig(this.identifiers.sessionId);\n this.loggerProvider.debug(\n JSON.stringify(\n { name: 'session replay joined privacy config', privacyConfig: this.config.privacyConfig },\n null,\n 2,\n ),\n );\n\n if (options.sessionId && this.config.interactionConfig?.enabled) {\n const scrollWatcher = ScrollWatcher.default(\n {\n sessionId: options.sessionId,\n type: 'interaction',\n },\n this.config,\n );\n this.pageLeaveFns = [scrollWatcher.send(this.getDeviceId.bind(this))];\n this.scrollHook = scrollWatcher.hook.bind(scrollWatcher);\n }\n\n this.removeInvalidSelectors();\n\n const managers: EventsManagerWithType<EventType, string>[] = [];\n const rrwebEventManager = await createEventsManager<'replay'>({\n config: this.config,\n sessionId: this.identifiers.sessionId,\n type: 'replay',\n });\n managers.push({ name: 'replay', manager: rrwebEventManager });\n\n if (this.config.interactionConfig?.enabled) {\n const interactionEventManager = await createEventsManager<'interaction'>({\n config: this.config,\n sessionId: this.identifiers.sessionId,\n type: 'interaction',\n minInterval: this.config.interactionConfig.trackEveryNms ?? INTERACTION_MIN_INTERVAL,\n maxInterval: INTERACTION_MAX_INTERVAL,\n payloadBatcher: clickBatcher,\n });\n managers.push({ name: 'interaction', manager: interactionEventManager });\n }\n\n this.eventsManager = new MultiEventManager<'replay' | 'interaction', string>(...managers);\n\n this.loggerProvider.log('Installing @amplitude/session-replay-browser.');\n\n this.teardownEventListeners(false);\n\n const globalScope = getGlobalScope();\n if (globalScope && globalScope.document && globalScope.document.hasFocus()) {\n this.initialize(true);\n }\n }\n\n setSessionId(sessionId: number, deviceId?: string) {\n return returnWrapper(this.asyncSetSessionId(sessionId, deviceId));\n }\n\n async asyncSetSessionId(sessionId: number, deviceId?: string) {\n const previousSessionId = this.identifiers && this.identifiers.sessionId;\n if (previousSessionId) {\n this.stopRecordingAndSendEvents(previousSessionId);\n }\n\n const deviceIdForReplayId = deviceId || this.getDeviceId();\n this.identifiers = new SessionIdentifiers({\n sessionId: sessionId,\n deviceId: deviceIdForReplayId,\n });\n\n // If there is no previous session id, SDK is being initialized for the first time,\n // and config was just fetched in initialization, so no need to fetch it a second time\n if (this.joinedConfigGenerator && previousSessionId) {\n this.config = await this.joinedConfigGenerator.generateJoinedConfig(this.identifiers.sessionId);\n }\n this.recordEvents();\n }\n\n getSessionReplayDebugPropertyValue() {\n let apiKeyHash = '';\n if (this.config) {\n apiKeyHash = generateHashCode(this.config.apiKey).toString();\n }\n return JSON.stringify({\n appHash: apiKeyHash,\n });\n }\n\n getSessionReplayProperties() {\n if (!this.config || !this.identifiers) {\n this.loggerProvider.error('Session replay init has not been called, cannot get session recording properties.');\n return {};\n }\n\n // If the user is in debug mode, ignore the focus handler when tagging events.\n // this is a common mishap when someone is developing locally and not seeing events getting tagged.\n const ignoreFocus = !!this.config.debugMode;\n const shouldRecord = this.getShouldRecord(ignoreFocus);\n\n if (shouldRecord) {\n const eventProperties: { [key: string]: string | null } = {\n [DEFAULT_SESSION_REPLAY_PROPERTY]: this.identifiers.sessionReplayId ? this.identifiers.sessionReplayId : null,\n };\n if (this.config.debugMode) {\n eventProperties[SESSION_REPLAY_DEBUG_PROPERTY] = this.getSessionReplayDebugPropertyValue();\n }\n return eventProperties;\n }\n\n return {};\n }\n\n blurListener = () => {\n this.stopRecordingAndSendEvents();\n };\n\n focusListener = () => {\n this.initialize();\n };\n /**\n * This is an instance member so that if init is called multiple times\n * it doesn't add another listener to the page leave event. This is to\n * prevent duplicate listener actions from firing.\n */\n private pageLeaveListener = (e: PageTransitionEvent | Event) => {\n this.pageLeaveFns.forEach((fn) => {\n fn(e);\n });\n };\n\n stopRecordingAndSendEvents(sessionId?: number) {\n this.stopRecordingEvents();\n\n const sessionIdToSend = sessionId || this.identifiers?.sessionId;\n const deviceId = this.getDeviceId();\n this.eventsManager &&\n sessionIdToSend &&\n deviceId &&\n this.eventsManager.sendCurrentSequenceEvents({ sessionId: sessionIdToSend, deviceId });\n }\n\n initialize(shouldSendStoredEvents = false) {\n if (!this.identifiers?.sessionId) {\n this.loggerProvider.log(`Session is not being recorded due to lack of session id.`);\n return;\n }\n\n const deviceId = this.getDeviceId();\n if (!deviceId) {\n this.loggerProvider.log(`Session is not being recorded due to lack of device id.`);\n return;\n }\n this.eventsManager && shouldSendStoredEvents && this.eventsManager.sendStoredEvents({ deviceId });\n\n this.recordEvents();\n }\n\n shouldOptOut() {\n let identityStoreOptOut: boolean | undefined;\n if (this.config?.instanceName) {\n const identityStore = getAnalyticsConnector(this.config.instanceName).identityStore;\n identityStoreOptOut = identityStore.getIdentity().optOut;\n }\n\n return identityStoreOptOut !== undefined ? identityStoreOptOut : this.config?.optOut;\n }\n\n getShouldRecord(ignoreFocus = false) {\n if (!this.identifiers || !this.config || !this.identifiers.sessionId) {\n this.loggerProvider.warn(`Session is not being recorded due to lack of config, please call sessionReplay.init.`);\n return false;\n }\n if (!this.config.captureEnabled) {\n this.loggerProvider.log(\n `Session ${this.identifiers.sessionId} not being captured due to capture being disabled for project or because the remote config could not be fetched.`,\n );\n return false;\n }\n\n const globalScope = getGlobalScope();\n if (!ignoreFocus && globalScope && globalScope.document && !globalScope.document.hasFocus()) {\n this.loggerProvider.log(\n `Session ${this.identifiers.sessionId} temporarily not recording due to lack of browser focus.`,\n );\n return false;\n }\n\n if (this.shouldOptOut()) {\n this.loggerProvider.log(`Opting session ${this.identifiers.sessionId} out of recording due to optOut config.`);\n return false;\n }\n\n const isInSample = isSessionInSample(this.identifiers.sessionId, this.config.sampleRate);\n if (!isInSample) {\n this.loggerProvider.log(`Opting session ${this.identifiers.sessionId} out of recording due to sample rate.`);\n }\n return isInSample;\n }\n\n getBlockSelectors(): string | string[] | undefined {\n // For some reason, this defaults to empty array ([]) if undefined in the compiled script.\n // Empty arrays cause errors when being evaluated in Safari.\n // Force the selector to be undefined if it's an empty array.\n const blockSelector = this.config?.privacyConfig?.blockSelector ?? [];\n if (blockSelector.length === 0) {\n return undefined;\n }\n return blockSelector;\n }\n\n getMaskTextSelectors(): string | undefined {\n if (this.config?.privacyConfig?.defaultMaskLevel === 'conservative') {\n return '*';\n }\n\n const maskSelector = this.config?.privacyConfig?.maskSelector;\n if (!maskSelector) {\n return;\n }\n\n return maskSelector as unknown as string;\n }\n\n recordEvents() {\n const shouldRecord = this.getShouldRecord();\n const sessionId = this.identifiers?.sessionId;\n if (!shouldRecord || !sessionId || !this.config) {\n return;\n }\n this.stopRecordingEvents();\n const privacyConfig = this.config.privacyConfig;\n\n this.recordCancelCallback = record({\n emit: (event) => {\n const globalScope = getGlobalScope();\n if ((globalScope && globalScope.document && !globalScope.document.hasFocus()) || !this.getShouldRecord()) {\n this.stopRecordingAndSendEvents();\n return;\n }\n const eventString = JSON.stringify(event);\n const deviceId = this.getDeviceId();\n this.eventsManager &&\n deviceId &&\n this.eventsManager.addEvent({ event: { type: 'replay', data: eventString }, sessionId, deviceId });\n },\n packFn: pack,\n inlineStylesheet: this.config.shouldInlineStylesheet,\n hooks: {\n mouseInteraction:\n this.eventsManager &&\n clickHook({\n eventsManager: this.eventsManager,\n sessionId,\n deviceIdFn: this.getDeviceId.bind(this),\n }),\n scroll: this.scrollHook,\n },\n maskAllInputs: true,\n maskTextClass: MASK_TEXT_CLASS,\n blockClass: BLOCK_CLASS,\n // rrweb only exposes string type through its types, but arrays are also be supported. #class, ['#class', 'id']\n blockSelector: this.getBlockSelectors() as string | undefined,\n maskInputFn: maskFn('input', privacyConfig),\n maskTextFn: maskFn('text', privacyConfig),\n // rrweb only exposes string type through its types, but arrays are also be supported. since rrweb uses .matches() which supports arrays.\n maskTextSelector: this.getMaskTextSelectors(),\n recordCanvas: false,\n errorHandler: (error) => {\n const typedError = error as Error & { _external_?: boolean };\n\n // styled-components relies on this error being thrown and bubbled up, rrweb is otherwise suppressing it\n if (typedError.message.includes('insertRule') && typedError.message.includes('CSSStyleSheet')) {\n throw typedError;\n }\n\n // rrweb does monkey patching on certain window functions such as CSSStyleSheet.proptype.insertRule,\n // and errors from external clients calling these functions can get suppressed. Styled components depend\n // on these errors being re-thrown.\n if (typedError._external_) {\n throw typedError;\n }\n\n this.loggerProvider.warn('Error while recording: ', typedError.toString());\n // Return true so that we don't clutter user's consoles with internal rrweb errors\n return true;\n },\n });\n }\n\n stopRecordingEvents = () => {\n try {\n this.recordCancelCallback && this.recordCancelCallback();\n this.recordCancelCallback = null;\n } catch (error) {\n const typedError = error as Error;\n this.loggerProvider.warn(`Error occurred while stopping recording: ${typedError.toString()}`);\n }\n };\n\n getDeviceId() {\n let identityStoreDeviceId: string | undefined;\n if (this.config?.instanceName) {\n const identityStore = getAnalyticsConnector(this.config.instanceName).identityStore;\n identityStoreDeviceId = identityStore.getIdentity().deviceId;\n }\n\n return identityStoreDeviceId || this.identifiers?.deviceId;\n }\n\n getSessionId() {\n return this.identifiers?.sessionId;\n }\n\n async flush(useRetry = false) {\n return this.eventsManager?.flush(useRetry);\n }\n\n shutdown() {\n this.teardownEventListeners(true);\n this.stopRecordingAndSendEvents();\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"session-replay.js","sourceRoot":"","sources":["../../src/session-replay.ts"],"names":[],"mappings":"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","sourcesContent":["import { getAnalyticsConnector, getGlobalScope } from '@amplitude/analytics-client-common';\nimport { Logger, returnWrapper } from '@amplitude/analytics-core';\nimport { Logger as ILogger, LogLevel } from '@amplitude/analytics-types';\nimport { pack, record } from '@amplitude/rrweb';\nimport { scrollCallback } from '@amplitude/rrweb-types';\nimport { createSessionReplayJoinedConfigGenerator } from './config/joined-config';\nimport { SessionReplayJoinedConfig, SessionReplayJoinedConfigGenerator } from './config/types';\nimport {\n BLOCK_CLASS,\n DEFAULT_SESSION_REPLAY_PROPERTY,\n INTERACTION_MAX_INTERVAL,\n INTERACTION_MIN_INTERVAL,\n MASK_TEXT_CLASS,\n SESSION_REPLAY_DEBUG_PROPERTY,\n} from './constants';\nimport { createEventsManager } from './events/events-manager';\nimport { MultiEventManager } from './events/multi-manager';\nimport { generateHashCode, isSessionInSample, maskFn } from './helpers';\nimport { clickBatcher, clickHook } from './hooks/click';\nimport { ScrollWatcher } from './hooks/scroll';\nimport { SessionIdentifiers } from './identifiers';\nimport {\n AmplitudeSessionReplay,\n SessionReplayEventsManager as AmplitudeSessionReplayEventsManager,\n EventType,\n EventsManagerWithType,\n SessionIdentifiers as ISessionIdentifiers,\n SessionReplayOptions,\n} from './typings/session-replay';\n\ntype PageLeaveFn = (e: PageTransitionEvent | Event) => void;\n\nexport class SessionReplay implements AmplitudeSessionReplay {\n name = '@amplitude/session-replay-browser';\n config: SessionReplayJoinedConfig | undefined;\n joinedConfigGenerator: SessionReplayJoinedConfigGenerator | undefined;\n identifiers: ISessionIdentifiers | undefined;\n eventsManager?: AmplitudeSessionReplayEventsManager<'replay' | 'interaction', string>;\n loggerProvider: ILogger;\n recordCancelCallback: ReturnType<typeof record> | null = null;\n\n // Visible for testing\n pageLeaveFns: PageLeaveFn[] = [];\n private scrollHook?: scrollCallback;\n\n constructor() {\n this.loggerProvider = new Logger();\n }\n\n init(apiKey: string, options: SessionReplayOptions) {\n return returnWrapper(this._init(apiKey, options));\n }\n\n removeInvalidSelectors() {\n if (!this.config?.privacyConfig) {\n return;\n }\n\n // This allows us to not search the DOM.\n const fragment = document.createDocumentFragment();\n\n const dropInvalidSelectors = (selectors: string[] | string = []): string[] | undefined => {\n if (typeof selectors === 'string') {\n selectors = [selectors];\n }\n selectors = selectors.filter((selector: string) => {\n try {\n fragment.querySelector(selector);\n } catch {\n this.loggerProvider.warn(`[session-replay-browser] omitting selector \"${selector}\" because it is invalid`);\n return false;\n }\n return true;\n });\n if (selectors.length === 0) {\n return undefined;\n }\n return selectors;\n };\n this.config.privacyConfig.blockSelector = dropInvalidSelectors(this.config.privacyConfig.blockSelector);\n this.config.privacyConfig.maskSelector = dropInvalidSelectors(this.config.privacyConfig.maskSelector);\n this.config.privacyConfig.unmaskSelector = dropInvalidSelectors(this.config.privacyConfig.unmaskSelector);\n }\n\n private teardownEventListeners = (teardown: boolean) => {\n const globalScope = getGlobalScope();\n if (globalScope) {\n globalScope.removeEventListener('blur', this.blurListener);\n !teardown && globalScope.addEventListener('blur', this.blurListener);\n // prefer pagehide to unload events, this is the standard going forward. it is not\n // 100% reliable, but is bfcache-compatible.\n if (globalScope.self && 'onpagehide' in globalScope.self) {\n globalScope.removeEventListener('pagehide', this.pageLeaveListener);\n !teardown && globalScope.addEventListener('pagehide', this.pageLeaveListener);\n } else {\n // this has performance implications, but is the only way we can reliably send events\n // in browser that don't support pagehide.\n globalScope.removeEventListener('beforeunload', this.pageLeaveListener);\n !teardown && globalScope.addEventListener('beforeunload', this.pageLeaveListener);\n }\n }\n };\n\n protected async _init(apiKey: string, options: SessionReplayOptions) {\n this.loggerProvider = options.loggerProvider || new Logger();\n Object.prototype.hasOwnProperty.call(options, 'logLevel') &&\n this.loggerProvider.enable(options.logLevel as LogLevel);\n this.identifiers = new SessionIdentifiers({ sessionId: options.sessionId, deviceId: options.deviceId });\n this.joinedConfigGenerator = await createSessionReplayJoinedConfigGenerator(apiKey, options);\n this.config = await this.joinedConfigGenerator.generateJoinedConfig(this.identifiers.sessionId);\n this.loggerProvider.debug(\n JSON.stringify(\n { name: 'session replay joined privacy config', privacyConfig: this.config.privacyConfig },\n null,\n 2,\n ),\n );\n\n if (options.sessionId && this.config.interactionConfig?.enabled) {\n const scrollWatcher = ScrollWatcher.default(\n {\n sessionId: options.sessionId,\n type: 'interaction',\n },\n this.config,\n );\n this.pageLeaveFns = [scrollWatcher.send(this.getDeviceId.bind(this))];\n this.scrollHook = scrollWatcher.hook.bind(scrollWatcher);\n }\n\n this.removeInvalidSelectors();\n\n const managers: EventsManagerWithType<EventType, string>[] = [];\n const rrwebEventManager = await createEventsManager<'replay'>({\n config: this.config,\n sessionId: this.identifiers.sessionId,\n type: 'replay',\n });\n managers.push({ name: 'replay', manager: rrwebEventManager });\n\n if (this.config.interactionConfig?.enabled) {\n const interactionEventManager = await createEventsManager<'interaction'>({\n config: this.config,\n sessionId: this.identifiers.sessionId,\n type: 'interaction',\n minInterval: this.config.interactionConfig.trackEveryNms ?? INTERACTION_MIN_INTERVAL,\n maxInterval: INTERACTION_MAX_INTERVAL,\n payloadBatcher: clickBatcher,\n });\n managers.push({ name: 'interaction', manager: interactionEventManager });\n }\n\n this.eventsManager = new MultiEventManager<'replay' | 'interaction', string>(...managers);\n\n this.loggerProvider.log('Installing @amplitude/session-replay-browser.');\n\n this.teardownEventListeners(false);\n\n this.initialize(true);\n }\n\n setSessionId(sessionId: number, deviceId?: string) {\n return returnWrapper(this.asyncSetSessionId(sessionId, deviceId));\n }\n\n async asyncSetSessionId(sessionId: number, deviceId?: string) {\n const previousSessionId = this.identifiers && this.identifiers.sessionId;\n if (previousSessionId) {\n this.sendEvents(previousSessionId);\n }\n\n const deviceIdForReplayId = deviceId || this.getDeviceId();\n this.identifiers = new SessionIdentifiers({\n sessionId: sessionId,\n deviceId: deviceIdForReplayId,\n });\n\n // If there is no previous session id, SDK is being initialized for the first time,\n // and config was just fetched in initialization, so no need to fetch it a second time\n if (this.joinedConfigGenerator && previousSessionId) {\n this.config = await this.joinedConfigGenerator.generateJoinedConfig(this.identifiers.sessionId);\n }\n this.recordEvents();\n }\n\n getSessionReplayDebugPropertyValue() {\n let apiKeyHash = '';\n if (this.config) {\n apiKeyHash = generateHashCode(this.config.apiKey).toString();\n }\n return JSON.stringify({\n appHash: apiKeyHash,\n });\n }\n\n getSessionReplayProperties() {\n if (!this.config || !this.identifiers) {\n this.loggerProvider.error('Session replay init has not been called, cannot get session recording properties.');\n return {};\n }\n\n const shouldRecord = this.getShouldRecord();\n\n if (shouldRecord) {\n const eventProperties: { [key: string]: string | null } = {\n [DEFAULT_SESSION_REPLAY_PROPERTY]: this.identifiers.sessionReplayId ? this.identifiers.sessionReplayId : null,\n };\n if (this.config.debugMode) {\n eventProperties[SESSION_REPLAY_DEBUG_PROPERTY] = this.getSessionReplayDebugPropertyValue();\n }\n return eventProperties;\n }\n\n return {};\n }\n\n blurListener = () => {\n this.sendEvents();\n };\n\n /**\n * This is an instance member so that if init is called multiple times\n * it doesn't add another listener to the page leave event. This is to\n * prevent duplicate listener actions from firing.\n */\n private pageLeaveListener = (e: PageTransitionEvent | Event) => {\n this.pageLeaveFns.forEach((fn) => {\n fn(e);\n });\n };\n\n sendEvents(sessionId?: number) {\n const sessionIdToSend = sessionId || this.identifiers?.sessionId;\n const deviceId = this.getDeviceId();\n this.eventsManager &&\n sessionIdToSend &&\n deviceId &&\n this.eventsManager.sendCurrentSequenceEvents({ sessionId: sessionIdToSend, deviceId });\n }\n\n initialize(shouldSendStoredEvents = false) {\n if (!this.identifiers?.sessionId) {\n this.loggerProvider.log(`Session is not being recorded due to lack of session id.`);\n return;\n }\n\n const deviceId = this.getDeviceId();\n if (!deviceId) {\n this.loggerProvider.log(`Session is not being recorded due to lack of device id.`);\n return;\n }\n this.eventsManager && shouldSendStoredEvents && this.eventsManager.sendStoredEvents({ deviceId });\n\n this.recordEvents();\n }\n\n shouldOptOut() {\n let identityStoreOptOut: boolean | undefined;\n if (this.config?.instanceName) {\n const identityStore = getAnalyticsConnector(this.config.instanceName).identityStore;\n identityStoreOptOut = identityStore.getIdentity().optOut;\n }\n\n return identityStoreOptOut !== undefined ? identityStoreOptOut : this.config?.optOut;\n }\n\n getShouldRecord() {\n if (!this.identifiers || !this.config || !this.identifiers.sessionId) {\n this.loggerProvider.warn(`Session is not being recorded due to lack of config, please call sessionReplay.init.`);\n return false;\n }\n if (!this.config.captureEnabled) {\n this.loggerProvider.log(\n `Session ${this.identifiers.sessionId} not being captured due to capture being disabled for project or because the remote config could not be fetched.`,\n );\n return false;\n }\n\n if (this.shouldOptOut()) {\n this.loggerProvider.log(`Opting session ${this.identifiers.sessionId} out of recording due to optOut config.`);\n return false;\n }\n\n const isInSample = isSessionInSample(this.identifiers.sessionId, this.config.sampleRate);\n if (!isInSample) {\n this.loggerProvider.log(`Opting session ${this.identifiers.sessionId} out of recording due to sample rate.`);\n }\n return isInSample;\n }\n\n getBlockSelectors(): string | string[] | undefined {\n // For some reason, this defaults to empty array ([]) if undefined in the compiled script.\n // Empty arrays cause errors when being evaluated in Safari.\n // Force the selector to be undefined if it's an empty array.\n const blockSelector = this.config?.privacyConfig?.blockSelector ?? [];\n if (blockSelector.length === 0) {\n return undefined;\n }\n return blockSelector;\n }\n\n getMaskTextSelectors(): string | undefined {\n if (this.config?.privacyConfig?.defaultMaskLevel === 'conservative') {\n return '*';\n }\n\n const maskSelector = this.config?.privacyConfig?.maskSelector;\n if (!maskSelector) {\n return;\n }\n\n return maskSelector as unknown as string;\n }\n\n recordEvents() {\n const shouldRecord = this.getShouldRecord();\n const sessionId = this.identifiers?.sessionId;\n if (!shouldRecord || !sessionId || !this.config) {\n return;\n }\n this.stopRecordingEvents();\n const privacyConfig = this.config.privacyConfig;\n\n this.recordCancelCallback = record({\n emit: (event) => {\n if (this.shouldOptOut()) {\n this.loggerProvider.log(`Opting session ${sessionId} out of recording due to optOut config.`);\n this.stopRecordingEvents();\n this.sendEvents();\n return;\n }\n const eventString = JSON.stringify(event);\n const deviceId = this.getDeviceId();\n this.eventsManager &&\n deviceId &&\n this.eventsManager.addEvent({ event: { type: 'replay', data: eventString }, sessionId, deviceId });\n },\n packFn: pack,\n inlineStylesheet: this.config.shouldInlineStylesheet,\n hooks: {\n mouseInteraction:\n this.eventsManager &&\n clickHook({\n eventsManager: this.eventsManager,\n sessionId,\n deviceIdFn: this.getDeviceId.bind(this),\n }),\n scroll: this.scrollHook,\n },\n maskAllInputs: true,\n maskTextClass: MASK_TEXT_CLASS,\n blockClass: BLOCK_CLASS,\n // rrweb only exposes string type through its types, but arrays are also be supported. #class, ['#class', 'id']\n blockSelector: this.getBlockSelectors() as string | undefined,\n maskInputFn: maskFn('input', privacyConfig),\n maskTextFn: maskFn('text', privacyConfig),\n // rrweb only exposes string type through its types, but arrays are also be supported. since rrweb uses .matches() which supports arrays.\n maskTextSelector: this.getMaskTextSelectors(),\n recordCanvas: false,\n errorHandler: (error) => {\n const typedError = error as Error & { _external_?: boolean };\n\n // styled-components relies on this error being thrown and bubbled up, rrweb is otherwise suppressing it\n if (typedError.message.includes('insertRule') && typedError.message.includes('CSSStyleSheet')) {\n throw typedError;\n }\n\n // rrweb does monkey patching on certain window functions such as CSSStyleSheet.proptype.insertRule,\n // and errors from external clients calling these functions can get suppressed. Styled components depend\n // on these errors being re-thrown.\n if (typedError._external_) {\n throw typedError;\n }\n\n this.loggerProvider.warn('Error while recording: ', typedError.toString());\n // Return true so that we don't clutter user's consoles with internal rrweb errors\n return true;\n },\n });\n }\n\n stopRecordingEvents = () => {\n try {\n this.recordCancelCallback && this.recordCancelCallback();\n this.recordCancelCallback = null;\n } catch (error) {\n const typedError = error as Error;\n this.loggerProvider.warn(`Error occurred while stopping recording: ${typedError.toString()}`);\n }\n };\n\n getDeviceId() {\n let identityStoreDeviceId: string | undefined;\n if (this.config?.instanceName) {\n const identityStore = getAnalyticsConnector(this.config.instanceName).identityStore;\n identityStoreDeviceId = identityStore.getIdentity().deviceId;\n }\n\n return identityStoreDeviceId || this.identifiers?.deviceId;\n }\n\n getSessionId() {\n return this.identifiers?.sessionId;\n }\n\n async flush(useRetry = false) {\n return this.eventsManager?.flush(useRetry);\n }\n\n shutdown() {\n this.teardownEventListeners(true);\n this.stopRecordingEvents();\n this.sendEvents();\n }\n}\n"]}
|
|
@@ -84,7 +84,7 @@ var SessionReplayJoinedConfigGenerator = /** @class */ (function () {
|
|
|
84
84
|
else {
|
|
85
85
|
config.captureEnabled = false;
|
|
86
86
|
}
|
|
87
|
-
if (samplingConfig
|
|
87
|
+
if (Object.prototype.hasOwnProperty.call(samplingConfig, 'sample_rate')) {
|
|
88
88
|
config.sampleRate = samplingConfig.sample_rate;
|
|
89
89
|
}
|
|
90
90
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"joined-config.js","sourceRoot":"","sources":["../../../src/config/joined-config.ts"],"names":[],"mappings":"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","sourcesContent":["import { RemoteConfigFetch, createRemoteConfigFetch } from '@amplitude/analytics-remote-config';\nimport { SessionReplayOptions } from '../typings/session-replay';\nimport { SessionReplayLocalConfig } from './local-config';\nimport {\n SessionReplayLocalConfig as ISessionReplayLocalConfig,\n PrivacyConfig,\n SessionReplayJoinedConfig,\n SessionReplayRemoteConfig,\n} from './types';\n\nexport class SessionReplayJoinedConfigGenerator {\n localConfig: ISessionReplayLocalConfig;\n remoteConfigFetch: RemoteConfigFetch<SessionReplayRemoteConfig> | undefined;\n\n constructor(apiKey: string, options: SessionReplayOptions) {\n this.localConfig = new SessionReplayLocalConfig(apiKey, options);\n }\n\n async initialize() {\n this.remoteConfigFetch = await createRemoteConfigFetch<SessionReplayRemoteConfig>({\n localConfig: this.localConfig,\n configKeys: ['sessionReplay'],\n });\n }\n\n async generateJoinedConfig(sessionId?: number): Promise<SessionReplayJoinedConfig> {\n const config: SessionReplayJoinedConfig = { ...this.localConfig };\n // Special case here as optOut is implemented via getter/setter\n config.optOut = this.localConfig.optOut;\n // We always want captureEnabled to be true, unless there's an override\n // in the remote config.\n config.captureEnabled = true;\n let remoteConfig: SessionReplayRemoteConfig | undefined;\n try {\n if (!this.remoteConfigFetch) {\n config.captureEnabled = false;\n return config;\n }\n\n const samplingConfig = await this.remoteConfigFetch.getRemoteConfig(\n 'sessionReplay',\n 'sr_sampling_config',\n sessionId,\n );\n\n const privacyConfig = await this.remoteConfigFetch.getRemoteConfig(\n 'sessionReplay',\n 'sr_privacy_config',\n sessionId,\n );\n\n // This is intentionally forced to only be set through the remote config.\n config.interactionConfig = await this.remoteConfigFetch.getRemoteConfig(\n 'sessionReplay',\n 'sr_interaction_config',\n sessionId,\n );\n\n if (samplingConfig || privacyConfig) {\n remoteConfig = {};\n if (samplingConfig) {\n remoteConfig.sr_sampling_config = samplingConfig;\n }\n if (privacyConfig) {\n remoteConfig.sr_privacy_config = privacyConfig;\n }\n }\n } catch (err: unknown) {\n const knownError = err as Error;\n this.localConfig.loggerProvider.warn(knownError.message);\n config.captureEnabled = false;\n }\n\n if (!remoteConfig) {\n return config;\n }\n\n const { sr_sampling_config: samplingConfig, sr_privacy_config: remotePrivacyConfig } = remoteConfig;\n if (samplingConfig && Object.keys(samplingConfig).length > 0) {\n if (Object.prototype.hasOwnProperty.call(samplingConfig, 'capture_enabled')) {\n config.captureEnabled = samplingConfig.capture_enabled;\n } else {\n config.captureEnabled = false;\n }\n\n if (samplingConfig.sample_rate) {\n config.sampleRate = samplingConfig.sample_rate;\n }\n } else {\n // If config API response was valid (ie 200), but no config returned, assume that\n // customer has not yet set up config, and use sample rate from SDK options,\n // allowing for immediate replay capture\n config.captureEnabled = true;\n this.localConfig.loggerProvider.debug(\n 'Remote config successfully fetched, but no values set for project, Session Replay capture enabled.',\n );\n }\n\n // Remote config join acts somewhat like a left join between the remote and the local\n // config. That is, remote config has precedence over local values as with sampling.\n // However, non conflicting values will be added to the lists.\n // Here's an example to illustrate:\n //\n // Remote config: {'.selector1': 'MASK', '.selector2': 'UNMASK'}\n // Local config: {'.selector1': 'UNMASK', '.selector3': 'MASK'}\n //\n // Resolved config: {'.selector1': 'MASK', '.selector2': 'UNMASK', '.selector3': 'MASK'}\n // config.privacyConfig = {\n // ...(config.privacyConfig ?? {}),\n // ...remotePrivacyConfig,\n // };\n\n if (remotePrivacyConfig) {\n const localPrivacyConfig: PrivacyConfig = config.privacyConfig ?? {};\n\n const joinedPrivacyConfig: Required<PrivacyConfig> & { blockSelector: string[] } = {\n defaultMaskLevel: remotePrivacyConfig.defaultMaskLevel ?? localPrivacyConfig.defaultMaskLevel ?? 'medium',\n blockSelector: [],\n maskSelector: [],\n unmaskSelector: [],\n };\n\n const privacyConfigSelectorMap = (privacyConfig: PrivacyConfig): Record<string, 'mask' | 'unmask' | 'block'> => {\n const selectorMap: Record<string, 'mask' | 'unmask' | 'block'> = {};\n if (typeof privacyConfig.blockSelector === 'string') {\n privacyConfig.blockSelector = [privacyConfig.blockSelector];\n }\n\n for (const selector of privacyConfig.blockSelector ?? []) {\n selectorMap[selector] = 'block';\n }\n for (const selector of privacyConfig.maskSelector ?? []) {\n selectorMap[selector] = 'mask';\n }\n for (const selector of privacyConfig.unmaskSelector ?? []) {\n selectorMap[selector] = 'unmask';\n }\n return selectorMap;\n };\n\n const selectorMap: Record<string, 'mask' | 'unmask' | 'block'> = {\n ...privacyConfigSelectorMap(localPrivacyConfig),\n ...privacyConfigSelectorMap(remotePrivacyConfig),\n };\n\n for (const [selector, selectorType] of Object.entries(selectorMap)) {\n if (selectorType === 'mask') {\n joinedPrivacyConfig.maskSelector.push(selector);\n } else if (selectorType === 'block') {\n joinedPrivacyConfig.blockSelector.push(selector);\n } else if (selectorType === 'unmask') {\n joinedPrivacyConfig.unmaskSelector.push(selector);\n }\n }\n\n config.privacyConfig = joinedPrivacyConfig;\n }\n\n return config;\n }\n}\n\nexport const createSessionReplayJoinedConfigGenerator = async (apiKey: string, options: SessionReplayOptions) => {\n const joinedConfigGenerator = new SessionReplayJoinedConfigGenerator(apiKey, options);\n await joinedConfigGenerator.initialize();\n return joinedConfigGenerator;\n};\n"]}
|
|
1
|
+
{"version":3,"file":"joined-config.js","sourceRoot":"","sources":["../../../src/config/joined-config.ts"],"names":[],"mappings":"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","sourcesContent":["import { RemoteConfigFetch, createRemoteConfigFetch } from '@amplitude/analytics-remote-config';\nimport { SessionReplayOptions } from '../typings/session-replay';\nimport { SessionReplayLocalConfig } from './local-config';\nimport {\n SessionReplayLocalConfig as ISessionReplayLocalConfig,\n PrivacyConfig,\n SessionReplayJoinedConfig,\n SessionReplayRemoteConfig,\n} from './types';\n\nexport class SessionReplayJoinedConfigGenerator {\n localConfig: ISessionReplayLocalConfig;\n remoteConfigFetch: RemoteConfigFetch<SessionReplayRemoteConfig> | undefined;\n\n constructor(apiKey: string, options: SessionReplayOptions) {\n this.localConfig = new SessionReplayLocalConfig(apiKey, options);\n }\n\n async initialize() {\n this.remoteConfigFetch = await createRemoteConfigFetch<SessionReplayRemoteConfig>({\n localConfig: this.localConfig,\n configKeys: ['sessionReplay'],\n });\n }\n\n async generateJoinedConfig(sessionId?: number): Promise<SessionReplayJoinedConfig> {\n const config: SessionReplayJoinedConfig = { ...this.localConfig };\n // Special case here as optOut is implemented via getter/setter\n config.optOut = this.localConfig.optOut;\n // We always want captureEnabled to be true, unless there's an override\n // in the remote config.\n config.captureEnabled = true;\n let remoteConfig: SessionReplayRemoteConfig | undefined;\n try {\n if (!this.remoteConfigFetch) {\n config.captureEnabled = false;\n return config;\n }\n\n const samplingConfig = await this.remoteConfigFetch.getRemoteConfig(\n 'sessionReplay',\n 'sr_sampling_config',\n sessionId,\n );\n\n const privacyConfig = await this.remoteConfigFetch.getRemoteConfig(\n 'sessionReplay',\n 'sr_privacy_config',\n sessionId,\n );\n\n // This is intentionally forced to only be set through the remote config.\n config.interactionConfig = await this.remoteConfigFetch.getRemoteConfig(\n 'sessionReplay',\n 'sr_interaction_config',\n sessionId,\n );\n\n if (samplingConfig || privacyConfig) {\n remoteConfig = {};\n if (samplingConfig) {\n remoteConfig.sr_sampling_config = samplingConfig;\n }\n if (privacyConfig) {\n remoteConfig.sr_privacy_config = privacyConfig;\n }\n }\n } catch (err: unknown) {\n const knownError = err as Error;\n this.localConfig.loggerProvider.warn(knownError.message);\n config.captureEnabled = false;\n }\n\n if (!remoteConfig) {\n return config;\n }\n\n const { sr_sampling_config: samplingConfig, sr_privacy_config: remotePrivacyConfig } = remoteConfig;\n if (samplingConfig && Object.keys(samplingConfig).length > 0) {\n if (Object.prototype.hasOwnProperty.call(samplingConfig, 'capture_enabled')) {\n config.captureEnabled = samplingConfig.capture_enabled;\n } else {\n config.captureEnabled = false;\n }\n\n if (Object.prototype.hasOwnProperty.call(samplingConfig, 'sample_rate')) {\n config.sampleRate = samplingConfig.sample_rate;\n }\n } else {\n // If config API response was valid (ie 200), but no config returned, assume that\n // customer has not yet set up config, and use sample rate from SDK options,\n // allowing for immediate replay capture\n config.captureEnabled = true;\n this.localConfig.loggerProvider.debug(\n 'Remote config successfully fetched, but no values set for project, Session Replay capture enabled.',\n );\n }\n\n // Remote config join acts somewhat like a left join between the remote and the local\n // config. That is, remote config has precedence over local values as with sampling.\n // However, non conflicting values will be added to the lists.\n // Here's an example to illustrate:\n //\n // Remote config: {'.selector1': 'MASK', '.selector2': 'UNMASK'}\n // Local config: {'.selector1': 'UNMASK', '.selector3': 'MASK'}\n //\n // Resolved config: {'.selector1': 'MASK', '.selector2': 'UNMASK', '.selector3': 'MASK'}\n // config.privacyConfig = {\n // ...(config.privacyConfig ?? {}),\n // ...remotePrivacyConfig,\n // };\n\n if (remotePrivacyConfig) {\n const localPrivacyConfig: PrivacyConfig = config.privacyConfig ?? {};\n\n const joinedPrivacyConfig: Required<PrivacyConfig> & { blockSelector: string[] } = {\n defaultMaskLevel: remotePrivacyConfig.defaultMaskLevel ?? localPrivacyConfig.defaultMaskLevel ?? 'medium',\n blockSelector: [],\n maskSelector: [],\n unmaskSelector: [],\n };\n\n const privacyConfigSelectorMap = (privacyConfig: PrivacyConfig): Record<string, 'mask' | 'unmask' | 'block'> => {\n const selectorMap: Record<string, 'mask' | 'unmask' | 'block'> = {};\n if (typeof privacyConfig.blockSelector === 'string') {\n privacyConfig.blockSelector = [privacyConfig.blockSelector];\n }\n\n for (const selector of privacyConfig.blockSelector ?? []) {\n selectorMap[selector] = 'block';\n }\n for (const selector of privacyConfig.maskSelector ?? []) {\n selectorMap[selector] = 'mask';\n }\n for (const selector of privacyConfig.unmaskSelector ?? []) {\n selectorMap[selector] = 'unmask';\n }\n return selectorMap;\n };\n\n const selectorMap: Record<string, 'mask' | 'unmask' | 'block'> = {\n ...privacyConfigSelectorMap(localPrivacyConfig),\n ...privacyConfigSelectorMap(remotePrivacyConfig),\n };\n\n for (const [selector, selectorType] of Object.entries(selectorMap)) {\n if (selectorType === 'mask') {\n joinedPrivacyConfig.maskSelector.push(selector);\n } else if (selectorType === 'block') {\n joinedPrivacyConfig.blockSelector.push(selector);\n } else if (selectorType === 'unmask') {\n joinedPrivacyConfig.unmaskSelector.push(selector);\n }\n }\n\n config.privacyConfig = joinedPrivacyConfig;\n }\n\n return config;\n }\n}\n\nexport const createSessionReplayJoinedConfigGenerator = async (apiKey: string, options: SessionReplayOptions) => {\n const joinedConfigGenerator = new SessionReplayJoinedConfigGenerator(apiKey, options);\n await joinedConfigGenerator.initialize();\n return joinedConfigGenerator;\n};\n"]}
|
|
@@ -25,17 +25,16 @@ export declare class SessionReplay implements AmplitudeSessionReplay {
|
|
|
25
25
|
[key: string]: string | null;
|
|
26
26
|
};
|
|
27
27
|
blurListener: () => void;
|
|
28
|
-
focusListener: () => void;
|
|
29
28
|
/**
|
|
30
29
|
* This is an instance member so that if init is called multiple times
|
|
31
30
|
* it doesn't add another listener to the page leave event. This is to
|
|
32
31
|
* prevent duplicate listener actions from firing.
|
|
33
32
|
*/
|
|
34
33
|
private pageLeaveListener;
|
|
35
|
-
|
|
34
|
+
sendEvents(sessionId?: number): void;
|
|
36
35
|
initialize(shouldSendStoredEvents?: boolean): void;
|
|
37
36
|
shouldOptOut(): boolean | undefined;
|
|
38
|
-
getShouldRecord(
|
|
37
|
+
getShouldRecord(): boolean;
|
|
39
38
|
getBlockSelectors(): string | string[] | undefined;
|
|
40
39
|
getMaskTextSelectors(): string | undefined;
|
|
41
40
|
recordEvents(): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-replay.d.ts","sourceRoot":"","sources":["../../src/session-replay.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,IAAI,OAAO,EAAY,MAAM,4BAA4B,CAAC;AACzE,OAAO,EAAQ,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAGhD,OAAO,EAAE,yBAAyB,EAAE,kCAAkC,EAAE,MAAM,gBAAgB,CAAC;AAe/F,OAAO,EACL,sBAAsB,EACtB,0BAA0B,IAAI,mCAAmC,EAGjE,kBAAkB,IAAI,mBAAmB,EACzC,oBAAoB,EACrB,MAAM,0BAA0B,CAAC;AAElC,KAAK,WAAW,GAAG,CAAC,CAAC,EAAE,mBAAmB,GAAG,KAAK,KAAK,IAAI,CAAC;AAE5D,qBAAa,aAAc,YAAW,sBAAsB;IAC1D,IAAI,SAAuC;IAC3C,MAAM,EAAE,yBAAyB,GAAG,SAAS,CAAC;IAC9C,qBAAqB,EAAE,kCAAkC,GAAG,SAAS,CAAC;IACtE,WAAW,EAAE,mBAAmB,GAAG,SAAS,CAAC;IAC7C,aAAa,CAAC,EAAE,mCAAmC,CAAC,QAAQ,GAAG,aAAa,EAAE,MAAM,CAAC,CAAC;IACtF,cAAc,EAAE,OAAO,CAAC;IACxB,oBAAoB,EAAE,UAAU,CAAC,OAAO,MAAM,CAAC,GAAG,IAAI,CAAQ;IAG9D,YAAY,EAAE,WAAW,EAAE,CAAM;IACjC,OAAO,CAAC,UAAU,CAAC,CAAiB;;IAMpC,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,oBAAoB;IAIlD,sBAAsB;IA+BtB,OAAO,CAAC,sBAAsB,
|
|
1
|
+
{"version":3,"file":"session-replay.d.ts","sourceRoot":"","sources":["../../src/session-replay.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,IAAI,OAAO,EAAY,MAAM,4BAA4B,CAAC;AACzE,OAAO,EAAQ,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAGhD,OAAO,EAAE,yBAAyB,EAAE,kCAAkC,EAAE,MAAM,gBAAgB,CAAC;AAe/F,OAAO,EACL,sBAAsB,EACtB,0BAA0B,IAAI,mCAAmC,EAGjE,kBAAkB,IAAI,mBAAmB,EACzC,oBAAoB,EACrB,MAAM,0BAA0B,CAAC;AAElC,KAAK,WAAW,GAAG,CAAC,CAAC,EAAE,mBAAmB,GAAG,KAAK,KAAK,IAAI,CAAC;AAE5D,qBAAa,aAAc,YAAW,sBAAsB;IAC1D,IAAI,SAAuC;IAC3C,MAAM,EAAE,yBAAyB,GAAG,SAAS,CAAC;IAC9C,qBAAqB,EAAE,kCAAkC,GAAG,SAAS,CAAC;IACtE,WAAW,EAAE,mBAAmB,GAAG,SAAS,CAAC;IAC7C,aAAa,CAAC,EAAE,mCAAmC,CAAC,QAAQ,GAAG,aAAa,EAAE,MAAM,CAAC,CAAC;IACtF,cAAc,EAAE,OAAO,CAAC;IACxB,oBAAoB,EAAE,UAAU,CAAC,OAAO,MAAM,CAAC,GAAG,IAAI,CAAQ;IAG9D,YAAY,EAAE,WAAW,EAAE,CAAM;IACjC,OAAO,CAAC,UAAU,CAAC,CAAiB;;IAMpC,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,oBAAoB;IAIlD,sBAAsB;IA+BtB,OAAO,CAAC,sBAAsB,CAiB5B;cAEc,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,oBAAoB;IA0DnE,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM;IAI3C,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM;IAoB5D,kCAAkC;IAUlC,0BAA0B;;;IAqB1B,YAAY,aAEV;IAEF;;;;OAIG;IACH,OAAO,CAAC,iBAAiB,CAIvB;IAEF,UAAU,CAAC,SAAS,CAAC,EAAE,MAAM;IAS7B,UAAU,CAAC,sBAAsB,UAAQ;IAgBzC,YAAY;IAUZ,eAAe;IAwBf,iBAAiB,IAAI,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS;IAWlD,oBAAoB,IAAI,MAAM,GAAG,SAAS;IAa1C,YAAY;IAmEZ,mBAAmB,aAQjB;IAEF,WAAW;IAUX,YAAY;IAIN,KAAK,CAAC,QAAQ,UAAQ;IAI5B,QAAQ;CAKT"}
|
|
@@ -21,9 +21,7 @@ var SessionReplay = /** @class */ (function () {
|
|
|
21
21
|
var globalScope = getGlobalScope();
|
|
22
22
|
if (globalScope) {
|
|
23
23
|
globalScope.removeEventListener('blur', _this.blurListener);
|
|
24
|
-
globalScope.removeEventListener('focus', _this.focusListener);
|
|
25
24
|
!teardown && globalScope.addEventListener('blur', _this.blurListener);
|
|
26
|
-
!teardown && globalScope.addEventListener('focus', _this.focusListener);
|
|
27
25
|
// prefer pagehide to unload events, this is the standard going forward. it is not
|
|
28
26
|
// 100% reliable, but is bfcache-compatible.
|
|
29
27
|
if (globalScope.self && 'onpagehide' in globalScope.self) {
|
|
@@ -39,10 +37,7 @@ var SessionReplay = /** @class */ (function () {
|
|
|
39
37
|
}
|
|
40
38
|
};
|
|
41
39
|
this.blurListener = function () {
|
|
42
|
-
_this.
|
|
43
|
-
};
|
|
44
|
-
this.focusListener = function () {
|
|
45
|
-
_this.initialize();
|
|
40
|
+
_this.sendEvents();
|
|
46
41
|
};
|
|
47
42
|
/**
|
|
48
43
|
* This is an instance member so that if init is called multiple times
|
|
@@ -104,7 +99,7 @@ var SessionReplay = /** @class */ (function () {
|
|
|
104
99
|
SessionReplay.prototype._init = function (apiKey, options) {
|
|
105
100
|
var _a, _b, _c;
|
|
106
101
|
return __awaiter(this, void 0, void 0, function () {
|
|
107
|
-
var _d, _e, scrollWatcher, managers, rrwebEventManager, interactionEventManager
|
|
102
|
+
var _d, _e, scrollWatcher, managers, rrwebEventManager, interactionEventManager;
|
|
108
103
|
return __generator(this, function (_f) {
|
|
109
104
|
switch (_f.label) {
|
|
110
105
|
case 0:
|
|
@@ -156,10 +151,7 @@ var SessionReplay = /** @class */ (function () {
|
|
|
156
151
|
this.eventsManager = new (MultiEventManager.bind.apply(MultiEventManager, __spreadArray([void 0], __read(managers), false)))();
|
|
157
152
|
this.loggerProvider.log('Installing @amplitude/session-replay-browser.');
|
|
158
153
|
this.teardownEventListeners(false);
|
|
159
|
-
|
|
160
|
-
if (globalScope && globalScope.document && globalScope.document.hasFocus()) {
|
|
161
|
-
this.initialize(true);
|
|
162
|
-
}
|
|
154
|
+
this.initialize(true);
|
|
163
155
|
return [2 /*return*/];
|
|
164
156
|
}
|
|
165
157
|
});
|
|
@@ -176,7 +168,7 @@ var SessionReplay = /** @class */ (function () {
|
|
|
176
168
|
case 0:
|
|
177
169
|
previousSessionId = this.identifiers && this.identifiers.sessionId;
|
|
178
170
|
if (previousSessionId) {
|
|
179
|
-
this.
|
|
171
|
+
this.sendEvents(previousSessionId);
|
|
180
172
|
}
|
|
181
173
|
deviceIdForReplayId = deviceId || this.getDeviceId();
|
|
182
174
|
this.identifiers = new SessionIdentifiers({
|
|
@@ -211,10 +203,7 @@ var SessionReplay = /** @class */ (function () {
|
|
|
211
203
|
this.loggerProvider.error('Session replay init has not been called, cannot get session recording properties.');
|
|
212
204
|
return {};
|
|
213
205
|
}
|
|
214
|
-
|
|
215
|
-
// this is a common mishap when someone is developing locally and not seeing events getting tagged.
|
|
216
|
-
var ignoreFocus = !!this.config.debugMode;
|
|
217
|
-
var shouldRecord = this.getShouldRecord(ignoreFocus);
|
|
206
|
+
var shouldRecord = this.getShouldRecord();
|
|
218
207
|
if (shouldRecord) {
|
|
219
208
|
var eventProperties = (_a = {},
|
|
220
209
|
_a[DEFAULT_SESSION_REPLAY_PROPERTY] = this.identifiers.sessionReplayId ? this.identifiers.sessionReplayId : null,
|
|
@@ -226,9 +215,8 @@ var SessionReplay = /** @class */ (function () {
|
|
|
226
215
|
}
|
|
227
216
|
return {};
|
|
228
217
|
};
|
|
229
|
-
SessionReplay.prototype.
|
|
218
|
+
SessionReplay.prototype.sendEvents = function (sessionId) {
|
|
230
219
|
var _a;
|
|
231
|
-
this.stopRecordingEvents();
|
|
232
220
|
var sessionIdToSend = sessionId || ((_a = this.identifiers) === null || _a === void 0 ? void 0 : _a.sessionId);
|
|
233
221
|
var deviceId = this.getDeviceId();
|
|
234
222
|
this.eventsManager &&
|
|
@@ -260,8 +248,7 @@ var SessionReplay = /** @class */ (function () {
|
|
|
260
248
|
}
|
|
261
249
|
return identityStoreOptOut !== undefined ? identityStoreOptOut : (_b = this.config) === null || _b === void 0 ? void 0 : _b.optOut;
|
|
262
250
|
};
|
|
263
|
-
SessionReplay.prototype.getShouldRecord = function (
|
|
264
|
-
if (ignoreFocus === void 0) { ignoreFocus = false; }
|
|
251
|
+
SessionReplay.prototype.getShouldRecord = function () {
|
|
265
252
|
if (!this.identifiers || !this.config || !this.identifiers.sessionId) {
|
|
266
253
|
this.loggerProvider.warn("Session is not being recorded due to lack of config, please call sessionReplay.init.");
|
|
267
254
|
return false;
|
|
@@ -270,11 +257,6 @@ var SessionReplay = /** @class */ (function () {
|
|
|
270
257
|
this.loggerProvider.log("Session ".concat(this.identifiers.sessionId, " not being captured due to capture being disabled for project or because the remote config could not be fetched."));
|
|
271
258
|
return false;
|
|
272
259
|
}
|
|
273
|
-
var globalScope = getGlobalScope();
|
|
274
|
-
if (!ignoreFocus && globalScope && globalScope.document && !globalScope.document.hasFocus()) {
|
|
275
|
-
this.loggerProvider.log("Session ".concat(this.identifiers.sessionId, " temporarily not recording due to lack of browser focus."));
|
|
276
|
-
return false;
|
|
277
|
-
}
|
|
278
260
|
if (this.shouldOptOut()) {
|
|
279
261
|
this.loggerProvider.log("Opting session ".concat(this.identifiers.sessionId, " out of recording due to optOut config."));
|
|
280
262
|
return false;
|
|
@@ -319,9 +301,10 @@ var SessionReplay = /** @class */ (function () {
|
|
|
319
301
|
var privacyConfig = this.config.privacyConfig;
|
|
320
302
|
this.recordCancelCallback = record({
|
|
321
303
|
emit: function (event) {
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
_this.
|
|
304
|
+
if (_this.shouldOptOut()) {
|
|
305
|
+
_this.loggerProvider.log("Opting session ".concat(sessionId, " out of recording due to optOut config."));
|
|
306
|
+
_this.stopRecordingEvents();
|
|
307
|
+
_this.sendEvents();
|
|
325
308
|
return;
|
|
326
309
|
}
|
|
327
310
|
var eventString = JSON.stringify(event);
|
|
@@ -393,7 +376,8 @@ var SessionReplay = /** @class */ (function () {
|
|
|
393
376
|
};
|
|
394
377
|
SessionReplay.prototype.shutdown = function () {
|
|
395
378
|
this.teardownEventListeners(true);
|
|
396
|
-
this.
|
|
379
|
+
this.stopRecordingEvents();
|
|
380
|
+
this.sendEvents();
|
|
397
381
|
};
|
|
398
382
|
return SessionReplay;
|
|
399
383
|
}());
|