posthog-js 1.274.3 → 1.275.1

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.
Files changed (40) hide show
  1. package/dist/array.full.es5.js +1 -1
  2. package/dist/array.full.es5.js.map +1 -1
  3. package/dist/array.full.js +1 -1
  4. package/dist/array.full.js.map +1 -1
  5. package/dist/array.full.no-external.js +1 -1
  6. package/dist/array.full.no-external.js.map +1 -1
  7. package/dist/array.js +1 -1
  8. package/dist/array.js.map +1 -1
  9. package/dist/array.no-external.js +1 -1
  10. package/dist/array.no-external.js.map +1 -1
  11. package/dist/customizations.full.js +1 -1
  12. package/dist/lazy-recorder.js +1 -1
  13. package/dist/main.js +1 -1
  14. package/dist/main.js.map +1 -1
  15. package/dist/module.d.ts +6 -0
  16. package/dist/module.full.d.ts +6 -0
  17. package/dist/module.full.js +1 -1
  18. package/dist/module.full.js.map +1 -1
  19. package/dist/module.full.no-external.d.ts +6 -0
  20. package/dist/module.full.no-external.js +1 -1
  21. package/dist/module.full.no-external.js.map +1 -1
  22. package/dist/module.js +1 -1
  23. package/dist/module.js.map +1 -1
  24. package/dist/module.no-external.d.ts +6 -0
  25. package/dist/module.no-external.js +1 -1
  26. package/dist/module.no-external.js.map +1 -1
  27. package/dist/posthog-recorder.js +1 -1
  28. package/dist/src/sessionid.d.ts +6 -0
  29. package/dist/surveys-preview.d.ts +6 -0
  30. package/lib/package.json +1 -1
  31. package/lib/src/extensions/web-vitals/index.js +11 -2
  32. package/lib/src/extensions/web-vitals/index.js.map +1 -1
  33. package/lib/src/heatmaps.js +10 -2
  34. package/lib/src/heatmaps.js.map +1 -1
  35. package/lib/src/posthog-core.js +6 -4
  36. package/lib/src/posthog-core.js.map +1 -1
  37. package/lib/src/sessionid.d.ts +6 -0
  38. package/lib/src/sessionid.js +20 -4
  39. package/lib/src/sessionid.js.map +1 -1
  40. package/package.json +1 -1
@@ -16,6 +16,7 @@ export declare class SessionIdManager {
16
16
  private _sessionIdChangedHandlers;
17
17
  private readonly _sessionTimeoutMs;
18
18
  private _enforceIdleTimeout;
19
+ private _beforeUnloadListener;
19
20
  private _eventEmitter;
20
21
  on(event: 'forcedIdleReset', handler: () => void): () => void;
21
22
  constructor(instance: PostHog, sessionIdGenerator?: () => string, windowIdGenerator?: () => string);
@@ -27,6 +28,11 @@ export declare class SessionIdManager {
27
28
  private _setSessionId;
28
29
  private _getSessionId;
29
30
  resetSessionId(): void;
31
+ /**
32
+ * Cleans up resources used by SessionIdManager.
33
+ * Should be called when the SessionIdManager is no longer needed to prevent memory leaks.
34
+ */
35
+ destroy(): void;
30
36
  private _listenToReloadWindow;
31
37
  private _sessionHasBeenIdleTooLong;
32
38
  checkAndGetSessionAndWindowId(readOnly?: boolean, _timestamp?: number | null): {
@@ -1910,6 +1910,7 @@ declare class SessionIdManager {
1910
1910
  private _sessionIdChangedHandlers;
1911
1911
  private readonly _sessionTimeoutMs;
1912
1912
  private _enforceIdleTimeout;
1913
+ private _beforeUnloadListener;
1913
1914
  private _eventEmitter;
1914
1915
  on(event: 'forcedIdleReset', handler: () => void): () => void;
1915
1916
  constructor(instance: PostHog, sessionIdGenerator?: () => string, windowIdGenerator?: () => string);
@@ -1921,6 +1922,11 @@ declare class SessionIdManager {
1921
1922
  private _setSessionId;
1922
1923
  private _getSessionId;
1923
1924
  resetSessionId(): void;
1925
+ /**
1926
+ * Cleans up resources used by SessionIdManager.
1927
+ * Should be called when the SessionIdManager is no longer needed to prevent memory leaks.
1928
+ */
1929
+ destroy(): void;
1924
1930
  private _listenToReloadWindow;
1925
1931
  private _sessionHasBeenIdleTooLong;
1926
1932
  checkAndGetSessionAndWindowId(readOnly?: boolean, _timestamp?: number | null): {
package/lib/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "posthog-js",
3
- "version": "1.274.3",
3
+ "version": "1.275.1",
4
4
  "description": "Posthog-js allows you to automatically capture usage and send events to PostHog.",
5
5
  "repository": "https://github.com/PostHog/posthog-js",
6
6
  "author": "hey@posthog.com",
@@ -16,6 +16,9 @@ var logger_1 = require("../../utils/logger");
16
16
  var core_1 = require("@posthog/core");
17
17
  var constants_1 = require("../../constants");
18
18
  var globals_1 = require("../../utils/globals");
19
+ var request_utils_1 = require("../../utils/request-utils");
20
+ var event_utils_1 = require("../../utils/event-utils");
21
+ var utils_1 = require("../../utils");
19
22
  var logger = (0, logger_1.createLogger)('[Web Vitals]');
20
23
  exports.DEFAULT_FLUSH_TO_CAPTURE_TIMEOUT_MILLISECONDS = 5000;
21
24
  var ONE_MINUTE_IN_MILLIS = 60 * 1000;
@@ -216,12 +219,18 @@ var WebVitalsAutocapture = /** @class */ (function () {
216
219
  });
217
220
  };
218
221
  WebVitalsAutocapture.prototype._currentURL = function () {
219
- // TODO you should be able to mask the URL here
220
222
  var href = globals_1.window ? globals_1.window.location.href : undefined;
221
223
  if (!href) {
222
224
  logger.error('Could not determine current URL');
225
+ return undefined;
223
226
  }
224
- return href;
227
+ // mask url query params
228
+ var maskPersonalDataProperties = this._instance.config.mask_personal_data_properties;
229
+ var customPersonalDataProperties = this._instance.config.custom_personal_data_properties;
230
+ var paramsToMask = maskPersonalDataProperties
231
+ ? (0, utils_1.extendArray)([], event_utils_1.PERSONAL_DATA_CAMPAIGN_PARAMS, customPersonalDataProperties || [])
232
+ : [];
233
+ return (0, request_utils_1.maskQueryParams)(href, paramsToMask, event_utils_1.MASKED);
225
234
  };
226
235
  return WebVitalsAutocapture;
227
236
  }());
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/extensions/web-vitals/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { PostHog } from '../../posthog-core'\nimport { RemoteConfig, SupportedWebVitalsMetrics } from '../../types'\nimport { createLogger } from '../../utils/logger'\nimport { isBoolean, isNullish, isNumber, isUndefined, isObject } from '@posthog/core'\nimport { WEB_VITALS_ALLOWED_METRICS, WEB_VITALS_ENABLED_SERVER_SIDE } from '../../constants'\nimport { assignableWindow, window, location } from '../../utils/globals'\n\nconst logger = createLogger('[Web Vitals]')\n\ntype WebVitalsMetricCallback = (metric: any) => void\n\nexport const DEFAULT_FLUSH_TO_CAPTURE_TIMEOUT_MILLISECONDS = 5000\nconst ONE_MINUTE_IN_MILLIS = 60 * 1000\nexport const FIFTEEN_MINUTES_IN_MILLIS = 15 * ONE_MINUTE_IN_MILLIS\n\ntype WebVitalsEventBuffer = { url: string | undefined; metrics: any[]; firstMetricTimestamp: number | undefined }\n\nexport class WebVitalsAutocapture {\n private _enabledServerSide: boolean = false\n private _initialized = false\n\n private _buffer: WebVitalsEventBuffer = { url: undefined, metrics: [], firstMetricTimestamp: undefined }\n private _delayedFlushTimer: ReturnType<typeof setTimeout> | undefined\n\n constructor(private readonly _instance: PostHog) {\n this._enabledServerSide = !!this._instance.persistence?.props[WEB_VITALS_ENABLED_SERVER_SIDE]\n\n this.startIfEnabled()\n }\n\n public get allowedMetrics(): SupportedWebVitalsMetrics[] {\n const clientConfigMetricAllowList: SupportedWebVitalsMetrics[] | undefined = isObject(\n this._instance.config.capture_performance\n )\n ? this._instance.config.capture_performance?.web_vitals_allowed_metrics\n : undefined\n return !isUndefined(clientConfigMetricAllowList)\n ? clientConfigMetricAllowList\n : this._instance.persistence?.props[WEB_VITALS_ALLOWED_METRICS] || ['CLS', 'FCP', 'INP', 'LCP']\n }\n\n public get flushToCaptureTimeoutMs(): number {\n const clientConfig: number | undefined = isObject(this._instance.config.capture_performance)\n ? this._instance.config.capture_performance.web_vitals_delayed_flush_ms\n : undefined\n return clientConfig || DEFAULT_FLUSH_TO_CAPTURE_TIMEOUT_MILLISECONDS\n }\n\n public get _maxAllowedValue(): number {\n const configured =\n isObject(this._instance.config.capture_performance) &&\n isNumber(this._instance.config.capture_performance.__web_vitals_max_value)\n ? this._instance.config.capture_performance.__web_vitals_max_value\n : FIFTEEN_MINUTES_IN_MILLIS\n // you can set to 0 to disable the check or any value over ten seconds\n // 1 milli to 1 minute will be set to 15 minutes, cos that would be a silly low maximum\n return 0 < configured && configured <= ONE_MINUTE_IN_MILLIS ? FIFTEEN_MINUTES_IN_MILLIS : configured\n }\n\n public get isEnabled(): boolean {\n // Always disable web vitals if we're not on http or https\n const protocol = location?.protocol\n if (protocol !== 'http:' && protocol !== 'https:') {\n logger.info('Web Vitals are disabled on non-http/https protocols')\n return false\n }\n\n // Otherwise, check config\n const clientConfig = isObject(this._instance.config.capture_performance)\n ? this._instance.config.capture_performance.web_vitals\n : isBoolean(this._instance.config.capture_performance)\n ? this._instance.config.capture_performance\n : undefined\n return isBoolean(clientConfig) ? clientConfig : this._enabledServerSide\n }\n\n public startIfEnabled(): void {\n if (this.isEnabled && !this._initialized) {\n logger.info('enabled, starting...')\n this._loadScript(this._startCapturing)\n }\n }\n\n public onRemoteConfig(response: RemoteConfig) {\n const webVitalsOptIn = isObject(response.capturePerformance) && !!response.capturePerformance.web_vitals\n\n const allowedMetrics = isObject(response.capturePerformance)\n ? response.capturePerformance.web_vitals_allowed_metrics\n : undefined\n\n if (this._instance.persistence) {\n this._instance.persistence.register({\n [WEB_VITALS_ENABLED_SERVER_SIDE]: webVitalsOptIn,\n })\n\n this._instance.persistence.register({\n [WEB_VITALS_ALLOWED_METRICS]: allowedMetrics,\n })\n }\n // store this in-memory in case persistence is disabled\n this._enabledServerSide = webVitalsOptIn\n\n this.startIfEnabled()\n }\n\n private _loadScript(cb: () => void): void {\n if (assignableWindow.__PosthogExtensions__?.postHogWebVitalsCallbacks) {\n // already loaded\n cb()\n }\n assignableWindow.__PosthogExtensions__?.loadExternalDependency?.(this._instance, 'web-vitals', (err) => {\n if (err) {\n logger.error('failed to load script', err)\n return\n }\n cb()\n })\n }\n\n private _currentURL(): string | undefined {\n // TODO you should be able to mask the URL here\n const href = window ? window.location.href : undefined\n if (!href) {\n logger.error('Could not determine current URL')\n }\n return href\n }\n\n private _flushToCapture = () => {\n clearTimeout(this._delayedFlushTimer)\n if (this._buffer.metrics.length === 0) {\n return\n }\n\n this._instance.capture(\n '$web_vitals',\n this._buffer.metrics.reduce(\n (acc, metric) => ({\n ...acc,\n // the entire event so we can use it in the future e.g. includes google's rating\n [`$web_vitals_${metric.name}_event`]: { ...metric },\n [`$web_vitals_${metric.name}_value`]: metric.value,\n }),\n {}\n )\n )\n this._buffer = { url: undefined, metrics: [], firstMetricTimestamp: undefined }\n }\n\n private _addToBuffer = (metric: any) => {\n const sessionIds = this._instance.sessionManager?.checkAndGetSessionAndWindowId(true)\n if (isUndefined(sessionIds)) {\n logger.error('Could not read session ID. Dropping metrics!')\n return\n }\n\n this._buffer = this._buffer || { url: undefined, metrics: [], firstMetricTimestamp: undefined }\n\n const $currentUrl = this._currentURL()\n if (isUndefined($currentUrl)) {\n return\n }\n\n if (isNullish(metric?.name) || isNullish(metric?.value)) {\n logger.error('Invalid metric received', metric)\n return\n }\n\n // we observe some very large values sometimes, we'll ignore them\n // since the likelihood of LCP > 1 hour being correct is very low\n if (this._maxAllowedValue && metric.value >= this._maxAllowedValue) {\n logger.error('Ignoring metric with value >= ' + this._maxAllowedValue, metric)\n return\n }\n\n const urlHasChanged = this._buffer.url !== $currentUrl\n\n if (urlHasChanged) {\n // we need to send what we have\n this._flushToCapture()\n // poor performance is >4s, we wait twice that time to send\n // this is in case we haven't received all metrics\n // we'll at least gather some\n this._delayedFlushTimer = setTimeout(this._flushToCapture, this.flushToCaptureTimeoutMs)\n }\n\n if (isUndefined(this._buffer.url)) {\n this._buffer.url = $currentUrl\n }\n\n this._buffer.firstMetricTimestamp = isUndefined(this._buffer.firstMetricTimestamp)\n ? Date.now()\n : this._buffer.firstMetricTimestamp\n\n if (metric.attribution && metric.attribution.interactionTargetElement) {\n // we don't want to send the entire element\n // they can be very large\n // TODO we could run this through autocapture code so that we get elements chain info\n // and can display the element in the UI\n metric.attribution.interactionTargetElement = undefined\n }\n\n this._buffer.metrics.push({\n ...metric,\n $current_url: $currentUrl,\n $session_id: sessionIds.sessionId,\n $window_id: sessionIds.windowId,\n timestamp: Date.now(),\n })\n\n if (this._buffer.metrics.length === this.allowedMetrics.length) {\n // we have all allowed metrics\n this._flushToCapture()\n }\n }\n\n private _startCapturing = () => {\n let onLCP: WebVitalsMetricCallback | undefined\n let onCLS: WebVitalsMetricCallback | undefined\n let onFCP: WebVitalsMetricCallback | undefined\n let onINP: WebVitalsMetricCallback | undefined\n\n const posthogExtensions = assignableWindow.__PosthogExtensions__\n if (!isUndefined(posthogExtensions) && !isUndefined(posthogExtensions.postHogWebVitalsCallbacks)) {\n ;({ onLCP, onCLS, onFCP, onINP } = posthogExtensions.postHogWebVitalsCallbacks)\n }\n\n if (!onLCP || !onCLS || !onFCP || !onINP) {\n logger.error('web vitals callbacks not loaded - not starting')\n return\n }\n\n // register performance observers\n if (this.allowedMetrics.indexOf('LCP') > -1) {\n onLCP(this._addToBuffer.bind(this))\n }\n if (this.allowedMetrics.indexOf('CLS') > -1) {\n onCLS(this._addToBuffer.bind(this))\n }\n if (this.allowedMetrics.indexOf('FCP') > -1) {\n onFCP(this._addToBuffer.bind(this))\n }\n if (this.allowedMetrics.indexOf('INP') > -1) {\n onINP(this._addToBuffer.bind(this))\n }\n\n this._initialized = true\n }\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/extensions/web-vitals/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { PostHog } from '../../posthog-core'\nimport { RemoteConfig, SupportedWebVitalsMetrics } from '../../types'\nimport { createLogger } from '../../utils/logger'\nimport { isBoolean, isNullish, isNumber, isUndefined, isObject } from '@posthog/core'\nimport { WEB_VITALS_ALLOWED_METRICS, WEB_VITALS_ENABLED_SERVER_SIDE } from '../../constants'\nimport { assignableWindow, window, location } from '../../utils/globals'\nimport { maskQueryParams } from '../../utils/request-utils'\nimport { PERSONAL_DATA_CAMPAIGN_PARAMS, MASKED } from '../../utils/event-utils'\nimport { extendArray } from '../../utils'\n\nconst logger = createLogger('[Web Vitals]')\n\ntype WebVitalsMetricCallback = (metric: any) => void\n\nexport const DEFAULT_FLUSH_TO_CAPTURE_TIMEOUT_MILLISECONDS = 5000\nconst ONE_MINUTE_IN_MILLIS = 60 * 1000\nexport const FIFTEEN_MINUTES_IN_MILLIS = 15 * ONE_MINUTE_IN_MILLIS\n\ntype WebVitalsEventBuffer = { url: string | undefined; metrics: any[]; firstMetricTimestamp: number | undefined }\n\nexport class WebVitalsAutocapture {\n private _enabledServerSide: boolean = false\n private _initialized = false\n\n private _buffer: WebVitalsEventBuffer = { url: undefined, metrics: [], firstMetricTimestamp: undefined }\n private _delayedFlushTimer: ReturnType<typeof setTimeout> | undefined\n\n constructor(private readonly _instance: PostHog) {\n this._enabledServerSide = !!this._instance.persistence?.props[WEB_VITALS_ENABLED_SERVER_SIDE]\n\n this.startIfEnabled()\n }\n\n public get allowedMetrics(): SupportedWebVitalsMetrics[] {\n const clientConfigMetricAllowList: SupportedWebVitalsMetrics[] | undefined = isObject(\n this._instance.config.capture_performance\n )\n ? this._instance.config.capture_performance?.web_vitals_allowed_metrics\n : undefined\n return !isUndefined(clientConfigMetricAllowList)\n ? clientConfigMetricAllowList\n : this._instance.persistence?.props[WEB_VITALS_ALLOWED_METRICS] || ['CLS', 'FCP', 'INP', 'LCP']\n }\n\n public get flushToCaptureTimeoutMs(): number {\n const clientConfig: number | undefined = isObject(this._instance.config.capture_performance)\n ? this._instance.config.capture_performance.web_vitals_delayed_flush_ms\n : undefined\n return clientConfig || DEFAULT_FLUSH_TO_CAPTURE_TIMEOUT_MILLISECONDS\n }\n\n public get _maxAllowedValue(): number {\n const configured =\n isObject(this._instance.config.capture_performance) &&\n isNumber(this._instance.config.capture_performance.__web_vitals_max_value)\n ? this._instance.config.capture_performance.__web_vitals_max_value\n : FIFTEEN_MINUTES_IN_MILLIS\n // you can set to 0 to disable the check or any value over ten seconds\n // 1 milli to 1 minute will be set to 15 minutes, cos that would be a silly low maximum\n return 0 < configured && configured <= ONE_MINUTE_IN_MILLIS ? FIFTEEN_MINUTES_IN_MILLIS : configured\n }\n\n public get isEnabled(): boolean {\n // Always disable web vitals if we're not on http or https\n const protocol = location?.protocol\n if (protocol !== 'http:' && protocol !== 'https:') {\n logger.info('Web Vitals are disabled on non-http/https protocols')\n return false\n }\n\n // Otherwise, check config\n const clientConfig = isObject(this._instance.config.capture_performance)\n ? this._instance.config.capture_performance.web_vitals\n : isBoolean(this._instance.config.capture_performance)\n ? this._instance.config.capture_performance\n : undefined\n return isBoolean(clientConfig) ? clientConfig : this._enabledServerSide\n }\n\n public startIfEnabled(): void {\n if (this.isEnabled && !this._initialized) {\n logger.info('enabled, starting...')\n this._loadScript(this._startCapturing)\n }\n }\n\n public onRemoteConfig(response: RemoteConfig) {\n const webVitalsOptIn = isObject(response.capturePerformance) && !!response.capturePerformance.web_vitals\n\n const allowedMetrics = isObject(response.capturePerformance)\n ? response.capturePerformance.web_vitals_allowed_metrics\n : undefined\n\n if (this._instance.persistence) {\n this._instance.persistence.register({\n [WEB_VITALS_ENABLED_SERVER_SIDE]: webVitalsOptIn,\n })\n\n this._instance.persistence.register({\n [WEB_VITALS_ALLOWED_METRICS]: allowedMetrics,\n })\n }\n // store this in-memory in case persistence is disabled\n this._enabledServerSide = webVitalsOptIn\n\n this.startIfEnabled()\n }\n\n private _loadScript(cb: () => void): void {\n if (assignableWindow.__PosthogExtensions__?.postHogWebVitalsCallbacks) {\n // already loaded\n cb()\n }\n assignableWindow.__PosthogExtensions__?.loadExternalDependency?.(this._instance, 'web-vitals', (err) => {\n if (err) {\n logger.error('failed to load script', err)\n return\n }\n cb()\n })\n }\n\n private _currentURL(): string | undefined {\n const href = window ? window.location.href : undefined\n if (!href) {\n logger.error('Could not determine current URL')\n return undefined\n }\n\n // mask url query params\n const maskPersonalDataProperties = this._instance.config.mask_personal_data_properties\n const customPersonalDataProperties = this._instance.config.custom_personal_data_properties\n\n const paramsToMask = maskPersonalDataProperties\n ? extendArray([], PERSONAL_DATA_CAMPAIGN_PARAMS, customPersonalDataProperties || [])\n : []\n\n return maskQueryParams(href, paramsToMask, MASKED)\n }\n\n private _flushToCapture = () => {\n clearTimeout(this._delayedFlushTimer)\n if (this._buffer.metrics.length === 0) {\n return\n }\n\n this._instance.capture(\n '$web_vitals',\n this._buffer.metrics.reduce(\n (acc, metric) => ({\n ...acc,\n // the entire event so we can use it in the future e.g. includes google's rating\n [`$web_vitals_${metric.name}_event`]: { ...metric },\n [`$web_vitals_${metric.name}_value`]: metric.value,\n }),\n {}\n )\n )\n this._buffer = { url: undefined, metrics: [], firstMetricTimestamp: undefined }\n }\n\n private _addToBuffer = (metric: any) => {\n const sessionIds = this._instance.sessionManager?.checkAndGetSessionAndWindowId(true)\n if (isUndefined(sessionIds)) {\n logger.error('Could not read session ID. Dropping metrics!')\n return\n }\n\n this._buffer = this._buffer || { url: undefined, metrics: [], firstMetricTimestamp: undefined }\n\n const $currentUrl = this._currentURL()\n if (isUndefined($currentUrl)) {\n return\n }\n\n if (isNullish(metric?.name) || isNullish(metric?.value)) {\n logger.error('Invalid metric received', metric)\n return\n }\n\n // we observe some very large values sometimes, we'll ignore them\n // since the likelihood of LCP > 1 hour being correct is very low\n if (this._maxAllowedValue && metric.value >= this._maxAllowedValue) {\n logger.error('Ignoring metric with value >= ' + this._maxAllowedValue, metric)\n return\n }\n\n const urlHasChanged = this._buffer.url !== $currentUrl\n\n if (urlHasChanged) {\n // we need to send what we have\n this._flushToCapture()\n // poor performance is >4s, we wait twice that time to send\n // this is in case we haven't received all metrics\n // we'll at least gather some\n this._delayedFlushTimer = setTimeout(this._flushToCapture, this.flushToCaptureTimeoutMs)\n }\n\n if (isUndefined(this._buffer.url)) {\n this._buffer.url = $currentUrl\n }\n\n this._buffer.firstMetricTimestamp = isUndefined(this._buffer.firstMetricTimestamp)\n ? Date.now()\n : this._buffer.firstMetricTimestamp\n\n if (metric.attribution && metric.attribution.interactionTargetElement) {\n // we don't want to send the entire element\n // they can be very large\n // TODO we could run this through autocapture code so that we get elements chain info\n // and can display the element in the UI\n metric.attribution.interactionTargetElement = undefined\n }\n\n this._buffer.metrics.push({\n ...metric,\n $current_url: $currentUrl,\n $session_id: sessionIds.sessionId,\n $window_id: sessionIds.windowId,\n timestamp: Date.now(),\n })\n\n if (this._buffer.metrics.length === this.allowedMetrics.length) {\n // we have all allowed metrics\n this._flushToCapture()\n }\n }\n\n private _startCapturing = () => {\n let onLCP: WebVitalsMetricCallback | undefined\n let onCLS: WebVitalsMetricCallback | undefined\n let onFCP: WebVitalsMetricCallback | undefined\n let onINP: WebVitalsMetricCallback | undefined\n\n const posthogExtensions = assignableWindow.__PosthogExtensions__\n if (!isUndefined(posthogExtensions) && !isUndefined(posthogExtensions.postHogWebVitalsCallbacks)) {\n ;({ onLCP, onCLS, onFCP, onINP } = posthogExtensions.postHogWebVitalsCallbacks)\n }\n\n if (!onLCP || !onCLS || !onFCP || !onINP) {\n logger.error('web vitals callbacks not loaded - not starting')\n return\n }\n\n // register performance observers\n if (this.allowedMetrics.indexOf('LCP') > -1) {\n onLCP(this._addToBuffer.bind(this))\n }\n if (this.allowedMetrics.indexOf('CLS') > -1) {\n onCLS(this._addToBuffer.bind(this))\n }\n if (this.allowedMetrics.indexOf('FCP') > -1) {\n onFCP(this._addToBuffer.bind(this))\n }\n if (this.allowedMetrics.indexOf('INP') > -1) {\n onINP(this._addToBuffer.bind(this))\n }\n\n this._initialized = true\n }\n}\n"]}
@@ -25,6 +25,8 @@ var element_utils_1 = require("./utils/element-utils");
25
25
  var dead_clicks_autocapture_1 = require("./extensions/dead-clicks-autocapture");
26
26
  var core_2 = require("@posthog/core");
27
27
  var utils_1 = require("./utils");
28
+ var request_utils_1 = require("./utils/request-utils");
29
+ var event_utils_1 = require("./utils/event-utils");
28
30
  var DEFAULT_FLUSH_INTERVAL = 5000;
29
31
  var logger = (0, logger_1.createLogger)('[Heatmaps]');
30
32
  function elementOrParentPositionMatches(el, matches, breakOnElement) {
@@ -172,8 +174,14 @@ var Heatmaps = /** @class */ (function () {
172
174
  if (!globals_1.window) {
173
175
  return;
174
176
  }
175
- // TODO we should be able to mask this
176
- var url = globals_1.window.location.href;
177
+ var href = globals_1.window.location.href;
178
+ // mask url query params
179
+ var maskPersonalDataProperties = this.instance.config.mask_personal_data_properties;
180
+ var customPersonalDataProperties = this.instance.config.custom_personal_data_properties;
181
+ var paramsToMask = maskPersonalDataProperties
182
+ ? (0, utils_1.extendArray)([], event_utils_1.PERSONAL_DATA_CAMPAIGN_PARAMS, customPersonalDataProperties || [])
183
+ : [];
184
+ var url = (0, request_utils_1.maskQueryParams)(href, paramsToMask, event_utils_1.MASKED);
177
185
  this._buffer = this._buffer || {};
178
186
  if (!this._buffer[url]) {
179
187
  this._buffer[url] = [];
@@ -1 +1 @@
1
- {"version":3,"file":"heatmaps.js","sourceRoot":"","sources":["../../src/heatmaps.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,qEAA8C;AAI9C,2CAAkD;AAClD,yDAAsE;AACtE,yCAA0D;AAC1D,sCAA8E;AAC9E,yCAA6C;AAC7C,uDAAgF;AAChF,gFAA4G;AAC5G,sCAAwC;AACxC,iCAA0C;AAE1C,IAAM,sBAAsB,GAAG,IAAI,CAAA;AAEnC,IAAM,MAAM,GAAG,IAAA,qBAAY,EAAC,YAAY,CAAC,CAAA;AAQzC,SAAS,8BAA8B,CAAC,EAAkB,EAAE,OAAiB,EAAE,cAAwB;IACnG,IAAI,KAAK,GAA2B,EAAE,CAAA;IAEtC,OAAO,KAAK,IAAI,IAAA,6BAAa,EAAC,KAAK,CAAC,IAAI,CAAC,IAAA,qBAAK,EAAC,KAAK,EAAE,MAAM,CAAC,EAAE,CAAC;QAC5D,IAAI,KAAK,KAAK,cAAc,EAAE,CAAC;YAC3B,OAAO,KAAK,CAAA;QAChB,CAAC;QAED,IAAI,IAAA,eAAQ,EAAC,OAAO,EAAE,gBAAM,aAAN,gBAAM,uBAAN,gBAAM,CAAE,gBAAgB,CAAC,KAAK,EAAE,QAAQ,CAAC,EAAE,CAAC;YAC9D,OAAO,IAAI,CAAA;QACf,CAAC;QAED,KAAK,GAAG,IAAA,oCAAgB,EAAC,KAAK,CAAC,CAAA;IACnC,CAAC;IAED,OAAO,KAAK,CAAA;AAChB,CAAC;AAED,SAAS,iBAAiB,CAAC,CAAU;IACjC,OAAO,IAAA,eAAQ,EAAC,CAAC,CAAC,IAAI,SAAS,IAAI,CAAC,IAAI,SAAS,IAAI,CAAC,IAAI,IAAA,eAAQ,EAAC,CAAC,CAAC,OAAO,CAAC,IAAI,IAAA,eAAQ,EAAC,CAAC,CAAC,OAAO,CAAC,CAAA;AACxG,CAAC;AAED;IAYI,kBAAY,QAAiB;;QAV7B,eAAU,GAAG,IAAI,mBAAS,EAAE,CAAA;QAC5B,uBAAkB,GAAY,KAAK,CAAA;QACnC,iBAAY,GAAG,KAAK,CAAA;QAKZ,mBAAc,GAA0C,IAAI,CAAA;QAIhE,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAA;QACxB,IAAI,CAAC,kBAAkB,GAAG,CAAC,CAAC,CAAA,MAAA,IAAI,CAAC,QAAQ,CAAC,WAAW,0CAAE,KAAK,CAAC,wCAA4B,CAAC,CAAA,CAAA;IAC9F,CAAC;IAED,sBAAW,+CAAyB;aAApC;YACI,IAAI,aAAa,GAAG,sBAAsB,CAAA;YAC1C,IACI,IAAA,eAAQ,EAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,gBAAgB,CAAC;gBAC/C,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,gBAAgB,CAAC,2BAA2B,EACnE,CAAC;gBACC,aAAa,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,gBAAgB,CAAC,2BAA2B,CAAA;YACrF,CAAC;YACD,OAAO,aAAa,CAAA;QACxB,CAAC;;;OAAA;IAED,sBAAW,+BAAS;aAApB;YACI,IAAI,CAAC,IAAA,kBAAW,EAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,gBAAgB,CAAC,EAAE,CAAC;gBACtD,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,gBAAgB,KAAK,KAAK,CAAA;YAC1D,CAAC;YACD,IAAI,CAAC,IAAA,kBAAW,EAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,eAAe,CAAC,EAAE,CAAC;gBACrD,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,eAAe,CAAA;YAC/C,CAAC;YACD,OAAO,IAAI,CAAC,kBAAkB,CAAA;QAClC,CAAC;;;OAAA;IAEM,iCAAc,GAArB;;QACI,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACjB,oDAAoD;YACpD,4BAA4B;YAC5B,8CAA8C;YAC9C,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;gBACpB,OAAM;YACV,CAAC;YACD,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAA;YAC1B,IAAI,CAAC,eAAe,EAAE,CAAA;YACtB,IAAI,CAAC,cAAc,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,yBAAyB,CAAC,CAAA;QAC7F,CAAC;aAAM,CAAC;YACJ,aAAa,CAAC,MAAA,IAAI,CAAC,cAAc,mCAAI,SAAS,CAAC,CAAA;YAC/C,MAAA,IAAI,CAAC,kBAAkB,0CAAE,IAAI,EAAE,CAAA;YAC/B,IAAI,CAAC,iBAAiB,EAAE,CAAA;QAC5B,CAAC;IACL,CAAC;IAEM,iCAAc,GAArB,UAAsB,QAAsB;;QACxC,IAAM,KAAK,GAAG,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAA;QAEpC,IAAI,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;YAC5B,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,QAAQ;gBAC9B,GAAC,wCAA4B,IAAG,KAAK;oBACvC,CAAA;QACN,CAAC;QACD,uDAAuD;QACvD,IAAI,CAAC,kBAAkB,GAAG,KAAK,CAAA;QAC/B,IAAI,CAAC,cAAc,EAAE,CAAA;IACzB,CAAC;IAEM,oCAAiB,GAAxB;QACI,IAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAA;QAC3B,IAAI,CAAC,OAAO,GAAG,SAAS,CAAA;QACxB,OAAO,MAAM,CAAA;IACjB,CAAC;IAEO,+BAAY,GAApB,UAAqB,KAAyB;QAC1C,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,aAAa,EAAE,WAAW,CAAC,CAAA;IACnD,CAAC;IAEO,kCAAe,GAAvB;QAAA,iBAoBC;QAnBG,IAAI,CAAC,gBAAM,IAAI,CAAC,kBAAQ,EAAE,CAAC;YACvB,OAAM;QACV,CAAC;QAED,IAAA,wBAAgB,EAAC,gBAAM,EAAE,cAAc,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;QAEhE,IAAA,wBAAgB,EAAC,kBAAQ,EAAE,OAAO,EAAE,UAAC,CAAC,IAAK,OAAA,KAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAI,gBAAM,aAAN,gBAAM,uBAAN,gBAAM,CAAE,KAAK,CAAA,CAAe,CAAC,EAAjD,CAAiD,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAA;QAChH,IAAA,wBAAgB,EAAC,kBAAQ,EAAE,WAAW,EAAE,UAAC,CAAC,IAAK,OAAA,KAAI,CAAC,YAAY,CAAC,CAAC,CAAC,KAAI,gBAAM,aAAN,gBAAM,uBAAN,gBAAM,CAAE,KAAK,CAAA,CAAe,CAAC,EAArD,CAAqD,EAAE;YAClG,OAAO,EAAE,IAAI;SAChB,CAAC,CAAA;QAEF,IAAI,CAAC,kBAAkB,GAAG,IAAI,+CAAqB,CAC/C,IAAI,CAAC,QAAQ,EACb,wDAA8B,EAC9B,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAC/B,CAAA;QACD,IAAI,CAAC,kBAAkB,CAAC,cAAc,EAAE,CAAA;QAExC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAA;IAC5B,CAAC;IAEO,iCAAc,GAAtB,UAAuB,CAAa,EAAE,IAAY;QAC9C,wDAAwD;QACxD,+CAA+C;QAC/C,4CAA4C;QAE5C,IAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,OAAO,EAAE,CAAA;QACrD,IAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,OAAO,EAAE,CAAA;QACrD,IAAM,aAAa,GAAG,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,aAAa,EAAE,CAAA;QAEjE,IAAM,eAAe,GAAG,8BAA8B,CAAC,IAAA,kCAAc,EAAC,CAAC,CAAC,EAAE,CAAC,OAAO,EAAE,QAAQ,CAAC,EAAE,aAAa,CAAC,CAAA;QAE7G,OAAO;YACH,CAAC,EAAE,CAAC,CAAC,OAAO,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;YAC9C,CAAC,EAAE,CAAC,CAAC,OAAO,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;YAC9C,YAAY,EAAE,eAAe;YAC7B,IAAI,MAAA;SACP,CAAA;IACL,CAAC;IAEO,2BAAQ,GAAhB,UAAiB,CAAa,EAAE,IAAsB;;QAAtB,qBAAA,EAAA,cAAsB;QAClD,IAAI,IAAA,kCAAkB,EAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,EAAE,CAAC;YACxD,OAAM;QACV,CAAC;QAED,IAAM,UAAU,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC,EAAE,IAAI,CAAC,CAAA;QAE/C,IAAI,MAAA,IAAI,CAAC,UAAU,0CAAE,WAAW,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC;YAC3E,IAAI,CAAC,QAAQ,uBACN,UAAU,KACb,IAAI,EAAE,WAAW,IACnB,CAAA;QACN,CAAC;QAED,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAA;IAC7B,CAAC;IAEO,+BAAY,GAApB,UAAqB,CAAQ;QAA7B,iBAUC;QATG,IAAI,IAAA,kCAAkB,EAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,EAAE,CAAC;YACxD,OAAM;QACV,CAAC;QAED,YAAY,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAA;QAEpC,IAAI,CAAC,iBAAiB,GAAG,UAAU,CAAC;YAChC,KAAI,CAAC,QAAQ,CAAC,KAAI,CAAC,cAAc,CAAC,CAAe,EAAE,WAAW,CAAC,CAAC,CAAA;QACpE,CAAC,EAAE,GAAG,CAAC,CAAA;IACX,CAAC;IAEO,2BAAQ,GAAhB,UAAiB,UAAsB;QACnC,IAAI,CAAC,gBAAM,EAAE,CAAC;YACV,OAAM;QACV,CAAC;QAED,sCAAsC;QACtC,IAAM,GAAG,GAAG,gBAAM,CAAC,QAAQ,CAAC,IAAI,CAAA;QAEhC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,EAAE,CAAA;QAEjC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;YACrB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,CAAA;QAC1B,CAAC;QAED,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;IACtC,CAAC;IAEO,yBAAM,GAAd;QACI,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,IAAA,oBAAa,EAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YAC/C,OAAM;QACV,CAAC;QAED,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,WAAW,EAAE;YAC/B,aAAa,EAAE,IAAI,CAAC,iBAAiB,EAAE;SAC1C,CAAC,CAAA;IACN,CAAC;IACL,eAAC;AAAD,CAAC,AA/KD,IA+KC;AA/KY,4BAAQ","sourcesContent":["import RageClick from './extensions/rageclick'\nimport { DeadClickCandidate, Properties, RemoteConfig } from './types'\nimport { PostHog } from './posthog-core'\n\nimport { document, window } from './utils/globals'\nimport { getEventTarget, getParentElement } from './autocapture-utils'\nimport { HEATMAPS_ENABLED_SERVER_SIDE } from './constants'\nimport { isNumber, isUndefined, isEmptyObject, isObject } from '@posthog/core'\nimport { createLogger } from './utils/logger'\nimport { isElementInToolbar, isElementNode, isTag } from './utils/element-utils'\nimport { DeadClicksAutocapture, isDeadClicksEnabledForHeatmaps } from './extensions/dead-clicks-autocapture'\nimport { includes } from '@posthog/core'\nimport { addEventListener } from './utils'\n\nconst DEFAULT_FLUSH_INTERVAL = 5000\n\nconst logger = createLogger('[Heatmaps]')\n\ntype HeatmapEventBuffer =\n | {\n [key: string]: Properties[]\n }\n | undefined\n\nfunction elementOrParentPositionMatches(el: Element | null, matches: string[], breakOnElement?: Element): boolean {\n let curEl: Element | null | false = el\n\n while (curEl && isElementNode(curEl) && !isTag(curEl, 'body')) {\n if (curEl === breakOnElement) {\n return false\n }\n\n if (includes(matches, window?.getComputedStyle(curEl).position)) {\n return true\n }\n\n curEl = getParentElement(curEl)\n }\n\n return false\n}\n\nfunction isValidMouseEvent(e: unknown): e is MouseEvent {\n return isObject(e) && 'clientX' in e && 'clientY' in e && isNumber(e.clientX) && isNumber(e.clientY)\n}\n\nexport class Heatmaps {\n instance: PostHog\n rageclicks = new RageClick()\n _enabledServerSide: boolean = false\n _initialized = false\n _mouseMoveTimeout: ReturnType<typeof setTimeout> | undefined\n\n // TODO: Periodically flush this if no other event has taken care of it\n private _buffer: HeatmapEventBuffer\n private _flushInterval: ReturnType<typeof setInterval> | null = null\n private _deadClicksCapture: DeadClicksAutocapture | undefined\n\n constructor(instance: PostHog) {\n this.instance = instance\n this._enabledServerSide = !!this.instance.persistence?.props[HEATMAPS_ENABLED_SERVER_SIDE]\n }\n\n public get flushIntervalMilliseconds(): number {\n let flushInterval = DEFAULT_FLUSH_INTERVAL\n if (\n isObject(this.instance.config.capture_heatmaps) &&\n this.instance.config.capture_heatmaps.flush_interval_milliseconds\n ) {\n flushInterval = this.instance.config.capture_heatmaps.flush_interval_milliseconds\n }\n return flushInterval\n }\n\n public get isEnabled(): boolean {\n if (!isUndefined(this.instance.config.capture_heatmaps)) {\n return this.instance.config.capture_heatmaps !== false\n }\n if (!isUndefined(this.instance.config.enable_heatmaps)) {\n return this.instance.config.enable_heatmaps\n }\n return this._enabledServerSide\n }\n\n public startIfEnabled(): void {\n if (this.isEnabled) {\n // nested if here since we only want to run the else\n // if this.enabled === false\n // not if this method is called more than once\n if (this._initialized) {\n return\n }\n logger.info('starting...')\n this._setupListeners()\n this._flushInterval = setInterval(this._flush.bind(this), this.flushIntervalMilliseconds)\n } else {\n clearInterval(this._flushInterval ?? undefined)\n this._deadClicksCapture?.stop()\n this.getAndClearBuffer()\n }\n }\n\n public onRemoteConfig(response: RemoteConfig) {\n const optIn = !!response['heatmaps']\n\n if (this.instance.persistence) {\n this.instance.persistence.register({\n [HEATMAPS_ENABLED_SERVER_SIDE]: optIn,\n })\n }\n // store this in-memory in case persistence is disabled\n this._enabledServerSide = optIn\n this.startIfEnabled()\n }\n\n public getAndClearBuffer(): HeatmapEventBuffer {\n const buffer = this._buffer\n this._buffer = undefined\n return buffer\n }\n\n private _onDeadClick(click: DeadClickCandidate): void {\n this._onClick(click.originalEvent, 'deadclick')\n }\n\n private _setupListeners(): void {\n if (!window || !document) {\n return\n }\n\n addEventListener(window, 'beforeunload', this._flush.bind(this))\n\n addEventListener(document, 'click', (e) => this._onClick((e || window?.event) as MouseEvent), { capture: true })\n addEventListener(document, 'mousemove', (e) => this._onMouseMove((e || window?.event) as MouseEvent), {\n capture: true,\n })\n\n this._deadClicksCapture = new DeadClicksAutocapture(\n this.instance,\n isDeadClicksEnabledForHeatmaps,\n this._onDeadClick.bind(this)\n )\n this._deadClicksCapture.startIfEnabled()\n\n this._initialized = true\n }\n\n private _getProperties(e: MouseEvent, type: string): Properties {\n // We need to know if the target element is fixed or not\n // If fixed then we won't account for scrolling\n // If not then we will account for scrolling\n\n const scrollY = this.instance.scrollManager.scrollY()\n const scrollX = this.instance.scrollManager.scrollX()\n const scrollElement = this.instance.scrollManager.scrollElement()\n\n const isFixedOrSticky = elementOrParentPositionMatches(getEventTarget(e), ['fixed', 'sticky'], scrollElement)\n\n return {\n x: e.clientX + (isFixedOrSticky ? 0 : scrollX),\n y: e.clientY + (isFixedOrSticky ? 0 : scrollY),\n target_fixed: isFixedOrSticky,\n type,\n }\n }\n\n private _onClick(e: MouseEvent, type: string = 'click'): void {\n if (isElementInToolbar(e.target) || !isValidMouseEvent(e)) {\n return\n }\n\n const properties = this._getProperties(e, type)\n\n if (this.rageclicks?.isRageClick(e.clientX, e.clientY, new Date().getTime())) {\n this._capture({\n ...properties,\n type: 'rageclick',\n })\n }\n\n this._capture(properties)\n }\n\n private _onMouseMove(e: Event): void {\n if (isElementInToolbar(e.target) || !isValidMouseEvent(e)) {\n return\n }\n\n clearTimeout(this._mouseMoveTimeout)\n\n this._mouseMoveTimeout = setTimeout(() => {\n this._capture(this._getProperties(e as MouseEvent, 'mousemove'))\n }, 500)\n }\n\n private _capture(properties: Properties): void {\n if (!window) {\n return\n }\n\n // TODO we should be able to mask this\n const url = window.location.href\n\n this._buffer = this._buffer || {}\n\n if (!this._buffer[url]) {\n this._buffer[url] = []\n }\n\n this._buffer[url].push(properties)\n }\n\n private _flush(): void {\n if (!this._buffer || isEmptyObject(this._buffer)) {\n return\n }\n\n this.instance.capture('$$heatmap', {\n $heatmap_data: this.getAndClearBuffer(),\n })\n }\n}\n"]}
1
+ {"version":3,"file":"heatmaps.js","sourceRoot":"","sources":["../../src/heatmaps.ts"],"names":[],"mappings":"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","sourcesContent":["import RageClick from './extensions/rageclick'\nimport { DeadClickCandidate, Properties, RemoteConfig } from './types'\nimport { PostHog } from './posthog-core'\n\nimport { document, window } from './utils/globals'\nimport { getEventTarget, getParentElement } from './autocapture-utils'\nimport { HEATMAPS_ENABLED_SERVER_SIDE } from './constants'\nimport { isNumber, isUndefined, isEmptyObject, isObject } from '@posthog/core'\nimport { createLogger } from './utils/logger'\nimport { isElementInToolbar, isElementNode, isTag } from './utils/element-utils'\nimport { DeadClicksAutocapture, isDeadClicksEnabledForHeatmaps } from './extensions/dead-clicks-autocapture'\nimport { includes } from '@posthog/core'\nimport { addEventListener, extendArray } from './utils'\nimport { maskQueryParams } from './utils/request-utils'\nimport { PERSONAL_DATA_CAMPAIGN_PARAMS, MASKED } from './utils/event-utils'\n\nconst DEFAULT_FLUSH_INTERVAL = 5000\n\nconst logger = createLogger('[Heatmaps]')\n\ntype HeatmapEventBuffer =\n | {\n [key: string]: Properties[]\n }\n | undefined\n\nfunction elementOrParentPositionMatches(el: Element | null, matches: string[], breakOnElement?: Element): boolean {\n let curEl: Element | null | false = el\n\n while (curEl && isElementNode(curEl) && !isTag(curEl, 'body')) {\n if (curEl === breakOnElement) {\n return false\n }\n\n if (includes(matches, window?.getComputedStyle(curEl).position)) {\n return true\n }\n\n curEl = getParentElement(curEl)\n }\n\n return false\n}\n\nfunction isValidMouseEvent(e: unknown): e is MouseEvent {\n return isObject(e) && 'clientX' in e && 'clientY' in e && isNumber(e.clientX) && isNumber(e.clientY)\n}\n\nexport class Heatmaps {\n instance: PostHog\n rageclicks = new RageClick()\n _enabledServerSide: boolean = false\n _initialized = false\n _mouseMoveTimeout: ReturnType<typeof setTimeout> | undefined\n\n // TODO: Periodically flush this if no other event has taken care of it\n private _buffer: HeatmapEventBuffer\n private _flushInterval: ReturnType<typeof setInterval> | null = null\n private _deadClicksCapture: DeadClicksAutocapture | undefined\n\n constructor(instance: PostHog) {\n this.instance = instance\n this._enabledServerSide = !!this.instance.persistence?.props[HEATMAPS_ENABLED_SERVER_SIDE]\n }\n\n public get flushIntervalMilliseconds(): number {\n let flushInterval = DEFAULT_FLUSH_INTERVAL\n if (\n isObject(this.instance.config.capture_heatmaps) &&\n this.instance.config.capture_heatmaps.flush_interval_milliseconds\n ) {\n flushInterval = this.instance.config.capture_heatmaps.flush_interval_milliseconds\n }\n return flushInterval\n }\n\n public get isEnabled(): boolean {\n if (!isUndefined(this.instance.config.capture_heatmaps)) {\n return this.instance.config.capture_heatmaps !== false\n }\n if (!isUndefined(this.instance.config.enable_heatmaps)) {\n return this.instance.config.enable_heatmaps\n }\n return this._enabledServerSide\n }\n\n public startIfEnabled(): void {\n if (this.isEnabled) {\n // nested if here since we only want to run the else\n // if this.enabled === false\n // not if this method is called more than once\n if (this._initialized) {\n return\n }\n logger.info('starting...')\n this._setupListeners()\n this._flushInterval = setInterval(this._flush.bind(this), this.flushIntervalMilliseconds)\n } else {\n clearInterval(this._flushInterval ?? undefined)\n this._deadClicksCapture?.stop()\n this.getAndClearBuffer()\n }\n }\n\n public onRemoteConfig(response: RemoteConfig) {\n const optIn = !!response['heatmaps']\n\n if (this.instance.persistence) {\n this.instance.persistence.register({\n [HEATMAPS_ENABLED_SERVER_SIDE]: optIn,\n })\n }\n // store this in-memory in case persistence is disabled\n this._enabledServerSide = optIn\n this.startIfEnabled()\n }\n\n public getAndClearBuffer(): HeatmapEventBuffer {\n const buffer = this._buffer\n this._buffer = undefined\n return buffer\n }\n\n private _onDeadClick(click: DeadClickCandidate): void {\n this._onClick(click.originalEvent, 'deadclick')\n }\n\n private _setupListeners(): void {\n if (!window || !document) {\n return\n }\n\n addEventListener(window, 'beforeunload', this._flush.bind(this))\n\n addEventListener(document, 'click', (e) => this._onClick((e || window?.event) as MouseEvent), { capture: true })\n addEventListener(document, 'mousemove', (e) => this._onMouseMove((e || window?.event) as MouseEvent), {\n capture: true,\n })\n\n this._deadClicksCapture = new DeadClicksAutocapture(\n this.instance,\n isDeadClicksEnabledForHeatmaps,\n this._onDeadClick.bind(this)\n )\n this._deadClicksCapture.startIfEnabled()\n\n this._initialized = true\n }\n\n private _getProperties(e: MouseEvent, type: string): Properties {\n // We need to know if the target element is fixed or not\n // If fixed then we won't account for scrolling\n // If not then we will account for scrolling\n\n const scrollY = this.instance.scrollManager.scrollY()\n const scrollX = this.instance.scrollManager.scrollX()\n const scrollElement = this.instance.scrollManager.scrollElement()\n\n const isFixedOrSticky = elementOrParentPositionMatches(getEventTarget(e), ['fixed', 'sticky'], scrollElement)\n\n return {\n x: e.clientX + (isFixedOrSticky ? 0 : scrollX),\n y: e.clientY + (isFixedOrSticky ? 0 : scrollY),\n target_fixed: isFixedOrSticky,\n type,\n }\n }\n\n private _onClick(e: MouseEvent, type: string = 'click'): void {\n if (isElementInToolbar(e.target) || !isValidMouseEvent(e)) {\n return\n }\n\n const properties = this._getProperties(e, type)\n\n if (this.rageclicks?.isRageClick(e.clientX, e.clientY, new Date().getTime())) {\n this._capture({\n ...properties,\n type: 'rageclick',\n })\n }\n\n this._capture(properties)\n }\n\n private _onMouseMove(e: Event): void {\n if (isElementInToolbar(e.target) || !isValidMouseEvent(e)) {\n return\n }\n\n clearTimeout(this._mouseMoveTimeout)\n\n this._mouseMoveTimeout = setTimeout(() => {\n this._capture(this._getProperties(e as MouseEvent, 'mousemove'))\n }, 500)\n }\n\n private _capture(properties: Properties): void {\n if (!window) {\n return\n }\n\n const href = window.location.href\n\n // mask url query params\n const maskPersonalDataProperties = this.instance.config.mask_personal_data_properties\n const customPersonalDataProperties = this.instance.config.custom_personal_data_properties\n\n const paramsToMask = maskPersonalDataProperties\n ? extendArray([], PERSONAL_DATA_CAMPAIGN_PARAMS, customPersonalDataProperties || [])\n : []\n\n const url = maskQueryParams(href, paramsToMask, MASKED)\n\n this._buffer = this._buffer || {}\n\n if (!this._buffer[url]) {\n this._buffer[url] = []\n }\n\n this._buffer[url].push(properties)\n }\n\n private _flush(): void {\n if (!this._buffer || isEmptyObject(this._buffer)) {\n return\n }\n\n this.instance.capture('$$heatmap', {\n $heatmap_data: this.getAndClearBuffer(),\n })\n }\n}\n"]}
@@ -2560,7 +2560,7 @@ var PostHog = /** @class */ (function () {
2560
2560
  * @param {Object} [config.capture_properties] Set of properties to be captured along with the opt-in action
2561
2561
  */
2562
2562
  PostHog.prototype.opt_in_capturing = function (options) {
2563
- var _a;
2563
+ var _a, _b;
2564
2564
  if (this.config.cookieless_mode === 'always') {
2565
2565
  logger_1.logger.warn('Consent opt in/out is not valid with cookieless_mode="always" and will be ignored');
2566
2566
  return;
@@ -2569,6 +2569,7 @@ var PostHog = /** @class */ (function () {
2569
2569
  // If the user has explicitly opted out on_reject mode, then before we can start sending regular non-cookieless events
2570
2570
  // we need to reset the instance to ensure that there is no leaking of state or data between the cookieless and regular events
2571
2571
  this.reset(true);
2572
+ (_a = this.sessionManager) === null || _a === void 0 ? void 0 : _a.destroy();
2572
2573
  this.sessionManager = new sessionid_1.SessionIdManager(this);
2573
2574
  if (this.persistence) {
2574
2575
  this.sessionPropsManager = new session_props_1.SessionPropsManager(this, this.sessionManager, this.persistence);
@@ -2586,7 +2587,7 @@ var PostHog = /** @class */ (function () {
2586
2587
  }
2587
2588
  // Don't capture if captureEventName is null or false
2588
2589
  if ((0, core_1.isUndefined)(options === null || options === void 0 ? void 0 : options.captureEventName) || (options === null || options === void 0 ? void 0 : options.captureEventName)) {
2589
- this.capture((_a = options === null || options === void 0 ? void 0 : options.captureEventName) !== null && _a !== void 0 ? _a : '$opt_in', options === null || options === void 0 ? void 0 : options.captureProperties, { send_instantly: true });
2590
+ this.capture((_b = options === null || options === void 0 ? void 0 : options.captureEventName) !== null && _b !== void 0 ? _b : '$opt_in', options === null || options === void 0 ? void 0 : options.captureProperties, { send_instantly: true });
2590
2591
  }
2591
2592
  if (this.config.capture_pageview) {
2592
2593
  this._captureInitialPageview();
@@ -2610,7 +2611,7 @@ var PostHog = /** @class */ (function () {
2610
2611
  * @public
2611
2612
  */
2612
2613
  PostHog.prototype.opt_out_capturing = function () {
2613
- var _a;
2614
+ var _a, _b;
2614
2615
  if (this.config.cookieless_mode === 'always') {
2615
2616
  logger_1.logger.warn('Consent opt in/out is not valid with cookieless_mode="always" and will be ignored');
2616
2617
  return;
@@ -2627,9 +2628,10 @@ var PostHog = /** @class */ (function () {
2627
2628
  distinct_id: constants_1.COOKIELESS_SENTINEL_VALUE,
2628
2629
  $device_id: null,
2629
2630
  });
2631
+ (_a = this.sessionManager) === null || _a === void 0 ? void 0 : _a.destroy();
2630
2632
  this.sessionManager = undefined;
2631
2633
  this.sessionPropsManager = undefined;
2632
- (_a = this.sessionRecording) === null || _a === void 0 ? void 0 : _a.stopRecording();
2634
+ (_b = this.sessionRecording) === null || _b === void 0 ? void 0 : _b.stopRecording();
2633
2635
  this.sessionRecording = undefined;
2634
2636
  this._captureInitialPageview();
2635
2637
  }