@amplitude/session-replay-browser 1.22.11 → 1.23.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/lib/cjs/config/joined-config.d.ts.map +1 -1
- package/lib/cjs/config/joined-config.js +23 -19
- package/lib/cjs/config/joined-config.js.map +1 -1
- package/lib/cjs/config/local-config.d.ts.map +1 -1
- package/lib/cjs/config/local-config.js +8 -0
- package/lib/cjs/config/local-config.js.map +1 -1
- package/lib/cjs/config/types.d.ts +18 -0
- package/lib/cjs/config/types.d.ts.map +1 -1
- package/lib/cjs/config/types.js.map +1 -1
- package/lib/cjs/helpers.d.ts +4 -8
- package/lib/cjs/helpers.d.ts.map +1 -1
- package/lib/cjs/helpers.js +52 -3
- package/lib/cjs/helpers.js.map +1 -1
- package/lib/cjs/hooks/click.d.ts +2 -0
- package/lib/cjs/hooks/click.d.ts.map +1 -1
- package/lib/cjs/hooks/click.js +4 -2
- package/lib/cjs/hooks/click.js.map +1 -1
- package/lib/cjs/hooks/scroll.d.ts +2 -1
- package/lib/cjs/hooks/scroll.d.ts.map +1 -1
- package/lib/cjs/hooks/scroll.js +6 -3
- package/lib/cjs/hooks/scroll.js.map +1 -1
- package/lib/cjs/session-replay.d.ts.map +1 -1
- package/lib/cjs/session-replay.js +19 -13
- package/lib/cjs/session-replay.js.map +1 -1
- package/lib/cjs/version.d.ts +1 -1
- package/lib/cjs/version.d.ts.map +1 -1
- package/lib/cjs/version.js +1 -1
- package/lib/cjs/version.js.map +1 -1
- package/lib/esm/config/joined-config.d.ts.map +1 -1
- package/lib/esm/config/joined-config.js +23 -19
- package/lib/esm/config/joined-config.js.map +1 -1
- package/lib/esm/config/local-config.d.ts.map +1 -1
- package/lib/esm/config/local-config.js +8 -0
- package/lib/esm/config/local-config.js.map +1 -1
- package/lib/esm/config/types.d.ts +18 -0
- package/lib/esm/config/types.d.ts.map +1 -1
- package/lib/esm/config/types.js.map +1 -1
- package/lib/esm/helpers.d.ts +4 -8
- package/lib/esm/helpers.d.ts.map +1 -1
- package/lib/esm/helpers.js +50 -3
- package/lib/esm/helpers.js.map +1 -1
- package/lib/esm/hooks/click.d.ts +2 -0
- package/lib/esm/hooks/click.d.ts.map +1 -1
- package/lib/esm/hooks/click.js +4 -2
- package/lib/esm/hooks/click.js.map +1 -1
- package/lib/esm/hooks/scroll.d.ts +2 -1
- package/lib/esm/hooks/scroll.d.ts.map +1 -1
- package/lib/esm/hooks/scroll.js +6 -3
- package/lib/esm/hooks/scroll.js.map +1 -1
- package/lib/esm/session-replay.d.ts.map +1 -1
- package/lib/esm/session-replay.js +20 -14
- package/lib/esm/session-replay.js.map +1 -1
- package/lib/esm/version.d.ts +1 -1
- package/lib/esm/version.d.ts.map +1 -1
- package/lib/esm/version.js +1 -1
- package/lib/esm/version.js.map +1 -1
- package/lib/scripts/session-replay-browser-esm.js +1 -1
- package/lib/scripts/session-replay-browser-esm.js.gz +0 -0
- package/lib/scripts/session-replay-browser-esm.js.map +1 -1
- package/lib/scripts/session-replay-browser-min.js +1 -1
- package/lib/scripts/session-replay-browser-min.js.gz +0 -0
- package/lib/scripts/session-replay-browser-min.js.map +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local-config.js","sourceRoot":"","sources":["../../../src/config/local-config.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AACrF,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AASxE,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"local-config.js","sourceRoot":"","sources":["../../../src/config/local-config.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AACrF,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AASxE,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAEpD,MAAM,CAAC,IAAM,gBAAgB,GAAG,cAAM,OAAA,CAAC;IACrC,eAAe,EAAE,CAAC;IAClB,QAAQ,EAAE,QAAQ,CAAC,IAAI;IACvB,cAAc,EAAE,IAAI,MAAM,EAAE;IAC5B,iBAAiB,EAAE,IAAI,cAAc,EAAE;CACxC,CAAC,EALoC,CAKpC,CAAC;AAEH;IAA8C,4CAAM;IAclD,kCAAY,MAAc,EAAE,OAA6B;QAAzD,iBAwCC;;QAvCC,IAAM,aAAa,GAAG,gBAAgB,EAAE,CAAC;gBACzC,sCACE,iBAAiB,EAAE,aAAa,CAAC,iBAAiB,EAClD,cAAc,EAAE,IAAI,kBAAkB,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,mBAAmB,CAAC;QAC5D,KAAI,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,mBAAmB,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,iBAAiB,EAAE;YAC7B,KAAI,CAAC,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC;YAEnD,+FAA+F;YAC/F,IAAI,KAAI,CAAC,iBAAiB,CAAC,cAAc,EAAE;gBACzC,sBAAsB,CAAC,KAAI,CAAC,iBAAiB,CAAC,cAAc,CAAC,CAAC;aAC/D;SACF;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,AAvDD,CAA8C,MAAM,GAuDnD","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';\nimport { validateUGCFilterRules } from '../helpers';\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.interactionConfig) {\n this.interactionConfig = options.interactionConfig;\n\n // validate ugcFilterRules, throw error if invalid - throw error at the beginning of the config\n if (this.interactionConfig.ugcFilterRules) {\n validateUGCFilterRules(this.interactionConfig.ugcFilterRules);\n }\n }\n if (options.debugMode) {\n this.debugMode = options.debugMode;\n }\n if (options.experimental) {\n this.experimental = options.experimental;\n }\n }\n}\n"]}
|
|
@@ -8,6 +8,10 @@ export interface InteractionConfig {
|
|
|
8
8
|
trackEveryNms?: number;
|
|
9
9
|
enabled: boolean;
|
|
10
10
|
batch: boolean;
|
|
11
|
+
/**
|
|
12
|
+
* UGC filter rules.
|
|
13
|
+
*/
|
|
14
|
+
ugcFilterRules?: UGCFilterRule[];
|
|
11
15
|
}
|
|
12
16
|
export interface LoggingConfig {
|
|
13
17
|
console: {
|
|
@@ -37,6 +41,19 @@ export type PrivacyConfig = {
|
|
|
37
41
|
maskSelector?: string[];
|
|
38
42
|
unmaskSelector?: string[];
|
|
39
43
|
};
|
|
44
|
+
/**
|
|
45
|
+
* UGC filter rule.
|
|
46
|
+
*/
|
|
47
|
+
export type UGCFilterRule = {
|
|
48
|
+
/**
|
|
49
|
+
* The selector of the UGC element.
|
|
50
|
+
*/
|
|
51
|
+
selector: string;
|
|
52
|
+
/**
|
|
53
|
+
* The replacement text for the UGC element.
|
|
54
|
+
*/
|
|
55
|
+
replacement: string;
|
|
56
|
+
};
|
|
40
57
|
export interface SessionReplayLocalConfig extends IConfig {
|
|
41
58
|
apiKey: string;
|
|
42
59
|
loggerProvider: ILogger;
|
|
@@ -109,6 +126,7 @@ export interface SessionReplayLocalConfig extends IConfig {
|
|
|
109
126
|
*/
|
|
110
127
|
useWebWorker: boolean;
|
|
111
128
|
};
|
|
129
|
+
interactionConfig?: InteractionConfig;
|
|
112
130
|
}
|
|
113
131
|
export interface SessionReplayJoinedConfig extends SessionReplayLocalConfig {
|
|
114
132
|
captureEnabled?: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/config/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAC;AACvE,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAEvE,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,iBAAiB;IAChC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;
|
|
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":"
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/config/types.ts"],"names":[],"mappings":"AA8CA,MAAM,CAAC,IAAM,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 * UGC filter rules.\n */\n ugcFilterRules?: UGCFilterRule[];\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\n/**\n * UGC filter rule.\n */\nexport type UGCFilterRule = {\n /**\n * The selector of the UGC element.\n */\n selector: string;\n /**\n * The replacement text for the UGC element.\n */\n replacement: 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 interactionConfig?: InteractionConfig;\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 SessionReplayConfigs {\n localConfig: SessionReplayLocalConfig;\n joinedConfig: SessionReplayJoinedConfig;\n remoteConfig: SessionReplayRemoteConfig | undefined;\n}\nexport interface SessionReplayJoinedConfigGenerator {\n generateJoinedConfig: (sessionId?: string | number) => Promise<SessionReplayConfigs>;\n}\n\nexport interface SessionReplayMetadata {\n remoteConfig: SessionReplayRemoteConfig | undefined;\n localConfig: SessionReplayLocalConfig;\n joinedConfig: SessionReplayJoinedConfig;\n framework?: {\n name: string;\n version: string;\n };\n sessionId: string | number | undefined;\n hashValue?: number;\n sampleRate: number;\n replaySDKType: string | null;\n replaySDKVersion: string | undefined;\n standaloneSDKType: string;\n standaloneSDKVersion: string | undefined;\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/esm/helpers.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ServerZone } from '@amplitude/analytics-core';
|
|
2
|
-
import { PrivacyConfig, SessionReplayJoinedConfig } from './config/types';
|
|
2
|
+
import { PrivacyConfig, SessionReplayJoinedConfig, UGCFilterRule } from './config/types';
|
|
3
3
|
import { StorageData } from './typings/session-replay';
|
|
4
4
|
export declare const maskFn: (elementType: 'text' | 'input', config?: PrivacyConfig) => (text: string, element: HTMLElement | null) => string;
|
|
5
5
|
export declare const generateHashCode: (str: string) => number;
|
|
@@ -7,19 +7,15 @@ export declare const isSessionInSample: (sessionId: string | number, sampleRate:
|
|
|
7
7
|
export declare const getCurrentUrl: () => string;
|
|
8
8
|
export declare const generateSessionReplayId: (sessionId: string | number, deviceId: string) => string;
|
|
9
9
|
export declare const getServerUrl: (serverZone?: keyof typeof ServerZone, trackServerUrl?: string) => string;
|
|
10
|
+
export declare const validateUGCFilterRules: (ugcFilterRules: UGCFilterRule[]) => void;
|
|
11
|
+
export declare const getPageUrl: (pageUrl: string, ugcFilterRules: UGCFilterRule[]) => string;
|
|
10
12
|
export declare const getStorageSize: () => Promise<StorageData>;
|
|
11
13
|
export declare const getDebugConfig: (config: SessionReplayJoinedConfig) => {
|
|
12
14
|
captureEnabled?: boolean | undefined;
|
|
13
15
|
interactionConfig?: import("./config/types").InteractionConfig | undefined;
|
|
14
16
|
loggingConfig?: import("./config/types").LoggingConfig | undefined;
|
|
15
17
|
apiKey: string;
|
|
16
|
-
loggerProvider: import("@amplitude/analytics-core").ILogger;
|
|
17
|
-
* Checks if the given element set to be masked by rrweb
|
|
18
|
-
*
|
|
19
|
-
* Priority is:
|
|
20
|
-
* 1. [In code] Element/class based masking/unmasking <> [Config based] Selector based masking/unmasking
|
|
21
|
-
* 2. Use app defaults
|
|
22
|
-
*/
|
|
18
|
+
loggerProvider: import("@amplitude/analytics-core").ILogger;
|
|
23
19
|
logLevel: import("@amplitude/analytics-core").LogLevel;
|
|
24
20
|
flushMaxRetries: number;
|
|
25
21
|
sampleRate: number;
|
package/lib/esm/helpers.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACvE,OAAO,EAAiC,aAAa,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACvE,OAAO,EAAiC,aAAa,EAAE,yBAAyB,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AASxH,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAqFvD,eAAO,MAAM,MAAM,gBACH,MAAM,GAAG,OAAO,WAAW,aAAa,YAC/C,MAAM,WAAW,WAAW,GAAG,IAAI,KAAG,MAE5C,CAAC;AAEJ,eAAO,MAAM,gBAAgB,QAAkB,MAAM,WASpD,CAAC;AAEF,eAAO,MAAM,iBAAiB,cAAwB,MAAM,GAAG,MAAM,cAAc,MAAM,YAMxF,CAAC;AAEF,eAAO,MAAM,aAAa,cAGzB,CAAC;AAEF,eAAO,MAAM,uBAAuB,cAAe,MAAM,GAAG,MAAM,YAAY,MAAM,KAAG,MAEtF,CAAC;AAEF,eAAO,MAAM,YAAY,gBAAiB,MAAM,iBAAiB,mBAAmB,MAAM,KAAG,MAc5F,CAAC;AAmBF,eAAO,MAAM,sBAAsB,mBAAoB,aAAa,EAAE,SAUrE,CAAC;AAEF,eAAO,MAAM,UAAU,YAAa,MAAM,kBAAkB,aAAa,EAAE,WAW1E,CAAC;AAEF,eAAO,MAAM,cAAc,QAAa,QAAQ,WAAW,CAa1D,CAAC;AAEF,eAAO,MAAM,cAAc,WAAY,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAO/D,CAAC"}
|
package/lib/esm/helpers.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { __assign, __awaiter, __generator } from "tslib";
|
|
1
|
+
import { __assign, __awaiter, __generator, __values } from "tslib";
|
|
2
2
|
import { getGlobalScope, ServerZone } from '@amplitude/analytics-core';
|
|
3
3
|
import { DEFAULT_MASK_LEVEL } from './config/types';
|
|
4
4
|
import { KB_SIZE, MASK_TEXT_CLASS, SESSION_REPLAY_EU_URL, SESSION_REPLAY_SERVER_URL, SESSION_REPLAY_STAGING_URL, UNMASK_TEXT_CLASS, } from './constants';
|
|
@@ -109,8 +109,55 @@ export var getServerUrl = function (serverZone, trackServerUrl) {
|
|
|
109
109
|
}
|
|
110
110
|
return SESSION_REPLAY_SERVER_URL;
|
|
111
111
|
};
|
|
112
|
+
var isValidGlobUrl = function (globUrl) {
|
|
113
|
+
if (typeof globUrl !== 'string' || globUrl.trim() === '')
|
|
114
|
+
return false;
|
|
115
|
+
var urlPattern = /^\/|^https?:\/\/[^\s]+$/;
|
|
116
|
+
if (!urlPattern.test(globUrl))
|
|
117
|
+
return false;
|
|
118
|
+
return true;
|
|
119
|
+
};
|
|
120
|
+
var globToRegex = function (glob) {
|
|
121
|
+
// Escape special regex characters, then convert globs
|
|
122
|
+
var escaped = glob
|
|
123
|
+
.replace(/[.+^${}()|[\]\\]/g, '\\$&') // Escape regex specials
|
|
124
|
+
.replace(/\*/g, '.*') // Convert * to .*
|
|
125
|
+
.replace(/\?/g, '.'); // Convert ? to .
|
|
126
|
+
return new RegExp("^".concat(escaped, "$"));
|
|
127
|
+
};
|
|
128
|
+
export var validateUGCFilterRules = function (ugcFilterRules) {
|
|
129
|
+
// validate ugcFilterRules
|
|
130
|
+
if (!ugcFilterRules.every(function (rule) { return typeof rule.selector === 'string' && typeof rule.replacement === 'string'; })) {
|
|
131
|
+
throw new Error('ugcFilterRules must be an array of objects with selector and replacement properties');
|
|
132
|
+
}
|
|
133
|
+
// validate ugcFilterRules are valid globs
|
|
134
|
+
if (!ugcFilterRules.every(function (rule) { return isValidGlobUrl(rule.selector); })) {
|
|
135
|
+
throw new Error('ugcFilterRules must be an array of objects with valid globs');
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
export var getPageUrl = function (pageUrl, ugcFilterRules) {
|
|
139
|
+
var e_1, _a;
|
|
140
|
+
try {
|
|
141
|
+
// apply ugcFilterRules, order is important, first rule wins
|
|
142
|
+
for (var ugcFilterRules_1 = __values(ugcFilterRules), ugcFilterRules_1_1 = ugcFilterRules_1.next(); !ugcFilterRules_1_1.done; ugcFilterRules_1_1 = ugcFilterRules_1.next()) {
|
|
143
|
+
var rule = ugcFilterRules_1_1.value;
|
|
144
|
+
var regex = globToRegex(rule.selector);
|
|
145
|
+
if (regex.test(pageUrl)) {
|
|
146
|
+
return pageUrl.replace(regex, rule.replacement);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
151
|
+
finally {
|
|
152
|
+
try {
|
|
153
|
+
if (ugcFilterRules_1_1 && !ugcFilterRules_1_1.done && (_a = ugcFilterRules_1.return)) _a.call(ugcFilterRules_1);
|
|
154
|
+
}
|
|
155
|
+
finally { if (e_1) throw e_1.error; }
|
|
156
|
+
}
|
|
157
|
+
return pageUrl;
|
|
158
|
+
};
|
|
112
159
|
export var getStorageSize = function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
113
|
-
var globalScope, _a, usage, quota, usageDetails, totalStorageSize, percentOfQuota,
|
|
160
|
+
var globalScope, _a, usage, quota, usageDetails, totalStorageSize, percentOfQuota, e_2;
|
|
114
161
|
return __generator(this, function (_b) {
|
|
115
162
|
switch (_b.label) {
|
|
116
163
|
case 0:
|
|
@@ -125,7 +172,7 @@ export var getStorageSize = function () { return __awaiter(void 0, void 0, void
|
|
|
125
172
|
return [2 /*return*/, { totalStorageSize: totalStorageSize, percentOfQuota: percentOfQuota, usageDetails: JSON.stringify(usageDetails) }];
|
|
126
173
|
case 2: return [3 /*break*/, 4];
|
|
127
174
|
case 3:
|
|
128
|
-
|
|
175
|
+
e_2 = _b.sent();
|
|
129
176
|
return [3 /*break*/, 4];
|
|
130
177
|
case 4: return [2 /*return*/, { totalStorageSize: 0, percentOfQuota: 0, usageDetails: '' }];
|
|
131
178
|
}
|
package/lib/esm/helpers.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/helpers.ts"],"names":[],"mappings":"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","sourcesContent":["import { getGlobalScope, ServerZone } from '@amplitude/analytics-core';\nimport { DEFAULT_MASK_LEVEL, MaskLevel, PrivacyConfig, SessionReplayJoinedConfig } from './config/types';\nimport {\n KB_SIZE,\n MASK_TEXT_CLASS,\n SESSION_REPLAY_EU_URL,\n SESSION_REPLAY_SERVER_URL,\n SESSION_REPLAY_STAGING_URL,\n UNMASK_TEXT_CLASS,\n} from './constants';\nimport { StorageData } from './typings/session-replay';\nimport { getInputType } from './utils/get-input-type';\n\ntype ChromeStorageEstimate = {\n quota?: number;\n usage?: number;\n usageDetails?: { [key: string]: number };\n};\n\n/**\n * Light: Subset of inputs\n * Medium: All inputs\n * Conservative: All inputs and all texts\n */\nconst isMaskedForLevel = (elementType: 'input' | 'text', level: MaskLevel, element: HTMLElement | null): boolean => {\n switch (level) {\n case 'light': {\n if (elementType !== 'input') {\n return true;\n }\n\n const inputType = element ? getInputType(element) : '';\n /* istanbul ignore if */ // TODO(lew): For some reason it's impossible to test this.\n if (!inputType) {\n return false;\n }\n\n if (['password', 'hidden', 'email', 'tel'].includes(inputType)) {\n return true;\n }\n\n if ((element as HTMLInputElement).autocomplete.startsWith('cc-')) {\n return true;\n }\n\n return false;\n }\n case 'medium':\n case 'conservative':\n return true;\n default:\n return isMaskedForLevel(elementType, DEFAULT_MASK_LEVEL, element);\n }\n};\n\n/**\n * Checks if the given element set to be masked by rrweb\n *\n * Priority is:\n * 1. [In code] Element/class based masking/unmasking <> [Config based] Selector based masking/unmasking\n * 2. Use app defaults\n */\nconst isMasked = (\n elementType: 'input' | 'text',\n config: PrivacyConfig = { defaultMaskLevel: DEFAULT_MASK_LEVEL },\n element: HTMLElement | null,\n): boolean => {\n if (element) {\n // Element or parent is explicitly instrumented in code to mask\n if (element.closest('.' + MASK_TEXT_CLASS)) {\n return true;\n }\n\n // Config has override for mask\n const shouldMask = (config.maskSelector ?? []).some((selector) => element.closest(selector));\n if (shouldMask) {\n return true;\n }\n\n // Code or config has override to unmask\n if (element.closest('.' + UNMASK_TEXT_CLASS)) {\n return false;\n }\n\n // Here we are probably sent an element, but we want to match if they have a\n // parent with an unmask selector.\n const shouldUnmask = (config.unmaskSelector ?? []).some((selector) => element.closest(selector));\n if (shouldUnmask) {\n return false;\n }\n }\n\n return isMaskedForLevel(elementType, config.defaultMaskLevel ?? DEFAULT_MASK_LEVEL, element);\n};\n\nexport const maskFn =\n (elementType: 'text' | 'input', config?: PrivacyConfig) =>\n (text: string, element: HTMLElement | null): string => {\n return isMasked(elementType, config, element) ? text.replace(/[^\\s]/g, '*') : text;\n };\n\nexport const generateHashCode = function (str: string) {\n let hash = 0;\n if (str.length === 0) return hash;\n for (let i = 0; i < str.length; i++) {\n const chr = str.charCodeAt(i);\n hash = (hash << 5) - hash + chr;\n hash |= 0;\n }\n return hash;\n};\n\nexport const isSessionInSample = function (sessionId: string | number, sampleRate: number) {\n const hashNumber = generateHashCode(sessionId.toString());\n const absHash = Math.abs(hashNumber);\n const absHashMultiply = absHash * 31;\n const mod = absHashMultiply % 1000000;\n return mod / 1000000 < sampleRate;\n};\n\nexport const getCurrentUrl = () => {\n const globalScope = getGlobalScope();\n return globalScope?.location ? globalScope.location.href : '';\n};\n\nexport const generateSessionReplayId = (sessionId: string | number, deviceId: string): string => {\n return `${deviceId}/${sessionId}`;\n};\n\nexport const getServerUrl = (serverZone?: keyof typeof ServerZone, trackServerUrl?: string): string => {\n if (trackServerUrl) {\n return trackServerUrl;\n }\n\n if (serverZone === ServerZone.STAGING) {\n return SESSION_REPLAY_STAGING_URL;\n }\n\n if (serverZone === ServerZone.EU) {\n return SESSION_REPLAY_EU_URL;\n }\n\n return SESSION_REPLAY_SERVER_URL;\n};\n\nexport const getStorageSize = async (): Promise<StorageData> => {\n try {\n const globalScope = getGlobalScope();\n if (globalScope) {\n const { usage, quota, usageDetails }: ChromeStorageEstimate = await globalScope.navigator.storage.estimate();\n const totalStorageSize = usage ? Math.round(usage / KB_SIZE) : 0;\n const percentOfQuota = usage && quota ? Math.round((usage / quota + Number.EPSILON) * 1000) / 1000 : 0;\n return { totalStorageSize, percentOfQuota, usageDetails: JSON.stringify(usageDetails) };\n }\n } catch (e) {\n // swallow\n }\n return { totalStorageSize: 0, percentOfQuota: 0, usageDetails: '' };\n};\n\nexport const getDebugConfig = (config: SessionReplayJoinedConfig) => {\n const debugConfig = {\n ...config,\n };\n const { apiKey } = debugConfig;\n debugConfig.apiKey = `****${apiKey.substring(apiKey.length - 4)}`;\n return debugConfig;\n};\n"]}
|
|
1
|
+
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/helpers.ts"],"names":[],"mappings":"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","sourcesContent":["import { getGlobalScope, ServerZone } from '@amplitude/analytics-core';\nimport { DEFAULT_MASK_LEVEL, MaskLevel, PrivacyConfig, SessionReplayJoinedConfig, UGCFilterRule } from './config/types';\nimport {\n KB_SIZE,\n MASK_TEXT_CLASS,\n SESSION_REPLAY_EU_URL,\n SESSION_REPLAY_SERVER_URL,\n SESSION_REPLAY_STAGING_URL,\n UNMASK_TEXT_CLASS,\n} from './constants';\nimport { StorageData } from './typings/session-replay';\nimport { getInputType } from './utils/get-input-type';\n\ntype ChromeStorageEstimate = {\n quota?: number;\n usage?: number;\n usageDetails?: { [key: string]: number };\n};\n\n/**\n * Light: Subset of inputs\n * Medium: All inputs\n * Conservative: All inputs and all texts\n */\nconst isMaskedForLevel = (elementType: 'input' | 'text', level: MaskLevel, element: HTMLElement | null): boolean => {\n switch (level) {\n case 'light': {\n if (elementType !== 'input') {\n return true;\n }\n\n const inputType = element ? getInputType(element) : '';\n /* istanbul ignore if */ // TODO(lew): For some reason it's impossible to test this.\n if (!inputType) {\n return false;\n }\n\n if (['password', 'hidden', 'email', 'tel'].includes(inputType)) {\n return true;\n }\n\n if ((element as HTMLInputElement).autocomplete.startsWith('cc-')) {\n return true;\n }\n\n return false;\n }\n case 'medium':\n case 'conservative':\n return true;\n default:\n return isMaskedForLevel(elementType, DEFAULT_MASK_LEVEL, element);\n }\n};\n\n/**\n * Checks if the given element set to be masked by rrweb\n *\n * Priority is:\n * 1. [In code] Element/class based masking/unmasking <> [Config based] Selector based masking/unmasking\n * 2. Use app defaults\n */\nconst isMasked = (\n elementType: 'input' | 'text',\n config: PrivacyConfig = { defaultMaskLevel: DEFAULT_MASK_LEVEL },\n element: HTMLElement | null,\n): boolean => {\n if (element) {\n // Element or parent is explicitly instrumented in code to mask\n if (element.closest('.' + MASK_TEXT_CLASS)) {\n return true;\n }\n\n // Config has override for mask\n const shouldMask = (config.maskSelector ?? []).some((selector) => element.closest(selector));\n if (shouldMask) {\n return true;\n }\n\n // Code or config has override to unmask\n if (element.closest('.' + UNMASK_TEXT_CLASS)) {\n return false;\n }\n\n // Here we are probably sent an element, but we want to match if they have a\n // parent with an unmask selector.\n const shouldUnmask = (config.unmaskSelector ?? []).some((selector) => element.closest(selector));\n if (shouldUnmask) {\n return false;\n }\n }\n\n return isMaskedForLevel(elementType, config.defaultMaskLevel ?? DEFAULT_MASK_LEVEL, element);\n};\n\nexport const maskFn =\n (elementType: 'text' | 'input', config?: PrivacyConfig) =>\n (text: string, element: HTMLElement | null): string => {\n return isMasked(elementType, config, element) ? text.replace(/[^\\s]/g, '*') : text;\n };\n\nexport const generateHashCode = function (str: string) {\n let hash = 0;\n if (str.length === 0) return hash;\n for (let i = 0; i < str.length; i++) {\n const chr = str.charCodeAt(i);\n hash = (hash << 5) - hash + chr;\n hash |= 0;\n }\n return hash;\n};\n\nexport const isSessionInSample = function (sessionId: string | number, sampleRate: number) {\n const hashNumber = generateHashCode(sessionId.toString());\n const absHash = Math.abs(hashNumber);\n const absHashMultiply = absHash * 31;\n const mod = absHashMultiply % 1000000;\n return mod / 1000000 < sampleRate;\n};\n\nexport const getCurrentUrl = () => {\n const globalScope = getGlobalScope();\n return globalScope?.location ? globalScope.location.href : '';\n};\n\nexport const generateSessionReplayId = (sessionId: string | number, deviceId: string): string => {\n return `${deviceId}/${sessionId}`;\n};\n\nexport const getServerUrl = (serverZone?: keyof typeof ServerZone, trackServerUrl?: string): string => {\n if (trackServerUrl) {\n return trackServerUrl;\n }\n\n if (serverZone === ServerZone.STAGING) {\n return SESSION_REPLAY_STAGING_URL;\n }\n\n if (serverZone === ServerZone.EU) {\n return SESSION_REPLAY_EU_URL;\n }\n\n return SESSION_REPLAY_SERVER_URL;\n};\n\nconst isValidGlobUrl = (globUrl: string): boolean => {\n if (typeof globUrl !== 'string' || globUrl.trim() === '') return false;\n const urlPattern = /^\\/|^https?:\\/\\/[^\\s]+$/;\n if (!urlPattern.test(globUrl)) return false;\n return true;\n};\n\nconst globToRegex = (glob: string): RegExp => {\n // Escape special regex characters, then convert globs\n const escaped = glob\n .replace(/[.+^${}()|[\\]\\\\]/g, '\\\\$&') // Escape regex specials\n .replace(/\\*/g, '.*') // Convert * to .*\n .replace(/\\?/g, '.'); // Convert ? to .\n\n return new RegExp(`^${escaped}$`);\n};\n\nexport const validateUGCFilterRules = (ugcFilterRules: UGCFilterRule[]) => {\n // validate ugcFilterRules\n if (!ugcFilterRules.every((rule) => typeof rule.selector === 'string' && typeof rule.replacement === 'string')) {\n throw new Error('ugcFilterRules must be an array of objects with selector and replacement properties');\n }\n\n // validate ugcFilterRules are valid globs\n if (!ugcFilterRules.every((rule) => isValidGlobUrl(rule.selector))) {\n throw new Error('ugcFilterRules must be an array of objects with valid globs');\n }\n};\n\nexport const getPageUrl = (pageUrl: string, ugcFilterRules: UGCFilterRule[]) => {\n // apply ugcFilterRules, order is important, first rule wins\n for (const rule of ugcFilterRules) {\n const regex = globToRegex(rule.selector);\n\n if (regex.test(pageUrl)) {\n return pageUrl.replace(regex, rule.replacement);\n }\n }\n\n return pageUrl;\n};\n\nexport const getStorageSize = async (): Promise<StorageData> => {\n try {\n const globalScope = getGlobalScope();\n if (globalScope) {\n const { usage, quota, usageDetails }: ChromeStorageEstimate = await globalScope.navigator.storage.estimate();\n const totalStorageSize = usage ? Math.round(usage / KB_SIZE) : 0;\n const percentOfQuota = usage && quota ? Math.round((usage / quota + Number.EPSILON) * 1000) / 1000 : 0;\n return { totalStorageSize, percentOfQuota, usageDetails: JSON.stringify(usageDetails) };\n }\n } catch (e) {\n // swallow\n }\n return { totalStorageSize: 0, percentOfQuota: 0, usageDetails: '' };\n};\n\nexport const getDebugConfig = (config: SessionReplayJoinedConfig) => {\n const debugConfig = {\n ...config,\n };\n const { apiKey } = debugConfig;\n debugConfig.apiKey = `****${apiKey.substring(apiKey.length - 4)}`;\n return debugConfig;\n};\n"]}
|
package/lib/esm/hooks/click.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { mouseInteractionCallBack } from '@amplitude/rrweb-types';
|
|
|
2
2
|
import { SessionReplayEventsManager as AmplitudeSessionReplayEventsManager } from '../typings/session-replay';
|
|
3
3
|
import { PayloadBatcher } from 'src/track-destination';
|
|
4
4
|
import { ILogger } from '@amplitude/analytics-core';
|
|
5
|
+
import { UGCFilterRule } from 'src/config/types';
|
|
5
6
|
export type ClickEvent = {
|
|
6
7
|
timestamp: number;
|
|
7
8
|
x: number;
|
|
@@ -19,6 +20,7 @@ type Options = {
|
|
|
19
20
|
sessionId: string | number;
|
|
20
21
|
deviceIdFn: () => string | undefined;
|
|
21
22
|
eventsManager: AmplitudeSessionReplayEventsManager<'interaction', string>;
|
|
23
|
+
ugcFilterRules: UGCFilterRule[];
|
|
22
24
|
};
|
|
23
25
|
export declare const clickNonBatcher: PayloadBatcher;
|
|
24
26
|
export declare const clickBatcher: PayloadBatcher;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"click.d.ts","sourceRoot":"","sources":["../../../src/hooks/click.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAqB,MAAM,wBAAwB,CAAC;AAErF,OAAO,EAAE,0BAA0B,IAAI,mCAAmC,EAAE,MAAM,2BAA2B,CAAC;AAC9G,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAEvD,OAAO,EAAkB,OAAO,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"click.d.ts","sourceRoot":"","sources":["../../../src/hooks/click.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAqB,MAAM,wBAAwB,CAAC;AAErF,OAAO,EAAE,0BAA0B,IAAI,mCAAmC,EAAE,MAAM,2BAA2B,CAAC;AAC9G,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAEvD,OAAO,EAAkB,OAAO,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAIjD,MAAM,MAAM,UAAU,GAAG;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,OAAO,CAAC;CACf,CAAC;AAGF,MAAM,MAAM,mBAAmB,GAAG,UAAU,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjE,KAAK,OAAO,GAAG;IACb,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3B,UAAU,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;IACrC,aAAa,EAAE,mCAAmC,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;IAC1E,cAAc,EAAE,aAAa,EAAE,CAAC;CACjC,CAAC;AAIF,eAAO,MAAM,eAAe,EAAE,cAU7B,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,cAyB1B,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,KAAK,wBAoD5D,CAAC"}
|
package/lib/esm/hooks/click.js
CHANGED
|
@@ -3,6 +3,7 @@ import { MouseInteractions } from '@amplitude/rrweb-types';
|
|
|
3
3
|
import { record, utils } from '@amplitude/rrweb';
|
|
4
4
|
import { finder } from '../libs/finder';
|
|
5
5
|
import { getGlobalScope } from '@amplitude/analytics-core';
|
|
6
|
+
import { getPageUrl } from '../helpers';
|
|
6
7
|
var HOUR_IN_MILLISECONDS = 3600000;
|
|
7
8
|
export var clickNonBatcher = function (_a) {
|
|
8
9
|
var version = _a.version, events = _a.events;
|
|
@@ -41,7 +42,7 @@ export var clickBatcher = function (_a) {
|
|
|
41
42
|
return { version: version, events: Object.values(reduced) };
|
|
42
43
|
};
|
|
43
44
|
export var clickHook = function (logger, _a) {
|
|
44
|
-
var eventsManager = _a.eventsManager, sessionId = _a.sessionId, deviceIdFn = _a.deviceIdFn;
|
|
45
|
+
var eventsManager = _a.eventsManager, sessionId = _a.sessionId, deviceIdFn = _a.deviceIdFn, ugcFilterRules = _a.ugcFilterRules;
|
|
45
46
|
return function (e) {
|
|
46
47
|
if (e.type !== MouseInteractions.Click) {
|
|
47
48
|
return;
|
|
@@ -70,13 +71,14 @@ export var clickHook = function (logger, _a) {
|
|
|
70
71
|
}
|
|
71
72
|
}
|
|
72
73
|
var _a = utils.getWindowScroll(globalScope), scrollX = _a.left, scrollY = _a.top;
|
|
74
|
+
var pageUrl = getPageUrl(location.href, ugcFilterRules);
|
|
73
75
|
var event = {
|
|
74
76
|
x: x + scrollX,
|
|
75
77
|
y: y + scrollY,
|
|
76
78
|
selector: selector,
|
|
77
79
|
viewportHeight: innerHeight,
|
|
78
80
|
viewportWidth: innerWidth,
|
|
79
|
-
pageUrl:
|
|
81
|
+
pageUrl: pageUrl,
|
|
80
82
|
timestamp: Date.now(),
|
|
81
83
|
type: 'click',
|
|
82
84
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"click.js","sourceRoot":"","sources":["../../../src/hooks/click.ts"],"names":[],"mappings":";AAAA,OAAO,EAA4B,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AACrF,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAGjD,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AACxC,OAAO,EAAE,cAAc,EAAW,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"click.js","sourceRoot":"","sources":["../../../src/hooks/click.ts"],"names":[],"mappings":"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","sourcesContent":["import { mouseInteractionCallBack, MouseInteractions } from '@amplitude/rrweb-types';\nimport { record, utils } from '@amplitude/rrweb';\nimport { SessionReplayEventsManager as AmplitudeSessionReplayEventsManager } from '../typings/session-replay';\nimport { PayloadBatcher } from 'src/track-destination';\nimport { finder } from '../libs/finder';\nimport { getGlobalScope, ILogger } from '@amplitude/analytics-core';\nimport { UGCFilterRule } from 'src/config/types';\nimport { getPageUrl } from '../helpers';\n\n// exported for testing\nexport type ClickEvent = {\n timestamp: number;\n x: number;\n y: number;\n viewportWidth: number;\n viewportHeight: number;\n pageUrl: string;\n selector?: string;\n type: 'click';\n};\n\n// exported for testing\nexport type ClickEventWithCount = ClickEvent & { count: number };\n\ntype Options = {\n sessionId: string | number;\n deviceIdFn: () => string | undefined;\n eventsManager: AmplitudeSessionReplayEventsManager<'interaction', string>;\n ugcFilterRules: UGCFilterRule[];\n};\n\nconst HOUR_IN_MILLISECONDS = 3_600_000;\n\nexport const clickNonBatcher: PayloadBatcher = ({ version, events }) => {\n const clickEvents: ClickEvent[] = [];\n events.forEach((evt: string) => {\n const record = JSON.parse(evt) as Record<string, unknown>;\n record.count = 1;\n if (record.type === 'click') {\n clickEvents.push(record as ClickEvent);\n }\n });\n return { version, events: clickEvents };\n};\n\nexport const clickBatcher: PayloadBatcher = ({ version, events }) => {\n const clickEvents: ClickEvent[] = [];\n events.forEach((evt: string) => {\n const record = JSON.parse(evt) as Record<string, unknown>;\n if (record.type === 'click') {\n clickEvents.push(record as ClickEvent);\n }\n });\n\n const reduced = clickEvents.reduce<Record<string, ClickEventWithCount>>((prev, curr) => {\n const { x, y, selector, timestamp } = curr;\n\n // round down to nearest hour.\n const hour = timestamp - (timestamp % HOUR_IN_MILLISECONDS);\n\n const k = `${x}:${y}:${selector ?? ''}:${hour}`;\n if (!prev[k]) {\n prev[k] = { ...curr, timestamp: hour, count: 1 };\n } else {\n prev[k].count += 1;\n }\n return prev;\n }, {});\n\n return { version, events: Object.values(reduced) };\n};\n\nexport const clickHook: (logger: ILogger, options: Options) => mouseInteractionCallBack =\n (logger, { eventsManager, sessionId, deviceIdFn, ugcFilterRules }) =>\n (e) => {\n if (e.type !== MouseInteractions.Click) {\n return;\n }\n\n const globalScope = getGlobalScope();\n if (!globalScope) {\n return;\n }\n\n const { location, innerHeight, innerWidth } = globalScope;\n // it only makes sense to send events if a pageUrl exists\n if (!location) {\n return;\n }\n\n const { x, y } = e;\n if (x === undefined || y === undefined) {\n return;\n }\n\n const node = record.mirror.getNode(e.id);\n let selector;\n if (node) {\n try {\n selector = finder(node as Element);\n } catch (err) {\n logger.debug('error resolving selector from finder');\n }\n }\n\n const { left: scrollX, top: scrollY } = utils.getWindowScroll(globalScope as unknown as Window);\n\n const pageUrl = getPageUrl(location.href, ugcFilterRules);\n\n const event: ClickEvent = {\n x: x + scrollX,\n y: y + scrollY,\n selector,\n\n viewportHeight: innerHeight,\n viewportWidth: innerWidth,\n pageUrl,\n timestamp: Date.now(),\n type: 'click',\n };\n const deviceId = deviceIdFn();\n if (deviceId) {\n eventsManager.addEvent({ sessionId, event: { type: 'interaction', data: JSON.stringify(event) }, deviceId });\n }\n };\n"]}
|
|
@@ -31,8 +31,9 @@ export declare class ScrollWatcher {
|
|
|
31
31
|
private _maxScrollWidth;
|
|
32
32
|
private _maxScrollHeight;
|
|
33
33
|
private readonly transport;
|
|
34
|
+
private readonly config;
|
|
34
35
|
static default(context: Omit<SessionReplayDestinationSessionMetadata, 'deviceId'>, config: SessionReplayJoinedConfig): ScrollWatcher;
|
|
35
|
-
constructor(transport: BeaconTransport<ScrollEventPayload>);
|
|
36
|
+
constructor(transport: BeaconTransport<ScrollEventPayload>, config: Pick<SessionReplayJoinedConfig, 'loggerProvider' | 'interactionConfig'>);
|
|
36
37
|
get maxScrollX(): number;
|
|
37
38
|
get maxScrollY(): number;
|
|
38
39
|
get maxScrollWidth(): number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scroll.d.ts","sourceRoot":"","sources":["../../../src/hooks/scroll.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxE,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEtD,OAAO,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAC5D,OAAO,EAAE,uCAAuC,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"scroll.d.ts","sourceRoot":"","sources":["../../../src/hooks/scroll.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxE,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEtD,OAAO,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAC5D,OAAO,EAAE,uCAAuC,EAAE,MAAM,2BAA2B,CAAC;AAKpF,MAAM,MAAM,WAAW,GAAG;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,QAAQ,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,WAAW,EAAE,CAAA;CAAE,CAAC;AAE5E;;;;;;GAMG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,SAAS,CAAc;IAC/B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,gBAAgB,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAsC;IAChE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA0E;IAEjG,MAAM,CAAC,OAAO,CACZ,OAAO,EAAE,IAAI,CAAC,uCAAuC,EAAE,UAAU,CAAC,EAClE,MAAM,EAAE,yBAAyB,GAChC,aAAa;gBAKd,SAAS,EAAE,eAAe,CAAC,kBAAkB,CAAC,EAC9C,MAAM,EAAE,IAAI,CAAC,yBAAyB,EAAE,gBAAgB,GAAG,mBAAmB,CAAC;IAWjF,IAAW,UAAU,IAAI,MAAM,CAE9B;IAED,IAAW,UAAU,IAAI,MAAM,CAE9B;IAED,IAAW,cAAc,IAAI,MAAM,CAElC;IAED,IAAW,eAAe,IAAI,MAAM,CAEnC;IAED,MAAM,CAAC,CAAC,EAAE,cAAc;IAuBxB,IAAI,EAAE,cAAc,CAElB;IAEF,IAAI,EAAE,CAAC,UAAU,EAAE,MAAM,MAAM,GAAG,SAAS,KAAK,CAAC,CAAC,EAAE,mBAAmB,GAAG,KAAK,KAAK,IAAI,CAsBtF;CACH"}
|
package/lib/esm/hooks/scroll.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { utils } from '@amplitude/rrweb';
|
|
2
2
|
import { BeaconTransport } from '../beacon-transport';
|
|
3
3
|
import { getGlobalScope } from '@amplitude/analytics-core';
|
|
4
|
+
import { getPageUrl } from '../helpers';
|
|
4
5
|
var getWindowHeight = utils.getWindowHeight, getWindowWidth = utils.getWindowWidth;
|
|
5
6
|
/**
|
|
6
7
|
* This is intended to watch and update max scroll activity when loaded for a particular page.
|
|
@@ -10,13 +11,14 @@ var getWindowHeight = utils.getWindowHeight, getWindowWidth = utils.getWindowWid
|
|
|
10
11
|
* @see {@link BeaconTransport} for more details on Beacon API usage.
|
|
11
12
|
*/
|
|
12
13
|
var ScrollWatcher = /** @class */ (function () {
|
|
13
|
-
function ScrollWatcher(transport) {
|
|
14
|
+
function ScrollWatcher(transport, config) {
|
|
14
15
|
var _this = this;
|
|
15
16
|
this.timestamp = Date.now();
|
|
16
17
|
this.hook = function (e) {
|
|
17
18
|
_this.update(e);
|
|
18
19
|
};
|
|
19
20
|
this.send = function (deviceIdFn) { return function (_) {
|
|
21
|
+
var _a, _b;
|
|
20
22
|
var deviceId = deviceIdFn();
|
|
21
23
|
var globalScope = getGlobalScope();
|
|
22
24
|
if (globalScope && deviceId) {
|
|
@@ -30,7 +32,7 @@ var ScrollWatcher = /** @class */ (function () {
|
|
|
30
32
|
maxScrollHeight: _this._maxScrollHeight,
|
|
31
33
|
viewportHeight: getWindowHeight(),
|
|
32
34
|
viewportWidth: getWindowWidth(),
|
|
33
|
-
pageUrl: globalScope.location.href,
|
|
35
|
+
pageUrl: getPageUrl(globalScope.location.href, (_b = (_a = _this.config.interactionConfig) === null || _a === void 0 ? void 0 : _a.ugcFilterRules) !== null && _b !== void 0 ? _b : []),
|
|
34
36
|
timestamp: _this.timestamp,
|
|
35
37
|
type: 'scroll',
|
|
36
38
|
},
|
|
@@ -42,10 +44,11 @@ var ScrollWatcher = /** @class */ (function () {
|
|
|
42
44
|
this._maxScrollY = 0;
|
|
43
45
|
this._maxScrollWidth = getWindowWidth();
|
|
44
46
|
this._maxScrollHeight = getWindowHeight();
|
|
47
|
+
this.config = config;
|
|
45
48
|
this.transport = transport;
|
|
46
49
|
}
|
|
47
50
|
ScrollWatcher.default = function (context, config) {
|
|
48
|
-
return new ScrollWatcher(new BeaconTransport(context, config));
|
|
51
|
+
return new ScrollWatcher(new BeaconTransport(context, config), config);
|
|
49
52
|
};
|
|
50
53
|
Object.defineProperty(ScrollWatcher.prototype, "maxScrollX", {
|
|
51
54
|
get: function () {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scroll.js","sourceRoot":"","sources":["../../../src/hooks/scroll.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAEzC,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"scroll.js","sourceRoot":"","sources":["../../../src/hooks/scroll.ts"],"names":[],"mappings":"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","sourcesContent":["import { utils } from '@amplitude/rrweb';\nimport { scrollCallback, scrollPosition } from '@amplitude/rrweb-types';\nimport { BeaconTransport } from '../beacon-transport';\nimport { getGlobalScope } from '@amplitude/analytics-core';\nimport { SessionReplayJoinedConfig } from '../config/types';\nimport { SessionReplayDestinationSessionMetadata } from '../typings/session-replay';\nimport { getPageUrl } from '../helpers';\n\nconst { getWindowHeight, getWindowWidth } = utils;\n\nexport type ScrollEvent = {\n timestamp: number; // Timestamp the event occurred\n maxScrollX: number; // Max window scroll X on a page\n maxScrollY: number; // Max window scroll Y on a page\n maxScrollHeight: number; // Max window scroll Y + window height on a page\n maxScrollWidth: number; // Max window scroll X + window width on a page\n viewportWidth: number;\n viewportHeight: number;\n pageUrl: string;\n type: 'scroll';\n};\n\nexport type ScrollEventPayload = { version: number; events: ScrollEvent[] };\n\n/**\n * This is intended to watch and update max scroll activity when loaded for a particular page.\n * A new instance should be created if the page URL changes, since by default it does not reset\n * it's max scroll state. It is intended to send very few and very small events utilizing the\n * Beacon API.\n * @see {@link BeaconTransport} for more details on Beacon API usage.\n */\nexport class ScrollWatcher {\n private timestamp = Date.now();\n private _maxScrollX: number;\n private _maxScrollY: number;\n private _maxScrollWidth: number;\n private _maxScrollHeight: number;\n private readonly transport: BeaconTransport<ScrollEventPayload>;\n private readonly config: Pick<SessionReplayJoinedConfig, 'loggerProvider' | 'interactionConfig'>;\n\n static default(\n context: Omit<SessionReplayDestinationSessionMetadata, 'deviceId'>,\n config: SessionReplayJoinedConfig,\n ): ScrollWatcher {\n return new ScrollWatcher(new BeaconTransport<ScrollEventPayload>(context, config), config);\n }\n\n constructor(\n transport: BeaconTransport<ScrollEventPayload>,\n config: Pick<SessionReplayJoinedConfig, 'loggerProvider' | 'interactionConfig'>,\n ) {\n this._maxScrollX = 0;\n this._maxScrollY = 0;\n this._maxScrollWidth = getWindowWidth();\n this._maxScrollHeight = getWindowHeight();\n this.config = config;\n\n this.transport = transport;\n }\n\n public get maxScrollX(): number {\n return this._maxScrollX;\n }\n\n public get maxScrollY(): number {\n return this._maxScrollY;\n }\n\n public get maxScrollWidth(): number {\n return this._maxScrollWidth;\n }\n\n public get maxScrollHeight(): number {\n return this._maxScrollHeight;\n }\n\n update(e: scrollPosition) {\n const now = Date.now();\n if (e.x > this._maxScrollX) {\n const width = getWindowWidth();\n this._maxScrollX = e.x;\n const maxScrollWidth = e.x + width;\n if (maxScrollWidth > this._maxScrollWidth) {\n this._maxScrollWidth = maxScrollWidth;\n }\n this.timestamp = now;\n }\n\n if (e.y > this._maxScrollY) {\n const height = getWindowHeight();\n this._maxScrollY = e.y;\n const maxScrollHeight = e.y + height;\n if (maxScrollHeight > this._maxScrollHeight) {\n this._maxScrollHeight = maxScrollHeight;\n }\n this.timestamp = now;\n }\n }\n\n hook: scrollCallback = (e: scrollPosition) => {\n this.update(e);\n };\n\n send: (deviceIdFn: () => string | undefined) => (_: PageTransitionEvent | Event) => void = (deviceIdFn) => (_) => {\n const deviceId = deviceIdFn();\n const globalScope = getGlobalScope();\n if (globalScope && deviceId) {\n this.transport.send(deviceId, {\n version: 1,\n events: [\n {\n maxScrollX: this._maxScrollX,\n maxScrollY: this._maxScrollY,\n maxScrollWidth: this._maxScrollWidth,\n maxScrollHeight: this._maxScrollHeight,\n\n viewportHeight: getWindowHeight(),\n viewportWidth: getWindowWidth(),\n pageUrl: getPageUrl(globalScope.location.href, this.config.interactionConfig?.ugcFilterRules ?? []),\n timestamp: this.timestamp,\n type: 'scroll',\n },\n ],\n });\n }\n };\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-replay.d.ts","sourceRoot":"","sources":["../../src/session-replay.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,OAAO,EAER,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAG1C,OAAO,EACL,aAAa,EACb,yBAAyB,EACzB,kCAAkC,EAInC,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAEL,gBAAgB,EAMjB,MAAM,aAAa,CAAC;AAOrB,OAAO,EACL,sBAAsB,EACtB,0BAA0B,IAAI,mCAAmC,EAIjE,kBAAkB,IAAI,mBAAmB,EACzC,oBAAoB,EACrB,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAI5D,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;IAC9D,UAAU,SAAK;IACf,eAAe,EAAE,eAAe,GAAG,SAAS,CAAC;IAG7C,YAAY,EAAE,WAAW,EAAE,CAAM;IACjC,OAAO,CAAC,UAAU,CAAC,CAAiB;IACpC,OAAO,CAAC,gBAAgB,CAAC,CAAmB;IAC5C,OAAO,CAAC,QAAQ,CAAoC;;IAMpD,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,oBAAoB;IAIlD,OAAO,CAAC,sBAAsB,CAmB5B;cAEc,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,oBAAoB;IA2FnE,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM;IAIpD,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM;IAqBrE,0BAA0B;;;IAsC1B,YAAY,aAEV;IAEF,aAAa,aAIX;IAEF;;;;OAIG;IACH,OAAO,CAAC,iBAAiB,CAIvB;IAEF,UAAU,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM;IAShC,UAAU,CAAC,sBAAsB,UAAQ;IAgB/C,YAAY;IAUZ,eAAe;IAwBf,iBAAiB,IAAI,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS;IAWlD,oBAAoB,IAAI,MAAM,GAAG,SAAS;IAapC,mBAAmB,CAAC,aAAa,EAAE,aAAa,GAAG,SAAS;IA0B5D,YAAY,CAAC,iBAAiB,UAAO;
|
|
1
|
+
{"version":3,"file":"session-replay.d.ts","sourceRoot":"","sources":["../../src/session-replay.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,OAAO,EAER,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAG1C,OAAO,EACL,aAAa,EACb,yBAAyB,EACzB,kCAAkC,EAInC,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAEL,gBAAgB,EAMjB,MAAM,aAAa,CAAC;AAOrB,OAAO,EACL,sBAAsB,EACtB,0BAA0B,IAAI,mCAAmC,EAIjE,kBAAkB,IAAI,mBAAmB,EACzC,oBAAoB,EACrB,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAI5D,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;IAC9D,UAAU,SAAK;IACf,eAAe,EAAE,eAAe,GAAG,SAAS,CAAC;IAG7C,YAAY,EAAE,WAAW,EAAE,CAAM;IACjC,OAAO,CAAC,UAAU,CAAC,CAAiB;IACpC,OAAO,CAAC,gBAAgB,CAAC,CAAmB;IAC5C,OAAO,CAAC,QAAQ,CAAoC;;IAMpD,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,oBAAoB;IAIlD,OAAO,CAAC,sBAAsB,CAmB5B;cAEc,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,oBAAoB;IA2FnE,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM;IAIpD,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM;IAqBrE,0BAA0B;;;IAsC1B,YAAY,aAEV;IAEF,aAAa,aAIX;IAEF;;;;OAIG;IACH,OAAO,CAAC,iBAAiB,CAIvB;IAEF,UAAU,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM;IAShC,UAAU,CAAC,sBAAsB,UAAQ;IAgB/C,YAAY;IAUZ,eAAe;IAwBf,iBAAiB,IAAI,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS;IAWlD,oBAAoB,IAAI,MAAM,GAAG,SAAS;IAapC,mBAAmB,CAAC,aAAa,EAAE,aAAa,GAAG,SAAS;IA0B5D,YAAY,CAAC,iBAAiB,UAAO;IA8F3C,mBAAmB,cACN,gBAAgB;;kDAmC3B;IAEF,mBAAmB,aAUjB;IAEF,WAAW;IAIX,YAAY;IAIN,KAAK,CAAC,QAAQ,UAAQ;IAI5B,QAAQ;IAMR,OAAO,CAAC,UAAU;IAYlB,OAAO,CAAC,WAAW;CAwBpB"}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { __assign, __awaiter, __generator, __read, __spreadArray } from "tslib";
|
|
2
2
|
import { Logger, returnWrapper, getAnalyticsConnector, getGlobalScope, } from '@amplitude/analytics-core';
|
|
3
3
|
import { record } from '@amplitude/rrweb';
|
|
4
|
+
import { EventType as RRWebEventType } from '@amplitude/rrweb-types';
|
|
4
5
|
import { createSessionReplayJoinedConfigGenerator } from './config/joined-config';
|
|
5
6
|
import { BLOCK_CLASS, CustomRRwebEvent, DEFAULT_SESSION_REPLAY_PROPERTY, INTERACTION_MAX_INTERVAL, INTERACTION_MIN_INTERVAL, MASK_TEXT_CLASS, SESSION_REPLAY_DEBUG_PROPERTY, } from './constants';
|
|
6
7
|
import { createEventsManager } from './events/events-manager';
|
|
7
8
|
import { MultiEventManager } from './events/multi-manager';
|
|
8
|
-
import { generateHashCode, getDebugConfig, getStorageSize, isSessionInSample, maskFn } from './helpers';
|
|
9
|
+
import { generateHashCode, getDebugConfig, getPageUrl, getStorageSize, isSessionInSample, maskFn } from './helpers';
|
|
9
10
|
import { clickBatcher, clickHook, clickNonBatcher } from './hooks/click';
|
|
10
11
|
import { ScrollWatcher } from './hooks/scroll';
|
|
11
12
|
import { SessionIdentifiers } from './identifiers';
|
|
@@ -381,14 +382,14 @@ var SessionReplay = /** @class */ (function () {
|
|
|
381
382
|
});
|
|
382
383
|
};
|
|
383
384
|
SessionReplay.prototype.recordEvents = function (shouldLogMetadata) {
|
|
384
|
-
var _a, _b;
|
|
385
|
+
var _a, _b, _c;
|
|
385
386
|
if (shouldLogMetadata === void 0) { shouldLogMetadata = true; }
|
|
386
387
|
return __awaiter(this, void 0, void 0, function () {
|
|
387
|
-
var config, shouldRecord, sessionId, privacyConfig, interactionConfig, loggingConfig, hooks,
|
|
388
|
-
var
|
|
388
|
+
var config, shouldRecord, sessionId, privacyConfig, interactionConfig, loggingConfig, hooks, ugcFilterRules, _d, _e, error_4;
|
|
389
|
+
var _f;
|
|
389
390
|
var _this = this;
|
|
390
|
-
return __generator(this, function (
|
|
391
|
-
switch (
|
|
391
|
+
return __generator(this, function (_g) {
|
|
392
|
+
switch (_g.label) {
|
|
392
393
|
case 0:
|
|
393
394
|
config = this.config;
|
|
394
395
|
shouldRecord = this.getShouldRecord();
|
|
@@ -408,17 +409,19 @@ var SessionReplay = /** @class */ (function () {
|
|
|
408
409
|
eventsManager: this.eventsManager,
|
|
409
410
|
sessionId: sessionId,
|
|
410
411
|
deviceIdFn: this.getDeviceId.bind(this),
|
|
412
|
+
ugcFilterRules: (_c = interactionConfig.ugcFilterRules) !== null && _c !== void 0 ? _c : [],
|
|
411
413
|
}),
|
|
412
414
|
scroll: this.scrollHook,
|
|
413
415
|
}
|
|
414
416
|
: {};
|
|
417
|
+
ugcFilterRules = (interactionConfig === null || interactionConfig === void 0 ? void 0 : interactionConfig.enabled) && interactionConfig.ugcFilterRules ? interactionConfig.ugcFilterRules : [];
|
|
415
418
|
this.loggerProvider.log("Session Replay capture beginning for ".concat(sessionId, "."));
|
|
416
|
-
|
|
419
|
+
_g.label = 1;
|
|
417
420
|
case 1:
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
421
|
+
_g.trys.push([1, 3, , 4]);
|
|
422
|
+
_d = this;
|
|
423
|
+
_e = record;
|
|
424
|
+
_f = {
|
|
422
425
|
emit: function (event) {
|
|
423
426
|
if (_this.shouldOptOut()) {
|
|
424
427
|
_this.loggerProvider.log("Opting session ".concat(sessionId, " out of recording due to optOut config."));
|
|
@@ -426,6 +429,9 @@ var SessionReplay = /** @class */ (function () {
|
|
|
426
429
|
_this.sendEvents();
|
|
427
430
|
return;
|
|
428
431
|
}
|
|
432
|
+
if (event.type === RRWebEventType.Meta) {
|
|
433
|
+
event.data.href = getPageUrl(event.data.href, ugcFilterRules);
|
|
434
|
+
}
|
|
429
435
|
if (_this.eventCompressor) {
|
|
430
436
|
// Schedule processing during idle time if the browser supports requestIdleCallback
|
|
431
437
|
_this.eventCompressor.enqueueEvent(event, sessionId);
|
|
@@ -462,15 +468,15 @@ var SessionReplay = /** @class */ (function () {
|
|
|
462
468
|
};
|
|
463
469
|
return [4 /*yield*/, this.getRecordingPlugins(loggingConfig)];
|
|
464
470
|
case 2:
|
|
465
|
-
|
|
466
|
-
|
|
471
|
+
_d.recordCancelCallback = _e.apply(void 0, [(_f.plugins = _g.sent(),
|
|
472
|
+
_f)]);
|
|
467
473
|
void this.addCustomRRWebEvent(CustomRRwebEvent.DEBUG_INFO);
|
|
468
474
|
if (shouldLogMetadata) {
|
|
469
475
|
void this.addCustomRRWebEvent(CustomRRwebEvent.METADATA, this.metadata);
|
|
470
476
|
}
|
|
471
477
|
return [3 /*break*/, 4];
|
|
472
478
|
case 3:
|
|
473
|
-
error_4 =
|
|
479
|
+
error_4 = _g.sent();
|
|
474
480
|
this.loggerProvider.warn('Failed to initialize session replay:', error_4);
|
|
475
481
|
return [3 /*break*/, 4];
|
|
476
482
|
case 4: return [2 /*return*/];
|