@newrelic/browser-agent 1.322.0-rc.9 → 1.323.0-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/dist/cjs/common/constants/env.cdn.js +1 -1
- package/dist/cjs/common/constants/env.npm.js +1 -1
- package/dist/cjs/common/harvest/connector.js +2 -0
- package/dist/cjs/features/ajax/aggregate/index.js +3 -1
- package/dist/cjs/features/ajax/instrument/distributed-tracing.js +12 -4
- package/dist/esm/common/constants/env.cdn.js +1 -1
- package/dist/esm/common/constants/env.npm.js +1 -1
- package/dist/esm/common/harvest/connector.js +2 -0
- package/dist/esm/features/ajax/aggregate/index.js +3 -1
- package/dist/esm/features/ajax/instrument/distributed-tracing.js +12 -4
- package/dist/types/common/harvest/connector.d.ts.map +1 -1
- package/dist/types/features/ajax/instrument/distributed-tracing.d.ts +1 -0
- package/dist/types/features/ajax/instrument/distributed-tracing.d.ts.map +1 -1
- package/package.json +4 -1
- package/src/common/harvest/connector.js +2 -0
- package/src/features/ajax/aggregate/index.js +3 -3
- package/src/features/ajax/instrument/distributed-tracing.js +12 -4
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,20 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [1.323.0](https://github.com/newrelic/newrelic-browser-agent/compare/v1.322.0...v1.323.0) (2026-09-30)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* Add internal adoption metrics for AJAX Payloads ([#1842](https://github.com/newrelic/newrelic-browser-agent/issues/1842)) ([055b917](https://github.com/newrelic/newrelic-browser-agent/commit/055b9171ef6393da18ee64cc156c51af4ac1498e))
|
|
12
|
+
* Harvest SR on switch from ERROR to FULL mode ([#1864](https://github.com/newrelic/newrelic-browser-agent/issues/1864)) ([b95f9cd](https://github.com/newrelic/newrelic-browser-agent/commit/b95f9cd065225ae4386a75bfa5e7acc4adb528d9))
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
### Bug Fixes
|
|
16
|
+
|
|
17
|
+
* **ajax:** correct DT header timestamp to server time ([#1867](https://github.com/newrelic/newrelic-browser-agent/issues/1867)) ([5e86506](https://github.com/newrelic/newrelic-browser-agent/commit/5e865062e5162acc7c4ee2924cf7b1db9d8f5685))
|
|
18
|
+
* Ensure timeKeeper readiness on Connector race condition ([#1875](https://github.com/newrelic/newrelic-browser-agent/issues/1875)) ([45de2d8](https://github.com/newrelic/newrelic-browser-agent/commit/45de2d85c730a0dd189ed6f14c7166e89ef3e1a0))
|
|
19
|
+
|
|
6
20
|
## [1.322.0](https://github.com/newrelic/newrelic-browser-agent/compare/v1.321.0...v1.322.0) (2026-09-11)
|
|
7
21
|
|
|
8
22
|
|
|
@@ -17,7 +17,7 @@ exports.VERSION = exports.RRWEB_VERSION = exports.RRWEB_PACKAGE_NAME = exports.D
|
|
|
17
17
|
/**
|
|
18
18
|
* Exposes the version of the agent
|
|
19
19
|
*/
|
|
20
|
-
const VERSION = exports.VERSION = "1.
|
|
20
|
+
const VERSION = exports.VERSION = "1.323.0-rc.0";
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
23
|
* Exposes the build type of the agent
|
|
@@ -17,7 +17,7 @@ exports.VERSION = exports.RRWEB_VERSION = exports.RRWEB_PACKAGE_NAME = exports.D
|
|
|
17
17
|
/**
|
|
18
18
|
* Exposes the version of the agent
|
|
19
19
|
*/
|
|
20
|
-
const VERSION = exports.VERSION = "1.
|
|
20
|
+
const VERSION = exports.VERSION = "1.323.0-rc.0";
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
23
|
* Exposes the build type of the agent
|
|
@@ -90,6 +90,8 @@ class Connector {
|
|
|
90
90
|
if (cachedResp) {
|
|
91
91
|
// Report that we've seen a race condition on updating session state
|
|
92
92
|
(0, _handle.handle)(_constants.SUPPORTABILITY_METRIC_CHANNEL, ['Session/RaceCondition/Seen'], undefined, _features.FEATURE_NAMES.metrics, this.#agentRef.ee);
|
|
93
|
+
// The other tab/agent that wrote this cached response also wrote its own serverTimeDiff to the session around the same time. TimeKeeper was constructed before that happened, so re-check the session now to pick it up.
|
|
94
|
+
this.#agentRef.runtime.timeKeeper.processStoredDiff();
|
|
93
95
|
// `cachedRumResponse` is stored flat (`{ app, ...flags }`, matching the old v1 RUM response), so re-nest it before applying.
|
|
94
96
|
const {
|
|
95
97
|
app,
|
|
@@ -121,7 +121,9 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
121
121
|
if (ctx.dt) {
|
|
122
122
|
event.spanId = ctx.dt.spanId;
|
|
123
123
|
event.traceId = ctx.dt.traceId;
|
|
124
|
-
|
|
124
|
+
// ctx.dt.timestampCorrected holds the already NR-server-time-corrected value (see distributed-tracing.js) if
|
|
125
|
+
// timeKeeper was ready when the request started -- reuse it if present, otherwise correct it here now, to avoid double-correcting.
|
|
126
|
+
event.spanTimestamp = ctx.dt.timestampCorrected ?? Math.floor(this.agentRef.runtime.timeKeeper.correctAbsoluteTimestamp(ctx.dt.timestamp));
|
|
125
127
|
}
|
|
126
128
|
if (event.gql) this.reportSupportabilityMetric('Ajax/Events/GraphQL/Bytes-Added', (0, _stringify.stringify)(event.gql).length);
|
|
127
129
|
|
|
@@ -9,7 +9,7 @@ var _parseUrl = require("../../../common/url/parse-url");
|
|
|
9
9
|
var _runtime = require("../../../common/constants/runtime");
|
|
10
10
|
var _stringify = require("../../../common/util/stringify");
|
|
11
11
|
/**
|
|
12
|
-
* Copyright 2020-
|
|
12
|
+
* Copyright 2020-2026 New Relic, Inc. All rights reserved.
|
|
13
13
|
* SPDX-License-Identifier: Apache-2.0
|
|
14
14
|
*/
|
|
15
15
|
|
|
@@ -31,17 +31,25 @@ class DT {
|
|
|
31
31
|
var spanId = (0, _uniqueId.generateSpanId)();
|
|
32
32
|
var traceId = (0, _uniqueId.generateTraceId)();
|
|
33
33
|
var timestamp = Date.now();
|
|
34
|
+
// Correct to NR server time when timeKeeper is available/ready; if it isn't connected yet (e.g. RUM hasn't
|
|
35
|
+
// completed), accept the uncorrected local timestamp. This only affects the receiving APM agent's computed
|
|
36
|
+
// transportDuration value on its Span -- it is not used for anything else in this payload.
|
|
37
|
+
var timestampCorrected;
|
|
38
|
+
if (this.agentRef.runtime?.timeKeeper?.ready) {
|
|
39
|
+
timestampCorrected = Math.floor(this.agentRef.runtime.timeKeeper.correctAbsoluteTimestamp(timestamp));
|
|
40
|
+
}
|
|
34
41
|
var payload = {
|
|
35
42
|
spanId,
|
|
36
43
|
traceId,
|
|
37
|
-
timestamp
|
|
44
|
+
timestamp,
|
|
45
|
+
timestampCorrected
|
|
38
46
|
};
|
|
39
47
|
if (parsedOrigin.sameOrigin || this.isAllowedOrigin(parsedOrigin) && this.useTraceContextHeadersForCors()) {
|
|
40
48
|
payload.traceContextParentHeader = this.generateTraceContextParentHeader(spanId, traceId);
|
|
41
|
-
payload.traceContextStateHeader = this.generateTraceContextStateHeader(spanId, timestamp, accountId, agentId, trustKey);
|
|
49
|
+
payload.traceContextStateHeader = this.generateTraceContextStateHeader(spanId, timestampCorrected ?? timestamp, accountId, agentId, trustKey);
|
|
42
50
|
}
|
|
43
51
|
if (parsedOrigin.sameOrigin && !this.excludeNewrelicHeader() || !parsedOrigin.sameOrigin && this.isAllowedOrigin(parsedOrigin) && this.useNewrelicHeaderForCors()) {
|
|
44
|
-
payload.newrelicHeader = this.generateTraceHeader(spanId, traceId, timestamp, accountId, agentId, trustKey);
|
|
52
|
+
payload.newrelicHeader = this.generateTraceHeader(spanId, traceId, timestampCorrected ?? timestamp, accountId, agentId, trustKey);
|
|
45
53
|
}
|
|
46
54
|
return payload;
|
|
47
55
|
}
|
|
@@ -84,6 +84,8 @@ export class Connector {
|
|
|
84
84
|
if (cachedResp) {
|
|
85
85
|
// Report that we've seen a race condition on updating session state
|
|
86
86
|
handle(SUPPORTABILITY_METRIC_CHANNEL, ['Session/RaceCondition/Seen'], undefined, FEATURE_NAMES.metrics, this.#agentRef.ee);
|
|
87
|
+
// The other tab/agent that wrote this cached response also wrote its own serverTimeDiff to the session around the same time. TimeKeeper was constructed before that happened, so re-check the session now to pick it up.
|
|
88
|
+
this.#agentRef.runtime.timeKeeper.processStoredDiff();
|
|
87
89
|
// `cachedRumResponse` is stored flat (`{ app, ...flags }`, matching the old v1 RUM response), so re-nest it before applying.
|
|
88
90
|
const {
|
|
89
91
|
app,
|
|
@@ -114,7 +114,9 @@ export class Aggregate extends AggregateBase {
|
|
|
114
114
|
if (ctx.dt) {
|
|
115
115
|
event.spanId = ctx.dt.spanId;
|
|
116
116
|
event.traceId = ctx.dt.traceId;
|
|
117
|
-
|
|
117
|
+
// ctx.dt.timestampCorrected holds the already NR-server-time-corrected value (see distributed-tracing.js) if
|
|
118
|
+
// timeKeeper was ready when the request started -- reuse it if present, otherwise correct it here now, to avoid double-correcting.
|
|
119
|
+
event.spanTimestamp = ctx.dt.timestampCorrected ?? Math.floor(this.agentRef.runtime.timeKeeper.correctAbsoluteTimestamp(ctx.dt.timestamp));
|
|
118
120
|
}
|
|
119
121
|
if (event.gql) this.reportSupportabilityMetric('Ajax/Events/GraphQL/Bytes-Added', stringify(event.gql).length);
|
|
120
122
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Copyright 2020-
|
|
2
|
+
* Copyright 2020-2026 New Relic, Inc. All rights reserved.
|
|
3
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
*/
|
|
5
5
|
import { generateSpanId, generateTraceId } from '../../../common/ids/unique-id';
|
|
@@ -24,17 +24,25 @@ export class DT {
|
|
|
24
24
|
var spanId = generateSpanId();
|
|
25
25
|
var traceId = generateTraceId();
|
|
26
26
|
var timestamp = Date.now();
|
|
27
|
+
// Correct to NR server time when timeKeeper is available/ready; if it isn't connected yet (e.g. RUM hasn't
|
|
28
|
+
// completed), accept the uncorrected local timestamp. This only affects the receiving APM agent's computed
|
|
29
|
+
// transportDuration value on its Span -- it is not used for anything else in this payload.
|
|
30
|
+
var timestampCorrected;
|
|
31
|
+
if (this.agentRef.runtime?.timeKeeper?.ready) {
|
|
32
|
+
timestampCorrected = Math.floor(this.agentRef.runtime.timeKeeper.correctAbsoluteTimestamp(timestamp));
|
|
33
|
+
}
|
|
27
34
|
var payload = {
|
|
28
35
|
spanId,
|
|
29
36
|
traceId,
|
|
30
|
-
timestamp
|
|
37
|
+
timestamp,
|
|
38
|
+
timestampCorrected
|
|
31
39
|
};
|
|
32
40
|
if (parsedOrigin.sameOrigin || this.isAllowedOrigin(parsedOrigin) && this.useTraceContextHeadersForCors()) {
|
|
33
41
|
payload.traceContextParentHeader = this.generateTraceContextParentHeader(spanId, traceId);
|
|
34
|
-
payload.traceContextStateHeader = this.generateTraceContextStateHeader(spanId, timestamp, accountId, agentId, trustKey);
|
|
42
|
+
payload.traceContextStateHeader = this.generateTraceContextStateHeader(spanId, timestampCorrected ?? timestamp, accountId, agentId, trustKey);
|
|
35
43
|
}
|
|
36
44
|
if (parsedOrigin.sameOrigin && !this.excludeNewrelicHeader() || !parsedOrigin.sameOrigin && this.isAllowedOrigin(parsedOrigin) && this.useNewrelicHeaderForCors()) {
|
|
37
|
-
payload.newrelicHeader = this.generateTraceHeader(spanId, traceId, timestamp, accountId, agentId, trustKey);
|
|
45
|
+
payload.newrelicHeader = this.generateTraceHeader(spanId, traceId, timestampCorrected ?? timestamp, accountId, agentId, trustKey);
|
|
38
46
|
}
|
|
39
47
|
return payload;
|
|
40
48
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connector.d.ts","sourceRoot":"","sources":["../../../../src/common/harvest/connector.js"],"names":[],"mappings":"AAmBA;IAKE,2BAeC;IAED,+CAiBC;;
|
|
1
|
+
{"version":3,"file":"connector.d.ts","sourceRoot":"","sources":["../../../../src/common/harvest/connector.js"],"names":[],"mappings":"AAmBA;IAKE,2BAeC;IAED,+CAiBC;;CAiHF"}
|
|
@@ -5,6 +5,7 @@ export class DT {
|
|
|
5
5
|
spanId: string;
|
|
6
6
|
traceId: string;
|
|
7
7
|
timestamp: number;
|
|
8
|
+
timestampCorrected: number | undefined;
|
|
8
9
|
} | null;
|
|
9
10
|
generateTraceContextParentHeader(spanId: any, traceId: any): string;
|
|
10
11
|
generateTraceContextStateHeader(spanId: any, timestamp: any, accountId: any, appId: any, trustKey: any): string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"distributed-tracing.d.ts","sourceRoot":"","sources":["../../../../../src/features/ajax/instrument/distributed-tracing.js"],"names":[],"mappings":"AASA;IACE,2BAEC;IADC,cAAwB;IAG1B
|
|
1
|
+
{"version":3,"file":"distributed-tracing.d.ts","sourceRoot":"","sources":["../../../../../src/features/ajax/instrument/distributed-tracing.js"],"names":[],"mappings":"AASA;IACE,2BAEC;IADC,cAAwB;IAG1B;;;;;aA8CC;IAED,oEAEC;IAED,gHASC;IAED,yHAsBC;IAID,4CAEC;IAED,4CAkBC;IAGD,iCAMC;IAED,oCAMC;IAED,yCAMC;CACF"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@newrelic/browser-agent",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.323.0-rc.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"author": "New Relic Browser Agent Team <browser-agent@newrelic.com>",
|
|
6
6
|
"description": "New Relic Browser Agent",
|
|
@@ -206,7 +206,10 @@
|
|
|
206
206
|
"test-server": "node ./tools/wdio/bin/server",
|
|
207
207
|
"lt:update-browsers": "node ./tools/browsers-lists/lt-update-supported.mjs",
|
|
208
208
|
"lt:upload-webview-assets": "node ./tools/lambda-test/upload-webview-assets.mjs",
|
|
209
|
+
"build:frameworks": "npm run build:npm && npm --prefix ./tools/test-builds run build-frameworks",
|
|
209
210
|
"tools:test-builds": "npm --prefix ./tools/test-builds run build-all",
|
|
211
|
+
"test-builds:bump-latest": "node ./tools/test-builds/bump-latest.mjs",
|
|
212
|
+
"test-builds:framework-report": "node ./tools/test-builds/generate-framework-report.mjs",
|
|
210
213
|
"third-party-updates": "oss third-party manifest --includeOptDeps && oss third-party notices --includeOptDeps",
|
|
211
214
|
"prepare": "husky install",
|
|
212
215
|
"npm:build:esm": "npx babel --env-name npm-esm --out-dir dist/esm --out-file-extension .js ./src",
|
|
@@ -73,6 +73,8 @@ export class Connector {
|
|
|
73
73
|
if (cachedResp) {
|
|
74
74
|
// Report that we've seen a race condition on updating session state
|
|
75
75
|
handle(SUPPORTABILITY_METRIC_CHANNEL, ['Session/RaceCondition/Seen'], undefined, FEATURE_NAMES.metrics, this.#agentRef.ee)
|
|
76
|
+
// The other tab/agent that wrote this cached response also wrote its own serverTimeDiff to the session around the same time. TimeKeeper was constructed before that happened, so re-check the session now to pick it up.
|
|
77
|
+
this.#agentRef.runtime.timeKeeper.processStoredDiff()
|
|
76
78
|
// `cachedRumResponse` is stored flat (`{ app, ...flags }`, matching the old v1 RUM response), so re-nest it before applying.
|
|
77
79
|
const { app, ...config } = cachedResp
|
|
78
80
|
this.#applyConnectResponse({ app, config })
|
|
@@ -129,9 +129,9 @@ export class Aggregate extends AggregateBase {
|
|
|
129
129
|
if (ctx.dt) {
|
|
130
130
|
event.spanId = ctx.dt.spanId
|
|
131
131
|
event.traceId = ctx.dt.traceId
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
)
|
|
132
|
+
// ctx.dt.timestampCorrected holds the already NR-server-time-corrected value (see distributed-tracing.js) if
|
|
133
|
+
// timeKeeper was ready when the request started -- reuse it if present, otherwise correct it here now, to avoid double-correcting.
|
|
134
|
+
event.spanTimestamp = ctx.dt.timestampCorrected ?? Math.floor(this.agentRef.runtime.timeKeeper.correctAbsoluteTimestamp(ctx.dt.timestamp))
|
|
135
135
|
}
|
|
136
136
|
|
|
137
137
|
if (event.gql) this.reportSupportabilityMetric('Ajax/Events/GraphQL/Bytes-Added', stringify(event.gql).length)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Copyright 2020-
|
|
2
|
+
* Copyright 2020-2026 New Relic, Inc. All rights reserved.
|
|
3
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
*/
|
|
5
5
|
import { generateSpanId, generateTraceId } from '../../../common/ids/unique-id'
|
|
@@ -29,23 +29,31 @@ export class DT {
|
|
|
29
29
|
var spanId = generateSpanId()
|
|
30
30
|
var traceId = generateTraceId()
|
|
31
31
|
var timestamp = Date.now()
|
|
32
|
+
// Correct to NR server time when timeKeeper is available/ready; if it isn't connected yet (e.g. RUM hasn't
|
|
33
|
+
// completed), accept the uncorrected local timestamp. This only affects the receiving APM agent's computed
|
|
34
|
+
// transportDuration value on its Span -- it is not used for anything else in this payload.
|
|
35
|
+
var timestampCorrected
|
|
36
|
+
if (this.agentRef.runtime?.timeKeeper?.ready) {
|
|
37
|
+
timestampCorrected = Math.floor(this.agentRef.runtime.timeKeeper.correctAbsoluteTimestamp(timestamp))
|
|
38
|
+
}
|
|
32
39
|
|
|
33
40
|
var payload = {
|
|
34
41
|
spanId,
|
|
35
42
|
traceId,
|
|
36
|
-
timestamp
|
|
43
|
+
timestamp,
|
|
44
|
+
timestampCorrected
|
|
37
45
|
}
|
|
38
46
|
|
|
39
47
|
if (parsedOrigin.sameOrigin ||
|
|
40
48
|
(this.isAllowedOrigin(parsedOrigin) && this.useTraceContextHeadersForCors())) {
|
|
41
49
|
payload.traceContextParentHeader = this.generateTraceContextParentHeader(spanId, traceId)
|
|
42
|
-
payload.traceContextStateHeader = this.generateTraceContextStateHeader(spanId, timestamp,
|
|
50
|
+
payload.traceContextStateHeader = this.generateTraceContextStateHeader(spanId, timestampCorrected ?? timestamp,
|
|
43
51
|
accountId, agentId, trustKey)
|
|
44
52
|
}
|
|
45
53
|
|
|
46
54
|
if ((parsedOrigin.sameOrigin && !this.excludeNewrelicHeader()) ||
|
|
47
55
|
(!parsedOrigin.sameOrigin && this.isAllowedOrigin(parsedOrigin) && this.useNewrelicHeaderForCors())) {
|
|
48
|
-
payload.newrelicHeader = this.generateTraceHeader(spanId, traceId, timestamp, accountId,
|
|
56
|
+
payload.newrelicHeader = this.generateTraceHeader(spanId, traceId, timestampCorrected ?? timestamp, accountId,
|
|
49
57
|
agentId, trustKey)
|
|
50
58
|
}
|
|
51
59
|
|