@newrelic/browser-agent 1.258.2 → 1.260.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 +20 -0
- package/dist/cjs/cdn/polyfills.js +3 -1
- package/dist/cjs/common/constants/env.cdn.js +1 -1
- package/dist/cjs/common/constants/env.npm.js +1 -1
- package/dist/cjs/common/drain/drain.js +1 -1
- package/dist/cjs/common/harvest/harvest-scheduler.js +4 -2
- package/dist/cjs/common/session/session-entity.js +8 -1
- package/dist/cjs/common/timing/time-keeper.js +9 -30
- package/dist/cjs/features/ajax/constants.js +3 -2
- package/dist/cjs/features/jserrors/instrument/index.js +3 -4
- package/dist/cjs/features/metrics/aggregate/index.js +0 -8
- package/dist/cjs/features/page_view_event/aggregate/index.js +8 -6
- package/dist/cjs/features/session_replay/aggregate/index.js +31 -36
- package/dist/cjs/features/session_replay/constants.js +5 -2
- package/dist/cjs/features/session_replay/instrument/index.js +53 -13
- package/dist/cjs/features/session_replay/shared/recorder.js +8 -1
- package/dist/cjs/features/session_replay/shared/utils.js +3 -5
- package/dist/cjs/features/session_trace/aggregate/index.js +181 -527
- package/dist/cjs/features/session_trace/aggregate/trace/node.js +19 -0
- package/dist/cjs/features/session_trace/aggregate/trace/storage.js +289 -0
- package/dist/cjs/features/session_trace/constants.js +3 -2
- package/dist/cjs/features/session_trace/instrument/index.js +7 -3
- package/dist/cjs/features/utils/aggregate-base.js +1 -0
- package/dist/cjs/features/utils/feature-gates.js +17 -0
- package/dist/cjs/features/utils/instrument-base.js +2 -1
- package/dist/cjs/loaders/agent-base.js +4 -0
- package/dist/cjs/loaders/api/api-methods.js +1 -1
- package/dist/cjs/loaders/api/api.js +2 -2
- package/dist/cjs/loaders/configure/configure.js +1 -0
- package/dist/esm/cdn/polyfills.js +3 -1
- package/dist/esm/common/constants/env.cdn.js +1 -1
- package/dist/esm/common/constants/env.npm.js +1 -1
- package/dist/esm/common/drain/drain.js +1 -1
- package/dist/esm/common/harvest/harvest-scheduler.js +4 -2
- package/dist/esm/common/session/session-entity.js +8 -1
- package/dist/esm/common/timing/time-keeper.js +9 -30
- package/dist/esm/features/ajax/constants.js +2 -1
- package/dist/esm/features/jserrors/instrument/index.js +3 -4
- package/dist/esm/features/metrics/aggregate/index.js +0 -8
- package/dist/esm/features/page_view_event/aggregate/index.js +8 -6
- package/dist/esm/features/session_replay/aggregate/index.js +32 -37
- package/dist/esm/features/session_replay/constants.js +4 -1
- package/dist/esm/features/session_replay/instrument/index.js +54 -14
- package/dist/esm/features/session_replay/shared/recorder.js +8 -1
- package/dist/esm/features/session_replay/shared/utils.js +4 -6
- package/dist/esm/features/session_trace/aggregate/index.js +182 -527
- package/dist/esm/features/session_trace/aggregate/trace/node.js +12 -0
- package/dist/esm/features/session_trace/aggregate/trace/storage.js +282 -0
- package/dist/esm/features/session_trace/constants.js +2 -1
- package/dist/esm/features/session_trace/instrument/index.js +7 -3
- package/dist/esm/features/utils/aggregate-base.js +1 -0
- package/dist/esm/features/utils/feature-gates.js +11 -0
- package/dist/esm/features/utils/instrument-base.js +3 -2
- package/dist/esm/loaders/agent-base.js +4 -0
- package/dist/esm/loaders/api/api-methods.js +1 -1
- package/dist/esm/loaders/api/api.js +2 -2
- package/dist/esm/loaders/configure/configure.js +1 -0
- package/dist/types/common/harvest/harvest-scheduler.d.ts +1 -0
- package/dist/types/common/harvest/harvest-scheduler.d.ts.map +1 -1
- package/dist/types/common/session/session-entity.d.ts.map +1 -1
- package/dist/types/common/timing/time-keeper.d.ts +2 -0
- package/dist/types/common/timing/time-keeper.d.ts.map +1 -1
- package/dist/types/features/ajax/constants.d.ts +1 -0
- package/dist/types/features/ajax/constants.d.ts.map +1 -1
- package/dist/types/features/jserrors/instrument/index.d.ts.map +1 -1
- package/dist/types/features/metrics/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/page_view_event/aggregate/index.d.ts +2 -0
- package/dist/types/features/page_view_event/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/session_replay/aggregate/index.d.ts +1 -1
- package/dist/types/features/session_replay/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/session_replay/constants.d.ts +3 -0
- package/dist/types/features/session_replay/instrument/index.d.ts +0 -1
- package/dist/types/features/session_replay/instrument/index.d.ts.map +1 -1
- package/dist/types/features/session_replay/shared/recorder.d.ts.map +1 -1
- package/dist/types/features/session_replay/shared/utils.d.ts +1 -1
- package/dist/types/features/session_replay/shared/utils.d.ts.map +1 -1
- package/dist/types/features/session_trace/aggregate/index.d.ts +39 -52
- package/dist/types/features/session_trace/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/session_trace/aggregate/trace/node.d.ts +12 -0
- package/dist/types/features/session_trace/aggregate/trace/node.d.ts.map +1 -0
- package/dist/types/features/session_trace/aggregate/trace/storage.d.ts +43 -0
- package/dist/types/features/session_trace/aggregate/trace/storage.d.ts.map +1 -0
- package/dist/types/features/session_trace/constants.d.ts +1 -0
- package/dist/types/features/session_trace/constants.d.ts.map +1 -1
- package/dist/types/features/session_trace/instrument/index.d.ts.map +1 -1
- package/dist/types/features/utils/aggregate-base.d.ts +1 -0
- package/dist/types/features/utils/aggregate-base.d.ts.map +1 -1
- package/dist/types/features/utils/feature-gates.d.ts +2 -0
- package/dist/types/features/utils/feature-gates.d.ts.map +1 -0
- package/dist/types/features/utils/instrument-base.d.ts.map +1 -1
- package/dist/types/loaders/agent-base.d.ts +1 -0
- package/dist/types/loaders/agent-base.d.ts.map +1 -1
- package/dist/types/loaders/configure/configure.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/cdn/polyfills.js +2 -0
- package/src/common/drain/drain.js +1 -1
- package/src/common/harvest/harvest-scheduler.js +4 -2
- package/src/common/session/session-entity.js +3 -1
- package/src/common/timing/time-keeper.js +9 -30
- package/src/features/ajax/constants.js +2 -0
- package/src/features/jserrors/instrument/index.js +3 -4
- package/src/features/metrics/aggregate/index.js +0 -8
- package/src/features/page_view_event/aggregate/index.js +9 -5
- package/src/features/session_replay/aggregate/index.js +30 -39
- package/src/features/session_replay/constants.js +4 -0
- package/src/features/session_replay/instrument/index.js +48 -8
- package/src/features/session_replay/shared/__mocks__/utils.js +0 -1
- package/src/features/session_replay/shared/recorder.js +8 -1
- package/src/features/session_replay/shared/utils.js +4 -7
- package/src/features/session_trace/aggregate/index.js +157 -493
- package/src/features/session_trace/aggregate/trace/node.js +12 -0
- package/src/features/session_trace/aggregate/trace/storage.js +287 -0
- package/src/features/session_trace/constants.js +1 -0
- package/src/features/session_trace/instrument/index.js +7 -2
- package/src/features/utils/__mocks__/feature-gates.js +1 -0
- package/src/features/utils/aggregate-base.js +1 -0
- package/src/features/utils/feature-gates.js +11 -0
- package/src/features/utils/instrument-base.js +3 -2
- package/src/loaders/agent-base.js +4 -0
- package/src/loaders/api/api-methods.js +1 -1
- package/src/loaders/api/api.js +2 -2
- package/src/loaders/configure/configure.js +1 -0
- package/dist/cjs/features/session_replay/shared/replay-mode.js +0 -28
- package/dist/cjs/features/utils/handler-cache.js +0 -70
- package/dist/esm/features/session_replay/shared/replay-mode.js +0 -23
- package/dist/esm/features/utils/handler-cache.js +0 -63
- package/dist/types/features/session_replay/shared/replay-mode.d.ts +0 -9
- package/dist/types/features/session_replay/shared/replay-mode.d.ts.map +0 -1
- package/dist/types/features/utils/handler-cache.d.ts +0 -23
- package/dist/types/features/utils/handler-cache.d.ts.map +0 -1
- package/src/features/session_replay/shared/replay-mode.js +0 -23
- package/src/features/utils/handler-cache.js +0 -65
|
@@ -1,61 +1,48 @@
|
|
|
1
1
|
export class Aggregate extends AggregateBase {
|
|
2
2
|
static featureName: string;
|
|
3
|
-
constructor(agentIdentifier: any, aggregator: any
|
|
3
|
+
constructor(agentIdentifier: any, aggregator: any);
|
|
4
4
|
agentRuntime: any;
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
nodeCount: number;
|
|
9
|
-
sentTrace: {} | null;
|
|
10
|
-
prevStoredEvents: Set<any>;
|
|
5
|
+
agentInfo: any;
|
|
6
|
+
/** A buffer to hold on to harvested traces in the case that a retry must be made later */
|
|
7
|
+
sentTrace: any[] | null | undefined;
|
|
11
8
|
harvestTimeSeconds: any;
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
storeSTN(stn: any): void;
|
|
30
|
-
/**
|
|
31
|
-
* Trim the collection of nodes awaiting harvest such that those seen outside a certain span of time are discarded.
|
|
32
|
-
* @param {number} lookbackDuration Past length of time until now for which we care about nodes, in milliseconds
|
|
33
|
-
* @returns {number} However many nodes were discarded after trimming.
|
|
34
|
-
*/
|
|
35
|
-
trimSTNs(lookbackDuration: number): number;
|
|
36
|
-
takeSTNs(retry: any): {
|
|
37
|
-
qs?: undefined;
|
|
38
|
-
body?: undefined;
|
|
39
|
-
} | {
|
|
9
|
+
/** Tied to the entitlement flag response from BCS. Will short circuit operations of the agg if false */
|
|
10
|
+
entitled: any;
|
|
11
|
+
/** A flag used to decide if the 30 node threshold should be ignored on the first harvest to ensure sending on the first payload */
|
|
12
|
+
everHarvested: boolean;
|
|
13
|
+
/** If the harvest module is harvesting */
|
|
14
|
+
harvesting: boolean;
|
|
15
|
+
/** TraceStorage is the mechanism that holds, normalizes and aggregates ST nodes. It will be accessed and purged when harvests occur */
|
|
16
|
+
traceStorage: TraceStorage;
|
|
17
|
+
/** Sets up event listeners, and initializes this module to run in the correct "mode". Can be triggered from a few places, but makes an effort to only set up listeners once */
|
|
18
|
+
initialize(stMode: any, stEntitled: any, ignoreSession: any): void;
|
|
19
|
+
mode: any;
|
|
20
|
+
initialized: boolean | undefined;
|
|
21
|
+
scheduler: HarvestScheduler | undefined;
|
|
22
|
+
/** This module does not auto harvest by default -- it needs to be kicked off. Once this method is called, it will then harvest on an interval */
|
|
23
|
+
startHarvesting(): void;
|
|
24
|
+
/** Called by the harvest scheduler at harvest time to retrieve the payload. This will only actually return a payload if running in full mode */
|
|
25
|
+
prepareHarvest(options?: {}): {
|
|
40
26
|
qs: {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
* so that blob parsing doesn't need to happen to support UI/API functions */
|
|
48
|
-
fts: number;
|
|
49
|
-
/** n === "nodeCount" in NR1, a count of nodes in the ST payload, so that blob parsing doesn't need to happen to support UI/API functions */
|
|
50
|
-
n: number;
|
|
51
|
-
};
|
|
52
|
-
body: {
|
|
53
|
-
res: any[];
|
|
27
|
+
browser_monitoring_key: any;
|
|
28
|
+
type: string;
|
|
29
|
+
app_id: any;
|
|
30
|
+
protocol_version: string;
|
|
31
|
+
timestamp: any;
|
|
32
|
+
attributes: string;
|
|
54
33
|
};
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
34
|
+
body: any[] | undefined;
|
|
35
|
+
} | undefined;
|
|
36
|
+
/** When the harvest scheduler finishes, this callback is executed. It's main purpose is to determine if the payload needs to be retried
|
|
37
|
+
* and if so, it will take all data from the temporary buffer and place it back into the traceStorage module
|
|
38
|
+
*/
|
|
39
|
+
onHarvestFinished(result: any): void;
|
|
40
|
+
/** Switch from "off" or "error" to full mode (if entitled) */
|
|
41
|
+
switchToFull(): void;
|
|
42
|
+
/** Stop running for the remainder of the page lifecycle */
|
|
43
|
+
abort(): void;
|
|
58
44
|
}
|
|
59
45
|
import { AggregateBase } from '../../utils/aggregate-base';
|
|
60
|
-
import {
|
|
46
|
+
import { TraceStorage } from './trace/storage';
|
|
47
|
+
import { HarvestScheduler } from '../../../common/harvest/harvest-scheduler';
|
|
61
48
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/features/session_trace/aggregate/index.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/features/session_trace/aggregate/index.js"],"names":[],"mappings":"AAcA;IACE,2BAAiC;IAEjC,mDAmBC;IAjBC,kBAA+C;IAC/C,eAAyC;IAEzC,0FAA0F;IAC1F,oCAAqB;IACrB,wBAA0G;IAC1G,0GAA0G;IAC1G,cAAyB;IACzB,mIAAmI;IACnI,uBAA0B;IAC1B,0CAA0C;IAC1C,oBAAuB;IACvB,wIAAwI;IACxI,2BAA0C;IAM5C,gLAAgL;IAChL,mEA6DC;IA1CyD,UAA4D;IAGpH,iCAAuB;IAOvB,wCAKQ;IA6BV,kJAAkJ;IAClJ,wBAIC;IAED,iJAAiJ;IACjJ;;;;;;;;;;kBA4DC;IAED;;OAEG;IACH,qCAKC;IAED,8DAA8D;IAC9D,qBAUC;IAED,2DAA2D;IAC3D,cAKC;CACF;8BAtM6B,4BAA4B;6BAC7B,iBAAiB;iCAJb,2CAA2C"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* All nodes reported to the consumer must take this shape
|
|
3
|
+
*/
|
|
4
|
+
export class TraceNode {
|
|
5
|
+
constructor(name: any, start: any, end: any, origin: any, type: any);
|
|
6
|
+
n: any;
|
|
7
|
+
s: any;
|
|
8
|
+
e: any;
|
|
9
|
+
o: any;
|
|
10
|
+
t: any;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=node.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../../../../../src/features/session_trace/aggregate/trace/node.js"],"names":[],"mappings":"AAAA;;GAEG;AACH;IACE,qEAMC;IALC,OAAa;IACb,OAAc;IACd,OAAY;IACZ,OAAe;IACf,OAAa;CAEhB"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/** The purpose of this class is to manage, normalize, and retrieve ST nodes as needed without polluting the main ST modules */
|
|
2
|
+
export class TraceStorage {
|
|
3
|
+
constructor(parent: any);
|
|
4
|
+
nodeCount: number;
|
|
5
|
+
trace: {};
|
|
6
|
+
earliestTimeStamp: number;
|
|
7
|
+
latestTimeStamp: number;
|
|
8
|
+
tempStorage: any[];
|
|
9
|
+
prevStoredEvents: Set<any>;
|
|
10
|
+
parent: any;
|
|
11
|
+
/** Central function called by all the other store__ & addToTrace API to append a trace node. */
|
|
12
|
+
storeSTN(stn: any): void;
|
|
13
|
+
/**
|
|
14
|
+
* Trim the collection of nodes awaiting harvest such that those seen outside a certain span of time are discarded.
|
|
15
|
+
* @param {number} lookbackDuration Past length of time until now for which we care about nodes, in milliseconds
|
|
16
|
+
* @returns {number} However many nodes were discarded after trimming.
|
|
17
|
+
*/
|
|
18
|
+
trimSTNs(lookbackDuration: number): number;
|
|
19
|
+
/** Used by session trace's harvester to create the payload body. */
|
|
20
|
+
takeSTNs(): {
|
|
21
|
+
stns?: undefined;
|
|
22
|
+
earliestTimeStamp?: undefined;
|
|
23
|
+
latestTimeStamp?: undefined;
|
|
24
|
+
} | {
|
|
25
|
+
stns: any[];
|
|
26
|
+
earliestTimeStamp: number;
|
|
27
|
+
latestTimeStamp: number;
|
|
28
|
+
};
|
|
29
|
+
smearEvtsByOrigin(name: any): (byOrigin: any, evtNode: any) => any;
|
|
30
|
+
processPVT(name: any, value: any, attrs: any): void;
|
|
31
|
+
storeTiming(timingEntry: any): void;
|
|
32
|
+
storeEvent(currentEvent: any, target: any, start: any, end: any): void;
|
|
33
|
+
shouldIgnoreEvent(event: any, target: any): boolean;
|
|
34
|
+
evtName(type: any): any;
|
|
35
|
+
evtOrigin(t: any, target: any): string;
|
|
36
|
+
storeHist(path: any, old: any, time: any): void;
|
|
37
|
+
storeResources(resources: any): void;
|
|
38
|
+
storeErrorAgg(type: any, name: any, params: any, metrics: any): void;
|
|
39
|
+
storeXhrAgg(type: any, name: any, params: any, metrics: any): void;
|
|
40
|
+
restoreNode(name: any, listOfSTNodes: any): void;
|
|
41
|
+
#private;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=storage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../../../../../src/features/session_trace/aggregate/trace/storage.js"],"names":[],"mappings":"AAyBA,+HAA+H;AAC/H;IAQE,yBAEC;IATD,kBAAa;IACb,UAAU;IACV,0BAA4B;IAC5B,wBAAmB;IACnB,mBAAgB;IAChB,2BAA4B;IAG1B,YAAoB;IAGtB,gGAAgG;IAChG,yBAiBC;IAED;;;;OAIG;IACH,2BAHW,MAAM,GACJ,MAAM,CAsBlB;IAED,oEAAoE;IACpE;;;;;;;;MAsBC;IAED,mEA6BC;IAED,oDAOC;IAED,oCAkBC;IAGD,uEAcC;IAED,oDAKC;IAED,wBAwBC;IAED,uCAuBC;IAGD,gDAEC;IAID,qCAaC;IAGD,qEAGC;IAGD,mEAIC;IAED,iDAKC;;CACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../../src/features/session_trace/constants.js"],"names":[],"mappings":"AAEA,kCAAsD;AACtD,yCAAyC;AACzC,kCAAkC;AAClC,6BAA6B;AAC7B,yBAAyB;AACzB,8BAAoC;AACpC,4BAAgC;AAChC,qCAAqC"}
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../../src/features/session_trace/constants.js"],"names":[],"mappings":"AAEA,kCAAsD;AACtD,yCAAyC;AACzC,kCAAkC;AAClC,6BAA6B;AAC7B,yBAAyB;AACzB,8BAAoC;AACpC,4BAAgC;AAChC,qCAAqC;AACrC,yCAAyC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/features/session_trace/instrument/index.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/features/session_trace/instrument/index.js"],"names":[],"mappings":"AAiBA;IACE,2BAAiC;IACjC,mEA0CC;IAhCC,6BAA4C;CAiC/C;+BAxD8B,6BAA6B"}
|
|
@@ -7,6 +7,7 @@ export class AggregateBase extends FeatureBase {
|
|
|
7
7
|
*/
|
|
8
8
|
waitForFlags(flagNames?: string[]): Promise<any>;
|
|
9
9
|
drain(): void;
|
|
10
|
+
drained: boolean | undefined;
|
|
10
11
|
/**
|
|
11
12
|
* Checks for additional `jsAttributes` items to support backward compatibility with implementations of the agent where
|
|
12
13
|
* loader configurations may appear after the loader code is executed.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"aggregate-base.d.ts","sourceRoot":"","sources":["../../../../src/features/utils/aggregate-base.js"],"names":[],"mappings":"AAOA;IACE,4BAGC;IAED;;;;OAIG;IACH,yBAHW,MAAM,EAAE,gBAmBlB;IAED,
|
|
1
|
+
{"version":3,"file":"aggregate-base.d.ts","sourceRoot":"","sources":["../../../../src/features/utils/aggregate-base.js"],"names":[],"mappings":"AAOA;IACE,4BAGC;IAED;;;;OAIG;IACH,yBAHW,MAAM,EAAE,gBAmBlB;IAED,cAGC;IADC,6BAAmB;IAGrB;;;OAGG;IACH,2BAqBC;CACF;4BAnE2B,gBAAgB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feature-gates.d.ts","sourceRoot":"","sources":["../../../../src/features/utils/feature-gates.js"],"names":[],"mappings":"AAQO,kDAHI,MAAM,GACJ,OAAO,CAInB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instrument-base.d.ts","sourceRoot":"","sources":["../../../../src/features/utils/instrument-base.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"instrument-base.d.ts","sourceRoot":"","sources":["../../../../src/features/utils/instrument-base.js"],"names":[],"mappings":"AAiBA;;;GAGG;AACH;IACE;;;;;;;;OAQG;IACH,6BAPW,MAAM,cACN,OAAO,mCAAmC,EAAE,UAAU,eACtD,MAAM,8BAqChB;IA9BC,cAAgB;IAEhB,8IAA8I;IAC9I,cADW,WAAW,SAAS,CACF;IAE7B;;;MAGE;IACF,eAHU,OAAO,kBAAkB,EAAE,aAAa,CAGpB;IAE9B;;;MAGE;IACF,kCAAoC;IAiBtC;;;;;OAKG;IACH,mEAgDC;;CAYF;4BA5H2B,gBAAgB"}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
export class AgentBase {
|
|
5
5
|
constructor(agentIdentifier?: string);
|
|
6
6
|
agentIdentifier: string;
|
|
7
|
+
ee: any;
|
|
7
8
|
/**
|
|
8
9
|
* Reports a browser PageAction event along with a name and optional attributes.
|
|
9
10
|
* {@link https://docs.newrelic.com/docs/browser/new-relic-browser/browser-apis/addpageaction/}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-base.d.ts","sourceRoot":"","sources":["../../../src/loaders/agent-base.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"agent-base.d.ts","sourceRoot":"","sources":["../../../src/loaders/agent-base.js"],"names":[],"mappings":"AAOA;;GAEG;AAEH;IAGE,sCAKC;IAPD,wBAAe;IAMb,QAAiC;IAanC;;;;;OAKG;IACH,oBAHW,MAAM,wCAKhB;IAED;;;;;OAKG;IACH,sBAHW,MAAM,kCAKhB;IAED;;;;;;OAMG;IACH,yBAJW,MAAM,SACN,MAAM,GAAC,MAAM,GAAC,IAAI,sCAK5B;IAED;;;;;OAKG;IACH,mBAHW,KAAK,GAAC,MAAM,8CAKtB;IAED;;;;OAIG;IACH,iBAFW,MAAM,GAAC,IAAI,OAIrB;IAED;;;;;;;OAOG;IACH,6BAJW,MAAM,GAAC,IAAI,OAMrB;IAED;;;;OAIG;IACH,kCAFmB,KAAK,GAAC,MAAM,KAAK,OAAO,GAAG;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,OAI9D;IAED;;;;OAIG;IACH,8CAEC;IAED;;;;;OAKG;IACH,iBAHW,MAAM,MACN,MAAM,OAIhB;IAED;;;;OAIG;IACH,yDAEC;IAED;;;;OAIG;IACH,oBAEC;IAED;;;;;OAKG;IACH,mBAEC;IAED;;;;;;;;;;OAUG;IACH,6BARW;QAAC,MAAM,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAC,OAUrF;IAED;;;;;OAKG;IACH,0BAHW,MAAM,OAKhB;IAED;;;;;MAKE;IACF,eAHa,mBAAmB,CAK/B;;CACF;kCA/KY,OAAO,yBAAyB,EAAE,mBAAmB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"configure.d.ts","sourceRoot":"","sources":["../../../../src/loaders/configure/configure.js"],"names":[],"mappings":"AASA;;GAEG;AACH,
|
|
1
|
+
{"version":3,"file":"configure.d.ts","sourceRoot":"","sources":["../../../../src/loaders/configure/configure.js"],"names":[],"mappings":"AASA;;GAEG;AACH,oGAgDC"}
|
package/package.json
CHANGED
package/src/cdn/polyfills.js
CHANGED
|
@@ -10,6 +10,7 @@ import 'core-js/stable/array/flat'
|
|
|
10
10
|
import 'core-js/stable/array/flat-map'
|
|
11
11
|
import 'core-js/stable/array/from'
|
|
12
12
|
import 'core-js/stable/array/some'
|
|
13
|
+
import 'core-js/stable/array/find-index'
|
|
13
14
|
import 'core-js/stable/object/assign'
|
|
14
15
|
import 'core-js/stable/object/entries'
|
|
15
16
|
import 'core-js/stable/object/values'
|
|
@@ -23,3 +24,4 @@ import 'core-js/stable/url'
|
|
|
23
24
|
import 'core-js/stable/url-search-params'
|
|
24
25
|
import 'core-js/stable/string/starts-with'
|
|
25
26
|
import 'core-js/stable/number/is-nan'
|
|
27
|
+
import 'core-js/stable/string/includes'
|
|
@@ -71,7 +71,7 @@ export function drain (agentIdentifier = '', featureName = 'feature', force = fa
|
|
|
71
71
|
function checkCanDrainAll (agentIdentifier) {
|
|
72
72
|
// Only when the event-groups for all features are ready to drain (staged) do we execute the drain. This has the effect
|
|
73
73
|
// that the last feature to call drain triggers drain for all features.
|
|
74
|
-
const items =
|
|
74
|
+
const items = Array.from(registry[agentIdentifier])
|
|
75
75
|
if (items.every(([key, values]) => values.staged)) {
|
|
76
76
|
items.sort((a, b) => a[1].priority - b[1].priority)
|
|
77
77
|
items.forEach(([group]) => {
|
|
@@ -31,7 +31,7 @@ export class HarvestScheduler extends SharedContext {
|
|
|
31
31
|
this.started = false
|
|
32
32
|
this.timeoutHandle = null
|
|
33
33
|
this.aborted = false // this controls the per-interval and final harvests for the scheduler (currently per feature specific!)
|
|
34
|
-
|
|
34
|
+
this.harvesting = false
|
|
35
35
|
this.harvest = new Harvest(this.sharedContext)
|
|
36
36
|
|
|
37
37
|
// unload if EOL mechanism fires
|
|
@@ -82,12 +82,14 @@ export class HarvestScheduler extends SharedContext {
|
|
|
82
82
|
|
|
83
83
|
runHarvest (opts) {
|
|
84
84
|
if (this.aborted) return
|
|
85
|
+
this.harvesting = true
|
|
85
86
|
|
|
86
87
|
/**
|
|
87
88
|
* This is executed immediately after harvest sends the data via XHR, or if there's nothing to send. Note that this excludes on unloading / sendBeacon.
|
|
88
89
|
* @param {Object} result
|
|
89
90
|
*/
|
|
90
91
|
const cbRanAfterSend = (result) => {
|
|
92
|
+
this.harvesting = false
|
|
91
93
|
if (opts?.forceNoRetry) result.retry = false // discard unsent data rather than re-queuing for next harvest attempt
|
|
92
94
|
this.onHarvestFinished(opts, result)
|
|
93
95
|
}
|
|
@@ -102,7 +104,7 @@ export class HarvestScheduler extends SharedContext {
|
|
|
102
104
|
if (!submitMethod) return false
|
|
103
105
|
|
|
104
106
|
const retry = !opts?.unload && submitMethod === submitData.xhr
|
|
105
|
-
payload = this.opts.getPayload({ retry, opts })
|
|
107
|
+
payload = this.opts.getPayload({ retry, ...opts })
|
|
106
108
|
|
|
107
109
|
if (!payload) {
|
|
108
110
|
if (this.started) {
|
|
@@ -64,8 +64,10 @@ export class SessionEntity {
|
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
setup ({ value = generateRandomHexString(16), expiresMs = DEFAULT_EXPIRES_MS, inactiveMs = DEFAULT_INACTIVE_MS }) {
|
|
67
|
+
/** Ensure that certain properties are preserved across a reset if already set */
|
|
68
|
+
const persistentAttributes = { serverTimeDiff: this.state.serverTimeDiff || model.serverTimeDiff }
|
|
67
69
|
this.state = {}
|
|
68
|
-
this.sync(model)
|
|
70
|
+
this.sync({ ...model, ...persistentAttributes })
|
|
69
71
|
|
|
70
72
|
// value is intended to act as the primary value of the k=v pair
|
|
71
73
|
this.state.value = value
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import { originTime } from '../constants/runtime'
|
|
2
|
-
import { ee as baseEE } from '../event-emitter/contextual-ee'
|
|
3
2
|
import { getRuntime } from '../config/config'
|
|
4
|
-
import { SESSION_EVENT_TYPES, SESSION_EVENTS } from '../session/constants'
|
|
5
3
|
|
|
6
4
|
/**
|
|
7
5
|
* Class used to adjust the timestamp of harvested data to New Relic server time. This
|
|
@@ -37,17 +35,7 @@ export class TimeKeeper {
|
|
|
37
35
|
|
|
38
36
|
constructor (agentIdentifier) {
|
|
39
37
|
this.#session = getRuntime(agentIdentifier)?.session
|
|
40
|
-
|
|
41
|
-
if (this.#session) {
|
|
42
|
-
const ee = baseEE.get(agentIdentifier)
|
|
43
|
-
ee.on(SESSION_EVENTS.UPDATE, this.#processSessionUpdate.bind(this))
|
|
44
|
-
ee.on(SESSION_EVENTS.STARTED, () => {
|
|
45
|
-
if (this.#ready) {
|
|
46
|
-
this.#session.write({ serverTimeDiff: this.#localTimeDiff })
|
|
47
|
-
}
|
|
48
|
-
})
|
|
49
|
-
this.#processSessionUpdate(null, this.#session.read())
|
|
50
|
-
}
|
|
38
|
+
this.processStoredDiff()
|
|
51
39
|
}
|
|
52
40
|
|
|
53
41
|
get ready () {
|
|
@@ -65,8 +53,8 @@ export class TimeKeeper {
|
|
|
65
53
|
* @param endTime {number} The end time of the RUM request
|
|
66
54
|
*/
|
|
67
55
|
processRumRequest (rumRequest, startTime, endTime) {
|
|
56
|
+
this.processStoredDiff()
|
|
68
57
|
if (this.#ready) return // Server time calculated from session entity
|
|
69
|
-
|
|
70
58
|
const responseDateHeader = rumRequest.getResponseHeader('Date')
|
|
71
59
|
if (!responseDateHeader) {
|
|
72
60
|
throw new Error('Missing date header on rum response.')
|
|
@@ -79,11 +67,11 @@ export class TimeKeeper {
|
|
|
79
67
|
this.#correctedOriginTime = Math.floor(Date.parse(responseDateHeader) - serverOffset)
|
|
80
68
|
this.#localTimeDiff = originTime - this.#correctedOriginTime
|
|
81
69
|
|
|
82
|
-
if (
|
|
70
|
+
if (isNaN(this.#correctedOriginTime)) {
|
|
83
71
|
throw new Error('Date header invalid format.')
|
|
84
72
|
}
|
|
85
73
|
|
|
86
|
-
|
|
74
|
+
this.#session?.write({ serverTimeDiff: this.#localTimeDiff })
|
|
87
75
|
this.#ready = true
|
|
88
76
|
}
|
|
89
77
|
|
|
@@ -106,20 +94,11 @@ export class TimeKeeper {
|
|
|
106
94
|
return Math.floor(timestamp - this.#localTimeDiff)
|
|
107
95
|
}
|
|
108
96
|
|
|
109
|
-
/**
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
#processSessionUpdate (type, data) {
|
|
115
|
-
if (typeof data?.serverTimeDiff !== 'number') return
|
|
116
|
-
|
|
117
|
-
if (
|
|
118
|
-
(!type && !this.#ready) || // This captures the initial read from the session entity when the timekeeper first initializes
|
|
119
|
-
type === SESSION_EVENT_TYPES.CROSS_TAB // This captures any cross-tab write of the session entity
|
|
120
|
-
) {
|
|
121
|
-
// This captures the initial read from the session entity when the timekeeper first initializes
|
|
122
|
-
this.#localTimeDiff = data.serverTimeDiff
|
|
97
|
+
/** Process the session entity and use the info to set the main time calculations if present */
|
|
98
|
+
processStoredDiff () {
|
|
99
|
+
const storedServerTimeDiff = this.#session?.read()?.serverTimeDiff
|
|
100
|
+
if (typeof storedServerTimeDiff === 'number' && !isNaN(storedServerTimeDiff)) {
|
|
101
|
+
this.#localTimeDiff = storedServerTimeDiff
|
|
123
102
|
this.#correctedOriginTime = originTime - this.#localTimeDiff
|
|
124
103
|
this.#ready = true
|
|
125
104
|
}
|
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
import { handle } from '../../../common/event-emitter/handle'
|
|
7
7
|
import { InstrumentBase } from '../../utils/instrument-base'
|
|
8
8
|
import { FEATURE_NAME } from '../constants'
|
|
9
|
-
import { FEATURE_NAMES } from '../../../loaders/features/features'
|
|
10
9
|
import { globalScope } from '../../../common/constants/runtime'
|
|
11
10
|
import { eventListenerOpts } from '../../../common/event-listener/event-listener-opts'
|
|
12
11
|
import { now } from '../../../common/timing/now'
|
|
@@ -28,7 +27,7 @@ export class Instrument extends InstrumentBase {
|
|
|
28
27
|
|
|
29
28
|
this.ee.on('internal-error', (error) => {
|
|
30
29
|
if (!this.abortHandler) return
|
|
31
|
-
handle('ierr', [castError(error), now(), true, {}, this.#replayRunning], undefined,
|
|
30
|
+
handle('ierr', [castError(error), now(), true, {}, this.#replayRunning], undefined, this.featureName, this.ee)
|
|
32
31
|
})
|
|
33
32
|
|
|
34
33
|
this.ee.on(SR_EVENT_EMITTER_TYPES.REPLAY_RUNNING, (isRunning) => {
|
|
@@ -37,12 +36,12 @@ export class Instrument extends InstrumentBase {
|
|
|
37
36
|
|
|
38
37
|
globalScope.addEventListener('unhandledrejection', (promiseRejectionEvent) => {
|
|
39
38
|
if (!this.abortHandler) return
|
|
40
|
-
handle('err', [castPromiseRejectionEvent(promiseRejectionEvent), now(), false, { unhandledPromiseRejection: 1 }, this.#replayRunning], undefined,
|
|
39
|
+
handle('err', [castPromiseRejectionEvent(promiseRejectionEvent), now(), false, { unhandledPromiseRejection: 1 }, this.#replayRunning], undefined, this.featureName, this.ee)
|
|
41
40
|
}, eventListenerOpts(false, this.removeOnAbort?.signal))
|
|
42
41
|
|
|
43
42
|
globalScope.addEventListener('error', (errorEvent) => {
|
|
44
43
|
if (!this.abortHandler) return
|
|
45
|
-
handle('err', [castErrorEvent(errorEvent), now(), false, {}, this.#replayRunning], undefined,
|
|
44
|
+
handle('err', [castErrorEvent(errorEvent), now(), false, {}, this.#replayRunning], undefined, this.featureName, this.ee)
|
|
46
45
|
}, eventListenerOpts(false, this.removeOnAbort?.signal))
|
|
47
46
|
|
|
48
47
|
this.abortHandler = this.#abort // we also use this as a flag to denote that the feature is active or on and handling errors
|
|
@@ -112,8 +112,6 @@ export class Aggregate extends AggregateBase {
|
|
|
112
112
|
if (this.resourcesSent) return
|
|
113
113
|
this.resourcesSent = true // make sure this only gets sent once
|
|
114
114
|
|
|
115
|
-
const agentRuntime = getRuntime(this.agentIdentifier)
|
|
116
|
-
|
|
117
115
|
// Capture SMs around network resources using the performance API to assess
|
|
118
116
|
// work to split this out from the ST nodes
|
|
119
117
|
// differentiate between internal+external and ajax+non-ajax
|
|
@@ -132,12 +130,6 @@ export class Aggregate extends AggregateBase {
|
|
|
132
130
|
}
|
|
133
131
|
})
|
|
134
132
|
|
|
135
|
-
// Capture SMs for session trace if active (`ptid` is set when returned by replay ingest).
|
|
136
|
-
// Retain these SMs while we are working through the session_replay feature
|
|
137
|
-
if (agentRuntime.ptid) {
|
|
138
|
-
this.storeSupportabilityMetrics('PageSession/Feature/SessionTrace/DurationMs', Math.round(performance.now()))
|
|
139
|
-
}
|
|
140
|
-
|
|
141
133
|
// Capture SMs for performance markers and measures to assess the usage and possible inclusion of this
|
|
142
134
|
// data in the agent for use in NR
|
|
143
135
|
if (typeof performance !== 'undefined') {
|
|
@@ -26,6 +26,7 @@ export class Aggregate extends AggregateBase {
|
|
|
26
26
|
this.timeToFirstByte = 0
|
|
27
27
|
this.firstByteToWindowLoad = 0 // our "frontend" duration
|
|
28
28
|
this.firstByteToDomContent = 0 // our "dom processing" duration
|
|
29
|
+
this.timeKeeper = new TimeKeeper(this.agentIdentifier)
|
|
29
30
|
|
|
30
31
|
if (isBrowserScope) {
|
|
31
32
|
timeToFirstByte.subscribe(({ value, attrs }) => {
|
|
@@ -102,6 +103,10 @@ export class Aggregate extends AggregateBase {
|
|
|
102
103
|
queryParameters.fp = firstPaint.current.value
|
|
103
104
|
queryParameters.fcp = firstContentfulPaint.current.value
|
|
104
105
|
|
|
106
|
+
if (this.timeKeeper?.ready) {
|
|
107
|
+
queryParameters.timestamp = this.timeKeeper.convertRelativeTimestamp(now())
|
|
108
|
+
}
|
|
109
|
+
|
|
105
110
|
const rumStartTime = now()
|
|
106
111
|
harvester.send({
|
|
107
112
|
endpoint: 'rum',
|
|
@@ -117,16 +122,15 @@ export class Aggregate extends AggregateBase {
|
|
|
117
122
|
}
|
|
118
123
|
|
|
119
124
|
try {
|
|
120
|
-
|
|
121
|
-
timeKeeper.
|
|
122
|
-
if (!timeKeeper.ready) throw new Error('TimeKeeper not ready')
|
|
125
|
+
this.timeKeeper.processRumRequest(xhr, rumStartTime, rumEndTime)
|
|
126
|
+
if (!this.timeKeeper.ready) throw new Error('TimeKeeper not ready')
|
|
123
127
|
|
|
124
|
-
agentRuntime.timeKeeper = timeKeeper
|
|
128
|
+
agentRuntime.timeKeeper = this.timeKeeper
|
|
125
129
|
} catch (error) {
|
|
126
130
|
handle(SUPPORTABILITY_METRIC_CHANNEL, ['PVE/NRTime/Calculation/Failed'], undefined, FEATURE_NAMES.metrics, this.ee)
|
|
127
131
|
drain(this.agentIdentifier, FEATURE_NAMES.metrics, true)
|
|
128
132
|
this.ee.abort()
|
|
129
|
-
warn('Could not calculate New Relic server time. Agent shutting down.')
|
|
133
|
+
warn('Could not calculate New Relic server time. Agent shutting down.', error)
|
|
130
134
|
return
|
|
131
135
|
}
|
|
132
136
|
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
|
|
13
13
|
import { registerHandler } from '../../../common/event-emitter/register-handler'
|
|
14
14
|
import { HarvestScheduler } from '../../../common/harvest/harvest-scheduler'
|
|
15
|
-
import { ABORT_REASONS, FEATURE_NAME, MAX_PAYLOAD_SIZE, QUERY_PARAM_PADDING, RRWEB_EVENT_TYPES, SR_EVENT_EMITTER_TYPES } from '../constants'
|
|
15
|
+
import { ABORT_REASONS, FEATURE_NAME, MAX_PAYLOAD_SIZE, QUERY_PARAM_PADDING, RRWEB_EVENT_TYPES, SR_EVENT_EMITTER_TYPES, TRIGGERS } from '../constants'
|
|
16
16
|
import { getConfigurationValue, getInfo, getRuntime } from '../../../common/config/config'
|
|
17
17
|
import { AggregateBase } from '../../utils/aggregate-base'
|
|
18
18
|
import { sharedChannel } from '../../../common/constants/shared-channel'
|
|
@@ -97,16 +97,6 @@ export class Aggregate extends AggregateBase {
|
|
|
97
97
|
raw: true
|
|
98
98
|
}, this)
|
|
99
99
|
|
|
100
|
-
registerHandler(SR_EVENT_EMITTER_TYPES.RECORD, () => {
|
|
101
|
-
// if it has aborted or BCS returned bad entitlements, do not allow
|
|
102
|
-
if (this.blocked || !this.entitled) return
|
|
103
|
-
// if it isnt already (fully) initialized... initialize it
|
|
104
|
-
if (!this.recorder) this.initializeRecording(false, true, true)
|
|
105
|
-
// its been initialized and imported the recorder but its not recording (mode === off || error)
|
|
106
|
-
else if (this.mode !== MODE.FULL) this.switchToFull()
|
|
107
|
-
// if it gets all the way to here, that means a full session is already recording... do nothing
|
|
108
|
-
}, this.featureName, this.ee)
|
|
109
|
-
|
|
110
100
|
registerHandler(SR_EVENT_EMITTER_TYPES.PAUSE, () => {
|
|
111
101
|
this.forceStop(this.mode !== MODE.ERROR)
|
|
112
102
|
}, this.featureName, this.ee)
|
|
@@ -117,8 +107,8 @@ export class Aggregate extends AggregateBase {
|
|
|
117
107
|
|
|
118
108
|
const { error_sampling_rate, sampling_rate, autoStart, block_selector, mask_text_selector, mask_all_inputs, inline_stylesheet, inline_images, collect_fonts } = getConfigurationValue(this.agentIdentifier, 'session_replay')
|
|
119
109
|
|
|
120
|
-
this.waitForFlags(['sr']).then(([
|
|
121
|
-
this.entitled =
|
|
110
|
+
this.waitForFlags(['srs', 'sr']).then(([srMode, entitled]) => {
|
|
111
|
+
this.entitled = !!entitled
|
|
122
112
|
if (!this.entitled) {
|
|
123
113
|
deregisterDrain(this.agentIdentifier, this.featureName)
|
|
124
114
|
if (this.recorder?.recording) {
|
|
@@ -128,14 +118,14 @@ export class Aggregate extends AggregateBase {
|
|
|
128
118
|
return
|
|
129
119
|
}
|
|
130
120
|
this.drain()
|
|
131
|
-
this.initializeRecording(
|
|
132
|
-
(Math.random() * 100) < error_sampling_rate,
|
|
133
|
-
(Math.random() * 100) < sampling_rate
|
|
134
|
-
)
|
|
121
|
+
this.initializeRecording(srMode)
|
|
135
122
|
}).then(() => {
|
|
136
|
-
if (this.mode === MODE.OFF)
|
|
137
|
-
|
|
138
|
-
|
|
123
|
+
if (this.mode === MODE.OFF) {
|
|
124
|
+
this.recorder?.stopRecording() // stop any conservative preload recording launched by instrument
|
|
125
|
+
while (this.recorder?.getEvents().events.length) this.recorder?.clearBuffer?.()
|
|
126
|
+
}
|
|
127
|
+
sharedChannel.onReplayReady(this.mode)
|
|
128
|
+
}) // notify watchers that replay started with the mode
|
|
139
129
|
|
|
140
130
|
/** Detect if the default configs have been altered and report a SM. This is useful to evaluate what the reasonable defaults are across a customer base over time */
|
|
141
131
|
if (!autoStart) handle(SUPPORTABILITY_METRIC_CHANNEL, ['Config/SessionReplay/AutoStart/Modified'], undefined, FEATURE_NAMES.metrics, this.ee)
|
|
@@ -179,7 +169,7 @@ export class Aggregate extends AggregateBase {
|
|
|
179
169
|
* @param {boolean} ignoreSession - whether to force the method to ignore the session state and use just the sample flags
|
|
180
170
|
* @returns {void}
|
|
181
171
|
*/
|
|
182
|
-
async initializeRecording (
|
|
172
|
+
async initializeRecording (srMode, ignoreSession) {
|
|
183
173
|
this.initialized = true
|
|
184
174
|
if (!this.entitled) return
|
|
185
175
|
|
|
@@ -191,23 +181,16 @@ export class Aggregate extends AggregateBase {
|
|
|
191
181
|
// session replays can continue if already in progress
|
|
192
182
|
const { session, timeKeeper } = getRuntime(this.agentIdentifier)
|
|
193
183
|
this.timeKeeper = timeKeeper
|
|
194
|
-
if (
|
|
184
|
+
if (this.recorder?.parent.trigger === TRIGGERS.API && this.recorder?.recording) {
|
|
185
|
+
this.mode = MODE.FULL
|
|
186
|
+
} else if (!session.isNew && !ignoreSession) { // inherit the mode of the existing session
|
|
195
187
|
this.mode = session.state.sessionReplayMode
|
|
196
188
|
} else {
|
|
197
189
|
// The session is new... determine the mode the new session should start in
|
|
198
|
-
|
|
199
|
-
else if (errorSample) this.mode = MODE.ERROR
|
|
200
|
-
// If neither are selected, then don't record (early return)
|
|
201
|
-
else {
|
|
202
|
-
return
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
if (this.recorder?.getEvents().type === 'preloaded') {
|
|
207
|
-
this.prepUtils().then(() => {
|
|
208
|
-
this.scheduler.runHarvest()
|
|
209
|
-
})
|
|
190
|
+
this.mode = srMode
|
|
210
191
|
}
|
|
192
|
+
// If off, then don't record (early return)
|
|
193
|
+
if (this.mode === MODE.OFF) return
|
|
211
194
|
|
|
212
195
|
if (!this.recorder) {
|
|
213
196
|
try {
|
|
@@ -225,12 +208,20 @@ export class Aggregate extends AggregateBase {
|
|
|
225
208
|
// If an error was noticed before the mode could be set (like in the early lifecycle of the page), immediately set to FULL mode
|
|
226
209
|
if (this.mode === MODE.ERROR && this.errorNoticed) this.mode = MODE.FULL
|
|
227
210
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
211
|
+
if (this.mode === MODE.FULL) {
|
|
212
|
+
// If theres preloaded events and we are in full mode, just harvest immediately to clear up space and for consistency
|
|
213
|
+
if (this.recorder?.getEvents().type === 'preloaded') {
|
|
214
|
+
this.prepUtils().then(() => {
|
|
215
|
+
this.scheduler.runHarvest()
|
|
216
|
+
})
|
|
217
|
+
}
|
|
218
|
+
// FULL mode records AND reports from the beginning, while ERROR mode only records (but does not report).
|
|
219
|
+
// ERROR mode will do this until an error is thrown, and then switch into FULL mode.
|
|
220
|
+
// If an error happened in ERROR mode before we've gotten to this stage, it will have already set the mode to FULL
|
|
221
|
+
if (!this.scheduler.started) {
|
|
232
222
|
// We only report (harvest) in FULL mode
|
|
233
|
-
|
|
223
|
+
this.scheduler.startTimer(this.harvestTimeSeconds)
|
|
224
|
+
}
|
|
234
225
|
}
|
|
235
226
|
|
|
236
227
|
await this.prepUtils()
|