@newrelic/browser-agent 1.288.0 → 1.288.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.
- package/CHANGELOG.md +8 -0
- package/dist/cjs/common/constants/env.cdn.js +1 -1
- package/dist/cjs/common/constants/env.npm.js +1 -1
- package/dist/cjs/features/session_replay/shared/recorder.js +1 -1
- package/dist/cjs/features/soft_navigations/aggregate/index.js +1 -8
- package/dist/cjs/features/utils/aggregate-base.js +7 -5
- package/dist/cjs/features/utils/event-store-manager.js +15 -5
- package/dist/esm/common/constants/env.cdn.js +1 -1
- package/dist/esm/common/constants/env.npm.js +1 -1
- package/dist/esm/features/session_replay/shared/recorder.js +1 -1
- package/dist/esm/features/soft_navigations/aggregate/index.js +1 -8
- package/dist/esm/features/utils/aggregate-base.js +7 -5
- package/dist/esm/features/utils/event-store-manager.js +15 -6
- package/dist/types/features/soft_navigations/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/utils/aggregate-base.d.ts.map +1 -1
- package/dist/types/features/utils/event-store-manager.d.ts +6 -4
- package/dist/types/features/utils/event-store-manager.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/features/session_replay/shared/recorder.js +1 -1
- package/src/features/soft_navigations/aggregate/index.js +1 -9
- package/src/features/utils/aggregate-base.js +7 -5
- package/src/features/utils/event-store-manager.js +18 -5
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,14 @@
|
|
|
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.288.1](https://github.com/newrelic/newrelic-browser-agent/compare/v1.288.0...v1.288.1) (2025-04-18)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
* Call handle directly for submitting SM from SR recorder ([#1453](https://github.com/newrelic/newrelic-browser-agent/issues/1453)) ([4920580](https://github.com/newrelic/newrelic-browser-agent/commit/49205807b6038afb32e3f04ebabedfe5fc11456b))
|
|
12
|
+
* Ensure event buffer always exists ([#1452](https://github.com/newrelic/newrelic-browser-agent/issues/1452)) ([56e75b2](https://github.com/newrelic/newrelic-browser-agent/commit/56e75b243b87d1d44e8014ac0ad5f408f0d145c5))
|
|
13
|
+
|
|
6
14
|
## [1.288.0](https://github.com/newrelic/newrelic-browser-agent/compare/v1.287.0...v1.288.0) (2025-04-16)
|
|
7
15
|
|
|
8
16
|
|
|
@@ -17,7 +17,7 @@ exports.VERSION = exports.RRWEB_VERSION = exports.DIST_METHOD = exports.BUILD_EN
|
|
|
17
17
|
/**
|
|
18
18
|
* Exposes the version of the agent
|
|
19
19
|
*/
|
|
20
|
-
const VERSION = exports.VERSION = "1.288.
|
|
20
|
+
const VERSION = exports.VERSION = "1.288.1";
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
23
|
* Exposes the build type of the agent
|
|
@@ -17,7 +17,7 @@ exports.VERSION = exports.RRWEB_VERSION = exports.DIST_METHOD = exports.BUILD_EN
|
|
|
17
17
|
/**
|
|
18
18
|
* Exposes the version of the agent
|
|
19
19
|
*/
|
|
20
|
-
const VERSION = exports.VERSION = "1.288.
|
|
20
|
+
const VERSION = exports.VERSION = "1.288.1";
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
23
|
* Exposes the build type of the agent
|
|
@@ -166,7 +166,7 @@ class Recorder {
|
|
|
166
166
|
store(event, isCheckout) {
|
|
167
167
|
if (!event) return;
|
|
168
168
|
if (this.parent.agentRef.runtime?.session?.isAfterSessionExpiry(event.timestamp)) {
|
|
169
|
-
|
|
169
|
+
(0, _handle.handle)(_constants3.SUPPORTABILITY_METRIC_CHANNEL, ['Session/Expired/SessionReplay/Seen'], undefined, _features.FEATURE_NAMES.metrics, this.ee);
|
|
170
170
|
return;
|
|
171
171
|
}
|
|
172
172
|
if (!(this.parent instanceof _aggregateBase.AggregateBase) && this.#preloaded.length) this.currentBufferTarget = this.#preloaded[this.#preloaded.length - 1];else this.currentBufferTarget = this.#events;
|
|
@@ -33,14 +33,7 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
33
33
|
if (agentRef.runtime.session?.isNew) this.initialPageLoadInteraction.customAttributes.isFirstOfSession = true; // mark the hard page load as first of its session
|
|
34
34
|
this.initialPageLoadInteraction.forceSave = true; // unless forcibly ignored, iPL always finish by default
|
|
35
35
|
const ixn = this.initialPageLoadInteraction;
|
|
36
|
-
|
|
37
|
-
if (this.interactionsToHarvest) this.interactionsToHarvest.add(ixn);else {
|
|
38
|
-
/** this.events (ixns to harvest) hasnt been initialized yet... wait for it */
|
|
39
|
-
this.ee.on('entity-added', () => {
|
|
40
|
-
this.interactionsToHarvest = this.events;
|
|
41
|
-
this.interactionsToHarvest.add(ixn);
|
|
42
|
-
});
|
|
43
|
-
}
|
|
36
|
+
this.interactionsToHarvest.add(ixn);
|
|
44
37
|
this.initialPageLoadInteraction = null;
|
|
45
38
|
});
|
|
46
39
|
_timeToFirstByte.timeToFirstByte.subscribe(({
|
|
@@ -39,11 +39,13 @@ class AggregateBase extends _featureBase.FeatureBase {
|
|
|
39
39
|
this.harvestOpts = {}; // features aggregate classes can define custom opts for when their harvest is called
|
|
40
40
|
|
|
41
41
|
const agentEntityGuid = this.agentRef?.runtime?.appMetadata?.agents?.[0]?.entityGuid;
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
42
|
+
this.#setupEventStore(agentEntityGuid);
|
|
43
|
+
if (!agentEntityGuid) {
|
|
44
|
+
/** wait for the entity guid from the rum response and use to it to further configure things to set the default entity to share an indexed entity with entityGuid */
|
|
45
45
|
this.ee.on('entity-added', entity => {
|
|
46
|
-
this
|
|
46
|
+
// not all event managers have this fn, like ST and SR
|
|
47
|
+
// this allows the lookup to work for the default and an entityGuid without creating two separate buffers
|
|
48
|
+
this.events?.setEventStore?.(entity.entityGuid);
|
|
47
49
|
});
|
|
48
50
|
}
|
|
49
51
|
}
|
|
@@ -54,7 +56,7 @@ class AggregateBase extends _featureBase.FeatureBase {
|
|
|
54
56
|
* @returns {void}
|
|
55
57
|
*/
|
|
56
58
|
#setupEventStore(entityGuid) {
|
|
57
|
-
if (this.events
|
|
59
|
+
if (this.events) return;
|
|
58
60
|
switch (this.featureName) {
|
|
59
61
|
// SessionTrace + Replay have their own storage mechanisms.
|
|
60
62
|
case _features.FEATURE_NAMES.sessionTrace:
|
|
@@ -6,11 +6,13 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.EventStoreManager = void 0;
|
|
7
7
|
var _globalEvent = require("../../common/dispatch/global-event");
|
|
8
8
|
var _featureFlags = require("../../common/util/feature-flags");
|
|
9
|
+
var _target = require("../../common/util/target");
|
|
9
10
|
/**
|
|
10
11
|
* Copyright 2020-2025 New Relic, Inc. All rights reserved.
|
|
11
12
|
* SPDX-License-Identifier: Apache-2.0
|
|
12
13
|
*/
|
|
13
14
|
|
|
15
|
+
const DEFAULT_KEY = 'NR_CONTAINER_AGENT'; // this is the default entity guid used for the default storage instance
|
|
14
16
|
/**
|
|
15
17
|
* This layer allows multiple browser entity apps, or "target", to each have their own segregated storage instance.
|
|
16
18
|
* The purpose is so the harvester can send data to different apps within the same agent. Each feature should have a manager if it needs this capability.
|
|
@@ -19,14 +21,16 @@ class EventStoreManager {
|
|
|
19
21
|
/**
|
|
20
22
|
* @param {object} agentRef - reference to base agent class
|
|
21
23
|
* @param {EventBuffer|EventAggregator} storageClass - the type of storage to use in this manager; 'EventBuffer' (1), 'EventAggregator' (2)
|
|
24
|
+
* @param {string} [defaultEntityGuid] - the entity guid to use as the default storage instance; if not provided, a new one is created
|
|
25
|
+
* @param {string} featureName - the name of the feature this manager is for; used for event dispatching
|
|
22
26
|
*/
|
|
23
27
|
constructor(agentRef, storageClass, defaultEntityGuid, featureName) {
|
|
24
28
|
this.agentRef = agentRef;
|
|
25
29
|
this.entityManager = agentRef.runtime.entityManager;
|
|
26
30
|
this.StorageClass = storageClass;
|
|
27
|
-
this.appStorageMap = new Map();
|
|
28
|
-
this.defaultEntity = this.#getEventStore(defaultEntityGuid);
|
|
31
|
+
this.appStorageMap = new Map([[DEFAULT_KEY, new this.StorageClass()]]);
|
|
29
32
|
this.featureName = featureName;
|
|
33
|
+
this.setEventStore(defaultEntityGuid);
|
|
30
34
|
}
|
|
31
35
|
|
|
32
36
|
/**
|
|
@@ -34,11 +38,17 @@ class EventStoreManager {
|
|
|
34
38
|
* @param {string=} targetEntityGuid the lookup
|
|
35
39
|
* @returns {*} ALWAYS returns a storage instance
|
|
36
40
|
*/
|
|
37
|
-
#getEventStore(targetEntityGuid) {
|
|
38
|
-
if (!targetEntityGuid)
|
|
39
|
-
if (!this.appStorageMap.has(targetEntityGuid)) this.appStorageMap.set(targetEntityGuid, new this.StorageClass());
|
|
41
|
+
#getEventStore(targetEntityGuid = DEFAULT_KEY) {
|
|
42
|
+
if (!this.appStorageMap.has(targetEntityGuid)) this.setEventStore(targetEntityGuid);
|
|
40
43
|
return this.appStorageMap.get(targetEntityGuid);
|
|
41
44
|
}
|
|
45
|
+
setEventStore(targetEntityGuid) {
|
|
46
|
+
/** we should already have an event store for the default */
|
|
47
|
+
if (!targetEntityGuid) return;
|
|
48
|
+
/** if the target is the container agent, SHARE the default storage -- otherwise create a new event store */
|
|
49
|
+
const eventStorage = (0, _target.isContainerAgentTarget)(this.entityManager.get(targetEntityGuid), this.agentRef) ? this.appStorageMap.get(DEFAULT_KEY) : new this.StorageClass();
|
|
50
|
+
this.appStorageMap.set(targetEntityGuid, eventStorage);
|
|
51
|
+
}
|
|
42
52
|
|
|
43
53
|
// This class must contain an union of all methods from all supported storage classes and conceptualize away the target app argument.
|
|
44
54
|
|
|
@@ -159,7 +159,7 @@ export class Recorder {
|
|
|
159
159
|
store(event, isCheckout) {
|
|
160
160
|
if (!event) return;
|
|
161
161
|
if (this.parent.agentRef.runtime?.session?.isAfterSessionExpiry(event.timestamp)) {
|
|
162
|
-
|
|
162
|
+
handle(SUPPORTABILITY_METRIC_CHANNEL, ['Session/Expired/SessionReplay/Seen'], undefined, FEATURE_NAMES.metrics, this.ee);
|
|
163
163
|
return;
|
|
164
164
|
}
|
|
165
165
|
if (!(this.parent instanceof AggregateBase) && this.#preloaded.length) this.currentBufferTarget = this.#preloaded[this.#preloaded.length - 1];else this.currentBufferTarget = this.#events;
|
|
@@ -26,14 +26,7 @@ export class Aggregate extends AggregateBase {
|
|
|
26
26
|
if (agentRef.runtime.session?.isNew) this.initialPageLoadInteraction.customAttributes.isFirstOfSession = true; // mark the hard page load as first of its session
|
|
27
27
|
this.initialPageLoadInteraction.forceSave = true; // unless forcibly ignored, iPL always finish by default
|
|
28
28
|
const ixn = this.initialPageLoadInteraction;
|
|
29
|
-
|
|
30
|
-
if (this.interactionsToHarvest) this.interactionsToHarvest.add(ixn);else {
|
|
31
|
-
/** this.events (ixns to harvest) hasnt been initialized yet... wait for it */
|
|
32
|
-
this.ee.on('entity-added', () => {
|
|
33
|
-
this.interactionsToHarvest = this.events;
|
|
34
|
-
this.interactionsToHarvest.add(ixn);
|
|
35
|
-
});
|
|
36
|
-
}
|
|
29
|
+
this.interactionsToHarvest.add(ixn);
|
|
37
30
|
this.initialPageLoadInteraction = null;
|
|
38
31
|
});
|
|
39
32
|
timeToFirstByte.subscribe(({
|
|
@@ -32,11 +32,13 @@ export class AggregateBase extends FeatureBase {
|
|
|
32
32
|
this.harvestOpts = {}; // features aggregate classes can define custom opts for when their harvest is called
|
|
33
33
|
|
|
34
34
|
const agentEntityGuid = this.agentRef?.runtime?.appMetadata?.agents?.[0]?.entityGuid;
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
35
|
+
this.#setupEventStore(agentEntityGuid);
|
|
36
|
+
if (!agentEntityGuid) {
|
|
37
|
+
/** wait for the entity guid from the rum response and use to it to further configure things to set the default entity to share an indexed entity with entityGuid */
|
|
38
38
|
this.ee.on('entity-added', entity => {
|
|
39
|
-
this
|
|
39
|
+
// not all event managers have this fn, like ST and SR
|
|
40
|
+
// this allows the lookup to work for the default and an entityGuid without creating two separate buffers
|
|
41
|
+
this.events?.setEventStore?.(entity.entityGuid);
|
|
40
42
|
});
|
|
41
43
|
}
|
|
42
44
|
}
|
|
@@ -47,7 +49,7 @@ export class AggregateBase extends FeatureBase {
|
|
|
47
49
|
* @returns {void}
|
|
48
50
|
*/
|
|
49
51
|
#setupEventStore(entityGuid) {
|
|
50
|
-
if (this.events
|
|
52
|
+
if (this.events) return;
|
|
51
53
|
switch (this.featureName) {
|
|
52
54
|
// SessionTrace + Replay have their own storage mechanisms.
|
|
53
55
|
case FEATURE_NAMES.sessionTrace:
|
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { dispatchGlobalEvent } from '../../common/dispatch/global-event';
|
|
6
6
|
import { activatedFeatures } from '../../common/util/feature-flags';
|
|
7
|
-
|
|
7
|
+
import { isContainerAgentTarget } from '../../common/util/target';
|
|
8
|
+
const DEFAULT_KEY = 'NR_CONTAINER_AGENT'; // this is the default entity guid used for the default storage instance
|
|
8
9
|
/**
|
|
9
10
|
* This layer allows multiple browser entity apps, or "target", to each have their own segregated storage instance.
|
|
10
11
|
* The purpose is so the harvester can send data to different apps within the same agent. Each feature should have a manager if it needs this capability.
|
|
@@ -13,14 +14,16 @@ export class EventStoreManager {
|
|
|
13
14
|
/**
|
|
14
15
|
* @param {object} agentRef - reference to base agent class
|
|
15
16
|
* @param {EventBuffer|EventAggregator} storageClass - the type of storage to use in this manager; 'EventBuffer' (1), 'EventAggregator' (2)
|
|
17
|
+
* @param {string} [defaultEntityGuid] - the entity guid to use as the default storage instance; if not provided, a new one is created
|
|
18
|
+
* @param {string} featureName - the name of the feature this manager is for; used for event dispatching
|
|
16
19
|
*/
|
|
17
20
|
constructor(agentRef, storageClass, defaultEntityGuid, featureName) {
|
|
18
21
|
this.agentRef = agentRef;
|
|
19
22
|
this.entityManager = agentRef.runtime.entityManager;
|
|
20
23
|
this.StorageClass = storageClass;
|
|
21
|
-
this.appStorageMap = new Map();
|
|
22
|
-
this.defaultEntity = this.#getEventStore(defaultEntityGuid);
|
|
24
|
+
this.appStorageMap = new Map([[DEFAULT_KEY, new this.StorageClass()]]);
|
|
23
25
|
this.featureName = featureName;
|
|
26
|
+
this.setEventStore(defaultEntityGuid);
|
|
24
27
|
}
|
|
25
28
|
|
|
26
29
|
/**
|
|
@@ -28,11 +31,17 @@ export class EventStoreManager {
|
|
|
28
31
|
* @param {string=} targetEntityGuid the lookup
|
|
29
32
|
* @returns {*} ALWAYS returns a storage instance
|
|
30
33
|
*/
|
|
31
|
-
#getEventStore(targetEntityGuid) {
|
|
32
|
-
if (!targetEntityGuid)
|
|
33
|
-
if (!this.appStorageMap.has(targetEntityGuid)) this.appStorageMap.set(targetEntityGuid, new this.StorageClass());
|
|
34
|
+
#getEventStore(targetEntityGuid = DEFAULT_KEY) {
|
|
35
|
+
if (!this.appStorageMap.has(targetEntityGuid)) this.setEventStore(targetEntityGuid);
|
|
34
36
|
return this.appStorageMap.get(targetEntityGuid);
|
|
35
37
|
}
|
|
38
|
+
setEventStore(targetEntityGuid) {
|
|
39
|
+
/** we should already have an event store for the default */
|
|
40
|
+
if (!targetEntityGuid) return;
|
|
41
|
+
/** if the target is the container agent, SHARE the default storage -- otherwise create a new event store */
|
|
42
|
+
const eventStorage = isContainerAgentTarget(this.entityManager.get(targetEntityGuid), this.agentRef) ? this.appStorageMap.get(DEFAULT_KEY) : new this.StorageClass();
|
|
43
|
+
this.appStorageMap.set(targetEntityGuid, eventStorage);
|
|
44
|
+
}
|
|
36
45
|
|
|
37
46
|
// This class must contain an union of all methods from all supported storage classes and conceptualize away the target app argument.
|
|
38
47
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/features/soft_navigations/aggregate/index.js"],"names":[],"mappings":"AAeA;IACE,2BAAiC;IACjC;;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/features/soft_navigations/aggregate/index.js"],"names":[],"mappings":"AAeA;IACE,2BAAiC;IACjC;;OAoDC;IAjDC,2BAAwC;IACxC,iBAA8B;IAE9B,uDAA0F;IAe1F,yBAA+B;IAC/B,0CAAiC;IACjC,sBAA4B;IA+B9B,qCAUC;IAED,0EAiBC;IAED,2BAiBC;IAED;;;;;;;OAOG;IACH,6BAHW,mBAAmB,OAqB7B;;CA6FF;8BAvO6B,4BAA4B;2CAGf,iCAAiC;4BAChD,eAAe"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"aggregate-base.d.ts","sourceRoot":"","sources":["../../../../src/features/utils/aggregate-base.js"],"names":[],"mappings":"AAqBA;IACE;;;;OAIG;IACH,sBAHW,MAAM,eACN,MAAM,
|
|
1
|
+
{"version":3,"file":"aggregate-base.d.ts","sourceRoot":"","sources":["../../../../src/features/utils/aggregate-base.js"],"names":[],"mappings":"AAqBA;IACE;;;;OAIG;IACH,sBAHW,MAAM,eACN,MAAM,EAoBhB;IAhBC,iBAAwB;IAIxB,gBAAqB;IA6BjB,YAAuI;IAW7I;;;;OAIG;IACH,yBAHW,MAAM,EAAE,gBAwBlB;IAED;;OAEG;IACH,cAGC;IADC,6BAAmB;IAGrB,qCAEC;IAED;;;;;;OAMG;IACH,uDAJW,MAAM,GAAC,SAAS,SAyB1B;IAED;;;;;;;OAOG;IACH,4BALG;QAAwB,SAAS,GAAzB,MAAM,YAAC;KACf,QAQF;IAED;;;OAGG;IACH,6CAsBC;IAED;;;OAGG;IACH,2CAOC;IALC,gBAA6C;IAO/C;;;;OAIG;IACH,uCAHW,GAAC,UACD,GAAC,QAIX;;CACF;4BA1M2B,gBAAgB"}
|
|
@@ -6,14 +6,16 @@ export class EventStoreManager {
|
|
|
6
6
|
/**
|
|
7
7
|
* @param {object} agentRef - reference to base agent class
|
|
8
8
|
* @param {EventBuffer|EventAggregator} storageClass - the type of storage to use in this manager; 'EventBuffer' (1), 'EventAggregator' (2)
|
|
9
|
+
* @param {string} [defaultEntityGuid] - the entity guid to use as the default storage instance; if not provided, a new one is created
|
|
10
|
+
* @param {string} featureName - the name of the feature this manager is for; used for event dispatching
|
|
9
11
|
*/
|
|
10
|
-
constructor(agentRef: object, storageClass: EventBuffer | EventAggregator, defaultEntityGuid
|
|
12
|
+
constructor(agentRef: object, storageClass: EventBuffer | EventAggregator, defaultEntityGuid?: string, featureName: string);
|
|
11
13
|
agentRef: object;
|
|
12
14
|
entityManager: any;
|
|
13
15
|
StorageClass: any;
|
|
14
|
-
appStorageMap: Map<
|
|
15
|
-
|
|
16
|
-
|
|
16
|
+
appStorageMap: Map<string, any>;
|
|
17
|
+
featureName: string;
|
|
18
|
+
setEventStore(targetEntityGuid: any): void;
|
|
17
19
|
/**
|
|
18
20
|
* Calls the isEmpty method on the underlying storage class. If target is provided, runs just for the target, otherwise runs for all apps.
|
|
19
21
|
* @param {object} optsIfPresent - exists if called during harvest interval, @see AggregateBase.makeHarvestPayload
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"event-store-manager.d.ts","sourceRoot":"","sources":["../../../../src/features/utils/event-store-manager.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"event-store-manager.d.ts","sourceRoot":"","sources":["../../../../src/features/utils/event-store-manager.js"],"names":[],"mappings":"AASA;;;GAGG;AACH;IACE;;;;;OAKG;IACH,sBALW,MAAM,gBACN,WAAW,GAAC,eAAe,sBAC3B,MAAM,eACN,MAAM,EAShB;IANC,iBAAwB;IACxB,mBAAmD;IACnD,kBAAgC;IAChC,gCAAsE;IACtE,oBAA8B;IAchC,2CAQC;IAID;;;;;OAKG;IACH,uBAJW,MAAM,0BAEJ,OAAO,CASnB;IAED;;;;;OAKG;IACH,WAJW,MAAM,oBACN,MAAM,GACJ,OAAO,CAYnB;IAED,0GAA0G;IAC1G,8DAEC;IAED;;;;;OAKG;IACH,WAJW,MAAM,YAAC,gCAYjB;IAED;;;;OAIG;IACH,2BAHW,GAAC,OAKX;IAED;;;;;OAKG;IACH,iCAJW,GAAC,oBACD,GAAC,OAKX;IAED;;;;;OAKG;IACH,oBAJW,GAAC,oBACD,GAAC,OAMX;IAED;;;;;OAKG;IACH,qBAJW,GAAC,oBACD,GAAC,OAMX;IAGD,2DAEC;IAED,0DAEC;;CACF"}
|
package/package.json
CHANGED
|
@@ -155,7 +155,7 @@ export class Recorder {
|
|
|
155
155
|
store (event, isCheckout) {
|
|
156
156
|
if (!event) return
|
|
157
157
|
if (this.parent.agentRef.runtime?.session?.isAfterSessionExpiry(event.timestamp)) {
|
|
158
|
-
|
|
158
|
+
handle(SUPPORTABILITY_METRIC_CHANNEL, ['Session/Expired/SessionReplay/Seen'], undefined, FEATURE_NAMES.metrics, this.ee)
|
|
159
159
|
return
|
|
160
160
|
}
|
|
161
161
|
|
|
@@ -26,15 +26,7 @@ export class Aggregate extends AggregateBase {
|
|
|
26
26
|
if (agentRef.runtime.session?.isNew) this.initialPageLoadInteraction.customAttributes.isFirstOfSession = true // mark the hard page load as first of its session
|
|
27
27
|
this.initialPageLoadInteraction.forceSave = true // unless forcibly ignored, iPL always finish by default
|
|
28
28
|
const ixn = this.initialPageLoadInteraction
|
|
29
|
-
|
|
30
|
-
if (this.interactionsToHarvest) this.interactionsToHarvest.add(ixn)
|
|
31
|
-
else {
|
|
32
|
-
/** this.events (ixns to harvest) hasnt been initialized yet... wait for it */
|
|
33
|
-
this.ee.on('entity-added', () => {
|
|
34
|
-
this.interactionsToHarvest = this.events
|
|
35
|
-
this.interactionsToHarvest.add(ixn)
|
|
36
|
-
})
|
|
37
|
-
}
|
|
29
|
+
this.interactionsToHarvest.add(ixn)
|
|
38
30
|
this.initialPageLoadInteraction = null
|
|
39
31
|
})
|
|
40
32
|
timeToFirstByte.subscribe(({ attrs }) => {
|
|
@@ -34,11 +34,13 @@ export class AggregateBase extends FeatureBase {
|
|
|
34
34
|
this.harvestOpts = {} // features aggregate classes can define custom opts for when their harvest is called
|
|
35
35
|
|
|
36
36
|
const agentEntityGuid = this.agentRef?.runtime?.appMetadata?.agents?.[0]?.entityGuid
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
this.#setupEventStore(agentEntityGuid)
|
|
38
|
+
if (!agentEntityGuid) {
|
|
39
|
+
/** wait for the entity guid from the rum response and use to it to further configure things to set the default entity to share an indexed entity with entityGuid */
|
|
40
40
|
this.ee.on('entity-added', entity => {
|
|
41
|
-
this
|
|
41
|
+
// not all event managers have this fn, like ST and SR
|
|
42
|
+
// this allows the lookup to work for the default and an entityGuid without creating two separate buffers
|
|
43
|
+
this.events?.setEventStore?.(entity.entityGuid)
|
|
42
44
|
})
|
|
43
45
|
}
|
|
44
46
|
}
|
|
@@ -49,7 +51,7 @@ export class AggregateBase extends FeatureBase {
|
|
|
49
51
|
* @returns {void}
|
|
50
52
|
*/
|
|
51
53
|
#setupEventStore (entityGuid) {
|
|
52
|
-
if (this.events
|
|
54
|
+
if (this.events) return
|
|
53
55
|
switch (this.featureName) {
|
|
54
56
|
// SessionTrace + Replay have their own storage mechanisms.
|
|
55
57
|
case FEATURE_NAMES.sessionTrace:
|
|
@@ -4,7 +4,9 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { dispatchGlobalEvent } from '../../common/dispatch/global-event'
|
|
6
6
|
import { activatedFeatures } from '../../common/util/feature-flags'
|
|
7
|
+
import { isContainerAgentTarget } from '../../common/util/target'
|
|
7
8
|
|
|
9
|
+
const DEFAULT_KEY = 'NR_CONTAINER_AGENT' // this is the default entity guid used for the default storage instance
|
|
8
10
|
/**
|
|
9
11
|
* This layer allows multiple browser entity apps, or "target", to each have their own segregated storage instance.
|
|
10
12
|
* The purpose is so the harvester can send data to different apps within the same agent. Each feature should have a manager if it needs this capability.
|
|
@@ -13,14 +15,16 @@ export class EventStoreManager {
|
|
|
13
15
|
/**
|
|
14
16
|
* @param {object} agentRef - reference to base agent class
|
|
15
17
|
* @param {EventBuffer|EventAggregator} storageClass - the type of storage to use in this manager; 'EventBuffer' (1), 'EventAggregator' (2)
|
|
18
|
+
* @param {string} [defaultEntityGuid] - the entity guid to use as the default storage instance; if not provided, a new one is created
|
|
19
|
+
* @param {string} featureName - the name of the feature this manager is for; used for event dispatching
|
|
16
20
|
*/
|
|
17
21
|
constructor (agentRef, storageClass, defaultEntityGuid, featureName) {
|
|
18
22
|
this.agentRef = agentRef
|
|
19
23
|
this.entityManager = agentRef.runtime.entityManager
|
|
20
24
|
this.StorageClass = storageClass
|
|
21
|
-
this.appStorageMap = new Map()
|
|
22
|
-
this.defaultEntity = this.#getEventStore(defaultEntityGuid)
|
|
25
|
+
this.appStorageMap = new Map([[DEFAULT_KEY, new this.StorageClass()]])
|
|
23
26
|
this.featureName = featureName
|
|
27
|
+
this.setEventStore(defaultEntityGuid)
|
|
24
28
|
}
|
|
25
29
|
|
|
26
30
|
/**
|
|
@@ -28,12 +32,21 @@ export class EventStoreManager {
|
|
|
28
32
|
* @param {string=} targetEntityGuid the lookup
|
|
29
33
|
* @returns {*} ALWAYS returns a storage instance
|
|
30
34
|
*/
|
|
31
|
-
#getEventStore (targetEntityGuid) {
|
|
32
|
-
if (!targetEntityGuid)
|
|
33
|
-
if (!this.appStorageMap.has(targetEntityGuid)) this.appStorageMap.set(targetEntityGuid, new this.StorageClass())
|
|
35
|
+
#getEventStore (targetEntityGuid = DEFAULT_KEY) {
|
|
36
|
+
if (!this.appStorageMap.has(targetEntityGuid)) this.setEventStore(targetEntityGuid)
|
|
34
37
|
return this.appStorageMap.get(targetEntityGuid)
|
|
35
38
|
}
|
|
36
39
|
|
|
40
|
+
setEventStore (targetEntityGuid) {
|
|
41
|
+
/** we should already have an event store for the default */
|
|
42
|
+
if (!targetEntityGuid) return
|
|
43
|
+
/** if the target is the container agent, SHARE the default storage -- otherwise create a new event store */
|
|
44
|
+
const eventStorage = (isContainerAgentTarget(this.entityManager.get(targetEntityGuid), this.agentRef))
|
|
45
|
+
? this.appStorageMap.get(DEFAULT_KEY)
|
|
46
|
+
: new this.StorageClass()
|
|
47
|
+
this.appStorageMap.set(targetEntityGuid, eventStorage)
|
|
48
|
+
}
|
|
49
|
+
|
|
37
50
|
// This class must contain an union of all methods from all supported storage classes and conceptualize away the target app argument.
|
|
38
51
|
|
|
39
52
|
/**
|