@newrelic/browser-agent 1.320.0 → 1.320.1-rc.1

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 (121) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/cjs/common/config/runtime.js +1 -0
  3. package/dist/cjs/common/constants/env.cdn.js +1 -1
  4. package/dist/cjs/common/constants/env.npm.js +1 -1
  5. package/dist/cjs/common/event-listener/event-listener-opts.js +1 -1
  6. package/dist/cjs/common/harvest/connector.js +200 -0
  7. package/dist/cjs/common/harvest/harvester.js +5 -8
  8. package/dist/cjs/common/harvest/send.js +8 -7
  9. package/dist/cjs/common/payloads/payloads.js +3 -2
  10. package/dist/cjs/common/serialize/bel-serializer.js +17 -4
  11. package/dist/cjs/common/timer/interaction-timer.js +2 -2
  12. package/dist/cjs/common/unload/eol.js +3 -3
  13. package/dist/cjs/common/util/console.js +2 -1
  14. package/dist/cjs/common/util/feature-flags.js +2 -1
  15. package/dist/cjs/common/v2/mfe-vitals.js +34 -11
  16. package/dist/cjs/common/window/page-visibility.js +1 -1
  17. package/dist/cjs/features/ajax/aggregate/index.js +19 -8
  18. package/dist/cjs/features/page_view_event/aggregate/index.js +2 -6
  19. package/dist/cjs/features/page_view_event/aggregate_v2/index.js +109 -0
  20. package/dist/cjs/features/page_view_event/instrument/index.js +6 -1
  21. package/dist/cjs/features/page_view_timing/aggregate/index.js +33 -14
  22. package/dist/cjs/features/session_replay/instrument/index.js +9 -0
  23. package/dist/cjs/features/session_replay/shared/recorder.js +2 -1
  24. package/dist/cjs/features/soft_navigations/aggregate/ajax-node.js +16 -4
  25. package/dist/cjs/features/soft_navigations/aggregate/interaction.js +10 -3
  26. package/dist/cjs/features/utils/aggregate-base.js +0 -12
  27. package/dist/cjs/features/utils/instrument-base.js +72 -29
  28. package/dist/cjs/loaders/agent.js +2 -1
  29. package/dist/cjs/loaders/api/consent.js +2 -2
  30. package/dist/cjs/loaders/features/features.js +2 -1
  31. package/dist/esm/common/config/runtime.js +1 -0
  32. package/dist/esm/common/constants/env.cdn.js +1 -1
  33. package/dist/esm/common/constants/env.npm.js +1 -1
  34. package/dist/esm/common/event-listener/event-listener-opts.js +1 -1
  35. package/dist/esm/common/harvest/connector.js +193 -0
  36. package/dist/esm/common/harvest/harvester.js +5 -8
  37. package/dist/esm/common/harvest/send.js +10 -9
  38. package/dist/esm/common/payloads/payloads.js +3 -2
  39. package/dist/esm/common/serialize/bel-serializer.js +17 -4
  40. package/dist/esm/common/timer/interaction-timer.js +2 -2
  41. package/dist/esm/common/unload/eol.js +3 -3
  42. package/dist/esm/common/util/console.js +2 -1
  43. package/dist/esm/common/util/feature-flags.js +2 -1
  44. package/dist/esm/common/v2/mfe-vitals.js +34 -11
  45. package/dist/esm/common/window/page-visibility.js +1 -1
  46. package/dist/esm/features/ajax/aggregate/index.js +19 -8
  47. package/dist/esm/features/page_view_event/aggregate/index.js +2 -6
  48. package/dist/esm/features/page_view_event/aggregate_v2/index.js +100 -0
  49. package/dist/esm/features/page_view_event/instrument/index.js +6 -1
  50. package/dist/esm/features/page_view_timing/aggregate/index.js +33 -14
  51. package/dist/esm/features/session_replay/instrument/index.js +9 -0
  52. package/dist/esm/features/session_replay/shared/recorder.js +2 -1
  53. package/dist/esm/features/soft_navigations/aggregate/ajax-node.js +16 -4
  54. package/dist/esm/features/soft_navigations/aggregate/interaction.js +10 -3
  55. package/dist/esm/features/utils/aggregate-base.js +0 -12
  56. package/dist/esm/features/utils/instrument-base.js +71 -28
  57. package/dist/esm/loaders/agent.js +2 -1
  58. package/dist/esm/loaders/api/consent.js +2 -2
  59. package/dist/esm/loaders/features/features.js +1 -0
  60. package/dist/tsconfig.tsbuildinfo +1 -1
  61. package/dist/types/common/config/runtime.d.ts.map +1 -1
  62. package/dist/types/common/event-listener/event-listener-opts.d.ts +1 -1
  63. package/dist/types/common/harvest/connector.d.ts +6 -0
  64. package/dist/types/common/harvest/connector.d.ts.map +1 -0
  65. package/dist/types/common/harvest/harvester.d.ts.map +1 -1
  66. package/dist/types/common/harvest/send.d.ts.map +1 -1
  67. package/dist/types/common/payloads/payloads.d.ts +3 -2
  68. package/dist/types/common/payloads/payloads.d.ts.map +1 -1
  69. package/dist/types/common/serialize/bel-serializer.d.ts +9 -1
  70. package/dist/types/common/serialize/bel-serializer.d.ts.map +1 -1
  71. package/dist/types/common/unload/eol.d.ts +1 -1
  72. package/dist/types/common/unload/eol.d.ts.map +1 -1
  73. package/dist/types/common/util/console.d.ts +2 -1
  74. package/dist/types/common/util/console.d.ts.map +1 -1
  75. package/dist/types/common/v2/mfe-vitals.d.ts.map +1 -1
  76. package/dist/types/features/ajax/aggregate/index.d.ts.map +1 -1
  77. package/dist/types/features/page_view_event/aggregate/index.d.ts.map +1 -1
  78. package/dist/types/features/page_view_event/aggregate_v2/index.d.ts +20 -0
  79. package/dist/types/features/page_view_event/aggregate_v2/index.d.ts.map +1 -0
  80. package/dist/types/features/page_view_event/instrument/index.d.ts.map +1 -1
  81. package/dist/types/features/page_view_timing/aggregate/index.d.ts +0 -1
  82. package/dist/types/features/page_view_timing/aggregate/index.d.ts.map +1 -1
  83. package/dist/types/features/session_replay/instrument/index.d.ts +1 -0
  84. package/dist/types/features/session_replay/instrument/index.d.ts.map +1 -1
  85. package/dist/types/features/session_replay/shared/recorder.d.ts.map +1 -1
  86. package/dist/types/features/soft_navigations/aggregate/ajax-node.d.ts.map +1 -1
  87. package/dist/types/features/soft_navigations/aggregate/interaction.d.ts.map +1 -1
  88. package/dist/types/features/utils/aggregate-base.d.ts +0 -5
  89. package/dist/types/features/utils/aggregate-base.d.ts.map +1 -1
  90. package/dist/types/features/utils/instrument-base.d.ts.map +1 -1
  91. package/dist/types/loaders/agent.d.ts.map +1 -1
  92. package/dist/types/loaders/features/features.d.ts +1 -0
  93. package/dist/types/loaders/features/features.d.ts.map +1 -1
  94. package/package.json +2 -2
  95. package/src/common/config/runtime.js +1 -0
  96. package/src/common/event-listener/event-listener-opts.js +1 -1
  97. package/src/common/harvest/connector.js +168 -0
  98. package/src/common/harvest/harvester.js +7 -9
  99. package/src/common/harvest/send.js +9 -7
  100. package/src/common/payloads/payloads.js +3 -2
  101. package/src/common/serialize/bel-serializer.js +13 -4
  102. package/src/common/timer/interaction-timer.js +2 -2
  103. package/src/common/unload/eol.js +3 -3
  104. package/src/common/util/console.js +2 -1
  105. package/src/common/util/feature-flags.js +1 -1
  106. package/src/common/v2/mfe-vitals.js +39 -12
  107. package/src/common/window/page-visibility.js +1 -1
  108. package/src/features/ajax/aggregate/index.js +12 -9
  109. package/src/features/page_view_event/aggregate/index.js +2 -6
  110. package/src/features/page_view_event/aggregate_v2/index.js +97 -0
  111. package/src/features/page_view_event/instrument/index.js +6 -1
  112. package/src/features/page_view_timing/aggregate/index.js +24 -15
  113. package/src/features/session_replay/instrument/index.js +9 -0
  114. package/src/features/session_replay/shared/recorder.js +2 -1
  115. package/src/features/soft_navigations/aggregate/ajax-node.js +10 -7
  116. package/src/features/soft_navigations/aggregate/interaction.js +6 -5
  117. package/src/features/utils/aggregate-base.js +0 -12
  118. package/src/features/utils/instrument-base.js +71 -25
  119. package/src/loaders/agent.js +2 -1
  120. package/src/loaders/api/consent.js +2 -2
  121. package/src/loaders/features/features.js +1 -0
@@ -1 +1 @@
1
- {"version":3,"file":"send.d.ts","sourceRoot":"","sources":["../../../../src/common/harvest/send.js"],"names":[],"mappings":"AAuBA;;;;;GAKG;AACH,+BAJW,MAAM,sHACN,eAAe,GACb,OAAO,CAsHnB;8BA/HY,OAAO,YAAY,EAAE,eAAe"}
1
+ {"version":3,"file":"send.d.ts","sourceRoot":"","sources":["../../../../src/common/harvest/send.js"],"names":[],"mappings":"AAuBA;;;;;GAKG;AACH,+BAJW,MAAM,sHACN,eAAe,GACb,OAAO,CAyHnB;8BAlIY,OAAO,YAAY,EAAE,eAAe"}
@@ -40,14 +40,15 @@ export function isLikelyHumanReadable(headers: Object, data: any): boolean;
40
40
  */
41
41
  export function truncateAsString(data: any): string;
42
42
  /**
43
- * Creates string adder functions for BEL serialization with obfuscation and optional truncation.
43
+ * Creates string adder functions for BEL serialization with obfuscation and optional truncation, as well as raw string.
44
44
  * This ensures a single string table is used while providing separate handling for regular vs payload attributes.
45
45
  * @param {Function} getAddStringContext - Function that creates a new string table context
46
46
  * @param {Object} obfuscator - Optional obfuscator instance for string obfuscation
47
- * @returns {{addString: Function, addStringWithTruncation: Function}} Object containing both string adder functions
47
+ * @returns {{addString: Function, addStringRaw: Function, addStringWithTruncation: Function}} Object containing various string adder functions
48
48
  */
49
49
  export function createStringAdders(getAddStringContext: Function, obfuscator: Object): {
50
50
  addString: Function;
51
+ addStringRaw: Function;
51
52
  addStringWithTruncation: Function;
52
53
  };
53
54
  //# sourceMappingURL=payloads.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"payloads.d.ts","sourceRoot":"","sources":["../../../../src/common/payloads/payloads.js"],"names":[],"mappings":"AAQA;;;;;;;;;;;;GAYG;AACH,+CAVW,MAAM,+EAEd;IAAsB,UAAU,EAAxB,MAAM;IACS,YAAY,EAA3B,OAAO;IACO,WAAW,EAAzB,MAAM;IACQ,eAAe,EAA7B,MAAM;IACS,eAAe;CACtC,YAAQ,MAAM,EAAE,GACN,OAAO,CAqBnB;AAED;;;;GAIG;AACH,yCAHW,MAAM,GACJ,MAAM,GAAC,SAAS,CAgB5B;AAED;;;;;GAKG;AACH,+CAJW,MAAM,QACN,GAAC,GACC,OAAO,CA2BnB;AAED;;;;;;GAMG;AACH,uCAHW,GAAC,GACC,MAAM,CA2BlB;AAED;;;;;;GAMG;AACH,8EAHW,MAAM,GACJ;IAAC,SAAS,WAAW;IAAC,uBAAuB,WAAU;CAAC,CAiBpE"}
1
+ {"version":3,"file":"payloads.d.ts","sourceRoot":"","sources":["../../../../src/common/payloads/payloads.js"],"names":[],"mappings":"AAQA;;;;;;;;;;;;GAYG;AACH,+CAVW,MAAM,+EAEd;IAAsB,UAAU,EAAxB,MAAM;IACS,YAAY,EAA3B,OAAO;IACO,WAAW,EAAzB,MAAM;IACQ,eAAe,EAA7B,MAAM;IACS,eAAe;CACtC,YAAQ,MAAM,EAAE,GACN,OAAO,CAqBnB;AAED;;;;GAIG;AACH,yCAHW,MAAM,GACJ,MAAM,GAAC,SAAS,CAgB5B;AAED;;;;;GAKG;AACH,+CAJW,MAAM,QACN,GAAC,GACC,OAAO,CA2BnB;AAED;;;;;;GAMG;AACH,uCAHW,GAAC,GACC,MAAM,CA2BlB;AAED;;;;;;GAMG;AACH,8EAHW,MAAM,GACJ;IAAC,SAAS,WAAW;IAAC,YAAY,WAAW;IAAC,uBAAuB,WAAU;CAAC,CAkB5F"}
@@ -1,5 +1,13 @@
1
1
  export function nullable(val: any, fn: any, comma: any): string;
2
2
  export function numeric(n: any, noDefault: any): string;
3
3
  export function getAddStringContext(obfuscator: any, truncator: any): (str: any, obfuscate?: boolean) => string;
4
- export function addCustomAttributes(attrs: any, addString: any): any[];
4
+ /**
5
+ * Attributes are serialized according to their types, using the provided serializers. Only the first 64 attributes will be added to the payload.
6
+ * @param attrs
7
+ * @param serializers
8
+ * @param {function} serializers.addKey -function for serializing attribute keys
9
+ * @param {function} serializers.addVal - function for serializing attribute values
10
+ * @returns {*[]}
11
+ */
12
+ export function addCustomAttributes(attrs: any, serializers: any): any[];
5
13
  //# sourceMappingURL=bel-serializer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"bel-serializer.d.ts","sourceRoot":"","sources":["../../../../src/common/serialize/bel-serializer.js"],"names":[],"mappings":"AAUA,gEAIC;AAED,wDAKC;AAED,gHAiBC;AAED,uEAwCC"}
1
+ {"version":3,"file":"bel-serializer.d.ts","sourceRoot":"","sources":["../../../../src/common/serialize/bel-serializer.js"],"names":[],"mappings":"AAUA,gEAIC;AAED,wDAKC;AAED,gHAiBC;AAED;;;;;;;GAOG;AACH,mEAFa,GAAC,EAAE,CA2Cf"}
@@ -3,5 +3,5 @@
3
3
  * This is used, for example, to submit a final harvest and send all remaining data on best-effort.
4
4
  * @param {function} cb - func to run before or during the last reliable event or time of an env's life span
5
5
  */
6
- export function subscribeToEOL(cb: Function, capturePhase: any): void;
6
+ export function subscribeToEOL(cb: Function): void;
7
7
  //# sourceMappingURL=eol.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"eol.d.ts","sourceRoot":"","sources":["../../../../src/common/unload/eol.js"],"names":[],"mappings":"AAmBA;;;;GAIG;AACH,sEAOC"}
1
+ {"version":3,"file":"eol.d.ts","sourceRoot":"","sources":["../../../../src/common/unload/eol.js"],"names":[],"mappings":"AAmBA;;;;GAIG;AACH,mDAOC"}
@@ -58,7 +58,7 @@
58
58
  * | 50 | Failed to connect. Cannot allow registered API. |
59
59
  * | 51 | Container agent is not available to register with. Can not connect. |
60
60
  * | 52 | Unexpected problem encountered. There should be at least one app for harvest! |
61
- * | 53 | Did not receive a valid entityGuid from connection response. |
61
+ * | 53 | Failed to parse connect response. |
62
62
  * | 54 | An experimental feature is being used. Support can not be offered for issues. |
63
63
  * | 55 | Register API has been disabled on the container agent. |
64
64
  * | 56 | Could not find a matching entity to store data. |
@@ -84,6 +84,7 @@
84
84
  * | 76 | Agent rejected post message, could not match with existing entity. |
85
85
  * | 77 | Agent rejected post message, could not validate origin. |
86
86
  * | 78 | RegisteredIframeEntity could not determine parent origin and will not register, to avoid trusting messages from any origin. |
87
+ * | 79 | Unable to initialize Connector and/or Harvester. |
87
88
  *
88
89
  * @param {number} code The warning code to emit, which will be used to link to the warning code documentation
89
90
  * @param {*} [secondary] Secondary data to include, usually an extra message, error or object
@@ -1 +1 @@
1
- {"version":3,"file":"console.d.ts","sourceRoot":"","sources":["../../../../src/common/util/console.js"],"names":[],"mappings":"AAUA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0FG;AAEH,2BALW,MAAM,cACN,GAAC,QAiBX"}
1
+ {"version":3,"file":"console.d.ts","sourceRoot":"","sources":["../../../../src/common/util/console.js"],"names":[],"mappings":"AAUA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2FG;AAEH,2BALW,MAAM,cACN,GAAC,QAiBX"}
@@ -1 +1 @@
1
- {"version":3,"file":"mfe-vitals.d.ts","sourceRoot":"","sources":["../../../../src/common/v2/mfe-vitals.js"],"names":[],"mappings":"AAqHA;;;;;GAKG;AACH,uCAJW,iBAAiB,WACjB,kBAAkB,GAChB,iBAAiB,CAuM7B;iCAtTY,OAAO,sCAAsC,EAAE,kBAAkB;gCACjE,OAAO,sCAAsC,EAAE,iBAAiB;gCAChE,OAAO,sCAAsC,EAAE,iBAAiB"}
1
+ {"version":3,"file":"mfe-vitals.d.ts","sourceRoot":"","sources":["../../../../src/common/v2/mfe-vitals.js"],"names":[],"mappings":"AAqHA;;;;;GAKG;AACH,uCAJW,iBAAiB,WACjB,kBAAkB,GAChB,iBAAiB,CAkO7B;iCAjVY,OAAO,sCAAsC,EAAE,kBAAkB;gCACjE,OAAO,sCAAsC,EAAE,iBAAiB;gCAChE,OAAO,sCAAsC,EAAE,iBAAiB"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/features/ajax/aggregate/index.js"],"names":[],"mappings":"AAoBA;IACE,2BAAiC;IAEjC,2BA6BC;IAvBC,uBAA4D;IAyB9D,0GA2FC;IAED,+CAOC;IAED,iDAoEC;CACF;8BAvN6B,4BAA4B;2BAK/B,gCAAgC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/features/ajax/aggregate/index.js"],"names":[],"mappings":"AAoBA;IACE,2BAAiC;IAEjC,2BA6BC;IAvBC,uBAA4D;IAyB9D,0GA2FC;IAED,+CAOC;IAED,iDAuEC;CACF;8BA1N6B,4BAA4B;2BAK/B,gCAAgC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/features/page_view_event/aggregate/index.js"],"names":[],"mappings":"AAyBA;IACE,2BAA2C;IAE3C,2BAuCC;IApCC,kCAAqG;IACrG,iBAAoB;IAEpB,wBAAwB;IACxB,8BAA8B;IAC9B,8BAA8B;IAC9B,gBAAgB;IAGhB,uBAA2D;IA6B7D;;;;OAIG;IACH,2BAFW,GAAC,QAiEX;IAbC;;;;;;;;;;;;;;mBAOC;IANC,iCAAyB;IAc7B,kCAEC;IAED;;;;;;aA6GC;CACF;8BAlP6B,4BAA4B;2BAQ/B,gCAAgC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/features/page_view_event/aggregate/index.js"],"names":[],"mappings":"AAyBA;IACE,2BAA2C;IAE3C,2BAuCC;IApCC,kCAAqG;IACrG,iBAAoB;IAEpB,wBAAwB;IACxB,8BAA8B;IAC9B,8BAA8B;IAC9B,gBAAgB;IAGhB,uBAA2D;IA6B7D;;;;OAIG;IACH,2BAFW,GAAC,QA+DX;IAXC;;;;;;;;;;;;;;mBAOC;IANC,iCAAyB;IAY7B,kCAEC;IAED;;;;;;aA2GC;CACF;8BA9O6B,4BAA4B;2BAQ/B,gCAAgC"}
@@ -0,0 +1,20 @@
1
+ export class Aggregate extends AggregateBase {
2
+ static featureName: string;
3
+ constructor(agentRef: any);
4
+ queryStringsBuilder(): {
5
+ fp: any;
6
+ fcp: any;
7
+ qt: any;
8
+ ap: any;
9
+ be: number;
10
+ fe: number;
11
+ dc: number;
12
+ at: any;
13
+ af: string;
14
+ igp: any;
15
+ };
16
+ serializer(eventBuffer: any): any;
17
+ #private;
18
+ }
19
+ import { AggregateBase } from '../../utils/aggregate-base';
20
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/features/page_view_event/aggregate_v2/index.js"],"names":[],"mappings":"AAiBA;IACE,2BAA2C;IAO3C,2BAkBC;IAED;;;;;;;;;;;MA0CC;IAMD,kCAEC;;CACF;8BAvF6B,4BAA4B"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/features/page_view_event/instrument/index.js"],"names":[],"mappings":"AAWA;IACE,2BAA2C;IAC3C,2BAUC;IAED,8BA+BC;CACF;AAED,8CAAuC;+BAtDR,6BAA6B"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/features/page_view_event/instrument/index.js"],"names":[],"mappings":"AAWA;IACE,2BAA2C;IAC3C,2BAeC;IAED,8BA+BC;CACF;AAED,8CAAuC;+BA3DR,6BAA6B"}
@@ -19,7 +19,6 @@ export class Aggregate extends AggregateBase {
19
19
  * @returns {void}
20
20
  */
21
21
  checkForFirstInteraction(): void;
22
- appendGlobalCustomAttributes(timing: any): void;
23
22
  preHarvestChecks(): boolean;
24
23
  serializer(eventBuffer: any): string;
25
24
  #private;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/features/page_view_timing/aggregate/index.js"],"names":[],"mappings":"AA0BA;IACE,2BAAiC;IAMjC,2BA+BC;IA7BC,4BAA+B;IAC/B,0BAA6B;IAK7B,uBAA2D;IAyB7D;;;OAGG;IACH,6BAFW,MAAM,QAOhB;IAED;;;;MA+BC;IAED;;;OAGG;IACH,4BAFa,IAAI,CAahB;IAED,gDAWC;IAED,4BAGC;IAGD,qCAwBC;;CACF;8BAjK6B,4BAA4B;2BAC/B,gCAAgC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/features/page_view_timing/aggregate/index.js"],"names":[],"mappings":"AA2BA;IACE,2BAAiC;IAMjC,2BAmCC;IAjCC,4BAA+B;IAC/B,0BAA6B;IAK7B,uBAA2D;IA6B7D;;;OAGG;IACH,6BAFW,MAAM,QAOhB;IAED;;;;MAiCC;IAED;;;OAGG;IACH,4BAFa,IAAI,CAahB;IAWD,4BAGC;IAGD,qCA8BC;;CACF;8BA1K6B,4BAA4B;2BAC/B,gCAAgC"}
@@ -3,6 +3,7 @@ export class Instrument extends InstrumentBase {
3
3
  constructor(agentRef: any);
4
4
  /** The RRWEB recorder instance, if imported */
5
5
  recorder: any;
6
+ abortHandler: () => void;
6
7
  errorNoticed: boolean;
7
8
  /**
8
9
  * Returns a promise that imports the recorder module. Only lets the recorder module be imported and instantiated once. Rejects if failed to import/instantiate.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/features/session_replay/instrument/index.js"],"names":[],"mappings":"AAkBA;IACE,2BAAiC;IAMjC,2BAiCC;IApCD,+CAA+C;IAC/C,cAAQ;IA+BF,sBAAwB;IAmB9B;;;OAGG;IACH,+BAkBC;;CAgBF;AAED,8CAAuC;+BAtGR,6BAA6B"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/features/session_replay/instrument/index.js"],"names":[],"mappings":"AAkBA;IACE,2BAAiC;IAMjC,2BAqCC;IAxCD,+CAA+C;IAC/C,cAAQ;IA2BN,yBAA+B;IAQ3B,sBAAwB;IAmB9B;;;OAGG;IACH,+BAkBC;;CAqBF;AAED,8CAAuC;+BA/GR,6BAA6B"}
@@ -1 +1 @@
1
- {"version":3,"file":"recorder.d.ts","sourceRoot":"","sources":["../../../../../src/features/session_replay/shared/recorder.js"],"names":[],"mappings":"AAqBA;IAUE,+BAoCC;IAtCD,sBAAmB;IAGjB,iDAAiD;IACjD,kBAAgC;IAEhC,QAAyB;IACzB,mBAA6C;IAC7C,cAAqC;IAErC,qBAAwB;IACxB,0FAA0F;IAC1F,eAAkE;IAElE,iHAAiH;IACjH,uBAAgD;IAChD,mFAAmF;IACnF,iCAA0D;IAC1D,+DAA+D;IAC/D,kBAA6B;IAC7B,uIAAuI;IACvI,yBAA4B;IAC5B,qBAAwB;IACxB,kIAAkI;IAClI,kBAAqB;IACrB,uIAAuI;IACvI,0BAAwE;IAc1E,mBAEC;IAED;;;;;;;;;MAWC;IAED,kFAAkF;IAClF,oBAGC;IAED,qDAAqD;IACrD,8CA0CC;IAED;;;;;OAKG;IACH,aAHW,GAAC,cACD,GAAC,QAiCX;IAED,yHAAyH;IACzH,yCAiCC;IAED,0HAA0H;IAC1H,yBAOC;IAED,wBAEC;IAED,gCAAgC;IAChC,uCAGC;IAED;;;SAGK;IACL,oCAGC;;CACF;+BAzO8B,mBAAmB"}
1
+ {"version":3,"file":"recorder.d.ts","sourceRoot":"","sources":["../../../../../src/features/session_replay/shared/recorder.js"],"names":[],"mappings":"AAqBA;IAUE,+BAoCC;IAtCD,sBAAmB;IAGjB,iDAAiD;IACjD,kBAAgC;IAEhC,QAAyB;IACzB,mBAA6C;IAC7C,cAAqC;IAErC,qBAAwB;IACxB,0FAA0F;IAC1F,eAAkE;IAElE,iHAAiH;IACjH,uBAAgD;IAChD,mFAAmF;IACnF,iCAA0D;IAC1D,+DAA+D;IAC/D,kBAA6B;IAC7B,uIAAuI;IACvI,yBAA4B;IAC5B,qBAAwB;IACxB,kIAAkI;IAClI,kBAAqB;IACrB,uIAAuI;IACvI,0BAAwE;IAc1E,mBAEC;IAED;;;;;;;;;MAWC;IAED,kFAAkF;IAClF,oBAGC;IAED,qDAAqD;IACrD,8CA0CC;IAED;;;;;OAKG;IACH,aAHW,GAAC,cACD,GAAC,QAiCX;IAED,yHAAyH;IACzH,yCAkCC;IAED,0HAA0H;IAC1H,yBAOC;IAED,wBAEC;IAED,gCAAgC;IAChC,uCAGC;IAED;;;SAGK;IACL,oCAGC;;CACF;+BA1O8B,mBAAmB"}
@@ -1 +1 @@
1
- {"version":3,"file":"ajax-node.d.ts","sourceRoot":"","sources":["../../../../../src/features/soft_navigations/aggregate/ajax-node.js"],"names":[],"mappings":"AAUA;IACE,8CA8BC;IA5BC,gBAA6B;IAC7B,YAA8B;IAC9B,YAA8B;IAC9B,YAA8B;IAC9B,UAA0B;IAC1B,YAAmC;IACnC,YAAoC;IACpC,+BAAwD;IACxD,YAA8B;IAC9B,aAAgC;IAChC,mBAA4C;IAC5C,SAAwB;IACxB,sBAAkD;IAIlD,iBAAwC;IACxC,oBAA8C;IAC9C,kBAA0C;IAC1C,kBAA0C;IAC1C,qBAAgD;IAK9C,iBAAoE;IAKxE,iFA+CC;IAhEC,sBAAkC;CAiErC;wBAnFuB,YAAY"}
1
+ {"version":3,"file":"ajax-node.d.ts","sourceRoot":"","sources":["../../../../../src/features/soft_navigations/aggregate/ajax-node.js"],"names":[],"mappings":"AAUA;IACE,8CA8BC;IA5BC,gBAA6B;IAC7B,YAA8B;IAC9B,YAA8B;IAC9B,YAA8B;IAC9B,UAA0B;IAC1B,YAAmC;IACnC,YAAoC;IACpC,+BAAwD;IACxD,YAA8B;IAC9B,aAAgC;IAChC,mBAA4C;IAC5C,SAAwB;IACxB,sBAAkD;IAIlD,iBAAwC;IACxC,oBAA8C;IAC9C,kBAA0C;IAC1C,kBAA0C;IAC1C,qBAAgD;IAK9C,iBAAoE;IAKxE,iFAkDC;IAnEC,sBAAkC;CAoErC;wBAtFuB,YAAY"}
@@ -1 +1 @@
1
- {"version":3,"file":"interaction.d.ts","sourceRoot":"","sources":["../../../../../src/features/soft_navigations/aggregate/interaction.js"],"names":[],"mappings":"AAYA;;IAEI;AACJ;IAoBE,0FAaC;IAhCD,WAAmB;IACnB,uBAAgC;IAChC,gBAAU;IACV,qBAAqB;IACrB,oBAAoB;IACpB,eAAS;IACT,aAAO;IACP,cAAQ;IACR,+EAA+E;IAC/E,eAA8B;IAC9B,qBAAgB;IAChB,yBAAoB;IACpB,sBAAoB;IACpB,6BAA2B;IAC3B,cAAW;IACX,kBAAa;IACb,uBAAiB;IACjB,wBAAkB;IAIhB,gBAAoC;IACpC,aAAsB;IAEtB,cAAiC;IACjC,wCAGE;IACF,mBAAyC;IAAxB,qBAAwB;IAEzC,YAAsE;IAAxD,YAAwD;IAGxE,iDAKC;IAED,gCAGC;IAED,oCAUC;IAED,8BAIC;IAED,6DAeC;IAmBD;;;;;;OAMG;IACH,0BAHW,mBAAmB,WAM7B;IAGD,uBAAoB;IACpB,iCAA8B;IAC9B,sBAAmB;IAEnB;;;;;;;OAOG;IACH,qDALW,KAAK,yBACL,UAAU,kBACV,UAAU,UAgDpB;;CACF;wBA/KuB,YAAY"}
1
+ {"version":3,"file":"interaction.d.ts","sourceRoot":"","sources":["../../../../../src/features/soft_navigations/aggregate/interaction.js"],"names":[],"mappings":"AAaA;;IAEI;AACJ;IAoBE,0FAaC;IAhCD,WAAmB;IACnB,uBAAgC;IAChC,gBAAU;IACV,qBAAqB;IACrB,oBAAoB;IACpB,eAAS;IACT,aAAO;IACP,cAAQ;IACR,+EAA+E;IAC/E,eAA8B;IAC9B,qBAAgB;IAChB,yBAAoB;IACpB,sBAAoB;IACpB,6BAA2B;IAC3B,cAAW;IACX,kBAAa;IACb,uBAAiB;IACjB,wBAAkB;IAIhB,gBAAoC;IACpC,aAAsB;IAEtB,cAAiC;IACjC,wCAGE;IACF,mBAAyC;IAAxB,qBAAwB;IAEzC,YAAsE;IAAxD,YAAwD;IAGxE,iDAKC;IAED,gCAGC;IAED,oCAUC;IAED,8BAIC;IAED,6DAeC;IAmBD;;;;;;OAMG;IACH,0BAHW,mBAAmB,WAM7B;IAGD,uBAAoB;IACpB,iCAA8B;IAC9B,sBAAmB;IAEnB;;;;;;;OAOG;IACH,qDALW,KAAK,yBACL,UAAU,kBACV,UAAU,UAgDpB;;CACF;wBAhLuB,YAAY"}
@@ -58,11 +58,6 @@ export class AggregateBase extends FeatureBase {
58
58
  sent?: boolean | undefined;
59
59
  retry?: boolean | undefined;
60
60
  }): void;
61
- /**
62
- * These are actions related to shared resources that should be initialized once by whichever feature Aggregate subclass loads first.
63
- * This method should run after checkConfiguration, which may reset the agent's info/runtime object that is used here.
64
- */
65
- doOnceForAllAggregate(agentRef: any): void;
66
61
  /**
67
62
  * Report a supportability metric
68
63
  * @param {*} metricName The tag of the name matching the Angler aggregation tag
@@ -1 +1 @@
1
- {"version":3,"file":"aggregate-base.d.ts","sourceRoot":"","sources":["../../../../src/features/utils/aggregate-base.js"],"names":[],"mappings":"AAeA;IACE;;;;OAIG;IACH,sBAHW,MAAM,eACN,MAAM,EAkBhB;IAZC,uOAAuO;IACvO,qCAAwC;IACxC,gLAAgL;IAChL,yBAA2B;IAC3B,sFAAsF;IACtF,oBAAuB;IAEvB,gBAAqB;IAqBjB,YAAsE;IAW5E,iNAAiN;IACjN,0CAEC;IAED;;;;OAIG;IACH,8BAHU,MAAM,CAKf;IAED,qBAOC;IAFG,6BAAmB;IAIvB;;;;OAIG;IACH,2BAOC;IAED;;;;OAIG;IACH,yBAHW,MAAM,EAAE,gBAyBlB;IAED;;OAEG;IACH,cAEC;IAED,qCAEC;IAED;;;;;;OAMG;IACH,uDAJW,MAAM,GAAC,SAAS,SAsB1B;IAED;;;;;OAKG;IACH,4BAHG;QAAyB,IAAI,GAArB,OAAO,YAAC;QACS,KAAK,GAAtB,OAAO,YAAC;KAClB,QAKA;IAED;;;OAGG;IACH,2CAIC;IAED;;;;OAIG;IACH,uCAHW,GAAC,UACD,GAAC,QAIX;;CACF;4BAlM2B,gBAAgB"}
1
+ {"version":3,"file":"aggregate-base.d.ts","sourceRoot":"","sources":["../../../../src/features/utils/aggregate-base.js"],"names":[],"mappings":"AAcA;IACE;;;;OAIG;IACH,sBAHW,MAAM,eACN,MAAM,EAiBhB;IAZC,uOAAuO;IACvO,qCAAwC;IACxC,gLAAgL;IAChL,yBAA2B;IAC3B,sFAAsF;IACtF,oBAAuB;IAEvB,gBAAqB;IAqBjB,YAAsE;IAW5E,iNAAiN;IACjN,0CAEC;IAED;;;;OAIG;IACH,8BAHU,MAAM,CAKf;IAED,qBAOC;IAFG,6BAAmB;IAIvB;;;;OAIG;IACH,2BAOC;IAED;;;;OAIG;IACH,yBAHW,MAAM,EAAE,gBAyBlB;IAED;;OAEG;IACH,cAEC;IAED,qCAEC;IAED;;;;;;OAMG;IACH,uDAJW,MAAM,GAAC,SAAS,SAsB1B;IAED;;;;;OAKG;IACH,4BAHG;QAAyB,IAAI,GAArB,OAAO,YAAC;QACS,KAAK,GAAtB,OAAO,YAAC;KAClB,QAKA;IAED;;;;OAIG;IACH,uCAHW,GAAC,UACD,GAAC,QAIX;;CACF;4BAtL2B,gBAAgB"}
@@ -1 +1 @@
1
- {"version":3,"file":"instrument-base.d.ts","sourceRoot":"","sources":["../../../../src/features/utils/instrument-base.js"],"names":[],"mappings":"AA4BA;;;GAGG;AACH;IACE;;;;OAIG;IACH,sBAHW,MAAM,eACN,MAAM,EA0ChB;IArCC,8IAA8I;IAC9I,cADW,WAAW,SAAS,CACF;IAE7B;;;MAGE;IACF,eAHU,OAAO,kBAAkB,EAAE,aAAa,CAGpB;IAE9B;;;MAGE;IACF,iCAAmC;IACnC,kCAEE;IAEF;;;MAGE;IACF,uBAAiC;IAiBnC;;;;;;;OAOG;IACH,2BALW,MAAM,qDAEN,MAAM,QAyEhB;;CAiDF;4BAnM2B,gBAAgB"}
1
+ {"version":3,"file":"instrument-base.d.ts","sourceRoot":"","sources":["../../../../src/features/utils/instrument-base.js"],"names":[],"mappings":"AA6BA;;;GAGG;AACH;IACE;;;;OAIG;IACH,sBAHW,MAAM,eACN,MAAM,EA0ChB;IArCC,8IAA8I;IAC9I,cADW,WAAW,SAAS,CACF;IAE7B;;;MAGE;IACF,eAHU,OAAO,kBAAkB,EAAE,aAAa,CAGpB;IAE9B;;;MAGE;IACF,iCAAmC;IACnC,kCAEE;IAEF;;;MAGE;IACF,uBAAiC;IAiBnC;;;;;;;OAOG;IACH,2BALW,MAAM,qDAEN,MAAM,QA2DhB;;CAiDF;4BAtL2B,gBAAgB"}
@@ -1 +1 @@
1
- {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../../src/loaders/agent.js"],"names":[],"mappings":"AA2BA;;;;;;;;;GASG;AAEH;;;GAGG;AACH;IACE;;OAEG;IACH,qBAFW,YAAY,EA+BtB;IAnBC,yBAAkB;IAGlB,yCAAsD;IAkBxD;;;;;MAOC;IAED,gBAEC;IAED,yBAmCC;CACF;;;;;UAjGa,OAAO,uBAAuB,EAAE,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;0BApBxB,cAAc"}
1
+ {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../../src/loaders/agent.js"],"names":[],"mappings":"AA2BA;;;;;;;;;GASG;AAEH;;;GAGG;AACH;IACE;;OAEG;IACH,qBAFW,YAAY,EA+BtB;IAnBC,yBAAkB;IAGlB,yCAAsD;IAkBxD;;;;;MAOC;IAED,gBAEC;IAED,yBAoCC;CACF;;;;;UAlGa,OAAO,uBAAuB,EAAE,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;0BApBxB,cAAc"}
@@ -6,6 +6,7 @@ export const EVENTS: "events";
6
6
  export const JSERRORS: "jserrors";
7
7
  export const BLOBS: "browser/blobs";
8
8
  export const RUM: "rum";
9
+ export const CONNECT: "connect";
9
10
  export const LOGS: "browser/logs";
10
11
  export namespace FEATURE_NAMES {
11
12
  export let ajax: string;
@@ -1 +1 @@
1
- {"version":3,"file":"features.d.ts","sourceRoot":"","sources":["../../../../src/loaders/features/features.js"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,qBAAsB,QAAQ,CAAA;AAC9B,uBAAwB,UAAU,CAAA;AAClC,oBAAqB,eAAe,CAAA;AACpC,kBAAmB,KAAK,CAAA;AACxB,mBAAoB,cAAc,CAAA;;;;;;;;;;;;;;AAmBlC;;;GAGG;AACH;IACE,CAAC,aAAa,CAAC,aAAa,CAAC,SAAG;IAChC,CAAC,aAAa,CAAC,cAAc,CAAC,SAAG;IACjC,CAAC,aAAa,CAAC,OAAO,CAAC,SAAG;IAC1B,CAAC,aAAa,CAAC,QAAQ,CAAC,SAAG;IAC3B,CAAC,aAAa,CAAC,OAAO,CAAC,SAAG;IAC1B,CAAC,aAAa,CAAC,IAAI,CAAC,SAAG;IACvB,CAAC,aAAa,CAAC,YAAY,CAAC,SAAG;IAC/B,CAAC,aAAa,CAAC,aAAa,CAAC,SAAG;IAChC,CAAC,aAAa,CAAC,OAAO,CAAC,SAAG;IAC1B,CAAC,aAAa,CAAC,aAAa,CAAC,SAAI;EAClC;AAED;IACE,CAAC,aAAa,CAAC,aAAa,CAAC,SAAK;IAClC,CAAC,aAAa,CAAC,cAAc,CAAC,SAAQ;IACtC,CAAC,aAAa,CAAC,IAAI,CAAC,SAAQ;IAC5B,CAAC,aAAa,CAAC,OAAO,CAAC,SAAQ;IAC/B,CAAC,aAAa,CAAC,OAAO,CAAC,SAAU;IACjC,CAAC,aAAa,CAAC,QAAQ,CAAC,SAAU;IAClC,CAAC,aAAa,CAAC,YAAY,CAAC,SAAO;IACnC,CAAC,aAAa,CAAC,aAAa,CAAC,SAAO;IACpC,CAAC,aAAa,CAAC,OAAO,CAAC,SAAM;IAC7B,CAAC,aAAa,CAAC,aAAa,CAAC,SAAO;EACrC"}
1
+ {"version":3,"file":"features.d.ts","sourceRoot":"","sources":["../../../../src/loaders/features/features.js"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,qBAAsB,QAAQ,CAAA;AAC9B,uBAAwB,UAAU,CAAA;AAClC,oBAAqB,eAAe,CAAA;AACpC,kBAAmB,KAAK,CAAA;AACxB,sBAAuB,SAAS,CAAA;AAChC,mBAAoB,cAAc,CAAA;;;;;;;;;;;;;;AAmBlC;;;GAGG;AACH;IACE,CAAC,aAAa,CAAC,aAAa,CAAC,SAAG;IAChC,CAAC,aAAa,CAAC,cAAc,CAAC,SAAG;IACjC,CAAC,aAAa,CAAC,OAAO,CAAC,SAAG;IAC1B,CAAC,aAAa,CAAC,QAAQ,CAAC,SAAG;IAC3B,CAAC,aAAa,CAAC,OAAO,CAAC,SAAG;IAC1B,CAAC,aAAa,CAAC,IAAI,CAAC,SAAG;IACvB,CAAC,aAAa,CAAC,YAAY,CAAC,SAAG;IAC/B,CAAC,aAAa,CAAC,aAAa,CAAC,SAAG;IAChC,CAAC,aAAa,CAAC,OAAO,CAAC,SAAG;IAC1B,CAAC,aAAa,CAAC,aAAa,CAAC,SAAI;EAClC;AAED;IACE,CAAC,aAAa,CAAC,aAAa,CAAC,SAAK;IAClC,CAAC,aAAa,CAAC,cAAc,CAAC,SAAQ;IACtC,CAAC,aAAa,CAAC,IAAI,CAAC,SAAQ;IAC5B,CAAC,aAAa,CAAC,OAAO,CAAC,SAAQ;IAC/B,CAAC,aAAa,CAAC,OAAO,CAAC,SAAU;IACjC,CAAC,aAAa,CAAC,QAAQ,CAAC,SAAU;IAClC,CAAC,aAAa,CAAC,YAAY,CAAC,SAAO;IACnC,CAAC,aAAa,CAAC,aAAa,CAAC,SAAO;IACpC,CAAC,aAAa,CAAC,OAAO,CAAC,SAAM;IAC7B,CAAC,aAAa,CAAC,aAAa,CAAC,SAAO;EACrC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@newrelic/browser-agent",
3
- "version": "1.320.0",
3
+ "version": "1.320.1-rc.1",
4
4
  "private": false,
5
5
  "author": "New Relic Browser Agent Team <browser-agent@newrelic.com>",
6
6
  "description": "New Relic Browser Agent",
@@ -294,4 +294,4 @@
294
294
  "README.md",
295
295
  "CHANGELOG.md"
296
296
  ]
297
- }
297
+ }
@@ -41,6 +41,7 @@ const RuntimeModel = {
41
41
  disabled: false,
42
42
  /** @type {Map<string, {staged: boolean, priority: number}>} */
43
43
  drainRegistry: new Map(),
44
+ connector: undefined,
44
45
  harvester: undefined,
45
46
  isolatedBacklog: false,
46
47
  isRecording: false, // true when actively recording, false when paused or stopped
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright 2020-2025 New Relic, Inc. All rights reserved.
2
+ * Copyright 2020-2026 New Relic, Inc. All rights reserved.
3
3
  * SPDX-License-Identifier: Apache-2.0
4
4
  */
5
5
  export function eventListenerOpts (useCapture, abortSignal) {
@@ -0,0 +1,168 @@
1
+ /**
2
+ * Copyright 2020-2026 New Relic, Inc. All rights reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+
6
+ import { isBrowserScope } from '../constants/runtime'
7
+ import { send } from './send'
8
+ import { TimeKeeper } from '../timing/time-keeper'
9
+ import { activateFeatures } from '../util/feature-flags'
10
+ import { now } from '../timing/now'
11
+ import { warn } from '../util/console'
12
+ import { VERSION } from '../constants/env'
13
+ import { CONNECT, FEATURE_NAMES, FEATURE_TO_ENDPOINT } from '../../loaders/features/features'
14
+ import { handle } from '../event-emitter/handle'
15
+ import { SUPPORTABILITY_METRIC_CHANNEL } from '../../features/metrics/constants'
16
+
17
+ const MAX_CONNECT_ATTEMPTS = 3
18
+ const CONNECT_RETRY_BASE_MS = 3000 // affects each retry window proportionally (attempt 2: 0-3s, 3: 0-6s, 4: 0-12s, etc)
19
+
20
+ export class Connector {
21
+ #agentRef
22
+ #connectStartTime
23
+ #numOfAttempts = 0
24
+
25
+ constructor (agentRef) {
26
+ if (!agentRef.init.feature_flags.includes('rum_v2')) return // the Connector does not run in v1; legacy PVE has its own BCS handling
27
+ this.#agentRef = agentRef
28
+ agentRef.runtime.timeKeeper = new TimeKeeper(agentRef.runtime.session)
29
+
30
+ if (isBrowserScope) {
31
+ const cached = agentRef.runtime.session && agentRef.runtime.session.state.cachedRumResponse
32
+ if (cached) {
33
+ // `cachedRumResponse` is stored flat (`{ app, ...flags }`, matching the old v1 RUM response), so re-nest it before applying.
34
+ const { app, ...config } = cached
35
+ this.#applyConnectResponse({ app, config })
36
+ return
37
+ }
38
+ }
39
+ this.makeConnectRequest()
40
+ }
41
+
42
+ makeConnectRequest (retryHeaders) {
43
+ this.#connectStartTime = now()
44
+ return send(this.#agentRef, {
45
+ endpoint: `browser/connect/2/${this.#agentRef.info.licenseKey}`,
46
+ payload: {
47
+ body: {},
48
+ qs: {
49
+ a: this.#agentRef.info.applicationID,
50
+ v: VERSION,
51
+ s: this.#agentRef.runtime.session?.state.value || '0'
52
+ }
53
+ },
54
+ localOpts: { sendEmptyBody: true, headers: retryHeaders },
55
+ raw: true,
56
+ featureName: CONNECT,
57
+ cbFinished: this.#processConnectResponse.bind(this)
58
+ })
59
+ }
60
+
61
+ #applyConnectResponse ({ app, config }) {
62
+ if (!Object.keys(this.#agentRef.runtime.appMetadata).length) this.#agentRef.runtime.appMetadata = app
63
+ activateFeatures(config, this.#agentRef)
64
+ }
65
+
66
+ #processConnectResponse ({ sent, status, retry, xhr, responseText }) {
67
+ const connectEndTime = now()
68
+ const session = this.#agentRef.runtime.session
69
+
70
+ if (session) {
71
+ // Double check that there isn't a response saved (e.g. from another agent/browser tab) btwn the async time of the request and now in a race-condition.
72
+ const cachedResp = session.state.cachedRumResponse
73
+ if (cachedResp) {
74
+ // `cachedRumResponse` is stored flat (`{ app, ...flags }`, matching the old v1 RUM response), so re-nest it before applying.
75
+ const { app, ...config } = cachedResp
76
+ this.#applyConnectResponse({ app, config })
77
+ return
78
+ }
79
+ }
80
+
81
+ const shouldRetry = sent && retry // important to note: no retry if HTTP status is 0
82
+ if (shouldRetry && ++this.#numOfAttempts < MAX_CONNECT_ATTEMPTS) {
83
+ // We use an exponential backoff calculation for the retry to avoid thundering herd, skipping any further processing.
84
+ const delay = Math.floor(Math.random() * CONNECT_RETRY_BASE_MS * (2 ** (this.#numOfAttempts - 1)))
85
+ const retryHeaders = [
86
+ { key: 'X-Retry-Count', value: this.#numOfAttempts },
87
+ { key: 'X-Previous-Status', value: status }
88
+ ]
89
+ setTimeout(() => this.makeConnectRequest(retryHeaders), delay)
90
+ return
91
+ }
92
+
93
+ if (status >= 400 || status === 0) {
94
+ warn(18, status)
95
+
96
+ // Get estimated payload size of our backlog.
97
+ const textEncoder = new TextEncoder()
98
+ const payloadSize = Object.values(newrelic.ee.backlog).reduce((acc, value) => {
99
+ if (!value) return acc
100
+ const encoded = textEncoder.encode(value)
101
+ return acc + encoded.byteLength
102
+ }, 0)
103
+
104
+ // Send SMs about the (last) failed connect request, then abort agent.
105
+ const BCSError = 'BCS/Error/'
106
+ const sm = [{
107
+ params: {
108
+ name: BCSError + status
109
+ },
110
+ stats: {
111
+ c: 1
112
+ }
113
+ }, {
114
+ params: {
115
+ name: BCSError + 'Duration/Ms'
116
+ },
117
+ stats: {
118
+ c: 1,
119
+ t: connectEndTime - this.#connectStartTime
120
+ }
121
+ }, {
122
+ params: {
123
+ name: BCSError + 'Dropped/Bytes'
124
+ },
125
+ stats: {
126
+ c: 1,
127
+ t: payloadSize
128
+ }
129
+ }]
130
+ send(this.#agentRef, { // note we have to send it this way because the Metrics feature will never be harvested under this branch of code (BCS failure)
131
+ endpoint: FEATURE_TO_ENDPOINT[FEATURE_NAMES.metrics],
132
+ payload: { body: { sm } },
133
+ featureName: FEATURE_NAMES.metrics
134
+ })
135
+
136
+ this.#agentRef.ee.abort()
137
+ return
138
+ }
139
+
140
+ let resp
141
+ try {
142
+ resp = JSON.parse(responseText)
143
+ } catch (error) {
144
+ warn(53, error)
145
+ this.#agentRef.ee.abort()
146
+ return
147
+ }
148
+ // store the response for other pages later in same session or in parallel tabs; flatten `.config` into the old v1 RUM response shape
149
+ if (session) session.write({ cachedRumResponse: { app: resp.app, ...resp.config } })
150
+ try {
151
+ const wasReady = this.#agentRef.runtime.timeKeeper.ready
152
+ this.#agentRef.runtime.timeKeeper.processRumRequest(xhr, this.#connectStartTime, connectEndTime, resp.app.nrServerTime)
153
+ if (!this.#agentRef.runtime.timeKeeper.ready) throw new Error('TimeKeeper not ready')
154
+
155
+ // If timeKeeper's origin time is ahead of nrServerTime, then the timestamp is invalid. Report a supportability metric.
156
+ const timeDiff = this.#agentRef.runtime.timeKeeper.correctedOriginTime - resp.app.nrServerTime
157
+ if (wasReady && timeDiff > 0) {
158
+ handle(SUPPORTABILITY_METRIC_CHANNEL, ['Generic/TimeKeeper/InvalidTimestamp/Seen', timeDiff], undefined, FEATURE_NAMES.metrics, this.#agentRef.ee)
159
+ }
160
+ } catch (error) {
161
+ warn(17, error)
162
+ this.#agentRef.ee.abort()
163
+ return
164
+ }
165
+
166
+ this.#applyConnectResponse(resp)
167
+ }
168
+ }
@@ -22,23 +22,21 @@ export class Harvester {
22
22
  constructor (agentRef) {
23
23
  this.agentRef = agentRef
24
24
 
25
- // Create obfuscator for harvest metadata (referrer URL, etc.)
26
25
  // No event type specified - applies to all harvests regardless of feature
27
26
  this.obfuscator = new Obfuscator(agentRef)
28
-
29
- subscribeToEOL(() => { // do one last harvest round or check
30
- this.initializedAggregates.forEach(aggregateInst => { // let all features wrap up things needed to do before ANY harvest in case there's last minute cross-feature data dependencies
31
- if (typeof aggregateInst.harvestOpts.beforeUnload === 'function') aggregateInst.harvestOpts.beforeUnload()
32
- })
33
- this.initializedAggregates.forEach(aggregateInst => this.triggerHarvestFor(aggregateInst, { isFinalHarvest: true }))
34
- /* This callback should run in bubble phase, so that CWV api, like "onLCP", is called before the final harvest so that emitted timings are part of last outgoing. */
35
- }, false)
36
27
  }
37
28
 
38
29
  startTimer (harvestInterval = this.agentRef.init.harvest.interval) {
39
30
  if (this.#started) return
40
31
  this.#started = true
41
32
 
33
+ subscribeToEOL(() => {
34
+ this.initializedAggregates.forEach(aggregateInst => { // let all features wrap up things needed to do before ANY harvest in case there's last minute cross-feature data dependencies
35
+ if (typeof aggregateInst.harvestOpts.beforeUnload === 'function') aggregateInst.harvestOpts.beforeUnload()
36
+ })
37
+ this.initializedAggregates.forEach(aggregateInst => this.triggerHarvestFor(aggregateInst, { isFinalHarvest: true }))
38
+ })
39
+
42
40
  const onHarvestInterval = () => {
43
41
  this.initializedAggregates.forEach(aggregateInst => this.triggerHarvestFor(aggregateInst))
44
42
  setTimeout(onHarvestInterval, harvestInterval * 1000) // repeat in X seconds
@@ -2,7 +2,7 @@
2
2
  * Copyright 2020-2026 New Relic, Inc. All rights reserved.
3
3
  * SPDX-License-Identifier: Apache-2.0
4
4
  */
5
- import { JSERRORS, RUM, EVENTS, FEATURE_NAMES, BLOBS, LOGS } from '../../loaders/features/features'
5
+ import { JSERRORS, RUM, EVENTS, FEATURE_NAMES, BLOBS, LOGS, CONNECT } from '../../loaders/features/features'
6
6
  import { VERSION } from '../constants/env'
7
7
  import { globalScope, isWorkerScope } from '../constants/runtime'
8
8
  import { handle } from '../event-emitter/handle'
@@ -12,7 +12,7 @@ import { cleanURL } from '../url/clean-url'
12
12
  import { obj, param } from '../url/encode'
13
13
  import { warn } from '../util/console'
14
14
  import { stringify } from '../util/stringify'
15
- import { xhr as xhrMethod, xhrFetch as fetchMethod } from '../util/submit-data'
15
+ import { xhr as xhrMethod, xhrFetch as fetchMethod, getSubmitMethod } from '../util/submit-data'
16
16
  import { dispatchGlobalEvent } from '../dispatch/global-event'
17
17
 
18
18
  /**
@@ -27,7 +27,7 @@ const warnings = {}
27
27
  * @param {NetworkSendSpec} spec Specification for sending data
28
28
  * @returns {boolean} True if a network call was made. Note that this does not mean or guarantee that it was successful.
29
29
  */
30
- export function send (agentRef, { endpoint, payload, localOpts = {}, submitMethod, cbFinished, raw, featureName, endpointVersion = 1, harvesterObfuscator }) {
30
+ export function send (agentRef, { endpoint, payload, localOpts = {}, submitMethod = getSubmitMethod(), cbFinished, raw, featureName, endpointVersion = 1, harvesterObfuscator }) {
31
31
  if (!agentRef.info.errorBeacon) return false
32
32
 
33
33
  let { body, qs } = cleanPayload(payload)
@@ -39,16 +39,18 @@ export function send (agentRef, { endpoint, payload, localOpts = {}, submitMetho
39
39
 
40
40
  const protocol = agentRef.init.ssl === false ? 'http' : 'https'
41
41
  const perceivedBeacon = agentRef.init.proxy.beacon || agentRef.info.errorBeacon
42
+ const includeEndpointName = endpoint !== RUM || endpointVersion !== 1
42
43
  const url = raw
43
44
  ? `${protocol}://${perceivedBeacon}/${endpoint}`
44
- : `${protocol}://${perceivedBeacon}${endpoint !== RUM ? '/' + endpoint : ''}/${endpointVersion}/${agentRef.info.licenseKey}`
45
+ : `${protocol}://${perceivedBeacon}${includeEndpointName ? '/' + endpoint : ''}/${endpointVersion}/${agentRef.info.licenseKey}`
45
46
  const baseParams = !raw ? baseQueryString(agentRef, qs, endpoint, harvesterObfuscator) : ''
46
47
  let payloadParams = obj(qs, agentRef.runtime.maxBytes)
47
48
  if (baseParams === '' && payloadParams.startsWith('&')) {
48
49
  payloadParams = payloadParams.substring(1)
49
50
  }
50
51
 
51
- const fullUrl = `${url}?${baseParams}${payloadParams}`
52
+ const queryString = `${baseParams}${payloadParams}`
53
+ const fullUrl = queryString ? `${url}?${queryString}` : url // omit the '?' if there are no query params
52
54
  const gzip = !!qs?.attributes?.includes('gzip')
53
55
 
54
56
  // all gzipped data is already in the correct format and needs no transformation
@@ -61,7 +63,7 @@ export function send (agentRef, { endpoint, payload, localOpts = {}, submitMetho
61
63
  // Warn--once per endpoint--if the agent tries to send large payloads
62
64
  if (endpoint !== BLOBS && stringBody.length > 750000 && (warnings[endpoint] = (warnings[endpoint] || 0) + 1) === 1) warn(28, endpoint)
63
65
 
64
- const headers = [{ key: 'content-type', value: 'text/plain' }]
66
+ const headers = [{ key: 'content-type', value: 'text/plain' }, ...(localOpts.headers || [])]
65
67
 
66
68
  /* Since workers don't support sendBeacon right now, they can only use XHR method.
67
69
  Because they still do permit synch XHR, the idea is that at final harvest time (worker is closing),
@@ -92,6 +94,7 @@ export function send (agentRef, { endpoint, payload, localOpts = {}, submitMetho
92
94
 
93
95
  function trackHarvestMetadata () {
94
96
  try {
97
+ if (featureName === CONNECT) return
95
98
  if (featureName === FEATURE_NAMES.jserrors && !body?.err) return
96
99
 
97
100
  const hasReplay = baseParams.includes('hr=1')
@@ -189,7 +192,6 @@ function baseQueryString (agentRef, qs, endpoint, harvesterObfuscator) {
189
192
  transactionNameParam(),
190
193
  param('ct', agentRef.runtime.customTransaction),
191
194
  '&rst=' + now(),
192
- '&ck=0', // ck param DEPRECATED - still expected by backend
193
195
  '&s=' + (session?.state.value || '0'), // the 0 id encaps all untrackable and default traffic
194
196
  param('ref', ref),
195
197
  param('ptid', (agentRef.runtime.ptid ? '' + agentRef.runtime.ptid : ''))
@@ -129,11 +129,11 @@ export function truncateAsString (data) {
129
129
  }
130
130
 
131
131
  /**
132
- * Creates string adder functions for BEL serialization with obfuscation and optional truncation.
132
+ * Creates string adder functions for BEL serialization with obfuscation and optional truncation, as well as raw string.
133
133
  * This ensures a single string table is used while providing separate handling for regular vs payload attributes.
134
134
  * @param {Function} getAddStringContext - Function that creates a new string table context
135
135
  * @param {Object} obfuscator - Optional obfuscator instance for string obfuscation
136
- * @returns {{addString: Function, addStringWithTruncation: Function}} Object containing both string adder functions
136
+ * @returns {{addString: Function, addStringRaw: Function, addStringWithTruncation: Function}} Object containing various string adder functions
137
137
  */
138
138
  export function createStringAdders (getAddStringContext, obfuscator) {
139
139
  const addStringRaw = getAddStringContext()
@@ -148,6 +148,7 @@ export function createStringAdders (getAddStringContext, obfuscator) {
148
148
 
149
149
  return {
150
150
  addString: (str) => processString(str, false),
151
+ addStringRaw: (str) => addStringRaw(str),
151
152
  addStringWithTruncation: (str) => processString(str, true)
152
153
  }
153
154
  }
@@ -40,7 +40,16 @@ export function getAddStringContext (obfuscator, truncator) {
40
40
  }
41
41
  }
42
42
 
43
- export function addCustomAttributes (attrs, addString) {
43
+ /**
44
+ * Attributes are serialized according to their types, using the provided serializers. Only the first 64 attributes will be added to the payload.
45
+ * @param attrs
46
+ * @param serializers
47
+ * @param {function} serializers.addKey -function for serializing attribute keys
48
+ * @param {function} serializers.addVal - function for serializing attribute values
49
+ * @returns {*[]}
50
+ */
51
+ export function addCustomAttributes (attrs, serializers) {
52
+ const { addKey, addVal } = serializers
44
53
  var attrParts = []
45
54
 
46
55
  Object.entries(attrs || {}).forEach(([key, val]) => {
@@ -48,13 +57,13 @@ export function addCustomAttributes (attrs, addString) {
48
57
  var type = 5
49
58
  var serializedValue
50
59
  // add key to string table first
51
- key = addString(key, false)
60
+ key = addKey(key)
52
61
 
53
62
  switch (typeof val) {
54
63
  case 'object':
55
64
  if (val) {
56
65
  // serialize objects to strings
57
- serializedValue = addString(stringify(val))
66
+ serializedValue = addVal(stringify(val))
58
67
  } else {
59
68
  // null attribute type
60
69
  type = 9
@@ -73,7 +82,7 @@ export function addCustomAttributes (attrs, addString) {
73
82
  type = 9
74
83
  break
75
84
  default:
76
- serializedValue = addString(val)
85
+ serializedValue = addVal(val)
77
86
  }
78
87
 
79
88
  attrParts.push([type, key + (serializedValue ? ',' + serializedValue : '')])
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright 2020-2025 New Relic, Inc. All rights reserved.
2
+ * Copyright 2020-2026 New Relic, Inc. All rights reserved.
3
3
  * SPDX-License-Identifier: Apache-2.0
4
4
  */
5
5
  import { Timer } from './timer'
@@ -53,7 +53,7 @@ export class InteractionTimer extends Timer {
53
53
  if (state === 'hidden') this.pause()
54
54
  // vis change --> visible is treated like a new interaction with the page
55
55
  else this.resume()
56
- }, false, false, this.abortController?.signal)
56
+ }, false, this.abortController?.signal)
57
57
  }
58
58
  }
59
59