@newrelic/browser-agent 1.309.0 → 1.310.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/README.md +0 -2
- package/dist/cjs/common/config/init-types.js +1 -4
- package/dist/cjs/common/config/init.js +1 -5
- package/dist/cjs/common/constants/env.cdn.js +1 -1
- package/dist/cjs/common/constants/env.npm.js +1 -1
- package/dist/cjs/common/util/browser-stack-matchers.js +15 -0
- package/dist/cjs/common/util/script-tracker.js +184 -0
- package/dist/cjs/common/wrap/wrap-fetch.js +2 -2
- package/dist/cjs/common/wrap/wrap-history.js +2 -2
- package/dist/cjs/common/wrap/wrap-logger.js +2 -2
- package/dist/cjs/common/wrap/wrap-xhr.js +2 -2
- package/dist/cjs/features/jserrors/aggregate/compute-stack-trace.js +6 -10
- package/dist/cjs/features/page_view_event/aggregate/initialized-features.js +1 -2
- package/dist/cjs/index.js +3 -3
- package/dist/cjs/interfaces/registered-entity.js +2 -1
- package/dist/cjs/loaders/agent.js +1 -4
- package/dist/cjs/loaders/api/register-api-types.js +20 -8
- package/dist/cjs/loaders/api/register.js +36 -2
- package/dist/cjs/loaders/api-base.js +1 -1
- package/dist/cjs/loaders/features/features.js +6 -9
- package/dist/esm/common/config/init-types.js +1 -4
- package/dist/esm/common/config/init.js +1 -5
- package/dist/esm/common/constants/env.cdn.js +1 -1
- package/dist/esm/common/constants/env.npm.js +1 -1
- package/dist/esm/common/util/browser-stack-matchers.js +9 -0
- package/dist/esm/common/util/script-tracker.js +179 -0
- package/dist/esm/common/wrap/wrap-fetch.js +2 -2
- package/dist/esm/common/wrap/wrap-history.js +2 -2
- package/dist/esm/common/wrap/wrap-logger.js +2 -2
- package/dist/esm/common/wrap/wrap-xhr.js +2 -2
- package/dist/esm/features/jserrors/aggregate/compute-stack-trace.js +2 -6
- package/dist/esm/features/page_view_event/aggregate/initialized-features.js +1 -2
- package/dist/esm/index.js +2 -2
- package/dist/esm/interfaces/registered-entity.js +2 -1
- package/dist/esm/loaders/agent.js +1 -4
- package/dist/esm/loaders/api/register-api-types.js +22 -8
- package/dist/esm/loaders/api/register.js +36 -2
- package/dist/esm/loaders/api-base.js +1 -1
- package/dist/esm/loaders/features/features.js +6 -9
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/common/config/init-types.d.ts +0 -10
- package/dist/types/common/config/init.d.ts.map +1 -1
- package/dist/types/common/util/browser-stack-matchers.d.ts +10 -0
- package/dist/types/common/util/browser-stack-matchers.d.ts.map +1 -0
- package/dist/types/common/util/script-tracker.d.ts +7 -0
- package/dist/types/common/util/script-tracker.d.ts.map +1 -0
- package/dist/types/features/jserrors/aggregate/compute-stack-trace.d.ts.map +1 -1
- package/dist/types/features/page_view_event/aggregate/initialized-features.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/interfaces/registered-entity.d.ts +4 -5
- package/dist/types/interfaces/registered-entity.d.ts.map +1 -1
- package/dist/types/loaders/agent.d.ts.map +1 -1
- package/dist/types/loaders/api/register-api-types.d.ts +58 -14
- package/dist/types/loaders/api/register-api-types.d.ts.map +1 -1
- package/dist/types/loaders/api/register.d.ts.map +1 -1
- package/dist/types/loaders/api-base.d.ts +4 -5
- package/dist/types/loaders/api-base.d.ts.map +1 -1
- package/dist/types/loaders/features/features.d.ts +2 -5
- package/dist/types/loaders/features/features.d.ts.map +1 -1
- package/package.json +1 -9
- package/src/common/config/init-types.js +1 -4
- package/src/common/config/init.js +1 -2
- package/src/common/util/browser-stack-matchers.js +9 -0
- package/src/common/util/script-tracker.js +171 -0
- package/src/common/wrap/wrap-fetch.js +2 -2
- package/src/common/wrap/wrap-history.js +2 -2
- package/src/common/wrap/wrap-logger.js +2 -2
- package/src/common/wrap/wrap-xhr.js +2 -2
- package/src/features/jserrors/aggregate/compute-stack-trace.js +2 -7
- package/src/features/page_view_event/aggregate/initialized-features.js +1 -2
- package/src/index.js +2 -2
- package/src/interfaces/registered-entity.js +2 -1
- package/src/loaders/agent.js +0 -4
- package/src/loaders/api/register-api-types.js +22 -8
- package/src/loaders/api/register.js +31 -2
- package/src/loaders/api-base.js +1 -1
- package/src/loaders/features/features.js +6 -9
- package/dist/cjs/common/wrap/wrap-jsonp.js +0 -137
- package/dist/cjs/common/wrap/wrap-mutation.js +0 -62
- package/dist/cjs/common/wrap/wrap-promise.js +0 -166
- package/dist/cjs/common/wrap/wrap-timer.js +0 -71
- package/dist/cjs/features/spa/aggregate/index.js +0 -672
- package/dist/cjs/features/spa/aggregate/interaction-node.js +0 -83
- package/dist/cjs/features/spa/aggregate/interaction.js +0 -95
- package/dist/cjs/features/spa/aggregate/serializer.js +0 -150
- package/dist/cjs/features/spa/constants.js +0 -35
- package/dist/cjs/features/spa/index.js +0 -12
- package/dist/cjs/features/spa/instrument/index.js +0 -136
- package/dist/esm/common/wrap/wrap-jsonp.js +0 -130
- package/dist/esm/common/wrap/wrap-mutation.js +0 -55
- package/dist/esm/common/wrap/wrap-promise.js +0 -159
- package/dist/esm/common/wrap/wrap-timer.js +0 -64
- package/dist/esm/features/spa/aggregate/index.js +0 -663
- package/dist/esm/features/spa/aggregate/interaction-node.js +0 -77
- package/dist/esm/features/spa/aggregate/interaction.js +0 -88
- package/dist/esm/features/spa/aggregate/serializer.js +0 -142
- package/dist/esm/features/spa/constants.js +0 -28
- package/dist/esm/features/spa/index.js +0 -5
- package/dist/esm/features/spa/instrument/index.js +0 -129
- package/dist/types/common/wrap/wrap-jsonp.d.ts +0 -16
- package/dist/types/common/wrap/wrap-jsonp.d.ts.map +0 -1
- package/dist/types/common/wrap/wrap-mutation.d.ts +0 -16
- package/dist/types/common/wrap/wrap-mutation.d.ts.map +0 -1
- package/dist/types/common/wrap/wrap-promise.d.ts +0 -17
- package/dist/types/common/wrap/wrap-promise.d.ts.map +0 -1
- package/dist/types/common/wrap/wrap-timer.d.ts +0 -17
- package/dist/types/common/wrap/wrap-timer.d.ts.map +0 -1
- package/dist/types/features/spa/aggregate/index.d.ts +0 -24
- package/dist/types/features/spa/aggregate/index.d.ts.map +0 -1
- package/dist/types/features/spa/aggregate/interaction-node.d.ts +0 -15
- package/dist/types/features/spa/aggregate/interaction-node.d.ts.map +0 -1
- package/dist/types/features/spa/aggregate/interaction.d.ts +0 -19
- package/dist/types/features/spa/aggregate/interaction.d.ts.map +0 -1
- package/dist/types/features/spa/aggregate/serializer.d.ts +0 -17
- package/dist/types/features/spa/aggregate/serializer.d.ts.map +0 -1
- package/dist/types/features/spa/constants.d.ts +0 -23
- package/dist/types/features/spa/constants.d.ts.map +0 -1
- package/dist/types/features/spa/index.d.ts +0 -2
- package/dist/types/features/spa/index.d.ts.map +0 -1
- package/dist/types/features/spa/instrument/index.d.ts +0 -12
- package/dist/types/features/spa/instrument/index.d.ts.map +0 -1
- package/src/common/wrap/wrap-jsonp.js +0 -142
- package/src/common/wrap/wrap-mutation.js +0 -58
- package/src/common/wrap/wrap-promise.js +0 -176
- package/src/common/wrap/wrap-timer.js +0 -70
- package/src/features/spa/aggregate/index.js +0 -734
- package/src/features/spa/aggregate/interaction-node.js +0 -85
- package/src/features/spa/aggregate/interaction.js +0 -108
- package/src/features/spa/aggregate/serializer.js +0 -200
- package/src/features/spa/constants.js +0 -39
- package/src/features/spa/index.js +0 -5
- package/src/features/spa/instrument/index.js +0 -134
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.InteractionNode = InteractionNode;
|
|
7
|
-
/**
|
|
8
|
-
* Copyright 2020-2025 New Relic, Inc. All rights reserved.
|
|
9
|
-
* SPDX-License-Identifier: Apache-2.0
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
var MAX_NODES = 128;
|
|
13
|
-
var lastId = 0;
|
|
14
|
-
function InteractionNode(interaction, parent, type, timestamp) {
|
|
15
|
-
Object.defineProperty(this, 'interaction', {
|
|
16
|
-
value: interaction,
|
|
17
|
-
writable: true // enumerable: false -- by default, which hides this prop from obj (iterations)
|
|
18
|
-
});
|
|
19
|
-
this.parent = parent;
|
|
20
|
-
this.id = ++lastId;
|
|
21
|
-
this.type = type;
|
|
22
|
-
this.children = [];
|
|
23
|
-
this.end = null;
|
|
24
|
-
this.jsEnd = this.start = timestamp;
|
|
25
|
-
this.jsTime = 0;
|
|
26
|
-
this.attrs = {};
|
|
27
|
-
this.cancelled = false;
|
|
28
|
-
}
|
|
29
|
-
var InteractionNodePrototype = InteractionNode.prototype;
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* @param {string} type
|
|
33
|
-
* @param {number} timestamp
|
|
34
|
-
* @param {string} name
|
|
35
|
-
* @param {bool} dontWait - When true, the interaction will not immediately start waiting
|
|
36
|
-
* for this node to complete. This is used when the creation of
|
|
37
|
-
* the node and its start happen at different times (e.g. XHR).
|
|
38
|
-
*/
|
|
39
|
-
InteractionNodePrototype.child = function child(type, timestamp, name, dontWait) {
|
|
40
|
-
var interaction = this.interaction;
|
|
41
|
-
if (interaction.end || interaction.nodes >= MAX_NODES) return null;
|
|
42
|
-
interaction.onNodeAdded(this);
|
|
43
|
-
var node = new InteractionNode(interaction, this, type, timestamp);
|
|
44
|
-
node.attrs.name = name;
|
|
45
|
-
interaction.nodes++;
|
|
46
|
-
if (!dontWait) {
|
|
47
|
-
interaction.remaining++;
|
|
48
|
-
}
|
|
49
|
-
return node;
|
|
50
|
-
};
|
|
51
|
-
InteractionNodePrototype.callback = function addCallbackTime(exclusiveTime, end) {
|
|
52
|
-
var node = this;
|
|
53
|
-
node.jsTime += exclusiveTime;
|
|
54
|
-
if (end > node.jsEnd) {
|
|
55
|
-
node.jsEnd = end;
|
|
56
|
-
node.interaction.lastCb = end;
|
|
57
|
-
}
|
|
58
|
-
};
|
|
59
|
-
InteractionNodePrototype.cancel = function cancel() {
|
|
60
|
-
this.cancelled = true;
|
|
61
|
-
var interaction = this.interaction;
|
|
62
|
-
interaction.remaining--;
|
|
63
|
-
};
|
|
64
|
-
InteractionNodePrototype.finish = function finish(timestamp) {
|
|
65
|
-
var node = this;
|
|
66
|
-
if (node.end) return;
|
|
67
|
-
node.end = timestamp;
|
|
68
|
-
|
|
69
|
-
// Find the next parent node that is not cancelled
|
|
70
|
-
let parent = node.parent;
|
|
71
|
-
while (parent?.cancelled) parent = parent.parent;
|
|
72
|
-
|
|
73
|
-
// Assign the node to the non-cancelled parent node
|
|
74
|
-
if (parent) parent.children.push(node);
|
|
75
|
-
node.parent = null;
|
|
76
|
-
|
|
77
|
-
// Update the interaction remaining counter
|
|
78
|
-
var interaction = this.interaction;
|
|
79
|
-
interaction.remaining--;
|
|
80
|
-
interaction.lastFinish = timestamp;
|
|
81
|
-
// check if interaction has finished, (this is needed for older browsers for unknown reasons)
|
|
82
|
-
interaction.checkFinish();
|
|
83
|
-
};
|
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.Interaction = Interaction;
|
|
7
|
-
var _runtime = require("../../../common/constants/runtime");
|
|
8
|
-
var _nreum = require("../../../common/window/nreum");
|
|
9
|
-
var _interactionNode = require("./interaction-node");
|
|
10
|
-
/**
|
|
11
|
-
* Copyright 2020-2025 New Relic, Inc. All rights reserved.
|
|
12
|
-
* SPDX-License-Identifier: Apache-2.0
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
var originalSetTimeout = (0, _nreum.gosNREUMOriginals)().o.ST;
|
|
16
|
-
var originalClearTimeout = (0, _nreum.gosNREUMOriginals)().o.CT;
|
|
17
|
-
var lastId = {};
|
|
18
|
-
function Interaction(eventName, timestamp, url, routeName, onFinished, agentRef) {
|
|
19
|
-
this.agentRef = agentRef;
|
|
20
|
-
lastId[agentRef.agentIdentifier] = 0;
|
|
21
|
-
this.id = ++lastId[agentRef.agentIdentifier];
|
|
22
|
-
this.eventName = eventName;
|
|
23
|
-
this.nodes = 0;
|
|
24
|
-
this.remaining = 0;
|
|
25
|
-
this.finishTimer = null;
|
|
26
|
-
this.checkingFinish = false;
|
|
27
|
-
this.lastCb = this.lastFinish = timestamp;
|
|
28
|
-
this.handlers = [];
|
|
29
|
-
this.onFinished = onFinished;
|
|
30
|
-
this.done = false;
|
|
31
|
-
var root = this.root = new _interactionNode.InteractionNode(this, null, 'interaction', timestamp);
|
|
32
|
-
var attrs = root.attrs;
|
|
33
|
-
attrs.trigger = eventName;
|
|
34
|
-
attrs.initialPageURL = _runtime.initialLocation;
|
|
35
|
-
attrs.oldRoute = routeName;
|
|
36
|
-
attrs.newURL = url;
|
|
37
|
-
attrs.oldURL = eventName === 'initialPageLoad' ? document.referrer || undefined : url; // document referrer can return '' and flipper url grouping gets weird with empty strings. Pass undefined to skip flipper.
|
|
38
|
-
attrs.custom = {};
|
|
39
|
-
attrs.store = {};
|
|
40
|
-
}
|
|
41
|
-
var InteractionPrototype = Interaction.prototype;
|
|
42
|
-
InteractionPrototype.checkFinish = function checkFinish() {
|
|
43
|
-
var interaction = this;
|
|
44
|
-
if (interaction.remaining > 0) {
|
|
45
|
-
interaction._resetFinishCheck();
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
|
-
if (interaction.checkingFinish) {
|
|
49
|
-
return;
|
|
50
|
-
}
|
|
51
|
-
if (interaction.root.end !== null) return;
|
|
52
|
-
interaction._resetFinishCheck();
|
|
53
|
-
interaction.checkingFinish = true;
|
|
54
|
-
interaction.finishTimer = originalSetTimeout(() => {
|
|
55
|
-
interaction.checkingFinish = false;
|
|
56
|
-
interaction.finishTimer = originalSetTimeout(() => {
|
|
57
|
-
interaction.finishTimer = null;
|
|
58
|
-
if (interaction.remaining <= 0) interaction.finish();
|
|
59
|
-
}, 1);
|
|
60
|
-
}, 0);
|
|
61
|
-
};
|
|
62
|
-
InteractionPrototype.setNewURL = function setNewURL(url) {
|
|
63
|
-
this.root.attrs.newURL = url;
|
|
64
|
-
};
|
|
65
|
-
InteractionPrototype.setNewRoute = function setNewRoute(route) {
|
|
66
|
-
this.root.attrs.newRoute = route;
|
|
67
|
-
};
|
|
68
|
-
InteractionPrototype.onNodeAdded = function onNodeAdded() {
|
|
69
|
-
this._resetFinishCheck();
|
|
70
|
-
};
|
|
71
|
-
InteractionPrototype._resetFinishCheck = function _resetFinishCheck() {
|
|
72
|
-
if (this.finishTimer) {
|
|
73
|
-
originalClearTimeout(this.finishTimer);
|
|
74
|
-
this.finishTimer = null;
|
|
75
|
-
this.checkingFinish = false;
|
|
76
|
-
}
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
// serialize report and remove nodes from map
|
|
80
|
-
InteractionPrototype.finish = function finishInteraction() {
|
|
81
|
-
var interaction = this;
|
|
82
|
-
var root = interaction.root;
|
|
83
|
-
if (root.end !== null) return;
|
|
84
|
-
var endTimestamp = Math.max(interaction.lastCb, interaction.lastFinish);
|
|
85
|
-
var attrs = root.attrs;
|
|
86
|
-
var customAttrs = attrs.custom;
|
|
87
|
-
if (this.onFinished) {
|
|
88
|
-
this.onFinished(this);
|
|
89
|
-
}
|
|
90
|
-
Object.entries(interaction.agentRef.info.jsAttributes || {}).forEach(([attr, value]) => {
|
|
91
|
-
if (!(attr in customAttrs)) customAttrs[attr] = value;
|
|
92
|
-
});
|
|
93
|
-
root.end = endTimestamp;
|
|
94
|
-
interaction.agentRef.ee.emit('interaction', [this]);
|
|
95
|
-
};
|
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.Serializer = void 0;
|
|
7
|
-
var _cleanUrl = require("../../../common/url/clean-url");
|
|
8
|
-
var _belSerializer = require("../../../common/serialize/bel-serializer");
|
|
9
|
-
/**
|
|
10
|
-
* Copyright 2020-2025 New Relic, Inc. All rights reserved.
|
|
11
|
-
* SPDX-License-Identifier: Apache-2.0
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
class Serializer {
|
|
15
|
-
constructor(agentRef) {
|
|
16
|
-
this.obfuscator = agentRef.runtime.obfuscator;
|
|
17
|
-
this.info = agentRef.info;
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* This variable is used to calculate an interactions ending offset when the
|
|
21
|
-
* harvest includes multiple interactions. This variable is set by the first
|
|
22
|
-
* interaction processed and used by subsequent interactions in the same harvest.
|
|
23
|
-
* See https://issues.newrelic.com/browse/NEWRELIC-5498
|
|
24
|
-
* @type {number|undefined}
|
|
25
|
-
*/
|
|
26
|
-
this.firstTimestamp = undefined;
|
|
27
|
-
}
|
|
28
|
-
serializeMultiple(interactions, offset, navTiming) {
|
|
29
|
-
var addString = (0, _belSerializer.getAddStringContext)(this.obfuscator);
|
|
30
|
-
var serialized = 'bel.7';
|
|
31
|
-
interactions.forEach(interaction => {
|
|
32
|
-
serialized += ';' + this.serializeInteraction(interaction.root, offset, navTiming, interaction.routeChange, addString, this.info);
|
|
33
|
-
});
|
|
34
|
-
this.firstTimestamp = undefined;
|
|
35
|
-
return serialized;
|
|
36
|
-
}
|
|
37
|
-
serializeSingle(root, offset, navTiming, isRouteChange) {
|
|
38
|
-
var addString = (0, _belSerializer.getAddStringContext)(this.obfuscator);
|
|
39
|
-
var serialized = 'bel.7;' + this.serializeInteraction(root, offset, navTiming, isRouteChange, addString, this.info);
|
|
40
|
-
this.firstTimestamp = undefined;
|
|
41
|
-
return serialized;
|
|
42
|
-
}
|
|
43
|
-
serializeInteraction(root, offset, navTiming, isRouteChange, addString, info) {
|
|
44
|
-
offset = offset || 0;
|
|
45
|
-
var isInitialPage = root.attrs.trigger === 'initialPageLoad';
|
|
46
|
-
var typeIdsByName = {
|
|
47
|
-
interaction: 1,
|
|
48
|
-
ajax: 2,
|
|
49
|
-
customTracer: 4
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
// Include the hash fragment with all SPA data
|
|
53
|
-
var includeHashFragment = true;
|
|
54
|
-
const addNode = (node, nodeList) => {
|
|
55
|
-
if (node.type === 'customEnd') return nodeList.push([3, (0, _belSerializer.numeric)(node.end - this.firstTimestamp)]);
|
|
56
|
-
var typeName = node.type;
|
|
57
|
-
var typeId = typeIdsByName[typeName];
|
|
58
|
-
var startTimestamp = node.start;
|
|
59
|
-
var childCount = node.children.length;
|
|
60
|
-
var attrCount = 0;
|
|
61
|
-
var apmAttributes = info.atts;
|
|
62
|
-
var hasNavTiming = isInitialPage && navTiming.length && typeId === 1;
|
|
63
|
-
var children = [];
|
|
64
|
-
var attrs = node.attrs;
|
|
65
|
-
var metrics = attrs.metrics;
|
|
66
|
-
var params = attrs.params;
|
|
67
|
-
var queueTime = info.queueTime;
|
|
68
|
-
var appTime = info.applicationTime;
|
|
69
|
-
if (typeof this.firstTimestamp === 'undefined') {
|
|
70
|
-
startTimestamp += offset;
|
|
71
|
-
this.firstTimestamp = startTimestamp;
|
|
72
|
-
} else {
|
|
73
|
-
startTimestamp -= this.firstTimestamp;
|
|
74
|
-
}
|
|
75
|
-
var fields = [(0, _belSerializer.numeric)(startTimestamp), (0, _belSerializer.numeric)(node.end - node.start), (0, _belSerializer.numeric)(node.jsEnd - node.end), (0, _belSerializer.numeric)(node.jsTime)];
|
|
76
|
-
switch (typeId) {
|
|
77
|
-
case 1:
|
|
78
|
-
fields[2] = (0, _belSerializer.numeric)(node.jsEnd - this.firstTimestamp);
|
|
79
|
-
fields.push(addString(attrs.trigger), addString((0, _cleanUrl.cleanURL)(attrs.initialPageURL, includeHashFragment)), addString((0, _cleanUrl.cleanURL)(attrs.oldURL, includeHashFragment)), addString((0, _cleanUrl.cleanURL)(attrs.newURL, includeHashFragment)), addString(attrs.customName), isInitialPage ? '' : isRouteChange ? 1 : 2, (0, _belSerializer.nullable)(isInitialPage && queueTime, _belSerializer.numeric, true) + (0, _belSerializer.nullable)(isInitialPage && appTime, _belSerializer.numeric, true) + (0, _belSerializer.nullable)(attrs.oldRoute, addString, true) + (0, _belSerializer.nullable)(attrs.newRoute, addString, true) + addString(attrs.id), addString(node.id), (0, _belSerializer.nullable)(attrs.firstPaint, _belSerializer.numeric, true) + (0, _belSerializer.nullable)(attrs.firstContentfulPaint, _belSerializer.numeric, false));
|
|
80
|
-
var attrParts = (0, _belSerializer.addCustomAttributes)(attrs.custom, addString);
|
|
81
|
-
children = children.concat(attrParts);
|
|
82
|
-
attrCount = attrParts.length;
|
|
83
|
-
if (apmAttributes) {
|
|
84
|
-
childCount++;
|
|
85
|
-
children.push('a,' + addString(apmAttributes));
|
|
86
|
-
}
|
|
87
|
-
break;
|
|
88
|
-
case 2:
|
|
89
|
-
fields.push(addString(params.method), (0, _belSerializer.numeric)(params.status), addString(params.host), addString(params.pathname), (0, _belSerializer.numeric)(metrics.txSize), (0, _belSerializer.numeric)(metrics.rxSize), attrs.isFetch ? 1 : attrs.isJSONP ? 2 : '', addString(node.id), (0, _belSerializer.nullable)(node.dt && node.dt.spanId, addString, true) + (0, _belSerializer.nullable)(node.dt && node.dt.traceId, addString, true) + (0, _belSerializer.nullable)(node.dt && node.dt.timestamp, _belSerializer.numeric, false));
|
|
90
|
-
|
|
91
|
-
// add params.gql here
|
|
92
|
-
if (Object.keys(params?.gql || {}).length) {
|
|
93
|
-
var ajaxAttrParts = (0, _belSerializer.addCustomAttributes)(params.gql, addString);
|
|
94
|
-
children = children.concat(ajaxAttrParts);
|
|
95
|
-
attrCount = ajaxAttrParts.length;
|
|
96
|
-
}
|
|
97
|
-
break;
|
|
98
|
-
case 4:
|
|
99
|
-
var tracedTime = attrs.tracedTime;
|
|
100
|
-
fields.push(addString(attrs.name), (0, _belSerializer.nullable)(tracedTime, _belSerializer.numeric, true) + addString(node.id));
|
|
101
|
-
break;
|
|
102
|
-
}
|
|
103
|
-
for (var i = 0; i < node.children.length; i++) {
|
|
104
|
-
addNode(node.children[i], children);
|
|
105
|
-
}
|
|
106
|
-
fields.unshift((0, _belSerializer.numeric)(typeId), (0, _belSerializer.numeric)(childCount += attrCount));
|
|
107
|
-
nodeList.push(fields);
|
|
108
|
-
if (childCount) {
|
|
109
|
-
nodeList.push(children.join(';'));
|
|
110
|
-
}
|
|
111
|
-
if (hasNavTiming) {
|
|
112
|
-
// this build up the navTiming node
|
|
113
|
-
// it for each navTiming value (pre aggregated in nav-timing.js):
|
|
114
|
-
// we initialize the seperator to ',' (seperates the nodeType id from the first value)
|
|
115
|
-
// we initialize the navTiming node to 'b' (the nodeType id)
|
|
116
|
-
// if the value is present:
|
|
117
|
-
// we add the seperator followed by the value
|
|
118
|
-
// otherwise
|
|
119
|
-
// we add null seperator ('!') to the navTimingNode
|
|
120
|
-
// we set the seperator to an empty string since we already wrote it above
|
|
121
|
-
// the reason for writing the null seperator instead of setting the seperator
|
|
122
|
-
// is to ensure we still write it if the null is the last navTiming value.
|
|
123
|
-
|
|
124
|
-
var seperator = ',';
|
|
125
|
-
var navTimingNode = 'b';
|
|
126
|
-
var prev = 0;
|
|
127
|
-
|
|
128
|
-
// get all navTiming values except navigationStart
|
|
129
|
-
// (since its the same as interaction.start)
|
|
130
|
-
// and limit to just the first 20 values we know about
|
|
131
|
-
Object.values(navTiming.slice(1, 21) || {}).forEach(v => {
|
|
132
|
-
if (v !== undefined) {
|
|
133
|
-
navTimingNode += seperator + (0, _belSerializer.numeric)(v - prev);
|
|
134
|
-
seperator = ',';
|
|
135
|
-
prev = v;
|
|
136
|
-
} else {
|
|
137
|
-
navTimingNode += seperator + '!';
|
|
138
|
-
seperator = '';
|
|
139
|
-
}
|
|
140
|
-
});
|
|
141
|
-
nodeList.push(navTimingNode);
|
|
142
|
-
} else if (typeId === 1) {
|
|
143
|
-
nodeList.push('');
|
|
144
|
-
}
|
|
145
|
-
return nodeList;
|
|
146
|
-
};
|
|
147
|
-
return addNode(root, []).join(';');
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
exports.Serializer = Serializer;
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.originalSetTimeout = exports.START = exports.SPA_NODE = exports.REMAINING = exports.MAX_TIMER_BUDGET = exports.JS_TIME = exports.JSONP_NODE = exports.JSONP_END = exports.INTERACTION_EVENTS = exports.INTERACTION_API = exports.INTERACTION = exports.FN_START = exports.FN_END = exports.FETCH_START = exports.FETCH_DONE = exports.FETCH_BODY = exports.FETCH = exports.FEATURE_NAME = exports.END = exports.CB_START = exports.CB_END = exports.BODY = void 0;
|
|
7
|
-
var _nreum = require("../../common/window/nreum");
|
|
8
|
-
var _features = require("../../loaders/features/features");
|
|
9
|
-
/**
|
|
10
|
-
* Copyright 2020-2025 New Relic, Inc. All rights reserved.
|
|
11
|
-
* SPDX-License-Identifier: Apache-2.0
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
const FEATURE_NAME = exports.FEATURE_NAME = _features.FEATURE_NAMES.spa;
|
|
15
|
-
const INTERACTION_EVENTS = exports.INTERACTION_EVENTS = ['click', 'submit', 'keypress', 'keydown', 'keyup', 'change'];
|
|
16
|
-
const MAX_TIMER_BUDGET = exports.MAX_TIMER_BUDGET = 999;
|
|
17
|
-
const FN_START = exports.FN_START = 'fn-start';
|
|
18
|
-
const FN_END = exports.FN_END = 'fn-end';
|
|
19
|
-
const CB_START = exports.CB_START = 'cb-start';
|
|
20
|
-
const INTERACTION_API = exports.INTERACTION_API = 'api-ixn-';
|
|
21
|
-
const REMAINING = exports.REMAINING = 'remaining';
|
|
22
|
-
const INTERACTION = exports.INTERACTION = 'interaction';
|
|
23
|
-
const SPA_NODE = exports.SPA_NODE = 'spaNode';
|
|
24
|
-
const JSONP_NODE = exports.JSONP_NODE = 'jsonpNode';
|
|
25
|
-
const FETCH_START = exports.FETCH_START = 'fetch-start';
|
|
26
|
-
const FETCH_DONE = exports.FETCH_DONE = 'fetch-done';
|
|
27
|
-
const FETCH_BODY = exports.FETCH_BODY = 'fetch-body-';
|
|
28
|
-
const JSONP_END = exports.JSONP_END = 'jsonp-end';
|
|
29
|
-
const originalSetTimeout = exports.originalSetTimeout = (0, _nreum.gosNREUMOriginals)().o.ST;
|
|
30
|
-
const START = exports.START = '-start';
|
|
31
|
-
const END = exports.END = '-end';
|
|
32
|
-
const BODY = exports.BODY = '-body';
|
|
33
|
-
const CB_END = exports.CB_END = 'cb' + END;
|
|
34
|
-
const JS_TIME = exports.JS_TIME = 'jsTime';
|
|
35
|
-
const FETCH = exports.FETCH = 'fetch';
|
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.Spa = exports.Instrument = void 0;
|
|
7
|
-
var _eventListenerOpts = require("../../../common/event-listener/event-listener-opts");
|
|
8
|
-
var _instrumentBase = require("../../utils/instrument-base");
|
|
9
|
-
var CONSTANTS = _interopRequireWildcard(require("../constants"));
|
|
10
|
-
var _runtime = require("../../../common/constants/runtime");
|
|
11
|
-
var _now = require("../../../common/timing/now");
|
|
12
|
-
var _handle = require("../../../common/event-emitter/handle");
|
|
13
|
-
var _wrapJsonp = require("../../../common/wrap/wrap-jsonp");
|
|
14
|
-
var _wrapPromise = require("../../../common/wrap/wrap-promise");
|
|
15
|
-
var _wrapTimer = require("../../../common/wrap/wrap-timer");
|
|
16
|
-
var _wrapXhr = require("../../../common/wrap/wrap-xhr");
|
|
17
|
-
var _wrapFetch = require("../../../common/wrap/wrap-fetch");
|
|
18
|
-
var _wrapHistory = require("../../../common/wrap/wrap-history");
|
|
19
|
-
var _wrapMutation = require("../../../common/wrap/wrap-mutation");
|
|
20
|
-
var _interaction = require("../../../loaders/api/interaction");
|
|
21
|
-
var _load = require("../../../common/window/load");
|
|
22
|
-
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); } /**
|
|
23
|
-
* Copyright 2020-2025 New Relic, Inc. All rights reserved.
|
|
24
|
-
* SPDX-License-Identifier: Apache-2.0
|
|
25
|
-
*/
|
|
26
|
-
const {
|
|
27
|
-
FEATURE_NAME,
|
|
28
|
-
START,
|
|
29
|
-
END,
|
|
30
|
-
BODY,
|
|
31
|
-
CB_END,
|
|
32
|
-
JS_TIME,
|
|
33
|
-
FETCH,
|
|
34
|
-
FN_START,
|
|
35
|
-
CB_START,
|
|
36
|
-
FN_END
|
|
37
|
-
} = CONSTANTS;
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* @deprecated This feature has been deprecated, in favor of `soft_navigations`, which is in limited preview. Consider using/importing `SoftNavigations` instead. To gain access to the limited preview, please see https://docs.newrelic.com/docs/browser/single-page-app-monitoring/get-started/browser-spa-v2/ for more information. This feature will be removed in a future release.
|
|
41
|
-
*/
|
|
42
|
-
class Instrument extends _instrumentBase.InstrumentBase {
|
|
43
|
-
static featureName = FEATURE_NAME;
|
|
44
|
-
constructor(agentRef) {
|
|
45
|
-
super(agentRef, FEATURE_NAME);
|
|
46
|
-
|
|
47
|
-
/** feature specific APIs */
|
|
48
|
-
(0, _interaction.setupInteractionAPI)(agentRef);
|
|
49
|
-
if (!_runtime.isBrowserScope) return; // SPA not supported outside web env
|
|
50
|
-
|
|
51
|
-
try {
|
|
52
|
-
this.removeOnAbort = new AbortController();
|
|
53
|
-
} catch (e) {}
|
|
54
|
-
let depth = 0;
|
|
55
|
-
let startHash;
|
|
56
|
-
const tracerEE = this.ee.get('tracer');
|
|
57
|
-
const jsonpEE = (0, _wrapJsonp.wrapJsonP)(this.ee);
|
|
58
|
-
const promiseEE = (0, _wrapPromise.wrapPromise)(this.ee);
|
|
59
|
-
const timerEE = (0, _wrapTimer.wrapTimer)(this.ee);
|
|
60
|
-
const xhrEE = (0, _wrapXhr.wrapXhr)(this.ee);
|
|
61
|
-
const eventsEE = this.ee.get('events'); // wrapXhr will call wrapEvents
|
|
62
|
-
const fetchEE = (0, _wrapFetch.wrapFetch)(this.ee);
|
|
63
|
-
const historyEE = (0, _wrapHistory.wrapHistory)(this.ee);
|
|
64
|
-
const mutationEE = (0, _wrapMutation.wrapMutation)(this.ee);
|
|
65
|
-
this.ee.on(FN_START, startTimestamp);
|
|
66
|
-
promiseEE.on(CB_START, startTimestamp);
|
|
67
|
-
jsonpEE.on(CB_START, startTimestamp);
|
|
68
|
-
this.ee.on(FN_END, endTimestamp);
|
|
69
|
-
promiseEE.on(CB_END, endTimestamp);
|
|
70
|
-
jsonpEE.on(CB_END, endTimestamp);
|
|
71
|
-
this.ee.on('fn-err', (...args) => {
|
|
72
|
-
if (!args[2]?.__newrelic?.[agentRef.agentIdentifier]) (0, _handle.handle)('function-err', [...args], undefined, this.featureName, this.ee);
|
|
73
|
-
});
|
|
74
|
-
this.ee.buffer([FN_START, FN_END, 'xhr-resolved'], this.featureName);
|
|
75
|
-
eventsEE.buffer([FN_START], this.featureName);
|
|
76
|
-
timerEE.buffer(['setTimeout' + END, 'clearTimeout' + START, FN_START], this.featureName);
|
|
77
|
-
xhrEE.buffer([FN_START, 'new-xhr', 'send-xhr' + START], this.featureName);
|
|
78
|
-
fetchEE.buffer([FETCH + START, FETCH + '-done', FETCH + BODY + START, FETCH + BODY + END], this.featureName);
|
|
79
|
-
historyEE.buffer(['newURL'], this.featureName);
|
|
80
|
-
mutationEE.buffer([FN_START], this.featureName);
|
|
81
|
-
promiseEE.buffer(['propagate', CB_START, CB_END, 'executor-err', 'resolve' + START], this.featureName);
|
|
82
|
-
tracerEE.buffer([FN_START, 'no-' + FN_START], this.featureName);
|
|
83
|
-
jsonpEE.buffer(['new-jsonp', 'cb-start', 'jsonp-error', 'jsonp-end'], this.featureName);
|
|
84
|
-
timestamp(fetchEE, FETCH + START);
|
|
85
|
-
timestamp(fetchEE, FETCH + '-done');
|
|
86
|
-
timestamp(jsonpEE, 'new-jsonp');
|
|
87
|
-
timestamp(jsonpEE, 'jsonp-end');
|
|
88
|
-
timestamp(jsonpEE, 'cb-start');
|
|
89
|
-
historyEE.on('pushState-end', trackURLChange);
|
|
90
|
-
historyEE.on('replaceState-end', trackURLChange);
|
|
91
|
-
|
|
92
|
-
/** niche cases like GPT apps cause no window.load event to fire - which breaks IPLs - so manually force one through the pipe */
|
|
93
|
-
(0, _load.onWindowLoad)(() => {
|
|
94
|
-
eventsEE.emit(FN_START, [[{
|
|
95
|
-
type: 'load'
|
|
96
|
-
}], window], undefined, true);
|
|
97
|
-
});
|
|
98
|
-
window.addEventListener('hashchange', trackURLChange, (0, _eventListenerOpts.eventListenerOpts)(true, this.removeOnAbort?.signal));
|
|
99
|
-
window.addEventListener('load', trackURLChange, (0, _eventListenerOpts.eventListenerOpts)(true, this.removeOnAbort?.signal));
|
|
100
|
-
window.addEventListener('popstate', function () {
|
|
101
|
-
trackURLChange(0, depth > 1);
|
|
102
|
-
}, (0, _eventListenerOpts.eventListenerOpts)(true, this.removeOnAbort?.signal));
|
|
103
|
-
function trackURLChange(unusedArgs, hashChangedDuringCb) {
|
|
104
|
-
historyEE.emit('newURL', ['' + window.location, hashChangedDuringCb]);
|
|
105
|
-
}
|
|
106
|
-
function startTimestamp() {
|
|
107
|
-
depth++;
|
|
108
|
-
startHash = window.location.hash;
|
|
109
|
-
this[FN_START] = (0, _now.now)();
|
|
110
|
-
}
|
|
111
|
-
function endTimestamp() {
|
|
112
|
-
depth--;
|
|
113
|
-
if (window.location.hash !== startHash) {
|
|
114
|
-
trackURLChange(0, true);
|
|
115
|
-
}
|
|
116
|
-
var time = (0, _now.now)();
|
|
117
|
-
this[JS_TIME] = ~~this[JS_TIME] + time - this[FN_START];
|
|
118
|
-
this[FN_END] = time;
|
|
119
|
-
}
|
|
120
|
-
function timestamp(ee, type) {
|
|
121
|
-
ee.on(type, function () {
|
|
122
|
-
this[type] = (0, _now.now)();
|
|
123
|
-
});
|
|
124
|
-
}
|
|
125
|
-
this.abortHandler = this.#abort;
|
|
126
|
-
this.importAggregator(agentRef, () => Promise.resolve().then(() => _interopRequireWildcard(require(/* webpackChunkName: "spa-aggregate" */'../aggregate'))));
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
/** Restoration and resource release tasks to be done if SPA loader is being aborted. Unwind changes to globals and subscription to DOM events. */
|
|
130
|
-
#abort() {
|
|
131
|
-
this.removeOnAbort?.abort();
|
|
132
|
-
this.abortHandler = undefined; // weakly allow this abort op to run only once
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
exports.Instrument = Instrument;
|
|
136
|
-
const Spa = exports.Spa = Instrument;
|
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copyright 2020-2025 New Relic, Inc. All rights reserved.
|
|
3
|
-
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* @file Wraps DOM insertion methods which in turn wrap JSONP functions that show up in the DOM.
|
|
8
|
-
* This module is used by: spa.
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
import { eventListenerOpts } from '../event-listener/event-listener-opts';
|
|
12
|
-
import { ee as baseEE } from '../event-emitter/contextual-ee';
|
|
13
|
-
import { createWrapperWithEmitter as wfn } from './wrap-function';
|
|
14
|
-
import { isBrowserScope } from '../constants/runtime';
|
|
15
|
-
const wrapped = {};
|
|
16
|
-
const domInsertMethods = ['appendChild', 'insertBefore', 'replaceChild'];
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Wraps DOM insertion methods to identify script elements containing JSONP callback functions and instruments those
|
|
20
|
-
* functions with custom events in the context of a new event emitter scoped only to JSONP.
|
|
21
|
-
* @param {Object} sharedEE - The shared event emitter on which a new scoped event emitter will be based.
|
|
22
|
-
* @returns {Object} Scoped event emitter with a debug ID of `jsonp`.
|
|
23
|
-
*/
|
|
24
|
-
export function wrapJsonP(sharedEE) {
|
|
25
|
-
const ee = scopedEE(sharedEE);
|
|
26
|
-
|
|
27
|
-
// Notice if our wrapping never ran yet, the falsy NaN will not early return; but if it has,
|
|
28
|
-
// then we increment the count to track # of feats using this at runtime. JSONP deals with DOM
|
|
29
|
-
// tags so browser window env is required.
|
|
30
|
-
if (!isBrowserScope || wrapped[ee.debugId]) return ee;
|
|
31
|
-
wrapped[ee.debugId] = true; // otherwise, first feature to wrap JSONP
|
|
32
|
-
|
|
33
|
-
var wrapFn = wfn(ee);
|
|
34
|
-
var CALLBACK_REGEX = /[?&](?:callback|cb)=([^&#]+)/;
|
|
35
|
-
var PARENT_REGEX = /(.*)\.([^.]+)/;
|
|
36
|
-
var VALUE_REGEX = /^(\w+)(\.|$)(.*)$/;
|
|
37
|
-
|
|
38
|
-
// JSONP works by dynamically inserting <script> elements - wrap DOM methods for
|
|
39
|
-
// inserting elements to detect insertion of JSONP-specific elements.
|
|
40
|
-
wrapFn.inPlace(Node.prototype, domInsertMethods, 'dom-');
|
|
41
|
-
ee.on('dom-start', function (args) {
|
|
42
|
-
wrapElement(args[0]);
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
// subscribe to events on the JSONP <script> element and wrap the JSONP callback
|
|
46
|
-
// in order to track start and end of the interaction node
|
|
47
|
-
function wrapElement(el) {
|
|
48
|
-
var isScript = el && typeof el.nodeName === 'string' && el.nodeName.toLowerCase() === 'script';
|
|
49
|
-
if (!isScript) return;
|
|
50
|
-
var isValidElement = typeof el.addEventListener === 'function';
|
|
51
|
-
if (!isValidElement) return;
|
|
52
|
-
var callbackName = extractCallbackName(el.src);
|
|
53
|
-
if (!callbackName) return;
|
|
54
|
-
var callback = discoverParent(callbackName);
|
|
55
|
-
var validCallback = typeof callback.parent[callback.key] === 'function';
|
|
56
|
-
if (!validCallback) return;
|
|
57
|
-
|
|
58
|
-
// At this point we know that the element is a valid JSONP script element.
|
|
59
|
-
// The following events are emitted during the lifetime of a JSONP call:
|
|
60
|
-
// * immediately emit `new-jsonp` to notify start of the JSONP work
|
|
61
|
-
// * the wrapped callback will emit `cb-start` and `cb-end` during the execution
|
|
62
|
-
// of the callback, here we can inspect the response
|
|
63
|
-
// * when the element emits the `load` event (script loaded and executed),
|
|
64
|
-
// emit `jsonp-end` to notify end of the JSONP work
|
|
65
|
-
// * if the element emits the `error` event, in response emit `jsonp-error`
|
|
66
|
-
// (and `jsonp-end`). Note that the callback in this case will likely not get
|
|
67
|
-
// called.
|
|
68
|
-
|
|
69
|
-
var context = {};
|
|
70
|
-
wrapFn.inPlace(callback.parent, [callback.key], 'cb-', context);
|
|
71
|
-
el.addEventListener('load', onLoad, eventListenerOpts(false));
|
|
72
|
-
el.addEventListener('error', onError, eventListenerOpts(false));
|
|
73
|
-
ee.emit('new-jsonp', [el.src], context);
|
|
74
|
-
function onLoad() {
|
|
75
|
-
ee.emit('jsonp-end', [], context);
|
|
76
|
-
el.removeEventListener('load', onLoad, eventListenerOpts(false));
|
|
77
|
-
el.removeEventListener('error', onError, eventListenerOpts(false));
|
|
78
|
-
}
|
|
79
|
-
function onError() {
|
|
80
|
-
ee.emit('jsonp-error', [], context);
|
|
81
|
-
ee.emit('jsonp-end', [], context);
|
|
82
|
-
el.removeEventListener('load', onLoad, eventListenerOpts(false));
|
|
83
|
-
el.removeEventListener('error', onError, eventListenerOpts(false));
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
function extractCallbackName(src) {
|
|
87
|
-
var matches = src.match(CALLBACK_REGEX);
|
|
88
|
-
return matches ? matches[1] : null;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* Traverse a nested object using a '.'-delimited string wherein each substring piece maps to each subsequent object property layer.
|
|
93
|
-
* @param {string} longKey
|
|
94
|
-
* @param {object} obj
|
|
95
|
-
* @returns The final nested object referred to by initial longKey.
|
|
96
|
-
*/
|
|
97
|
-
function discoverValue(longKey, obj) {
|
|
98
|
-
if (!longKey) return obj; // end of object recursion depth when no more key levels
|
|
99
|
-
const matches = longKey.match(VALUE_REGEX);
|
|
100
|
-
// if 'longKey' was not undefined, that is it at least had 1 level left, then the regexp would've at least matched 1st group
|
|
101
|
-
const key = matches[1];
|
|
102
|
-
const remaining = matches[3];
|
|
103
|
-
return discoverValue(remaining, obj[key]);
|
|
104
|
-
}
|
|
105
|
-
function discoverParent(key) {
|
|
106
|
-
var matches = key.match(PARENT_REGEX);
|
|
107
|
-
if (matches && matches.length >= 3) {
|
|
108
|
-
return {
|
|
109
|
-
key: matches[2],
|
|
110
|
-
parent: discoverValue(matches[1], window)
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
return {
|
|
114
|
-
key,
|
|
115
|
-
parent: window
|
|
116
|
-
};
|
|
117
|
-
}
|
|
118
|
-
return ee;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* Returns an event emitter scoped specifically for the `jsonp` context. This scoping is a remnant from when all the
|
|
123
|
-
* features shared the same group in the event, to isolate events between features. It will likely be revisited.
|
|
124
|
-
* @param {Object} sharedEE - Optional event emitter on which to base the scoped emitter.
|
|
125
|
-
* Uses `ee` on the global scope if undefined).
|
|
126
|
-
* @returns {Object} Scoped event emitter with a debug ID of 'jsonp'.
|
|
127
|
-
*/
|
|
128
|
-
export function scopedEE(sharedEE) {
|
|
129
|
-
return (sharedEE || baseEE).get('jsonp');
|
|
130
|
-
}
|