@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.
- package/dist/index.cjs +168 -778
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +169 -779
- package/dist/index.mjs.map +1 -1
- package/dist/leanbase.iife.js +169 -780
- package/dist/leanbase.iife.js.map +1 -1
- package/package.json +1 -1
- package/src/extensions/replay/extension-shim.ts +15 -4
- package/src/extensions/replay/external/lazy-loaded-session-recorder.ts +25 -5
- package/src/version.ts +1 -1
package/dist/leanbase.iife.js
CHANGED
|
@@ -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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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.
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
4639
|
-
const maxScrollPercentage = maxScrollHeight <= 1 ? 1 : clampToRange(maxScrollY / maxScrollHeight, 0, 1, logger$
|
|
4640
|
-
const lastContentPercentage = maxContentHeight <= 1 ? 1 : clampToRange(lastContentY / maxContentHeight, 0, 1, logger$
|
|
4641
|
-
const maxContentPercentage = maxContentHeight <= 1 ? 1 : clampToRange(maxContentY / maxContentHeight, 0, 1, logger$
|
|
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$
|
|
4807
|
-
warn: (...args) => logger$
|
|
4808
|
-
error: (...args) => logger$
|
|
4809
|
-
critical: (...args) => logger$
|
|
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$
|
|
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$
|
|
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
|
|
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$
|
|
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$
|
|
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$
|
|
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
|
-
|
|
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$
|
|
7755
|
-
warn: (...args) => logger$
|
|
7756
|
-
error: (...args) => logger$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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
|
-
})(
|
|
7768
|
+
})(rrweb);
|
|
8380
7769
|
//# sourceMappingURL=leanbase.iife.js.map
|