@grafana/faro-web-sdk 1.14.1 → 1.14.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) hide show
  1. package/dist/bundle/faro-web-sdk.iife.js +1 -1
  2. package/dist/bundle/types/index.d.ts +4 -3
  3. package/dist/bundle/types/instrumentations/console/instrumentation.d.ts +1 -1
  4. package/dist/bundle/types/instrumentations/errors/instrumentation.d.ts +1 -1
  5. package/dist/bundle/types/instrumentations/index.d.ts +1 -0
  6. package/dist/bundle/types/instrumentations/performance/instrumentation.d.ts +4 -3
  7. package/dist/bundle/types/instrumentations/performance/navigation.d.ts +1 -1
  8. package/dist/bundle/types/instrumentations/performance/performanceUtils.d.ts +0 -1
  9. package/dist/bundle/types/instrumentations/performance/resource.d.ts +3 -2
  10. package/dist/bundle/types/instrumentations/performance/types.d.ts +4 -0
  11. package/dist/bundle/types/instrumentations/session/instrumentation.d.ts +1 -1
  12. package/dist/bundle/types/instrumentations/userActions/const.d.ts +7 -0
  13. package/dist/bundle/types/instrumentations/userActions/domMutationMonitor.d.ts +2 -0
  14. package/dist/bundle/types/instrumentations/userActions/httpRequestMonitor.d.ts +5 -0
  15. package/dist/bundle/types/instrumentations/userActions/index.d.ts +3 -0
  16. package/dist/bundle/types/instrumentations/userActions/instrumentation.d.ts +6 -0
  17. package/dist/bundle/types/instrumentations/userActions/performanceEntriesMonitor.d.ts +2 -0
  18. package/dist/bundle/types/instrumentations/userActions/processUserActionEventHandler.d.ts +2 -0
  19. package/dist/bundle/types/instrumentations/userActions/types.d.ts +12 -0
  20. package/dist/bundle/types/instrumentations/userActions/util.d.ts +8 -0
  21. package/dist/bundle/types/instrumentations/view/instrumentation.d.ts +1 -1
  22. package/dist/bundle/types/instrumentations/webVitals/instrumentation.d.ts +1 -1
  23. package/dist/bundle/types/transports/console/transport.d.ts +1 -1
  24. package/dist/bundle/types/transports/fetch/transport.d.ts +1 -1
  25. package/dist/bundle/types/utils/index.d.ts +1 -1
  26. package/dist/bundle/types/utils/url.d.ts +12 -2
  27. package/dist/cjs/config/getWebInstrumentations.js +1 -0
  28. package/dist/cjs/config/getWebInstrumentations.js.map +1 -1
  29. package/dist/cjs/config/makeCoreConfig.js +20 -7
  30. package/dist/cjs/config/makeCoreConfig.js.map +1 -1
  31. package/dist/cjs/index.js +11 -2
  32. package/dist/cjs/index.js.map +1 -1
  33. package/dist/cjs/instrumentations/index.js +4 -1
  34. package/dist/cjs/instrumentations/index.js.map +1 -1
  35. package/dist/cjs/instrumentations/performance/instrumentation.js +5 -9
  36. package/dist/cjs/instrumentations/performance/instrumentation.js.map +1 -1
  37. package/dist/cjs/instrumentations/performance/navigation.js +3 -2
  38. package/dist/cjs/instrumentations/performance/navigation.js.map +1 -1
  39. package/dist/cjs/instrumentations/performance/performanceUtils.js +1 -6
  40. package/dist/cjs/instrumentations/performance/performanceUtils.js.map +1 -1
  41. package/dist/cjs/instrumentations/performance/resource.js +8 -2
  42. package/dist/cjs/instrumentations/performance/resource.js.map +1 -1
  43. package/dist/cjs/instrumentations/performance/types.js.map +1 -1
  44. package/dist/cjs/instrumentations/userActions/const.js +11 -0
  45. package/dist/cjs/instrumentations/userActions/const.js.map +1 -0
  46. package/dist/cjs/instrumentations/userActions/domMutationMonitor.js +20 -0
  47. package/dist/cjs/instrumentations/userActions/domMutationMonitor.js.map +1 -0
  48. package/dist/cjs/instrumentations/userActions/httpRequestMonitor.js +88 -0
  49. package/dist/cjs/instrumentations/userActions/httpRequestMonitor.js.map +1 -0
  50. package/dist/cjs/instrumentations/userActions/index.js +11 -0
  51. package/dist/cjs/instrumentations/userActions/index.js.map +1 -0
  52. package/dist/cjs/instrumentations/userActions/instrumentation.js +37 -0
  53. package/dist/cjs/instrumentations/userActions/instrumentation.js.map +1 -0
  54. package/dist/cjs/instrumentations/userActions/performanceEntriesMonitor.js +18 -0
  55. package/dist/cjs/instrumentations/userActions/performanceEntriesMonitor.js.map +1 -0
  56. package/dist/cjs/instrumentations/userActions/processUserActionEventHandler.js +130 -0
  57. package/dist/cjs/instrumentations/userActions/processUserActionEventHandler.js.map +1 -0
  58. package/dist/cjs/instrumentations/userActions/types.js +3 -0
  59. package/dist/cjs/instrumentations/userActions/types.js.map +1 -0
  60. package/dist/cjs/instrumentations/userActions/util.js +17 -0
  61. package/dist/cjs/instrumentations/userActions/util.js.map +1 -0
  62. package/dist/cjs/utils/index.js +3 -3
  63. package/dist/cjs/utils/index.js.map +1 -1
  64. package/dist/cjs/utils/url.js +15 -2
  65. package/dist/cjs/utils/url.js.map +1 -1
  66. package/dist/esm/config/getWebInstrumentations.js +2 -1
  67. package/dist/esm/config/getWebInstrumentations.js.map +1 -1
  68. package/dist/esm/config/makeCoreConfig.js +20 -8
  69. package/dist/esm/config/makeCoreConfig.js.map +1 -1
  70. package/dist/esm/index.js +3 -2
  71. package/dist/esm/index.js.map +1 -1
  72. package/dist/esm/instrumentations/index.js +1 -0
  73. package/dist/esm/instrumentations/index.js.map +1 -1
  74. package/dist/esm/instrumentations/performance/instrumentation.js +4 -8
  75. package/dist/esm/instrumentations/performance/instrumentation.js.map +1 -1
  76. package/dist/esm/instrumentations/performance/navigation.js +4 -3
  77. package/dist/esm/instrumentations/performance/navigation.js.map +1 -1
  78. package/dist/esm/instrumentations/performance/performanceUtils.js +0 -3
  79. package/dist/esm/instrumentations/performance/performanceUtils.js.map +1 -1
  80. package/dist/esm/instrumentations/performance/resource.js +9 -3
  81. package/dist/esm/instrumentations/performance/resource.js.map +1 -1
  82. package/dist/esm/instrumentations/performance/types.js.map +1 -1
  83. package/dist/esm/instrumentations/userActions/const.js +8 -0
  84. package/dist/esm/instrumentations/userActions/const.js.map +1 -0
  85. package/dist/esm/instrumentations/userActions/domMutationMonitor.js +16 -0
  86. package/dist/esm/instrumentations/userActions/domMutationMonitor.js.map +1 -0
  87. package/dist/esm/instrumentations/userActions/httpRequestMonitor.js +84 -0
  88. package/dist/esm/instrumentations/userActions/httpRequestMonitor.js.map +1 -0
  89. package/dist/esm/instrumentations/userActions/index.js +3 -0
  90. package/dist/esm/instrumentations/userActions/index.js.map +1 -0
  91. package/dist/esm/instrumentations/userActions/instrumentation.js +15 -0
  92. package/dist/esm/instrumentations/userActions/instrumentation.js.map +1 -0
  93. package/dist/esm/instrumentations/userActions/performanceEntriesMonitor.js +14 -0
  94. package/dist/esm/instrumentations/userActions/performanceEntriesMonitor.js.map +1 -0
  95. package/dist/esm/instrumentations/userActions/processUserActionEventHandler.js +126 -0
  96. package/dist/esm/instrumentations/userActions/processUserActionEventHandler.js.map +1 -0
  97. package/dist/esm/instrumentations/userActions/types.js +2 -0
  98. package/dist/esm/instrumentations/userActions/types.js.map +1 -0
  99. package/dist/esm/instrumentations/userActions/util.js +13 -0
  100. package/dist/esm/instrumentations/userActions/util.js.map +1 -0
  101. package/dist/esm/utils/index.js +1 -1
  102. package/dist/esm/utils/index.js.map +1 -1
  103. package/dist/esm/utils/url.js +12 -1
  104. package/dist/esm/utils/url.js.map +1 -1
  105. package/dist/types/index.d.ts +4 -3
  106. package/dist/types/instrumentations/console/instrumentation.d.ts +1 -1
  107. package/dist/types/instrumentations/errors/instrumentation.d.ts +1 -1
  108. package/dist/types/instrumentations/index.d.ts +1 -0
  109. package/dist/types/instrumentations/performance/instrumentation.d.ts +4 -3
  110. package/dist/types/instrumentations/performance/navigation.d.ts +1 -1
  111. package/dist/types/instrumentations/performance/performanceUtils.d.ts +0 -1
  112. package/dist/types/instrumentations/performance/resource.d.ts +3 -2
  113. package/dist/types/instrumentations/performance/types.d.ts +4 -0
  114. package/dist/types/instrumentations/session/instrumentation.d.ts +1 -1
  115. package/dist/types/instrumentations/userActions/const.d.ts +7 -0
  116. package/dist/types/instrumentations/userActions/domMutationMonitor.d.ts +2 -0
  117. package/dist/types/instrumentations/userActions/httpRequestMonitor.d.ts +5 -0
  118. package/dist/types/instrumentations/userActions/index.d.ts +3 -0
  119. package/dist/types/instrumentations/userActions/instrumentation.d.ts +6 -0
  120. package/dist/types/instrumentations/userActions/performanceEntriesMonitor.d.ts +2 -0
  121. package/dist/types/instrumentations/userActions/processUserActionEventHandler.d.ts +2 -0
  122. package/dist/types/instrumentations/userActions/types.d.ts +12 -0
  123. package/dist/types/instrumentations/userActions/util.d.ts +8 -0
  124. package/dist/types/instrumentations/view/instrumentation.d.ts +1 -1
  125. package/dist/types/instrumentations/webVitals/instrumentation.d.ts +1 -1
  126. package/dist/types/transports/console/transport.d.ts +1 -1
  127. package/dist/types/transports/fetch/transport.d.ts +1 -1
  128. package/dist/types/utils/index.d.ts +1 -1
  129. package/dist/types/utils/url.d.ts +12 -2
  130. package/package.json +3 -3
@@ -0,0 +1,126 @@
1
+ import { apiMessageBus, dateNow, genShortID, merge, USER_ACTION_CANCEL_MESSAGE_TYPE, USER_ACTION_END_MESSAGE_TYPE, USER_ACTION_START_MESSAGE_TYPE, } from '@grafana/faro-core';
2
+ import { userActionDataAttributeParsed as userActionDataAttribute } from './const';
3
+ import { monitorDomMutations } from './domMutationMonitor';
4
+ import { monitorHttpRequests } from './httpRequestMonitor';
5
+ import { monitorPerformanceEntries } from './performanceEntriesMonitor';
6
+ import { convertDataAttributeName } from './util';
7
+ export function getUserEventHandler(faro) {
8
+ const { api, config } = faro;
9
+ const httpMonitor = monitorHttpRequests();
10
+ const domMutationsMonitor = monitorDomMutations();
11
+ const performanceEntriesMonitor = monitorPerformanceEntries();
12
+ let allMonitorsSub;
13
+ let allMonitorsObserver;
14
+ let timeoutId;
15
+ let actionRunning = false;
16
+ function processUserEvent(event) {
17
+ var _a;
18
+ const userActionName = getUserActionName(event.target, (_a = config.trackUserActionsDataAttributeName) !== null && _a !== void 0 ? _a : userActionDataAttribute);
19
+ if (actionRunning || userActionName == null) {
20
+ return;
21
+ }
22
+ actionRunning = true;
23
+ const startTime = dateNow();
24
+ let endTime;
25
+ const actionId = genShortID();
26
+ apiMessageBus.notify({
27
+ type: USER_ACTION_START_MESSAGE_TYPE,
28
+ name: userActionName,
29
+ startTime: startTime,
30
+ parentId: actionId,
31
+ });
32
+ // Triggers if no initial action happened within the first 100ms
33
+ timeoutId = startTimeout(timeoutId, () => {
34
+ endTime = dateNow();
35
+ // Listening for follow up activities stops once action is cancelled (set to false)
36
+ actionRunning = false;
37
+ sendUserActionCancelMessage(userActionName, actionId);
38
+ });
39
+ allMonitorsObserver = merge(httpMonitor, domMutationsMonitor, performanceEntriesMonitor);
40
+ allMonitorsSub = allMonitorsObserver
41
+ .takeWhile(() => actionRunning)
42
+ .subscribe(() => {
43
+ // A http request, a DOM mutation or a performance entry happened so we have a follow up activity and start the timeout again
44
+ // If timeout is triggered the user action is done and we send respective messages and events
45
+ timeoutId = startTimeout(timeoutId, () => {
46
+ endTime = dateNow();
47
+ const duration = endTime - startTime;
48
+ const eventType = event.type;
49
+ // order matters, first emit the user-action-end event and then push the event
50
+ apiMessageBus.notify({
51
+ type: USER_ACTION_END_MESSAGE_TYPE,
52
+ name: userActionName,
53
+ id: actionId,
54
+ startTime,
55
+ endTime,
56
+ duration,
57
+ eventType,
58
+ });
59
+ // Send the final action parent event
60
+ api.pushEvent(userActionName, {
61
+ userActionStartTime: startTime.toString(),
62
+ userActionEndTime: endTime.toString(),
63
+ userActionDuration: duration.toString(),
64
+ userActionEventType: eventType,
65
+ }, undefined, {
66
+ timestampOverwriteMs: startTime,
67
+ customPayloadTransformer: (payload) => {
68
+ payload.action = {
69
+ id: actionId,
70
+ name: userActionName,
71
+ };
72
+ return payload;
73
+ },
74
+ });
75
+ // Ensure action is blocked until it is fully processed.
76
+ actionRunning = false;
77
+ allMonitorsSub === null || allMonitorsSub === void 0 ? void 0 : allMonitorsSub.unsubscribe();
78
+ allMonitorsObserver === null || allMonitorsObserver === void 0 ? void 0 : allMonitorsObserver.unsubscribeAll();
79
+ });
80
+ });
81
+ }
82
+ registerVisibilityChangeHandler(allMonitorsSub, allMonitorsObserver);
83
+ return processUserEvent;
84
+ }
85
+ function getUserActionName(element, dataAttributeName) {
86
+ const parsedDataAttributeName = convertDataAttributeName(dataAttributeName);
87
+ const dataset = element.dataset;
88
+ for (const key in dataset) {
89
+ if (key === parsedDataAttributeName) {
90
+ return dataset[key];
91
+ }
92
+ }
93
+ return undefined;
94
+ }
95
+ function startTimeout(timeoutId, cb) {
96
+ const maxTimeSpanTillUserActionEnd = 100;
97
+ if (timeoutId) {
98
+ clearTimeout(timeoutId);
99
+ }
100
+ //@ts-expect-error for some reason vscode is using the node types
101
+ timeoutId = setTimeout(() => {
102
+ cb();
103
+ }, maxTimeSpanTillUserActionEnd);
104
+ return timeoutId;
105
+ }
106
+ function sendUserActionCancelMessage(userActionName, actionId) {
107
+ apiMessageBus.notify({
108
+ type: USER_ACTION_CANCEL_MESSAGE_TYPE,
109
+ name: userActionName,
110
+ parentId: actionId,
111
+ });
112
+ }
113
+ function registerVisibilityChangeHandler(allMonitorsSub, allMonitorsObserver) {
114
+ // stop monitoring in background tabs
115
+ document.addEventListener('visibilitychange', () => {
116
+ if (document.visibilityState === 'hidden') {
117
+ // Unsubscribe from all monitors when the tab goes into the background to free up resources (merge.unsubscribe() also unsubscribes from all inner observables)
118
+ // Monitors will be re-subscribed in the processEvent function when the first user action is detected
119
+ allMonitorsSub === null || allMonitorsSub === void 0 ? void 0 : allMonitorsSub.unsubscribe();
120
+ allMonitorsSub = undefined;
121
+ allMonitorsObserver === null || allMonitorsObserver === void 0 ? void 0 : allMonitorsObserver.unsubscribeAll();
122
+ allMonitorsObserver = undefined;
123
+ }
124
+ });
125
+ }
126
+ //# sourceMappingURL=processUserActionEventHandler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"processUserActionEventHandler.js","sourceRoot":"","sources":["../../../../src/instrumentations/userActions/processUserActionEventHandler.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n apiMessageBus,\n dateNow,\n Faro,\n genShortID,\n merge,\n Observable,\n Subscription,\n USER_ACTION_CANCEL_MESSAGE_TYPE,\n USER_ACTION_END_MESSAGE_TYPE,\n USER_ACTION_START_MESSAGE_TYPE,\n} from '@grafana/faro-core';\n\nimport { userActionDataAttributeParsed as userActionDataAttribute } from './const';\nimport { monitorDomMutations } from './domMutationMonitor';\nimport { monitorHttpRequests } from './httpRequestMonitor';\nimport { monitorPerformanceEntries } from './performanceEntriesMonitor';\nimport { convertDataAttributeName } from './util';\n\nexport function getUserEventHandler(faro: Faro) {\n const { api, config } = faro;\n\n const httpMonitor = monitorHttpRequests();\n const domMutationsMonitor = monitorDomMutations();\n const performanceEntriesMonitor = monitorPerformanceEntries();\n\n let allMonitorsSub: Subscription | undefined;\n let allMonitorsObserver: Observable | undefined;\n\n let timeoutId: number | undefined;\n let actionRunning = false;\n\n function processUserEvent(event: PointerEvent | KeyboardEvent) {\n const userActionName = getUserActionName(\n event.target as HTMLElement,\n config.trackUserActionsDataAttributeName ?? userActionDataAttribute\n );\n\n if (actionRunning || userActionName == null) {\n return;\n }\n\n actionRunning = true;\n\n const startTime = dateNow();\n let endTime: number | undefined;\n\n const actionId = genShortID();\n\n apiMessageBus.notify({\n type: USER_ACTION_START_MESSAGE_TYPE,\n name: userActionName,\n startTime: startTime,\n parentId: actionId,\n });\n\n // Triggers if no initial action happened within the first 100ms\n timeoutId = startTimeout(timeoutId, () => {\n endTime = dateNow();\n\n // Listening for follow up activities stops once action is cancelled (set to false)\n actionRunning = false;\n sendUserActionCancelMessage(userActionName, actionId);\n });\n\n allMonitorsObserver = merge(httpMonitor, domMutationsMonitor, performanceEntriesMonitor);\n\n allMonitorsSub = allMonitorsObserver\n .takeWhile(() => actionRunning)\n .subscribe(() => {\n // A http request, a DOM mutation or a performance entry happened so we have a follow up activity and start the timeout again\n // If timeout is triggered the user action is done and we send respective messages and events\n timeoutId = startTimeout(timeoutId, () => {\n endTime = dateNow();\n\n const duration = endTime - startTime;\n const eventType = event.type;\n\n // order matters, first emit the user-action-end event and then push the event\n apiMessageBus.notify({\n type: USER_ACTION_END_MESSAGE_TYPE,\n name: userActionName,\n id: actionId,\n startTime,\n endTime,\n duration,\n eventType,\n });\n\n // Send the final action parent event\n api.pushEvent(\n userActionName,\n {\n userActionStartTime: startTime.toString(),\n userActionEndTime: endTime.toString(),\n userActionDuration: duration.toString(),\n userActionEventType: eventType,\n },\n undefined,\n {\n timestampOverwriteMs: startTime,\n customPayloadTransformer: (payload) => {\n payload.action = {\n id: actionId,\n name: userActionName,\n };\n\n return payload;\n },\n }\n );\n\n // Ensure action is blocked until it is fully processed.\n actionRunning = false;\n allMonitorsSub?.unsubscribe();\n allMonitorsObserver?.unsubscribeAll();\n });\n });\n }\n\n registerVisibilityChangeHandler(allMonitorsSub, allMonitorsObserver);\n\n return processUserEvent;\n}\n\nfunction getUserActionName(element: HTMLElement, dataAttributeName: string): string | undefined {\n const parsedDataAttributeName = convertDataAttributeName(dataAttributeName);\n const dataset = element.dataset;\n\n for (const key in dataset) {\n if (key === parsedDataAttributeName) {\n return dataset[key];\n }\n }\n\n return undefined;\n}\n\nfunction startTimeout(timeoutId: number | undefined, cb: () => void) {\n const maxTimeSpanTillUserActionEnd = 100;\n\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 }, maxTimeSpanTillUserActionEnd);\n\n return timeoutId;\n}\n\nfunction sendUserActionCancelMessage(userActionName: string, actionId: string) {\n apiMessageBus.notify({\n type: USER_ACTION_CANCEL_MESSAGE_TYPE,\n name: userActionName,\n parentId: actionId,\n });\n}\n\nfunction registerVisibilityChangeHandler(\n allMonitorsSub: Subscription | undefined,\n allMonitorsObserver: Observable | undefined\n) {\n // stop monitoring in background tabs\n document.addEventListener('visibilitychange', () => {\n if (document.visibilityState === 'hidden') {\n // Unsubscribe from all monitors when the tab goes into the background to free up resources (merge.unsubscribe() also unsubscribes from all inner observables)\n // Monitors will be re-subscribed in the processEvent function when the first user action is detected\n allMonitorsSub?.unsubscribe();\n allMonitorsSub = undefined;\n\n allMonitorsObserver?.unsubscribeAll();\n allMonitorsObserver = undefined;\n }\n });\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/instrumentations/userActions/types.ts"],"names":[],"mappings":"","sourcesContent":["import type {\n MESSAGE_TYPE_DOM_MUTATION,\n MESSAGE_TYPE_HTTP_REQUEST_END,\n MESSAGE_TYPE_HTTP_REQUEST_START,\n} from './const';\n\nexport type DomMutationMessage = {\n type: typeof MESSAGE_TYPE_DOM_MUTATION;\n};\n\nexport type HttpRequestStartMessage = {\n type: typeof MESSAGE_TYPE_HTTP_REQUEST_START;\n pending: number;\n};\n\nexport type HttpRequestEndMessage = {\n type: typeof MESSAGE_TYPE_HTTP_REQUEST_END;\n pending: number;\n};\n"]}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Parses the action attribute name by removing the 'data-' prefix and converting
3
+ * the remaining string to camelCase.
4
+ *
5
+ * This is needed because the browser will remove the 'data-' prefix and the dashes from
6
+ * data attributes and make then camelCase.
7
+ */
8
+ export function convertDataAttributeName(userActionDataAttribute) {
9
+ const withoutData = userActionDataAttribute.split('data-')[1];
10
+ const withUpperCase = withoutData === null || withoutData === void 0 ? void 0 : withoutData.replace(/-(.)/g, (_, char) => char.toUpperCase());
11
+ return withUpperCase === null || withUpperCase === void 0 ? void 0 : withUpperCase.replace(/-/g, '');
12
+ }
13
+ //# sourceMappingURL=util.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"util.js","sourceRoot":"","sources":["../../../../src/instrumentations/userActions/util.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,UAAU,wBAAwB,CAAC,uBAA+B;IACtE,MAAM,WAAW,GAAG,uBAAuB,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9D,MAAM,aAAa,GAAG,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;IACrF,OAAO,aAAa,aAAb,aAAa,uBAAb,aAAa,CAAE,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;AAC1C,CAAC","sourcesContent":["/**\n * Parses the action attribute name by removing the 'data-' prefix and converting\n * the remaining string to camelCase.\n *\n * This is needed because the browser will remove the 'data-' prefix and the dashes from\n * data attributes and make then camelCase.\n */\nexport function convertDataAttributeName(userActionDataAttribute: string) {\n const withoutData = userActionDataAttribute.split('data-')[1];\n const withUpperCase = withoutData?.replace(/-(.)/g, (_, char) => char.toUpperCase());\n return withUpperCase?.replace(/-/g, '');\n}\n"]}
@@ -1,4 +1,4 @@
1
- export { isLocalStorageAvailable, isSessionStorageAvailable, webStorageType, getItem, isWebStorageAvailable, removeItem, setItem, } from './webStorage';
1
+ export { getItem, isLocalStorageAvailable, isSessionStorageAvailable, isWebStorageAvailable, removeItem, setItem, webStorageType, } from './webStorage';
2
2
  export { throttle } from './throttle';
3
3
  export { getIgnoreUrls } from './url';
4
4
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,uBAAuB,EACvB,yBAAyB,EACzB,cAAc,EACd,OAAO,EACP,qBAAqB,EACrB,UAAU,EACV,OAAO,GACR,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC","sourcesContent":["export {\n isLocalStorageAvailable,\n isSessionStorageAvailable,\n webStorageType,\n getItem,\n isWebStorageAvailable,\n removeItem,\n setItem,\n} from './webStorage';\n\nexport { throttle } from './throttle';\n\nexport { getIgnoreUrls } from './url';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,EACP,uBAAuB,EACvB,yBAAyB,EACzB,qBAAqB,EACrB,UAAU,EACV,OAAO,EACP,cAAc,GACf,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC","sourcesContent":["export {\n getItem,\n isLocalStorageAvailable,\n isSessionStorageAvailable,\n isWebStorageAvailable,\n removeItem,\n setItem,\n webStorageType,\n} from './webStorage';\n\nexport { throttle } from './throttle';\n\nexport { getIgnoreUrls } from './url';\n"]}
@@ -1,8 +1,19 @@
1
1
  import { faro } from '@grafana/faro-core';
2
2
  /**
3
- * Get all configured ignore URLs.
3
+ * Retrieves a list of URLs to be ignored by aggregating the ignore URLs from all transports.
4
+ *
5
+ * @returns {string[]} An array of URLs to be ignored.
4
6
  */
5
7
  export function getIgnoreUrls() {
6
8
  return faro.transports.transports.flatMap((transport) => transport.getIgnoreUrls());
7
9
  }
10
+ /**
11
+ * Checks if the given URL should be ignored based on a list of ignored URLs.
12
+ *
13
+ * @param url - The URL to check.
14
+ * @returns `true` if the URL is in the list of ignored URLs, `false` otherwise.
15
+ */
16
+ export function isUrlIgnored(url = '') {
17
+ return getIgnoreUrls().some((ignoredUrl) => url && url.match(ignoredUrl) != null);
18
+ }
8
19
  //# sourceMappingURL=url.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"url.js","sourceRoot":"","sources":["../../../src/utils/url.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAG1C;;GAEG;AACH,MAAM,UAAU,aAAa;IAC3B,OAAO,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,SAAoB,EAAE,EAAE,CAAC,SAAS,CAAC,aAAa,EAAE,CAAC,CAAC;AACjG,CAAC","sourcesContent":["import { faro } from '@grafana/faro-core';\nimport type { Transport } from '@grafana/faro-core';\n\n/**\n * Get all configured ignore URLs.\n */\nexport function getIgnoreUrls() {\n return faro.transports.transports.flatMap((transport: Transport) => transport.getIgnoreUrls());\n}\n"]}
1
+ {"version":3,"file":"url.js","sourceRoot":"","sources":["../../../src/utils/url.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAG1C;;;;GAIG;AACH,MAAM,UAAU,aAAa;IAC3B,OAAO,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,SAAoB,EAAE,EAAE,CAAC,SAAS,CAAC,aAAa,EAAE,CAAC,CAAC;AACjG,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,GAAG,GAAG,EAAE;IACnC,OAAO,aAAa,EAAE,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC,CAAC;AACpF,CAAC","sourcesContent":["import { faro } from '@grafana/faro-core';\nimport type { Patterns, Transport } from '@grafana/faro-core';\n\n/**\n * Retrieves a list of URLs to be ignored by aggregating the ignore URLs from all transports.\n *\n * @returns {string[]} An array of URLs to be ignored.\n */\nexport function getIgnoreUrls(): Patterns {\n return faro.transports.transports.flatMap((transport: Transport) => transport.getIgnoreUrls());\n}\n\n/**\n * Checks if the given URL should be ignored based on a list of ignored URLs.\n *\n * @param url - The URL to check.\n * @returns `true` if the URL is in the list of ignored URLs, `false` otherwise.\n */\nexport function isUrlIgnored(url = ''): boolean {\n return getIgnoreUrls().some((ignoredUrl) => url && url.match(ignoredUrl) != null);\n}\n"]}
@@ -2,12 +2,13 @@ export { getWebInstrumentations, makeCoreConfig } from './config';
2
2
  export type { BrowserConfig } from './config';
3
3
  export { defaultEventDomain } from './consts';
4
4
  export { initializeFaro } from './initialize';
5
- export { buildStackFrame, ConsoleInstrumentation, ErrorsInstrumentation, getDataFromSafariExtensions, getStackFramesFromError, parseStacktrace, ViewInstrumentation, WebVitalsInstrumentation, SessionInstrumentation, PerformanceInstrumentation, } from './instrumentations';
5
+ export { buildStackFrame, ConsoleInstrumentation, ErrorsInstrumentation, getDataFromSafariExtensions, getStackFramesFromError, parseStacktrace, ViewInstrumentation, WebVitalsInstrumentation, SessionInstrumentation, PerformanceInstrumentation, UserActionInstrumentation, } from './instrumentations';
6
6
  export type { ConsoleInstrumentationOptions, ErrorEvent, ExtendedPromiseRejectionEvent } from './instrumentations';
7
7
  export { browserMeta, createSession, sdkMeta } from './metas';
8
8
  export { ConsoleTransport, FetchTransport } from './transports';
9
9
  export type { ClockFn, ConsoleTransportOptions, FetchTransportOptions, FetchTransportRequestOptions, } from './transports';
10
- export { faro, allLogLevels, BaseExtension, BaseInstrumentation, BaseTransport, Conventions, createInternalLogger, createPromiseBuffer, deepEqual, defaultExceptionType, defaultGlobalObjectKey, defaultInternalLoggerLevel, defaultLogLevel, genShortID, getCurrentTimestamp, getInternalFaroFromGlobalObject, getTransportBody, globalObject, internalGlobalObjectKey, isArray, isBoolean, isDomError, isDomException, isElement, isElementDefined, isError, isErrorDefined, isErrorEvent, isEvent, isEventDefined, isFunction, isInstanceOf, isInt, isInternalFaroOnGlobalObject, isMap, isMapDefined, isNull, isNumber, isObject, isPrimitive, isRegExp, isString, isSymbol, isSyntheticEvent, isThenable, isToString, isTypeof, isUndefined, isEmpty, InternalLoggerLevel, LogLevel, noop, setInternalFaroOnGlobalObject, TransportItemType, transportItemTypeToBodyKey, VERSION, EVENT_CLICK, EVENT_NAVIGATION, EVENT_ROUTE_CHANGE, EVENT_SESSION_EXTEND, EVENT_SESSION_RESUME, EVENT_SESSION_START, EVENT_VIEW_CHANGED, } from '@grafana/faro-core';
11
- export type { Faro, API, APIEvent, BaseObject, BaseObjectKey, BaseObjectPrimitiveValue, BaseObjectValue, BeforeSendHook, BufferItem, Config, EventAttributes, EventEvent, EventsAPI, ExceptionEvent, ExceptionStackFrame, ExceptionsAPI, ExtendedError, Extension, GlobalObject, Instrumentation, Instrumentations, InternalLogger, LogContext, LogEvent, LogsAPI, MeasurementEvent, MeasurementsAPI, Meta, MetaAPI, MetaApp, MetaAttributes, MetaBrowser, MetaGetter, MetaItem, MetaPage, Metas, MetaSDK, MetaSDKIntegration, MetaSession, MetaUser, MetaView, OTELApi, Patterns, PromiseBuffer, PromiseBufferOptions, PromiseProducer, PushErrorOptions, PushLogOptions, PushMeasurementOptions, Stacktrace, StacktraceParser, TraceContext, TraceEvent, TracesAPI, Transport, TransportBody, TransportItem, TransportItemPayload, Transports, UnpatchedConsole, } from '@grafana/faro-core';
10
+ export { faro, allLogLevels, BaseExtension, BaseInstrumentation, BaseTransport, Conventions, createInternalLogger, createPromiseBuffer, deepEqual, defaultExceptionType, defaultGlobalObjectKey, defaultInternalLoggerLevel, defaultLogLevel, genShortID, getCurrentTimestamp, getInternalFaroFromGlobalObject, getTransportBody, globalObject, internalGlobalObjectKey, isArray, isBoolean, isDomError, isDomException, isElement, isElementDefined, isError, isErrorDefined, isErrorEvent, isEvent, isEventDefined, isFunction, isInstanceOf, isInt, isInternalFaroOnGlobalObject, isMap, isMapDefined, isNull, isNumber, isObject, isPrimitive, isRegExp, isString, isSymbol, isSyntheticEvent, isThenable, isToString, isTypeof, isUndefined, isEmpty, InternalLoggerLevel, LogLevel, noop, setInternalFaroOnGlobalObject, TransportItemType, transportItemTypeToBodyKey, VERSION, EVENT_CLICK, EVENT_NAVIGATION, EVENT_ROUTE_CHANGE, EVENT_SESSION_EXTEND, EVENT_SESSION_RESUME, EVENT_SESSION_START, EVENT_VIEW_CHANGED, apiMessageBus, Observable, merge, USER_ACTION_CANCEL_MESSAGE_TYPE, USER_ACTION_END_MESSAGE_TYPE, USER_ACTION_START_MESSAGE_TYPE, } from '@grafana/faro-core';
11
+ export type { Faro, API, APIEvent, BaseObject, BaseObjectKey, BaseObjectPrimitiveValue, BaseObjectValue, BeforeSendHook, BufferItem, Config, EventAttributes, EventEvent, EventsAPI, ExceptionEvent, ExceptionStackFrame, ExceptionsAPI, ExtendedError, Extension, GlobalObject, Instrumentation, Instrumentations, InternalLogger, LogContext, LogEvent, LogsAPI, MeasurementEvent, MeasurementsAPI, Meta, MetaAPI, MetaApp, MetaAttributes, MetaBrowser, MetaGetter, MetaItem, MetaPage, Metas, MetaSDK, MetaSDKIntegration, MetaSession, MetaUser, MetaView, OTELApi, Patterns, PromiseBuffer, PromiseBufferOptions, PromiseProducer, PushErrorOptions, PushLogOptions, PushMeasurementOptions, Stacktrace, StacktraceParser, TraceContext, TraceEvent, TracesAPI, Transport, TransportBody, TransportItem, TransportItemPayload, Transports, UnpatchedConsole, ApiMessageBusMessages, UserActionStartMessage, UserActionEndMessage, UserActionCancelMessage, UserAction, } from '@grafana/faro-core';
12
12
  export { PersistentSessionsManager, VolatileSessionsManager, MAX_SESSION_PERSISTENCE_TIME, MAX_SESSION_PERSISTENCE_TIME_BUFFER, SESSION_EXPIRATION_TIME, SESSION_INACTIVITY_TIME, STORAGE_KEY, } from './instrumentations/session';
13
13
  export { getIgnoreUrls } from './utils/url';
14
+ export { userActionDataAttribute } from './instrumentations/userActions/const';
@@ -3,7 +3,7 @@ import type { ConsoleInstrumentationOptions } from './types';
3
3
  export declare class ConsoleInstrumentation extends BaseInstrumentation {
4
4
  private options;
5
5
  readonly name = "@grafana/faro-web-sdk:instrumentation-console";
6
- readonly version = "1.14.1";
6
+ readonly version = "1.14.2";
7
7
  static defaultDisabledLevels: LogLevel[];
8
8
  static consoleErrorPrefix: string;
9
9
  private errorSerializer;
@@ -1,6 +1,6 @@
1
1
  import { BaseInstrumentation } from '@grafana/faro-core';
2
2
  export declare class ErrorsInstrumentation extends BaseInstrumentation {
3
3
  readonly name = "@grafana/faro-web-sdk:instrumentation-errors";
4
- readonly version = "1.14.1";
4
+ readonly version = "1.14.2";
5
5
  initialize(): void;
6
6
  }
@@ -7,3 +7,4 @@ export { ViewInstrumentation } from './view';
7
7
  export { WebVitalsInstrumentation } from './webVitals';
8
8
  export { PersistentSessionsManager, VolatileSessionsManager, MAX_SESSION_PERSISTENCE_TIME, MAX_SESSION_PERSISTENCE_TIME_BUFFER, SESSION_EXPIRATION_TIME, SESSION_INACTIVITY_TIME, STORAGE_KEY, } from './session';
9
9
  export { PerformanceInstrumentation } from './performance';
10
+ export { UserActionInstrumentation, userActionDataAttribute } from './userActions';
@@ -1,7 +1,8 @@
1
- import { BaseInstrumentation } from '@grafana/faro-core';
1
+ import { BaseInstrumentation, Observable } from '@grafana/faro-core';
2
+ import type { ResourceEntryMessage } from './types';
3
+ export declare const performanceEntriesSubscription: Observable<ResourceEntryMessage>;
2
4
  export declare class PerformanceInstrumentation extends BaseInstrumentation {
3
5
  readonly name = "@grafana/faro-web-sdk:instrumentation-performance";
4
- readonly version = "1.14.1";
6
+ readonly version = "1.14.2";
5
7
  initialize(): void;
6
- private getIgnoreUrls;
7
8
  }
@@ -1,3 +1,3 @@
1
1
  import type { EventsAPI } from '@grafana/faro-core';
2
2
  import type { FaroNavigationItem } from './types';
3
- export declare function getNavigationTimings(pushEvent: EventsAPI['pushEvent'], ignoredUrls: Array<string | RegExp>): Promise<FaroNavigationItem>;
3
+ export declare function getNavigationTimings(pushEvent: EventsAPI['pushEvent']): Promise<FaroNavigationItem>;
@@ -3,7 +3,6 @@ import type { FaroNavigationTiming, FaroResourceTiming } from './types';
3
3
  type SpanContext = PushEventOptions['spanContext'];
4
4
  export declare function getSpanContextFromServerTiming(serverTimings?: PerformanceServerTiming[]): SpanContext | undefined;
5
5
  export declare function performanceObserverSupported(): boolean;
6
- export declare function entryUrlIsIgnored(ignoredUrls: (string | RegExp)[] | undefined, entryName: string): boolean;
7
6
  export declare function onDocumentReady(handleReady: () => void): void;
8
7
  type PerformanceEntryAllowProperties = Record<string, Array<string | number> | string | number>;
9
8
  export declare function includePerformanceEntry(performanceEntryJSON: Record<string, any>, allowProps?: PerformanceEntryAllowProperties): boolean;
@@ -1,2 +1,3 @@
1
- import type { EventsAPI } from '@grafana/faro-core';
2
- export declare function observeResourceTimings(faroNavigationId: string, pushEvent: EventsAPI['pushEvent'], ignoredUrls: Array<string | RegExp>): void;
1
+ import type { EventsAPI, Observable } from '@grafana/faro-core';
2
+ import type { ResourceEntryMessage } from './types';
3
+ export declare function observeResourceTimings(faroNavigationId: string, pushEvent: EventsAPI['pushEvent'], observable: Observable<ResourceEntryMessage>): void;
@@ -1,4 +1,5 @@
1
1
  import type { unknownString } from '@grafana/faro-core';
2
+ import type { RESOURCE_ENTRY } from './performanceConstants';
2
3
  export type FaroNavigationTiming = Readonly<{
3
4
  duration: string;
4
5
  documentParsingTime: string;
@@ -38,3 +39,6 @@ export type FaroResourceItem = {
38
39
  faroResourceId: string;
39
40
  } & FaroResourceTiming;
40
41
  export type CacheType = 'cache' | 'conditionalFetch' | 'fullLoad';
42
+ export type ResourceEntryMessage = {
43
+ type: typeof RESOURCE_ENTRY;
44
+ };
@@ -1,7 +1,7 @@
1
1
  import { BaseInstrumentation } from '@grafana/faro-core';
2
2
  export declare class SessionInstrumentation extends BaseInstrumentation {
3
3
  readonly name = "@grafana/faro-web-sdk:instrumentation-session";
4
- readonly version = "1.14.1";
4
+ readonly version = "1.14.2";
5
5
  private notifiedSession;
6
6
  private sendSessionStartEvent;
7
7
  private createInitialSession;
@@ -0,0 +1,7 @@
1
+ export declare const MESSAGE_TYPE_RESOURCE_ENTRY = "resource-entry";
2
+ export declare const MESSAGE_TYPE_HTTP_REQUEST_START = "http-request-start";
3
+ export declare const MESSAGE_TYPE_HTTP_REQUEST_END = "http-request-end";
4
+ export declare const MESSAGE_TYPE_HTTP_REQUEST_PENDING = "http-request-pending";
5
+ export declare const MESSAGE_TYPE_DOM_MUTATION = "dom-mutation";
6
+ export declare const userActionDataAttributeParsed = "faroUserActionName";
7
+ export declare const userActionDataAttribute = "data-faro-user-action-name";
@@ -0,0 +1,2 @@
1
+ import { Observable } from '@grafana/faro-core';
2
+ export declare function monitorDomMutations(): Observable;
@@ -0,0 +1,5 @@
1
+ import { Observable } from '@grafana/faro-core';
2
+ /**
3
+ * Monitors if any http requests are in progress.
4
+ */
5
+ export declare function monitorHttpRequests(): Observable;
@@ -0,0 +1,3 @@
1
+ export { UserActionInstrumentation } from './instrumentation';
2
+ export type { DomMutationMessage, HttpRequestEndMessage, HttpRequestStartMessage } from './types';
3
+ export { MESSAGE_TYPE_DOM_MUTATION, MESSAGE_TYPE_HTTP_REQUEST_END, MESSAGE_TYPE_HTTP_REQUEST_START, userActionDataAttribute, } from './const';
@@ -0,0 +1,6 @@
1
+ import { BaseInstrumentation } from '@grafana/faro-core';
2
+ export declare class UserActionInstrumentation extends BaseInstrumentation {
3
+ readonly name = "@grafana/faro-web-sdk:instrumentation-user-action";
4
+ readonly version = "1.14.2";
5
+ initialize(): void;
6
+ }
@@ -0,0 +1,2 @@
1
+ import { Observable } from '@grafana/faro-core';
2
+ export declare function monitorPerformanceEntries(): Observable;
@@ -0,0 +1,2 @@
1
+ import { Faro } from '@grafana/faro-core';
2
+ export declare function getUserEventHandler(faro: Faro): (event: PointerEvent | KeyboardEvent) => void;
@@ -0,0 +1,12 @@
1
+ import type { MESSAGE_TYPE_DOM_MUTATION, MESSAGE_TYPE_HTTP_REQUEST_END, MESSAGE_TYPE_HTTP_REQUEST_START } from './const';
2
+ export type DomMutationMessage = {
3
+ type: typeof MESSAGE_TYPE_DOM_MUTATION;
4
+ };
5
+ export type HttpRequestStartMessage = {
6
+ type: typeof MESSAGE_TYPE_HTTP_REQUEST_START;
7
+ pending: number;
8
+ };
9
+ export type HttpRequestEndMessage = {
10
+ type: typeof MESSAGE_TYPE_HTTP_REQUEST_END;
11
+ pending: number;
12
+ };
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Parses the action attribute name by removing the 'data-' prefix and converting
3
+ * the remaining string to camelCase.
4
+ *
5
+ * This is needed because the browser will remove the 'data-' prefix and the dashes from
6
+ * data attributes and make then camelCase.
7
+ */
8
+ export declare function convertDataAttributeName(userActionDataAttribute: string): string | undefined;
@@ -1,7 +1,7 @@
1
1
  import { BaseInstrumentation } from '@grafana/faro-core';
2
2
  export declare class ViewInstrumentation extends BaseInstrumentation {
3
3
  readonly name = "@grafana/faro-web-sdk:instrumentation-view";
4
- readonly version = "1.14.1";
4
+ readonly version = "1.14.2";
5
5
  private notifiedView;
6
6
  private sendViewChangedEvent;
7
7
  initialize(): void;
@@ -1,7 +1,7 @@
1
1
  import { BaseInstrumentation } from '@grafana/faro-core';
2
2
  export declare class WebVitalsInstrumentation extends BaseInstrumentation {
3
3
  readonly name = "@grafana/faro-web-sdk:instrumentation-web-vitals";
4
- readonly version = "1.14.1";
4
+ readonly version = "1.14.2";
5
5
  initialize(): void;
6
6
  private intializeWebVitalsInstrumentation;
7
7
  }
@@ -4,7 +4,7 @@ import type { ConsoleTransportOptions } from './types';
4
4
  export declare class ConsoleTransport extends BaseTransport {
5
5
  private options;
6
6
  readonly name = "@grafana/faro-web-sdk:transport-console";
7
- readonly version = "1.14.1";
7
+ readonly version = "1.14.2";
8
8
  constructor(options?: ConsoleTransportOptions);
9
9
  send(item: TransportItem): void;
10
10
  }
@@ -4,7 +4,7 @@ import type { FetchTransportOptions } from './types';
4
4
  export declare class FetchTransport extends BaseTransport {
5
5
  private options;
6
6
  readonly name = "@grafana/faro-web-sdk:transport-fetch";
7
- readonly version = "1.14.1";
7
+ readonly version = "1.14.2";
8
8
  promiseBuffer: PromiseBuffer<Response | void>;
9
9
  private readonly rateLimitBackoffMs;
10
10
  private readonly getNow;
@@ -1,3 +1,3 @@
1
- export { isLocalStorageAvailable, isSessionStorageAvailable, webStorageType, getItem, isWebStorageAvailable, removeItem, setItem, } from './webStorage';
1
+ export { getItem, isLocalStorageAvailable, isSessionStorageAvailable, isWebStorageAvailable, removeItem, setItem, webStorageType, } from './webStorage';
2
2
  export { throttle } from './throttle';
3
3
  export { getIgnoreUrls } from './url';
@@ -1,4 +1,14 @@
1
+ import type { Patterns } from '@grafana/faro-core';
1
2
  /**
2
- * Get all configured ignore URLs.
3
+ * Retrieves a list of URLs to be ignored by aggregating the ignore URLs from all transports.
4
+ *
5
+ * @returns {string[]} An array of URLs to be ignored.
3
6
  */
4
- export declare function getIgnoreUrls(): (string | RegExp)[];
7
+ export declare function getIgnoreUrls(): Patterns;
8
+ /**
9
+ * Checks if the given URL should be ignored based on a list of ignored URLs.
10
+ *
11
+ * @param url - The URL to check.
12
+ * @returns `true` if the URL is in the list of ignored URLs, `false` otherwise.
13
+ */
14
+ export declare function isUrlIgnored(url?: string): boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@grafana/faro-web-sdk",
3
- "version": "1.14.1",
3
+ "version": "1.14.2",
4
4
  "description": "Faro instrumentations, metas, transports for web.",
5
5
  "engines": {
6
6
  "node": ">=18.0.0"
@@ -55,7 +55,7 @@
55
55
  "quality:circular-deps": "madge --circular ."
56
56
  },
57
57
  "dependencies": {
58
- "@grafana/faro-core": "^1.14.1",
58
+ "@grafana/faro-core": "^1.14.2",
59
59
  "ua-parser-js": "^1.0.32",
60
60
  "web-vitals": "^4.0.1"
61
61
  },
@@ -67,5 +67,5 @@
67
67
  "publishConfig": {
68
68
  "access": "public"
69
69
  },
70
- "gitHead": "b44d0c2a52419786a497fbf3f47b781d27cc0982"
70
+ "gitHead": "b115e12fe1242e502d57ef5f8439a326a80dd6b7"
71
71
  }