@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,11 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Copyright 2020-
|
|
2
|
+
* Copyright 2020-2026 New Relic, Inc. All rights reserved.
|
|
3
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* @file Wraps `pushState` and `replaceState` methods of `window.history` object for instrumentation.
|
|
8
|
-
* This module is used by: session_trace,
|
|
8
|
+
* This module is used by: session_trace, soft_navigations.
|
|
9
9
|
*/
|
|
10
10
|
import { ee as globalEE } from '../event-emitter/contextual-ee'
|
|
11
11
|
import { createWrapperWithEmitter as wfn } from './wrap-function'
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Copyright 2020-
|
|
2
|
+
* Copyright 2020-2026 New Relic, Inc. All rights reserved.
|
|
3
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* @file Wraps native timeout and interval methods for instrumentation.
|
|
8
|
-
* This module is used by:
|
|
8
|
+
* This module is used by: logging.
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import { ee as baseEE, contextId } from '../event-emitter/contextual-ee'
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Copyright 2020-
|
|
2
|
+
* Copyright 2020-2026 New Relic, Inc. All rights reserved.
|
|
3
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* @file Wraps AJAX (XHR) related methods for instrumentation.
|
|
8
|
-
* This module is used by: ajax, jserrors
|
|
8
|
+
* This module is used by: ajax, jserrors.
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import { wrapEvents } from './wrap-events'
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Copyright 2020-
|
|
2
|
+
* Copyright 2020-2026 New Relic, Inc. All rights reserved.
|
|
3
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
*/
|
|
5
5
|
|
|
@@ -58,15 +58,10 @@
|
|
|
58
58
|
// ex.name = ReferenceError
|
|
59
59
|
import { formatStackTrace } from './format-stack-trace'
|
|
60
60
|
import { canonicalizeUrl } from '../../../common/url/canonicalize-url'
|
|
61
|
+
import { chrome, chromeEval, classNameRegex, gecko, ieEval } from '../../../common/util/browser-stack-matchers'
|
|
61
62
|
|
|
62
63
|
var debug = false
|
|
63
64
|
|
|
64
|
-
var classNameRegex = /function (.+?)\s*\(/
|
|
65
|
-
var chrome = /^\s*at (?:((?:\[object object\])?(?:[^(]*\([^)]*\))*[^()]*(?: \[as \S+\])?) )?\(?((?:file|http|https|chrome-extension):.*?)?:(\d+)(?::(\d+))?\)?\s*$/i
|
|
66
|
-
var gecko = /^\s*(?:(\S*|global code)(?:\(.*?\))?@)?((?:file|http|https|chrome|safari-extension).*?):(\d+)(?::(\d+))?\s*$/i
|
|
67
|
-
var chromeEval = /^\s*at .+ \(eval at \S+ \((?:(?:file|http|https):[^)]+)?\)(?:, [^:]*:\d+:\d+)?\)$/i
|
|
68
|
-
var ieEval = /^\s*at Function code \(Function code:\d+:\d+\)\s*/i
|
|
69
|
-
|
|
70
65
|
/**
|
|
71
66
|
* Represents an error with a stack trace.
|
|
72
67
|
* @typedef {Object} StackInfo
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Copyright 2020-
|
|
2
|
+
* Copyright 2020-2026 New Relic, Inc. All rights reserved.
|
|
3
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
*/
|
|
5
5
|
import { FEATURE_NAMES } from '../../../loaders/features/features'
|
|
@@ -27,7 +27,6 @@ export function getActivatedFeaturesFlags (agentId) {
|
|
|
27
27
|
case FEATURE_NAMES.sessionTrace:
|
|
28
28
|
flagArr.push('stn'); break
|
|
29
29
|
case FEATURE_NAMES.softNav:
|
|
30
|
-
case FEATURE_NAMES.spa:
|
|
31
30
|
flagArr.push('spa'); break
|
|
32
31
|
}
|
|
33
32
|
})
|
package/src/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Copyright 2020-
|
|
2
|
+
* Copyright 2020-2026 New Relic, Inc. All rights reserved.
|
|
3
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
*/
|
|
5
5
|
export { Agent } from './loaders/agent'
|
|
@@ -16,4 +16,4 @@ export { PageViewEvent } from './features/page_view_event'
|
|
|
16
16
|
export { PageViewTiming } from './features/page_view_timing'
|
|
17
17
|
export { SessionTrace } from './features/session_trace'
|
|
18
18
|
export { SessionReplay } from './features/session_replay'
|
|
19
|
-
export {
|
|
19
|
+
export { SoftNav } from './features/soft_navigations'
|
|
@@ -21,6 +21,7 @@ export class RegisteredEntity {
|
|
|
21
21
|
/** @type {RegisterAPIMetadata} */
|
|
22
22
|
metadata = {
|
|
23
23
|
target: {},
|
|
24
|
+
timings: {},
|
|
24
25
|
customAttributes: {}
|
|
25
26
|
}
|
|
26
27
|
|
|
@@ -87,7 +88,7 @@ export class RegisteredEntity {
|
|
|
87
88
|
* Measures a task that is recorded as a BrowserPerformance event.
|
|
88
89
|
* {@link https://docs.newrelic.com/docs/browser/new-relic-browser/browser-apis/measure/}
|
|
89
90
|
* @param {string} name The name of the task
|
|
90
|
-
* @param {{start
|
|
91
|
+
* @param {{start?: number|PerformanceMark, end?: number|PerformanceMark, customAttributes?: object}} [options] An object used to control the way the measure API operates
|
|
91
92
|
* @returns {{start: number, end: number, duration: number, customAttributes: object}} Measurement details
|
|
92
93
|
*/
|
|
93
94
|
measure (name, options) {
|
package/src/loaders/agent.js
CHANGED
|
@@ -97,10 +97,6 @@ export class Agent extends AgentBase {
|
|
|
97
97
|
featuresToStart.sort((a, b) => featurePriority[a.featureName] - featurePriority[b.featureName])
|
|
98
98
|
featuresToStart.forEach(InstrumentCtor => {
|
|
99
99
|
if (!enabledFeatures[InstrumentCtor.featureName] && InstrumentCtor.featureName !== FEATURE_NAMES.pageViewEvent) return // PVE is required to run even if it's marked disabled
|
|
100
|
-
if (InstrumentCtor.featureName === FEATURE_NAMES.spa) {
|
|
101
|
-
warn(67)
|
|
102
|
-
return // Skip old SPA
|
|
103
|
-
}
|
|
104
100
|
|
|
105
101
|
const dependencies = getFeatureDependencyNames(InstrumentCtor.featureName)
|
|
106
102
|
const missingDependencies = dependencies.filter(featName => !(featName in this.features)) // any other feature(s) this depends on should've been initialized on prior iterations by priority order
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* @property {(target: RegisterAPIConstructor) => RegisterAPI} register - Record a custom event for the registered entity.
|
|
12
12
|
* @property {() => void} deregister - Deregister the registered entity, which blocks its use and captures end of life timings.
|
|
13
13
|
* @property {(eventType: string, attributes?: Object) => void} recordCustomEvent - Record a custom event for the registered entity.
|
|
14
|
-
* @property {(eventType: string, options?: {start
|
|
14
|
+
* @property {(eventType: string, options?: {start?: number|PerformanceMark, end?: number|PerformanceMark, customAttributes?: object}) => ({start: number, end: number, duration: number, customAttributes: object})} measure - Measures a task that is recorded as a BrowserPerformance event.
|
|
15
15
|
* @property {(value: string | null) => void} setApplicationVersion - Add an application.version attribute to all outgoing data for the registered entity.
|
|
16
16
|
* @property {(name: string, value: string | number | boolean | null, persist?: boolean) => void} setCustomAttribute - Add a custom attribute to outgoing data for the registered entity.
|
|
17
17
|
* @property {(value: string | null, resetSession?: boolean) => void} setUserId - Add an enduser.id attribute to all outgoing API data for the registered entity. Note: a registered entity will not be able to initiate a session reset. It must be done from the main agent.
|
|
@@ -30,13 +30,27 @@
|
|
|
30
30
|
/**
|
|
31
31
|
* @typedef {Object} RegisterAPIMetadata
|
|
32
32
|
* @property {Object} customAttributes - The custom attributes for the registered entity.
|
|
33
|
-
* @property {
|
|
34
|
-
* @property {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
* @
|
|
39
|
-
* @property {
|
|
33
|
+
* @property {RegisterAPITimings} timings - The timing metrics for the registered entity.
|
|
34
|
+
* @property {RegisterAPITarget} target - The options for the registered entity.
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* @typedef {Object} RegisterAPITarget
|
|
39
|
+
* @property {string} id - The ID for the registered entity.
|
|
40
|
+
* @property {string} name - The name returned for the registered entity.
|
|
41
|
+
* @property {{[key: string]: any}} [tags] - The tags for the registered entity as key-value pairs.
|
|
42
|
+
* @property {string} [parentId] - The parentId for the registered entity. If none was supplied, it will assume the entity guid from the main agent.
|
|
43
|
+
* @property {boolean} [isolated] - When true, each registration creates an isolated instance. When false, multiple registrations with the same id and isolated: false will share a single instance, including all custom attributes, ids, names, and metadata. Calling deregister on a shared instance will deregister it for all entities using the instance. Defaults to true.
|
|
44
|
+
*/
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* @typedef {Object} RegisterAPITimings
|
|
48
|
+
* @property {number} registeredAt - The timestamp when the registered entity was created.
|
|
49
|
+
* @property {number} [reportedAt] - The timestamp when the registered entity was deregistered.
|
|
50
|
+
* @property {number} fetchStart - The timestamp when the registered entity began fetching.
|
|
51
|
+
* @property {number} fetchEnd - The timestamp when the registered entity finished fetching.
|
|
52
|
+
* @property {Object} [asset] - The asset path (if found) for the registered entity.
|
|
53
|
+
* @property {string} type - The type of timing associated with the registered entity, 'script' or 'link' if found with the performance resource API, 'inline' if found to be associated with the root document URL, or 'unknown' if no associated resource could be found.
|
|
40
54
|
*/
|
|
41
55
|
|
|
42
56
|
export default {}
|
|
@@ -16,6 +16,8 @@ import { noticeError } from './noticeError'
|
|
|
16
16
|
import { single } from '../../common/util/invoke'
|
|
17
17
|
import { measure } from './measure'
|
|
18
18
|
import { recordCustomEvent } from './recordCustomEvent'
|
|
19
|
+
import { subscribeToPageUnload } from '../../common/window/page-visibility'
|
|
20
|
+
import { findScriptTimings } from '../../common/util/script-tracker'
|
|
19
21
|
|
|
20
22
|
/**
|
|
21
23
|
* @typedef {import('./register-api-types').RegisterAPI} RegisterAPI
|
|
@@ -52,6 +54,8 @@ function register (agentRef, target, parent) {
|
|
|
52
54
|
target.parent = parent || {}
|
|
53
55
|
if (typeof target.tags !== 'object' || target.tags === null || Array.isArray(target.tags)) target.tags = {}
|
|
54
56
|
|
|
57
|
+
const timings = findScriptTimings()
|
|
58
|
+
|
|
55
59
|
const attrs = {}
|
|
56
60
|
|
|
57
61
|
// Process tags object and add to attrs, excluding protected keys
|
|
@@ -96,6 +100,7 @@ function register (agentRef, target, parent) {
|
|
|
96
100
|
addPageAction: (name, attributes = {}) => report(addPageAction, [name, { ...attrs, ...attributes }, agentRef], target),
|
|
97
101
|
deregister: () => {
|
|
98
102
|
/** note: blocking this instance will disable access for all entities sharing the instance, and will invalidate it from the v2 checks */
|
|
103
|
+
reportTimings()
|
|
99
104
|
block(single(() => warn(68)))
|
|
100
105
|
},
|
|
101
106
|
log: (message, options = {}) => report(log, [message, { ...options, customAttributes: { ...attrs, ...(options.customAttributes || {}) } }, agentRef], target),
|
|
@@ -109,7 +114,8 @@ function register (agentRef, target, parent) {
|
|
|
109
114
|
/** metadata */
|
|
110
115
|
metadata: {
|
|
111
116
|
customAttributes: attrs,
|
|
112
|
-
target
|
|
117
|
+
target,
|
|
118
|
+
timings
|
|
113
119
|
}
|
|
114
120
|
}
|
|
115
121
|
|
|
@@ -123,7 +129,30 @@ function register (agentRef, target, parent) {
|
|
|
123
129
|
}
|
|
124
130
|
|
|
125
131
|
/** only allow registered APIs to be tracked in the agent runtime */
|
|
126
|
-
if (!isBlocked())
|
|
132
|
+
if (!isBlocked()) {
|
|
133
|
+
registeredEntities.push(api)
|
|
134
|
+
subscribeToPageUnload(reportTimings)
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Reports the gathered timings for the registered entity through a custom event to the container agent. Only reports once
|
|
139
|
+
* by checking for the presence of the reportedAt timing.
|
|
140
|
+
* @returns {void}
|
|
141
|
+
*/
|
|
142
|
+
function reportTimings () {
|
|
143
|
+
// only ever report the timings the first time this is called
|
|
144
|
+
if (timings.reportedAt) return
|
|
145
|
+
timings.reportedAt = now()
|
|
146
|
+
api.recordCustomEvent('MicroFrontEndTiming', {
|
|
147
|
+
assetUrl: timings.asset, // the url of the script that was registered, or undefined if it could not be determined (inline or no match)
|
|
148
|
+
assetType: timings.type, // the type of asset that was associated with the timings, one of 'script', 'link' (if preloaded and found in the resource timing buffer), 'preload' (if preloaded but not found in the resource timing buffer), or "unknown" if it could not be determined
|
|
149
|
+
timeToLoad: timings.registeredAt - timings.fetchStart, // fetchStart to registeredAt
|
|
150
|
+
timeToBeRequested: timings.fetchStart, // origin to fetchStart
|
|
151
|
+
timeToFetch: timings.fetchEnd - timings.fetchStart, // fetchStart to fetchEnd
|
|
152
|
+
timeToRegister: timings.registeredAt - timings.fetchEnd, // fetchEnd to registeredAt
|
|
153
|
+
timeAlive: timings.reportedAt - timings.registeredAt // registeredAt to reportedAt
|
|
154
|
+
})
|
|
155
|
+
}
|
|
127
156
|
|
|
128
157
|
/**
|
|
129
158
|
* Sets a value local to the registered API attrs. Will do nothing if APIs are deregistered.
|
package/src/loaders/api-base.js
CHANGED
|
@@ -220,7 +220,7 @@ export class ApiBase {
|
|
|
220
220
|
* Measures a task that is recorded as a BrowserPerformance event.
|
|
221
221
|
* {@link https://docs.newrelic.com/docs/browser/new-relic-browser/browser-apis/measure/}
|
|
222
222
|
* @param {string} name The name of the task
|
|
223
|
-
* @param {{start
|
|
223
|
+
* @param {{start?: number|PerformanceMark, end?: number|PerformanceMark, customAttributes?: object}} [options] An object used to control the way the measure API operates
|
|
224
224
|
* @returns {{start: number, end: number, duration: number, customAttributes: object}} Measurement details
|
|
225
225
|
*/
|
|
226
226
|
measure (name, options) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Copyright 2020-
|
|
2
|
+
* Copyright 2020-2026 New Relic, Inc. All rights reserved.
|
|
3
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
*/
|
|
5
5
|
|
|
@@ -24,8 +24,7 @@ export const FEATURE_NAMES = {
|
|
|
24
24
|
pageViewTiming: 'page_view_timing',
|
|
25
25
|
sessionReplay: 'session_replay',
|
|
26
26
|
sessionTrace: 'session_trace',
|
|
27
|
-
softNav: 'soft_navigations'
|
|
28
|
-
spa: 'spa'
|
|
27
|
+
softNav: 'soft_navigations'
|
|
29
28
|
}
|
|
30
29
|
|
|
31
30
|
/**
|
|
@@ -37,20 +36,18 @@ export const featurePriority = {
|
|
|
37
36
|
[FEATURE_NAMES.pageViewTiming]: 2,
|
|
38
37
|
[FEATURE_NAMES.metrics]: 3,
|
|
39
38
|
[FEATURE_NAMES.jserrors]: 4,
|
|
40
|
-
[FEATURE_NAMES.
|
|
39
|
+
[FEATURE_NAMES.softNav]: 5,
|
|
41
40
|
[FEATURE_NAMES.ajax]: 6,
|
|
42
41
|
[FEATURE_NAMES.sessionTrace]: 7,
|
|
43
|
-
[FEATURE_NAMES.
|
|
44
|
-
[FEATURE_NAMES.
|
|
45
|
-
[FEATURE_NAMES.
|
|
46
|
-
[FEATURE_NAMES.genericEvents]: 11
|
|
42
|
+
[FEATURE_NAMES.sessionReplay]: 8,
|
|
43
|
+
[FEATURE_NAMES.logging]: 9,
|
|
44
|
+
[FEATURE_NAMES.genericEvents]: 10
|
|
47
45
|
}
|
|
48
46
|
|
|
49
47
|
export const FEATURE_TO_ENDPOINT = {
|
|
50
48
|
[FEATURE_NAMES.pageViewEvent]: RUM,
|
|
51
49
|
[FEATURE_NAMES.pageViewTiming]: EVENTS,
|
|
52
50
|
[FEATURE_NAMES.ajax]: EVENTS,
|
|
53
|
-
[FEATURE_NAMES.spa]: EVENTS,
|
|
54
51
|
[FEATURE_NAMES.softNav]: EVENTS,
|
|
55
52
|
[FEATURE_NAMES.metrics]: JSERRORS,
|
|
56
53
|
[FEATURE_NAMES.jserrors]: JSERRORS,
|
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.scopedEE = scopedEE;
|
|
7
|
-
exports.wrapJsonP = wrapJsonP;
|
|
8
|
-
var _eventListenerOpts = require("../event-listener/event-listener-opts");
|
|
9
|
-
var _contextualEe = require("../event-emitter/contextual-ee");
|
|
10
|
-
var _wrapFunction = require("./wrap-function");
|
|
11
|
-
var _runtime = require("../constants/runtime");
|
|
12
|
-
/**
|
|
13
|
-
* Copyright 2020-2025 New Relic, Inc. All rights reserved.
|
|
14
|
-
* SPDX-License-Identifier: Apache-2.0
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* @file Wraps DOM insertion methods which in turn wrap JSONP functions that show up in the DOM.
|
|
19
|
-
* This module is used by: spa.
|
|
20
|
-
*/
|
|
21
|
-
|
|
22
|
-
const wrapped = {};
|
|
23
|
-
const domInsertMethods = ['appendChild', 'insertBefore', 'replaceChild'];
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Wraps DOM insertion methods to identify script elements containing JSONP callback functions and instruments those
|
|
27
|
-
* functions with custom events in the context of a new event emitter scoped only to JSONP.
|
|
28
|
-
* @param {Object} sharedEE - The shared event emitter on which a new scoped event emitter will be based.
|
|
29
|
-
* @returns {Object} Scoped event emitter with a debug ID of `jsonp`.
|
|
30
|
-
*/
|
|
31
|
-
function wrapJsonP(sharedEE) {
|
|
32
|
-
const ee = scopedEE(sharedEE);
|
|
33
|
-
|
|
34
|
-
// Notice if our wrapping never ran yet, the falsy NaN will not early return; but if it has,
|
|
35
|
-
// then we increment the count to track # of feats using this at runtime. JSONP deals with DOM
|
|
36
|
-
// tags so browser window env is required.
|
|
37
|
-
if (!_runtime.isBrowserScope || wrapped[ee.debugId]) return ee;
|
|
38
|
-
wrapped[ee.debugId] = true; // otherwise, first feature to wrap JSONP
|
|
39
|
-
|
|
40
|
-
var wrapFn = (0, _wrapFunction.createWrapperWithEmitter)(ee);
|
|
41
|
-
var CALLBACK_REGEX = /[?&](?:callback|cb)=([^&#]+)/;
|
|
42
|
-
var PARENT_REGEX = /(.*)\.([^.]+)/;
|
|
43
|
-
var VALUE_REGEX = /^(\w+)(\.|$)(.*)$/;
|
|
44
|
-
|
|
45
|
-
// JSONP works by dynamically inserting <script> elements - wrap DOM methods for
|
|
46
|
-
// inserting elements to detect insertion of JSONP-specific elements.
|
|
47
|
-
wrapFn.inPlace(Node.prototype, domInsertMethods, 'dom-');
|
|
48
|
-
ee.on('dom-start', function (args) {
|
|
49
|
-
wrapElement(args[0]);
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
// subscribe to events on the JSONP <script> element and wrap the JSONP callback
|
|
53
|
-
// in order to track start and end of the interaction node
|
|
54
|
-
function wrapElement(el) {
|
|
55
|
-
var isScript = el && typeof el.nodeName === 'string' && el.nodeName.toLowerCase() === 'script';
|
|
56
|
-
if (!isScript) return;
|
|
57
|
-
var isValidElement = typeof el.addEventListener === 'function';
|
|
58
|
-
if (!isValidElement) return;
|
|
59
|
-
var callbackName = extractCallbackName(el.src);
|
|
60
|
-
if (!callbackName) return;
|
|
61
|
-
var callback = discoverParent(callbackName);
|
|
62
|
-
var validCallback = typeof callback.parent[callback.key] === 'function';
|
|
63
|
-
if (!validCallback) return;
|
|
64
|
-
|
|
65
|
-
// At this point we know that the element is a valid JSONP script element.
|
|
66
|
-
// The following events are emitted during the lifetime of a JSONP call:
|
|
67
|
-
// * immediately emit `new-jsonp` to notify start of the JSONP work
|
|
68
|
-
// * the wrapped callback will emit `cb-start` and `cb-end` during the execution
|
|
69
|
-
// of the callback, here we can inspect the response
|
|
70
|
-
// * when the element emits the `load` event (script loaded and executed),
|
|
71
|
-
// emit `jsonp-end` to notify end of the JSONP work
|
|
72
|
-
// * if the element emits the `error` event, in response emit `jsonp-error`
|
|
73
|
-
// (and `jsonp-end`). Note that the callback in this case will likely not get
|
|
74
|
-
// called.
|
|
75
|
-
|
|
76
|
-
var context = {};
|
|
77
|
-
wrapFn.inPlace(callback.parent, [callback.key], 'cb-', context);
|
|
78
|
-
el.addEventListener('load', onLoad, (0, _eventListenerOpts.eventListenerOpts)(false));
|
|
79
|
-
el.addEventListener('error', onError, (0, _eventListenerOpts.eventListenerOpts)(false));
|
|
80
|
-
ee.emit('new-jsonp', [el.src], context);
|
|
81
|
-
function onLoad() {
|
|
82
|
-
ee.emit('jsonp-end', [], context);
|
|
83
|
-
el.removeEventListener('load', onLoad, (0, _eventListenerOpts.eventListenerOpts)(false));
|
|
84
|
-
el.removeEventListener('error', onError, (0, _eventListenerOpts.eventListenerOpts)(false));
|
|
85
|
-
}
|
|
86
|
-
function onError() {
|
|
87
|
-
ee.emit('jsonp-error', [], context);
|
|
88
|
-
ee.emit('jsonp-end', [], context);
|
|
89
|
-
el.removeEventListener('load', onLoad, (0, _eventListenerOpts.eventListenerOpts)(false));
|
|
90
|
-
el.removeEventListener('error', onError, (0, _eventListenerOpts.eventListenerOpts)(false));
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
function extractCallbackName(src) {
|
|
94
|
-
var matches = src.match(CALLBACK_REGEX);
|
|
95
|
-
return matches ? matches[1] : null;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* Traverse a nested object using a '.'-delimited string wherein each substring piece maps to each subsequent object property layer.
|
|
100
|
-
* @param {string} longKey
|
|
101
|
-
* @param {object} obj
|
|
102
|
-
* @returns The final nested object referred to by initial longKey.
|
|
103
|
-
*/
|
|
104
|
-
function discoverValue(longKey, obj) {
|
|
105
|
-
if (!longKey) return obj; // end of object recursion depth when no more key levels
|
|
106
|
-
const matches = longKey.match(VALUE_REGEX);
|
|
107
|
-
// if 'longKey' was not undefined, that is it at least had 1 level left, then the regexp would've at least matched 1st group
|
|
108
|
-
const key = matches[1];
|
|
109
|
-
const remaining = matches[3];
|
|
110
|
-
return discoverValue(remaining, obj[key]);
|
|
111
|
-
}
|
|
112
|
-
function discoverParent(key) {
|
|
113
|
-
var matches = key.match(PARENT_REGEX);
|
|
114
|
-
if (matches && matches.length >= 3) {
|
|
115
|
-
return {
|
|
116
|
-
key: matches[2],
|
|
117
|
-
parent: discoverValue(matches[1], window)
|
|
118
|
-
};
|
|
119
|
-
}
|
|
120
|
-
return {
|
|
121
|
-
key,
|
|
122
|
-
parent: window
|
|
123
|
-
};
|
|
124
|
-
}
|
|
125
|
-
return ee;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
/**
|
|
129
|
-
* Returns an event emitter scoped specifically for the `jsonp` context. This scoping is a remnant from when all the
|
|
130
|
-
* features shared the same group in the event, to isolate events between features. It will likely be revisited.
|
|
131
|
-
* @param {Object} sharedEE - Optional event emitter on which to base the scoped emitter.
|
|
132
|
-
* Uses `ee` on the global scope if undefined).
|
|
133
|
-
* @returns {Object} Scoped event emitter with a debug ID of 'jsonp'.
|
|
134
|
-
*/
|
|
135
|
-
function scopedEE(sharedEE) {
|
|
136
|
-
return (sharedEE || _contextualEe.ee).get('jsonp');
|
|
137
|
-
}
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.scopedEE = scopedEE;
|
|
7
|
-
exports.wrapMutation = wrapMutation;
|
|
8
|
-
var _contextualEe = require("../event-emitter/contextual-ee");
|
|
9
|
-
var _wrapFunction = require("./wrap-function");
|
|
10
|
-
var _runtime = require("../constants/runtime");
|
|
11
|
-
/**
|
|
12
|
-
* Copyright 2020-2025 New Relic, Inc. All rights reserved.
|
|
13
|
-
* SPDX-License-Identifier: Apache-2.0
|
|
14
|
-
*/
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* @file Wraps the window's DOM mutation observer for instrumentation.
|
|
18
|
-
* This module is used by: spa.
|
|
19
|
-
*/
|
|
20
|
-
|
|
21
|
-
const wrapped = {};
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* In web environments only, wraps the `window.MutationObserver` function to emit events on start, end, and error, in
|
|
25
|
-
* the context of a new event emitter scoped only to mutations.
|
|
26
|
-
* @param {Object} sharedEE - The shared event emitter on which a new scoped event emitter will be based.
|
|
27
|
-
* @returns {Object} Scoped event emitter with a debug ID of `mutation`.
|
|
28
|
-
*/
|
|
29
|
-
function wrapMutation(sharedEE) {
|
|
30
|
-
const ee = scopedEE(sharedEE);
|
|
31
|
-
|
|
32
|
-
// Notice if our wrapping never ran yet, the falsy NaN will not early return; but if it has,
|
|
33
|
-
// then we increment the count to track # of feats using this at runtime. Mutations API is only
|
|
34
|
-
// available in browser DOM context.
|
|
35
|
-
if (!_runtime.isBrowserScope || wrapped[ee.debugId]) return ee;
|
|
36
|
-
wrapped[ee.debugId] = true; // otherwise, first feature to wrap mutations
|
|
37
|
-
|
|
38
|
-
var wrapFn = (0, _wrapFunction.createWrapperWithEmitter)(ee);
|
|
39
|
-
var OriginalObserver = _runtime.globalScope.MutationObserver;
|
|
40
|
-
if (OriginalObserver) {
|
|
41
|
-
window.MutationObserver = function WrappedMutationObserver(cb) {
|
|
42
|
-
if (this instanceof OriginalObserver) {
|
|
43
|
-
return new OriginalObserver(wrapFn(cb, 'fn-'));
|
|
44
|
-
} else {
|
|
45
|
-
return OriginalObserver.apply(this, arguments);
|
|
46
|
-
}
|
|
47
|
-
};
|
|
48
|
-
MutationObserver.prototype = OriginalObserver.prototype;
|
|
49
|
-
}
|
|
50
|
-
return ee;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Returns an event emitter scoped specifically for the `mutation` context. This scoping is a remnant from when all the
|
|
55
|
-
* features shared the same group in the event, to isolate events between features. It will likely be revisited.
|
|
56
|
-
* @param {Object} sharedEE - Optional event emitter on which to base the scoped emitter.
|
|
57
|
-
* Uses `ee` on the global scope if undefined).
|
|
58
|
-
* @returns {Object} Scoped event emitter with a debug ID of 'mutation'.
|
|
59
|
-
*/
|
|
60
|
-
function scopedEE(sharedEE) {
|
|
61
|
-
return (sharedEE || _contextualEe.ee).get('mutation');
|
|
62
|
-
}
|
|
@@ -1,166 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.scopedEE = scopedEE;
|
|
7
|
-
exports.wrapPromise = wrapPromise;
|
|
8
|
-
var _wrapFunction = require("./wrap-function");
|
|
9
|
-
var _contextualEe = require("../event-emitter/contextual-ee");
|
|
10
|
-
var _runtime = require("../constants/runtime");
|
|
11
|
-
/**
|
|
12
|
-
* Copyright 2020-2025 New Relic, Inc. All rights reserved.
|
|
13
|
-
* SPDX-License-Identifier: Apache-2.0
|
|
14
|
-
*/
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* @file Wraps the native Promise object for instrumentation.
|
|
18
|
-
* This module is used by: spa.
|
|
19
|
-
*/
|
|
20
|
-
|
|
21
|
-
const wrapped = {};
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Wraps the native Promise object so that it will emit events for start, end and error in the context of a new event
|
|
25
|
-
* emitter scoped only to promise methods. Also instruments various methods, such as `all`, `race`, `resolve`,
|
|
26
|
-
* `reject`, `then`, and `catch`.
|
|
27
|
-
* @param {Object} sharedEE - The shared event emitter on which a new scoped event emitter will be based.
|
|
28
|
-
* @returns {Object} Scoped event emitter with a debug ID of `promise`.
|
|
29
|
-
*/
|
|
30
|
-
function wrapPromise(sharedEE) {
|
|
31
|
-
const promiseEE = scopedEE(sharedEE);
|
|
32
|
-
|
|
33
|
-
// Notice if our wrapping never ran yet, the falsy NaN will not early return; but if it has,
|
|
34
|
-
// then we increment the count to track # of feats using this at runtime.
|
|
35
|
-
if (wrapped[promiseEE.debugId]) return promiseEE;
|
|
36
|
-
wrapped[promiseEE.debugId] = true; // otherwise, first feature to wrap promise
|
|
37
|
-
|
|
38
|
-
var getContext = promiseEE.context;
|
|
39
|
-
var promiseWrapper = (0, _wrapFunction.createWrapperWithEmitter)(promiseEE);
|
|
40
|
-
var prevPromiseObj = _runtime.globalScope.Promise;
|
|
41
|
-
if (prevPromiseObj) {
|
|
42
|
-
// ensure there's a Promise API (native or otherwise) to even wrap
|
|
43
|
-
wrap();
|
|
44
|
-
}
|
|
45
|
-
function wrap() {
|
|
46
|
-
_runtime.globalScope.Promise = WrappedPromise;
|
|
47
|
-
|
|
48
|
-
// Renamed from "WrappedPromise" back to "Promise" & toString() so that we appear "native" to TP libraries...
|
|
49
|
-
Object.defineProperty(WrappedPromise, 'name', {
|
|
50
|
-
value: 'Promise'
|
|
51
|
-
});
|
|
52
|
-
WrappedPromise.toString = function () {
|
|
53
|
-
return prevPromiseObj.toString();
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* This constitutes the global used when calling "Promise.staticMethod" or chaining off a "new Promise()" object.
|
|
58
|
-
* @param {Function} executor - to be executed by the original Promise constructor
|
|
59
|
-
* @returns A new WrappedPromise object prototyped off the original.
|
|
60
|
-
*/
|
|
61
|
-
function WrappedPromise(executor) {
|
|
62
|
-
var ctx = promiseEE.context();
|
|
63
|
-
var wrappedExecutor = promiseWrapper(executor, 'executor-', ctx, null, false);
|
|
64
|
-
const newCustomPromiseInst = Reflect.construct(prevPromiseObj, [wrappedExecutor], WrappedPromise); // new Promises will use WrappedPromise.prototype as theirs prototype
|
|
65
|
-
|
|
66
|
-
promiseEE.context(newCustomPromiseInst).getCtx = function () {
|
|
67
|
-
return ctx;
|
|
68
|
-
};
|
|
69
|
-
return newCustomPromiseInst;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// Make WrappedPromise inherit statics from the orig Promise.
|
|
73
|
-
Object.setPrototypeOf(WrappedPromise, prevPromiseObj);
|
|
74
|
-
['all', 'race'].forEach(function (method) {
|
|
75
|
-
const prevStaticFn = prevPromiseObj[method];
|
|
76
|
-
WrappedPromise[method] = function (subPromises) {
|
|
77
|
-
// use our own wrapped version of "Promise.all" and ".race" static fns
|
|
78
|
-
let finalized = false;
|
|
79
|
-
[...(subPromises || [])].forEach(sub => {
|
|
80
|
-
this.resolve(sub).then(setNrId(method === 'all'), setNrId(false));
|
|
81
|
-
});
|
|
82
|
-
const origFnCallWithThis = prevStaticFn.apply(this, arguments);
|
|
83
|
-
return origFnCallWithThis;
|
|
84
|
-
function setNrId(overwrite) {
|
|
85
|
-
return function () {
|
|
86
|
-
promiseEE.emit('propagate', [null, !finalized], origFnCallWithThis, false, false);
|
|
87
|
-
finalized = finalized || !overwrite;
|
|
88
|
-
};
|
|
89
|
-
}
|
|
90
|
-
};
|
|
91
|
-
});
|
|
92
|
-
['resolve', 'reject'].forEach(function (method) {
|
|
93
|
-
const prevStaticFn = prevPromiseObj[method];
|
|
94
|
-
WrappedPromise[method] = function (val) {
|
|
95
|
-
// and the same for ".resolve" and ".reject"
|
|
96
|
-
const origFnCallWithThis = prevStaticFn.apply(this, arguments);
|
|
97
|
-
if (val !== origFnCallWithThis) {
|
|
98
|
-
promiseEE.emit('propagate', [val, true], origFnCallWithThis, false, false);
|
|
99
|
-
}
|
|
100
|
-
return origFnCallWithThis;
|
|
101
|
-
};
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
/*
|
|
105
|
-
* Ideally, we create a new WrappedPromise.prototype chained off the original Promise's so that we don't alter it.
|
|
106
|
-
* However, there's no way to make the (native) promise returned from async functions use our WrappedPromise,
|
|
107
|
-
* so we have to modify the original prototype. This ensures that promises returned from async functions execute
|
|
108
|
-
* the same instance methods as promises created with "new Promise()", and also that instanceof async() is
|
|
109
|
-
* the global Promise (see GH issue #409). This also affects the promise returned from fetch().
|
|
110
|
-
*/
|
|
111
|
-
WrappedPromise.prototype = prevPromiseObj.prototype;
|
|
112
|
-
|
|
113
|
-
// Note that this wrapping affects the same originals.PR (prototype) object.
|
|
114
|
-
const prevPromiseOrigThen = prevPromiseObj.prototype.then;
|
|
115
|
-
prevPromiseObj.prototype.then = function wrappedThen(...args) {
|
|
116
|
-
var originalThis = this;
|
|
117
|
-
var ctx = getContext(originalThis);
|
|
118
|
-
ctx.promise = originalThis;
|
|
119
|
-
args[0] = promiseWrapper(args[0], 'cb-', ctx, null, false);
|
|
120
|
-
args[1] = promiseWrapper(args[1], 'cb-', ctx, null, false);
|
|
121
|
-
const origFnCallWithThis = prevPromiseOrigThen.apply(this, args);
|
|
122
|
-
ctx.nextPromise = origFnCallWithThis;
|
|
123
|
-
promiseEE.emit('propagate', [originalThis, true], origFnCallWithThis, false, false);
|
|
124
|
-
return origFnCallWithThis;
|
|
125
|
-
};
|
|
126
|
-
prevPromiseObj.prototype.then[_wrapFunction.flag] = prevPromiseOrigThen;
|
|
127
|
-
promiseEE.on('executor-start', function (args) {
|
|
128
|
-
args[0] = promiseWrapper(args[0], 'resolve-', this, null, false);
|
|
129
|
-
args[1] = promiseWrapper(args[1], 'resolve-', this, null, false);
|
|
130
|
-
});
|
|
131
|
-
promiseEE.on('executor-err', function (args, originalThis, err) {
|
|
132
|
-
args[1](err);
|
|
133
|
-
});
|
|
134
|
-
promiseEE.on('cb-end', function (args, originalThis, result) {
|
|
135
|
-
promiseEE.emit('propagate', [result, true], this.nextPromise, false, false);
|
|
136
|
-
});
|
|
137
|
-
promiseEE.on('propagate', function (val, overwrite, trigger) {
|
|
138
|
-
if (!this.getCtx || overwrite) {
|
|
139
|
-
const selfStore = this;
|
|
140
|
-
const parentStore = val instanceof Promise ? promiseEE.context(val) : null;
|
|
141
|
-
let cachedCtx;
|
|
142
|
-
this.getCtx = function getCtx() {
|
|
143
|
-
if (cachedCtx) return cachedCtx;
|
|
144
|
-
if (parentStore && parentStore !== selfStore) {
|
|
145
|
-
cachedCtx = typeof parentStore.getCtx === 'function' ? parentStore.getCtx() : parentStore;
|
|
146
|
-
} else {
|
|
147
|
-
cachedCtx = selfStore;
|
|
148
|
-
}
|
|
149
|
-
return cachedCtx;
|
|
150
|
-
};
|
|
151
|
-
}
|
|
152
|
-
});
|
|
153
|
-
}
|
|
154
|
-
return promiseEE;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
/**
|
|
158
|
-
* Returns an event emitter scoped specifically for the `promise` context. This scoping is a remnant from when all the
|
|
159
|
-
* features shared the same group in the event, to isolate events between features. It will likely be revisited.
|
|
160
|
-
* @param {Object} sharedEE - Optional event emitter on which to base the scoped emitter.
|
|
161
|
-
* Uses `ee` on the global scope if undefined).
|
|
162
|
-
* @returns {Object} Scoped event emitter with a debug ID of 'promise'.
|
|
163
|
-
*/
|
|
164
|
-
function scopedEE(sharedEE) {
|
|
165
|
-
return (sharedEE || _contextualEe.ee).get('promise');
|
|
166
|
-
}
|