@grafana/faro-web-sdk 2.3.1 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/bundle/faro-web-sdk.iife.js +1 -1
- package/dist/bundle/types/index.d.ts +2 -2
- package/dist/bundle/types/instrumentations/console/instrumentation.d.ts +1 -1
- package/dist/bundle/types/instrumentations/csp/instrumentation.d.ts +1 -1
- package/dist/bundle/types/instrumentations/errors/instrumentation.d.ts +1 -1
- package/dist/bundle/types/instrumentations/navigation/instrumentation.d.ts +1 -1
- package/dist/bundle/types/instrumentations/performance/instrumentation.d.ts +1 -1
- package/dist/bundle/types/instrumentations/session/instrumentation.d.ts +1 -1
- package/dist/bundle/types/instrumentations/userActions/instrumentation.d.ts +1 -1
- package/dist/bundle/types/instrumentations/view/instrumentation.d.ts +1 -1
- package/dist/bundle/types/instrumentations/webVitals/instrumentation.d.ts +1 -1
- package/dist/bundle/types/metas/index.d.ts +1 -0
- package/dist/bundle/types/metas/os/index.d.ts +1 -0
- package/dist/bundle/types/metas/os/meta.d.ts +2 -0
- package/dist/bundle/types/metas/shared/index.d.ts +1 -0
- package/dist/bundle/types/metas/shared/uaParser.d.ts +4 -0
- package/dist/bundle/types/transports/console/transport.d.ts +1 -1
- package/dist/bundle/types/transports/fetch/transport.d.ts +1 -1
- package/dist/cjs/config/getWebInstrumentations.js +3 -4
- package/dist/cjs/config/getWebInstrumentations.js.map +1 -1
- package/dist/cjs/config/makeCoreConfig.js +49 -60
- package/dist/cjs/config/makeCoreConfig.js.map +1 -1
- package/dist/cjs/index.js +3 -2
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/initialize.js +3 -3
- package/dist/cjs/initialize.js.map +1 -1
- package/dist/cjs/instrumentations/_internal/activityWindowTracker.js +52 -68
- package/dist/cjs/instrumentations/_internal/activityWindowTracker.js.map +1 -1
- package/dist/cjs/instrumentations/_internal/monitors/consoleMonitor.js +11 -16
- package/dist/cjs/instrumentations/_internal/monitors/consoleMonitor.js.map +1 -1
- package/dist/cjs/instrumentations/_internal/monitors/domMutationMonitor.js +5 -5
- package/dist/cjs/instrumentations/_internal/monitors/domMutationMonitor.js.map +1 -1
- package/dist/cjs/instrumentations/_internal/monitors/httpRequestMonitor.js +28 -30
- package/dist/cjs/instrumentations/_internal/monitors/httpRequestMonitor.js.map +1 -1
- package/dist/cjs/instrumentations/_internal/monitors/interactionMonitor.js +7 -7
- package/dist/cjs/instrumentations/_internal/monitors/interactionMonitor.js.map +1 -1
- package/dist/cjs/instrumentations/_internal/monitors/performanceEntriesMonitor.js +8 -8
- package/dist/cjs/instrumentations/_internal/monitors/performanceEntriesMonitor.js.map +1 -1
- package/dist/cjs/instrumentations/_internal/monitors/urlChangeMonitor.js +24 -32
- package/dist/cjs/instrumentations/_internal/monitors/urlChangeMonitor.js.map +1 -1
- package/dist/cjs/instrumentations/console/instrumentation.js +29 -49
- package/dist/cjs/instrumentations/console/instrumentation.js.map +1 -1
- package/dist/cjs/instrumentations/csp/instrumentation.js +14 -32
- package/dist/cjs/instrumentations/csp/instrumentation.js.map +1 -1
- package/dist/cjs/instrumentations/errors/getErrorDetails.js +23 -23
- package/dist/cjs/instrumentations/errors/getErrorDetails.js.map +1 -1
- package/dist/cjs/instrumentations/errors/getValueAndTypeFromMessage.js +5 -5
- package/dist/cjs/instrumentations/errors/getValueAndTypeFromMessage.js.map +1 -1
- package/dist/cjs/instrumentations/errors/instrumentation.js +11 -29
- package/dist/cjs/instrumentations/errors/instrumentation.js.map +1 -1
- package/dist/cjs/instrumentations/errors/registerOnerror.js +6 -10
- package/dist/cjs/instrumentations/errors/registerOnerror.js.map +1 -1
- package/dist/cjs/instrumentations/errors/registerOnunhandledrejection.js +16 -17
- package/dist/cjs/instrumentations/errors/registerOnunhandledrejection.js.map +1 -1
- package/dist/cjs/instrumentations/errors/stackFrames/buildStackFrame.js +2 -2
- package/dist/cjs/instrumentations/errors/stackFrames/buildStackFrame.js.map +1 -1
- package/dist/cjs/instrumentations/errors/stackFrames/getDataFromSafariExtensions.js +4 -4
- package/dist/cjs/instrumentations/errors/stackFrames/getDataFromSafariExtensions.js.map +1 -1
- package/dist/cjs/instrumentations/errors/stackFrames/getStackFramesFromError.js +16 -17
- package/dist/cjs/instrumentations/errors/stackFrames/getStackFramesFromError.js.map +1 -1
- package/dist/cjs/instrumentations/errors/stackFrames/parseStacktrace.js +1 -1
- package/dist/cjs/instrumentations/errors/stackFrames/parseStacktrace.js.map +1 -1
- package/dist/cjs/instrumentations/navigation/instrumentation.js +27 -45
- package/dist/cjs/instrumentations/navigation/instrumentation.js.map +1 -1
- package/dist/cjs/instrumentations/performance/instrumentation.js +19 -74
- package/dist/cjs/instrumentations/performance/instrumentation.js.map +1 -1
- package/dist/cjs/instrumentations/performance/navigation.js +15 -26
- package/dist/cjs/instrumentations/performance/navigation.js.map +1 -1
- package/dist/cjs/instrumentations/performance/performanceUtils.js +18 -33
- package/dist/cjs/instrumentations/performance/performanceUtils.js.map +1 -1
- package/dist/cjs/instrumentations/performance/resource.js +13 -25
- package/dist/cjs/instrumentations/performance/resource.js.map +1 -1
- package/dist/cjs/instrumentations/session/instrumentation.js +45 -74
- package/dist/cjs/instrumentations/session/instrumentation.js.map +1 -1
- package/dist/cjs/instrumentations/session/sessionManager/PersistentSessionsManager.js +21 -24
- package/dist/cjs/instrumentations/session/sessionManager/PersistentSessionsManager.js.map +1 -1
- package/dist/cjs/instrumentations/session/sessionManager/VolatileSessionManager.js +21 -24
- package/dist/cjs/instrumentations/session/sessionManager/VolatileSessionManager.js.map +1 -1
- package/dist/cjs/instrumentations/session/sessionManager/getSessionManagerByConfig.js +2 -2
- package/dist/cjs/instrumentations/session/sessionManager/getSessionManagerByConfig.js.map +1 -1
- package/dist/cjs/instrumentations/session/sessionManager/sampling.js +5 -5
- package/dist/cjs/instrumentations/session/sessionManager/sampling.js.map +1 -1
- package/dist/cjs/instrumentations/session/sessionManager/sessionManagerUtils.js +47 -65
- package/dist/cjs/instrumentations/session/sessionManager/sessionManagerUtils.js.map +1 -1
- package/dist/cjs/instrumentations/userActions/instrumentation.js +15 -34
- package/dist/cjs/instrumentations/userActions/instrumentation.js.map +1 -1
- package/dist/cjs/instrumentations/userActions/processUserActionEventHandler.js +11 -11
- package/dist/cjs/instrumentations/userActions/processUserActionEventHandler.js.map +1 -1
- package/dist/cjs/instrumentations/userActions/userActionController.js +49 -53
- package/dist/cjs/instrumentations/userActions/userActionController.js.map +1 -1
- package/dist/cjs/instrumentations/userActions/util.js +4 -4
- package/dist/cjs/instrumentations/userActions/util.js.map +1 -1
- package/dist/cjs/instrumentations/view/instrumentation.js +12 -30
- package/dist/cjs/instrumentations/view/instrumentation.js.map +1 -1
- package/dist/cjs/instrumentations/webVitals/instrumentation.js +11 -29
- package/dist/cjs/instrumentations/webVitals/instrumentation.js.map +1 -1
- package/dist/cjs/instrumentations/webVitals/webVitalsWithAttribution.js +87 -94
- package/dist/cjs/instrumentations/webVitals/webVitalsWithAttribution.js.map +1 -1
- package/dist/cjs/metas/browser/meta.js +13 -14
- package/dist/cjs/metas/browser/meta.js.map +1 -1
- package/dist/cjs/metas/index.js +3 -1
- package/dist/cjs/metas/index.js.map +1 -1
- package/dist/cjs/metas/k6/meta.js +3 -14
- package/dist/cjs/metas/k6/meta.js.map +1 -1
- package/dist/cjs/metas/os/index.js +6 -0
- package/dist/cjs/metas/os/index.js.map +1 -0
- package/dist/cjs/metas/os/meta.js +20 -0
- package/dist/cjs/metas/os/meta.js.map +1 -0
- package/dist/cjs/metas/page/meta.js +7 -19
- package/dist/cjs/metas/page/meta.js.map +1 -1
- package/dist/cjs/metas/sdk/meta.js +3 -3
- package/dist/cjs/metas/sdk/meta.js.map +1 -1
- package/dist/cjs/metas/session/createSession.js +2 -2
- package/dist/cjs/metas/session/createSession.js.map +1 -1
- package/dist/cjs/metas/shared/index.js +6 -0
- package/dist/cjs/metas/shared/index.js.map +1 -0
- package/dist/cjs/metas/shared/uaParser.js +18 -0
- package/dist/cjs/metas/shared/uaParser.js.map +1 -0
- package/dist/cjs/transports/console/transport.js +10 -29
- package/dist/cjs/transports/console/transport.js.map +1 -1
- package/dist/cjs/transports/fetch/transport.js +82 -176
- package/dist/cjs/transports/fetch/transport.js.map +1 -1
- package/dist/cjs/utils/throttle.js +6 -10
- package/dist/cjs/utils/throttle.js.map +1 -1
- package/dist/cjs/utils/url.js +4 -5
- package/dist/cjs/utils/url.js.map +1 -1
- package/dist/cjs/utils/webStorage.js +4 -4
- package/dist/cjs/utils/webStorage.js.map +1 -1
- package/dist/esm/config/makeCoreConfig.js +2 -1
- package/dist/esm/config/makeCoreConfig.js.map +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/instrumentations/_internal/activityWindowTracker.js +10 -5
- package/dist/esm/instrumentations/_internal/activityWindowTracker.js.map +1 -1
- package/dist/esm/instrumentations/errors/getErrorDetails.js +1 -0
- package/dist/esm/instrumentations/errors/getErrorDetails.js.map +1 -1
- package/dist/esm/metas/browser/meta.js +5 -6
- package/dist/esm/metas/browser/meta.js.map +1 -1
- package/dist/esm/metas/index.js +1 -0
- package/dist/esm/metas/index.js.map +1 -1
- package/dist/esm/metas/os/index.js +2 -0
- package/dist/esm/metas/os/index.js.map +1 -0
- package/dist/esm/metas/os/meta.js +16 -0
- package/dist/esm/metas/os/meta.js.map +1 -0
- package/dist/esm/metas/shared/index.js +2 -0
- package/dist/esm/metas/shared/index.js.map +1 -0
- package/dist/esm/metas/shared/uaParser.js +15 -0
- package/dist/esm/metas/shared/uaParser.js.map +1 -0
- package/dist/esm/transports/fetch/transport.js +1 -1
- package/dist/esm/transports/fetch/transport.js.map +1 -1
- package/dist/types/index.d.ts +2 -2
- package/dist/types/instrumentations/console/instrumentation.d.ts +1 -1
- package/dist/types/instrumentations/csp/instrumentation.d.ts +1 -1
- package/dist/types/instrumentations/errors/instrumentation.d.ts +1 -1
- package/dist/types/instrumentations/navigation/instrumentation.d.ts +1 -1
- package/dist/types/instrumentations/performance/instrumentation.d.ts +1 -1
- package/dist/types/instrumentations/session/instrumentation.d.ts +1 -1
- package/dist/types/instrumentations/userActions/instrumentation.d.ts +1 -1
- package/dist/types/instrumentations/view/instrumentation.d.ts +1 -1
- package/dist/types/instrumentations/webVitals/instrumentation.d.ts +1 -1
- package/dist/types/metas/index.d.ts +1 -0
- package/dist/types/metas/os/index.d.ts +1 -0
- package/dist/types/metas/os/meta.d.ts +2 -0
- package/dist/types/metas/shared/index.d.ts +1 -0
- package/dist/types/metas/shared/uaParser.d.ts +4 -0
- package/dist/types/transports/console/transport.d.ts +1 -1
- package/dist/types/transports/fetch/transport.d.ts +1 -1
- package/package.json +5 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"activityWindowTracker.js","sourceRoot":"","sources":["../../../../src/instrumentations/_internal/activityWindowTracker.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"activityWindowTracker.js","sourceRoot":"","sources":["../../../../src/instrumentations/_internal/activityWindowTracker.ts"],"names":[],"mappings":"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","sourcesContent":["import { monoNow, Observable } from '@grafana/faro-core';\n\nimport { MESSAGE_TYPE_HTTP_REQUEST_END, MESSAGE_TYPE_HTTP_REQUEST_START } from './monitors/const';\nimport type { HttpRequestEndMessage, HttpRequestStartMessage } from './monitors/types';\n\ntype OperationKey = string;\n\nexport function isRequestStartMessage(msg: any): msg is HttpRequestStartMessage {\n return msg.type === MESSAGE_TYPE_HTTP_REQUEST_START;\n}\n\nexport function isRequestEndMessage(msg: any): msg is HttpRequestEndMessage {\n return msg.type === MESSAGE_TYPE_HTTP_REQUEST_END;\n}\n\nexport interface ActivityWindowTrackerOptions<TMsg = any> {\n inactivityMs?: number;\n drainTimeoutMs?: number;\n isOperationStart?: (msg: TMsg) => OperationKey | undefined;\n isOperationEnd?: (msg: TMsg) => OperationKey | undefined;\n}\n\n/**\n * Tracks events in a time‑boxed activity window. When the window goes quiet for `inactivityMs`,\n * it enters a draining phase: new short events are ignored; only active operations are awaited\n * until they end or `drainTimeoutMs` elapses.\n */\nexport class ActivityWindowTracker extends Observable {\n eventsObservable: Observable;\n\n private _tracking = false;\n private _inactivityTid?: number;\n private _drainTid?: number;\n private _currentEvents?: any[];\n private _activeOperations?: Map<OperationKey, true>;\n private _startTime?: number;\n private _lastEventTime?: number;\n private _options: Required<ActivityWindowTrackerOptions>;\n\n constructor(eventsObservable: Observable, options?: ActivityWindowTrackerOptions) {\n super();\n this.eventsObservable = eventsObservable;\n this._options = {\n inactivityMs: options?.inactivityMs ?? 100,\n drainTimeoutMs: options?.drainTimeoutMs ?? 10 * 1000,\n isOperationStart: options?.isOperationStart ?? (() => undefined),\n isOperationEnd: options?.isOperationEnd ?? (() => undefined),\n } as Required<ActivityWindowTrackerOptions>;\n this._initialize();\n }\n\n private _initialize() {\n this.eventsObservable\n .filter(() => {\n return this._tracking;\n })\n .subscribe((event) => {\n // Monotonic clock — used only for the duration delta in `stopTracking()`.\n // Not exposed as an absolute timestamp anywhere.\n this._lastEventTime = monoNow();\n this._currentEvents?.push(event);\n\n const startKey = this._options.isOperationStart(event as any);\n if (startKey) {\n this._activeOperations?.set(startKey, true);\n }\n\n const endKey = this._options.isOperationEnd(event as any);\n if (endKey) {\n this._activeOperations?.delete(endKey);\n }\n\n this._scheduleInactivityCheck();\n });\n }\n\n startTracking() {\n if (this._tracking) {\n return;\n }\n\n this._tracking = true;\n // Use a monotonic clock so the resulting `duration` (computed in `stopTracking()`)\n // is immune to wall-clock adjustments (NTP step, manual change, DST) that may\n // occur during the tracking window.\n this._startTime = monoNow();\n this._lastEventTime = this._startTime;\n\n this.notify({\n message: 'tracking-started',\n });\n\n this._currentEvents = [];\n this._activeOperations = new Map<OperationKey, true>();\n this._scheduleInactivityCheck();\n }\n\n stopTracking() {\n this._tracking = false;\n this._clearTimer(this._inactivityTid);\n this._clearTimer(this._drainTid);\n\n let duration;\n if (this.hasActiveOperations()) {\n duration = monoNow() - this._startTime!;\n } else {\n duration = this._lastEventTime ? this._lastEventTime - this._startTime! : 0;\n }\n\n this.notify({\n message: 'tracking-ended',\n events: this._currentEvents,\n duration: duration,\n });\n }\n\n private _scheduleInactivityCheck() {\n this._inactivityTid = startTimeout(\n this._inactivityTid,\n () => {\n if (this.hasActiveOperations()) {\n this._startDrainTimeout();\n } else {\n this.stopTracking();\n }\n },\n this._options.inactivityMs\n );\n }\n\n private _startDrainTimeout() {\n this._drainTid = startTimeout(\n this._drainTid,\n () => {\n this.stopTracking();\n },\n this._options.drainTimeoutMs\n );\n }\n\n private hasActiveOperations(): boolean {\n return !!this._activeOperations && this._activeOperations.size > 0;\n }\n\n private _clearTimer(id?: number) {\n if (id) {\n clearTimeout(id);\n }\n }\n}\n\nfunction startTimeout(timeoutId: number | undefined, cb: () => void, delay: number) {\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n\n //@ts-expect-error for some reason vscode is using the node types\n timeoutId = setTimeout(() => {\n cb();\n }, delay);\n\n return timeoutId;\n}\n"]}
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.monitorConsole = monitorConsole;
|
|
4
4
|
exports.__resetConsoleMonitorForTests = __resetConsoleMonitorForTests;
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
const faro_core_1 = require("@grafana/faro-core");
|
|
6
|
+
const const_1 = require("./const");
|
|
7
|
+
let consoleObservable;
|
|
8
|
+
let isInstrumented = false;
|
|
9
9
|
/**
|
|
10
10
|
* Monitors console methods and emits events to subscribers.
|
|
11
11
|
* @param unpatchedConsole - Optional console to call after notifying subscribers.
|
|
@@ -17,23 +17,19 @@ function monitorConsole(unpatchedConsole) {
|
|
|
17
17
|
consoleObservable = new faro_core_1.Observable();
|
|
18
18
|
}
|
|
19
19
|
if (!isInstrumented) {
|
|
20
|
-
|
|
20
|
+
const originalConsole = unpatchedConsole !== null && unpatchedConsole !== void 0 ? unpatchedConsole : faro_core_1.defaultUnpatchedConsole;
|
|
21
21
|
// Patch ALL console methods - subscribers decide which levels to process
|
|
22
|
-
faro_core_1.allLogLevels.forEach(
|
|
23
|
-
console[level] =
|
|
22
|
+
faro_core_1.allLogLevels.forEach((level) => {
|
|
23
|
+
console[level] = (...args) => {
|
|
24
24
|
var _a;
|
|
25
|
-
var args = [];
|
|
26
|
-
for (var _i = 0; _i < arguments.length; _i++) {
|
|
27
|
-
args[_i] = arguments[_i];
|
|
28
|
-
}
|
|
29
25
|
// Notify all subscribers
|
|
30
26
|
consoleObservable.notify({
|
|
31
27
|
type: const_1.MESSAGE_TYPE_CONSOLE,
|
|
32
|
-
level
|
|
33
|
-
args
|
|
28
|
+
level,
|
|
29
|
+
args,
|
|
34
30
|
});
|
|
35
31
|
// Call the unpatchedConsole method
|
|
36
|
-
(_a =
|
|
32
|
+
(_a = originalConsole[level]) === null || _a === void 0 ? void 0 : _a.apply(console, args);
|
|
37
33
|
};
|
|
38
34
|
});
|
|
39
35
|
isInstrumented = true;
|
|
@@ -43,8 +39,7 @@ function monitorConsole(unpatchedConsole) {
|
|
|
43
39
|
// Test-only utility to reset state between tests
|
|
44
40
|
function __resetConsoleMonitorForTests() {
|
|
45
41
|
// Restore original console methods from defaultUnpatchedConsole
|
|
46
|
-
for (
|
|
47
|
-
var level = allLogLevels_1[_i];
|
|
42
|
+
for (const level of faro_core_1.allLogLevels) {
|
|
48
43
|
if (faro_core_1.defaultUnpatchedConsole[level]) {
|
|
49
44
|
console[level] = faro_core_1.defaultUnpatchedConsole[level];
|
|
50
45
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"consoleMonitor.js","sourceRoot":"","sources":["../../../../../src/instrumentations/_internal/monitors/consoleMonitor.ts"],"names":[],"mappings":";;AAeA,wCA2BC;AAGD,sEAUC;AAvDD,
|
|
1
|
+
{"version":3,"file":"consoleMonitor.js","sourceRoot":"","sources":["../../../../../src/instrumentations/_internal/monitors/consoleMonitor.ts"],"names":[],"mappings":";;AAeA,wCA2BC;AAGD,sEAUC;AAvDD,kDAAuF;AAGvF,mCAA+C;AAG/C,IAAI,iBAAyD,CAAC;AAC9D,IAAI,cAAc,GAAG,KAAK,CAAC;AAE3B;;;;;GAKG;AACH,SAAgB,cAAc,CAAC,gBAAmC;IAChE,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACvB,iBAAiB,GAAG,IAAI,sBAAU,EAAkB,CAAC;IACvD,CAAC;IAED,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,MAAM,eAAe,GAAG,gBAAgB,aAAhB,gBAAgB,cAAhB,gBAAgB,GAAI,mCAAuB,CAAC;QAEpE,yEAAyE;QACzE,wBAAY,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;YAC7B,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,IAAe,EAAE,EAAE;;gBACtC,yBAAyB;gBACzB,iBAAkB,CAAC,MAAM,CAAC;oBACxB,IAAI,EAAE,4BAAoB;oBAC1B,KAAK;oBACL,IAAI;iBACL,CAAC,CAAC;gBAEH,mCAAmC;gBACnC,MAAA,eAAe,CAAC,KAAK,CAAC,0CAAE,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;YAC/C,CAAC,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,cAAc,GAAG,IAAI,CAAC;IACxB,CAAC;IAED,OAAO,iBAAiB,CAAC;AAC3B,CAAC;AAED,iDAAiD;AACjD,SAAgB,6BAA6B;IAC3C,gEAAgE;IAChE,KAAK,MAAM,KAAK,IAAI,wBAAY,EAAE,CAAC;QACjC,IAAI,mCAAuB,CAAC,KAAK,CAAC,EAAE,CAAC;YACnC,OAAO,CAAC,KAAK,CAAC,GAAG,mCAAuB,CAAC,KAAK,CAAuB,CAAC;QACxE,CAAC;IACH,CAAC;IAED,iBAAiB,GAAG,SAAS,CAAC;IAC9B,cAAc,GAAG,KAAK,CAAC;AACzB,CAAC","sourcesContent":["import { allLogLevels, defaultUnpatchedConsole, Observable } from '@grafana/faro-core';\nimport type { UnpatchedConsole } from '@grafana/faro-core';\n\nimport { MESSAGE_TYPE_CONSOLE } from './const';\nimport type { ConsoleMessage } from './types';\n\nlet consoleObservable: Observable<ConsoleMessage> | undefined;\nlet isInstrumented = false;\n\n/**\n * Monitors console methods and emits events to subscribers.\n * @param unpatchedConsole - Optional console to call after notifying subscribers.\n * Only the first caller's value is used (since we patch once).\n * Defaults to defaultUnpatchedConsole.\n */\nexport function monitorConsole(unpatchedConsole?: UnpatchedConsole): Observable<ConsoleMessage> {\n if (!consoleObservable) {\n consoleObservable = new Observable<ConsoleMessage>();\n }\n\n if (!isInstrumented) {\n const originalConsole = unpatchedConsole ?? defaultUnpatchedConsole;\n\n // Patch ALL console methods - subscribers decide which levels to process\n allLogLevels.forEach((level) => {\n console[level] = (...args: unknown[]) => {\n // Notify all subscribers\n consoleObservable!.notify({\n type: MESSAGE_TYPE_CONSOLE,\n level,\n args,\n });\n\n // Call the unpatchedConsole method\n originalConsole[level]?.apply(console, args);\n };\n });\n\n isInstrumented = true;\n }\n\n return consoleObservable;\n}\n\n// Test-only utility to reset state between tests\nexport function __resetConsoleMonitorForTests() {\n // Restore original console methods from defaultUnpatchedConsole\n for (const level of allLogLevels) {\n if (defaultUnpatchedConsole[level]) {\n console[level] = defaultUnpatchedConsole[level] as typeof console.log;\n }\n }\n\n consoleObservable = undefined;\n isInstrumented = false;\n}\n"]}
|
|
@@ -2,16 +2,16 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.monitorDomMutations = monitorDomMutations;
|
|
4
4
|
exports.__resetDomMutationMonitorForTests = __resetDomMutationMonitorForTests;
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
const faro_core_1 = require("@grafana/faro-core");
|
|
6
|
+
const const_1 = require("./const");
|
|
7
|
+
let domMutationObservable;
|
|
8
|
+
let domMutationObserver;
|
|
9
9
|
function monitorDomMutations() {
|
|
10
10
|
if (!domMutationObservable) {
|
|
11
11
|
domMutationObservable = new faro_core_1.Observable();
|
|
12
12
|
}
|
|
13
13
|
if (!domMutationObserver) {
|
|
14
|
-
domMutationObserver = new MutationObserver(
|
|
14
|
+
domMutationObserver = new MutationObserver((_mutationsList, _observer) => {
|
|
15
15
|
domMutationObservable.notify({ type: const_1.MESSAGE_TYPE_DOM_MUTATION });
|
|
16
16
|
});
|
|
17
17
|
domMutationObserver.observe(document, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"domMutationMonitor.js","sourceRoot":"","sources":["../../../../../src/instrumentations/_internal/monitors/domMutationMonitor.ts"],"names":[],"mappings":";;AAQA,kDAmBC;AAGD,8EAMC;AApCD,
|
|
1
|
+
{"version":3,"file":"domMutationMonitor.js","sourceRoot":"","sources":["../../../../../src/instrumentations/_internal/monitors/domMutationMonitor.ts"],"names":[],"mappings":";;AAQA,kDAmBC;AAGD,8EAMC;AApCD,kDAAgD;AAEhD,mCAAoD;AAGpD,IAAI,qBAAiE,CAAC;AACtE,IAAI,mBAAiD,CAAC;AAEtD,SAAgB,mBAAmB;IACjC,IAAI,CAAC,qBAAqB,EAAE,CAAC;QAC3B,qBAAqB,GAAG,IAAI,sBAAU,EAAsB,CAAC;IAC/D,CAAC;IAED,IAAI,CAAC,mBAAmB,EAAE,CAAC;QACzB,mBAAmB,GAAG,IAAI,gBAAgB,CAAC,CAAC,cAAc,EAAE,SAAS,EAAE,EAAE;YACvE,qBAAsB,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,iCAAyB,EAAE,CAAC,CAAC;QACrE,CAAC,CAAC,CAAC;QAEH,mBAAmB,CAAC,OAAO,CAAC,QAAQ,EAAE;YACpC,UAAU,EAAE,IAAI;YAChB,SAAS,EAAE,IAAI;YACf,OAAO,EAAE,IAAI;YACb,aAAa,EAAE,IAAI;SACpB,CAAC,CAAC;IACL,CAAC;IAED,OAAO,qBAAqB,CAAC;AAC/B,CAAC;AAED,iDAAiD;AACjD,SAAgB,iCAAiC;IAC/C,IAAI,mBAAmB,EAAE,CAAC;QACxB,mBAAmB,CAAC,UAAU,EAAE,CAAC;IACnC,CAAC;IACD,mBAAmB,GAAG,SAAS,CAAC;IAChC,qBAAqB,GAAG,SAAS,CAAC;AACpC,CAAC","sourcesContent":["import { Observable } from '@grafana/faro-core';\n\nimport { MESSAGE_TYPE_DOM_MUTATION } from './const';\nimport type { DomMutationMessage } from './types';\n\nlet domMutationObservable: Observable<DomMutationMessage> | undefined;\nlet domMutationObserver: MutationObserver | undefined;\n\nexport function monitorDomMutations(): Observable<DomMutationMessage> {\n if (!domMutationObservable) {\n domMutationObservable = new Observable<DomMutationMessage>();\n }\n\n if (!domMutationObserver) {\n domMutationObserver = new MutationObserver((_mutationsList, _observer) => {\n domMutationObservable!.notify({ type: MESSAGE_TYPE_DOM_MUTATION });\n });\n\n domMutationObserver.observe(document, {\n attributes: true,\n childList: true,\n subtree: true,\n characterData: true,\n });\n }\n\n return domMutationObservable;\n}\n\n// Test-only utility to reset state between tests\nexport function __resetDomMutationMonitorForTests() {\n if (domMutationObserver) {\n domMutationObserver.disconnect();\n }\n domMutationObserver = undefined;\n domMutationObservable = undefined;\n}\n"]}
|
|
@@ -2,18 +2,18 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.monitorHttpRequests = monitorHttpRequests;
|
|
4
4
|
exports.__resetHttpRequestMonitorForTests = __resetHttpRequestMonitorForTests;
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
const faro_core_1 = require("@grafana/faro-core");
|
|
6
|
+
const url_1 = require("../../../utils/url");
|
|
7
|
+
const const_1 = require("./const");
|
|
8
|
+
const apiTypeFetch = 'fetch';
|
|
9
|
+
const apiTypeXhr = 'xhr';
|
|
10
10
|
/**
|
|
11
11
|
* Monitors if any http requests are in progress.
|
|
12
12
|
*/
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
let httpRequestObservable;
|
|
14
|
+
let isInstrumented = false;
|
|
15
|
+
let originalXhrOpen;
|
|
16
|
+
let originalFetchFn;
|
|
17
17
|
function monitorHttpRequests() {
|
|
18
18
|
if (httpRequestObservable) {
|
|
19
19
|
return httpRequestObservable;
|
|
@@ -44,66 +44,64 @@ function monitorHttpRequests() {
|
|
|
44
44
|
}
|
|
45
45
|
return httpRequestObservable;
|
|
46
46
|
}
|
|
47
|
-
function monitorXhr(
|
|
48
|
-
var onRequestStart = _a.onRequestStart, onRequestEnd = _a.onRequestEnd;
|
|
47
|
+
function monitorXhr({ onRequestStart, onRequestEnd, }) {
|
|
49
48
|
if (!originalXhrOpen) {
|
|
50
49
|
originalXhrOpen = XMLHttpRequest.prototype.open;
|
|
51
50
|
}
|
|
52
51
|
XMLHttpRequest.prototype.open = function () {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
52
|
+
const url = arguments[1];
|
|
53
|
+
const isIgnoredUrl = (0, url_1.isUrlIgnored)(url);
|
|
54
|
+
const method = arguments[0];
|
|
55
|
+
const requestId = (0, faro_core_1.genShortID)();
|
|
57
56
|
// request has started to load data.
|
|
58
57
|
this.addEventListener('loadstart', function () {
|
|
59
58
|
if (!isIgnoredUrl) {
|
|
60
|
-
onRequestStart({ url
|
|
59
|
+
onRequestStart({ url, method, requestId, apiType: apiTypeXhr });
|
|
61
60
|
}
|
|
62
61
|
});
|
|
63
62
|
// transaction completes successfully.
|
|
64
63
|
this.addEventListener('load', function () {
|
|
65
64
|
if (!isIgnoredUrl) {
|
|
66
|
-
onRequestEnd({ url
|
|
65
|
+
onRequestEnd({ url, method, requestId, apiType: apiTypeXhr });
|
|
67
66
|
}
|
|
68
67
|
});
|
|
69
68
|
this.addEventListener('error', function () {
|
|
70
69
|
if (!isIgnoredUrl) {
|
|
71
|
-
onRequestEnd({ url
|
|
70
|
+
onRequestEnd({ url, method, requestId, apiType: apiTypeXhr });
|
|
72
71
|
}
|
|
73
72
|
});
|
|
74
73
|
this.addEventListener('abort', function () {
|
|
75
74
|
if (!isIgnoredUrl) {
|
|
76
|
-
onRequestEnd({ url
|
|
75
|
+
onRequestEnd({ url, method, requestId, apiType: apiTypeXhr });
|
|
77
76
|
}
|
|
78
77
|
});
|
|
79
78
|
originalXhrOpen.apply(this, arguments);
|
|
80
79
|
};
|
|
81
80
|
}
|
|
82
|
-
function monitorFetch(
|
|
83
|
-
var onRequestEnd = _a.onRequestEnd, onRequestStart = _a.onRequestStart;
|
|
81
|
+
function monitorFetch({ onRequestEnd, onRequestStart, }) {
|
|
84
82
|
if (!originalFetchFn) {
|
|
85
83
|
originalFetchFn = window.fetch;
|
|
86
84
|
}
|
|
87
85
|
window.fetch = function () {
|
|
88
86
|
var _a, _b;
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
87
|
+
const url = (_a = (0, url_1.getUrlFromResource)(arguments[0])) !== null && _a !== void 0 ? _a : '';
|
|
88
|
+
const isIgnoredUrl = (0, url_1.isUrlIgnored)(url);
|
|
89
|
+
const method = ((_b = arguments[1]) !== null && _b !== void 0 ? _b : {}).method;
|
|
90
|
+
const requestId = (0, faro_core_1.genShortID)();
|
|
93
91
|
if (!isIgnoredUrl) {
|
|
94
|
-
onRequestStart({ url
|
|
92
|
+
onRequestStart({ url, method, requestId, apiType: apiTypeFetch });
|
|
95
93
|
}
|
|
96
94
|
return originalFetchFn
|
|
97
95
|
.apply(this, arguments)
|
|
98
|
-
.then(
|
|
96
|
+
.then((response) => {
|
|
99
97
|
if (!isIgnoredUrl) {
|
|
100
|
-
onRequestEnd({ url
|
|
98
|
+
onRequestEnd({ url, method, requestId, apiType: apiTypeFetch });
|
|
101
99
|
}
|
|
102
100
|
return response;
|
|
103
101
|
})
|
|
104
|
-
.catch(
|
|
102
|
+
.catch((error) => {
|
|
105
103
|
if (!isIgnoredUrl) {
|
|
106
|
-
onRequestEnd({ url
|
|
104
|
+
onRequestEnd({ url, method, requestId, apiType: apiTypeFetch });
|
|
107
105
|
}
|
|
108
106
|
throw error;
|
|
109
107
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"httpRequestMonitor.js","sourceRoot":"","sources":["../../../../../src/instrumentations/_internal/monitors/httpRequestMonitor.ts"],"names":[],"mappings":";;AAoBA,kDAoCC;AAyFD,8EAWC;AA5JD,
|
|
1
|
+
{"version":3,"file":"httpRequestMonitor.js","sourceRoot":"","sources":["../../../../../src/instrumentations/_internal/monitors/httpRequestMonitor.ts"],"names":[],"mappings":"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","sourcesContent":["import { genShortID, Observable } from '@grafana/faro-core';\n\nimport { getUrlFromResource, isUrlIgnored } from '../../../utils/url';\n\nimport { MESSAGE_TYPE_HTTP_REQUEST_END, MESSAGE_TYPE_HTTP_REQUEST_START } from './const';\nimport type { HttpRequestEndMessage, HttpRequestMessagePayload, HttpRequestStartMessage } from './types';\n\ntype RequestProps = HttpRequestMessagePayload;\n\nconst apiTypeFetch = 'fetch';\nconst apiTypeXhr = 'xhr';\n\n/**\n * Monitors if any http requests are in progress.\n */\nlet httpRequestObservable: Observable<HttpRequestStartMessage | HttpRequestEndMessage> | undefined;\nlet isInstrumented = false;\nlet originalXhrOpen: typeof XMLHttpRequest.prototype.open | undefined;\nlet originalFetchFn: typeof window.fetch | undefined;\n\nexport function monitorHttpRequests(): Observable<HttpRequestStartMessage | HttpRequestEndMessage> {\n if (httpRequestObservable) {\n return httpRequestObservable;\n }\n\n httpRequestObservable = new Observable<HttpRequestStartMessage | HttpRequestEndMessage>();\n\n function emitStartMessage(requestProps: RequestProps) {\n httpRequestObservable!.notify({\n type: MESSAGE_TYPE_HTTP_REQUEST_START,\n request: requestProps,\n });\n }\n\n function emitEndMessage(requestProps: RequestProps) {\n httpRequestObservable!.notify({\n type: MESSAGE_TYPE_HTTP_REQUEST_END,\n request: requestProps,\n });\n }\n\n if (!isInstrumented) {\n monitorFetch({\n onRequestStart: emitStartMessage,\n onRequestEnd: emitEndMessage,\n });\n\n monitorXhr({\n onRequestStart: emitStartMessage,\n onRequestEnd: emitEndMessage,\n });\n\n isInstrumented = true;\n }\n\n return httpRequestObservable;\n}\n\nfunction monitorXhr({\n onRequestStart,\n onRequestEnd,\n}: {\n onRequestStart: (props: RequestProps) => void;\n onRequestEnd: (props: RequestProps) => void;\n}) {\n if (!originalXhrOpen) {\n originalXhrOpen = XMLHttpRequest.prototype.open;\n }\n\n XMLHttpRequest.prototype.open = function () {\n const url = arguments[1];\n const isIgnoredUrl = isUrlIgnored(url);\n const method = arguments[0];\n\n const requestId = genShortID();\n\n // request has started to load data.\n this.addEventListener('loadstart', function () {\n if (!isIgnoredUrl) {\n onRequestStart({ url, method, requestId, apiType: apiTypeXhr });\n }\n });\n\n // transaction completes successfully.\n this.addEventListener('load', function () {\n if (!isIgnoredUrl) {\n onRequestEnd({ url, method, requestId, apiType: apiTypeXhr });\n }\n });\n\n this.addEventListener('error', function () {\n if (!isIgnoredUrl) {\n onRequestEnd({ url, method, requestId, apiType: apiTypeXhr });\n }\n });\n\n this.addEventListener('abort', function () {\n if (!isIgnoredUrl) {\n onRequestEnd({ url, method, requestId, apiType: apiTypeXhr });\n }\n });\n originalXhrOpen!.apply(this, arguments as any);\n };\n}\n\nfunction monitorFetch({\n onRequestEnd,\n onRequestStart,\n}: {\n onRequestStart: (props: RequestProps) => void;\n onRequestEnd: (props: RequestProps) => void;\n}) {\n if (!originalFetchFn) {\n originalFetchFn = window.fetch;\n }\n\n window.fetch = function () {\n const url = getUrlFromResource(arguments[0]) ?? '';\n const isIgnoredUrl = isUrlIgnored(url);\n const method = (arguments[1] ?? {}).method;\n\n const requestId = genShortID();\n\n if (!isIgnoredUrl) {\n onRequestStart({ url, method, requestId, apiType: apiTypeFetch });\n }\n\n return originalFetchFn!\n .apply(this, arguments as any)\n .then((response) => {\n if (!isIgnoredUrl) {\n onRequestEnd({ url, method, requestId, apiType: apiTypeFetch });\n }\n return response;\n })\n .catch((error) => {\n if (!isIgnoredUrl) {\n onRequestEnd({ url, method, requestId, apiType: apiTypeFetch });\n }\n throw error;\n });\n };\n}\n\n// Test-only utility to reset instrumentation and singleton between tests\nexport function __resetHttpRequestMonitorForTests() {\n if (originalXhrOpen) {\n XMLHttpRequest.prototype.open = originalXhrOpen;\n }\n if (originalFetchFn) {\n (window as any).fetch = originalFetchFn;\n }\n httpRequestObservable = undefined;\n isInstrumented = false;\n originalXhrOpen = undefined;\n originalFetchFn = undefined;\n}\n"]}
|
|
@@ -3,18 +3,18 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.MESSAGE_TYPE_INTERACTION = void 0;
|
|
4
4
|
exports.monitorInteractions = monitorInteractions;
|
|
5
5
|
exports.__resetInteractionMonitorForTests = __resetInteractionMonitorForTests;
|
|
6
|
-
|
|
6
|
+
const faro_core_1 = require("@grafana/faro-core");
|
|
7
7
|
exports.MESSAGE_TYPE_INTERACTION = 'interaction';
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
let interactionObservable;
|
|
9
|
+
const registeredEventNames = new Set();
|
|
10
|
+
const eventNameToHandler = new Map();
|
|
11
11
|
function monitorInteractions(eventNames) {
|
|
12
12
|
if (!interactionObservable) {
|
|
13
13
|
interactionObservable = new faro_core_1.Observable();
|
|
14
14
|
}
|
|
15
|
-
eventNames.forEach(
|
|
15
|
+
eventNames.forEach((eventName) => {
|
|
16
16
|
if (!registeredEventNames.has(eventName)) {
|
|
17
|
-
|
|
17
|
+
const handler = () => {
|
|
18
18
|
interactionObservable.notify({ type: exports.MESSAGE_TYPE_INTERACTION, name: eventName });
|
|
19
19
|
};
|
|
20
20
|
window.addEventListener(eventName, handler);
|
|
@@ -26,7 +26,7 @@ function monitorInteractions(eventNames) {
|
|
|
26
26
|
}
|
|
27
27
|
// Test-only utility to reset state between tests
|
|
28
28
|
function __resetInteractionMonitorForTests() {
|
|
29
|
-
eventNameToHandler.forEach(
|
|
29
|
+
eventNameToHandler.forEach((handler, eventName) => {
|
|
30
30
|
window.removeEventListener(eventName, handler);
|
|
31
31
|
});
|
|
32
32
|
eventNameToHandler.clear();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interactionMonitor.js","sourceRoot":"","sources":["../../../../../src/instrumentations/_internal/monitors/interactionMonitor.ts"],"names":[],"mappings":";;;AAaA,kDAiBC;AAGD,8EAOC;AAxCD,
|
|
1
|
+
{"version":3,"file":"interactionMonitor.js","sourceRoot":"","sources":["../../../../../src/instrumentations/_internal/monitors/interactionMonitor.ts"],"names":[],"mappings":";;;AAaA,kDAiBC;AAGD,8EAOC;AAxCD,kDAAgD;AAEnC,QAAA,wBAAwB,GAAG,aAAa,CAAC;AAOtD,IAAI,qBAAiE,CAAC;AACtE,MAAM,oBAAoB,GAAG,IAAI,GAAG,EAAU,CAAC;AAC/C,MAAM,kBAAkB,GAAG,IAAI,GAAG,EAA8B,CAAC;AAEjE,SAAgB,mBAAmB,CAAC,UAAoB;IACtD,IAAI,CAAC,qBAAqB,EAAE,CAAC;QAC3B,qBAAqB,GAAG,IAAI,sBAAU,EAAsB,CAAC;IAC/D,CAAC;IAED,UAAU,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,EAAE;QAC/B,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;YACzC,MAAM,OAAO,GAAG,GAAG,EAAE;gBACnB,qBAAsB,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,gCAAwB,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;YACrF,CAAC,CAAC;YACF,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;YAC5C,oBAAoB,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YACpC,kBAAkB,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAC7C,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,qBAAqB,CAAC;AAC/B,CAAC;AAED,iDAAiD;AACjD,SAAgB,iCAAiC;IAC/C,kBAAkB,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,SAAS,EAAE,EAAE;QAChD,MAAM,CAAC,mBAAmB,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IACH,kBAAkB,CAAC,KAAK,EAAE,CAAC;IAC3B,oBAAoB,CAAC,KAAK,EAAE,CAAC;IAC7B,qBAAqB,GAAG,SAAS,CAAC;AACpC,CAAC","sourcesContent":["import { Observable } from '@grafana/faro-core';\n\nexport const MESSAGE_TYPE_INTERACTION = 'interaction';\n\nexport type InteractionMessage = {\n type: typeof MESSAGE_TYPE_INTERACTION;\n name: string;\n};\n\nlet interactionObservable: Observable<InteractionMessage> | undefined;\nconst registeredEventNames = new Set<string>();\nconst eventNameToHandler = new Map<string, (e: Event) => void>();\n\nexport function monitorInteractions(eventNames: string[]): Observable<InteractionMessage> {\n if (!interactionObservable) {\n interactionObservable = new Observable<InteractionMessage>();\n }\n\n eventNames.forEach((eventName) => {\n if (!registeredEventNames.has(eventName)) {\n const handler = () => {\n interactionObservable!.notify({ type: MESSAGE_TYPE_INTERACTION, name: eventName });\n };\n window.addEventListener(eventName, handler);\n registeredEventNames.add(eventName);\n eventNameToHandler.set(eventName, handler);\n }\n });\n\n return interactionObservable;\n}\n\n// Test-only utility to reset state between tests\nexport function __resetInteractionMonitorForTests() {\n eventNameToHandler.forEach((handler, eventName) => {\n window.removeEventListener(eventName, handler);\n });\n eventNameToHandler.clear();\n registeredEventNames.clear();\n interactionObservable = undefined;\n}\n"]}
|
|
@@ -2,19 +2,19 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.monitorPerformanceEntries = monitorPerformanceEntries;
|
|
4
4
|
exports.__resetPerformanceEntriesMonitorForTests = __resetPerformanceEntriesMonitorForTests;
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
5
|
+
const faro_core_1 = require("@grafana/faro-core");
|
|
6
|
+
const instrumentation_1 = require("../../performance/instrumentation");
|
|
7
|
+
const performanceConstants_1 = require("../../performance/performanceConstants");
|
|
8
|
+
const const_1 = require("./const");
|
|
9
|
+
let performanceObservable;
|
|
10
|
+
let isSubscribed = false;
|
|
11
|
+
let subscription;
|
|
12
12
|
function monitorPerformanceEntries() {
|
|
13
13
|
if (!performanceObservable) {
|
|
14
14
|
performanceObservable = new faro_core_1.Observable();
|
|
15
15
|
}
|
|
16
16
|
if (!isSubscribed) {
|
|
17
|
-
subscription = instrumentation_1.performanceEntriesSubscription.subscribe(
|
|
17
|
+
subscription = instrumentation_1.performanceEntriesSubscription.subscribe((data) => {
|
|
18
18
|
if (data.type === performanceConstants_1.RESOURCE_ENTRY) {
|
|
19
19
|
performanceObservable.notify({ type: const_1.MESSAGE_TYPE_RESOURCE_ENTRY });
|
|
20
20
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"performanceEntriesMonitor.js","sourceRoot":"","sources":["../../../../../src/instrumentations/_internal/monitors/performanceEntriesMonitor.ts"],"names":[],"mappings":";;AAYA,8DAeC;AAGD,4FAOC;AArCD,
|
|
1
|
+
{"version":3,"file":"performanceEntriesMonitor.js","sourceRoot":"","sources":["../../../../../src/instrumentations/_internal/monitors/performanceEntriesMonitor.ts"],"names":[],"mappings":";;AAYA,8DAeC;AAGD,4FAOC;AArCD,kDAAgD;AAGhD,uEAAmF;AACnF,iFAAwE;AAExE,mCAAsD;AAEtD,IAAI,qBAA6C,CAAC;AAClD,IAAI,YAAY,GAAG,KAAK,CAAC;AACzB,IAAI,YAAsC,CAAC;AAE3C,SAAgB,yBAAyB;IACvC,IAAI,CAAC,qBAAqB,EAAE,CAAC;QAC3B,qBAAqB,GAAG,IAAI,sBAAU,EAAE,CAAC;IAC3C,CAAC;IAED,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,YAAY,GAAG,gDAA8B,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE;YAC/D,IAAI,IAAI,CAAC,IAAI,KAAK,qCAAc,EAAE,CAAC;gBACjC,qBAAsB,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,mCAA2B,EAAE,CAAC,CAAC;YACvE,CAAC;QACH,CAAC,CAAC,CAAC;QACH,YAAY,GAAG,IAAI,CAAC;IACtB,CAAC;IAED,OAAO,qBAAqB,CAAC;AAC/B,CAAC;AAED,iDAAiD;AACjD,SAAgB,wCAAwC;IACtD,IAAI,YAAY,EAAE,CAAC;QACjB,YAAY,CAAC,WAAW,EAAE,CAAC;IAC7B,CAAC;IACD,YAAY,GAAG,SAAS,CAAC;IACzB,YAAY,GAAG,KAAK,CAAC;IACrB,qBAAqB,GAAG,SAAS,CAAC;AACpC,CAAC","sourcesContent":["import { Observable } from '@grafana/faro-core';\nimport type { Subscription } from '@grafana/faro-core';\n\nimport { performanceEntriesSubscription } from '../../performance/instrumentation';\nimport { RESOURCE_ENTRY } from '../../performance/performanceConstants';\n\nimport { MESSAGE_TYPE_RESOURCE_ENTRY } from './const';\n\nlet performanceObservable: Observable | undefined;\nlet isSubscribed = false;\nlet subscription: Subscription | undefined;\n\nexport function monitorPerformanceEntries(): Observable {\n if (!performanceObservable) {\n performanceObservable = new Observable();\n }\n\n if (!isSubscribed) {\n subscription = performanceEntriesSubscription.subscribe((data) => {\n if (data.type === RESOURCE_ENTRY) {\n performanceObservable!.notify({ type: MESSAGE_TYPE_RESOURCE_ENTRY });\n }\n });\n isSubscribed = true;\n }\n\n return performanceObservable;\n}\n\n// Test-only utility to reset state between tests\nexport function __resetPerformanceEntriesMonitorForTests() {\n if (subscription) {\n subscription.unsubscribe();\n }\n subscription = undefined;\n isSubscribed = false;\n performanceObservable = undefined;\n}\n"]}
|
|
@@ -3,36 +3,36 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.MESSAGE_TYPE_URL_CHANGE = void 0;
|
|
4
4
|
exports.monitorUrlChanges = monitorUrlChanges;
|
|
5
5
|
exports.__resetUrlChangeMonitorForTests = __resetUrlChangeMonitorForTests;
|
|
6
|
-
|
|
6
|
+
const faro_core_1 = require("@grafana/faro-core");
|
|
7
7
|
exports.MESSAGE_TYPE_URL_CHANGE = 'url-change';
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
8
|
+
let urlChangeObservable;
|
|
9
|
+
let isInstrumented = false;
|
|
10
|
+
let lastHref;
|
|
11
|
+
let originalPushState;
|
|
12
|
+
let originalReplaceState;
|
|
13
|
+
let onPopStateHandler;
|
|
14
|
+
let onHashChangeHandler;
|
|
15
|
+
let onNavigateHandler;
|
|
16
|
+
let originalNavigateEventIntercept;
|
|
17
17
|
function monitorUrlChanges() {
|
|
18
18
|
if (!urlChangeObservable) {
|
|
19
19
|
urlChangeObservable = new faro_core_1.Observable();
|
|
20
20
|
lastHref = location.href;
|
|
21
21
|
}
|
|
22
22
|
function emit(trigger, toOverride) {
|
|
23
|
-
|
|
23
|
+
const next = toOverride !== null && toOverride !== void 0 ? toOverride : location.href;
|
|
24
24
|
if (next !== lastHref) {
|
|
25
|
-
urlChangeObservable.notify({ type: exports.MESSAGE_TYPE_URL_CHANGE, from: lastHref, to: next, trigger
|
|
25
|
+
urlChangeObservable.notify({ type: exports.MESSAGE_TYPE_URL_CHANGE, from: lastHref, to: next, trigger });
|
|
26
26
|
lastHref = next;
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
29
|
if (!isInstrumented) {
|
|
30
|
-
|
|
30
|
+
const hasNavigation = 'navigation' in window && 'NavigateEvent' in window;
|
|
31
31
|
if (hasNavigation) {
|
|
32
32
|
// Prefer Navigation API when supported: do not patch history or add popstate/hashchange listeners
|
|
33
|
-
onNavigateHandler =
|
|
33
|
+
onNavigateHandler = (e) => {
|
|
34
34
|
try {
|
|
35
|
-
|
|
35
|
+
const destination = e === null || e === void 0 ? void 0 : e.destination;
|
|
36
36
|
if ((destination === null || destination === void 0 ? void 0 : destination.sameDocument) && typeof destination.url === 'string') {
|
|
37
37
|
emit('navigate', destination.url);
|
|
38
38
|
}
|
|
@@ -42,7 +42,7 @@ function monitorUrlChanges() {
|
|
|
42
42
|
}
|
|
43
43
|
};
|
|
44
44
|
window.navigation.addEventListener('navigate', onNavigateHandler);
|
|
45
|
-
|
|
45
|
+
const NavigateEventConstructor = window.NavigateEvent;
|
|
46
46
|
if (NavigateEventConstructor &&
|
|
47
47
|
NavigateEventConstructor.prototype &&
|
|
48
48
|
typeof NavigateEventConstructor.prototype.intercept === 'function') {
|
|
@@ -52,8 +52,8 @@ function monitorUrlChanges() {
|
|
|
52
52
|
// Wrap intercept to detect soft navigations (cross-document turned same-document)
|
|
53
53
|
NavigateEventConstructor.prototype.intercept = function (options) {
|
|
54
54
|
try {
|
|
55
|
-
|
|
56
|
-
|
|
55
|
+
const canIntercept = !!(this === null || this === void 0 ? void 0 : this.canIntercept);
|
|
56
|
+
const destination = this === null || this === void 0 ? void 0 : this.destination;
|
|
57
57
|
if (canIntercept &&
|
|
58
58
|
destination &&
|
|
59
59
|
destination.sameDocument === false &&
|
|
@@ -74,29 +74,21 @@ function monitorUrlChanges() {
|
|
|
74
74
|
if (!originalPushState) {
|
|
75
75
|
originalPushState = window.history.pushState;
|
|
76
76
|
}
|
|
77
|
-
window.history.pushState = function () {
|
|
78
|
-
|
|
79
|
-
for (var _i = 0; _i < arguments.length; _i++) {
|
|
80
|
-
args[_i] = arguments[_i];
|
|
81
|
-
}
|
|
82
|
-
var result = originalPushState.apply(window.history, args);
|
|
77
|
+
window.history.pushState = function (...args) {
|
|
78
|
+
const result = originalPushState.apply(window.history, args);
|
|
83
79
|
emit('pushState');
|
|
84
80
|
return result;
|
|
85
81
|
};
|
|
86
82
|
if (!originalReplaceState) {
|
|
87
83
|
originalReplaceState = window.history.replaceState;
|
|
88
84
|
}
|
|
89
|
-
window.history.replaceState = function () {
|
|
90
|
-
|
|
91
|
-
for (var _i = 0; _i < arguments.length; _i++) {
|
|
92
|
-
args[_i] = arguments[_i];
|
|
93
|
-
}
|
|
94
|
-
var result = originalReplaceState.apply(window.history, args);
|
|
85
|
+
window.history.replaceState = function (...args) {
|
|
86
|
+
const result = originalReplaceState.apply(window.history, args);
|
|
95
87
|
emit('replaceState');
|
|
96
88
|
return result;
|
|
97
89
|
};
|
|
98
|
-
onPopStateHandler =
|
|
99
|
-
onHashChangeHandler =
|
|
90
|
+
onPopStateHandler = () => emit('popstate');
|
|
91
|
+
onHashChangeHandler = () => emit('hashchange');
|
|
100
92
|
window.addEventListener('popstate', onPopStateHandler);
|
|
101
93
|
window.addEventListener('hashchange', onHashChangeHandler);
|
|
102
94
|
isInstrumented = true;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"urlChangeMonitor.js","sourceRoot":"","sources":["../../../../../src/instrumentations/_internal/monitors/urlChangeMonitor.ts"],"names":[],"mappings":"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","sourcesContent":["import { Observable } from '@grafana/faro-core';\n\nexport const MESSAGE_TYPE_URL_CHANGE = 'url-change';\n\nexport type UrlChangeMessage = {\n type: typeof MESSAGE_TYPE_URL_CHANGE;\n from: string;\n to: string;\n trigger: 'pushState' | 'replaceState' | 'popstate' | 'hashchange' | 'navigate' | 'navigate-intercept';\n};\n\nlet urlChangeObservable: Observable<UrlChangeMessage> | undefined;\nlet isInstrumented = false;\nlet lastHref: string | undefined;\nlet originalPushState: typeof window.history.pushState | undefined;\nlet originalReplaceState: typeof window.history.replaceState | undefined;\nlet onPopStateHandler: ((this: Window, ev: PopStateEvent) => any) | undefined;\nlet onHashChangeHandler: ((this: Window, ev: HashChangeEvent) => any) | undefined;\nlet onNavigateHandler: ((this: any, ev: any) => any) | undefined;\nlet originalNavigateEventIntercept: (((this: any, options?: any) => any) & { _faroWrapped?: boolean }) | undefined;\n\nexport function monitorUrlChanges(): Observable<UrlChangeMessage> {\n if (!urlChangeObservable) {\n urlChangeObservable = new Observable<UrlChangeMessage>();\n lastHref = location.href;\n }\n\n function emit(trigger: UrlChangeMessage['trigger'], toOverride?: string) {\n const next = toOverride ?? location.href;\n if (next !== lastHref) {\n urlChangeObservable!.notify({ type: MESSAGE_TYPE_URL_CHANGE, from: lastHref!, to: next, trigger });\n lastHref = next;\n }\n }\n\n if (!isInstrumented) {\n const hasNavigation = 'navigation' in window && 'NavigateEvent' in (window as any);\n\n if (hasNavigation) {\n // Prefer Navigation API when supported: do not patch history or add popstate/hashchange listeners\n onNavigateHandler = (e: any) => {\n try {\n const destination = e?.destination as { url?: string; sameDocument?: boolean } | undefined;\n if (destination?.sameDocument && typeof destination.url === 'string') {\n emit('navigate', destination.url);\n }\n } catch (_err) {\n // Swallow to avoid impacting host app\n }\n };\n (window as any).navigation.addEventListener('navigate', onNavigateHandler as any);\n\n const NavigateEventConstructor = (window as any).NavigateEvent;\n if (\n NavigateEventConstructor &&\n NavigateEventConstructor.prototype &&\n typeof NavigateEventConstructor.prototype.intercept === 'function'\n ) {\n if (!originalNavigateEventIntercept) {\n originalNavigateEventIntercept = NavigateEventConstructor.prototype.intercept;\n }\n\n // Wrap intercept to detect soft navigations (cross-document turned same-document)\n NavigateEventConstructor.prototype.intercept = function (this: any, options?: any) {\n try {\n const canIntercept = !!this?.canIntercept;\n const destination = this?.destination as { url?: string; sameDocument?: boolean } | undefined;\n if (\n canIntercept &&\n destination &&\n destination.sameDocument === false &&\n typeof destination.url === 'string'\n ) {\n emit('navigate-intercept', destination.url);\n }\n } catch (_err) {\n // ignore\n }\n return originalNavigateEventIntercept!.call(this, options);\n } as typeof originalNavigateEventIntercept;\n }\n\n isInstrumented = true;\n } else {\n // Fallback: history API patching + popstate/hashchange\n if (!originalPushState) {\n originalPushState = window.history.pushState;\n }\n window.history.pushState = function (...args: Parameters<typeof window.history.pushState>) {\n const result = originalPushState!.apply(window.history, args as any);\n emit('pushState');\n return result;\n } as typeof window.history.pushState;\n\n if (!originalReplaceState) {\n originalReplaceState = window.history.replaceState;\n }\n window.history.replaceState = function (...args: Parameters<typeof window.history.replaceState>) {\n const result = originalReplaceState!.apply(window.history, args as any);\n emit('replaceState');\n return result;\n } as typeof window.history.replaceState;\n\n onPopStateHandler = () => emit('popstate');\n onHashChangeHandler = () => emit('hashchange');\n window.addEventListener('popstate', onPopStateHandler);\n window.addEventListener('hashchange', onHashChangeHandler);\n\n isInstrumented = true;\n }\n }\n\n return urlChangeObservable;\n}\n\n// Test-only utility to reset state between tests\nexport function __resetUrlChangeMonitorForTests() {\n if (onPopStateHandler) {\n window.removeEventListener('popstate', onPopStateHandler);\n }\n if (onHashChangeHandler) {\n window.removeEventListener('hashchange', onHashChangeHandler);\n }\n if (onNavigateHandler && (window as any).navigation?.removeEventListener) {\n (window as any).navigation.removeEventListener('navigate', onNavigateHandler as any);\n }\n if (originalPushState) {\n window.history.pushState = originalPushState;\n }\n if (originalReplaceState) {\n window.history.replaceState = originalReplaceState;\n }\n if (originalNavigateEventIntercept && (window as any).NavigateEvent?.prototype) {\n (window as any).NavigateEvent.prototype.intercept = originalNavigateEventIntercept;\n }\n urlChangeObservable = undefined;\n isInstrumented = false;\n lastHref = undefined;\n onPopStateHandler = undefined;\n onHashChangeHandler = undefined;\n onNavigateHandler = undefined;\n originalPushState = undefined;\n originalReplaceState = undefined;\n originalNavigateEventIntercept = undefined;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"urlChangeMonitor.js","sourceRoot":"","sources":["../../../../../src/instrumentations/_internal/monitors/urlChangeMonitor.ts"],"names":[],"mappings":"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","sourcesContent":["import { Observable } from '@grafana/faro-core';\n\nexport const MESSAGE_TYPE_URL_CHANGE = 'url-change';\n\nexport type UrlChangeMessage = {\n type: typeof MESSAGE_TYPE_URL_CHANGE;\n from: string;\n to: string;\n trigger: 'pushState' | 'replaceState' | 'popstate' | 'hashchange' | 'navigate' | 'navigate-intercept';\n};\n\nlet urlChangeObservable: Observable<UrlChangeMessage> | undefined;\nlet isInstrumented = false;\nlet lastHref: string | undefined;\nlet originalPushState: typeof window.history.pushState | undefined;\nlet originalReplaceState: typeof window.history.replaceState | undefined;\nlet onPopStateHandler: ((this: Window, ev: PopStateEvent) => any) | undefined;\nlet onHashChangeHandler: ((this: Window, ev: HashChangeEvent) => any) | undefined;\nlet onNavigateHandler: ((this: any, ev: any) => any) | undefined;\nlet originalNavigateEventIntercept: (((this: any, options?: any) => any) & { _faroWrapped?: boolean }) | undefined;\n\nexport function monitorUrlChanges(): Observable<UrlChangeMessage> {\n if (!urlChangeObservable) {\n urlChangeObservable = new Observable<UrlChangeMessage>();\n lastHref = location.href;\n }\n\n function emit(trigger: UrlChangeMessage['trigger'], toOverride?: string) {\n const next = toOverride ?? location.href;\n if (next !== lastHref) {\n urlChangeObservable!.notify({ type: MESSAGE_TYPE_URL_CHANGE, from: lastHref!, to: next, trigger });\n lastHref = next;\n }\n }\n\n if (!isInstrumented) {\n const hasNavigation = 'navigation' in window && 'NavigateEvent' in (window as any);\n\n if (hasNavigation) {\n // Prefer Navigation API when supported: do not patch history or add popstate/hashchange listeners\n onNavigateHandler = (e: any) => {\n try {\n const destination = e?.destination as { url?: string; sameDocument?: boolean } | undefined;\n if (destination?.sameDocument && typeof destination.url === 'string') {\n emit('navigate', destination.url);\n }\n } catch (_err) {\n // Swallow to avoid impacting host app\n }\n };\n (window as any).navigation.addEventListener('navigate', onNavigateHandler as any);\n\n const NavigateEventConstructor = (window as any).NavigateEvent;\n if (\n NavigateEventConstructor &&\n NavigateEventConstructor.prototype &&\n typeof NavigateEventConstructor.prototype.intercept === 'function'\n ) {\n if (!originalNavigateEventIntercept) {\n originalNavigateEventIntercept = NavigateEventConstructor.prototype.intercept;\n }\n\n // Wrap intercept to detect soft navigations (cross-document turned same-document)\n NavigateEventConstructor.prototype.intercept = function (this: any, options?: any) {\n try {\n const canIntercept = !!this?.canIntercept;\n const destination = this?.destination as { url?: string; sameDocument?: boolean } | undefined;\n if (\n canIntercept &&\n destination &&\n destination.sameDocument === false &&\n typeof destination.url === 'string'\n ) {\n emit('navigate-intercept', destination.url);\n }\n } catch (_err) {\n // ignore\n }\n return originalNavigateEventIntercept!.call(this, options);\n } as typeof originalNavigateEventIntercept;\n }\n\n isInstrumented = true;\n } else {\n // Fallback: history API patching + popstate/hashchange\n if (!originalPushState) {\n originalPushState = window.history.pushState;\n }\n window.history.pushState = function (...args: Parameters<typeof window.history.pushState>) {\n const result = originalPushState!.apply(window.history, args as any);\n emit('pushState');\n return result;\n } as typeof window.history.pushState;\n\n if (!originalReplaceState) {\n originalReplaceState = window.history.replaceState;\n }\n window.history.replaceState = function (...args: Parameters<typeof window.history.replaceState>) {\n const result = originalReplaceState!.apply(window.history, args as any);\n emit('replaceState');\n return result;\n } as typeof window.history.replaceState;\n\n onPopStateHandler = () => emit('popstate');\n onHashChangeHandler = () => emit('hashchange');\n window.addEventListener('popstate', onPopStateHandler);\n window.addEventListener('hashchange', onHashChangeHandler);\n\n isInstrumented = true;\n }\n }\n\n return urlChangeObservable;\n}\n\n// Test-only utility to reset state between tests\nexport function __resetUrlChangeMonitorForTests() {\n if (onPopStateHandler) {\n window.removeEventListener('popstate', onPopStateHandler);\n }\n if (onHashChangeHandler) {\n window.removeEventListener('hashchange', onHashChangeHandler);\n }\n if (onNavigateHandler && (window as any).navigation?.removeEventListener) {\n (window as any).navigation.removeEventListener('navigate', onNavigateHandler as any);\n }\n if (originalPushState) {\n window.history.pushState = originalPushState;\n }\n if (originalReplaceState) {\n window.history.replaceState = originalReplaceState;\n }\n if (originalNavigateEventIntercept && (window as any).NavigateEvent?.prototype) {\n (window as any).NavigateEvent.prototype.intercept = originalNavigateEventIntercept;\n }\n urlChangeObservable = undefined;\n isInstrumented = false;\n lastHref = undefined;\n onPopStateHandler = undefined;\n onHashChangeHandler = undefined;\n onNavigateHandler = undefined;\n originalPushState = undefined;\n originalReplaceState = undefined;\n originalNavigateEventIntercept = undefined;\n}\n"]}
|