@grafana/faro-web-sdk 2.3.0 → 2.4.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/dist/bundle/faro-web-sdk.iife.js +1 -1
- 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/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 +48 -60
- package/dist/cjs/config/makeCoreConfig.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 +44 -65
- package/dist/cjs/instrumentations/_internal/activityWindowTracker.js.map +1 -1
- package/dist/cjs/instrumentations/_internal/monitors/consoleMonitor.js +11 -17
- 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 +64 -61
- 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 +14 -14
- package/dist/cjs/metas/browser/meta.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/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/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/instrumentations/_internal/monitors/consoleMonitor.js +0 -1
- package/dist/esm/instrumentations/_internal/monitors/consoleMonitor.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/instrumentations/session/sessionManager/sessionManagerUtils.js +22 -2
- package/dist/esm/instrumentations/session/sessionManager/sessionManagerUtils.js.map +1 -1
- package/dist/esm/transports/fetch/transport.js +1 -1
- package/dist/esm/transports/fetch/transport.js.map +1 -1
- 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/transports/console/transport.d.ts +1 -1
- package/dist/types/transports/fetch/transport.d.ts +1 -1
- package/package.json +9 -6
|
@@ -1,55 +1,38 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __extends = (this && this.__extends) || (function () {
|
|
3
|
-
var extendStatics = function (d, b) {
|
|
4
|
-
extendStatics = Object.setPrototypeOf ||
|
|
5
|
-
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
6
|
-
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
|
7
|
-
return extendStatics(d, b);
|
|
8
|
-
};
|
|
9
|
-
return function (d, b) {
|
|
10
|
-
if (typeof b !== "function" && b !== null)
|
|
11
|
-
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
|
12
|
-
extendStatics(d, b);
|
|
13
|
-
function __() { this.constructor = d; }
|
|
14
|
-
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
15
|
-
};
|
|
16
|
-
})();
|
|
17
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
3
|
exports.NavigationInstrumentation = void 0;
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
_this.version = faro_core_1.VERSION;
|
|
31
|
-
return _this;
|
|
4
|
+
const faro_core_1 = require("@grafana/faro-core");
|
|
5
|
+
const activityWindowTracker_1 = require("../_internal/activityWindowTracker");
|
|
6
|
+
const domMutationMonitor_1 = require("../_internal/monitors/domMutationMonitor");
|
|
7
|
+
const httpRequestMonitor_1 = require("../_internal/monitors/httpRequestMonitor");
|
|
8
|
+
const interactionMonitor_1 = require("../_internal/monitors/interactionMonitor");
|
|
9
|
+
const urlChangeMonitor_1 = require("../_internal/monitors/urlChangeMonitor");
|
|
10
|
+
class NavigationInstrumentation extends faro_core_1.BaseInstrumentation {
|
|
11
|
+
constructor() {
|
|
12
|
+
super(...arguments);
|
|
13
|
+
this.name = '@grafana/faro-web-sdk:instrumentation-navigation';
|
|
14
|
+
this.version = faro_core_1.VERSION;
|
|
32
15
|
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
16
|
+
initialize() {
|
|
17
|
+
const httpMonitor = (0, httpRequestMonitor_1.monitorHttpRequests)();
|
|
18
|
+
const domMutationsMonitor = (0, domMutationMonitor_1.monitorDomMutations)();
|
|
19
|
+
const urlMonitor = (0, urlChangeMonitor_1.monitorUrlChanges)();
|
|
20
|
+
const interactionMonitor = (0, interactionMonitor_1.monitorInteractions)(['pointerdown', 'keydown']);
|
|
21
|
+
const activityWindowTracker = new activityWindowTracker_1.ActivityWindowTracker(new faro_core_1.Observable().merge(httpMonitor, domMutationsMonitor, urlMonitor), {
|
|
39
22
|
inactivityMs: 100,
|
|
40
23
|
drainTimeoutMs: 10 * 1000,
|
|
41
|
-
isOperationStart:
|
|
42
|
-
isOperationEnd:
|
|
24
|
+
isOperationStart: (msg) => ((0, activityWindowTracker_1.isRequestStartMessage)(msg) ? msg.request.requestId : undefined),
|
|
25
|
+
isOperationEnd: (msg) => ((0, activityWindowTracker_1.isRequestEndMessage)(msg) ? msg.request.requestId : undefined),
|
|
43
26
|
});
|
|
44
27
|
activityWindowTracker
|
|
45
|
-
.filter(
|
|
28
|
+
.filter((msg) => {
|
|
46
29
|
return msg.message === 'tracking-ended';
|
|
47
30
|
})
|
|
48
|
-
.subscribe(
|
|
31
|
+
.subscribe((msg) => {
|
|
49
32
|
var _a, _b, _c;
|
|
50
|
-
if (((_a = msg.events) === null || _a === void 0 ? void 0 : _a.some(
|
|
51
|
-
((_b = msg.events) === null || _b === void 0 ? void 0 : _b.some(
|
|
52
|
-
|
|
33
|
+
if (((_a = msg.events) === null || _a === void 0 ? void 0 : _a.some((e) => e.type === 'url-change')) &&
|
|
34
|
+
((_b = msg.events) === null || _b === void 0 ? void 0 : _b.some((e) => e.type === 'dom-mutation'))) {
|
|
35
|
+
const urlChange = (_c = msg.events) === null || _c === void 0 ? void 0 : _c.find((e) => e.type === 'url-change');
|
|
53
36
|
faro_core_1.faro.api.pushEvent('faro.navigation', {
|
|
54
37
|
fromUrl: urlChange === null || urlChange === void 0 ? void 0 : urlChange.from,
|
|
55
38
|
toUrl: urlChange === null || urlChange === void 0 ? void 0 : urlChange.to,
|
|
@@ -58,11 +41,10 @@ var NavigationInstrumentation = /** @class */ (function (_super) {
|
|
|
58
41
|
});
|
|
59
42
|
}
|
|
60
43
|
});
|
|
61
|
-
interactionMonitor.subscribe(
|
|
44
|
+
interactionMonitor.subscribe(() => {
|
|
62
45
|
activityWindowTracker.startTracking();
|
|
63
46
|
});
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
}(faro_core_1.BaseInstrumentation));
|
|
47
|
+
}
|
|
48
|
+
}
|
|
67
49
|
exports.NavigationInstrumentation = NavigationInstrumentation;
|
|
68
50
|
//# sourceMappingURL=instrumentation.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instrumentation.js","sourceRoot":"","sources":["../../../../src/instrumentations/navigation/instrumentation.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"instrumentation.js","sourceRoot":"","sources":["../../../../src/instrumentations/navigation/instrumentation.ts"],"names":[],"mappings":";;;AAAA,kDAAoF;AAEpF,8EAAuH;AACvH,iFAA+E;AAC/E,iFAA+E;AAC/E,iFAA+E;AAC/E,6EAA2E;AAE3E,MAAa,yBAA0B,SAAQ,+BAAmB;IAAlE;;QACW,SAAI,GAAG,kDAAkD,CAAC;QAC1D,YAAO,GAAG,mBAAO,CAAC;IAyC7B,CAAC;IAvCU,UAAU;QACjB,MAAM,WAAW,GAAG,IAAA,wCAAmB,GAAE,CAAC;QAC1C,MAAM,mBAAmB,GAAG,IAAA,wCAAmB,GAAE,CAAC;QAClD,MAAM,UAAU,GAAG,IAAA,oCAAiB,GAAE,CAAC;QACvC,MAAM,kBAAkB,GAAG,IAAA,wCAAmB,EAAC,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC,CAAC;QAE3E,MAAM,qBAAqB,GAAG,IAAI,6CAAqB,CACrD,IAAI,sBAAU,EAAE,CAAC,KAAK,CAAC,WAAW,EAAE,mBAAmB,EAAE,UAAU,CAAC,EACpE;YACE,YAAY,EAAE,GAAG;YACjB,cAAc,EAAE,EAAE,GAAG,IAAI;YACzB,gBAAgB,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,IAAA,6CAAqB,EAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;YAC3F,cAAc,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,IAAA,2CAAmB,EAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;SACxF,CACF,CAAC;QAEF,qBAAqB;aAClB,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE;YACd,OAAO,GAAG,CAAC,OAAO,KAAK,gBAAgB,CAAC;QAC1C,CAAC,CAAC;aACD,SAAS,CAAC,CAAC,GAAG,EAAE,EAAE;;YACjB,IACE,CAAA,MAAA,GAAG,CAAC,MAAM,0CAAE,IAAI,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,YAAY,CAAC;iBACrD,MAAA,GAAG,CAAC,MAAM,0CAAE,IAAI,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,cAAc,CAAC,CAAA,EACvD,CAAC;gBACD,MAAM,SAAS,GAAG,MAAA,GAAG,CAAC,MAAM,0CAAE,IAAI,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,YAAY,CAAC,CAAC;gBACxE,gBAAI,CAAC,GAAG,CAAC,SAAS,CAAC,iBAAiB,EAAE;oBACpC,OAAO,EAAE,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,IAAI;oBACxB,KAAK,EAAE,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,EAAE;oBACpB,YAAY,EAAE,MAAM,CAAC,IAAI,CAAC;oBAC1B,QAAQ,EAAE,GAAG,CAAC,QAAQ;iBACvB,CAAC,CAAC;YACL,CAAC;QACH,CAAC,CAAC,CAAC;QAEL,kBAAkB,CAAC,SAAS,CAAC,GAAG,EAAE;YAChC,qBAAqB,CAAC,aAAa,EAAE,CAAC;QACxC,CAAC,CAAC,CAAC;IACL,CAAC;CACF;AA3CD,8DA2CC","sourcesContent":["import { BaseInstrumentation, faro, Observable, VERSION } from '@grafana/faro-core';\n\nimport { ActivityWindowTracker, isRequestEndMessage, isRequestStartMessage } from '../_internal/activityWindowTracker';\nimport { monitorDomMutations } from '../_internal/monitors/domMutationMonitor';\nimport { monitorHttpRequests } from '../_internal/monitors/httpRequestMonitor';\nimport { monitorInteractions } from '../_internal/monitors/interactionMonitor';\nimport { monitorUrlChanges } from '../_internal/monitors/urlChangeMonitor';\n\nexport class NavigationInstrumentation extends BaseInstrumentation {\n readonly name = '@grafana/faro-web-sdk:instrumentation-navigation';\n readonly version = VERSION;\n\n override initialize(): void {\n const httpMonitor = monitorHttpRequests();\n const domMutationsMonitor = monitorDomMutations();\n const urlMonitor = monitorUrlChanges();\n const interactionMonitor = monitorInteractions(['pointerdown', 'keydown']);\n\n const activityWindowTracker = new ActivityWindowTracker(\n new Observable().merge(httpMonitor, domMutationsMonitor, urlMonitor),\n {\n inactivityMs: 100,\n drainTimeoutMs: 10 * 1000,\n isOperationStart: (msg) => (isRequestStartMessage(msg) ? msg.request.requestId : undefined),\n isOperationEnd: (msg) => (isRequestEndMessage(msg) ? msg.request.requestId : undefined),\n }\n );\n\n activityWindowTracker\n .filter((msg) => {\n return msg.message === 'tracking-ended';\n })\n .subscribe((msg) => {\n if (\n msg.events?.some((e: any) => e.type === 'url-change') &&\n msg.events?.some((e: any) => e.type === 'dom-mutation')\n ) {\n const urlChange = msg.events?.find((e: any) => e.type === 'url-change');\n faro.api.pushEvent('faro.navigation', {\n fromUrl: urlChange?.from,\n toUrl: urlChange?.to,\n sameDocument: String(true),\n duration: msg.duration,\n });\n }\n });\n\n interactionMonitor.subscribe(() => {\n activityWindowTracker.startTracking();\n });\n }\n}\n"]}
|
|
@@ -1,19 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __extends = (this && this.__extends) || (function () {
|
|
3
|
-
var extendStatics = function (d, b) {
|
|
4
|
-
extendStatics = Object.setPrototypeOf ||
|
|
5
|
-
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
6
|
-
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
|
7
|
-
return extendStatics(d, b);
|
|
8
|
-
};
|
|
9
|
-
return function (d, b) {
|
|
10
|
-
if (typeof b !== "function" && b !== null)
|
|
11
|
-
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
|
12
|
-
extendStatics(d, b);
|
|
13
|
-
function __() { this.constructor = d; }
|
|
14
|
-
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
15
|
-
};
|
|
16
|
-
})();
|
|
17
2
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
18
3
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
19
4
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
@@ -23,72 +8,32 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
23
8
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
24
9
|
});
|
|
25
10
|
};
|
|
26
|
-
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
27
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
28
|
-
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
29
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
30
|
-
function step(op) {
|
|
31
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
32
|
-
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
33
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
34
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
35
|
-
switch (op[0]) {
|
|
36
|
-
case 0: case 1: t = op; break;
|
|
37
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
38
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
39
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
40
|
-
default:
|
|
41
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
42
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
43
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
44
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
45
|
-
if (t[2]) _.ops.pop();
|
|
46
|
-
_.trys.pop(); continue;
|
|
47
|
-
}
|
|
48
|
-
op = body.call(thisArg, _);
|
|
49
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
50
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
51
|
-
}
|
|
52
|
-
};
|
|
53
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
54
12
|
exports.PerformanceInstrumentation = exports.performanceEntriesSubscription = void 0;
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
13
|
+
const faro_core_1 = require("@grafana/faro-core");
|
|
14
|
+
const navigation_1 = require("./navigation");
|
|
15
|
+
const performanceUtils_1 = require("./performanceUtils");
|
|
16
|
+
const resource_1 = require("./resource");
|
|
59
17
|
exports.performanceEntriesSubscription = new faro_core_1.Observable();
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
_this.version = faro_core_1.VERSION;
|
|
66
|
-
return _this;
|
|
18
|
+
class PerformanceInstrumentation extends faro_core_1.BaseInstrumentation {
|
|
19
|
+
constructor() {
|
|
20
|
+
super(...arguments);
|
|
21
|
+
this.name = '@grafana/faro-web-sdk:instrumentation-performance';
|
|
22
|
+
this.version = faro_core_1.VERSION;
|
|
67
23
|
}
|
|
68
|
-
|
|
69
|
-
var _this = this;
|
|
24
|
+
initialize() {
|
|
70
25
|
if (!(0, performanceUtils_1.performanceObserverSupported)()) {
|
|
71
26
|
this.logDebug('performance observer not supported. Disable performance instrumentation.');
|
|
72
27
|
return;
|
|
73
28
|
}
|
|
74
|
-
(0, performanceUtils_1.onDocumentReady)(
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
if (faroNavigationId != null) {
|
|
84
|
-
(0, resource_1.observeResourceTimings)(faroNavigationId, pushEvent, exports.performanceEntriesSubscription);
|
|
85
|
-
}
|
|
86
|
-
return [2 /*return*/];
|
|
87
|
-
}
|
|
88
|
-
});
|
|
89
|
-
}); });
|
|
90
|
-
};
|
|
91
|
-
return PerformanceInstrumentation;
|
|
92
|
-
}(faro_core_1.BaseInstrumentation));
|
|
29
|
+
(0, performanceUtils_1.onDocumentReady)(() => __awaiter(this, void 0, void 0, function* () {
|
|
30
|
+
const pushEvent = this.api.pushEvent;
|
|
31
|
+
const { faroNavigationId } = yield (0, navigation_1.getNavigationTimings)(pushEvent);
|
|
32
|
+
if (faroNavigationId != null) {
|
|
33
|
+
(0, resource_1.observeResourceTimings)(faroNavigationId, pushEvent, exports.performanceEntriesSubscription);
|
|
34
|
+
}
|
|
35
|
+
}));
|
|
36
|
+
}
|
|
37
|
+
}
|
|
93
38
|
exports.PerformanceInstrumentation = PerformanceInstrumentation;
|
|
94
39
|
//# sourceMappingURL=instrumentation.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instrumentation.js","sourceRoot":"","sources":["../../../../src/instrumentations/performance/instrumentation.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"instrumentation.js","sourceRoot":"","sources":["../../../../src/instrumentations/performance/instrumentation.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,kDAA8E;AAE9E,6CAAoD;AACpD,yDAAmF;AACnF,yCAAoD;AAGvC,QAAA,8BAA8B,GAAG,IAAI,sBAAU,EAAwB,CAAC;AAErF,MAAa,0BAA2B,SAAQ,+BAAmB;IAAnE;;QACW,SAAI,GAAG,mDAAmD,CAAC;QAC3D,YAAO,GAAG,mBAAO,CAAC;IAkB7B,CAAC;IAhBC,UAAU;QACR,IAAI,CAAC,IAAA,+CAA4B,GAAE,EAAE,CAAC;YACpC,IAAI,CAAC,QAAQ,CAAC,0EAA0E,CAAC,CAAC;YAC1F,OAAO;QACT,CAAC;QAED,IAAA,kCAAe,EAAC,GAAS,EAAE;YACzB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC;YAErC,MAAM,EAAE,gBAAgB,EAAE,GAAG,MAAM,IAAA,iCAAoB,EAAC,SAAS,CAAC,CAAC;YAEnE,IAAI,gBAAgB,IAAI,IAAI,EAAE,CAAC;gBAC7B,IAAA,iCAAsB,EAAC,gBAAgB,EAAE,SAAS,EAAE,sCAA8B,CAAC,CAAC;YACtF,CAAC;QACH,CAAC,CAAA,CAAC,CAAC;IACL,CAAC;CACF;AApBD,gEAoBC","sourcesContent":["import { BaseInstrumentation, Observable, VERSION } from '@grafana/faro-core';\n\nimport { getNavigationTimings } from './navigation';\nimport { onDocumentReady, performanceObserverSupported } from './performanceUtils';\nimport { observeResourceTimings } from './resource';\nimport type { ResourceEntryMessage } from './types';\n\nexport const performanceEntriesSubscription = new Observable<ResourceEntryMessage>();\n\nexport class PerformanceInstrumentation extends BaseInstrumentation {\n readonly name = '@grafana/faro-web-sdk:instrumentation-performance';\n readonly version = VERSION;\n\n initialize() {\n if (!performanceObserverSupported()) {\n this.logDebug('performance observer not supported. Disable performance instrumentation.');\n return;\n }\n\n onDocumentReady(async () => {\n const pushEvent = this.api.pushEvent;\n\n const { faroNavigationId } = await getNavigationTimings(pushEvent);\n\n if (faroNavigationId != null) {\n observeResourceTimings(faroNavigationId, pushEvent, performanceEntriesSubscription);\n }\n });\n }\n}\n"]}
|
|
@@ -1,41 +1,30 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __assign = (this && this.__assign) || function () {
|
|
3
|
-
__assign = Object.assign || function(t) {
|
|
4
|
-
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
5
|
-
s = arguments[i];
|
|
6
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
7
|
-
t[p] = s[p];
|
|
8
|
-
}
|
|
9
|
-
return t;
|
|
10
|
-
};
|
|
11
|
-
return __assign.apply(this, arguments);
|
|
12
|
-
};
|
|
13
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
3
|
exports.getNavigationTimings = getNavigationTimings;
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
4
|
+
const faro_core_1 = require("@grafana/faro-core");
|
|
5
|
+
const utils_1 = require("../../utils");
|
|
6
|
+
const url_1 = require("../../utils/url");
|
|
7
|
+
const instrumentationConstants_1 = require("../instrumentationConstants");
|
|
8
|
+
const performanceConstants_1 = require("./performanceConstants");
|
|
9
|
+
const performanceUtils_1 = require("./performanceUtils");
|
|
21
10
|
function getNavigationTimings(pushEvent) {
|
|
22
|
-
|
|
23
|
-
|
|
11
|
+
let faroNavigationEntryResolve;
|
|
12
|
+
const faroNavigationEntryPromise = new Promise((resolve) => {
|
|
24
13
|
faroNavigationEntryResolve = resolve;
|
|
25
14
|
});
|
|
26
|
-
|
|
15
|
+
const observer = new PerformanceObserver((observedEntries) => {
|
|
27
16
|
var _a;
|
|
28
|
-
|
|
17
|
+
const [navigationEntryRaw] = observedEntries.getEntries();
|
|
29
18
|
if (navigationEntryRaw == null || (0, url_1.isUrlIgnored)(navigationEntryRaw.name)) {
|
|
30
19
|
return;
|
|
31
20
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
21
|
+
const navEntryJson = navigationEntryRaw.toJSON();
|
|
22
|
+
let spanContext = (0, performanceUtils_1.getSpanContextFromServerTiming)(navEntryJson === null || navEntryJson === void 0 ? void 0 : navEntryJson.serverTiming);
|
|
23
|
+
const faroPreviousNavigationId = (_a = (0, utils_1.getItem)(instrumentationConstants_1.NAVIGATION_ID_STORAGE_KEY, utils_1.webStorageType.session)) !== null && _a !== void 0 ? _a : faro_core_1.unknownString;
|
|
24
|
+
const faroNavigationEntry = Object.assign(Object.assign({}, (0, performanceUtils_1.createFaroNavigationTiming)(navEntryJson)), { faroNavigationId: (0, faro_core_1.genShortID)(), faroPreviousNavigationId });
|
|
36
25
|
(0, utils_1.setItem)(instrumentationConstants_1.NAVIGATION_ID_STORAGE_KEY, faroNavigationEntry.faroNavigationId, utils_1.webStorageType.session);
|
|
37
26
|
pushEvent('faro.performance.navigation', faroNavigationEntry, undefined, {
|
|
38
|
-
spanContext
|
|
27
|
+
spanContext,
|
|
39
28
|
timestampOverwriteMs: performance.timeOrigin + navEntryJson.startTime,
|
|
40
29
|
});
|
|
41
30
|
faroNavigationEntryResolve(faroNavigationEntry);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"navigation.js","sourceRoot":"","sources":["../../../../src/instrumentations/performance/navigation.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"navigation.js","sourceRoot":"","sources":["../../../../src/instrumentations/performance/navigation.ts"],"names":[],"mappings":";;AAaA,oDAyCC;AAtDD,kDAA+D;AAG/D,uCAA+D;AAC/D,yCAA+C;AAC/C,0EAAwE;AAExE,iEAA0D;AAC1D,yDAAgG;AAKhG,SAAgB,oBAAoB,CAAC,SAAiC;IACpE,IAAI,0BAA+D,CAAC;IACpE,MAAM,0BAA0B,GAAG,IAAI,OAAO,CAAqB,CAAC,OAAO,EAAE,EAAE;QAC7E,0BAA0B,GAAG,OAAO,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,MAAM,QAAQ,GAAG,IAAI,mBAAmB,CAAC,CAAC,eAAe,EAAE,EAAE;;QAC3D,MAAM,CAAC,kBAAkB,CAAC,GAAG,eAAe,CAAC,UAAU,EAAE,CAAC;QAE1D,IAAI,kBAAkB,IAAI,IAAI,IAAI,IAAA,kBAAY,EAAC,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC;YACxE,OAAO;QACT,CAAC;QAED,MAAM,YAAY,GAAG,kBAAkB,CAAC,MAAM,EAAE,CAAC;QAEjD,IAAI,WAAW,GAAgB,IAAA,iDAA8B,EAAC,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAE,YAAY,CAAC,CAAC;QAE1F,MAAM,wBAAwB,GAAG,MAAA,IAAA,eAAO,EAAC,oDAAyB,EAAE,sBAAc,CAAC,OAAO,CAAC,mCAAI,yBAAa,CAAC;QAE7G,MAAM,mBAAmB,mCACpB,IAAA,6CAA0B,EAAC,YAAY,CAAC,KAC3C,gBAAgB,EAAE,IAAA,sBAAU,GAAE,EAC9B,wBAAwB,GACzB,CAAC;QAEF,IAAA,eAAO,EAAC,oDAAyB,EAAE,mBAAmB,CAAC,gBAAgB,EAAE,sBAAc,CAAC,OAAO,CAAC,CAAC;QAEjG,SAAS,CAAC,6BAA6B,EAAE,mBAAmB,EAAE,SAAS,EAAE;YACvE,WAAW;YACX,oBAAoB,EAAE,WAAW,CAAC,UAAU,GAAG,YAAY,CAAC,SAAS;SACtE,CAAC,CAAC;QAEH,0BAA0B,CAAC,mBAAmB,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,OAAO,CAAC;QACf,IAAI,EAAE,uCAAgB;QACtB,QAAQ,EAAE,IAAI;KACf,CAAC,CAAC;IAEH,OAAO,0BAA0B,CAAC;AACpC,CAAC","sourcesContent":["import { genShortID, unknownString } from '@grafana/faro-core';\nimport type { EventsAPI, PushEventOptions } from '@grafana/faro-core';\n\nimport { getItem, setItem, webStorageType } from '../../utils';\nimport { isUrlIgnored } from '../../utils/url';\nimport { NAVIGATION_ID_STORAGE_KEY } from '../instrumentationConstants';\n\nimport { NAVIGATION_ENTRY } from './performanceConstants';\nimport { createFaroNavigationTiming, getSpanContextFromServerTiming } from './performanceUtils';\nimport type { FaroNavigationItem } from './types';\n\ntype SpanContext = PushEventOptions['spanContext'];\n\nexport function getNavigationTimings(pushEvent: EventsAPI['pushEvent']): Promise<FaroNavigationItem> {\n let faroNavigationEntryResolve: (value: FaroNavigationItem) => void;\n const faroNavigationEntryPromise = new Promise<FaroNavigationItem>((resolve) => {\n faroNavigationEntryResolve = resolve;\n });\n\n const observer = new PerformanceObserver((observedEntries) => {\n const [navigationEntryRaw] = observedEntries.getEntries();\n\n if (navigationEntryRaw == null || isUrlIgnored(navigationEntryRaw.name)) {\n return;\n }\n\n const navEntryJson = navigationEntryRaw.toJSON();\n\n let spanContext: SpanContext = getSpanContextFromServerTiming(navEntryJson?.serverTiming);\n\n const faroPreviousNavigationId = getItem(NAVIGATION_ID_STORAGE_KEY, webStorageType.session) ?? unknownString;\n\n const faroNavigationEntry: FaroNavigationItem = {\n ...createFaroNavigationTiming(navEntryJson),\n faroNavigationId: genShortID(),\n faroPreviousNavigationId,\n };\n\n setItem(NAVIGATION_ID_STORAGE_KEY, faroNavigationEntry.faroNavigationId, webStorageType.session);\n\n pushEvent('faro.performance.navigation', faroNavigationEntry, undefined, {\n spanContext,\n timestampOverwriteMs: performance.timeOrigin + navEntryJson.startTime,\n });\n\n faroNavigationEntryResolve(faroNavigationEntry);\n });\n\n observer.observe({\n type: NAVIGATION_ENTRY,\n buffered: true,\n });\n\n return faroNavigationEntryPromise;\n}\n"]}
|
|
@@ -1,15 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __assign = (this && this.__assign) || function () {
|
|
3
|
-
__assign = Object.assign || function(t) {
|
|
4
|
-
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
5
|
-
s = arguments[i];
|
|
6
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
7
|
-
t[p] = s[p];
|
|
8
|
-
}
|
|
9
|
-
return t;
|
|
10
|
-
};
|
|
11
|
-
return __assign.apply(this, arguments);
|
|
12
|
-
};
|
|
13
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
3
|
exports.getSpanContextFromServerTiming = getSpanContextFromServerTiming;
|
|
15
4
|
exports.performanceObserverSupported = performanceObserverSupported;
|
|
@@ -17,20 +6,18 @@ exports.onDocumentReady = onDocumentReady;
|
|
|
17
6
|
exports.includePerformanceEntry = includePerformanceEntry;
|
|
18
7
|
exports.createFaroResourceTiming = createFaroResourceTiming;
|
|
19
8
|
exports.createFaroNavigationTiming = createFaroNavigationTiming;
|
|
20
|
-
|
|
21
|
-
|
|
9
|
+
const faro_core_1 = require("@grafana/faro-core");
|
|
10
|
+
const w3cTraceparentFormat = /^00-[a-f0-9]{32}-[a-f0-9]{16}-[0-9]{1,2}$/;
|
|
22
11
|
// Extract traceparent from serverTiming, if present
|
|
23
|
-
function getSpanContextFromServerTiming(serverTimings) {
|
|
24
|
-
|
|
25
|
-
for (var _i = 0, serverTimings_1 = serverTimings; _i < serverTimings_1.length; _i++) {
|
|
26
|
-
var serverEntry = serverTimings_1[_i];
|
|
12
|
+
function getSpanContextFromServerTiming(serverTimings = []) {
|
|
13
|
+
for (const serverEntry of serverTimings) {
|
|
27
14
|
if (serverEntry.name === 'traceparent') {
|
|
28
15
|
if (!w3cTraceparentFormat.test(serverEntry.description)) {
|
|
29
16
|
continue;
|
|
30
17
|
}
|
|
31
|
-
|
|
18
|
+
const [, traceId, spanId] = serverEntry.description.split('-');
|
|
32
19
|
if (traceId != null && spanId != null) {
|
|
33
|
-
return { traceId
|
|
20
|
+
return { traceId, spanId };
|
|
34
21
|
}
|
|
35
22
|
break;
|
|
36
23
|
}
|
|
@@ -45,20 +32,18 @@ function onDocumentReady(handleReady) {
|
|
|
45
32
|
handleReady();
|
|
46
33
|
}
|
|
47
34
|
else {
|
|
48
|
-
|
|
35
|
+
const readyStateCompleteHandler = () => {
|
|
49
36
|
if (document.readyState === 'complete') {
|
|
50
37
|
handleReady();
|
|
51
|
-
document.removeEventListener('readystatechange',
|
|
38
|
+
document.removeEventListener('readystatechange', readyStateCompleteHandler);
|
|
52
39
|
}
|
|
53
40
|
};
|
|
54
|
-
document.addEventListener('readystatechange',
|
|
41
|
+
document.addEventListener('readystatechange', readyStateCompleteHandler);
|
|
55
42
|
}
|
|
56
43
|
}
|
|
57
|
-
function includePerformanceEntry(performanceEntryJSON, allowProps) {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
var _b = _a[_i], allowPropKey = _b[0], allowPropValue = _b[1];
|
|
61
|
-
var perfEntryPropVal = performanceEntryJSON[allowPropKey];
|
|
44
|
+
function includePerformanceEntry(performanceEntryJSON, allowProps = {}) {
|
|
45
|
+
for (const [allowPropKey, allowPropValue] of Object.entries(allowProps)) {
|
|
46
|
+
const perfEntryPropVal = performanceEntryJSON[allowPropKey];
|
|
62
47
|
if (perfEntryPropVal == null) {
|
|
63
48
|
return false;
|
|
64
49
|
}
|
|
@@ -71,9 +56,9 @@ function includePerformanceEntry(performanceEntryJSON, allowProps) {
|
|
|
71
56
|
return true;
|
|
72
57
|
}
|
|
73
58
|
function createFaroResourceTiming(resourceEntryRaw) {
|
|
74
|
-
|
|
59
|
+
const { connectEnd, connectStart, decodedBodySize, domainLookupEnd, domainLookupStart, duration, encodedBodySize, fetchStart, initiatorType, name, nextHopProtocol, redirectEnd, redirectStart,
|
|
75
60
|
// @ts-expect-error the renderBlockingStatus property is not available in all browsers
|
|
76
|
-
rbs
|
|
61
|
+
renderBlockingStatus: rbs, requestStart, responseEnd, responseStart, responseStatus, secureConnectionStart, transferSize, workerStart, } = resourceEntryRaw;
|
|
77
62
|
return {
|
|
78
63
|
name: name,
|
|
79
64
|
duration: toFaroPerformanceTimingString(duration),
|
|
@@ -99,7 +84,7 @@ function createFaroResourceTiming(resourceEntryRaw) {
|
|
|
99
84
|
// serverTiming: resourceEntryRaw.serverTiming,
|
|
100
85
|
};
|
|
101
86
|
function getCacheType() {
|
|
102
|
-
|
|
87
|
+
let cacheType = 'fullLoad';
|
|
103
88
|
if (transferSize === 0) {
|
|
104
89
|
if (decodedBodySize > 0) {
|
|
105
90
|
cacheType = 'cache';
|
|
@@ -119,9 +104,9 @@ function createFaroResourceTiming(resourceEntryRaw) {
|
|
|
119
104
|
}
|
|
120
105
|
}
|
|
121
106
|
function createFaroNavigationTiming(navigationEntryRaw) {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
return
|
|
107
|
+
const { activationStart, domComplete, domContentLoadedEventEnd, domContentLoadedEventStart, domInteractive, fetchStart, loadEventEnd, loadEventStart, responseStart, type, } = navigationEntryRaw;
|
|
108
|
+
const parserStart = getDocumentParsingTime();
|
|
109
|
+
return Object.assign(Object.assign({}, createFaroResourceTiming(navigationEntryRaw)), { pageLoadTime: toFaroPerformanceTimingString(domComplete - fetchStart), documentParsingTime: toFaroPerformanceTimingString(parserStart ? domInteractive - parserStart : null), domProcessingTime: toFaroPerformanceTimingString(domComplete - domInteractive), domContentLoadHandlerTime: toFaroPerformanceTimingString(domContentLoadedEventEnd - domContentLoadedEventStart), onLoadTime: toFaroPerformanceTimingString(loadEventEnd - loadEventStart),
|
|
125
110
|
// For navigation entries we can calculate the TTFB based on activationStart. We overwrite the TTFB value coming with the resource entry.
|
|
126
111
|
// For more accuracy on prerendered pages page we calculate relative top the activationStart instead of the start of the navigation.
|
|
127
112
|
// clamp to 0 if activationStart occurs after first byte is received.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"performanceUtils.js","sourceRoot":"","sources":["../../../../src/instrumentations/performance/performanceUtils.ts"],"names":[],"mappings":"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","sourcesContent":["import { isArray, type PushEventOptions, unknownString } from '@grafana/faro-core';\n\nimport type { CacheType, FaroNavigationTiming, FaroResourceTiming } from './types';\n\nconst w3cTraceparentFormat = /^00-[a-f0-9]{32}-[a-f0-9]{16}-[0-9]{1,2}$/;\n\ntype SpanContext = PushEventOptions['spanContext'];\n\n// Extract traceparent from serverTiming, if present\nexport function getSpanContextFromServerTiming(serverTimings: PerformanceServerTiming[] = []): SpanContext | undefined {\n for (const serverEntry of serverTimings) {\n if (serverEntry.name === 'traceparent') {\n if (!w3cTraceparentFormat.test(serverEntry.description)) {\n continue;\n }\n\n const [, traceId, spanId] = serverEntry.description.split('-');\n if (traceId != null && spanId != null) {\n return { traceId, spanId };\n }\n\n break;\n }\n }\n\n return undefined;\n}\n\nexport function performanceObserverSupported(): boolean {\n return 'PerformanceObserver' in window;\n}\n\nexport function onDocumentReady(handleReady: () => void) {\n if (document.readyState === 'complete') {\n handleReady();\n } else {\n const readyStateCompleteHandler = () => {\n if (document.readyState === 'complete') {\n handleReady();\n document.removeEventListener('readystatechange', readyStateCompleteHandler);\n }\n };\n\n document.addEventListener('readystatechange', readyStateCompleteHandler);\n }\n}\n\ntype PerformanceEntryAllowProperties = Record<string, Array<string | number> | string | number>;\n\nexport function includePerformanceEntry(\n performanceEntryJSON: Record<string, any>,\n allowProps: PerformanceEntryAllowProperties = {}\n): boolean {\n for (const [allowPropKey, allowPropValue] of Object.entries(allowProps)) {\n const perfEntryPropVal = performanceEntryJSON[allowPropKey];\n\n if (perfEntryPropVal == null) {\n return false;\n }\n\n if (isArray(allowPropValue)) {\n return allowPropValue.includes(perfEntryPropVal);\n }\n\n return perfEntryPropVal === allowPropValue;\n }\n\n // empty object allows all\n return true;\n}\n\nexport function createFaroResourceTiming(resourceEntryRaw: PerformanceResourceTiming): FaroResourceTiming {\n const {\n connectEnd,\n connectStart,\n decodedBodySize,\n domainLookupEnd,\n domainLookupStart,\n duration,\n encodedBodySize,\n fetchStart,\n initiatorType,\n name,\n nextHopProtocol,\n redirectEnd,\n redirectStart,\n // @ts-expect-error the renderBlockingStatus property is not available in all browsers\n renderBlockingStatus: rbs,\n requestStart,\n responseEnd,\n responseStart,\n responseStatus,\n secureConnectionStart,\n transferSize,\n workerStart,\n } = resourceEntryRaw;\n\n return {\n name: name,\n duration: toFaroPerformanceTimingString(duration),\n tcpHandshakeTime: toFaroPerformanceTimingString(connectEnd - connectStart),\n dnsLookupTime: toFaroPerformanceTimingString(domainLookupEnd - domainLookupStart),\n tlsNegotiationTime: toFaroPerformanceTimingString(connectEnd - secureConnectionStart),\n responseStatus: toFaroPerformanceTimingString(responseStatus),\n redirectTime: toFaroPerformanceTimingString(redirectEnd - redirectStart),\n requestTime: toFaroPerformanceTimingString(responseStart - requestStart),\n responseTime: toFaroPerformanceTimingString(responseEnd - responseStart),\n fetchTime: toFaroPerformanceTimingString(responseEnd - fetchStart),\n serviceWorkerTime: toFaroPerformanceTimingString(fetchStart - workerStart),\n decodedBodySize: toFaroPerformanceTimingString(decodedBodySize),\n encodedBodySize: toFaroPerformanceTimingString(encodedBodySize),\n cacheHitStatus: getCacheType(),\n renderBlockingStatus: toFaroPerformanceTimingString(rbs) as FaroResourceTiming['renderBlockingStatus'],\n protocol: nextHopProtocol,\n initiatorType: initiatorType,\n visibilityState: document.visibilityState,\n ttfb: toFaroPerformanceTimingString(responseStart - requestStart),\n transferSize: toFaroPerformanceTimingString(transferSize),\n\n // TODO: add in future iteration, ideally after nested objects are supported by the collector.\n // serverTiming: resourceEntryRaw.serverTiming,\n };\n\n function getCacheType(): CacheType {\n let cacheType: CacheType = 'fullLoad';\n if (transferSize === 0) {\n if (decodedBodySize > 0) {\n cacheType = 'cache';\n }\n } else {\n if (responseStatus != null) {\n if (responseStatus === 304) {\n cacheType = 'conditionalFetch';\n }\n } else if (encodedBodySize > 0 && transferSize < encodedBodySize) {\n cacheType = 'conditionalFetch';\n }\n }\n return cacheType;\n }\n}\n\nexport function createFaroNavigationTiming(navigationEntryRaw: PerformanceNavigationTiming): FaroNavigationTiming {\n const {\n activationStart,\n domComplete,\n domContentLoadedEventEnd,\n domContentLoadedEventStart,\n domInteractive,\n fetchStart,\n loadEventEnd,\n loadEventStart,\n responseStart,\n type,\n } = navigationEntryRaw;\n\n const parserStart = getDocumentParsingTime();\n\n return {\n ...createFaroResourceTiming(navigationEntryRaw),\n pageLoadTime: toFaroPerformanceTimingString(domComplete - fetchStart),\n documentParsingTime: toFaroPerformanceTimingString(parserStart ? domInteractive - parserStart : null),\n domProcessingTime: toFaroPerformanceTimingString(domComplete - domInteractive),\n domContentLoadHandlerTime: toFaroPerformanceTimingString(domContentLoadedEventEnd - domContentLoadedEventStart),\n onLoadTime: toFaroPerformanceTimingString(loadEventEnd - loadEventStart),\n\n // For navigation entries we can calculate the TTFB based on activationStart. We overwrite the TTFB value coming with the resource entry.\n // For more accuracy on prerendered pages page we calculate relative top the activationStart instead of the start of the navigation.\n // clamp to 0 if activationStart occurs after first byte is received.\n ttfb: toFaroPerformanceTimingString(Math.max(responseStart - (activationStart ?? 0), 0)),\n type: type,\n };\n}\n\nfunction getDocumentParsingTime(): number | null {\n if (performance.timing?.domLoading != null) {\n // the browser is about to start parsing the first received bytes of the HTML document.\n // This property is deprecated but there isn't a really good alternative atm.\n // For now we stick with domLoading and keep researching a better alternative.\n return performance.timing.domLoading - performance.timeOrigin;\n }\n\n return null;\n}\n\nfunction toFaroPerformanceTimingString(v: unknown): string {\n if (v == null) {\n return unknownString;\n }\n\n if (typeof v === 'number') {\n return Math.round(v > 0 ? v : 0).toString();\n }\n\n return v.toString();\n}\n"]}
|
|
1
|
+
{"version":3,"file":"performanceUtils.js","sourceRoot":"","sources":["../../../../src/instrumentations/performance/performanceUtils.ts"],"names":[],"mappings":"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","sourcesContent":["import { isArray, type PushEventOptions, unknownString } from '@grafana/faro-core';\n\nimport type { CacheType, FaroNavigationTiming, FaroResourceTiming } from './types';\n\nconst w3cTraceparentFormat = /^00-[a-f0-9]{32}-[a-f0-9]{16}-[0-9]{1,2}$/;\n\ntype SpanContext = PushEventOptions['spanContext'];\n\n// Extract traceparent from serverTiming, if present\nexport function getSpanContextFromServerTiming(serverTimings: PerformanceServerTiming[] = []): SpanContext | undefined {\n for (const serverEntry of serverTimings) {\n if (serverEntry.name === 'traceparent') {\n if (!w3cTraceparentFormat.test(serverEntry.description)) {\n continue;\n }\n\n const [, traceId, spanId] = serverEntry.description.split('-');\n if (traceId != null && spanId != null) {\n return { traceId, spanId };\n }\n\n break;\n }\n }\n\n return undefined;\n}\n\nexport function performanceObserverSupported(): boolean {\n return 'PerformanceObserver' in window;\n}\n\nexport function onDocumentReady(handleReady: () => void) {\n if (document.readyState === 'complete') {\n handleReady();\n } else {\n const readyStateCompleteHandler = () => {\n if (document.readyState === 'complete') {\n handleReady();\n document.removeEventListener('readystatechange', readyStateCompleteHandler);\n }\n };\n\n document.addEventListener('readystatechange', readyStateCompleteHandler);\n }\n}\n\ntype PerformanceEntryAllowProperties = Record<string, Array<string | number> | string | number>;\n\nexport function includePerformanceEntry(\n performanceEntryJSON: Record<string, any>,\n allowProps: PerformanceEntryAllowProperties = {}\n): boolean {\n for (const [allowPropKey, allowPropValue] of Object.entries(allowProps)) {\n const perfEntryPropVal = performanceEntryJSON[allowPropKey];\n\n if (perfEntryPropVal == null) {\n return false;\n }\n\n if (isArray(allowPropValue)) {\n return allowPropValue.includes(perfEntryPropVal);\n }\n\n return perfEntryPropVal === allowPropValue;\n }\n\n // empty object allows all\n return true;\n}\n\nexport function createFaroResourceTiming(resourceEntryRaw: PerformanceResourceTiming): FaroResourceTiming {\n const {\n connectEnd,\n connectStart,\n decodedBodySize,\n domainLookupEnd,\n domainLookupStart,\n duration,\n encodedBodySize,\n fetchStart,\n initiatorType,\n name,\n nextHopProtocol,\n redirectEnd,\n redirectStart,\n // @ts-expect-error the renderBlockingStatus property is not available in all browsers\n renderBlockingStatus: rbs,\n requestStart,\n responseEnd,\n responseStart,\n responseStatus,\n secureConnectionStart,\n transferSize,\n workerStart,\n } = resourceEntryRaw;\n\n return {\n name: name,\n duration: toFaroPerformanceTimingString(duration),\n tcpHandshakeTime: toFaroPerformanceTimingString(connectEnd - connectStart),\n dnsLookupTime: toFaroPerformanceTimingString(domainLookupEnd - domainLookupStart),\n tlsNegotiationTime: toFaroPerformanceTimingString(connectEnd - secureConnectionStart),\n responseStatus: toFaroPerformanceTimingString(responseStatus),\n redirectTime: toFaroPerformanceTimingString(redirectEnd - redirectStart),\n requestTime: toFaroPerformanceTimingString(responseStart - requestStart),\n responseTime: toFaroPerformanceTimingString(responseEnd - responseStart),\n fetchTime: toFaroPerformanceTimingString(responseEnd - fetchStart),\n serviceWorkerTime: toFaroPerformanceTimingString(fetchStart - workerStart),\n decodedBodySize: toFaroPerformanceTimingString(decodedBodySize),\n encodedBodySize: toFaroPerformanceTimingString(encodedBodySize),\n cacheHitStatus: getCacheType(),\n renderBlockingStatus: toFaroPerformanceTimingString(rbs) as FaroResourceTiming['renderBlockingStatus'],\n protocol: nextHopProtocol,\n initiatorType: initiatorType,\n visibilityState: document.visibilityState,\n ttfb: toFaroPerformanceTimingString(responseStart - requestStart),\n transferSize: toFaroPerformanceTimingString(transferSize),\n\n // TODO: add in future iteration, ideally after nested objects are supported by the collector.\n // serverTiming: resourceEntryRaw.serverTiming,\n };\n\n function getCacheType(): CacheType {\n let cacheType: CacheType = 'fullLoad';\n if (transferSize === 0) {\n if (decodedBodySize > 0) {\n cacheType = 'cache';\n }\n } else {\n if (responseStatus != null) {\n if (responseStatus === 304) {\n cacheType = 'conditionalFetch';\n }\n } else if (encodedBodySize > 0 && transferSize < encodedBodySize) {\n cacheType = 'conditionalFetch';\n }\n }\n return cacheType;\n }\n}\n\nexport function createFaroNavigationTiming(navigationEntryRaw: PerformanceNavigationTiming): FaroNavigationTiming {\n const {\n activationStart,\n domComplete,\n domContentLoadedEventEnd,\n domContentLoadedEventStart,\n domInteractive,\n fetchStart,\n loadEventEnd,\n loadEventStart,\n responseStart,\n type,\n } = navigationEntryRaw;\n\n const parserStart = getDocumentParsingTime();\n\n return {\n ...createFaroResourceTiming(navigationEntryRaw),\n pageLoadTime: toFaroPerformanceTimingString(domComplete - fetchStart),\n documentParsingTime: toFaroPerformanceTimingString(parserStart ? domInteractive - parserStart : null),\n domProcessingTime: toFaroPerformanceTimingString(domComplete - domInteractive),\n domContentLoadHandlerTime: toFaroPerformanceTimingString(domContentLoadedEventEnd - domContentLoadedEventStart),\n onLoadTime: toFaroPerformanceTimingString(loadEventEnd - loadEventStart),\n\n // For navigation entries we can calculate the TTFB based on activationStart. We overwrite the TTFB value coming with the resource entry.\n // For more accuracy on prerendered pages page we calculate relative top the activationStart instead of the start of the navigation.\n // clamp to 0 if activationStart occurs after first byte is received.\n ttfb: toFaroPerformanceTimingString(Math.max(responseStart - (activationStart ?? 0), 0)),\n type: type,\n };\n}\n\nfunction getDocumentParsingTime(): number | null {\n if (performance.timing?.domLoading != null) {\n // the browser is about to start parsing the first received bytes of the HTML document.\n // This property is deprecated but there isn't a really good alternative atm.\n // For now we stick with domLoading and keep researching a better alternative.\n return performance.timing.domLoading - performance.timeOrigin;\n }\n\n return null;\n}\n\nfunction toFaroPerformanceTimingString(v: unknown): string {\n if (v == null) {\n return unknownString;\n }\n\n if (typeof v === 'number') {\n return Math.round(v > 0 ? v : 0).toString();\n }\n\n return v.toString();\n}\n"]}
|
|
@@ -1,41 +1,29 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __assign = (this && this.__assign) || function () {
|
|
3
|
-
__assign = Object.assign || function(t) {
|
|
4
|
-
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
5
|
-
s = arguments[i];
|
|
6
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
7
|
-
t[p] = s[p];
|
|
8
|
-
}
|
|
9
|
-
return t;
|
|
10
|
-
};
|
|
11
|
-
return __assign.apply(this, arguments);
|
|
12
|
-
};
|
|
13
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
3
|
exports.observeResourceTimings = observeResourceTimings;
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
4
|
+
const faro_core_1 = require("@grafana/faro-core");
|
|
5
|
+
const url_1 = require("../../utils/url");
|
|
6
|
+
const performanceConstants_1 = require("./performanceConstants");
|
|
7
|
+
const performanceUtils_1 = require("./performanceUtils");
|
|
8
|
+
const DEFAULT_TRACK_RESOURCES = { initiatorType: ['xmlhttprequest', 'fetch'] };
|
|
20
9
|
function observeResourceTimings(faroNavigationId, pushEvent, observable) {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
for (
|
|
25
|
-
var resourceEntryRaw = entries_1[_i];
|
|
10
|
+
const trackResources = faro_core_1.faro.config.trackResources;
|
|
11
|
+
const observer = new PerformanceObserver((observedEntries) => {
|
|
12
|
+
const entries = observedEntries.getEntries();
|
|
13
|
+
for (const resourceEntryRaw of entries) {
|
|
26
14
|
if ((0, url_1.isUrlIgnored)(resourceEntryRaw.name)) {
|
|
27
15
|
continue;
|
|
28
16
|
}
|
|
29
17
|
observable === null || observable === void 0 ? void 0 : observable.notify({
|
|
30
18
|
type: performanceConstants_1.RESOURCE_ENTRY,
|
|
31
19
|
});
|
|
32
|
-
|
|
33
|
-
|
|
20
|
+
const resourceEntryJson = resourceEntryRaw.toJSON();
|
|
21
|
+
let spanContext = (0, performanceUtils_1.getSpanContextFromServerTiming)(resourceEntryJson === null || resourceEntryJson === void 0 ? void 0 : resourceEntryJson.serverTiming);
|
|
34
22
|
if ((trackResources == null && (0, performanceUtils_1.includePerformanceEntry)(resourceEntryJson, DEFAULT_TRACK_RESOURCES)) ||
|
|
35
23
|
trackResources) {
|
|
36
|
-
|
|
24
|
+
const faroResourceEntry = Object.assign(Object.assign({}, (0, performanceUtils_1.createFaroResourceTiming)(resourceEntryJson)), { faroNavigationId, faroResourceId: (0, faro_core_1.genShortID)() });
|
|
37
25
|
pushEvent('faro.performance.resource', faroResourceEntry, undefined, {
|
|
38
|
-
spanContext
|
|
26
|
+
spanContext,
|
|
39
27
|
timestampOverwriteMs: performance.timeOrigin + resourceEntryJson.startTime,
|
|
40
28
|
});
|
|
41
29
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resource.js","sourceRoot":"","sources":["../../../../src/instrumentations/performance/resource.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"resource.js","sourceRoot":"","sources":["../../../../src/instrumentations/performance/resource.ts"],"names":[],"mappings":";;AAaA,wDA4CC;AAzDD,kDAAsD;AAGtD,yCAA+C;AAE/C,iEAAwD;AACxD,yDAAuH;AAKvH,MAAM,uBAAuB,GAAG,EAAE,aAAa,EAAE,CAAC,gBAAgB,EAAE,OAAO,CAAC,EAAE,CAAC;AAE/E,SAAgB,sBAAsB,CACpC,gBAAwB,EACxB,SAAiC,EACjC,UAA4C;IAE5C,MAAM,cAAc,GAAG,gBAAI,CAAC,MAAM,CAAC,cAAc,CAAC;IAElD,MAAM,QAAQ,GAAG,IAAI,mBAAmB,CAAC,CAAC,eAAe,EAAE,EAAE;QAC3D,MAAM,OAAO,GAAG,eAAe,CAAC,UAAU,EAAE,CAAC;QAE7C,KAAK,MAAM,gBAAgB,IAAI,OAAO,EAAE,CAAC;YACvC,IAAI,IAAA,kBAAY,EAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC;gBACxC,SAAS;YACX,CAAC;YAED,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,MAAM,CAAC;gBACjB,IAAI,EAAE,qCAAc;aACrB,CAAC,CAAC;YAEH,MAAM,iBAAiB,GAAG,gBAAgB,CAAC,MAAM,EAAE,CAAC;YACpD,IAAI,WAAW,GAAgB,IAAA,iDAA8B,EAAC,iBAAiB,aAAjB,iBAAiB,uBAAjB,iBAAiB,CAAE,YAAY,CAAC,CAAC;YAE/F,IACE,CAAC,cAAc,IAAI,IAAI,IAAI,IAAA,0CAAuB,EAAC,iBAAiB,EAAE,uBAAuB,CAAC,CAAC;gBAC/F,cAAc,EACd,CAAC;gBACD,MAAM,iBAAiB,mCAClB,IAAA,2CAAwB,EAAC,iBAAiB,CAAC,KAC9C,gBAAgB,EAChB,cAAc,EAAE,IAAA,sBAAU,GAAE,GAC7B,CAAC;gBAEF,SAAS,CAAC,2BAA2B,EAAE,iBAAiB,EAAE,SAAS,EAAE;oBACnE,WAAW;oBACX,oBAAoB,EAAE,WAAW,CAAC,UAAU,GAAG,iBAAiB,CAAC,SAAS;iBAC3E,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,OAAO,CAAC;QACf,IAAI,EAAE,qCAAc;QACpB,QAAQ,EAAE,IAAI;KACf,CAAC,CAAC;AACL,CAAC","sourcesContent":["import { faro, genShortID } from '@grafana/faro-core';\nimport type { EventsAPI, Observable, PushEventOptions } from '@grafana/faro-core';\n\nimport { isUrlIgnored } from '../../utils/url';\n\nimport { RESOURCE_ENTRY } from './performanceConstants';\nimport { createFaroResourceTiming, getSpanContextFromServerTiming, includePerformanceEntry } from './performanceUtils';\nimport type { ResourceEntryMessage } from './types';\n\ntype SpanContext = PushEventOptions['spanContext'];\n\nconst DEFAULT_TRACK_RESOURCES = { initiatorType: ['xmlhttprequest', 'fetch'] };\n\nexport function observeResourceTimings(\n faroNavigationId: string,\n pushEvent: EventsAPI['pushEvent'],\n observable: Observable<ResourceEntryMessage>\n) {\n const trackResources = faro.config.trackResources;\n\n const observer = new PerformanceObserver((observedEntries) => {\n const entries = observedEntries.getEntries();\n\n for (const resourceEntryRaw of entries) {\n if (isUrlIgnored(resourceEntryRaw.name)) {\n continue;\n }\n\n observable?.notify({\n type: RESOURCE_ENTRY,\n });\n\n const resourceEntryJson = resourceEntryRaw.toJSON();\n let spanContext: SpanContext = getSpanContextFromServerTiming(resourceEntryJson?.serverTiming);\n\n if (\n (trackResources == null && includePerformanceEntry(resourceEntryJson, DEFAULT_TRACK_RESOURCES)) ||\n trackResources\n ) {\n const faroResourceEntry = {\n ...createFaroResourceTiming(resourceEntryJson),\n faroNavigationId,\n faroResourceId: genShortID(),\n };\n\n pushEvent('faro.performance.resource', faroResourceEntry, undefined, {\n spanContext,\n timestampOverwriteMs: performance.timeOrigin + resourceEntryJson.startTime,\n });\n }\n }\n });\n\n observer.observe({\n type: RESOURCE_ENTRY,\n buffered: true,\n });\n}\n"]}
|