@newrelic/browser-agent 1.262.0 → 1.264.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.
Files changed (259) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/README.md +2 -2
  3. package/dist/cjs/cdn/experimental.js +3 -7
  4. package/dist/cjs/cdn/pro.js +2 -2
  5. package/dist/cjs/cdn/spa.js +2 -2
  6. package/dist/cjs/common/aggregate/aggregator.js +3 -3
  7. package/dist/cjs/common/config/state/configurable.js +4 -4
  8. package/dist/cjs/common/config/state/init.js +11 -6
  9. package/dist/cjs/common/constants/env.cdn.js +1 -1
  10. package/dist/cjs/common/constants/env.npm.js +1 -1
  11. package/dist/cjs/common/constants/runtime.js +1 -3
  12. package/dist/cjs/common/context/shared-context.js +2 -2
  13. package/dist/cjs/common/drain/drain.js +5 -5
  14. package/dist/cjs/common/harvest/harvest.js +3 -3
  15. package/dist/cjs/common/serialize/bel-serializer.js +2 -2
  16. package/dist/cjs/common/session/session-entity.js +3 -3
  17. package/dist/cjs/common/timing/time-keeper.js +13 -2
  18. package/dist/cjs/common/url/encode.js +3 -5
  19. package/dist/cjs/common/util/console.js +3 -4
  20. package/dist/cjs/common/util/obfuscate.js +3 -3
  21. package/dist/cjs/common/util/submit-data.js +0 -1
  22. package/dist/cjs/common/vitals/vital-metric.js +1 -1
  23. package/dist/cjs/common/wrap/wrap-logger.js +1 -2
  24. package/dist/cjs/common/wrap/wrap-xhr.js +1 -1
  25. package/dist/cjs/features/ajax/aggregate/index.js +1 -1
  26. package/dist/cjs/features/ajax/instrument/index.js +1 -1
  27. package/dist/cjs/features/generic_events/aggregate/index.js +137 -0
  28. package/dist/cjs/features/generic_events/constants.js +8 -0
  29. package/dist/cjs/features/generic_events/index.js +12 -0
  30. package/dist/cjs/features/generic_events/instrument/index.js +27 -0
  31. package/dist/cjs/features/jserrors/aggregate/index.js +13 -12
  32. package/dist/cjs/features/jserrors/instrument/index.js +1 -1
  33. package/dist/cjs/features/logging/aggregate/index.js +6 -6
  34. package/dist/cjs/features/logging/constants.js +2 -5
  35. package/dist/cjs/features/logging/instrument/index.js +1 -1
  36. package/dist/cjs/features/metrics/aggregate/index.js +17 -1
  37. package/dist/cjs/features/metrics/instrument/index.js +1 -1
  38. package/dist/cjs/features/page_action/instrument/index.js +6 -6
  39. package/dist/cjs/features/page_view_event/aggregate/index.js +21 -5
  40. package/dist/cjs/features/page_view_event/aggregate/initialized-features.js +1 -1
  41. package/dist/cjs/features/page_view_event/instrument/index.js +1 -1
  42. package/dist/cjs/features/page_view_timing/aggregate/index.js +3 -3
  43. package/dist/cjs/features/page_view_timing/instrument/index.js +1 -1
  44. package/dist/cjs/features/session_replay/aggregate/index.js +3 -3
  45. package/dist/cjs/features/session_replay/instrument/index.js +1 -1
  46. package/dist/cjs/features/session_replay/shared/recorder.js +1 -1
  47. package/dist/cjs/features/session_replay/shared/stylesheet-evaluator.js +1 -1
  48. package/dist/cjs/features/session_trace/aggregate/index.js +1 -1
  49. package/dist/cjs/features/session_trace/aggregate/trace/storage.js +2 -2
  50. package/dist/cjs/features/session_trace/instrument/index.js +1 -1
  51. package/dist/cjs/features/soft_navigations/aggregate/bel-node.js +1 -1
  52. package/dist/cjs/features/soft_navigations/aggregate/index.js +1 -1
  53. package/dist/cjs/features/soft_navigations/aggregate/interaction.js +5 -5
  54. package/dist/cjs/features/soft_navigations/instrument/index.js +1 -1
  55. package/dist/cjs/features/spa/aggregate/index.js +3 -4
  56. package/dist/cjs/features/spa/aggregate/interaction.js +2 -2
  57. package/dist/cjs/features/spa/aggregate/serializer.js +1 -2
  58. package/dist/cjs/features/spa/instrument/index.js +1 -1
  59. package/dist/cjs/features/utils/aggregate-base.js +6 -3
  60. package/dist/cjs/features/utils/instrument-base.js +2 -2
  61. package/dist/cjs/features/utils/lazy-feature-loader.js +2 -2
  62. package/dist/cjs/index.js +21 -0
  63. package/dist/cjs/loaders/agent-base.js +1 -5
  64. package/dist/cjs/loaders/agent.js +3 -4
  65. package/dist/cjs/loaders/api/api.js +10 -8
  66. package/dist/cjs/loaders/api/apiAsync.js +1 -1
  67. package/dist/cjs/loaders/browser-agent.js +4 -3
  68. package/dist/cjs/loaders/configure/configure.js +4 -3
  69. package/dist/cjs/loaders/features/features.js +8 -4
  70. package/dist/cjs/loaders/micro-agent.js +6 -6
  71. package/dist/esm/cdn/experimental.js +2 -5
  72. package/dist/esm/cdn/pro.js +2 -2
  73. package/dist/esm/cdn/spa.js +2 -2
  74. package/dist/esm/common/aggregate/aggregator.js +3 -3
  75. package/dist/esm/common/config/state/configurable.js +4 -4
  76. package/dist/esm/common/config/state/init.js +11 -6
  77. package/dist/esm/common/constants/env.cdn.js +1 -1
  78. package/dist/esm/common/constants/env.npm.js +1 -1
  79. package/dist/esm/common/constants/runtime.js +0 -2
  80. package/dist/esm/common/context/shared-context.js +2 -2
  81. package/dist/esm/common/drain/drain.js +5 -5
  82. package/dist/esm/common/harvest/harvest.js +4 -4
  83. package/dist/esm/common/serialize/bel-serializer.js +2 -2
  84. package/dist/esm/common/session/session-entity.js +4 -4
  85. package/dist/esm/common/timing/time-keeper.js +12 -2
  86. package/dist/esm/common/url/encode.js +3 -5
  87. package/dist/esm/common/util/console.js +3 -4
  88. package/dist/esm/common/util/obfuscate.js +3 -3
  89. package/dist/esm/common/util/submit-data.js +0 -1
  90. package/dist/esm/common/vitals/vital-metric.js +1 -1
  91. package/dist/esm/common/wrap/wrap-logger.js +1 -2
  92. package/dist/esm/common/wrap/wrap-xhr.js +1 -1
  93. package/dist/esm/features/ajax/aggregate/index.js +1 -1
  94. package/dist/esm/features/ajax/instrument/index.js +1 -1
  95. package/dist/esm/features/generic_events/aggregate/index.js +129 -0
  96. package/dist/esm/features/generic_events/constants.js +2 -0
  97. package/dist/esm/features/generic_events/index.js +1 -0
  98. package/dist/esm/features/generic_events/instrument/index.js +20 -0
  99. package/dist/esm/features/jserrors/aggregate/index.js +13 -12
  100. package/dist/esm/features/jserrors/instrument/index.js +1 -1
  101. package/dist/esm/features/logging/aggregate/index.js +7 -7
  102. package/dist/esm/features/logging/constants.js +1 -4
  103. package/dist/esm/features/logging/instrument/index.js +1 -1
  104. package/dist/esm/features/metrics/aggregate/index.js +17 -1
  105. package/dist/esm/features/metrics/instrument/index.js +1 -1
  106. package/dist/esm/features/page_action/instrument/index.js +7 -6
  107. package/dist/esm/features/page_view_event/aggregate/index.js +22 -6
  108. package/dist/esm/features/page_view_event/aggregate/initialized-features.js +1 -1
  109. package/dist/esm/features/page_view_event/instrument/index.js +1 -1
  110. package/dist/esm/features/page_view_timing/aggregate/index.js +3 -3
  111. package/dist/esm/features/page_view_timing/instrument/index.js +1 -1
  112. package/dist/esm/features/session_replay/aggregate/index.js +3 -3
  113. package/dist/esm/features/session_replay/instrument/index.js +1 -1
  114. package/dist/esm/features/session_replay/shared/recorder.js +1 -1
  115. package/dist/esm/features/session_replay/shared/stylesheet-evaluator.js +1 -1
  116. package/dist/esm/features/session_trace/aggregate/index.js +1 -1
  117. package/dist/esm/features/session_trace/aggregate/trace/storage.js +2 -2
  118. package/dist/esm/features/session_trace/instrument/index.js +1 -1
  119. package/dist/esm/features/soft_navigations/aggregate/bel-node.js +1 -1
  120. package/dist/esm/features/soft_navigations/aggregate/index.js +1 -1
  121. package/dist/esm/features/soft_navigations/aggregate/interaction.js +5 -5
  122. package/dist/esm/features/soft_navigations/instrument/index.js +1 -1
  123. package/dist/esm/features/spa/aggregate/index.js +3 -4
  124. package/dist/esm/features/spa/aggregate/interaction.js +2 -2
  125. package/dist/esm/features/spa/aggregate/serializer.js +1 -2
  126. package/dist/esm/features/spa/instrument/index.js +1 -1
  127. package/dist/esm/features/utils/aggregate-base.js +7 -4
  128. package/dist/esm/features/utils/instrument-base.js +2 -2
  129. package/dist/esm/features/utils/lazy-feature-loader.js +2 -2
  130. package/dist/esm/index.js +3 -0
  131. package/dist/esm/loaders/agent-base.js +1 -5
  132. package/dist/esm/loaders/agent.js +3 -4
  133. package/dist/esm/loaders/api/api.js +10 -8
  134. package/dist/esm/loaders/api/apiAsync.js +1 -1
  135. package/dist/esm/loaders/browser-agent.js +3 -2
  136. package/dist/esm/loaders/configure/configure.js +4 -3
  137. package/dist/esm/loaders/features/features.js +8 -4
  138. package/dist/esm/loaders/micro-agent.js +6 -6
  139. package/dist/types/common/aggregate/aggregator.d.ts.map +1 -1
  140. package/dist/types/common/config/state/init.d.ts.map +1 -1
  141. package/dist/types/common/constants/runtime.d.ts +0 -1
  142. package/dist/types/common/constants/runtime.d.ts.map +1 -1
  143. package/dist/types/common/drain/drain.d.ts.map +1 -1
  144. package/dist/types/common/serialize/bel-serializer.d.ts.map +1 -1
  145. package/dist/types/common/timing/time-keeper.d.ts +2 -1
  146. package/dist/types/common/timing/time-keeper.d.ts.map +1 -1
  147. package/dist/types/common/url/encode.d.ts.map +1 -1
  148. package/dist/types/common/util/console.d.ts +1 -1
  149. package/dist/types/common/util/console.d.ts.map +1 -1
  150. package/dist/types/common/util/submit-data.d.ts.map +1 -1
  151. package/dist/types/common/wrap/wrap-logger.d.ts.map +1 -1
  152. package/dist/types/features/{page_action → generic_events}/aggregate/index.d.ts +7 -5
  153. package/dist/types/features/generic_events/aggregate/index.d.ts.map +1 -0
  154. package/dist/types/features/generic_events/constants.d.ts +2 -0
  155. package/dist/types/features/generic_events/constants.d.ts.map +1 -0
  156. package/dist/types/features/generic_events/index.d.ts +2 -0
  157. package/dist/types/features/generic_events/index.d.ts.map +1 -0
  158. package/dist/types/features/generic_events/instrument/index.d.ts +6 -0
  159. package/dist/types/features/generic_events/instrument/index.d.ts.map +1 -0
  160. package/dist/types/features/jserrors/aggregate/index.d.ts.map +1 -1
  161. package/dist/types/features/logging/constants.d.ts +0 -3
  162. package/dist/types/features/logging/constants.d.ts.map +1 -1
  163. package/dist/types/features/metrics/aggregate/index.d.ts.map +1 -1
  164. package/dist/types/features/page_action/instrument/index.d.ts +5 -4
  165. package/dist/types/features/page_action/instrument/index.d.ts.map +1 -1
  166. package/dist/types/features/page_view_event/aggregate/index.d.ts.map +1 -1
  167. package/dist/types/features/page_view_timing/aggregate/index.d.ts.map +1 -1
  168. package/dist/types/features/session_replay/shared/recorder.d.ts.map +1 -1
  169. package/dist/types/features/spa/aggregate/index.d.ts.map +1 -1
  170. package/dist/types/features/spa/aggregate/interaction.d.ts.map +1 -1
  171. package/dist/types/features/spa/aggregate/serializer.d.ts.map +1 -1
  172. package/dist/types/features/utils/aggregate-base.d.ts.map +1 -1
  173. package/dist/types/index.d.ts +3 -0
  174. package/dist/types/loaders/agent-base.d.ts +0 -1
  175. package/dist/types/loaders/agent-base.d.ts.map +1 -1
  176. package/dist/types/loaders/agent.d.ts.map +1 -1
  177. package/dist/types/loaders/api/api.d.ts.map +1 -1
  178. package/dist/types/loaders/browser-agent.d.ts.map +1 -1
  179. package/dist/types/loaders/configure/configure.d.ts.map +1 -1
  180. package/dist/types/loaders/features/features.d.ts +1 -0
  181. package/dist/types/loaders/features/features.d.ts.map +1 -1
  182. package/package.json +25 -6
  183. package/src/cdn/experimental.js +2 -4
  184. package/src/cdn/pro.js +2 -2
  185. package/src/cdn/spa.js +2 -2
  186. package/src/common/aggregate/aggregator.js +2 -3
  187. package/src/common/config/state/configurable.js +4 -4
  188. package/src/common/config/state/init.js +6 -4
  189. package/src/common/constants/runtime.js +0 -2
  190. package/src/common/context/shared-context.js +2 -2
  191. package/src/common/drain/drain.js +4 -5
  192. package/src/common/harvest/harvest.js +4 -4
  193. package/src/common/serialize/bel-serializer.js +1 -2
  194. package/src/common/session/session-entity.js +4 -4
  195. package/src/common/timing/time-keeper.js +14 -2
  196. package/src/common/url/encode.js +2 -3
  197. package/src/common/util/console.js +3 -4
  198. package/src/common/util/obfuscate.js +3 -3
  199. package/src/common/util/submit-data.js +0 -1
  200. package/src/common/wrap/wrap-logger.js +1 -2
  201. package/src/common/wrap/wrap-xhr.js +1 -1
  202. package/src/features/generic_events/aggregate/index.js +133 -0
  203. package/src/features/generic_events/constants.js +3 -0
  204. package/src/features/generic_events/index.js +1 -0
  205. package/src/features/generic_events/instrument/index.js +22 -0
  206. package/src/features/jserrors/aggregate/index.js +4 -5
  207. package/src/features/logging/aggregate/index.js +6 -6
  208. package/src/features/logging/constants.js +0 -4
  209. package/src/features/metrics/aggregate/index.js +12 -0
  210. package/src/features/page_action/instrument/index.js +6 -6
  211. package/src/features/page_view_event/aggregate/index.js +22 -5
  212. package/src/features/page_view_event/aggregate/initialized-features.js +1 -1
  213. package/src/features/page_view_timing/aggregate/index.js +1 -2
  214. package/src/features/session_replay/aggregate/index.js +1 -1
  215. package/src/features/session_replay/shared/recorder.js +1 -1
  216. package/src/features/spa/aggregate/index.js +2 -3
  217. package/src/features/spa/aggregate/interaction.js +1 -2
  218. package/src/features/spa/aggregate/serializer.js +1 -2
  219. package/src/features/utils/aggregate-base.js +7 -4
  220. package/src/features/utils/instrument-base.js +2 -2
  221. package/src/features/utils/lazy-feature-loader.js +2 -2
  222. package/src/index.js +3 -0
  223. package/src/loaders/agent-base.js +1 -5
  224. package/src/loaders/agent.js +3 -4
  225. package/src/loaders/api/api.js +10 -8
  226. package/src/loaders/api/apiAsync.js +1 -1
  227. package/src/loaders/browser-agent.js +5 -3
  228. package/src/loaders/configure/configure.js +5 -1
  229. package/src/loaders/features/features.js +8 -4
  230. package/src/loaders/micro-agent.js +6 -6
  231. package/dist/cjs/cdn/polyfills/lite.js +0 -16
  232. package/dist/cjs/cdn/polyfills/pro.js +0 -21
  233. package/dist/cjs/cdn/polyfills/spa.js +0 -22
  234. package/dist/cjs/cdn/polyfills.js +0 -24
  235. package/dist/cjs/common/util/map-own.js +0 -31
  236. package/dist/cjs/features/page_action/aggregate/index.js +0 -121
  237. package/dist/esm/cdn/polyfills/lite.js +0 -14
  238. package/dist/esm/cdn/polyfills/pro.js +0 -19
  239. package/dist/esm/cdn/polyfills/spa.js +0 -20
  240. package/dist/esm/cdn/polyfills.js +0 -27
  241. package/dist/esm/common/util/map-own.js +0 -24
  242. package/dist/esm/features/page_action/aggregate/index.js +0 -114
  243. package/dist/types/cdn/polyfills/lite.d.ts +0 -2
  244. package/dist/types/cdn/polyfills/lite.d.ts.map +0 -1
  245. package/dist/types/cdn/polyfills/pro.d.ts +0 -2
  246. package/dist/types/cdn/polyfills/pro.d.ts.map +0 -1
  247. package/dist/types/cdn/polyfills/spa.d.ts +0 -2
  248. package/dist/types/cdn/polyfills/spa.d.ts.map +0 -1
  249. package/dist/types/cdn/polyfills.d.ts +0 -2
  250. package/dist/types/cdn/polyfills.d.ts.map +0 -1
  251. package/dist/types/common/util/map-own.d.ts +0 -3
  252. package/dist/types/common/util/map-own.d.ts.map +0 -1
  253. package/dist/types/features/page_action/aggregate/index.d.ts.map +0 -1
  254. package/src/cdn/polyfills/lite.js +0 -20
  255. package/src/cdn/polyfills/pro.js +0 -30
  256. package/src/cdn/polyfills/spa.js +0 -32
  257. package/src/cdn/polyfills.js +0 -27
  258. package/src/common/util/map-own.js +0 -22
  259. package/src/features/page_action/aggregate/index.js +0 -114
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@newrelic/browser-agent",
3
- "version": "1.262.0",
3
+ "version": "1.264.0",
4
4
  "private": false,
5
5
  "author": "New Relic Browser Agent Team <browser-agent@newrelic.com>",
6
6
  "description": "New Relic Browser Agent",
@@ -44,6 +44,9 @@
44
44
  "features/page_action": [
45
45
  "dist/types/features/page_action/index.d.ts"
46
46
  ],
47
+ "features/generic_events": [
48
+ "dist/types/features/generic_events/index.d.ts"
49
+ ],
47
50
  "features/page_view_event": [
48
51
  "dist/types/features/page_view_event/index.d.ts"
49
52
  ],
@@ -53,6 +56,9 @@
53
56
  "features/session_trace": [
54
57
  "dist/types/features/session_trace/index.d.ts"
55
58
  ],
59
+ "features/session_replay": [
60
+ "dist/types/features/session_replay/index.d.ts"
61
+ ],
56
62
  "features/spa": [
57
63
  "dist/types/features/spa/index.d.ts"
58
64
  ]
@@ -89,6 +95,11 @@
89
95
  "require": "./dist/cjs/features/ajax/index.js",
90
96
  "default": "./dist/esm/features/ajax/index.js"
91
97
  },
98
+ "./features/generic_events": {
99
+ "types": "./dist/types/features/generic_events/index.d.ts",
100
+ "require": "./dist/cjs/features/generic_events/index.js",
101
+ "default": "./dist/esm/features/generic_events/index.js"
102
+ },
92
103
  "./features/jserrors": {
93
104
  "types": "./dist/types/features/jserrors/index.d.ts",
94
105
  "require": "./dist/cjs/features/jserrors/index.js",
@@ -119,11 +130,21 @@
119
130
  "require": "./dist/cjs/features/page_view_timing/index.js",
120
131
  "default": "./dist/esm/features/page_view_timing/index.js"
121
132
  },
133
+ "./features/session_replay": {
134
+ "types": "./dist/types/features/session_replay/index.d.ts",
135
+ "require": "./dist/cjs/features/session_replay/index.js",
136
+ "default": "./dist/esm/features/session_replay/index.js"
137
+ },
122
138
  "./features/session_trace": {
123
139
  "types": "./dist/types/features/session_trace/index.d.ts",
124
140
  "require": "./dist/cjs/features/session_trace/index.js",
125
141
  "default": "./dist/esm/features/session_trace/index.js"
126
142
  },
143
+ "./features/soft_navigations": {
144
+ "types": "./dist/types/features/soft_navigations/index.d.ts",
145
+ "require": "./dist/cjs/features/soft_navigations/index.js",
146
+ "default": "./dist/esm/features/soft_navigations/index.js"
147
+ },
127
148
  "./features/spa": {
128
149
  "types": "./dist/types/features/spa/index.d.ts",
129
150
  "require": "./dist/cjs/features/spa/index.js",
@@ -170,10 +191,9 @@
170
191
  "url": "https://github.com/newrelic/newrelic-browser-agent.git"
171
192
  },
172
193
  "dependencies": {
173
- "core-js": "^3.26.0",
174
- "fflate": "^0.7.4",
194
+ "fflate": "0.7.4",
175
195
  "rrweb": "2.0.0-alpha.12",
176
- "web-vitals": "^3.1.0"
196
+ "web-vitals": "3.5.2"
177
197
  },
178
198
  "devDependencies": {
179
199
  "@babel/cli": "^7.23.4",
@@ -184,7 +204,6 @@
184
204
  "@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6",
185
205
  "@babel/plugin-proposal-optional-chaining": "^7.21.0",
186
206
  "@babel/plugin-proposal-private-methods": "^7.18.6",
187
- "@babel/plugin-syntax-import-assertions": "^7.23.3",
188
207
  "@babel/preset-env": "^7.23.8",
189
208
  "@babel/register": "^7.23.7",
190
209
  "@faker-js/faker": "^8.3.1",
@@ -235,7 +254,7 @@
235
254
  "util": "^0.12.5",
236
255
  "uuid": "^9.0.1",
237
256
  "wait-on": "^7.2.0",
238
- "wdio-lambdatest-service": "^2.1.3",
257
+ "wdio-lambdatest-service": "^3.0.0",
239
258
  "webpack": "^5.89.0",
240
259
  "webpack-bundle-analyzer": "^4.10.1",
241
260
  "webpack-cli": "^5.1.4",
@@ -17,9 +17,8 @@ import { Instrument as InstrumentErrors } from '../features/jserrors/instrument'
17
17
  import { Instrument as InstrumentXhr } from '../features/ajax/instrument'
18
18
  import { Instrument as InstrumentSessionTrace } from '../features/session_trace/instrument'
19
19
  import { Instrument as InstrumentSessionReplay } from '../features/session_replay/instrument'
20
- // import { Instrument as InstrumentSpa } from '../features/spa/instrument'
20
+ import { Instrument as InstrumentGenericEvents } from '../features/generic_events/instrument'
21
21
  import { Instrument as InstrumentSoftNav } from '../features/soft_navigations/instrument'
22
- import { Instrument as InstrumentPageAction } from '../features/page_action/instrument'
23
22
  import { Instrument as InstrumentLogs } from '../features/logging/instrument'
24
23
 
25
24
  new Agent({
@@ -30,10 +29,9 @@ new Agent({
30
29
  InstrumentSessionTrace,
31
30
  InstrumentSessionReplay,
32
31
  InstrumentMetrics,
33
- InstrumentPageAction,
34
32
  InstrumentErrors,
33
+ InstrumentGenericEvents,
35
34
  InstrumentLogs,
36
- // InstrumentSpa,
37
35
  InstrumentSoftNav
38
36
  ],
39
37
  loaderType: 'experimental'
package/src/cdn/pro.js CHANGED
@@ -12,7 +12,7 @@ import { Instrument as InstrumentErrors } from '../features/jserrors/instrument'
12
12
  import { Instrument as InstrumentXhr } from '../features/ajax/instrument'
13
13
  import { Instrument as InstrumentSessionTrace } from '../features/session_trace/instrument'
14
14
  import { Instrument as InstrumentSessionReplay } from '../features/session_replay/instrument'
15
- import { Instrument as InstrumentPageAction } from '../features/page_action/instrument'
15
+ import { Instrument as InstrumentGenericEvents } from '../features/generic_events/instrument'
16
16
  import { Instrument as InstrumentLogs } from '../features/logging/instrument'
17
17
 
18
18
  new Agent({
@@ -23,8 +23,8 @@ new Agent({
23
23
  InstrumentSessionReplay,
24
24
  InstrumentXhr,
25
25
  InstrumentMetrics,
26
- InstrumentPageAction,
27
26
  InstrumentErrors,
27
+ InstrumentGenericEvents,
28
28
  InstrumentLogs
29
29
  ],
30
30
  loaderType: 'pro'
package/src/cdn/spa.js CHANGED
@@ -13,7 +13,7 @@ import { Instrument as InstrumentSessionTrace } from '../features/session_trace/
13
13
  import { Instrument as InstrumentSessionReplay } from '../features/session_replay/instrument'
14
14
  import { Instrument as InstrumentSoftNav } from '../features/soft_navigations/instrument'
15
15
  import { Instrument as InstrumentSpa } from '../features/spa/instrument'
16
- import { Instrument as InstrumentPageAction } from '../features/page_action/instrument'
16
+ import { Instrument as InstrumentGenericEvents } from '../features/generic_events/instrument'
17
17
  import { Instrument as InstrumentLogs } from '../features/logging/instrument'
18
18
 
19
19
  new Agent({
@@ -24,8 +24,8 @@ new Agent({
24
24
  InstrumentSessionTrace,
25
25
  InstrumentSessionReplay,
26
26
  InstrumentMetrics,
27
- InstrumentPageAction,
28
27
  InstrumentErrors,
28
+ InstrumentGenericEvents,
29
29
  InstrumentLogs,
30
30
  InstrumentSoftNav,
31
31
  InstrumentSpa // either the softnav or the old spa will be used (not both), but we still need to pack both to avoid dynamic import for instrument files
@@ -4,7 +4,6 @@
4
4
  */
5
5
 
6
6
  import { SharedContext } from '../context/shared-context'
7
- import { mapOwn } from '../util/map-own'
8
7
 
9
8
  export class Aggregator extends SharedContext {
10
9
  constructor (parent) {
@@ -34,7 +33,7 @@ export class Aggregator extends SharedContext {
34
33
  oldMetrics.count += metrics.count
35
34
 
36
35
  // iterate through each new metric and merge
37
- mapOwn(metrics, function (key, value) {
36
+ Object.keys(metrics || {}).forEach((key) => {
38
37
  // count is a special case handled above
39
38
  if (key === 'count') return
40
39
 
@@ -94,7 +93,7 @@ export class Aggregator extends SharedContext {
94
93
  function aggregateMetrics (newMetrics, oldMetrics) {
95
94
  if (!oldMetrics) oldMetrics = { count: 0 }
96
95
  oldMetrics.count += 1
97
- mapOwn(newMetrics, function (key, value) {
96
+ Object.entries(newMetrics || {}).forEach(([key, value]) => {
98
97
  oldMetrics[key] = updateMetric(value, oldMetrics[key])
99
98
  })
100
99
  return oldMetrics
@@ -2,8 +2,8 @@ import { warn } from '../../util/console'
2
2
 
3
3
  export function getModeledObject (obj, model) {
4
4
  try {
5
- if (!obj || typeof obj !== 'object') return warn('Setting a Configurable requires an object as input')
6
- if (!model || typeof model !== 'object') return warn('Setting a Configurable requires a model to set its initial properties')
5
+ if (!obj || typeof obj !== 'object') return warn(3)
6
+ if (!model || typeof model !== 'object') return warn(4)
7
7
  // allow getters and setters to pass from model to target
8
8
  const output = Object.create(
9
9
  Object.getPrototypeOf(model),
@@ -19,11 +19,11 @@ export function getModeledObject (obj, model) {
19
19
  else if (typeof obj[key] === 'object' && typeof model[key] === 'object') output[key] = getModeledObject(obj[key], model[key])
20
20
  else output[key] = obj[key]
21
21
  } catch (e) {
22
- warn('An error occurred while setting a property of a Configurable', e)
22
+ warn(1, e)
23
23
  }
24
24
  }
25
25
  return output
26
26
  } catch (err) {
27
- warn('An error occured while setting a Configurable', err)
27
+ warn(2, err)
28
28
  }
29
29
  }
@@ -41,12 +41,13 @@ const model = () => {
41
41
  allowed_origins: undefined
42
42
  },
43
43
  feature_flags: [],
44
+ generic_events: { enabled: true, harvestTimeSeconds: 30, autoStart: true },
44
45
  harvest: { tooManyRequestsDelay: 60 },
45
46
  jserrors: { enabled: true, harvestTimeSeconds: 10, autoStart: true },
46
47
  logging: { enabled: true, harvestTimeSeconds: 10, autoStart: true, level: LOG_LEVELS.INFO },
47
48
  metrics: { enabled: true, autoStart: true },
48
49
  obfuscate: undefined,
49
- page_action: { enabled: true, harvestTimeSeconds: 30, autoStart: true },
50
+ page_action: { enabled: true },
50
51
  page_view_event: { enabled: true, autoStart: true },
51
52
  page_view_timing: { enabled: true, harvestTimeSeconds: 30, long_task: false, autoStart: true },
52
53
  privacy: { cookies_enabled: true }, // *cli - per discussion, default should be true
@@ -69,6 +70,7 @@ const model = () => {
69
70
  collect_fonts: false, // serialize fonts for collection without public asset url, this is currently broken in RRWeb -- https://github.com/rrweb-io/rrweb/issues/1304. When fixed, revisit with test cases
70
71
  inline_images: false, // serialize images for collection without public asset url -- right now this is only useful for testing as it easily generates payloads too large to be harvested
71
72
  inline_stylesheet: true, // serialize css for collection without public asset url
73
+ fix_stylesheets: true, // fetch missing stylesheet resources for inlining, only works if 'inline_stylesheet' is also true
72
74
  // recording config settings
73
75
  mask_all_inputs: true,
74
76
  // this has a getter/setter to facilitate validation of the selectors
@@ -76,7 +78,7 @@ const model = () => {
76
78
  set mask_text_selector (val) {
77
79
  if (isValidSelector(val)) hiddenState.mask_selector = `${val},${nrMask}`
78
80
  else if (val === '' || val === null) hiddenState.mask_selector = nrMask
79
- else warn('An invalid session_replay.mask_selector was provided. \'*\' will be used.', val)
81
+ else warn(5, val)
80
82
  },
81
83
  // these properties only have getters because they are enforcable constants and should error if someone tries to override them
82
84
  get block_class () { return 'nr-block' },
@@ -89,7 +91,7 @@ const model = () => {
89
91
  },
90
92
  set block_selector (val) {
91
93
  if (isValidSelector(val)) hiddenState.block_selector += `,${val}`
92
- else if (val !== '') warn('An invalid session_replay.block_selector was provided and will not be used', val)
94
+ else if (val !== '') warn(6, val)
93
95
  },
94
96
  // password: must always be present and true no matter what customer sets
95
97
  get mask_input_options () {
@@ -97,7 +99,7 @@ const model = () => {
97
99
  },
98
100
  set mask_input_options (val) {
99
101
  if (val && typeof val === 'object') hiddenState.mask_input_options = { ...val, password: true }
100
- else warn('An invalid session_replay.mask_input_option was provided and will not be used', val)
102
+ else warn(7, val)
101
103
  }
102
104
  },
103
105
  session_trace: { enabled: true, harvestTimeSeconds: 10, autoStart: true },
@@ -72,8 +72,6 @@ export const ffVersion = (() => {
72
72
  return 0
73
73
  })()
74
74
 
75
- export const isIE = Boolean(isBrowserScope && window.document.documentMode) // deprecated property that only works in IE
76
-
77
75
  export const supportsSendBeacon = !!globalScope.navigator?.sendBeacon
78
76
 
79
77
  /**
@@ -8,14 +8,14 @@ const model = {
8
8
  export class SharedContext {
9
9
  constructor (context) {
10
10
  try {
11
- if (typeof context !== 'object') return warn('shared context requires an object as input')
11
+ if (typeof context !== 'object') return warn(8)
12
12
  this.sharedContext = {}
13
13
  Object.assign(this.sharedContext, model)
14
14
  Object.entries(context).forEach(([key, value]) => {
15
15
  if (Object.keys(model).includes(key)) this.sharedContext[key] = value
16
16
  })
17
17
  } catch (err) {
18
- warn('An error occurred while setting SharedContext', err)
18
+ warn(9, err)
19
19
  }
20
20
  }
21
21
  }
@@ -4,7 +4,6 @@
4
4
  */
5
5
 
6
6
  import { ee } from '../event-emitter/contextual-ee'
7
- import { mapOwn } from '../util/map-own'
8
7
  import { registerHandler as defaultRegister } from '../event-emitter/register-handler'
9
8
  import { featurePriority } from '../../loaders/features/features'
10
9
 
@@ -90,7 +89,7 @@ function checkCanDrainAll (agentIdentifier) {
90
89
  function drainGroup (agentIdentifier, group, activateGroup = true) {
91
90
  const baseEE = agentIdentifier ? ee.get(agentIdentifier) : ee
92
91
  const handlers = defaultRegister.handlers // other storage in registerHandler
93
- if (!baseEE.backlog || !handlers) return
92
+ if (baseEE.aborted || !baseEE.backlog || !handlers) return
94
93
 
95
94
  // Only activated features being drained should run queued listeners on buffered events. Deactivated features only need to release memory.
96
95
  if (activateGroup) {
@@ -102,8 +101,8 @@ function drainGroup (agentIdentifier, group, activateGroup = true) {
102
101
  emitEvent(bufferedEventsInGroup[i], groupHandlers)
103
102
  }
104
103
 
105
- mapOwn(groupHandlers, function (eventType, handlerRegistrationList) {
106
- mapOwn(handlerRegistrationList, function (i, registration) {
104
+ Object.entries(groupHandlers).forEach(([eventType, handlerRegistrationList]) => {
105
+ Object.values(handlerRegistrationList || {}).forEach((registration) => {
107
106
  // registration is an array of: [targetEE, eventHandler]
108
107
  registration[0].on(eventType, registration[1])
109
108
  })
@@ -125,7 +124,7 @@ function drainGroup (agentIdentifier, group, activateGroup = true) {
125
124
  */
126
125
  function emitEvent (evt, groupHandlers) {
127
126
  var type = evt[1]
128
- mapOwn(groupHandlers[type], function (i, registration) {
127
+ Object.values(groupHandlers[type] || {}).forEach((registration) => {
129
128
  var sourceEE = evt[0]
130
129
  var ee = registration[0]
131
130
  if (ee === sourceEE) {
@@ -14,7 +14,7 @@ import { Obfuscator } from '../util/obfuscate'
14
14
  import { applyFnToProps } from '../util/traverse'
15
15
  import { SharedContext } from '../context/shared-context'
16
16
  import { VERSION } from '../constants/env'
17
- import { isWorkerScope, isIE } from '../constants/runtime'
17
+ import { isWorkerScope } from '../constants/runtime'
18
18
  import { warn } from '../util/console'
19
19
  import { now } from '../timing/now'
20
20
 
@@ -122,7 +122,7 @@ export class Harvest extends SharedContext {
122
122
  body = stringify(body)
123
123
  }
124
124
  /** Warn --once per endpoint-- if the agent tries to send large payloads */
125
- if (body.length > 750000 && (warnings[endpoint] = (warnings?.[endpoint] || 0) + 1) === 1) warn(`The Browser Agent is attempting to send a very large payload to /${endpoint}. This is usually tied to large amounts of custom attributes. Please check your configurations.`)
125
+ if (body.length > 750000 && (warnings[endpoint] = (warnings?.[endpoint] || 0) + 1) === 1) warn(28, endpoint)
126
126
  }
127
127
 
128
128
  if (!body || body.length === 0 || body === '{}' || body === '[]') {
@@ -137,8 +137,8 @@ export class Harvest extends SharedContext {
137
137
  /* Since workers don't support sendBeacon right now, they can only use XHR method.
138
138
  Because they still do permit synch XHR, the idea is that at final harvest time (worker is closing),
139
139
  we just make a BLOCKING request--trivial impact--with the remaining data as a temp fill-in for sendBeacon.
140
- Following the removal of img-element method, IE will also use sync XHR on page dismissal to ensure final analytics are sent. */
141
- let result = submitMethod({ url: fullUrl, body, sync: opts.unload && (isWorkerScope || isIE), headers })
140
+ Following the removal of img-element method. */
141
+ let result = submitMethod({ url: fullUrl, body, sync: opts.unload && (isWorkerScope), headers })
142
142
 
143
143
  if (!opts.unload && cbFinished && submitMethod === submitData.xhr) {
144
144
  const harvestScope = this
@@ -3,7 +3,6 @@
3
3
  * SPDX-License-Identifier: Apache-2.0
4
4
  */
5
5
 
6
- import { mapOwn } from '../util/map-own'
7
6
  import { stringify } from '../util/stringify'
8
7
  import { Obfuscator } from '../util/obfuscate'
9
8
 
@@ -47,7 +46,7 @@ export function getAddStringContext (agentIdentifier) {
47
46
  export function addCustomAttributes (attrs, addString) {
48
47
  var attrParts = []
49
48
 
50
- mapOwn(attrs, function (key, val) {
49
+ Object.entries(attrs || {}).forEach(([key, val]) => {
51
50
  if (attrParts.length >= MAX_ATTRIBUTES) return
52
51
  var type = 5
53
52
  var serializedValue
@@ -3,7 +3,7 @@ import { warn } from '../util/console'
3
3
  import { stringify } from '../util/stringify'
4
4
  import { ee } from '../event-emitter/contextual-ee'
5
5
  import { Timer } from '../timer/timer'
6
- import { isBrowserScope, isIE } from '../constants/runtime'
6
+ import { isBrowserScope } from '../constants/runtime'
7
7
  import { DEFAULT_EXPIRES_MS, DEFAULT_INACTIVE_MS, MODE, PREFIX, SESSION_EVENTS, SESSION_EVENT_TYPES } from './constants'
8
8
  import { InteractionTimer } from '../timer/interaction-timer'
9
9
  import { wrapEvents } from '../wrap'
@@ -57,7 +57,7 @@ export class SessionEntity {
57
57
  * if the event was spawned on the current page or an adjacent page, and the behavior tied
58
58
  * to storage events is critical to apply only to cross-tab behavior
59
59
  * */
60
- if (isBrowserScope && !isIE) {
60
+ if (isBrowserScope) {
61
61
  windowAddEventListener('storage', (event) => {
62
62
  if (event.key === this.lookupKey) {
63
63
  const obj = typeof event.newValue === 'string' ? JSON.parse(event.newValue) : event.newValue
@@ -182,7 +182,7 @@ export class SessionEntity {
182
182
 
183
183
  return obj
184
184
  } catch (e) {
185
- warn('Failed to read from storage API', e)
185
+ warn(10, e)
186
186
  // storage is inaccessible
187
187
  return {}
188
188
  }
@@ -208,7 +208,7 @@ export class SessionEntity {
208
208
  return data
209
209
  } catch (e) {
210
210
  // storage is inaccessible
211
- warn('Failed to write to the storage API', e)
211
+ warn(11, e)
212
212
  return null
213
213
  }
214
214
  }
@@ -1,6 +1,8 @@
1
1
  import { originTime } from '../constants/runtime'
2
2
  import { getRuntime } from '../config/config'
3
3
 
4
+ const rfc2616Regex = /^(Mon|Tue|Wed|Thu|Fri|Sat|Sun), ([0-3][0-9]) (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) ([0-9]{4}) ([01][0-9]|2[0-3])(:[0-5][0-9]){2} GMT$/
5
+
4
6
  /**
5
7
  * Class used to adjust the timestamp of harvested data to New Relic server time. This
6
8
  * is done by tracking the performance timings of the RUM call and applying a calculation
@@ -29,7 +31,7 @@ export class TimeKeeper {
29
31
  /**
30
32
  * Represents whether the timekeeper is in a state that it can accurately convert
31
33
  * timestamps.
32
- * @type {number}
34
+ * @type {boolean}
33
35
  */
34
36
  #ready = false
35
37
 
@@ -46,6 +48,10 @@ export class TimeKeeper {
46
48
  return this.#correctedOriginTime
47
49
  }
48
50
 
51
+ get localTimeDiff () {
52
+ return this.#localTimeDiff
53
+ }
54
+
49
55
  /**
50
56
  * Process a rum request to calculate NR server time.
51
57
  * @param rumRequest {XMLHttpRequest} The xhr for the rum request
@@ -53,12 +59,16 @@ export class TimeKeeper {
53
59
  * @param endTime {number} The end time of the RUM request
54
60
  */
55
61
  processRumRequest (rumRequest, startTime, endTime) {
56
- this.processStoredDiff()
62
+ this.processStoredDiff() // Check session entity for stored time diff
57
63
  if (this.#ready) return // Server time calculated from session entity
64
+
58
65
  const responseDateHeader = rumRequest.getResponseHeader('Date')
59
66
  if (!responseDateHeader) {
60
67
  throw new Error('Missing date header on rum response.')
61
68
  }
69
+ if (!rfc2616Regex.test(responseDateHeader)) {
70
+ throw new Error('Date header invalid format.')
71
+ }
62
72
 
63
73
  const medianRumOffset = (endTime - startTime) / 2
64
74
  const serverOffset = startTime + medianRumOffset
@@ -96,6 +106,8 @@ export class TimeKeeper {
96
106
 
97
107
  /** Process the session entity and use the info to set the main time calculations if present */
98
108
  processStoredDiff () {
109
+ if (this.#ready) return // Time diff has already been calculated
110
+
99
111
  const storedServerTimeDiff = this.#session?.read()?.serverTimeDiff
100
112
  if (typeof storedServerTimeDiff === 'number' && !isNaN(storedServerTimeDiff)) {
101
113
  this.#localTimeDiff = storedServerTimeDiff
@@ -3,7 +3,6 @@
3
3
  * SPDX-License-Identifier: Apache-2.0
4
4
  */
5
5
 
6
- import { mapOwn } from '../util/map-own'
7
6
  import { stringify } from '../util/stringify'
8
7
 
9
8
  // Characters that are safe in a qs, but get encoded.
@@ -16,7 +15,7 @@ var charMap = {
16
15
  '%3B': ';'
17
16
  }
18
17
 
19
- var charList = mapOwn(charMap, function (k) { return k })
18
+ var charList = Object.keys(charMap)
20
19
  var safeEncoded = new RegExp(charList.join('|'), 'g')
21
20
 
22
21
  function real (c) {
@@ -43,7 +42,7 @@ export function obj (payload, maxBytes) {
43
42
  var total = 0
44
43
  var result = ''
45
44
 
46
- mapOwn(payload, function (feature, dataArray) {
45
+ Object.entries(payload || {}).forEach(([feature, dataArray]) => {
47
46
  var intermediate = []
48
47
  var next
49
48
  var i
@@ -4,8 +4,7 @@
4
4
  * @param {*} [secondary] Secondary data to include, usually an error or object
5
5
  * @returns
6
6
  */
7
- export function warn (message, secondary) {
8
- if (typeof console.warn !== 'function') return
9
- console.warn(`New Relic: ${message}`)
10
- if (secondary) console.warn(secondary)
7
+ export function warn (code, secondary) {
8
+ if (typeof console.debug !== 'function') return
9
+ console.debug(`New Relic Warning: https://github.com/newrelic/newrelic-browser-agent/blob/main/docs/warning-codes.md#${code}`, secondary)
11
10
  }
@@ -49,16 +49,16 @@ export function validateRules (rules) {
49
49
  var invalidRegexDetected = false
50
50
  for (var i = 0; i < rules.length; i++) {
51
51
  if (!('regex' in rules[i])) {
52
- warn('An obfuscation replacement rule was detected missing a "regex" value.')
52
+ warn(12)
53
53
  invalidRegexDetected = true
54
54
  } else if (typeof rules[i].regex !== 'string' && !(rules[i].regex instanceof RegExp)) {
55
- warn('An obfuscation replacement rule contains a "regex" value with an invalid type (must be a string or RegExp)')
55
+ warn(13)
56
56
  invalidRegexDetected = true
57
57
  }
58
58
 
59
59
  var replacement = rules[i].replacement
60
60
  if (replacement && typeof replacement !== 'string') {
61
- warn('An obfuscation replacement rule contains a "replacement" value with an invalid type (must be a string)')
61
+ warn(14)
62
62
  invalidReplacementDetected = true
63
63
  }
64
64
  }
@@ -20,7 +20,6 @@ export function getSubmitMethod ({ isFinalHarvest = false } = {}) {
20
20
  return isFinalHarvest && isBrowserScope && supportsSendBeacon
21
21
  // Use sendBeacon for final harvest
22
22
  ? beacon
23
- // Only IE does not support sendBeacon for final harvest
24
23
  // If not final harvest, or not browserScope, always use xhr post
25
24
  : xhr
26
25
  }
@@ -7,7 +7,6 @@
7
7
  * This module is used by: jserrors, spa.
8
8
  */
9
9
 
10
- import { LOGGING_FAILURE_MESSAGE } from '../../features/logging/constants'
11
10
  import { ee as baseEE, contextId } from '../event-emitter/contextual-ee'
12
11
  import { EventContext } from '../event-emitter/event-context'
13
12
  import { warn } from '../util/console'
@@ -22,7 +21,7 @@ import { createWrapperWithEmitter as wfn } from './wrap-function'
22
21
  */
23
22
  // eslint-disable-next-line
24
23
  export function wrapLogger(sharedEE, parent, loggerFn, context) {
25
- if (!(typeof parent === 'object' && !!parent && typeof loggerFn === 'string' && !!loggerFn && typeof parent[loggerFn] === 'function')) return warn(LOGGING_FAILURE_MESSAGE + 'invalid argument(s)')
24
+ if (!(typeof parent === 'object' && !!parent && typeof loggerFn === 'string' && !!loggerFn && typeof parent[loggerFn] === 'function')) return warn(29)
26
25
  const ee = scopedEE(sharedEE)
27
26
  const wrapFn = wfn(ee)
28
27
 
@@ -56,7 +56,7 @@ export function wrapXhr (sharedEE) {
56
56
  ee.emit('new-xhr', [xhr], context)
57
57
  xhr.addEventListener(READY_STATE_CHANGE, wrapXHR(context), eventListenerOpts(false))
58
58
  } catch (e) {
59
- warn('An error occurred while intercepting XHR', e)
59
+ warn(15, e)
60
60
  try {
61
61
  ee.emit('internal-error', [e])
62
62
  } catch (err) {