@amplitude/session-replay-browser 1.20.1 → 1.21.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 +10 -3
- package/lib/cjs/beacon-transport.js +2 -2
- package/lib/cjs/beacon-transport.js.map +1 -1
- package/lib/cjs/config/joined-config.d.ts +2 -2
- package/lib/cjs/config/joined-config.d.ts.map +1 -1
- package/lib/cjs/config/joined-config.js.map +1 -1
- package/lib/cjs/config/local-config.d.ts +1 -3
- package/lib/cjs/config/local-config.d.ts.map +1 -1
- package/lib/cjs/config/local-config.js +2 -4
- package/lib/cjs/config/local-config.js.map +1 -1
- package/lib/cjs/config/types.d.ts +69 -3
- package/lib/cjs/config/types.d.ts.map +1 -1
- package/lib/cjs/config/types.js.map +1 -1
- package/lib/cjs/constants.d.ts +1 -1
- package/lib/cjs/constants.d.ts.map +1 -1
- package/lib/cjs/constants.js +1 -2
- package/lib/cjs/constants.js.map +1 -1
- package/lib/cjs/events/base-events-store.d.ts +3 -3
- package/lib/cjs/events/base-events-store.d.ts.map +1 -1
- package/lib/cjs/events/base-events-store.js.map +1 -1
- package/lib/cjs/events/event-compressor.js +2 -2
- package/lib/cjs/events/event-compressor.js.map +1 -1
- package/lib/cjs/events/events-idb-store.d.ts.map +1 -1
- package/lib/cjs/events/events-idb-store.js +2 -3
- package/lib/cjs/events/events-idb-store.js.map +1 -1
- package/lib/cjs/helpers.d.ts +10 -8
- package/lib/cjs/helpers.d.ts.map +1 -1
- package/lib/cjs/helpers.js +5 -6
- package/lib/cjs/helpers.js.map +1 -1
- package/lib/cjs/hooks/click.d.ts +2 -2
- package/lib/cjs/hooks/click.d.ts.map +1 -1
- package/lib/cjs/hooks/click.js +2 -2
- package/lib/cjs/hooks/click.js.map +1 -1
- package/lib/cjs/hooks/scroll.js +2 -2
- package/lib/cjs/hooks/scroll.js.map +1 -1
- package/lib/cjs/index.d.ts +1 -1
- package/lib/cjs/index.d.ts.map +1 -1
- package/lib/cjs/logger.d.ts +1 -1
- package/lib/cjs/logger.d.ts.map +1 -1
- package/lib/cjs/logger.js.map +1 -1
- package/lib/cjs/observers.js +2 -2
- package/lib/cjs/observers.js.map +1 -1
- package/lib/cjs/session-replay-factory.d.ts +1 -1
- package/lib/cjs/session-replay-factory.d.ts.map +1 -1
- package/lib/cjs/session-replay-factory.js.map +1 -1
- package/lib/cjs/session-replay.d.ts +3 -3
- package/lib/cjs/session-replay.d.ts.map +1 -1
- package/lib/cjs/session-replay.js +3 -4
- package/lib/cjs/session-replay.js.map +1 -1
- package/lib/cjs/track-destination.d.ts +1 -1
- package/lib/cjs/track-destination.d.ts.map +1 -1
- package/lib/cjs/track-destination.js +2 -3
- package/lib/cjs/track-destination.js.map +1 -1
- package/lib/cjs/typings/session-replay.d.ts +7 -1
- package/lib/cjs/typings/session-replay.d.ts.map +1 -1
- package/lib/cjs/typings/session-replay.js.map +1 -1
- package/lib/cjs/version.d.ts +1 -1
- package/lib/cjs/version.js +1 -1
- package/lib/cjs/version.js.map +1 -1
- package/lib/esm/beacon-transport.js +1 -1
- package/lib/esm/beacon-transport.js.map +1 -1
- package/lib/esm/config/joined-config.d.ts +2 -2
- package/lib/esm/config/joined-config.d.ts.map +1 -1
- package/lib/esm/config/joined-config.js.map +1 -1
- package/lib/esm/config/local-config.d.ts +1 -3
- package/lib/esm/config/local-config.d.ts.map +1 -1
- package/lib/esm/config/local-config.js +1 -3
- package/lib/esm/config/local-config.js.map +1 -1
- package/lib/esm/config/types.d.ts +69 -3
- package/lib/esm/config/types.d.ts.map +1 -1
- package/lib/esm/config/types.js.map +1 -1
- package/lib/esm/constants.d.ts +1 -1
- package/lib/esm/constants.d.ts.map +1 -1
- package/lib/esm/constants.js +1 -2
- package/lib/esm/constants.js.map +1 -1
- package/lib/esm/events/base-events-store.d.ts +3 -3
- package/lib/esm/events/base-events-store.d.ts.map +1 -1
- package/lib/esm/events/base-events-store.js.map +1 -1
- package/lib/esm/events/event-compressor.js +1 -1
- package/lib/esm/events/event-compressor.js.map +1 -1
- package/lib/esm/events/events-idb-store.d.ts.map +1 -1
- package/lib/esm/events/events-idb-store.js +1 -2
- package/lib/esm/events/events-idb-store.js.map +1 -1
- package/lib/esm/helpers.d.ts +10 -8
- package/lib/esm/helpers.d.ts.map +1 -1
- package/lib/esm/helpers.js +1 -2
- package/lib/esm/helpers.js.map +1 -1
- package/lib/esm/hooks/click.d.ts +2 -2
- package/lib/esm/hooks/click.d.ts.map +1 -1
- package/lib/esm/hooks/click.js +1 -1
- package/lib/esm/hooks/click.js.map +1 -1
- package/lib/esm/hooks/scroll.js +1 -1
- package/lib/esm/hooks/scroll.js.map +1 -1
- package/lib/esm/index.d.ts +1 -1
- package/lib/esm/index.d.ts.map +1 -1
- package/lib/esm/logger.d.ts +1 -1
- package/lib/esm/logger.d.ts.map +1 -1
- package/lib/esm/logger.js.map +1 -1
- package/lib/esm/observers.js +1 -1
- package/lib/esm/observers.js.map +1 -1
- package/lib/esm/session-replay-factory.d.ts +1 -1
- package/lib/esm/session-replay-factory.d.ts.map +1 -1
- package/lib/esm/session-replay-factory.js.map +1 -1
- package/lib/esm/session-replay.d.ts +3 -3
- package/lib/esm/session-replay.d.ts.map +1 -1
- package/lib/esm/session-replay.js +1 -2
- package/lib/esm/session-replay.js.map +1 -1
- package/lib/esm/track-destination.d.ts +1 -1
- package/lib/esm/track-destination.d.ts.map +1 -1
- package/lib/esm/track-destination.js +1 -2
- package/lib/esm/track-destination.js.map +1 -1
- package/lib/esm/typings/session-replay.d.ts +7 -1
- package/lib/esm/typings/session-replay.d.ts.map +1 -1
- package/lib/esm/typings/session-replay.js.map +1 -1
- package/lib/esm/version.d.ts +1 -1
- package/lib/esm/version.js +1 -1
- package/lib/esm/version.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.js.map +1 -1
- package/lib/scripts/amplitude-min.umd.js +1 -1
- package/lib/scripts/amplitude-min.umd.js.gz +0 -0
- package/lib/scripts/config/joined-config.d.ts +2 -2
- package/lib/scripts/config/joined-config.d.ts.map +1 -1
- package/lib/scripts/config/local-config.d.ts +1 -3
- package/lib/scripts/config/local-config.d.ts.map +1 -1
- package/lib/scripts/config/types.d.ts +69 -3
- package/lib/scripts/config/types.d.ts.map +1 -1
- package/lib/scripts/constants.d.ts +1 -1
- package/lib/scripts/constants.d.ts.map +1 -1
- package/lib/scripts/events/base-events-store.d.ts +3 -3
- package/lib/scripts/events/base-events-store.d.ts.map +1 -1
- package/lib/scripts/events/events-idb-store.d.ts.map +1 -1
- package/lib/scripts/helpers.d.ts +10 -8
- package/lib/scripts/helpers.d.ts.map +1 -1
- package/lib/scripts/hooks/click.d.ts +2 -2
- package/lib/scripts/hooks/click.d.ts.map +1 -1
- package/lib/scripts/index.d.ts +1 -1
- package/lib/scripts/index.d.ts.map +1 -1
- package/lib/scripts/logger.d.ts +1 -1
- package/lib/scripts/logger.d.ts.map +1 -1
- package/lib/scripts/session-replay-factory.d.ts +1 -1
- package/lib/scripts/session-replay-factory.d.ts.map +1 -1
- package/lib/scripts/session-replay.d.ts +3 -3
- package/lib/scripts/session-replay.d.ts.map +1 -1
- package/lib/scripts/track-destination.d.ts +1 -1
- package/lib/scripts/track-destination.d.ts.map +1 -1
- package/lib/scripts/typings/session-replay.d.ts +7 -1
- package/lib/scripts/typings/session-replay.d.ts.map +1 -1
- package/lib/scripts/version.d.ts +1 -1
- package/package.json +3 -5
package/README.md
CHANGED
|
@@ -81,12 +81,19 @@ sessionReplay.shutdown()
|
|
|
81
81
|
|`sessionId`|`number`|Yes|`undefined`|Sets an identifier for the users current session. The value must be in milliseconds since epoch (Unix Timestamp).|
|
|
82
82
|
|`sampleRate`|`number`|No|`0`|Use this option to control how many sessions will be selected for replay collection. A selected session will be collected for replay, while sessions that are not selected will not. <br></br>The number should be a decimal between 0 and 1, ie `0.01`, representing the fraction of sessions you would like to have randomly selected for replay collection. Over a large number of sessions, `0.01` would select `1%` of those sessions.|
|
|
83
83
|
|`optOut`|`boolean`|No|`false`|Sets permission to collect replays for sessions. Setting a value of true prevents Amplitude from collecting session replays.|
|
|
84
|
-
|`flushMaxRetries`|`number`|No|`
|
|
84
|
+
|`flushMaxRetries`|`number`|No|`2`|Sets the maximum number of retries for failed upload attempts. This is only applicable to retryable errors.|
|
|
85
85
|
|`logLevel`|`number`|No|`LogLevel.Warn`|`LogLevel.None` or `LogLevel.Error` or `LogLevel.Warn` or `LogLevel.Verbose` or `LogLevel.Debug`. Sets the log level.|
|
|
86
86
|
|`loggerProvider`|`Logger`|No|`Logger`|Sets a custom loggerProvider class from the Logger to emit log messages to desired destination.|
|
|
87
87
|
|`serverZone`|`string`|No|`US`|EU or US. Sets the Amplitude server zone. Set this to EU for Amplitude projects created in EU data center.|
|
|
88
|
-
|`privacyConfig`|`object`|No|`undefined`|
|
|
89
|
-
|`debugMode`|`boolean`|No|`false`|
|
|
88
|
+
|`privacyConfig`|`object`|No|`undefined`|Supports advanced masking configs with CSS selectors.|
|
|
89
|
+
|`debugMode`|`boolean`|No|`false`|Adds additional debug event property to help debug instrumentation issues (such as mismatching apps). Only recommended for debugging initial setup, and not recommended for production.|
|
|
90
|
+
|`configServerUrl`|`string`|No|`undefined`|Specifies the endpoint URL to fetch remote configuration. If provided, it overrides the default server zone configuration.|
|
|
91
|
+
|`trackServerUrl`|`string`|No|`undefined`|Specifies the endpoint URL for sending session replay data. If provided, it overrides the default server zone configuration.|
|
|
92
|
+
|`shouldInlineStylesheet`|`boolean`|No|`true`|If stylesheets are inlined, the contents of the stylesheet will be stored. During replay, the stored stylesheet will be used instead of attempting to fetch it remotely. This prevents replays from appearing broken due to missing stylesheets. Note: Inlining stylesheets may not work in all cases. If this is `undefined` stylesheets will be inlined.|
|
|
93
|
+
|`storeType`|`string`|No|`idb`|Specifies how replay events should be stored. `idb` uses IndexedDB to persist replay events when all events cannot be sent during capture. `memory` stores replay events only in memory, meaning events are lost when the page is closed. If IndexedDB is unavailable, the system falls back to `memory`.|
|
|
94
|
+
|`performanceConfig.enabled`|`boolean`|No|`false`|If enabled, event compression will be deferred to occur during the browser's idle periods.|
|
|
95
|
+
|`performanceConfig.timeout`|`number`|No|`undefined`|Optional timeout in milliseconds for the `requestIdleCallback` API. If specified, this value will be used to set a maximum time for the browser to wait before executing the deferred compression task, even if the browser is not idle.|
|
|
96
|
+
|`experimental.useWebWorker`|`boolean`|No|`false`|If the SDK should compress the replay events using a webworker.|
|
|
90
97
|
|
|
91
98
|
## Privacy
|
|
92
99
|
By default, the session replay will mask all inputs, meaning the text in inputs will appear in a session replay as asterisks: `***`. You may require more specific masking controls based on your use case, so we offer the following controls:
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.BeaconTransport = void 0;
|
|
4
|
-
var
|
|
4
|
+
var analytics_core_1 = require("@amplitude/analytics-core");
|
|
5
5
|
var helpers_1 = require("./helpers");
|
|
6
6
|
/**
|
|
7
7
|
* For very small payloads it's preferable to use the [Beacon API](https://developer.mozilla.org/en-US/docs/Web/API/Beacon_API).
|
|
@@ -21,7 +21,7 @@ var helpers_1 = require("./helpers");
|
|
|
21
21
|
*/
|
|
22
22
|
var BeaconTransport = /** @class */ (function () {
|
|
23
23
|
function BeaconTransport(context, config) {
|
|
24
|
-
var globalScope = (0,
|
|
24
|
+
var globalScope = (0, analytics_core_1.getGlobalScope)();
|
|
25
25
|
if (globalScope && globalScope.navigator && typeof globalScope.navigator.sendBeacon === 'function') {
|
|
26
26
|
this.sendBeacon = function (pageUrl, payload) {
|
|
27
27
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"beacon-transport.js","sourceRoot":"","sources":["../../src/beacon-transport.ts"],"names":[],"mappings":";;;AAAA,
|
|
1
|
+
{"version":3,"file":"beacon-transport.js","sourceRoot":"","sources":["../../src/beacon-transport.ts"],"names":[],"mappings":";;;AAAA,4DAA2D;AAG3D,qCAAyC;AAIzC;;;;;;;;;;;;;;;GAeG;AACH;IAOE,yBAAY,OAAkE,EAAE,MAAiC;QAC/G,IAAM,WAAW,GAAG,IAAA,+BAAc,GAAE,CAAC;QACrC,IAAI,WAAW,IAAI,WAAW,CAAC,SAAS,IAAI,OAAO,WAAW,CAAC,SAAS,CAAC,UAAU,KAAK,UAAU,EAAE;YAClG,IAAI,CAAC,UAAU,GAAG,UAAC,OAAO,EAAE,OAAO;gBACjC,IAAI;oBACF,IAAI,WAAW,CAAC,SAAS,CAAC,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,EAAE;wBACtE,OAAO,IAAI,CAAC;qBACb;iBACF;gBAAC,OAAO,CAAC,EAAE;oBACV,4EAA4E;iBAC7E;gBACD,OAAO,KAAK,CAAC;YACf,CAAC,CAAC;SACH;aAAM;YACL,IAAI,CAAC,UAAU,GAAG,cAAM,OAAA,KAAK,EAAL,CAAK,CAAC;SAC/B;QAED,IAAI,CAAC,OAAO,GAAG,UAAC,OAAO,EAAE,OAAO;YAC9B,IAAM,GAAG,GAAG,IAAI,cAAc,EAAE,CAAC;YACjC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;YAChC,GAAG,CAAC,gBAAgB,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;YACtC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;YAClC,OAAO,IAAI,CAAC;QACd,CAAC,CAAC;QAEF,IAAI,CAAC,WAAW,GAAG,IAAA,sBAAY,EAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,cAAc,CAAC,CAAC;QAC1E,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;QAC5B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAED,8BAAI,GAAJ,UAAK,QAAgB,EAAE,OAAU;QACzB,IAAA,KAAsB,IAAI,CAAC,OAAO,EAAhC,SAAS,eAAA,EAAE,IAAI,UAAiB,CAAC;QACzC,IAAM,SAAS,GAAG,IAAI,eAAe,CAAC;YACpC,SAAS,EAAE,QAAQ;YACnB,UAAU,EAAE,MAAM,CAAC,SAAS,CAAC;YAC7B,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC;YAClB,OAAO,EAAE,IAAI,CAAC,MAAM;SACrB,CAAC,CAAC;QAEH,IAAM,OAAO,GAAG,UAAG,IAAI,CAAC,WAAW,cAAI,SAAS,CAAC,QAAQ,EAAE,CAAE,CAAC;QAE9D,kGAAkG;QAClG,+DAA+D;QAC/D,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IACtE,CAAC;IACH,sBAAC;AAAD,CAAC,AApDD,IAoDC;AApDY,0CAAe","sourcesContent":["import { getGlobalScope } from '@amplitude/analytics-core';\nimport { SessionReplayJoinedConfig } from './config/types';\nimport { SessionReplayDestinationSessionMetadata } from './typings/session-replay';\nimport { getServerUrl } from './helpers';\n\ntype BeaconSendFn<T> = (pageUrl: string, payload: T) => boolean;\n\n/**\n * For very small payloads it's preferable to use the [Beacon API](https://developer.mozilla.org/en-US/docs/Web/API/Beacon_API).\n * While it doesn't provide 100% guarantees on sends, it greatly helps with overall reliability and page load performance. As\n * the Beacon API has a potential to fail due to size constraints we want to fall back to XHR if need be. This is mostly to\n * be used with 'pagehide' or 'beforeunload' events.\n *\n * Note there are only 3 CORS safelisted Content-Types you can send:\n *\n * - application/x-www-form-urlencoded\n * - multipart/form-data\n * - text/plain\n *\n * If we do not send one of these, some browsers like Chrome may not send this at all. Also we incur the overhead of a preflight\n * request. In our case we will add no additional content-type header. If you are trying to ping a server that requires this\n * header, you may want to use the regular fetch API or a different mechanism.\n */\nexport class BeaconTransport<T> {\n private sendBeacon: BeaconSendFn<T>;\n private sendXhr: BeaconSendFn<T>;\n private readonly basePageUrl: string;\n private readonly context: Omit<SessionReplayDestinationSessionMetadata, 'deviceId'>;\n private readonly apiKey: string;\n\n constructor(context: Omit<SessionReplayDestinationSessionMetadata, 'deviceId'>, config: SessionReplayJoinedConfig) {\n const globalScope = getGlobalScope();\n if (globalScope && globalScope.navigator && typeof globalScope.navigator.sendBeacon === 'function') {\n this.sendBeacon = (pageUrl, payload) => {\n try {\n if (globalScope.navigator.sendBeacon(pageUrl, JSON.stringify(payload))) {\n return true;\n }\n } catch (e) {\n // not logging error, since it would be hard to view and just adds overhead.\n }\n return false;\n };\n } else {\n this.sendBeacon = () => false;\n }\n\n this.sendXhr = (pageUrl, payload) => {\n const xhr = new XMLHttpRequest();\n xhr.open('POST', pageUrl, true);\n xhr.setRequestHeader('Accept', '*/*');\n xhr.send(JSON.stringify(payload));\n return true;\n };\n\n this.basePageUrl = getServerUrl(config.serverZone, config.trackServerUrl);\n this.apiKey = config.apiKey;\n this.context = context;\n }\n\n send(deviceId: string, payload: T) {\n const { sessionId, type } = this.context;\n const urlParams = new URLSearchParams({\n device_id: deviceId,\n session_id: String(sessionId),\n type: String(type),\n api_key: this.apiKey,\n });\n\n const pageUrl = `${this.basePageUrl}?${urlParams.toString()}`;\n\n // ideally send using the beacon API, but there is a chance it may fail, possibly due to a payload\n // size limit. in this case, try best effort to send using xhr.\n this.sendBeacon(pageUrl, payload) || this.sendXhr(pageUrl, payload);\n }\n}\n"]}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { RemoteConfigFetch } from '@amplitude/analytics-remote-config';
|
|
2
|
-
import {
|
|
2
|
+
import { ILogger } from '@amplitude/analytics-core';
|
|
3
3
|
import { SessionReplayOptions } from '../typings/session-replay';
|
|
4
4
|
import { SessionReplayLocalConfig as ISessionReplayLocalConfig, PrivacyConfig, SessionReplayJoinedConfig, SessionReplayRemoteConfig } from './types';
|
|
5
|
-
export declare const removeInvalidSelectorsFromPrivacyConfig: (privacyConfig: PrivacyConfig, loggerProvider:
|
|
5
|
+
export declare const removeInvalidSelectorsFromPrivacyConfig: (privacyConfig: PrivacyConfig, loggerProvider: ILogger) => PrivacyConfig;
|
|
6
6
|
export declare class SessionReplayJoinedConfigGenerator {
|
|
7
7
|
private readonly localConfig;
|
|
8
8
|
private readonly remoteConfigFetch;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"joined-config.d.ts","sourceRoot":"","sources":["../../../src/config/joined-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAA2B,MAAM,oCAAoC,CAAC;AAChG,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"joined-config.d.ts","sourceRoot":"","sources":["../../../src/config/joined-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAA2B,MAAM,oCAAoC,CAAC;AAChG,OAAO,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAC;AAEpD,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAEjE,OAAO,EACL,wBAAwB,IAAI,yBAAyB,EACrD,aAAa,EACb,yBAAyB,EACzB,yBAAyB,EAC1B,MAAM,SAAS,CAAC;AAEjB,eAAO,MAAM,uCAAuC,kBAAmB,aAAa,kBAAkB,OAAO,kBA0B5G,CAAC;AACF,qBAAa,kCAAkC;IAC7C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA4B;IACxD,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAA+C;gBAErE,iBAAiB,EAAE,iBAAiB,CAAC,yBAAyB,CAAC,EAAE,WAAW,EAAE,yBAAyB;IAK7G,oBAAoB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,yBAAyB,CAAC;CAgJ5F;AAED,eAAO,MAAM,wCAAwC,WAAkB,MAAM,WAAW,oBAAoB,gDAQ3G,CAAC"}
|
|
@@ -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 { Logger } from '@amplitude/analytics-types';\nimport { getDebugConfig } from '../helpers';\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 const removeInvalidSelectorsFromPrivacyConfig = (privacyConfig: PrivacyConfig, loggerProvider: Logger) => {\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 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 privacyConfig.blockSelector = dropInvalidSelectors(privacyConfig.blockSelector);\n privacyConfig.maskSelector = dropInvalidSelectors(privacyConfig.maskSelector);\n privacyConfig.unmaskSelector = dropInvalidSelectors(privacyConfig.unmaskSelector);\n return privacyConfig;\n};\nexport class SessionReplayJoinedConfigGenerator {\n private readonly localConfig: ISessionReplayLocalConfig;\n private readonly remoteConfigFetch: RemoteConfigFetch<SessionReplayRemoteConfig>;\n\n constructor(remoteConfigFetch: RemoteConfigFetch<SessionReplayRemoteConfig>, localConfig: ISessionReplayLocalConfig) {\n this.localConfig = localConfig;\n this.remoteConfigFetch = remoteConfigFetch;\n }\n\n async generateJoinedConfig(sessionId?: string | 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 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 // This is intentionally forced to only be set through the remote config.\n config.loggingConfig = await this.remoteConfigFetch.getRemoteConfig(\n 'sessionReplay',\n 'sr_logging_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 = removeInvalidSelectorsFromPrivacyConfig(\n joinedPrivacyConfig,\n this.localConfig.loggerProvider,\n );\n }\n\n this.localConfig.loggerProvider.debug(\n JSON.stringify({ name: 'session replay joined config', config: getDebugConfig(config) }, null, 2),\n );\n\n return config;\n }\n}\n\nexport const createSessionReplayJoinedConfigGenerator = async (apiKey: string, options: SessionReplayOptions) => {\n const localConfig = new SessionReplayLocalConfig(apiKey, options);\n const remoteConfigFetch = await createRemoteConfigFetch<SessionReplayRemoteConfig>({\n localConfig,\n configKeys: ['sessionReplay'],\n });\n\n return new SessionReplayJoinedConfigGenerator(remoteConfigFetch, localConfig);\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 { ILogger } from '@amplitude/analytics-core';\nimport { getDebugConfig } from '../helpers';\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 const removeInvalidSelectorsFromPrivacyConfig = (privacyConfig: PrivacyConfig, loggerProvider: ILogger) => {\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 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 privacyConfig.blockSelector = dropInvalidSelectors(privacyConfig.blockSelector);\n privacyConfig.maskSelector = dropInvalidSelectors(privacyConfig.maskSelector);\n privacyConfig.unmaskSelector = dropInvalidSelectors(privacyConfig.unmaskSelector);\n return privacyConfig;\n};\nexport class SessionReplayJoinedConfigGenerator {\n private readonly localConfig: ISessionReplayLocalConfig;\n private readonly remoteConfigFetch: RemoteConfigFetch<SessionReplayRemoteConfig>;\n\n constructor(remoteConfigFetch: RemoteConfigFetch<SessionReplayRemoteConfig>, localConfig: ISessionReplayLocalConfig) {\n this.localConfig = localConfig;\n this.remoteConfigFetch = remoteConfigFetch;\n }\n\n async generateJoinedConfig(sessionId?: string | 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 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 // This is intentionally forced to only be set through the remote config.\n config.loggingConfig = await this.remoteConfigFetch.getRemoteConfig(\n 'sessionReplay',\n 'sr_logging_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 = removeInvalidSelectorsFromPrivacyConfig(\n joinedPrivacyConfig,\n this.localConfig.loggerProvider,\n );\n }\n\n this.localConfig.loggerProvider.debug(\n JSON.stringify({ name: 'session replay joined config', config: getDebugConfig(config) }, null, 2),\n );\n\n return config;\n }\n}\n\nexport const createSessionReplayJoinedConfigGenerator = async (apiKey: string, options: SessionReplayOptions) => {\n const localConfig = new SessionReplayLocalConfig(apiKey, options);\n const remoteConfigFetch = await createRemoteConfigFetch<SessionReplayRemoteConfig>({\n localConfig,\n configKeys: ['sessionReplay'],\n });\n\n return new SessionReplayJoinedConfigGenerator(remoteConfigFetch, localConfig);\n};\n"]}
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import { FetchTransport } from '@amplitude/analytics-
|
|
2
|
-
import { Config, Logger } from '@amplitude/analytics-core';
|
|
3
|
-
import { LogLevel } from '@amplitude/analytics-types';
|
|
1
|
+
import { Config, Logger, FetchTransport, LogLevel } from '@amplitude/analytics-core';
|
|
4
2
|
import { SessionReplayOptions, StoreType } from '../typings/session-replay';
|
|
5
3
|
import { SessionReplayLocalConfig as ISessionReplayLocalConfig, InteractionConfig, PrivacyConfig, SessionReplayPerformanceConfig, SessionReplayVersion } from './types';
|
|
6
4
|
export declare const getDefaultConfig: () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local-config.d.ts","sourceRoot":"","sources":["../../../src/config/local-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"local-config.d.ts","sourceRoot":"","sources":["../../../src/config/local-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAErF,OAAO,EAAE,oBAAoB,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAC5E,OAAO,EACL,wBAAwB,IAAI,yBAAyB,EACrD,iBAAiB,EACjB,aAAa,EACb,8BAA8B,EAC9B,oBAAoB,EACrB,MAAM,SAAS,CAAC;AAGjB,eAAO,MAAM,gBAAgB;;;;;CAK3B,CAAC;AAEH,qBAAa,wBAAyB,SAAQ,MAAO,YAAW,yBAAyB;IACvF,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,OAAO,CAAC,EAAE,oBAAoB,CAAC;IAC/B,SAAS,EAAE,SAAS,CAAC;IACrB,iBAAiB,CAAC,EAAE,8BAA8B,CAAC;IACnD,YAAY,CAAC,EAAE;QAAE,YAAY,EAAE,OAAO,CAAA;KAAE,CAAC;gBAE7B,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,oBAAoB;CAiC1D"}
|
|
@@ -2,16 +2,14 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.SessionReplayLocalConfig = exports.getDefaultConfig = void 0;
|
|
4
4
|
var tslib_1 = require("tslib");
|
|
5
|
-
var analytics_client_common_1 = require("@amplitude/analytics-client-common");
|
|
6
5
|
var analytics_core_1 = require("@amplitude/analytics-core");
|
|
7
|
-
var analytics_types_1 = require("@amplitude/analytics-types");
|
|
8
6
|
var constants_1 = require("../constants");
|
|
9
7
|
var logger_1 = require("../logger");
|
|
10
8
|
var getDefaultConfig = function () { return ({
|
|
11
9
|
flushMaxRetries: 2,
|
|
12
|
-
logLevel:
|
|
10
|
+
logLevel: analytics_core_1.LogLevel.Warn,
|
|
13
11
|
loggerProvider: new analytics_core_1.Logger(),
|
|
14
|
-
transportProvider: new
|
|
12
|
+
transportProvider: new analytics_core_1.FetchTransport(),
|
|
15
13
|
}); };
|
|
16
14
|
exports.getDefaultConfig = getDefaultConfig;
|
|
17
15
|
var SessionReplayLocalConfig = /** @class */ (function (_super) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local-config.js","sourceRoot":"","sources":["../../../src/config/local-config.ts"],"names":[],"mappings":";;;;AAAA,
|
|
1
|
+
{"version":3,"file":"local-config.js","sourceRoot":"","sources":["../../../src/config/local-config.ts"],"names":[],"mappings":";;;;AAAA,4DAAqF;AACrF,0CAAwE;AASxE,oCAA+C;AAExC,IAAM,gBAAgB,GAAG,cAAM,OAAA,CAAC;IACrC,eAAe,EAAE,CAAC;IAClB,QAAQ,EAAE,yBAAQ,CAAC,IAAI;IACvB,cAAc,EAAE,IAAI,uBAAM,EAAE;IAC5B,iBAAiB,EAAE,IAAI,+BAAc,EAAE;CACxC,CAAC,EALoC,CAKpC,CAAC;AALU,QAAA,gBAAgB,oBAK1B;AAEH;IAA8C,oDAAM;IAclD,kCAAY,MAAc,EAAE,OAA6B;QAAzD,iBAgCC;;QA/BC,IAAM,aAAa,GAAG,IAAA,wBAAgB,GAAE,CAAC;gBACzC,sDACE,iBAAiB,EAAE,aAAa,CAAC,iBAAiB,EAClD,cAAc,EAAE,IAAI,2BAAkB,CAAC,OAAO,CAAC,cAAc,IAAI,aAAa,CAAC,cAAc,CAAC,IAC3F,OAAO,KACV,MAAM,QAAA,IACN;QACF,KAAI,CAAC,eAAe;YAClB,OAAO,CAAC,eAAe,KAAK,SAAS,IAAI,OAAO,CAAC,eAAe,IAAI,aAAa,CAAC,eAAe;gBAC/F,CAAC,CAAC,OAAO,CAAC,eAAe;gBACzB,CAAC,CAAC,aAAa,CAAC,eAAe,CAAC;QAEpC,KAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,KAAI,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,+BAAmB,CAAC;QAC5D,KAAI,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,+BAAmB,CAAC;QAC5D,KAAI,CAAC,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC;QAC/C,KAAI,CAAC,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC;QAC7C,KAAI,CAAC,sBAAsB,GAAG,OAAO,CAAC,sBAAsB,CAAC;QAC7D,KAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;QAC/B,KAAI,CAAC,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC;QACnD,KAAI,CAAC,SAAS,GAAG,MAAA,OAAO,CAAC,SAAS,mCAAI,KAAK,CAAC;QAE5C,IAAI,OAAO,CAAC,aAAa,EAAE;YACzB,KAAI,CAAC,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC;SAC5C;QACD,IAAI,OAAO,CAAC,SAAS,EAAE;YACrB,KAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;SACpC;QACD,IAAI,OAAO,CAAC,YAAY,EAAE;YACxB,KAAI,CAAC,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;SAC1C;;IACH,CAAC;IACH,+BAAC;AAAD,CAAC,AA/CD,CAA8C,uBAAM,GA+CnD;AA/CY,4DAAwB","sourcesContent":["import { Config, Logger, FetchTransport, LogLevel } from '@amplitude/analytics-core';\nimport { DEFAULT_SAMPLE_RATE, DEFAULT_SERVER_ZONE } from '../constants';\nimport { SessionReplayOptions, StoreType } from '../typings/session-replay';\nimport {\n SessionReplayLocalConfig as ISessionReplayLocalConfig,\n InteractionConfig,\n PrivacyConfig,\n SessionReplayPerformanceConfig,\n SessionReplayVersion,\n} from './types';\nimport { SafeLoggerProvider } from '../logger';\n\nexport const getDefaultConfig = () => ({\n flushMaxRetries: 2,\n logLevel: LogLevel.Warn,\n loggerProvider: new Logger(),\n transportProvider: new FetchTransport(),\n});\n\nexport class SessionReplayLocalConfig extends Config implements ISessionReplayLocalConfig {\n apiKey: string;\n sampleRate: number;\n privacyConfig?: PrivacyConfig;\n interactionConfig?: InteractionConfig;\n debugMode?: boolean;\n configServerUrl?: string;\n trackServerUrl?: string;\n shouldInlineStylesheet?: boolean;\n version?: SessionReplayVersion;\n storeType: StoreType;\n performanceConfig?: SessionReplayPerformanceConfig;\n experimental?: { useWebWorker: boolean };\n\n constructor(apiKey: string, options: SessionReplayOptions) {\n const defaultConfig = getDefaultConfig();\n super({\n transportProvider: defaultConfig.transportProvider,\n loggerProvider: new SafeLoggerProvider(options.loggerProvider || defaultConfig.loggerProvider),\n ...options,\n apiKey,\n });\n this.flushMaxRetries =\n options.flushMaxRetries !== undefined && options.flushMaxRetries <= defaultConfig.flushMaxRetries\n ? options.flushMaxRetries\n : defaultConfig.flushMaxRetries;\n\n this.apiKey = apiKey;\n this.sampleRate = options.sampleRate || DEFAULT_SAMPLE_RATE;\n this.serverZone = options.serverZone || DEFAULT_SERVER_ZONE;\n this.configServerUrl = options.configServerUrl;\n this.trackServerUrl = options.trackServerUrl;\n this.shouldInlineStylesheet = options.shouldInlineStylesheet;\n this.version = options.version;\n this.performanceConfig = options.performanceConfig;\n this.storeType = options.storeType ?? 'idb';\n\n if (options.privacyConfig) {\n this.privacyConfig = options.privacyConfig;\n }\n if (options.debugMode) {\n this.debugMode = options.debugMode;\n }\n if (options.experimental) {\n this.experimental = options.experimental;\n }\n }\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { IConfig, LogLevel, ILogger } from '@amplitude/analytics-core';
|
|
2
2
|
import { StoreType, ConsoleLogLevel } from '../typings/session-replay';
|
|
3
3
|
export interface SamplingConfig {
|
|
4
4
|
sample_rate: number;
|
|
@@ -37,21 +37,76 @@ export type PrivacyConfig = {
|
|
|
37
37
|
maskSelector?: string[];
|
|
38
38
|
unmaskSelector?: string[];
|
|
39
39
|
};
|
|
40
|
-
export interface SessionReplayLocalConfig extends
|
|
40
|
+
export interface SessionReplayLocalConfig extends IConfig {
|
|
41
41
|
apiKey: string;
|
|
42
|
-
loggerProvider:
|
|
42
|
+
loggerProvider: ILogger;
|
|
43
|
+
/**
|
|
44
|
+
* LogLevel.None or LogLevel.Error or LogLevel.Warn or LogLevel.Verbose or LogLevel.Debug.
|
|
45
|
+
* Sets the log level.
|
|
46
|
+
*
|
|
47
|
+
* @defaultValue LogLevel.Warn
|
|
48
|
+
*/
|
|
43
49
|
logLevel: LogLevel;
|
|
50
|
+
/**
|
|
51
|
+
* The maximum number of retries allowed for sending replay events.
|
|
52
|
+
* Once this limit is reached, failed events will no longer be sent.
|
|
53
|
+
*
|
|
54
|
+
* @defaultValue 2
|
|
55
|
+
*/
|
|
44
56
|
flushMaxRetries: number;
|
|
57
|
+
/**
|
|
58
|
+
* Use this option to control how many sessions to select for replay collection.
|
|
59
|
+
* The number should be a decimal between 0 and 1, for example 0.4, representing
|
|
60
|
+
* the fraction of sessions to have randomly selected for replay collection.
|
|
61
|
+
* Over a large number of sessions, 0.4 would select 40% of those sessions.
|
|
62
|
+
* Sample rates as small as six decimal places (0.000001) are supported.
|
|
63
|
+
*
|
|
64
|
+
* @defaultValue 0
|
|
65
|
+
*/
|
|
45
66
|
sampleRate: number;
|
|
46
67
|
privacyConfig?: PrivacyConfig;
|
|
68
|
+
/**
|
|
69
|
+
* Adds additional debug event property to help debug instrumentation issues
|
|
70
|
+
* (such as mismatching apps). Only recommended for debugging initial setup,
|
|
71
|
+
* and not recommended for production.
|
|
72
|
+
*/
|
|
47
73
|
debugMode?: boolean;
|
|
74
|
+
/**
|
|
75
|
+
* Specifies the endpoint URL to fetch remote configuration.
|
|
76
|
+
* If provided, it overrides the default server zone configuration.
|
|
77
|
+
*/
|
|
48
78
|
configServerUrl?: string;
|
|
79
|
+
/**
|
|
80
|
+
* Specifies the endpoint URL for sending session replay data.
|
|
81
|
+
* If provided, it overrides the default server zone configuration.
|
|
82
|
+
*/
|
|
49
83
|
trackServerUrl?: string;
|
|
84
|
+
/**
|
|
85
|
+
* If stylesheets are inlined, the contents of the stylesheet will be stored.
|
|
86
|
+
* During replay, the stored stylesheet will be used instead of attempting to fetch it remotely.
|
|
87
|
+
* This prevents replays from appearing broken due to missing stylesheets.
|
|
88
|
+
* Note: Inlining stylesheets may not work in all cases.
|
|
89
|
+
*/
|
|
50
90
|
shouldInlineStylesheet?: boolean;
|
|
51
91
|
version?: SessionReplayVersion;
|
|
92
|
+
/**
|
|
93
|
+
* Performance configuration config. If enabled, we will defer compression
|
|
94
|
+
* to be done during the browser's idle periods.
|
|
95
|
+
*/
|
|
52
96
|
performanceConfig?: SessionReplayPerformanceConfig;
|
|
97
|
+
/**
|
|
98
|
+
* Specifies how replay events should be stored. `idb` uses IndexedDB to persist replay events
|
|
99
|
+
* when all events cannot be sent during capture. `memory` stores replay events only in memory,
|
|
100
|
+
* meaning events are lost when the page is closed. If IndexedDB is unavailable, the system falls back to `memory`.
|
|
101
|
+
*/
|
|
53
102
|
storeType: StoreType;
|
|
103
|
+
/**
|
|
104
|
+
* Experimental features.
|
|
105
|
+
*/
|
|
54
106
|
experimental?: {
|
|
107
|
+
/**
|
|
108
|
+
* If the SDK should compress the replay events using a webworker.
|
|
109
|
+
*/
|
|
55
110
|
useWebWorker: boolean;
|
|
56
111
|
};
|
|
57
112
|
}
|
|
@@ -73,8 +128,19 @@ export interface SessionReplayVersion {
|
|
|
73
128
|
version: string;
|
|
74
129
|
type: SessionReplayType;
|
|
75
130
|
}
|
|
131
|
+
/**
|
|
132
|
+
* Configuration options for session replay performance.
|
|
133
|
+
*/
|
|
76
134
|
export interface SessionReplayPerformanceConfig {
|
|
135
|
+
/**
|
|
136
|
+
* If enabled, event compression will be deferred to occur during the browser's idle periods.
|
|
137
|
+
*/
|
|
77
138
|
enabled: boolean;
|
|
139
|
+
/**
|
|
140
|
+
* Optional timeout in milliseconds for the `requestIdleCallback` API.
|
|
141
|
+
* If specified, this value will be used to set a maximum time for the browser to wait
|
|
142
|
+
* before executing the deferred compression task, even if the browser is not idle.
|
|
143
|
+
*/
|
|
78
144
|
timeout?: number;
|
|
79
145
|
}
|
|
80
146
|
export type SessionReplayType = 'standalone' | 'plugin' | 'segment';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/config/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/config/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/config/types.ts"],"names":[],"mappings":";;;AA0Ca,QAAA,kBAAkB,GAAG,QAAQ,CAAC","sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/config/types.ts"],"names":[],"mappings":";;;AA0Ca,QAAA,kBAAkB,GAAG,QAAQ,CAAC","sourcesContent":["import { IConfig, LogLevel, ILogger } from '@amplitude/analytics-core';\nimport { StoreType, ConsoleLogLevel } from '../typings/session-replay';\n\nexport interface SamplingConfig {\n sample_rate: number;\n capture_enabled: boolean;\n}\n\nexport interface InteractionConfig {\n trackEveryNms?: number;\n enabled: boolean; // defaults to false\n batch: boolean; // defaults to false\n}\n\nexport interface LoggingConfig {\n console: {\n enabled: boolean;\n levels: ConsoleLogLevel[];\n };\n network?: {\n enabled: boolean;\n };\n}\n\nexport type SessionReplayRemoteConfig = {\n sr_sampling_config?: SamplingConfig;\n sr_privacy_config?: PrivacyConfig;\n sr_interaction_config?: InteractionConfig;\n sr_logging_config?: LoggingConfig;\n};\n\nexport interface SessionReplayRemoteConfigAPIResponse {\n configs: {\n sessionReplay: SessionReplayRemoteConfig;\n };\n}\n\nexport type MaskLevel =\n | 'light' // only mask a subset of inputs that’s deemed sensitive - password, credit card, telephone #, email. These are information we never want to capture.\n | 'medium' // mask all inputs\n | 'conservative'; // mask all inputs and all texts\n\nexport const DEFAULT_MASK_LEVEL = 'medium';\n\n// err on the side of excluding more\nexport type PrivacyConfig = {\n blockSelector?: string | string[]; // exclude in the UI\n defaultMaskLevel?: MaskLevel;\n maskSelector?: string[];\n unmaskSelector?: string[];\n};\n\nexport interface SessionReplayLocalConfig extends IConfig {\n apiKey: string;\n loggerProvider: ILogger;\n /**\n * LogLevel.None or LogLevel.Error or LogLevel.Warn or LogLevel.Verbose or LogLevel.Debug.\n * Sets the log level.\n *\n * @defaultValue LogLevel.Warn\n */\n logLevel: LogLevel;\n /**\n * The maximum number of retries allowed for sending replay events.\n * Once this limit is reached, failed events will no longer be sent.\n *\n * @defaultValue 2\n */\n flushMaxRetries: number;\n /**\n * Use this option to control how many sessions to select for replay collection.\n * The number should be a decimal between 0 and 1, for example 0.4, representing\n * the fraction of sessions to have randomly selected for replay collection.\n * Over a large number of sessions, 0.4 would select 40% of those sessions.\n * Sample rates as small as six decimal places (0.000001) are supported.\n *\n * @defaultValue 0\n */\n sampleRate: number;\n privacyConfig?: PrivacyConfig;\n /**\n * Adds additional debug event property to help debug instrumentation issues\n * (such as mismatching apps). Only recommended for debugging initial setup,\n * and not recommended for production.\n */\n debugMode?: boolean;\n /**\n * Specifies the endpoint URL to fetch remote configuration.\n * If provided, it overrides the default server zone configuration.\n */\n configServerUrl?: string;\n /**\n * Specifies the endpoint URL for sending session replay data.\n * If provided, it overrides the default server zone configuration.\n */\n trackServerUrl?: string;\n /**\n * If stylesheets are inlined, the contents of the stylesheet will be stored.\n * During replay, the stored stylesheet will be used instead of attempting to fetch it remotely.\n * This prevents replays from appearing broken due to missing stylesheets.\n * Note: Inlining stylesheets may not work in all cases.\n */\n shouldInlineStylesheet?: boolean;\n version?: SessionReplayVersion;\n /**\n * Performance configuration config. If enabled, we will defer compression\n * to be done during the browser's idle periods.\n */\n performanceConfig?: SessionReplayPerformanceConfig;\n /**\n * Specifies how replay events should be stored. `idb` uses IndexedDB to persist replay events\n * when all events cannot be sent during capture. `memory` stores replay events only in memory,\n * meaning events are lost when the page is closed. If IndexedDB is unavailable, the system falls back to `memory`.\n */\n storeType: StoreType;\n\n /**\n * Experimental features.\n */\n experimental?: {\n /**\n * If the SDK should compress the replay events using a webworker.\n */\n useWebWorker: boolean;\n };\n}\n\nexport interface SessionReplayJoinedConfig extends SessionReplayLocalConfig {\n captureEnabled?: boolean;\n interactionConfig?: InteractionConfig;\n loggingConfig?: LoggingConfig;\n}\n\nexport interface SessionReplayRemoteConfigFetch {\n getServerUrl: () => void;\n getSamplingConfig: (sessionId?: number) => Promise<SessionReplayRemoteConfig['sr_sampling_config'] | void>;\n fetchRemoteConfig: (sessionId?: number) => Promise<SessionReplayRemoteConfig | void>;\n getRemoteConfig: (sessionId?: number) => Promise<SessionReplayRemoteConfig | void>;\n}\n\nexport interface SessionReplayJoinedConfigGenerator {\n generateJoinedConfig: (sessionId?: string | number) => Promise<SessionReplayJoinedConfig>;\n}\n\nexport interface SessionReplayVersion {\n version: string;\n type: SessionReplayType;\n}\n\n/**\n * Configuration options for session replay performance.\n */\nexport interface SessionReplayPerformanceConfig {\n /**\n * If enabled, event compression will be deferred to occur during the browser's idle periods.\n */\n enabled: boolean;\n /**\n * Optional timeout in milliseconds for the `requestIdleCallback` API.\n * If specified, this value will be used to set a maximum time for the browser to wait\n * before executing the deferred compression task, even if the browser is not idle.\n */\n timeout?: number;\n}\n\nexport type SessionReplayType = 'standalone' | 'plugin' | 'segment';\n"]}
|
package/lib/cjs/constants.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ServerZone } from '@amplitude/analytics-
|
|
1
|
+
import { ServerZone } from '@amplitude/analytics-core';
|
|
2
2
|
export declare const DEFAULT_EVENT_PROPERTY_PREFIX = "[Amplitude]";
|
|
3
3
|
export declare const DEFAULT_SESSION_REPLAY_PROPERTY: string;
|
|
4
4
|
export declare const DEFAULT_SESSION_START_EVENT = "session_start";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAEzE,eAAO,MAAM,6BAA6B,gBAAgB,CAAC;AAE3D,eAAO,MAAM,+BAA+B,QAAuD,CAAC;AACpG,eAAO,MAAM,2BAA2B,kBAAkB,CAAC;AAC3D,eAAO,MAAM,yBAAyB,gBAAgB,CAAC;AACvD,eAAO,MAAM,mBAAmB,IAAI,CAAC;AACrC,eAAO,MAAM,mBAAmB,gBAAgB,CAAC;AAEjD,eAAO,MAAM,6BAA6B,QAA0D,CAAC;AAErG,eAAO,MAAM,WAAW,cAAc,CAAC;AACvC,eAAO,MAAM,eAAe,aAAa,CAAC;AAC1C,eAAO,MAAM,iBAAiB,eAAe,CAAC;AAC9C,eAAO,MAAM,yBAAyB,mDAAmD,CAAC;AAC1F,eAAO,MAAM,qBAAqB,sDAAsD,CAAC;AACzF,eAAO,MAAM,0BAA0B,yDAAyD,CAAC;AACjG,eAAO,MAAM,cAAc,QAAsC,CAAC;AAClE,eAAO,MAAM,4BAA4B,QAAc,CAAC;AACxD,eAAO,MAAM,wBAAwB,QAAS,CAAC;AAC/C,eAAO,MAAM,wBAAwB,QAAS,CAAC;AAC/C,eAAO,MAAM,YAAY,MAAM,CAAC;AAChC,eAAO,MAAM,YAAY,QAAY,CAAC;AACtC,eAAO,MAAM,sBAAsB,QAA0B,CAAC;AAC9D,eAAO,MAAM,OAAO,OAAO,CAAC;AAC5B,eAAO,MAAM,cAAc,OAAO,CAAC;AAEnC,oBAAY,gBAAgB;IAC1B,YAAY,iBAAiB;IAC7B,UAAU,eAAe;IACzB,aAAa,kBAAkB;CAChC"}
|
package/lib/cjs/constants.js
CHANGED
|
@@ -2,13 +2,12 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.CustomRRwebEvent = exports.MAX_URL_LENGTH = exports.KB_SIZE = exports.MAX_IDB_STORAGE_LENGTH = exports.MAX_INTERVAL = exports.MIN_INTERVAL = exports.INTERACTION_MAX_INTERVAL = exports.INTERACTION_MIN_INTERVAL = exports.MAX_EVENT_LIST_SIZE_IN_BYTES = exports.STORAGE_PREFIX = exports.SESSION_REPLAY_STAGING_URL = exports.SESSION_REPLAY_EU_URL = exports.SESSION_REPLAY_SERVER_URL = exports.UNMASK_TEXT_CLASS = exports.MASK_TEXT_CLASS = exports.BLOCK_CLASS = exports.SESSION_REPLAY_DEBUG_PROPERTY = exports.DEFAULT_SERVER_ZONE = exports.DEFAULT_SAMPLE_RATE = exports.DEFAULT_SESSION_END_EVENT = exports.DEFAULT_SESSION_START_EVENT = exports.DEFAULT_SESSION_REPLAY_PROPERTY = exports.DEFAULT_EVENT_PROPERTY_PREFIX = void 0;
|
|
4
4
|
var analytics_core_1 = require("@amplitude/analytics-core");
|
|
5
|
-
var analytics_types_1 = require("@amplitude/analytics-types");
|
|
6
5
|
exports.DEFAULT_EVENT_PROPERTY_PREFIX = '[Amplitude]';
|
|
7
6
|
exports.DEFAULT_SESSION_REPLAY_PROPERTY = "".concat(exports.DEFAULT_EVENT_PROPERTY_PREFIX, " Session Replay ID");
|
|
8
7
|
exports.DEFAULT_SESSION_START_EVENT = 'session_start';
|
|
9
8
|
exports.DEFAULT_SESSION_END_EVENT = 'session_end';
|
|
10
9
|
exports.DEFAULT_SAMPLE_RATE = 0;
|
|
11
|
-
exports.DEFAULT_SERVER_ZONE =
|
|
10
|
+
exports.DEFAULT_SERVER_ZONE = analytics_core_1.ServerZone.US;
|
|
12
11
|
exports.SESSION_REPLAY_DEBUG_PROPERTY = "".concat(exports.DEFAULT_EVENT_PROPERTY_PREFIX, " Session Replay Debug");
|
|
13
12
|
exports.BLOCK_CLASS = 'amp-block';
|
|
14
13
|
exports.MASK_TEXT_CLASS = 'amp-mask';
|
package/lib/cjs/constants.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":";;;AAAA,
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":";;;AAAA,4DAAyE;AAE5D,QAAA,6BAA6B,GAAG,aAAa,CAAC;AAE9C,QAAA,+BAA+B,GAAG,UAAG,qCAA6B,uBAAoB,CAAC;AACvF,QAAA,2BAA2B,GAAG,eAAe,CAAC;AAC9C,QAAA,yBAAyB,GAAG,aAAa,CAAC;AAC1C,QAAA,mBAAmB,GAAG,CAAC,CAAC;AACxB,QAAA,mBAAmB,GAAG,2BAAU,CAAC,EAAE,CAAC;AAEpC,QAAA,6BAA6B,GAAG,UAAG,qCAA6B,0BAAuB,CAAC;AAExF,QAAA,WAAW,GAAG,WAAW,CAAC;AAC1B,QAAA,eAAe,GAAG,UAAU,CAAC;AAC7B,QAAA,iBAAiB,GAAG,YAAY,CAAC;AACjC,QAAA,yBAAyB,GAAG,gDAAgD,CAAC;AAC7E,QAAA,qBAAqB,GAAG,mDAAmD,CAAC;AAC5E,QAAA,0BAA0B,GAAG,sDAAsD,CAAC;AACpF,QAAA,cAAc,GAAG,UAAG,iCAAgB,mBAAgB,CAAC;AACrD,QAAA,4BAA4B,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC,OAAO;AACnD,QAAA,wBAAwB,GAAG,KAAM,CAAC,CAAC,aAAa;AAChD,QAAA,wBAAwB,GAAG,KAAM,CAAC,CAAC,WAAW;AAC9C,QAAA,YAAY,GAAG,GAAG,CAAC,CAAC,SAAS;AAC7B,QAAA,YAAY,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,aAAa;AACvC,QAAA,sBAAsB,GAAG,IAAI,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,SAAS;AAC3D,QAAA,OAAO,GAAG,IAAI,CAAC;AACf,QAAA,cAAc,GAAG,IAAI,CAAC;AAEnC,IAAY,gBAIX;AAJD,WAAY,gBAAgB;IAC1B,iDAA6B,CAAA;IAC7B,6CAAyB,CAAA;IACzB,mDAA+B,CAAA;AACjC,CAAC,EAJW,gBAAgB,GAAhB,wBAAgB,KAAhB,wBAAgB,QAI3B","sourcesContent":["import { AMPLITUDE_PREFIX, ServerZone } from '@amplitude/analytics-core';\n\nexport const DEFAULT_EVENT_PROPERTY_PREFIX = '[Amplitude]';\n\nexport const DEFAULT_SESSION_REPLAY_PROPERTY = `${DEFAULT_EVENT_PROPERTY_PREFIX} Session Replay ID`;\nexport const DEFAULT_SESSION_START_EVENT = 'session_start';\nexport const DEFAULT_SESSION_END_EVENT = 'session_end';\nexport const DEFAULT_SAMPLE_RATE = 0;\nexport const DEFAULT_SERVER_ZONE = ServerZone.US;\n\nexport const SESSION_REPLAY_DEBUG_PROPERTY = `${DEFAULT_EVENT_PROPERTY_PREFIX} Session Replay Debug`;\n\nexport const BLOCK_CLASS = 'amp-block';\nexport const MASK_TEXT_CLASS = 'amp-mask';\nexport const UNMASK_TEXT_CLASS = 'amp-unmask';\nexport const SESSION_REPLAY_SERVER_URL = 'https://api-sr.amplitude.com/sessions/v2/track';\nexport const SESSION_REPLAY_EU_URL = 'https://api-sr.eu.amplitude.com/sessions/v2/track';\nexport const SESSION_REPLAY_STAGING_URL = 'https://api-sr.stag2.amplitude.com/sessions/v2/track';\nexport const STORAGE_PREFIX = `${AMPLITUDE_PREFIX}_replay_unsent`;\nexport const MAX_EVENT_LIST_SIZE_IN_BYTES = 1 * 1000000; // 1 MB\nexport const INTERACTION_MIN_INTERVAL = 30_000; // 30 seconds\nexport const INTERACTION_MAX_INTERVAL = 60_000; // 1 minute\nexport const MIN_INTERVAL = 500; // 500 ms\nexport const MAX_INTERVAL = 10 * 1000; // 10 seconds\nexport const MAX_IDB_STORAGE_LENGTH = 1000 * 60 * 60 * 24 * 3; // 3 days\nexport const KB_SIZE = 1024;\nexport const MAX_URL_LENGTH = 1000;\n\nexport enum CustomRRwebEvent {\n GET_SR_PROPS = 'get-sr-props',\n DEBUG_INFO = 'debug-info',\n FETCH_REQUEST = 'fetch-request',\n}\n"]}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { Events, EventsStore, SendingSequencesReturn } from '../typings/session-replay';
|
|
2
|
-
import {
|
|
2
|
+
import { ILogger } from '@amplitude/analytics-core';
|
|
3
3
|
export type InstanceArgs = {
|
|
4
|
-
loggerProvider:
|
|
4
|
+
loggerProvider: ILogger;
|
|
5
5
|
minInterval?: number;
|
|
6
6
|
maxInterval?: number;
|
|
7
7
|
maxPersistedEventsSize?: number;
|
|
8
8
|
};
|
|
9
9
|
export declare abstract class BaseEventsStore<KeyType> implements EventsStore<KeyType> {
|
|
10
|
-
protected readonly loggerProvider:
|
|
10
|
+
protected readonly loggerProvider: ILogger;
|
|
11
11
|
private minInterval;
|
|
12
12
|
private maxInterval;
|
|
13
13
|
private maxPersistedEventsSize;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base-events-store.d.ts","sourceRoot":"","sources":["../../../src/events/base-events-store.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AACxF,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"base-events-store.d.ts","sourceRoot":"","sources":["../../../src/events/base-events-store.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AACxF,OAAO,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAC;AAEpD,MAAM,MAAM,YAAY,GAAG;IACzB,cAAc,EAAE,OAAO,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,sBAAsB,CAAC,EAAE,MAAM,CAAC;CACjC,CAAC;AAEF,8BAAsB,eAAe,CAAC,OAAO,CAAE,YAAW,WAAW,CAAC,OAAO,CAAC;IAC5E,SAAS,CAAC,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;IAC3C,OAAO,CAAC,WAAW,CAAgB;IACnC,OAAO,CAAC,WAAW,CAAgB;IACnC,OAAO,CAAC,sBAAsB,CAAgC;IAC9D,OAAO,CAAC,QAAQ,CAAoB;IACpC,OAAO,CAAC,gBAAgB,CAAc;IAEtC,IAAW,eAAe,WAEzB;gBAEW,IAAI,EAAE,YAAY;IAO9B,QAAQ,CAAC,yBAAyB,CAChC,SAAS,EAAE,MAAM,GAAG,MAAM,EAC1B,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,sBAAsB,CAAC,OAAO,CAAC,GAAG,SAAS,CAAC;IACvD,QAAQ,CAAC,kBAAkB,IAAI,OAAO,CAAC,sBAAsB,CAAC,OAAO,CAAC,EAAE,GAAG,SAAS,CAAC;IACrF,QAAQ,CAAC,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,CAAC,OAAO,CAAC,GAAG,SAAS,CAAC;IACtG,QAAQ,CAAC,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC;IACrG,QAAQ,CAAC,yBAAyB,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAEzF;;;;;OAKG;IACH,qBAAqB,oCAAqC,MAAM,KAAG,OAAO,CAYxE;CACH"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base-events-store.js","sourceRoot":"","sources":["../../../src/events/base-events-store.ts"],"names":[],"mappings":";;;AAAA,0CAAwF;AAWxF;IAYE,yBAAY,IAAkB;QAA9B,iBAKC;;QAfO,gBAAW,GAAG,wBAAY,CAAC;QAC3B,gBAAW,GAAG,wBAAY,CAAC;QAC3B,2BAAsB,GAAG,wCAA4B,CAAC;QACtD,aAAQ,GAAG,IAAI,CAAC,WAAW,CAAC;QAC5B,qBAAgB,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,4EAA4E;QAsBnH;;;;;WAKG;QACH,0BAAqB,GAAG,UAAC,MAAc,EAAE,eAAuB;YAC9D,IAAM,eAAe,GAAG,IAAI,IAAI,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC;YACzD,IAAM,gBAAgB,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC;YAC/C,IAAI,gBAAgB,GAAG,eAAe,IAAI,KAAI,CAAC,sBAAsB,EAAE;gBACrE,OAAO,IAAI,CAAC;aACb;YACD,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,KAAI,CAAC,eAAe,GAAG,KAAI,CAAC,QAAQ,IAAI,MAAM,CAAC,MAAM,EAAE;gBACtE,KAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,KAAI,CAAC,WAAW,EAAE,KAAI,CAAC,QAAQ,GAAG,KAAI,CAAC,WAAW,CAAC,CAAC;gBAC7E,KAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;gBACnC,OAAO,IAAI,CAAC;aACb;YACD,OAAO,KAAK,CAAC;QACf,CAAC,CAAC;QAjCA,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,cAAc,CAAC;QAC1C,IAAI,CAAC,WAAW,GAAG,MAAA,IAAI,CAAC,WAAW,mCAAI,IAAI,CAAC,WAAW,CAAC;QACxD,IAAI,CAAC,WAAW,GAAG,MAAA,IAAI,CAAC,WAAW,mCAAI,IAAI,CAAC,WAAW,CAAC;QACxD,IAAI,CAAC,sBAAsB,GAAG,MAAA,IAAI,CAAC,sBAAsB,mCAAI,IAAI,CAAC,sBAAsB,CAAC;IAC3F,CAAC;IATD,sBAAW,4CAAe;aAA1B;YACE,OAAO,IAAI,CAAC,gBAAgB,CAAC;QAC/B,CAAC;;;OAAA;IAqCH,sBAAC;AAAD,CAAC,AA/CD,IA+CC;AA/CqB,0CAAe","sourcesContent":["import { MAX_EVENT_LIST_SIZE_IN_BYTES, MAX_INTERVAL, MIN_INTERVAL } from '../constants';\nimport { Events, EventsStore, SendingSequencesReturn } from '../typings/session-replay';\nimport {
|
|
1
|
+
{"version":3,"file":"base-events-store.js","sourceRoot":"","sources":["../../../src/events/base-events-store.ts"],"names":[],"mappings":";;;AAAA,0CAAwF;AAWxF;IAYE,yBAAY,IAAkB;QAA9B,iBAKC;;QAfO,gBAAW,GAAG,wBAAY,CAAC;QAC3B,gBAAW,GAAG,wBAAY,CAAC;QAC3B,2BAAsB,GAAG,wCAA4B,CAAC;QACtD,aAAQ,GAAG,IAAI,CAAC,WAAW,CAAC;QAC5B,qBAAgB,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,4EAA4E;QAsBnH;;;;;WAKG;QACH,0BAAqB,GAAG,UAAC,MAAc,EAAE,eAAuB;YAC9D,IAAM,eAAe,GAAG,IAAI,IAAI,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC;YACzD,IAAM,gBAAgB,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC;YAC/C,IAAI,gBAAgB,GAAG,eAAe,IAAI,KAAI,CAAC,sBAAsB,EAAE;gBACrE,OAAO,IAAI,CAAC;aACb;YACD,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,KAAI,CAAC,eAAe,GAAG,KAAI,CAAC,QAAQ,IAAI,MAAM,CAAC,MAAM,EAAE;gBACtE,KAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,KAAI,CAAC,WAAW,EAAE,KAAI,CAAC,QAAQ,GAAG,KAAI,CAAC,WAAW,CAAC,CAAC;gBAC7E,KAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;gBACnC,OAAO,IAAI,CAAC;aACb;YACD,OAAO,KAAK,CAAC;QACf,CAAC,CAAC;QAjCA,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,cAAc,CAAC;QAC1C,IAAI,CAAC,WAAW,GAAG,MAAA,IAAI,CAAC,WAAW,mCAAI,IAAI,CAAC,WAAW,CAAC;QACxD,IAAI,CAAC,WAAW,GAAG,MAAA,IAAI,CAAC,WAAW,mCAAI,IAAI,CAAC,WAAW,CAAC;QACxD,IAAI,CAAC,sBAAsB,GAAG,MAAA,IAAI,CAAC,sBAAsB,mCAAI,IAAI,CAAC,sBAAsB,CAAC;IAC3F,CAAC;IATD,sBAAW,4CAAe;aAA1B;YACE,OAAO,IAAI,CAAC,gBAAgB,CAAC;QAC/B,CAAC;;;OAAA;IAqCH,sBAAC;AAAD,CAAC,AA/CD,IA+CC;AA/CqB,0CAAe","sourcesContent":["import { MAX_EVENT_LIST_SIZE_IN_BYTES, MAX_INTERVAL, MIN_INTERVAL } from '../constants';\nimport { Events, EventsStore, SendingSequencesReturn } from '../typings/session-replay';\nimport { ILogger } from '@amplitude/analytics-core';\n\nexport type InstanceArgs = {\n loggerProvider: ILogger;\n minInterval?: number;\n maxInterval?: number;\n maxPersistedEventsSize?: number;\n};\n\nexport abstract class BaseEventsStore<KeyType> implements EventsStore<KeyType> {\n protected readonly loggerProvider: ILogger;\n private minInterval = MIN_INTERVAL;\n private maxInterval = MAX_INTERVAL;\n private maxPersistedEventsSize = MAX_EVENT_LIST_SIZE_IN_BYTES;\n private interval = this.minInterval;\n private _timeAtLastSplit = Date.now(); // Initialize this so we have a point of comparison when events are recorded\n\n public get timeAtLastSplit() {\n return this._timeAtLastSplit;\n }\n\n constructor(args: InstanceArgs) {\n this.loggerProvider = args.loggerProvider;\n this.minInterval = args.minInterval ?? this.minInterval;\n this.maxInterval = args.maxInterval ?? this.maxInterval;\n this.maxPersistedEventsSize = args.maxPersistedEventsSize ?? this.maxPersistedEventsSize;\n }\n\n abstract addEventToCurrentSequence(\n sessionId: string | number,\n event: string,\n ): Promise<SendingSequencesReturn<KeyType> | undefined>;\n abstract getSequencesToSend(): Promise<SendingSequencesReturn<KeyType>[] | undefined>;\n abstract storeCurrentSequence(sessionId: number): Promise<SendingSequencesReturn<KeyType> | undefined>;\n abstract storeSendingEvents(sessionId: string | number, events: Events): Promise<KeyType | undefined>;\n abstract cleanUpSessionEventsStore(sessionId: number, sequenceId: KeyType): Promise<void>;\n\n /**\n * Determines whether to send the events list to the backend and start a new\n * empty events list, based on the size of the list as well as the last time sent\n * @param nextEventString\n * @returns boolean\n */\n shouldSplitEventsList = (events: Events, nextEventString: string): boolean => {\n const sizeOfNextEvent = new Blob([nextEventString]).size;\n const sizeOfEventsList = new Blob(events).size;\n if (sizeOfEventsList + sizeOfNextEvent >= this.maxPersistedEventsSize) {\n return true;\n }\n if (Date.now() - this.timeAtLastSplit > this.interval && events.length) {\n this.interval = Math.min(this.maxInterval, this.interval + this.minInterval);\n this._timeAtLastSplit = Date.now();\n return true;\n }\n return false;\n };\n}\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.EventCompressor = void 0;
|
|
4
|
-
var
|
|
4
|
+
var analytics_core_1 = require("@amplitude/analytics-core");
|
|
5
5
|
var rrweb_packer_1 = require("@amplitude/rrweb-packer");
|
|
6
6
|
var DEFAULT_TIMEOUT = 2000;
|
|
7
7
|
var EventCompressor = /** @class */ (function () {
|
|
@@ -37,7 +37,7 @@ var EventCompressor = /** @class */ (function () {
|
|
|
37
37
|
var _a;
|
|
38
38
|
(_a = _this.worker) === null || _a === void 0 ? void 0 : _a.terminate();
|
|
39
39
|
};
|
|
40
|
-
var globalScope = (0,
|
|
40
|
+
var globalScope = (0, analytics_core_1.getGlobalScope)();
|
|
41
41
|
this.canUseIdleCallback = globalScope && 'requestIdleCallback' in globalScope;
|
|
42
42
|
this.eventsManager = eventsManager;
|
|
43
43
|
this.config = config;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"event-compressor.js","sourceRoot":"","sources":["../../../src/events/event-compressor.ts"],"names":[],"mappings":";;;AAAA,
|
|
1
|
+
{"version":3,"file":"event-compressor.js","sourceRoot":"","sources":["../../../src/events/event-compressor.ts"],"names":[],"mappings":";;;AAAA,4DAA2D;AAC3D,wDAA+C;AAU/C,IAAM,eAAe,GAAG,IAAI,CAAC;AAC7B;IAUE,yBACE,aAA2E,EAC3E,MAAiC,EACjC,QAA4B,EAC5B,oBAA6B;QAJ/B,iBAgCC;;QAzCD,cAAS,GAAgB,EAAE,CAAC;QAC5B,iBAAY,GAAG,KAAK,CAAC;QA2FrB,kBAAa,GAAG,UAAC,KAAoB;YACnC,IAAM,WAAW,GAAG,IAAA,mBAAI,EAAC,KAAK,CAAC,CAAC;YAChC,OAAO,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QACrC,CAAC,CAAC;QAEM,gCAA2B,GAAG,UAAC,eAAuB,EAAE,SAA0B;YACxF,IAAI,KAAI,CAAC,aAAa,IAAI,KAAI,CAAC,QAAQ,EAAE;gBACvC,KAAI,CAAC,aAAa,CAAC,QAAQ,CAAC;oBAC1B,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,eAAe,EAAE;oBAChD,SAAS,WAAA;oBACT,QAAQ,EAAE,KAAI,CAAC,QAAQ;iBACxB,CAAC,CAAC;aACJ;QACH,CAAC,CAAC;QAEK,uBAAkB,GAAG,UAAC,KAAoB,EAAE,SAA0B;YAC3E,IAAI,KAAI,CAAC,MAAM,EAAE;gBACf,wCAAwC;gBACxC,KAAI,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,KAAK,OAAA,EAAE,SAAS,WAAA,EAAE,CAAC,CAAC;aAC/C;iBAAM;gBACL,IAAM,eAAe,GAAG,KAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;gBAClD,KAAI,CAAC,2BAA2B,CAAC,eAAe,EAAE,SAAS,CAAC,CAAC;aAC9D;QACH,CAAC,CAAC;QAEK,cAAS,GAAG;;YACjB,MAAA,KAAI,CAAC,MAAM,0CAAE,SAAS,EAAE,CAAC;QAC3B,CAAC,CAAC;QAxGA,IAAM,WAAW,GAAG,IAAA,+BAAc,GAAE,CAAC;QACrC,IAAI,CAAC,kBAAkB,GAAG,WAAW,IAAI,qBAAqB,IAAI,WAAW,CAAC;QAC9E,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;QACnC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,OAAO,GAAG,CAAA,MAAA,MAAM,CAAC,iBAAiB,0CAAE,OAAO,KAAI,eAAe,CAAC;QAEpE,mDAAmD;QACnD,IAAM,OAAO,GAA2B,EAAE,CAAC;QAC3C,oFAAoF;QACpF,0BAA0B;QAC1B,IAAM,YAAY,GAAG,MAAA,OAAO,CAAC,0BAA0B,mCAAI,oBAAoB,CAAC;QAChF,IAAI,CAAA,MAAA,IAAI,CAAC,MAAM,CAAC,YAAY,0CAAE,YAAY,KAAI,WAAW,IAAI,WAAW,CAAC,MAAM,IAAI,YAAY,EAAE;YAC/F,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC,oDAAoD,CAAC,CAAC;YAEhF,IAAM,MAAM,GAAG,IAAI,MAAM,CAAC,GAAG,CAAC,eAAe,CAAC,IAAI,IAAI,CAAC,CAAC,YAAY,CAAC,EAAE,EAAE,IAAI,EAAE,wBAAwB,EAAE,CAAC,CAAC,CAAC,CAAC;YAC7G,MAAM,CAAC,OAAO,GAAG,UAAC,CAAC;gBACjB,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YACjC,CAAC,CAAC;YACF,MAAM,CAAC,SAAS,GAAG,UAAC,CAAC;gBACb,IAAA,KAAiC,CAAC,CAAC,IAA8B,EAA/D,eAAe,qBAAA,EAAE,SAAS,eAAqC,CAAC;gBACxE,KAAI,CAAC,2BAA2B,CAAC,eAAe,EAAE,SAAS,CAAC,CAAC;YAC/D,CAAC,CAAC;YAEF,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;SACtB;IACH,CAAC;IAED,uCAAuC;IAChC,gDAAsB,GAA7B;QAAA,iBAUC;QATC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE;YACtB,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;YACzB,mBAAmB,CACjB,UAAC,YAAY;gBACX,KAAI,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;YAClC,CAAC,EACD,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAC1B,CAAC;SACH;IACH,CAAC;IAED,8FAA8F;IACvF,sCAAY,GAAnB,UAAoB,KAAoB,EAAE,SAA0B;;QAClE,IAAI,IAAI,CAAC,kBAAkB,KAAI,MAAA,IAAI,CAAC,MAAM,CAAC,iBAAiB,0CAAE,OAAO,CAAA,EAAE;YACrE,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,kDAAkD,CAAC,CAAC;YACrF,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,KAAK,OAAA,EAAE,SAAS,WAAA,EAAE,CAAC,CAAC;YAC1C,IAAI,CAAC,sBAAsB,EAAE,CAAC;SAC/B;aAAM;YACL,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,yCAAyC,CAAC,CAAC;YAC5E,IAAI,CAAC,kBAAkB,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;SAC3C;IACH,CAAC;IAED,0CAA0C;IACnC,sCAAY,GAAnB,UAAoB,YAA0B;QAA9C,iBAqBC;QApBC,oFAAoF;QACpF,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,aAAa,EAAE,GAAG,CAAC,IAAI,YAAY,CAAC,UAAU,CAAC,EAAE;YACjG,IAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;YACpC,IAAI,IAAI,EAAE;gBACA,IAAA,OAAK,GAAgB,IAAI,MAApB,EAAE,SAAS,GAAK,IAAI,UAAT,CAAU;gBAClC,IAAI,CAAC,kBAAkB,CAAC,OAAK,EAAE,SAAS,CAAC,CAAC;aAC3C;SACF;QAED,yEAAyE;QACzE,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE;YAC7B,mBAAmB,CACjB,UAAC,YAAY;gBACX,KAAI,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;YAClC,CAAC,EACD,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAC1B,CAAC;SACH;aAAM;YACL,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC;SAC3B;IACH,CAAC;IA8BH,sBAAC;AAAD,CAAC,AAzHD,IAyHC;AAzHY,0CAAe","sourcesContent":["import { getGlobalScope } from '@amplitude/analytics-core';\nimport { pack } from '@amplitude/rrweb-packer';\nimport type { eventWithTime } from '@amplitude/rrweb-types';\nimport { SessionReplayJoinedConfig } from 'src/config/types';\nimport { SessionReplayEventsManager } from 'src/typings/session-replay';\n\ninterface TaskQueue {\n event: eventWithTime;\n sessionId: string | number;\n}\n\nconst DEFAULT_TIMEOUT = 2000;\nexport class EventCompressor {\n taskQueue: TaskQueue[] = [];\n isProcessing = false;\n eventsManager?: SessionReplayEventsManager<'replay' | 'interaction', string>;\n config: SessionReplayJoinedConfig;\n deviceId: string | undefined;\n canUseIdleCallback: boolean | undefined;\n timeout: number;\n worker?: Worker;\n\n constructor(\n eventsManager: SessionReplayEventsManager<'replay' | 'interaction', string>,\n config: SessionReplayJoinedConfig,\n deviceId: string | undefined,\n workerScriptInternal?: string, // this is used for unit testing\n ) {\n const globalScope = getGlobalScope();\n this.canUseIdleCallback = globalScope && 'requestIdleCallback' in globalScope;\n this.eventsManager = eventsManager;\n this.config = config;\n this.deviceId = deviceId;\n this.timeout = config.performanceConfig?.timeout || DEFAULT_TIMEOUT;\n\n // These two lines will be changed at compile time.\n const replace: Record<string, string> = {};\n // This next line is going to be ridiculously hard to cover in unit tests, ignoring.\n /* istanbul ignore next */\n const workerScript = replace.COMPRESSION_WEBWORKER_BODY ?? workerScriptInternal;\n if (this.config.experimental?.useWebWorker && globalScope && globalScope.Worker && workerScript) {\n config.loggerProvider.log('[Experimental] Enabling web worker for compression');\n\n const worker = new Worker(URL.createObjectURL(new Blob([workerScript], { type: 'application/javascript' })));\n worker.onerror = (e) => {\n config.loggerProvider.error(e);\n };\n worker.onmessage = (e) => {\n const { compressedEvent, sessionId } = e.data as Record<string, string>;\n this.addCompressedEventToManager(compressedEvent, sessionId);\n };\n\n this.worker = worker;\n }\n }\n\n // Schedule processing during idle time\n public scheduleIdleProcessing(): void {\n if (!this.isProcessing) {\n this.isProcessing = true;\n requestIdleCallback(\n (idleDeadline) => {\n this.processQueue(idleDeadline);\n },\n { timeout: this.timeout },\n );\n }\n }\n\n // Add an event to the task queue if idle callback is supported or compress the event directly\n public enqueueEvent(event: eventWithTime, sessionId: string | number): void {\n if (this.canUseIdleCallback && this.config.performanceConfig?.enabled) {\n this.config.loggerProvider.debug('Enqueuing event for processing during idle time.');\n this.taskQueue.push({ event, sessionId });\n this.scheduleIdleProcessing();\n } else {\n this.config.loggerProvider.debug('Processing event without idle callback.');\n this.addCompressedEvent(event, sessionId);\n }\n }\n\n // Process the task queue during idle time\n public processQueue(idleDeadline: IdleDeadline): void {\n // Process tasks while there's idle time or until the max number of tasks is reached\n while (this.taskQueue.length > 0 && (idleDeadline.timeRemaining() > 0 || idleDeadline.didTimeout)) {\n const task = this.taskQueue.shift();\n if (task) {\n const { event, sessionId } = task;\n this.addCompressedEvent(event, sessionId);\n }\n }\n\n // If there are still tasks in the queue, schedule the next idle callback\n if (this.taskQueue.length > 0) {\n requestIdleCallback(\n (idleDeadline) => {\n this.processQueue(idleDeadline);\n },\n { timeout: this.timeout },\n );\n } else {\n this.isProcessing = false;\n }\n }\n\n compressEvent = (event: eventWithTime) => {\n const packedEvent = pack(event);\n return JSON.stringify(packedEvent);\n };\n\n private addCompressedEventToManager = (compressedEvent: string, sessionId: string | number) => {\n if (this.eventsManager && this.deviceId) {\n this.eventsManager.addEvent({\n event: { type: 'replay', data: compressedEvent },\n sessionId,\n deviceId: this.deviceId,\n });\n }\n };\n\n public addCompressedEvent = (event: eventWithTime, sessionId: string | number) => {\n if (this.worker) {\n // This indirectly compresses the event.\n this.worker.postMessage({ event, sessionId });\n } else {\n const compressedEvent = this.compressEvent(event);\n this.addCompressedEventToManager(compressedEvent, sessionId);\n }\n };\n\n public terminate = () => {\n this.worker?.terminate();\n };\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"events-idb-store.d.ts","sourceRoot":"","sources":["../../../src/events/events-idb-store.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"events-idb-store.d.ts","sourceRoot":"","sources":["../../../src/events/events-idb-store.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAU,MAAM,KAAK,CAAC;AAErD,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AACtF,OAAO,EAAE,eAAe,EAAE,YAAY,IAAI,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAGxF,eAAO,MAAM,kBAAkB,2BAA2B,CAAC;AAC3D,eAAO,MAAM,kBAAkB,oBAAoB,CAAC;AACpD,eAAO,MAAM,eAAe,iBAAiB,CAAC;AAE9C,MAAM,WAAW,eAAgB,SAAQ,QAAQ;IAC/C,sBAAsB,EAAE;QACtB,GAAG,EAAE,MAAM,CAAC;QACZ,KAAK,EAAE,IAAI,CAAC,sBAAsB,CAAC,MAAM,CAAC,EAAE,YAAY,CAAC,CAAC;KAC3D,CAAC;IACF,eAAe,EAAE;QACf,GAAG,EAAE,MAAM,CAAC;QACZ,KAAK,EAAE,IAAI,CAAC,sBAAsB,CAAC,MAAM,CAAC,EAAE,YAAY,CAAC,CAAC;QAC1D,OAAO,EAAE;YAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAAA;SAAE,CAAC;KACzC,CAAC;CACH;AAED,eAAO,MAAM,oBAAoB,QAAgB,QAAQ,WAAW,GAAG,IAAI,CA4B1E,CAAC;AAUF,eAAO,MAAM,kBAAkB,OAAQ,aAAa,eAAe,CAAC;;;CAmBnE,CAAC;AAEF,eAAO,MAAM,WAAW,WAAkB,MAAM,2CAI/C,CAAC;AAEF,KAAK,YAAY,GAAG;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,EAAE,EAAE,YAAY,CAAC,eAAe,CAAC,CAAC;CACnC,GAAG,gBAAgB,CAAC;AAErB,qBAAa,2BAA4B,SAAQ,eAAe,CAAC,MAAM,CAAC;IACtE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAgC;gBAEvC,IAAI,EAAE,YAAY;WAMjB,GAAG,CACd,IAAI,EAAE,SAAS,EACf,IAAI,EAAE,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,EAC9B,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,GAC1B,OAAO,CAAC,2BAA2B,GAAG,SAAS,CAAC;IAiB7C,wBAAwB,CAAC,SAAS,CAAC,EAAE,MAAM;IAiBjD,kBAAkB,QAAa,QAAQ,uBAAuB,MAAM,CAAC,EAAE,GAAG,SAAS,CAAC,CAmBlF;IAEF,oBAAoB,cAAqB,MAAM;;;;mBA0B7C;IAEF,yBAAyB,cAAqB,MAAM,SAAS,MAAM;;;;mBAuCjE;IAEF,kBAAkB,cAAqB,MAAM,iDAW3C;IAEF,yBAAyB,eAAsB,MAAM,eAAe,MAAM,mBASxE;IAEF,yBAAyB,eAAsB,MAAM,GAAG,MAAM,mBA6E5D;CACH"}
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.SessionReplayEventsIDBStore = exports.createStore = exports.defineObjectStores = exports.keyValDatabaseExists = exports.remoteConfigKey = exports.sequencesToSendKey = exports.currentSequenceKey = void 0;
|
|
4
4
|
var tslib_1 = require("tslib");
|
|
5
|
-
var analytics_client_common_1 = require("@amplitude/analytics-client-common");
|
|
6
5
|
var analytics_core_1 = require("@amplitude/analytics-core");
|
|
7
6
|
var idb_1 = require("idb");
|
|
8
7
|
var messages_1 = require("../messages");
|
|
@@ -12,7 +11,7 @@ exports.currentSequenceKey = 'sessionCurrentSequence';
|
|
|
12
11
|
exports.sequencesToSendKey = 'sequencesToSend';
|
|
13
12
|
exports.remoteConfigKey = 'remoteConfig';
|
|
14
13
|
var keyValDatabaseExists = function () {
|
|
15
|
-
var globalScope = (0,
|
|
14
|
+
var globalScope = (0, analytics_core_1.getGlobalScope)();
|
|
16
15
|
return new Promise(function (resolve, reject) {
|
|
17
16
|
if (!globalScope) {
|
|
18
17
|
return reject(new Error('Global scope not found'));
|
|
@@ -344,7 +343,7 @@ var SessionReplayEventsIDBStore = /** @class */ (function (_super) {
|
|
|
344
343
|
return [4 /*yield*/, transitionPromise];
|
|
345
344
|
case 3:
|
|
346
345
|
_a.sent();
|
|
347
|
-
globalScope = (0,
|
|
346
|
+
globalScope = (0, analytics_core_1.getGlobalScope)();
|
|
348
347
|
if (globalScope) {
|
|
349
348
|
globalScope.indexedDB.deleteDatabase('keyval-store');
|
|
350
349
|
}
|