@leanbase-giangnd/js 0.1.2 → 0.1.5

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.
@@ -329,7 +329,6 @@ var leanbase = (function (record) {
329
329
  const isNumber = (x)=>'[object Number]' == type_utils_toString.call(x);
330
330
  const isBoolean = (x)=>'[object Boolean]' === type_utils_toString.call(x);
331
331
  const isFormData = (x)=>x instanceof FormData;
332
- const isFile = (x)=>x instanceof File;
333
332
  const isPlainError = (x)=>x instanceof Error;
334
333
 
335
334
  function clampToRange(value, min, max, logger, fallbackValue) {
@@ -1908,7 +1907,7 @@ var leanbase = (function (record) {
1908
1907
 
1909
1908
  /* eslint-disable no-console */
1910
1909
  const PREFIX = '[Leanbase]';
1911
- const logger$3 = {
1910
+ const logger$2 = {
1912
1911
  info: (...args) => {
1913
1912
  if (typeof console !== 'undefined') {
1914
1913
  console.log(PREFIX, ...args);
@@ -2206,7 +2205,7 @@ var leanbase = (function (record) {
2206
2205
  if (!matchedSubDomain) {
2207
2206
  const originalMatch = originalCookieDomainFn(hostname);
2208
2207
  if (originalMatch !== matchedSubDomain) {
2209
- logger$3.info('Warning: cookie subdomain discovery mismatch', originalMatch, matchedSubDomain);
2208
+ logger$2.info('Warning: cookie subdomain discovery mismatch', originalMatch, matchedSubDomain);
2210
2209
  }
2211
2210
  matchedSubDomain = originalMatch;
2212
2211
  }
@@ -2218,7 +2217,7 @@ var leanbase = (function (record) {
2218
2217
  const cookieStore = {
2219
2218
  _is_supported: () => !!document,
2220
2219
  _error: function (msg) {
2221
- logger$3.error('cookieStore error: ' + msg);
2220
+ logger$2.error('cookieStore error: ' + msg);
2222
2221
  },
2223
2222
  _get: function (name) {
2224
2223
  if (!document) {
@@ -2267,7 +2266,7 @@ var leanbase = (function (record) {
2267
2266
  const new_cookie_val = name + '=' + encodeURIComponent(JSON.stringify(value)) + expires + '; SameSite=Lax; path=/' + cdomain + secure;
2268
2267
  // 4096 bytes is the size at which some browsers (e.g. firefox) will not store a cookie, warn slightly before that
2269
2268
  if (new_cookie_val.length > 4096 * 0.9) {
2270
- logger$3.warn('cookieStore warning: large cookie, len=' + new_cookie_val.length);
2269
+ logger$2.warn('cookieStore warning: large cookie, len=' + new_cookie_val.length);
2271
2270
  }
2272
2271
  document.cookie = new_cookie_val;
2273
2272
  return new_cookie_val;
@@ -2309,13 +2308,13 @@ var leanbase = (function (record) {
2309
2308
  supported = false;
2310
2309
  }
2311
2310
  if (!supported) {
2312
- logger$3.error('localStorage unsupported; falling back to cookie store');
2311
+ logger$2.error('localStorage unsupported; falling back to cookie store');
2313
2312
  }
2314
2313
  _localStorage_supported = supported;
2315
2314
  return supported;
2316
2315
  },
2317
2316
  _error: function (msg) {
2318
- logger$3.error('localStorage error: ' + msg);
2317
+ logger$2.error('localStorage error: ' + msg);
2319
2318
  },
2320
2319
  _get: function (name) {
2321
2320
  try {
@@ -2401,7 +2400,7 @@ var leanbase = (function (record) {
2401
2400
  return true;
2402
2401
  },
2403
2402
  _error: function (msg) {
2404
- logger$3.error('memoryStorage error: ' + msg);
2403
+ logger$2.error('memoryStorage error: ' + msg);
2405
2404
  },
2406
2405
  _get: function (name) {
2407
2406
  return memoryStorage[name] || null;
@@ -2442,7 +2441,7 @@ var leanbase = (function (record) {
2442
2441
  return sessionStorageSupported;
2443
2442
  },
2444
2443
  _error: function (msg) {
2445
- logger$3.error('sessionStorage error: ', msg);
2444
+ logger$2.error('sessionStorage error: ', msg);
2446
2445
  },
2447
2446
  _get: function (name) {
2448
2447
  try {
@@ -2491,21 +2490,6 @@ var leanbase = (function (record) {
2491
2490
  location.href = url;
2492
2491
  return location;
2493
2492
  };
2494
- const formDataToQuery = function (formdata, arg_separator = '&') {
2495
- let use_val;
2496
- let use_key;
2497
- const tph_arr = [];
2498
- each(formdata, function (val, key) {
2499
- // the key might be literally the string undefined for e.g. if {undefined: 'something'}
2500
- if (isUndefined(val) || isUndefined(key) || key === 'undefined') {
2501
- return;
2502
- }
2503
- use_val = encodeURIComponent(isFile(val) ? val.name : val.toString());
2504
- use_key = encodeURIComponent(key);
2505
- tph_arr[tph_arr.length] = use_key + '=' + use_val;
2506
- });
2507
- return tph_arr.join(arg_separator);
2508
- };
2509
2493
  // NOTE: Once we get rid of IE11/op_mini we can start using URLSearchParams
2510
2494
  const getQueryParam = function (url, param) {
2511
2495
  const withoutHash = url.split('#')[0] || '';
@@ -2529,7 +2513,7 @@ var leanbase = (function (record) {
2529
2513
  try {
2530
2514
  result = decodeURIComponent(result);
2531
2515
  } catch {
2532
- logger$3.error('Skipping decoding for malformed query param: ' + result);
2516
+ logger$2.error('Skipping decoding for malformed query param: ' + result);
2533
2517
  }
2534
2518
  return result.replace(/\+/g, ' ');
2535
2519
  }
@@ -2863,7 +2847,7 @@ var leanbase = (function (record) {
2863
2847
  }
2864
2848
  };
2865
2849
 
2866
- var version = "0.1.2";
2850
+ var version = "0.1.5";
2867
2851
  var packageInfo = {
2868
2852
  version: version};
2869
2853
 
@@ -3128,7 +3112,7 @@ var leanbase = (function (record) {
3128
3112
  this._storage = this._buildStorage(config);
3129
3113
  this.load();
3130
3114
  if (config.debug) {
3131
- logger$3.info('Persistence loaded', config['persistence'], {
3115
+ logger$2.info('Persistence loaded', config['persistence'], {
3132
3116
  ...this.props
3133
3117
  });
3134
3118
  }
@@ -3144,7 +3128,7 @@ var leanbase = (function (record) {
3144
3128
  }
3145
3129
  _buildStorage(config) {
3146
3130
  if (CASE_INSENSITIVE_PERSISTENCE_TYPES.indexOf(config['persistence'].toLowerCase()) === -1) {
3147
- logger$3.info('Unknown persistence type ' + config['persistence'] + '; falling back to localStorage+cookie');
3131
+ logger$2.info('Unknown persistence type ' + config['persistence'] + '; falling back to localStorage+cookie');
3148
3132
  config['persistence'] = 'localStorage+cookie';
3149
3133
  }
3150
3134
  let store;
@@ -3780,7 +3764,7 @@ var leanbase = (function (record) {
3780
3764
  text = `${text} ${getNestedSpanText(child)}`.trim();
3781
3765
  }
3782
3766
  } catch (e) {
3783
- logger$3.error('[AutoCapture]', e);
3767
+ logger$2.error('[AutoCapture]', e);
3784
3768
  }
3785
3769
  }
3786
3770
  });
@@ -4082,7 +4066,7 @@ var leanbase = (function (record) {
4082
4066
  }
4083
4067
  _addDomEventHandlers() {
4084
4068
  if (!this.isBrowserSupported()) {
4085
- logger$3.info('Disabling Automatic Event Collection because this browser is not supported');
4069
+ logger$2.info('Disabling Automatic Event Collection because this browser is not supported');
4086
4070
  return;
4087
4071
  }
4088
4072
  if (!win || !document) {
@@ -4093,7 +4077,7 @@ var leanbase = (function (record) {
4093
4077
  try {
4094
4078
  this._captureEvent(e);
4095
4079
  } catch (error) {
4096
- logger$3.error('Failed to capture event', error);
4080
+ logger$2.error('Failed to capture event', error);
4097
4081
  }
4098
4082
  };
4099
4083
  addEventListener(document, 'submit', handler, {
@@ -4278,7 +4262,7 @@ var leanbase = (function (record) {
4278
4262
  this._windowIdGenerator = windowIdGenerator || uuidv7;
4279
4263
  const persistenceName = this._config['persistence_name'] || this._config['token'];
4280
4264
  const desiredTimeout = this._config['session_idle_timeout_seconds'] || DEFAULT_SESSION_IDLE_TIMEOUT_SECONDS;
4281
- this._sessionTimeoutMs = clampToRange(desiredTimeout, MIN_SESSION_IDLE_TIMEOUT_SECONDS, MAX_SESSION_IDLE_TIMEOUT_SECONDS, logger$3, DEFAULT_SESSION_IDLE_TIMEOUT_SECONDS) * 1000;
4265
+ this._sessionTimeoutMs = clampToRange(desiredTimeout, MIN_SESSION_IDLE_TIMEOUT_SECONDS, MAX_SESSION_IDLE_TIMEOUT_SECONDS, logger$2, DEFAULT_SESSION_IDLE_TIMEOUT_SECONDS) * 1000;
4282
4266
  instance.register({
4283
4267
  $configured_session_timeout_ms: this._sessionTimeoutMs
4284
4268
  });
@@ -4305,7 +4289,7 @@ var leanbase = (function (record) {
4305
4289
  const sessionStartTimestamp = uuid7ToTimestampMs(this._config.bootstrap.sessionID);
4306
4290
  this._setSessionId(this._config.bootstrap.sessionID, new Date().getTime(), sessionStartTimestamp);
4307
4291
  } catch (e) {
4308
- logger$3.error('Invalid sessionID in bootstrap', e);
4292
+ logger$2.error('Invalid sessionID in bootstrap', e);
4309
4293
  }
4310
4294
  }
4311
4295
  this._listenToReloadWindow();
@@ -4446,7 +4430,7 @@ var leanbase = (function (record) {
4446
4430
  if (noSessionId || activityTimeout || sessionPastMaximumLength) {
4447
4431
  sessionId = this._sessionIdGenerator();
4448
4432
  windowId = this._windowIdGenerator();
4449
- logger$3.info('new session ID generated', {
4433
+ logger$2.info('new session ID generated', {
4450
4434
  sessionId,
4451
4435
  windowId,
4452
4436
  changeReason: {
@@ -4635,10 +4619,10 @@ var leanbase = (function (record) {
4635
4619
  lastContentY = Math.ceil(lastContentY);
4636
4620
  maxContentY = Math.ceil(maxContentY);
4637
4621
  // if the maximum scroll height is near 0, then the percentage is 1
4638
- const lastScrollPercentage = maxScrollHeight <= 1 ? 1 : clampToRange(lastScrollY / maxScrollHeight, 0, 1, logger$3);
4639
- const maxScrollPercentage = maxScrollHeight <= 1 ? 1 : clampToRange(maxScrollY / maxScrollHeight, 0, 1, logger$3);
4640
- const lastContentPercentage = maxContentHeight <= 1 ? 1 : clampToRange(lastContentY / maxContentHeight, 0, 1, logger$3);
4641
- const maxContentPercentage = maxContentHeight <= 1 ? 1 : clampToRange(maxContentY / maxContentHeight, 0, 1, logger$3);
4622
+ const lastScrollPercentage = maxScrollHeight <= 1 ? 1 : clampToRange(lastScrollY / maxScrollHeight, 0, 1, logger$2);
4623
+ const maxScrollPercentage = maxScrollHeight <= 1 ? 1 : clampToRange(maxScrollY / maxScrollHeight, 0, 1, logger$2);
4624
+ const lastContentPercentage = maxContentHeight <= 1 ? 1 : clampToRange(lastContentY / maxContentHeight, 0, 1, logger$2);
4625
+ const maxContentPercentage = maxContentHeight <= 1 ? 1 : clampToRange(maxContentY / maxContentHeight, 0, 1, logger$2);
4642
4626
  properties = extend(properties, {
4643
4627
  $prev_pageview_last_scroll: lastScrollY,
4644
4628
  $prev_pageview_last_scroll_percentage: lastScrollPercentage,
@@ -4801,84 +4785,129 @@ var leanbase = (function (record) {
4801
4785
  // It would be very bad if posthog-js caused a permission prompt to appear on every page load.
4802
4786
  };
4803
4787
 
4788
+ // Use a safe global target (prefer `win`, fallback to globalThis)
4789
+ const _target = win ?? globalThis;
4790
+ _target.__PosthogExtensions__ = _target.__PosthogExtensions__ || {};
4791
+ // Expose rrweb.record under the same contract
4792
+ _target.__PosthogExtensions__.rrweb = _target.__PosthogExtensions__.rrweb || {
4793
+ record: record.record
4794
+ };
4795
+ // Provide initSessionRecording if not present — return a new LazyLoadedSessionRecording when called
4796
+ _target.__PosthogExtensions__.initSessionRecording = _target.__PosthogExtensions__.initSessionRecording || (instance => {
4797
+ const factory = _target.__PosthogExtensions__._initSessionRecordingFactory;
4798
+ if (factory) {
4799
+ return factory(instance);
4800
+ }
4801
+ // If no factory is registered yet, return undefined — callers should handle lazy-loading.
4802
+ return undefined;
4803
+ });
4804
+ // Provide a no-op loadExternalDependency that calls the callback immediately (since rrweb is bundled)
4805
+ _target.__PosthogExtensions__.loadExternalDependency = _target.__PosthogExtensions__.loadExternalDependency || ((instance, scriptName, cb) => {
4806
+ if (cb) cb(undefined);
4807
+ });
4808
+ // Provide rrwebPlugins object with network plugin factory if not present
4809
+ _target.__PosthogExtensions__.rrwebPlugins = _target.__PosthogExtensions__.rrwebPlugins || {};
4810
+ // Default to undefined; the lazy-loaded recorder will register the real factory when it initializes.
4811
+ _target.__PosthogExtensions__.rrwebPlugins.getRecordNetworkPlugin = _target.__PosthogExtensions__.rrwebPlugins.getRecordNetworkPlugin || (() => undefined);
4812
+
4813
+ // Type definitions copied from @rrweb/types@2.0.0-alpha.17 and rrweb-snapshot@2.0.0-alpha.17
4814
+ // Both packages are MIT licensed: https://github.com/rrweb-io/rrweb
4815
+ //
4816
+ // These types are copied here to avoid requiring users to install peer dependencies
4817
+ // solely for TypeScript type information.
4818
+ //
4819
+ // Original sources:
4820
+ // - @rrweb/types: https://github.com/rrweb-io/rrweb/tree/main/packages/@rrweb/types
4821
+ // - rrweb-snapshot: https://github.com/rrweb-io/rrweb/tree/main/packages/rrweb-snapshot
4822
+ var NodeType;
4823
+ (function (NodeType) {
4824
+ NodeType[NodeType["Document"] = 0] = "Document";
4825
+ NodeType[NodeType["DocumentType"] = 1] = "DocumentType";
4826
+ NodeType[NodeType["Element"] = 2] = "Element";
4827
+ NodeType[NodeType["Text"] = 3] = "Text";
4828
+ NodeType[NodeType["CDATA"] = 4] = "CDATA";
4829
+ NodeType[NodeType["Comment"] = 5] = "Comment";
4830
+ })(NodeType || (NodeType = {}));
4831
+ var EventType;
4832
+ (function (EventType) {
4833
+ EventType[EventType["DomContentLoaded"] = 0] = "DomContentLoaded";
4834
+ EventType[EventType["Load"] = 1] = "Load";
4835
+ EventType[EventType["FullSnapshot"] = 2] = "FullSnapshot";
4836
+ EventType[EventType["IncrementalSnapshot"] = 3] = "IncrementalSnapshot";
4837
+ EventType[EventType["Meta"] = 4] = "Meta";
4838
+ EventType[EventType["Custom"] = 5] = "Custom";
4839
+ EventType[EventType["Plugin"] = 6] = "Plugin";
4840
+ })(EventType || (EventType = {}));
4841
+ var IncrementalSource;
4842
+ (function (IncrementalSource) {
4843
+ IncrementalSource[IncrementalSource["Mutation"] = 0] = "Mutation";
4844
+ IncrementalSource[IncrementalSource["MouseMove"] = 1] = "MouseMove";
4845
+ IncrementalSource[IncrementalSource["MouseInteraction"] = 2] = "MouseInteraction";
4846
+ IncrementalSource[IncrementalSource["Scroll"] = 3] = "Scroll";
4847
+ IncrementalSource[IncrementalSource["ViewportResize"] = 4] = "ViewportResize";
4848
+ IncrementalSource[IncrementalSource["Input"] = 5] = "Input";
4849
+ IncrementalSource[IncrementalSource["TouchMove"] = 6] = "TouchMove";
4850
+ IncrementalSource[IncrementalSource["MediaInteraction"] = 7] = "MediaInteraction";
4851
+ IncrementalSource[IncrementalSource["StyleSheetRule"] = 8] = "StyleSheetRule";
4852
+ IncrementalSource[IncrementalSource["CanvasMutation"] = 9] = "CanvasMutation";
4853
+ IncrementalSource[IncrementalSource["Font"] = 10] = "Font";
4854
+ IncrementalSource[IncrementalSource["Log"] = 11] = "Log";
4855
+ IncrementalSource[IncrementalSource["Drag"] = 12] = "Drag";
4856
+ IncrementalSource[IncrementalSource["StyleDeclaration"] = 13] = "StyleDeclaration";
4857
+ IncrementalSource[IncrementalSource["Selection"] = 14] = "Selection";
4858
+ IncrementalSource[IncrementalSource["AdoptedStyleSheet"] = 15] = "AdoptedStyleSheet";
4859
+ IncrementalSource[IncrementalSource["CustomElement"] = 16] = "CustomElement";
4860
+ })(IncrementalSource || (IncrementalSource = {}));
4861
+ var MouseInteractions;
4862
+ (function (MouseInteractions) {
4863
+ MouseInteractions[MouseInteractions["MouseUp"] = 0] = "MouseUp";
4864
+ MouseInteractions[MouseInteractions["MouseDown"] = 1] = "MouseDown";
4865
+ MouseInteractions[MouseInteractions["Click"] = 2] = "Click";
4866
+ MouseInteractions[MouseInteractions["ContextMenu"] = 3] = "ContextMenu";
4867
+ MouseInteractions[MouseInteractions["DblClick"] = 4] = "DblClick";
4868
+ MouseInteractions[MouseInteractions["Focus"] = 5] = "Focus";
4869
+ MouseInteractions[MouseInteractions["Blur"] = 6] = "Blur";
4870
+ MouseInteractions[MouseInteractions["TouchStart"] = 7] = "TouchStart";
4871
+ MouseInteractions[MouseInteractions["TouchMove_Departed"] = 8] = "TouchMove_Departed";
4872
+ MouseInteractions[MouseInteractions["TouchEnd"] = 9] = "TouchEnd";
4873
+ MouseInteractions[MouseInteractions["TouchCancel"] = 10] = "TouchCancel";
4874
+ })(MouseInteractions || (MouseInteractions = {}));
4875
+ var PointerTypes;
4876
+ (function (PointerTypes) {
4877
+ PointerTypes[PointerTypes["Mouse"] = 0] = "Mouse";
4878
+ PointerTypes[PointerTypes["Pen"] = 1] = "Pen";
4879
+ PointerTypes[PointerTypes["Touch"] = 2] = "Touch";
4880
+ })(PointerTypes || (PointerTypes = {}));
4881
+ var MediaInteractions;
4882
+ (function (MediaInteractions) {
4883
+ MediaInteractions[MediaInteractions["Play"] = 0] = "Play";
4884
+ MediaInteractions[MediaInteractions["Pause"] = 1] = "Pause";
4885
+ MediaInteractions[MediaInteractions["Seeked"] = 2] = "Seeked";
4886
+ MediaInteractions[MediaInteractions["VolumeChange"] = 3] = "VolumeChange";
4887
+ MediaInteractions[MediaInteractions["RateChange"] = 4] = "RateChange";
4888
+ })(MediaInteractions || (MediaInteractions = {}));
4889
+ var CanvasContext;
4890
+ (function (CanvasContext) {
4891
+ CanvasContext[CanvasContext["2D"] = 0] = "2D";
4892
+ CanvasContext[CanvasContext["WebGL"] = 1] = "WebGL";
4893
+ CanvasContext[CanvasContext["WebGL2"] = 2] = "WebGL2";
4894
+ })(CanvasContext || (CanvasContext = {}));
4895
+
4804
4896
  const _createLogger = prefix => {
4805
4897
  return {
4806
- info: (...args) => logger$3.info(prefix, ...args),
4807
- warn: (...args) => logger$3.warn(prefix, ...args),
4808
- error: (...args) => logger$3.error(prefix, ...args),
4809
- critical: (...args) => logger$3.critical(prefix, ...args),
4898
+ info: (...args) => logger$2.info(prefix, ...args),
4899
+ warn: (...args) => logger$2.warn(prefix, ...args),
4900
+ error: (...args) => logger$2.error(prefix, ...args),
4901
+ critical: (...args) => logger$2.critical(prefix, ...args),
4810
4902
  uninitializedWarning: methodName => {
4811
- logger$3.error(prefix, `You must initialize Leanbase before calling ${methodName}`);
4903
+ logger$2.error(prefix, `You must initialize Leanbase before calling ${methodName}`);
4812
4904
  },
4813
4905
  createLogger: additionalPrefix => _createLogger(`${prefix} ${additionalPrefix}`)
4814
4906
  };
4815
4907
  };
4816
- const logger$2 = _createLogger('[Leanbase]');
4908
+ const logger$1 = _createLogger('[Leanbase]');
4817
4909
  const createLogger = _createLogger;
4818
4910
 
4819
- function patch(source, name, replacement) {
4820
- try {
4821
- if (!(name in source)) {
4822
- return () => {
4823
- //
4824
- };
4825
- }
4826
- const original = source[name];
4827
- const wrapped = replacement(original);
4828
- if (isFunction(wrapped)) {
4829
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
4830
- wrapped.prototype = wrapped.prototype || {};
4831
- Object.defineProperties(wrapped, {
4832
- __posthog_wrapped__: {
4833
- enumerable: false,
4834
- value: true
4835
- }
4836
- });
4837
- }
4838
- source[name] = wrapped;
4839
- return () => {
4840
- source[name] = original;
4841
- };
4842
- } catch {
4843
- return () => {
4844
- //
4845
- };
4846
- }
4847
- }
4848
-
4849
- function hostnameFromURL(url) {
4850
- try {
4851
- if (typeof url === 'string') {
4852
- return new URL(url).hostname;
4853
- }
4854
- if ('url' in url) {
4855
- return new URL(url.url).hostname;
4856
- }
4857
- return url.hostname;
4858
- } catch {
4859
- return null;
4860
- }
4861
- }
4862
- function isHostOnDenyList(url, options) {
4863
- const hostname = hostnameFromURL(url);
4864
- const defaultNotDenied = {
4865
- hostname,
4866
- isHostDenied: false
4867
- };
4868
- if (!options.payloadHostDenyList?.length || !hostname?.trim().length) {
4869
- return defaultNotDenied;
4870
- }
4871
- for (const deny of options.payloadHostDenyList) {
4872
- if (hostname.endsWith(deny)) {
4873
- return {
4874
- hostname,
4875
- isHostDenied: true
4876
- };
4877
- }
4878
- }
4879
- return defaultNotDenied;
4880
- }
4881
-
4882
4911
  const LOGGER_PREFIX$2 = '[SessionRecording]';
4883
4912
  const REDACTED = 'redacted';
4884
4913
  const defaultNetworkOptions = {
@@ -4950,7 +4979,7 @@ var leanbase = (function (record) {
4950
4979
  // people can have arbitrarily large payloads on their site, but we don't want to ingest them
4951
4980
  const limitPayloadSize = options => {
4952
4981
  // the smallest of 1MB or the specified limit if there is one
4953
- const limit = Math.min(1000000, options.payloadSizeLimitBytes ?? 1000000);
4982
+ const limit = Math.min(1000000, options.payloadSizeLimitBytes);
4954
4983
  return data => {
4955
4984
  if (data?.requestBody) {
4956
4985
  data.requestBody = enforcePayloadSizeLimit(data.requestBody, data.requestHeaders, limit, 'Request');
@@ -5008,7 +5037,7 @@ var leanbase = (function (record) {
5008
5037
  const enforcedCleaningFn = d => payloadLimiter(ignorePostHogPaths(removeAuthorizationHeader(d), instanceConfig.host || ''));
5009
5038
  const hasDeprecatedMaskFunction = isFunction(sessionRecordingConfig.maskNetworkRequestFn);
5010
5039
  if (hasDeprecatedMaskFunction && isFunction(sessionRecordingConfig.maskCapturedNetworkRequestFn)) {
5011
- logger$2.warn('Both `maskNetworkRequestFn` and `maskCapturedNetworkRequestFn` are defined. `maskNetworkRequestFn` will be ignored.');
5040
+ logger$1.warn('Both `maskNetworkRequestFn` and `maskCapturedNetworkRequestFn` are defined. `maskNetworkRequestFn` will be ignored.');
5012
5041
  }
5013
5042
  if (hasDeprecatedMaskFunction) {
5014
5043
  sessionRecordingConfig.maskCapturedNetworkRequestFn = data => {
@@ -5035,666 +5064,6 @@ var leanbase = (function (record) {
5035
5064
  };
5036
5065
  };
5037
5066
 
5038
- /// <reference lib="dom" />
5039
- const logger$1 = createLogger('[Recorder]');
5040
- const isNavigationTiming = entry => entry.entryType === 'navigation';
5041
- const isResourceTiming = entry => entry.entryType === 'resource';
5042
- function findLast(array, predicate) {
5043
- const length = array.length;
5044
- for (let i = length - 1; i >= 0; i -= 1) {
5045
- if (predicate(array[i])) {
5046
- return array[i];
5047
- }
5048
- }
5049
- return undefined;
5050
- }
5051
- function isDocument(value) {
5052
- return !!value && typeof value === 'object' && 'nodeType' in value && value.nodeType === 9;
5053
- }
5054
- function initPerformanceObserver(cb, win, options) {
5055
- // if we are only observing timings then we could have a single observer for all types, with buffer true,
5056
- // but we are going to filter by initiatorType _if we are wrapping fetch and xhr as the wrapped functions
5057
- // will deal with those.
5058
- // so we have a block which captures requests from before fetch/xhr is wrapped
5059
- // these are marked `isInitial` so playback can display them differently if needed
5060
- // they will never have method/status/headers/body because they are pre-wrapping that provides that
5061
- if (options.recordInitialRequests) {
5062
- const initialPerformanceEntries = win.performance.getEntries().filter(entry => isNavigationTiming(entry) || isResourceTiming(entry) && options.initiatorTypes.includes(entry.initiatorType));
5063
- cb({
5064
- requests: initialPerformanceEntries.flatMap(entry => prepareRequest({
5065
- entry,
5066
- method: undefined,
5067
- status: undefined,
5068
- networkRequest: {},
5069
- isInitial: true
5070
- })),
5071
- isInitial: true
5072
- });
5073
- }
5074
- const observer = new win.PerformanceObserver(entries => {
5075
- // if recordBody or recordHeaders is true then we don't want to record fetch or xhr here
5076
- // as the wrapped functions will do that. Otherwise, this filter becomes a noop
5077
- // because we do want to record them here
5078
- const wrappedInitiatorFilter = entry => options.recordBody || options.recordHeaders ? entry.initiatorType !== 'xmlhttprequest' && entry.initiatorType !== 'fetch' : true;
5079
- const performanceEntries = entries.getEntries().filter(entry => isNavigationTiming(entry) || isResourceTiming(entry) && options.initiatorTypes.includes(entry.initiatorType) &&
5080
- // TODO if we are _only_ capturing timing we don't want to filter initiator here
5081
- wrappedInitiatorFilter(entry));
5082
- cb({
5083
- requests: performanceEntries.flatMap(entry => prepareRequest({
5084
- entry,
5085
- method: undefined,
5086
- status: undefined,
5087
- networkRequest: {}
5088
- }))
5089
- });
5090
- });
5091
- // compat checked earlier
5092
- // eslint-disable-next-line compat/compat
5093
- const entryTypes = PerformanceObserver.supportedEntryTypes.filter(x => options.performanceEntryTypeToObserve.includes(x));
5094
- // initial records are gathered above, so we don't need to observe and buffer each type separately
5095
- observer.observe({
5096
- entryTypes
5097
- });
5098
- return () => {
5099
- observer.disconnect();
5100
- };
5101
- }
5102
- function shouldRecordHeaders(type, recordHeaders) {
5103
- return !!recordHeaders && (isBoolean(recordHeaders) || recordHeaders[type]);
5104
- }
5105
- function shouldRecordBody({
5106
- type,
5107
- recordBody,
5108
- headers,
5109
- url
5110
- }) {
5111
- function matchesContentType(contentTypes) {
5112
- const contentTypeHeader = Object.keys(headers).find(key => key.toLowerCase() === 'content-type');
5113
- const contentType = contentTypeHeader && headers[contentTypeHeader];
5114
- return contentTypes.some(ct => contentType?.includes(ct));
5115
- }
5116
- /**
5117
- * particularly in canvas applications we see many requests to blob URLs
5118
- * e.g. blob:https://video_url
5119
- * these blob/object URLs are local to the browser, we can never capture that body
5120
- * so we can just return false here
5121
- */
5122
- function isBlobURL(url) {
5123
- try {
5124
- if (typeof url === 'string') {
5125
- return url.startsWith('blob:');
5126
- }
5127
- if (url instanceof URL) {
5128
- return url.protocol === 'blob:';
5129
- }
5130
- if (url instanceof Request) {
5131
- return isBlobURL(url.url);
5132
- }
5133
- return false;
5134
- } catch {
5135
- return false;
5136
- }
5137
- }
5138
- if (!recordBody) return false;
5139
- if (isBlobURL(url)) return false;
5140
- if (isBoolean(recordBody)) return true;
5141
- if (isArray(recordBody)) return matchesContentType(recordBody);
5142
- const recordBodyType = recordBody[type];
5143
- if (isBoolean(recordBodyType)) return recordBodyType;
5144
- return matchesContentType(recordBodyType);
5145
- }
5146
- async function getRequestPerformanceEntry(win, initiatorType, url, start, end, attempt = 0) {
5147
- if (attempt > 10) {
5148
- logger$1.warn('Failed to get performance entry for request', {
5149
- url,
5150
- initiatorType
5151
- });
5152
- return null;
5153
- }
5154
- const urlPerformanceEntries = win.performance.getEntriesByName(url);
5155
- const performanceEntry = findLast(urlPerformanceEntries, entry => isResourceTiming(entry) && entry.initiatorType === initiatorType && (isUndefined(start) || entry.startTime >= start) && (isUndefined(end) || entry.startTime <= end));
5156
- if (!performanceEntry) {
5157
- await new Promise(resolve => setTimeout(resolve, 50 * attempt));
5158
- return getRequestPerformanceEntry(win, initiatorType, url, start, end, attempt + 1);
5159
- }
5160
- return performanceEntry;
5161
- }
5162
- /**
5163
- * According to MDN https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/response
5164
- * xhr response is typed as any but can be an ArrayBuffer, a Blob, a Document, a JavaScript object,
5165
- * or a string, depending on the value of XMLHttpRequest.responseType, that contains the response entity body.
5166
- *
5167
- * XHR request body is Document | XMLHttpRequestBodyInit | null | undefined
5168
- */
5169
- function _tryReadXHRBody({
5170
- body,
5171
- options,
5172
- url
5173
- }) {
5174
- if (isNullish(body)) {
5175
- return null;
5176
- }
5177
- const {
5178
- hostname,
5179
- isHostDenied
5180
- } = isHostOnDenyList(url, options);
5181
- if (isHostDenied) {
5182
- return hostname + ' is in deny list';
5183
- }
5184
- if (isString(body)) {
5185
- return body;
5186
- }
5187
- if (isDocument(body)) {
5188
- return body.textContent;
5189
- }
5190
- if (isFormData(body)) {
5191
- return formDataToQuery(body);
5192
- }
5193
- if (isObject(body)) {
5194
- try {
5195
- return JSON.stringify(body);
5196
- } catch {
5197
- return '[SessionReplay] Failed to stringify response object';
5198
- }
5199
- }
5200
- return '[SessionReplay] Cannot read body of type ' + toString.call(body);
5201
- }
5202
- function initXhrObserver(cb, win, options) {
5203
- if (!options.initiatorTypes.includes('xmlhttprequest')) {
5204
- return () => {
5205
- //
5206
- };
5207
- }
5208
- const recordRequestHeaders = shouldRecordHeaders('request', options.recordHeaders);
5209
- const recordResponseHeaders = shouldRecordHeaders('response', options.recordHeaders);
5210
- const restorePatch = patch(win.XMLHttpRequest.prototype, 'open',
5211
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
5212
- // @ts-ignore
5213
- originalOpen => {
5214
- return function (method, url, async = true, username, password) {
5215
- // because this function is returned in its actual context `this` _is_ an XMLHttpRequest
5216
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
5217
- // @ts-ignore
5218
- const xhr = this;
5219
- // check IE earlier than this, we only initialize if Request is present
5220
- // eslint-disable-next-line compat/compat
5221
- const req = new Request(url);
5222
- const networkRequest = {};
5223
- let start;
5224
- let end;
5225
- const requestHeaders = {};
5226
- const originalSetRequestHeader = xhr.setRequestHeader.bind(xhr);
5227
- xhr.setRequestHeader = (header, value) => {
5228
- requestHeaders[header] = value;
5229
- return originalSetRequestHeader(header, value);
5230
- };
5231
- if (recordRequestHeaders) {
5232
- networkRequest.requestHeaders = requestHeaders;
5233
- }
5234
- const originalSend = xhr.send.bind(xhr);
5235
- xhr.send = body => {
5236
- if (shouldRecordBody({
5237
- type: 'request',
5238
- headers: requestHeaders,
5239
- url,
5240
- recordBody: options.recordBody
5241
- })) {
5242
- networkRequest.requestBody = _tryReadXHRBody({
5243
- body,
5244
- options,
5245
- url
5246
- });
5247
- }
5248
- start = win.performance.now();
5249
- return originalSend(body);
5250
- };
5251
- const readyStateListener = () => {
5252
- if (xhr.readyState !== xhr.DONE) {
5253
- return;
5254
- }
5255
- // Clean up the listener immediately when done to prevent memory leaks
5256
- xhr.removeEventListener('readystatechange', readyStateListener);
5257
- end = win.performance.now();
5258
- const responseHeaders = {};
5259
- const rawHeaders = xhr.getAllResponseHeaders();
5260
- const headers = rawHeaders.trim().split(/[\r\n]+/);
5261
- headers.forEach(line => {
5262
- const parts = line.split(': ');
5263
- const header = parts.shift();
5264
- const value = parts.join(': ');
5265
- if (header) {
5266
- responseHeaders[header] = value;
5267
- }
5268
- });
5269
- if (recordResponseHeaders) {
5270
- networkRequest.responseHeaders = responseHeaders;
5271
- }
5272
- if (shouldRecordBody({
5273
- type: 'response',
5274
- headers: responseHeaders,
5275
- url,
5276
- recordBody: options.recordBody
5277
- })) {
5278
- networkRequest.responseBody = _tryReadXHRBody({
5279
- body: xhr.response,
5280
- options,
5281
- url
5282
- });
5283
- }
5284
- getRequestPerformanceEntry(win, 'xmlhttprequest', req.url, start, end).then(entry => {
5285
- const requests = prepareRequest({
5286
- entry,
5287
- method: method,
5288
- status: xhr?.status,
5289
- networkRequest,
5290
- start,
5291
- end,
5292
- url: url.toString(),
5293
- initiatorType: 'xmlhttprequest'
5294
- });
5295
- cb({
5296
- requests
5297
- });
5298
- }).catch(() => {
5299
- //
5300
- });
5301
- };
5302
- // This is very tricky code, and making it passive won't bring many performance benefits,
5303
- // so let's ignore the rule here.
5304
- // eslint-disable-next-line posthog-js/no-add-event-listener
5305
- xhr.addEventListener('readystatechange', readyStateListener);
5306
- originalOpen.call(xhr, method, url, async, username, password);
5307
- };
5308
- });
5309
- return () => {
5310
- restorePatch();
5311
- };
5312
- }
5313
- /**
5314
- * Check if this PerformanceEntry is either a PerformanceResourceTiming or a PerformanceNavigationTiming
5315
- * NB PerformanceNavigationTiming extends PerformanceResourceTiming
5316
- * Here we don't care which interface it implements as both expose `serverTimings`
5317
- */
5318
- const exposesServerTiming = event => !isNull(event) && (event.entryType === 'navigation' || event.entryType === 'resource');
5319
- function prepareRequest({
5320
- entry,
5321
- method,
5322
- status,
5323
- networkRequest,
5324
- isInitial,
5325
- start,
5326
- end,
5327
- url,
5328
- initiatorType
5329
- }) {
5330
- start = entry ? entry.startTime : start;
5331
- end = entry ? entry.responseEnd : end;
5332
- // kudos to sentry javascript sdk for excellent background on why to use Date.now() here
5333
- // https://github.com/getsentry/sentry-javascript/blob/e856e40b6e71a73252e788cd42b5260f81c9c88e/packages/utils/src/time.ts#L70
5334
- // can't start observer if performance.now() is not available
5335
- // eslint-disable-next-line compat/compat
5336
- const timeOrigin = Math.floor(Date.now() - performance.now());
5337
- // clickhouse can't ingest timestamps that are floats
5338
- // (in this case representing fractions of a millisecond we don't care about anyway)
5339
- // use timeOrigin if we really can't gather a start time
5340
- const timestamp = Math.floor(timeOrigin + (start || 0));
5341
- const entryJSON = entry ? entry.toJSON() : {
5342
- name: url
5343
- };
5344
- const requests = [{
5345
- ...entryJSON,
5346
- startTime: isUndefined(start) ? undefined : Math.round(start),
5347
- endTime: isUndefined(end) ? undefined : Math.round(end),
5348
- timeOrigin,
5349
- timestamp,
5350
- method: method,
5351
- initiatorType: initiatorType ? initiatorType : entry ? entry.initiatorType : undefined,
5352
- status,
5353
- requestHeaders: networkRequest.requestHeaders,
5354
- requestBody: networkRequest.requestBody,
5355
- responseHeaders: networkRequest.responseHeaders,
5356
- responseBody: networkRequest.responseBody,
5357
- isInitial
5358
- }];
5359
- if (exposesServerTiming(entry)) {
5360
- for (const timing of entry.serverTiming || []) {
5361
- requests.push({
5362
- timeOrigin,
5363
- timestamp,
5364
- startTime: Math.round(entry.startTime),
5365
- name: timing.name,
5366
- duration: timing.duration,
5367
- // the spec has a closed list of possible types
5368
- // https://developer.mozilla.org/en-US/docs/Web/API/PerformanceEntry/entryType
5369
- // but, we need to know this was a server timing so that we know to
5370
- // match it to the appropriate navigation or resource timing
5371
- // that matching will have to be on timestamp and $current_url
5372
- entryType: 'serverTiming'
5373
- });
5374
- }
5375
- }
5376
- return requests;
5377
- }
5378
- const contentTypePrefixDenyList = ['video/', 'audio/'];
5379
- function _checkForCannotReadResponseBody({
5380
- r,
5381
- options,
5382
- url
5383
- }) {
5384
- if (r.headers.get('Transfer-Encoding') === 'chunked') {
5385
- return 'Chunked Transfer-Encoding is not supported';
5386
- }
5387
- // `get` and `has` are case-insensitive
5388
- // but return the header value with the casing that was supplied
5389
- const contentType = r.headers.get('Content-Type')?.toLowerCase();
5390
- const contentTypeIsDenied = contentTypePrefixDenyList.some(prefix => contentType?.startsWith(prefix));
5391
- if (contentType && contentTypeIsDenied) {
5392
- return `Content-Type ${contentType} is not supported`;
5393
- }
5394
- const {
5395
- hostname,
5396
- isHostDenied
5397
- } = isHostOnDenyList(url, options);
5398
- if (isHostDenied) {
5399
- return hostname + ' is in deny list';
5400
- }
5401
- return null;
5402
- }
5403
- function _tryReadBody(r) {
5404
- // there are now already multiple places where we're using Promise...
5405
- // eslint-disable-next-line compat/compat
5406
- return new Promise((resolve, reject) => {
5407
- const timeout = setTimeout(() => resolve('[SessionReplay] Timeout while trying to read body'), 500);
5408
- try {
5409
- r.clone().text().then(txt => resolve(txt), reason => reject(reason)).finally(() => clearTimeout(timeout));
5410
- } catch {
5411
- clearTimeout(timeout);
5412
- resolve('[SessionReplay] Failed to read body');
5413
- }
5414
- });
5415
- }
5416
- async function _tryReadRequestBody({
5417
- r,
5418
- options,
5419
- url
5420
- }) {
5421
- const {
5422
- hostname,
5423
- isHostDenied
5424
- } = isHostOnDenyList(url, options);
5425
- if (isHostDenied) {
5426
- return Promise.resolve(hostname + ' is in deny list');
5427
- }
5428
- return _tryReadBody(r);
5429
- }
5430
- async function _tryReadResponseBody({
5431
- r,
5432
- options,
5433
- url
5434
- }) {
5435
- const cannotReadBodyReason = _checkForCannotReadResponseBody({
5436
- r,
5437
- options,
5438
- url
5439
- });
5440
- if (!isNull(cannotReadBodyReason)) {
5441
- return Promise.resolve(cannotReadBodyReason);
5442
- }
5443
- return _tryReadBody(r);
5444
- }
5445
- function initFetchObserver(cb, win, options) {
5446
- if (!options.initiatorTypes.includes('fetch')) {
5447
- return () => {
5448
- //
5449
- };
5450
- }
5451
- const recordRequestHeaders = shouldRecordHeaders('request', options.recordHeaders);
5452
- const recordResponseHeaders = shouldRecordHeaders('response', options.recordHeaders);
5453
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
5454
- // @ts-ignore
5455
- const restorePatch = patch(win, 'fetch', originalFetch => {
5456
- return async function (url, init) {
5457
- // check IE earlier than this, we only initialize if Request is present
5458
- // eslint-disable-next-line compat/compat
5459
- const req = new Request(url, init);
5460
- let res;
5461
- const networkRequest = {};
5462
- let start;
5463
- let end;
5464
- try {
5465
- const requestHeaders = {};
5466
- req.headers.forEach((value, header) => {
5467
- requestHeaders[header] = value;
5468
- });
5469
- if (recordRequestHeaders) {
5470
- networkRequest.requestHeaders = requestHeaders;
5471
- }
5472
- if (shouldRecordBody({
5473
- type: 'request',
5474
- headers: requestHeaders,
5475
- url,
5476
- recordBody: options.recordBody
5477
- })) {
5478
- networkRequest.requestBody = await _tryReadRequestBody({
5479
- r: req,
5480
- options,
5481
- url
5482
- });
5483
- }
5484
- start = win.performance.now();
5485
- res = await originalFetch(req);
5486
- end = win.performance.now();
5487
- const responseHeaders = {};
5488
- res.headers.forEach((value, header) => {
5489
- responseHeaders[header] = value;
5490
- });
5491
- if (recordResponseHeaders) {
5492
- networkRequest.responseHeaders = responseHeaders;
5493
- }
5494
- if (shouldRecordBody({
5495
- type: 'response',
5496
- headers: responseHeaders,
5497
- url,
5498
- recordBody: options.recordBody
5499
- })) {
5500
- networkRequest.responseBody = await _tryReadResponseBody({
5501
- r: res,
5502
- options,
5503
- url
5504
- });
5505
- }
5506
- return res;
5507
- } finally {
5508
- getRequestPerformanceEntry(win, 'fetch', req.url, start, end).then(entry => {
5509
- const requests = prepareRequest({
5510
- entry,
5511
- method: req.method,
5512
- status: res?.status,
5513
- networkRequest,
5514
- start,
5515
- end,
5516
- url: req.url,
5517
- initiatorType: 'fetch'
5518
- });
5519
- cb({
5520
- requests
5521
- });
5522
- }).catch(() => {
5523
- //
5524
- });
5525
- }
5526
- };
5527
- });
5528
- return () => {
5529
- restorePatch();
5530
- };
5531
- }
5532
- let initialisedHandler = null;
5533
- function initNetworkObserver(callback, win,
5534
- // top window or in an iframe
5535
- options) {
5536
- if (!('performance' in win)) {
5537
- return () => {
5538
- //
5539
- };
5540
- }
5541
- if (initialisedHandler) {
5542
- logger$1.warn('Network observer already initialised, doing nothing');
5543
- return () => {
5544
- // the first caller should already have this handler and will be responsible for teardown
5545
- };
5546
- }
5547
- const networkOptions = options ? Object.assign({}, defaultNetworkOptions, options) : defaultNetworkOptions;
5548
- const cb = data => {
5549
- const requests = [];
5550
- data.requests.forEach(request => {
5551
- const maskedRequest = networkOptions.maskRequestFn(request);
5552
- if (maskedRequest) {
5553
- requests.push(maskedRequest);
5554
- }
5555
- });
5556
- if (requests.length > 0) {
5557
- callback({
5558
- ...data,
5559
- requests
5560
- });
5561
- }
5562
- };
5563
- const performanceObserver = initPerformanceObserver(cb, win, networkOptions);
5564
- // only wrap fetch and xhr if headers or body are being recorded
5565
- let xhrObserver = () => {};
5566
- let fetchObserver = () => {};
5567
- if (networkOptions.recordHeaders || networkOptions.recordBody) {
5568
- xhrObserver = initXhrObserver(cb, win, networkOptions);
5569
- fetchObserver = initFetchObserver(cb, win, networkOptions);
5570
- }
5571
- const teardown = () => {
5572
- performanceObserver();
5573
- xhrObserver();
5574
- fetchObserver();
5575
- // allow future observers to initialize after cleanup
5576
- initialisedHandler = null;
5577
- };
5578
- initialisedHandler = teardown;
5579
- return teardown;
5580
- }
5581
- // use the plugin name so that when this functionality is adopted into rrweb
5582
- // we can remove this plugin and use the core functionality with the same data
5583
- const NETWORK_PLUGIN_NAME = 'rrweb/network@1';
5584
- // TODO how should this be typed?
5585
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
5586
- // @ts-ignore
5587
- const getRecordNetworkPlugin = options => {
5588
- return {
5589
- name: NETWORK_PLUGIN_NAME,
5590
- observer: initNetworkObserver,
5591
- options: options
5592
- };
5593
- };
5594
- // rrweb/networ@1 ends
5595
-
5596
- // Use a safe global target (prefer `win`, fallback to globalThis)
5597
- const _target = win ?? globalThis;
5598
- _target.__PosthogExtensions__ = _target.__PosthogExtensions__ || {};
5599
- // Expose rrweb.record under the same contract
5600
- _target.__PosthogExtensions__.rrweb = _target.__PosthogExtensions__.rrweb || {
5601
- record: record.record
5602
- };
5603
- // Provide initSessionRecording if not present — return a new LazyLoadedSessionRecording when called
5604
- _target.__PosthogExtensions__.initSessionRecording = _target.__PosthogExtensions__.initSessionRecording || (instance => {
5605
- return new LazyLoadedSessionRecording(instance);
5606
- });
5607
- // Provide a no-op loadExternalDependency that calls the callback immediately (since rrweb is bundled)
5608
- _target.__PosthogExtensions__.loadExternalDependency = _target.__PosthogExtensions__.loadExternalDependency || ((instance, scriptName, cb) => {
5609
- if (cb) cb(undefined);
5610
- });
5611
- // Provide rrwebPlugins object with network plugin factory if not present
5612
- _target.__PosthogExtensions__.rrwebPlugins = _target.__PosthogExtensions__.rrwebPlugins || {};
5613
- _target.__PosthogExtensions__.rrwebPlugins.getRecordNetworkPlugin = _target.__PosthogExtensions__.rrwebPlugins.getRecordNetworkPlugin || (() => getRecordNetworkPlugin);
5614
-
5615
- // Type definitions copied from @rrweb/types@2.0.0-alpha.17 and rrweb-snapshot@2.0.0-alpha.17
5616
- // Both packages are MIT licensed: https://github.com/rrweb-io/rrweb
5617
- //
5618
- // These types are copied here to avoid requiring users to install peer dependencies
5619
- // solely for TypeScript type information.
5620
- //
5621
- // Original sources:
5622
- // - @rrweb/types: https://github.com/rrweb-io/rrweb/tree/main/packages/@rrweb/types
5623
- // - rrweb-snapshot: https://github.com/rrweb-io/rrweb/tree/main/packages/rrweb-snapshot
5624
- var NodeType;
5625
- (function (NodeType) {
5626
- NodeType[NodeType["Document"] = 0] = "Document";
5627
- NodeType[NodeType["DocumentType"] = 1] = "DocumentType";
5628
- NodeType[NodeType["Element"] = 2] = "Element";
5629
- NodeType[NodeType["Text"] = 3] = "Text";
5630
- NodeType[NodeType["CDATA"] = 4] = "CDATA";
5631
- NodeType[NodeType["Comment"] = 5] = "Comment";
5632
- })(NodeType || (NodeType = {}));
5633
- var EventType;
5634
- (function (EventType) {
5635
- EventType[EventType["DomContentLoaded"] = 0] = "DomContentLoaded";
5636
- EventType[EventType["Load"] = 1] = "Load";
5637
- EventType[EventType["FullSnapshot"] = 2] = "FullSnapshot";
5638
- EventType[EventType["IncrementalSnapshot"] = 3] = "IncrementalSnapshot";
5639
- EventType[EventType["Meta"] = 4] = "Meta";
5640
- EventType[EventType["Custom"] = 5] = "Custom";
5641
- EventType[EventType["Plugin"] = 6] = "Plugin";
5642
- })(EventType || (EventType = {}));
5643
- var IncrementalSource;
5644
- (function (IncrementalSource) {
5645
- IncrementalSource[IncrementalSource["Mutation"] = 0] = "Mutation";
5646
- IncrementalSource[IncrementalSource["MouseMove"] = 1] = "MouseMove";
5647
- IncrementalSource[IncrementalSource["MouseInteraction"] = 2] = "MouseInteraction";
5648
- IncrementalSource[IncrementalSource["Scroll"] = 3] = "Scroll";
5649
- IncrementalSource[IncrementalSource["ViewportResize"] = 4] = "ViewportResize";
5650
- IncrementalSource[IncrementalSource["Input"] = 5] = "Input";
5651
- IncrementalSource[IncrementalSource["TouchMove"] = 6] = "TouchMove";
5652
- IncrementalSource[IncrementalSource["MediaInteraction"] = 7] = "MediaInteraction";
5653
- IncrementalSource[IncrementalSource["StyleSheetRule"] = 8] = "StyleSheetRule";
5654
- IncrementalSource[IncrementalSource["CanvasMutation"] = 9] = "CanvasMutation";
5655
- IncrementalSource[IncrementalSource["Font"] = 10] = "Font";
5656
- IncrementalSource[IncrementalSource["Log"] = 11] = "Log";
5657
- IncrementalSource[IncrementalSource["Drag"] = 12] = "Drag";
5658
- IncrementalSource[IncrementalSource["StyleDeclaration"] = 13] = "StyleDeclaration";
5659
- IncrementalSource[IncrementalSource["Selection"] = 14] = "Selection";
5660
- IncrementalSource[IncrementalSource["AdoptedStyleSheet"] = 15] = "AdoptedStyleSheet";
5661
- IncrementalSource[IncrementalSource["CustomElement"] = 16] = "CustomElement";
5662
- })(IncrementalSource || (IncrementalSource = {}));
5663
- var MouseInteractions;
5664
- (function (MouseInteractions) {
5665
- MouseInteractions[MouseInteractions["MouseUp"] = 0] = "MouseUp";
5666
- MouseInteractions[MouseInteractions["MouseDown"] = 1] = "MouseDown";
5667
- MouseInteractions[MouseInteractions["Click"] = 2] = "Click";
5668
- MouseInteractions[MouseInteractions["ContextMenu"] = 3] = "ContextMenu";
5669
- MouseInteractions[MouseInteractions["DblClick"] = 4] = "DblClick";
5670
- MouseInteractions[MouseInteractions["Focus"] = 5] = "Focus";
5671
- MouseInteractions[MouseInteractions["Blur"] = 6] = "Blur";
5672
- MouseInteractions[MouseInteractions["TouchStart"] = 7] = "TouchStart";
5673
- MouseInteractions[MouseInteractions["TouchMove_Departed"] = 8] = "TouchMove_Departed";
5674
- MouseInteractions[MouseInteractions["TouchEnd"] = 9] = "TouchEnd";
5675
- MouseInteractions[MouseInteractions["TouchCancel"] = 10] = "TouchCancel";
5676
- })(MouseInteractions || (MouseInteractions = {}));
5677
- var PointerTypes;
5678
- (function (PointerTypes) {
5679
- PointerTypes[PointerTypes["Mouse"] = 0] = "Mouse";
5680
- PointerTypes[PointerTypes["Pen"] = 1] = "Pen";
5681
- PointerTypes[PointerTypes["Touch"] = 2] = "Touch";
5682
- })(PointerTypes || (PointerTypes = {}));
5683
- var MediaInteractions;
5684
- (function (MediaInteractions) {
5685
- MediaInteractions[MediaInteractions["Play"] = 0] = "Play";
5686
- MediaInteractions[MediaInteractions["Pause"] = 1] = "Pause";
5687
- MediaInteractions[MediaInteractions["Seeked"] = 2] = "Seeked";
5688
- MediaInteractions[MediaInteractions["VolumeChange"] = 3] = "VolumeChange";
5689
- MediaInteractions[MediaInteractions["RateChange"] = 4] = "RateChange";
5690
- })(MediaInteractions || (MediaInteractions = {}));
5691
- var CanvasContext;
5692
- (function (CanvasContext) {
5693
- CanvasContext[CanvasContext["2D"] = 0] = "2D";
5694
- CanvasContext[CanvasContext["WebGL"] = 1] = "WebGL";
5695
- CanvasContext[CanvasContext["WebGL2"] = 2] = "WebGL2";
5696
- })(CanvasContext || (CanvasContext = {}));
5697
-
5698
5067
  const DISABLED = 'disabled';
5699
5068
  const SAMPLED = 'sampled';
5700
5069
  const ACTIVE = 'active';
@@ -6686,7 +6055,7 @@ var leanbase = (function (record) {
6686
6055
  refillInterval: 1000,
6687
6056
  // one second
6688
6057
  _onBucketRateLimited: this._onNodeRateLimited,
6689
- _logger: logger$2
6058
+ _logger: logger$1
6690
6059
  });
6691
6060
  }
6692
6061
  reset() {
@@ -6710,9 +6079,10 @@ var leanbase = (function (record) {
6710
6079
  * receives percent as a number between 0 and 1
6711
6080
  */
6712
6081
  function sampleOnProperty(prop, percent) {
6713
- return simpleHash(prop) % 100 < clampToRange(percent * 100, 0, 100, logger$2);
6082
+ return simpleHash(prop) % 100 < clampToRange(percent * 100, 0, 100, logger$1);
6714
6083
  }
6715
6084
 
6085
+ /* eslint-disable posthog-js/no-direct-function-check */
6716
6086
  const BASE_ENDPOINT = '/s/';
6717
6087
  const DEFAULT_CANVAS_QUALITY = 0.4;
6718
6088
  const DEFAULT_CANVAS_FPS = 4;
@@ -6723,6 +6093,19 @@ var leanbase = (function (record) {
6723
6093
  const ONE_MINUTE = 1000 * 60;
6724
6094
  const FIVE_MINUTES = ONE_MINUTE * 5;
6725
6095
  const RECORDING_IDLE_THRESHOLD_MS = FIVE_MINUTES;
6096
+ // Register a factory on the global extensions object so the extension shim can
6097
+ // instantiate a LazyLoadedSessionRecording without importing this module directly.
6098
+ try {
6099
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
6100
+ const ext = globalThis.__PosthogExtensions__;
6101
+ if (ext) {
6102
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
6103
+ ext._initSessionRecordingFactory = ext._initSessionRecordingFactory || (instance => new LazyLoadedSessionRecording(instance));
6104
+ }
6105
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
6106
+ } catch (e) {
6107
+ // ignore
6108
+ }
6726
6109
  const RECORDING_MAX_EVENT_SIZE = ONE_KB * ONE_KB * 0.9; // ~1mb (with some wiggle room)
6727
6110
  const RECORDING_BUFFER_TIMEOUT = 2000; // 2 seconds
6728
6111
  const SESSION_RECORDING_BATCH_KEY = 'recordings';
@@ -7001,7 +6384,13 @@ var leanbase = (function (record) {
7001
6384
  if (this._networkPayloadCapture) {
7002
6385
  const canRecordNetwork = !isLocalhost() || this._forceAllowLocalhostNetworkCapture;
7003
6386
  if (canRecordNetwork) {
7004
- plugins.push(getRecordNetworkPlugin(buildNetworkRequestOptions(this._instance.config, this._networkPayloadCapture)));
6387
+ const assignableWindow = globalThis;
6388
+ const networkFactory = assignableWindow.__PosthogExtensions__?.rrwebPlugins?.getRecordNetworkPlugin?.();
6389
+ if (typeof networkFactory === 'function') {
6390
+ plugins.push(networkFactory(buildNetworkRequestOptions(this._instance.config, this._networkPayloadCapture)));
6391
+ } else {
6392
+ logger.info('Network plugin factory not available yet; skipping network plugin');
6393
+ }
7005
6394
  } else {
7006
6395
  logger.info('NetworkCapture not started because we are on localhost.');
7007
6396
  }
@@ -7751,9 +7140,9 @@ var leanbase = (function (record) {
7751
7140
 
7752
7141
  const LOGGER_PREFIX = '[SessionRecording]';
7753
7142
  const log = {
7754
- info: (...args) => logger$3.info(LOGGER_PREFIX, ...args),
7755
- warn: (...args) => logger$3.warn(LOGGER_PREFIX, ...args),
7756
- error: (...args) => logger$3.error(LOGGER_PREFIX, ...args)
7143
+ info: (...args) => logger$2.info(LOGGER_PREFIX, ...args),
7144
+ warn: (...args) => logger$2.warn(LOGGER_PREFIX, ...args),
7145
+ error: (...args) => logger$2.error(LOGGER_PREFIX, ...args)
7757
7146
  };
7758
7147
  class SessionRecording {
7759
7148
  get started() {
@@ -7892,7 +7281,7 @@ var leanbase = (function (record) {
7892
7281
  if (this._lazyLoadedSessionRecording?.log) {
7893
7282
  this._lazyLoadedSessionRecording.log(message, level);
7894
7283
  } else {
7895
- logger$3.warn('log called before recorder was ready');
7284
+ logger$2.warn('log called before recorder was ready');
7896
7285
  }
7897
7286
  }
7898
7287
  _onScriptLoaded(startReason) {
@@ -8157,7 +7546,7 @@ var leanbase = (function (record) {
8157
7546
  };
8158
7547
  properties['distinct_id'] = persistenceProps.distinct_id;
8159
7548
  if (!(isString(properties['distinct_id']) || isNumber(properties['distinct_id'])) || isEmptyString(properties['distinct_id'])) {
8160
- logger$3.error('Invalid distinct_id for replay event. This indicates a bug in your implementation');
7549
+ logger$2.error('Invalid distinct_id for replay event. This indicates a bug in your implementation');
8161
7550
  }
8162
7551
  return properties;
8163
7552
  }
@@ -8232,11 +7621,11 @@ var leanbase = (function (record) {
8232
7621
  return;
8233
7622
  }
8234
7623
  if (isUndefined(event) || !isString(event)) {
8235
- logger$3.error('No event name provided to posthog.capture');
7624
+ logger$2.error('No event name provided to posthog.capture');
8236
7625
  return;
8237
7626
  }
8238
7627
  if (properties?.$current_url && !isString(properties?.$current_url)) {
8239
- logger$3.error('Invalid `$current_url` property provided to `posthog.capture`. Input must be a string. Ignoring provided value.');
7628
+ logger$2.error('Invalid `$current_url` property provided to `posthog.capture`. Input must be a string. Ignoring provided value.');
8240
7629
  delete properties?.$current_url;
8241
7630
  }
8242
7631
  this.sessionPersistence.update_search_keyword();
@@ -8376,5 +7765,5 @@ var leanbase = (function (record) {
8376
7765
 
8377
7766
  return api;
8378
7767
 
8379
- })(record);
7768
+ })(rrweb);
8380
7769
  //# sourceMappingURL=leanbase.iife.js.map