@newrelic/browser-agent 0.0.9 → 0.1.229
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/README.md +84 -207
- package/dist/cjs/cdn/lite.js +14 -0
- package/dist/cjs/cdn/polyfills/lite.js +4 -0
- package/dist/cjs/cdn/polyfills/pro.js +4 -0
- package/dist/cjs/cdn/polyfills/spa.js +4 -0
- package/dist/cjs/cdn/polyfills.js +14 -0
- package/dist/cjs/cdn/pro.js +19 -0
- package/dist/cjs/cdn/spa.js +19 -0
- package/dist/cjs/cdn/worker.js +16 -0
- package/dist/cjs/common/aggregate/aggregator.js +168 -0
- package/dist/cjs/common/browser-version/firefox-version.js +17 -0
- package/dist/cjs/common/browser-version/ios-version.js +18 -0
- package/dist/cjs/common/config/config.js +76 -0
- package/dist/cjs/common/config/state/configurable.js +32 -0
- package/dist/cjs/common/config/state/info.js +50 -0
- package/dist/cjs/common/config/state/init.js +86 -0
- package/dist/cjs/common/config/state/loader-config.js +28 -0
- package/dist/cjs/common/config/state/originals.js +9 -0
- package/dist/cjs/common/config/state/runtime.js +50 -0
- package/dist/cjs/common/constants/environment-variables.js +20 -0
- package/dist/cjs/common/context/shared-context.js +25 -0
- package/dist/cjs/common/deny-list/deny-list.js +108 -0
- package/dist/cjs/common/drain/drain.js +126 -0
- package/dist/cjs/common/event-emitter/contextual-ee.js +149 -0
- package/dist/cjs/common/event-emitter/handle.js +24 -0
- package/dist/cjs/common/event-emitter/register-handler.js +24 -0
- package/dist/cjs/common/event-listener/event-listener-opts.js +46 -0
- package/dist/cjs/common/harvest/harvest-scheduler.js +111 -0
- package/dist/cjs/common/harvest/harvest.js +236 -0
- package/dist/cjs/common/ids/id.js +30 -0
- package/dist/cjs/common/ids/unique-id.js +84 -0
- package/dist/cjs/common/metrics/framework-detection.js +72 -0
- package/dist/cjs/common/metrics/paint-metrics.js +13 -0
- package/dist/cjs/common/serialize/bel-serializer.js +89 -0
- package/dist/cjs/common/timing/nav-timing.js +77 -0
- package/dist/cjs/common/timing/now.js +15 -0
- package/dist/cjs/common/unload/eol.js +69 -0
- package/dist/cjs/common/url/clean-url.js +16 -0
- package/dist/cjs/common/url/encode.js +79 -0
- package/dist/cjs/common/url/location.js +14 -0
- package/dist/cjs/common/url/parse-url.js +66 -0
- package/dist/cjs/common/url/protocol.js +25 -0
- package/dist/cjs/common/util/console.js +17 -0
- package/dist/cjs/common/util/data-size.js +25 -0
- package/dist/cjs/common/util/feature-flags.js +42 -0
- package/dist/cjs/common/util/get-or-set.js +39 -0
- package/dist/cjs/common/util/global-scope.js +56 -0
- package/dist/cjs/common/util/map-own.js +24 -0
- package/dist/cjs/common/util/obfuscate.js +76 -0
- package/dist/cjs/common/util/reduce.js +22 -0
- package/dist/cjs/common/util/s-hash.js +19 -0
- package/dist/cjs/common/util/single.js +23 -0
- package/dist/cjs/common/util/stringify.js +47 -0
- package/dist/cjs/common/util/submit-data.js +99 -0
- package/dist/cjs/common/util/traverse.js +41 -0
- package/dist/cjs/common/util/user-agent.js +57 -0
- package/dist/cjs/common/window/load.js +19 -0
- package/dist/cjs/common/window/nreum.js +107 -0
- package/dist/cjs/common/window/page-visibility.js +28 -0
- package/dist/cjs/common/window/session-storage.js +42 -0
- package/dist/cjs/common/window/supports-performance-observer.js +15 -0
- package/dist/cjs/common/window/top-level-callers.js +23 -0
- package/dist/cjs/common/wrap/index.js +68 -0
- package/dist/cjs/common/wrap/wrap-events.js +105 -0
- package/dist/cjs/common/wrap/wrap-fetch.js +114 -0
- package/dist/cjs/common/wrap/wrap-function.js +269 -0
- package/dist/cjs/common/wrap/wrap-history.js +56 -0
- package/dist/cjs/common/wrap/wrap-jsonp.js +129 -0
- package/dist/cjs/common/wrap/wrap-mutation.js +61 -0
- package/dist/cjs/common/wrap/wrap-promise.js +160 -0
- package/dist/cjs/common/wrap/wrap-raf.js +55 -0
- package/dist/cjs/common/wrap/wrap-timer.js +70 -0
- package/dist/cjs/common/wrap/wrap-xhr.js +206 -0
- package/dist/cjs/features/ajax/aggregate/index.js +226 -0
- package/dist/cjs/features/ajax/constants.js +9 -0
- package/dist/cjs/features/ajax/index.js +12 -0
- package/dist/cjs/features/ajax/instrument/distributed-tracing.js +145 -0
- package/dist/cjs/features/ajax/instrument/index.js +338 -0
- package/dist/cjs/features/ajax/instrument/response-size.js +26 -0
- package/dist/cjs/features/jserrors/aggregate/canonical-function-name.js +18 -0
- package/dist/cjs/features/jserrors/aggregate/canonical-function-name.test.js +30 -0
- package/dist/cjs/features/jserrors/aggregate/compute-stack-trace.js +216 -0
- package/dist/cjs/features/jserrors/aggregate/compute-stack-trace.test.js +257 -0
- package/dist/cjs/features/jserrors/aggregate/format-stack-trace.js +36 -0
- package/dist/cjs/features/jserrors/aggregate/format-stack-trace.test.js +39 -0
- package/dist/cjs/features/jserrors/aggregate/index.js +267 -0
- package/dist/cjs/features/jserrors/aggregate/string-hash-code.js +23 -0
- package/dist/cjs/features/jserrors/aggregate/string-hash-code.test.js +26 -0
- package/dist/cjs/features/jserrors/constants.js +11 -0
- package/dist/cjs/features/jserrors/index.js +12 -0
- package/dist/cjs/features/jserrors/instrument/debug.js +40 -0
- package/dist/cjs/features/jserrors/instrument/index.js +158 -0
- package/dist/cjs/features/metrics/aggregate/index.js +136 -0
- package/dist/cjs/features/metrics/constants.js +17 -0
- package/dist/cjs/features/metrics/index.js +12 -0
- package/dist/cjs/features/metrics/instrument/index.js +20 -0
- package/dist/cjs/features/metrics/instrument/workers-helper.js +121 -0
- package/dist/cjs/features/page_action/aggregate/index.js +112 -0
- package/dist/cjs/features/page_action/constants.js +9 -0
- package/dist/cjs/features/page_action/index.js +12 -0
- package/dist/cjs/features/page_action/instrument/index.js +21 -0
- package/dist/cjs/features/page_view_event/aggregate/index.js +133 -0
- package/dist/cjs/features/page_view_event/aggregate/initialized-features.js +39 -0
- package/dist/cjs/features/page_view_event/constants.js +15 -0
- package/dist/cjs/features/page_view_event/index.js +12 -0
- package/dist/cjs/features/page_view_event/instrument/index.js +38 -0
- package/dist/cjs/features/page_view_timing/aggregate/index.js +265 -0
- package/dist/cjs/features/page_view_timing/constants.js +9 -0
- package/dist/cjs/features/page_view_timing/first-paint.js +50 -0
- package/dist/cjs/features/page_view_timing/index.js +12 -0
- package/dist/cjs/features/page_view_timing/instrument/index.js +36 -0
- package/dist/cjs/features/page_view_timing/long-tasks.js +75 -0
- package/dist/cjs/features/session_trace/aggregate/index.js +375 -0
- package/dist/cjs/features/session_trace/constants.js +32 -0
- package/dist/cjs/features/session_trace/index.js +12 -0
- package/dist/cjs/features/session_trace/instrument/index.js +133 -0
- package/dist/cjs/features/spa/aggregate/index.js +684 -0
- package/dist/cjs/features/spa/aggregate/interaction-node.js +84 -0
- package/dist/cjs/features/spa/aggregate/interaction-node.test.js +16 -0
- package/dist/cjs/features/spa/aggregate/interaction.js +98 -0
- package/dist/cjs/features/spa/aggregate/serializer.js +147 -0
- package/dist/cjs/features/spa/constants.js +53 -0
- package/dist/cjs/features/spa/index.js +12 -0
- package/dist/cjs/features/spa/instrument/index.js +114 -0
- package/dist/cjs/features/utils/aggregate-base.js +13 -0
- package/dist/cjs/features/utils/feature-base.js +58 -0
- package/dist/cjs/features/utils/handler-cache.js +64 -0
- package/dist/cjs/features/utils/instrument-base.js +71 -0
- package/dist/cjs/features/utils/lazy-loader.js +44 -0
- package/dist/cjs/index.js +81 -58
- package/dist/cjs/loaders/agent.js +86 -0
- package/dist/cjs/loaders/api/api.js +109 -0
- package/dist/cjs/loaders/api/apiAsync.js +94 -0
- package/dist/cjs/loaders/browser-agent.js +29 -0
- package/dist/cjs/loaders/configure/configure.js +47 -0
- package/dist/cjs/loaders/features/enabled-features.js +19 -0
- package/dist/cjs/loaders/features/featureDependencies.js +32 -0
- package/dist/cjs/loaders/features/features.js +33 -0
- package/dist/cjs/loaders/micro-agent.js +93 -0
- package/dist/cjs/loaders/worker-agent.js +24 -0
- package/dist/esm/cdn/lite.js +12 -0
- package/dist/esm/cdn/polyfills/lite.js +7 -0
- package/dist/esm/cdn/polyfills/pro.js +7 -0
- package/dist/esm/cdn/polyfills/spa.js +7 -0
- package/dist/esm/cdn/polyfills.js +17 -0
- package/dist/esm/cdn/pro.js +17 -0
- package/dist/esm/cdn/spa.js +17 -0
- package/dist/esm/cdn/worker.js +14 -0
- package/dist/esm/common/aggregate/aggregator.js +161 -0
- package/dist/esm/common/browser-version/firefox-version.js +10 -0
- package/dist/esm/common/browser-version/ios-version.js +10 -0
- package/dist/esm/common/config/config.js +11 -0
- package/dist/esm/common/config/state/configurable.js +25 -0
- package/dist/esm/common/config/state/info.js +42 -0
- package/dist/esm/common/config/state/init.js +78 -0
- package/dist/esm/common/config/state/loader-config.js +21 -0
- package/dist/esm/common/config/state/originals.js +2 -0
- package/dist/esm/common/config/state/runtime.js +41 -0
- package/dist/esm/common/constants/environment-variables.js +11 -0
- package/dist/esm/common/context/shared-context.js +18 -0
- package/dist/esm/common/deny-list/deny-list.js +101 -0
- package/dist/esm/common/drain/drain.js +119 -0
- package/dist/esm/common/event-emitter/contextual-ee.js +142 -0
- package/dist/esm/common/event-emitter/handle.js +16 -0
- package/dist/esm/common/event-emitter/register-handler.js +19 -0
- package/dist/esm/common/event-listener/event-listener-opts.js +39 -0
- package/dist/esm/common/harvest/harvest-scheduler.js +105 -0
- package/dist/esm/common/harvest/harvest.js +228 -0
- package/dist/esm/common/ids/id.js +23 -0
- package/dist/esm/common/ids/unique-id.js +75 -0
- package/dist/esm/common/metrics/framework-detection.js +66 -0
- package/dist/esm/common/metrics/paint-metrics.js +6 -0
- package/dist/esm/common/serialize/bel-serializer.js +80 -0
- package/dist/esm/common/timing/nav-timing.js +67 -0
- package/dist/esm/common/timing/now.js +9 -0
- package/dist/esm/common/unload/eol.js +62 -0
- package/dist/esm/common/url/clean-url.js +10 -0
- package/dist/esm/common/url/encode.js +71 -0
- package/dist/esm/common/url/location.js +8 -0
- package/dist/esm/common/url/parse-url.js +60 -0
- package/dist/esm/common/url/protocol.js +17 -0
- package/dist/esm/common/util/console.js +11 -0
- package/dist/esm/common/util/data-size.js +19 -0
- package/dist/esm/common/util/feature-flags.js +33 -0
- package/dist/esm/common/util/get-or-set.js +33 -0
- package/dist/esm/common/util/global-scope.js +44 -0
- package/dist/esm/common/util/map-own.js +18 -0
- package/dist/esm/common/util/obfuscate.js +67 -0
- package/dist/esm/common/util/reduce.js +16 -0
- package/dist/esm/common/util/s-hash.js +13 -0
- package/dist/esm/common/util/single.js +16 -0
- package/dist/esm/common/util/stringify.js +42 -0
- package/dist/esm/common/util/submit-data.js +91 -0
- package/dist/esm/common/util/traverse.js +35 -0
- package/dist/esm/common/util/user-agent.js +48 -0
- package/dist/esm/common/window/load.js +12 -0
- package/dist/esm/common/window/nreum.js +91 -0
- package/dist/esm/common/window/page-visibility.js +23 -0
- package/dist/esm/common/window/session-storage.js +36 -0
- package/dist/esm/common/window/supports-performance-observer.js +9 -0
- package/dist/esm/common/window/top-level-callers.js +17 -0
- package/dist/esm/common/wrap/index.js +14 -0
- package/dist/esm/common/wrap/wrap-events.js +97 -0
- package/dist/esm/common/wrap/wrap-fetch.js +105 -0
- package/dist/esm/common/wrap/wrap-function.js +257 -0
- package/dist/esm/common/wrap/wrap-history.js +48 -0
- package/dist/esm/common/wrap/wrap-jsonp.js +122 -0
- package/dist/esm/common/wrap/wrap-mutation.js +54 -0
- package/dist/esm/common/wrap/wrap-promise.js +153 -0
- package/dist/esm/common/wrap/wrap-raf.js +48 -0
- package/dist/esm/common/wrap/wrap-timer.js +63 -0
- package/dist/esm/common/wrap/wrap-xhr.js +199 -0
- package/dist/esm/features/ajax/aggregate/index.js +218 -0
- package/dist/esm/features/ajax/constants.js +2 -0
- package/dist/esm/features/ajax/index.js +1 -0
- package/dist/esm/features/ajax/instrument/distributed-tracing.js +137 -0
- package/dist/esm/features/ajax/instrument/index.js +330 -0
- package/dist/esm/features/ajax/instrument/response-size.js +19 -0
- package/dist/esm/features/jserrors/aggregate/canonical-function-name.js +12 -0
- package/dist/esm/features/jserrors/aggregate/canonical-function-name.test.js +28 -0
- package/dist/esm/features/jserrors/aggregate/compute-stack-trace.js +209 -0
- package/dist/esm/features/jserrors/aggregate/compute-stack-trace.test.js +255 -0
- package/dist/esm/features/jserrors/aggregate/format-stack-trace.js +29 -0
- package/dist/esm/features/jserrors/aggregate/format-stack-trace.test.js +37 -0
- package/dist/esm/features/jserrors/aggregate/index.js +260 -0
- package/dist/esm/features/jserrors/aggregate/string-hash-code.js +17 -0
- package/dist/esm/features/jserrors/aggregate/string-hash-code.test.js +24 -0
- package/dist/esm/features/jserrors/constants.js +3 -0
- package/dist/esm/features/jserrors/index.js +1 -0
- package/dist/esm/features/jserrors/instrument/debug.js +38 -0
- package/dist/esm/features/jserrors/instrument/index.js +150 -0
- package/dist/esm/features/metrics/aggregate/index.js +129 -0
- package/dist/esm/features/metrics/constants.js +6 -0
- package/dist/esm/features/metrics/index.js +1 -0
- package/dist/esm/features/metrics/instrument/index.js +13 -0
- package/dist/esm/features/metrics/instrument/workers-helper.js +116 -0
- package/dist/esm/features/page_action/aggregate/index.js +105 -0
- package/dist/esm/features/page_action/constants.js +2 -0
- package/dist/esm/features/page_action/index.js +1 -0
- package/dist/esm/features/page_action/instrument/index.js +14 -0
- package/dist/esm/features/page_view_event/aggregate/index.js +124 -0
- package/dist/esm/features/page_view_event/aggregate/initialized-features.js +34 -0
- package/dist/esm/features/page_view_event/constants.js +5 -0
- package/dist/esm/features/page_view_event/index.js +1 -0
- package/dist/esm/features/page_view_event/instrument/index.js +29 -0
- package/dist/esm/features/page_view_timing/aggregate/index.js +258 -0
- package/dist/esm/features/page_view_timing/constants.js +2 -0
- package/dist/esm/features/page_view_timing/first-paint.js +43 -0
- package/dist/esm/features/page_view_timing/index.js +1 -0
- package/dist/esm/features/page_view_timing/instrument/index.js +28 -0
- package/dist/esm/features/page_view_timing/long-tasks.js +69 -0
- package/dist/esm/features/session_trace/aggregate/index.js +366 -0
- package/dist/esm/features/session_trace/constants.js +14 -0
- package/dist/esm/features/session_trace/index.js +1 -0
- package/dist/esm/features/session_trace/instrument/index.js +123 -0
- package/dist/esm/features/spa/aggregate/index.js +674 -0
- package/dist/esm/features/spa/aggregate/interaction-node.js +78 -0
- package/dist/esm/features/spa/aggregate/interaction-node.test.js +14 -0
- package/dist/esm/features/spa/aggregate/interaction.js +92 -0
- package/dist/esm/features/spa/aggregate/serializer.js +139 -0
- package/dist/esm/features/spa/constants.js +25 -0
- package/dist/esm/features/spa/index.js +1 -0
- package/dist/esm/features/spa/instrument/index.js +104 -0
- package/dist/esm/features/utils/aggregate-base.js +6 -0
- package/dist/esm/features/utils/feature-base.js +51 -0
- package/dist/esm/features/utils/handler-cache.js +57 -0
- package/dist/esm/features/utils/instrument-base.js +69 -0
- package/dist/esm/features/utils/lazy-loader.js +37 -0
- package/dist/esm/index.js +15 -0
- package/dist/esm/loaders/agent.js +77 -0
- package/dist/esm/loaders/api/api.js +104 -0
- package/dist/esm/loaders/api/apiAsync.js +88 -0
- package/dist/esm/loaders/browser-agent.js +23 -0
- package/dist/esm/loaders/configure/configure.js +41 -0
- package/dist/esm/loaders/features/enabled-features.js +13 -0
- package/dist/esm/loaders/features/featureDependencies.js +25 -0
- package/dist/esm/loaders/features/features.js +25 -0
- package/dist/esm/loaders/micro-agent.js +86 -0
- package/dist/esm/loaders/worker-agent.js +18 -0
- package/package.json +204 -71
- package/types.ts +221 -0
- package/dist/bundled/es5/index.js +0 -2
- package/dist/bundled/es5/index.js.map +0 -1
- package/dist/bundled/es6/index.js +0 -2
- package/dist/bundled/es6/index.js.map +0 -1
- package/dist/cjs/index.d.ts +0 -19
- package/dist/cjs/index.js.map +0 -1
- package/dist/cjs/types.d.ts +0 -94
- package/dist/cjs/types.js +0 -28
- package/dist/cjs/types.js.map +0 -1
- package/dist/cjs/utils/api/api.d.ts +0 -10
- package/dist/cjs/utils/api/api.js +0 -40
- package/dist/cjs/utils/api/api.js.map +0 -1
- package/dist/cjs/utils/config/build-configs.d.ts +0 -6
- package/dist/cjs/utils/config/build-configs.js +0 -68
- package/dist/cjs/utils/config/build-configs.js.map +0 -1
- package/dist/cjs/utils/features/features.d.ts +0 -5
- package/dist/cjs/utils/features/features.js +0 -14
- package/dist/cjs/utils/features/features.js.map +0 -1
- package/dist/cjs/utils/features/initialize.d.ts +0 -5
- package/dist/cjs/utils/features/initialize.js +0 -51
- package/dist/cjs/utils/features/initialize.js.map +0 -1
- package/dist/es/index.d.ts +0 -19
- package/dist/es/index.js +0 -55
- package/dist/es/index.js.map +0 -1
- package/dist/es/types.d.ts +0 -94
- package/dist/es/types.js +0 -24
- package/dist/es/types.js.map +0 -1
- package/dist/es/utils/api/api.d.ts +0 -10
- package/dist/es/utils/api/api.js +0 -36
- package/dist/es/utils/api/api.js.map +0 -1
- package/dist/es/utils/config/build-configs.d.ts +0 -6
- package/dist/es/utils/config/build-configs.js +0 -64
- package/dist/es/utils/config/build-configs.js.map +0 -1
- package/dist/es/utils/features/features.d.ts +0 -5
- package/dist/es/utils/features/features.js +0 -10
- package/dist/es/utils/features/features.js.map +0 -1
- package/dist/es/utils/features/initialize.d.ts +0 -5
- package/dist/es/utils/features/initialize.js +0 -24
- package/dist/es/utils/features/initialize.js.map +0 -1
- package/dist/umd/index.d.ts +0 -19
- package/dist/umd/index.js +0 -69
- package/dist/umd/index.js.map +0 -1
- package/dist/umd/types.d.ts +0 -94
- package/dist/umd/types.js +0 -38
- package/dist/umd/types.js.map +0 -1
- package/dist/umd/utils/api/api.d.ts +0 -10
- package/dist/umd/utils/api/api.js +0 -50
- package/dist/umd/utils/api/api.js.map +0 -1
- package/dist/umd/utils/config/build-configs.d.ts +0 -6
- package/dist/umd/utils/config/build-configs.js +0 -78
- package/dist/umd/utils/config/build-configs.js.map +0 -1
- package/dist/umd/utils/features/features.d.ts +0 -5
- package/dist/umd/utils/features/features.js +0 -24
- package/dist/umd/utils/features/features.js.map +0 -1
- package/dist/umd/utils/features/initialize.d.ts +0 -5
- package/dist/umd/utils/features/initialize.js +0 -63
- package/dist/umd/utils/features/initialize.js.map +0 -1
- package/dist/webpack-analysis.html +0 -38
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { now } from '../timing/now';
|
|
2
|
+
import { globalScope } from '../util/global-scope';
|
|
3
|
+
export const defaults = {
|
|
4
|
+
beacon: 'bam.nr-data.net',
|
|
5
|
+
errorBeacon: 'bam.nr-data.net'
|
|
6
|
+
};
|
|
7
|
+
export function gosNREUM() {
|
|
8
|
+
if (!globalScope.NREUM) {
|
|
9
|
+
globalScope.NREUM = {};
|
|
10
|
+
}
|
|
11
|
+
if (typeof globalScope.newrelic === 'undefined') globalScope.newrelic = globalScope.NREUM;
|
|
12
|
+
return globalScope.NREUM;
|
|
13
|
+
}
|
|
14
|
+
export function gosNREUMInfo() {
|
|
15
|
+
let nr = gosNREUM();
|
|
16
|
+
const externallySupplied = nr.info || {};
|
|
17
|
+
nr.info = {
|
|
18
|
+
beacon: defaults.beacon,
|
|
19
|
+
errorBeacon: defaults.errorBeacon,
|
|
20
|
+
...externallySupplied
|
|
21
|
+
};
|
|
22
|
+
return nr;
|
|
23
|
+
}
|
|
24
|
+
export function gosNREUMLoaderConfig() {
|
|
25
|
+
let nr = gosNREUM();
|
|
26
|
+
const externallySupplied = nr.loader_config || {};
|
|
27
|
+
nr.loader_config = {
|
|
28
|
+
...externallySupplied
|
|
29
|
+
};
|
|
30
|
+
return nr;
|
|
31
|
+
}
|
|
32
|
+
export function gosNREUMInit() {
|
|
33
|
+
let nr = gosNREUM();
|
|
34
|
+
const externallySupplied = nr.init || {};
|
|
35
|
+
nr.init = {
|
|
36
|
+
...externallySupplied
|
|
37
|
+
};
|
|
38
|
+
return nr;
|
|
39
|
+
}
|
|
40
|
+
export function gosNREUMOriginals() {
|
|
41
|
+
let nr = gosNREUM();
|
|
42
|
+
if (!nr.o) {
|
|
43
|
+
nr.o = {
|
|
44
|
+
ST: globalScope.setTimeout,
|
|
45
|
+
SI: globalScope.setImmediate,
|
|
46
|
+
CT: globalScope.clearTimeout,
|
|
47
|
+
XHR: globalScope.XMLHttpRequest,
|
|
48
|
+
REQ: globalScope.Request,
|
|
49
|
+
EV: globalScope.Event,
|
|
50
|
+
PR: globalScope.Promise,
|
|
51
|
+
MO: globalScope.MutationObserver,
|
|
52
|
+
// this'll be undefined if not in a web window
|
|
53
|
+
FETCH: globalScope.fetch
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
return nr;
|
|
57
|
+
}
|
|
58
|
+
export function gosNREUMInitializedAgents(id, obj, target) {
|
|
59
|
+
let nr = gosNREUM();
|
|
60
|
+
const externallySupplied = nr.initializedAgents || {};
|
|
61
|
+
const curr = externallySupplied[id] || {};
|
|
62
|
+
if (!Object.keys(curr).length) {
|
|
63
|
+
curr.initializedAt = {
|
|
64
|
+
ms: now(),
|
|
65
|
+
date: new Date()
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
nr.initializedAgents = {
|
|
69
|
+
...externallySupplied,
|
|
70
|
+
[id]: {
|
|
71
|
+
...curr,
|
|
72
|
+
[target]: obj
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
return nr;
|
|
76
|
+
}
|
|
77
|
+
export function addToNREUM(fnName, fn) {
|
|
78
|
+
let nr = gosNREUM();
|
|
79
|
+
nr[fnName] = fn;
|
|
80
|
+
}
|
|
81
|
+
export function NREUMinitialized() {
|
|
82
|
+
const nr = gosNREUM();
|
|
83
|
+
nr.initialized = true;
|
|
84
|
+
}
|
|
85
|
+
export function gosCDN() {
|
|
86
|
+
gosNREUMInfo();
|
|
87
|
+
gosNREUMInit();
|
|
88
|
+
gosNREUMOriginals();
|
|
89
|
+
gosNREUMLoaderConfig();
|
|
90
|
+
return gosNREUM();
|
|
91
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2020 New Relic Corporation. All rights reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { documentAddEventListener } from '../event-listener/event-listener-opts';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @param {function} cb - called when a visibility change occurs with the vis state at that time
|
|
10
|
+
* @param {boolean} [toHiddenOnly=false] - only execute the 'cb' when the vis is changing to the hidden state; no arg is passed to 'cb' if used
|
|
11
|
+
* @returns void
|
|
12
|
+
*/
|
|
13
|
+
export function subscribeToVisibilityChange(cb, toHiddenOnly = false) {
|
|
14
|
+
documentAddEventListener('visibilitychange', handleVisibilityChange);
|
|
15
|
+
return;
|
|
16
|
+
function handleVisibilityChange() {
|
|
17
|
+
if (toHiddenOnly) {
|
|
18
|
+
// trigger cb on change to hidden state only
|
|
19
|
+
if (document.visibilityState == 'hidden') cb();else return;
|
|
20
|
+
}
|
|
21
|
+
cb(document.visibilityState);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Interface for Agents' usage of the Window.sessionStorage as a replacement to third-party cookies.
|
|
3
|
+
* (All agents on a tab|window will share the same sessionStorage.)
|
|
4
|
+
*
|
|
5
|
+
* @design https://newrelic.atlassian.net/wiki/spaces/INST/pages/2522513791/JSESSIONID+Cookie+Change+Design+Document
|
|
6
|
+
* @environment Browser script
|
|
7
|
+
*/
|
|
8
|
+
import { generateRandomHexString } from '../ids/unique-id';
|
|
9
|
+
import { isBrowserScope } from '../util/global-scope';
|
|
10
|
+
export { getCurrentSessionIdOrMakeNew };
|
|
11
|
+
const SESS_ID = 'NRBA_SESSION_ID'; // prevents potential key collisions in session storage
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @returns {string} This tab|window's session identifier, or a new ID if not found in storage
|
|
15
|
+
*/
|
|
16
|
+
function getCurrentSessionIdOrMakeNew() {
|
|
17
|
+
if (!isBrowserScope) {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
try {
|
|
21
|
+
let sessionId;
|
|
22
|
+
if ((sessionId = window.sessionStorage.getItem(SESS_ID)) === null) {
|
|
23
|
+
// Generate a new one if storage is empty (no previous ID was created or currently exists)
|
|
24
|
+
sessionId = generateRandomHexString(16);
|
|
25
|
+
window.sessionStorage.setItem(SESS_ID, sessionId);
|
|
26
|
+
}
|
|
27
|
+
return sessionId;
|
|
28
|
+
} catch (ex) {
|
|
29
|
+
// Session storage quota most likely 0mb and cannot be written to
|
|
30
|
+
// OR the agent is running in a security context that does not allow
|
|
31
|
+
// access to the browser sessionStorage
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// In the future, we may expand sessionStorage to, say, auto-save some other agent data between page refreshes.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2020 New Relic Corporation. All rights reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { globalScope } from '../util/global-scope';
|
|
7
|
+
export function supportsPerformanceObserver() {
|
|
8
|
+
return typeof globalScope?.PerformanceObserver === 'function';
|
|
9
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { gosCDN } from './nreum';
|
|
2
|
+
export function setTopLevelCallers() {
|
|
3
|
+
const nr = gosCDN();
|
|
4
|
+
const funcs = ['setErrorHandler', 'finished', 'addToTrace', 'inlineHit', 'addRelease', 'addPageAction', 'setCurrentRouteName', 'setPageViewName', 'setCustomAttribute', 'interaction', 'noticeError'];
|
|
5
|
+
funcs.forEach(f => {
|
|
6
|
+
nr[f] = (...args) => caller(f, ...args);
|
|
7
|
+
});
|
|
8
|
+
function caller(fnName, ...args) {
|
|
9
|
+
let returnVals = [];
|
|
10
|
+
Object.values(nr.initializedAgents).forEach(val => {
|
|
11
|
+
if (val.exposed && val.api[fnName]) {
|
|
12
|
+
returnVals.push(val.api[fnName](...args));
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
return returnVals.length > 1 ? returnsVals : returnVals[0];
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Wraps assorted native objects and functions for instrumentation.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { wrapFetch } from './wrap-fetch';
|
|
6
|
+
import { wrapTimer } from './wrap-timer';
|
|
7
|
+
import { wrapRaf } from './wrap-raf';
|
|
8
|
+
import { wrapHistory } from './wrap-history';
|
|
9
|
+
import { wrapJsonP } from './wrap-jsonp';
|
|
10
|
+
import { wrapMutation } from './wrap-mutation';
|
|
11
|
+
import { wrapPromise } from './wrap-promise';
|
|
12
|
+
import { wrapXhr } from './wrap-xhr';
|
|
13
|
+
import { wrapEvents } from './wrap-events';
|
|
14
|
+
export { wrapEvents, wrapFetch, wrapHistory, wrapJsonP, wrapMutation, wrapPromise, wrapRaf, wrapTimer, wrapXhr };
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2020 New Relic Corporation. All rights reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* @file Wraps `addEventListener` and `removeEventListener` for instrumentation.
|
|
7
|
+
* This module is used directly by: session_trace.
|
|
8
|
+
* It is also called by -> wrapXhr <-, so see "wrap-xhr.js" for features that use this indirectly.
|
|
9
|
+
*/
|
|
10
|
+
import { ee as baseEE } from '../event-emitter/contextual-ee';
|
|
11
|
+
import { createWrapperWithEmitter as wfn, unwrapFunction } from './wrap-function';
|
|
12
|
+
import { getOrSet } from '../util/get-or-set';
|
|
13
|
+
import { globalScope, isBrowserScope } from '../util/global-scope';
|
|
14
|
+
const wrapped = {};
|
|
15
|
+
const XHR = XMLHttpRequest;
|
|
16
|
+
const ADD_EVENT_LISTENER = 'addEventListener';
|
|
17
|
+
const REMOVE_EVENT_LISTENER = 'removeEventListener';
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Wraps `addEventListener` and `removeEventListener` on: global scope; the prototype of `XMLHttpRequest`, and
|
|
21
|
+
* `document` (if in a browser scope). Adds custom events in context of a new emitter scoped only to these methods.
|
|
22
|
+
* @param {Object} sharedEE - The shared event emitter on which a new scoped
|
|
23
|
+
* event emitter will be based.
|
|
24
|
+
* @returns {Object} Scoped event emitter with a debug ID of `events`.
|
|
25
|
+
*/
|
|
26
|
+
export function wrapEvents(sharedEE) {
|
|
27
|
+
var ee = scopedEE(sharedEE);
|
|
28
|
+
if (wrapped[ee.debugId]++)
|
|
29
|
+
// Notice if our wrapping never ran yet, the falsey NaN will not early return; but if it has,
|
|
30
|
+
{
|
|
31
|
+
return ee;
|
|
32
|
+
} // then we increment the count to track # of feats using this at runtime.
|
|
33
|
+
wrapped[ee.debugId] = 1;
|
|
34
|
+
var wrapFn = wfn(ee, true);
|
|
35
|
+
|
|
36
|
+
// Guard against instrumenting environments w/o necessary features
|
|
37
|
+
if ('getPrototypeOf' in Object) {
|
|
38
|
+
if (isBrowserScope) {
|
|
39
|
+
findEventListenerProtoAndCb(document, wrapNode);
|
|
40
|
+
}
|
|
41
|
+
findEventListenerProtoAndCb(globalScope, wrapNode);
|
|
42
|
+
findEventListenerProtoAndCb(XHR.prototype, wrapNode);
|
|
43
|
+
}
|
|
44
|
+
ee.on(ADD_EVENT_LISTENER + '-start', function (args, target) {
|
|
45
|
+
var originalListener = args[1];
|
|
46
|
+
if (originalListener === null || typeof originalListener !== 'function' && typeof originalListener !== 'object') {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
var wrapped = getOrSet(originalListener, 'nr@wrapped', function () {
|
|
50
|
+
var listener = {
|
|
51
|
+
object: wrapHandleEvent,
|
|
52
|
+
function: originalListener
|
|
53
|
+
}[typeof originalListener];
|
|
54
|
+
return listener ? wrapFn(listener, 'fn-', null, listener.name || 'anonymous') : originalListener;
|
|
55
|
+
function wrapHandleEvent() {
|
|
56
|
+
if (typeof originalListener.handleEvent !== 'function') return;
|
|
57
|
+
return originalListener.handleEvent.apply(originalListener, arguments);
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
this.wrapped = args[1] = wrapped;
|
|
61
|
+
});
|
|
62
|
+
ee.on(REMOVE_EVENT_LISTENER + '-start', function (args) {
|
|
63
|
+
args[1] = this.wrapped || args[1];
|
|
64
|
+
});
|
|
65
|
+
function wrapNode(node) {
|
|
66
|
+
wrapFn.inPlace(node, [ADD_EVENT_LISTENER, REMOVE_EVENT_LISTENER], '-', uniqueListener);
|
|
67
|
+
}
|
|
68
|
+
function uniqueListener(args, obj) {
|
|
69
|
+
// Context for the listener is stored on itself.
|
|
70
|
+
return args[1];
|
|
71
|
+
}
|
|
72
|
+
return ee;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Find the base prototype of 'object' that has its own "addEventListener" property, and run some function on it.
|
|
76
|
+
* @param {Object} object - the initial object to traverse prototype chain on
|
|
77
|
+
* @param {Function} cb - the function to run on the ancestral object once found, accepts an object as a arg
|
|
78
|
+
* @param {Array} rest - [optional] any additional arguments to pass to the cb
|
|
79
|
+
*/
|
|
80
|
+
function findEventListenerProtoAndCb(object, cb, ...rest) {
|
|
81
|
+
let step = object;
|
|
82
|
+
while (typeof step === 'object' && !Object.prototype.hasOwnProperty.call(step, ADD_EVENT_LISTENER)) {
|
|
83
|
+
step = Object.getPrototypeOf(step);
|
|
84
|
+
}
|
|
85
|
+
if (step) cb(step, ...rest);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Returns an event emitter scoped specifically for the `events` context. This scoping is a remnant from when all the
|
|
90
|
+
* features shared the same group in the event, to isolate events between features. It will likely be revisited.
|
|
91
|
+
* @param {Object} sharedEE - Optional event emitter on which to base the scoped emitter.
|
|
92
|
+
* Uses `ee` on the global scope if undefined).
|
|
93
|
+
* @returns {Object} Scoped event emitter with a debug ID of 'events'.
|
|
94
|
+
*/
|
|
95
|
+
export function scopedEE(sharedEE) {
|
|
96
|
+
return (sharedEE || baseEE).get('events');
|
|
97
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2020 New Relic Corporation. All rights reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* @file Wraps `fetch` and related methods for instrumentation.
|
|
7
|
+
* This module is used by: ajax, spa.
|
|
8
|
+
*/
|
|
9
|
+
import { ee as baseEE } from '../event-emitter/contextual-ee';
|
|
10
|
+
import slice from 'lodash._slice';
|
|
11
|
+
import { globalScope } from '../util/global-scope';
|
|
12
|
+
import { flag, unwrapFunction } from './wrap-function';
|
|
13
|
+
var prefix = 'fetch-';
|
|
14
|
+
var bodyPrefix = prefix + 'body-';
|
|
15
|
+
var bodyMethods = ['arrayBuffer', 'blob', 'json', 'text', 'formData'];
|
|
16
|
+
var Req = globalScope.Request;
|
|
17
|
+
var Res = globalScope.Response;
|
|
18
|
+
var proto = 'prototype';
|
|
19
|
+
var ctxId = 'nr@context';
|
|
20
|
+
const wrapped = {};
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Wraps the `fetch` method of the global scope for instrumentation. Also wraps the prototypes of the async methods
|
|
24
|
+
* that parse Request and Response bodies to generate start and end events for each, in context of a new event
|
|
25
|
+
* emitter scoped only to fetch and related methods.
|
|
26
|
+
* @param {Object} sharedEE - The shared event emitter on which a new scoped
|
|
27
|
+
* event emitter will be based.
|
|
28
|
+
* @returns {Object} Scoped event emitter with a debug ID of `fetch`.
|
|
29
|
+
*/
|
|
30
|
+
export function wrapFetch(sharedEE) {
|
|
31
|
+
const ee = scopedEE(sharedEE);
|
|
32
|
+
if (!(Req && Res && globalScope.fetch)) {
|
|
33
|
+
return ee;
|
|
34
|
+
}
|
|
35
|
+
if (wrapped[ee.debugId]++)
|
|
36
|
+
// Notice if our wrapping never ran yet, the falsey NaN will not early return; but if it has,
|
|
37
|
+
{
|
|
38
|
+
return ee;
|
|
39
|
+
} // then we increment the count to track # of feats using this at runtime.
|
|
40
|
+
wrapped[ee.debugId] = 1;
|
|
41
|
+
bodyMethods.forEach(method => {
|
|
42
|
+
wrapPromiseMethod(Req[proto], method, bodyPrefix);
|
|
43
|
+
wrapPromiseMethod(Res[proto], method, bodyPrefix);
|
|
44
|
+
});
|
|
45
|
+
wrapPromiseMethod(globalScope, 'fetch', prefix);
|
|
46
|
+
ee.on(prefix + 'end', function (err, res) {
|
|
47
|
+
var ctx = this;
|
|
48
|
+
if (res) {
|
|
49
|
+
var size = res.headers.get('content-length');
|
|
50
|
+
if (size !== null) {
|
|
51
|
+
ctx.rxSize = size;
|
|
52
|
+
}
|
|
53
|
+
ee.emit(prefix + 'done', [null, res], ctx);
|
|
54
|
+
} else {
|
|
55
|
+
ee.emit(prefix + 'done', [err], ctx);
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Wraps a Promise-returning function (referenced by `target[name]`) to emit custom events before and after
|
|
61
|
+
* execution, each decorated with metadata (arguments, payloads, errors). Used to wrap the async body
|
|
62
|
+
* parsing methods of Request and Response (e.g. `json`, `text`, `formData`).
|
|
63
|
+
* @param {Object} target - The object having the method to be wrapped.
|
|
64
|
+
* @param {string} name - The name of the method to wrap.
|
|
65
|
+
* @param {string} prefix - Used to decorate event names with context.
|
|
66
|
+
*/
|
|
67
|
+
function wrapPromiseMethod(target, name, prefix) {
|
|
68
|
+
var fn = target[name];
|
|
69
|
+
if (typeof fn === 'function') {
|
|
70
|
+
target[name] = function () {
|
|
71
|
+
var args = slice(arguments);
|
|
72
|
+
var ctx = {};
|
|
73
|
+
// we are wrapping args in an array so we can preserve the reference
|
|
74
|
+
ee.emit(prefix + 'before-start', [args], ctx);
|
|
75
|
+
var dtPayload;
|
|
76
|
+
if (ctx[ctxId] && ctx[ctxId].dt) dtPayload = ctx[ctxId].dt;
|
|
77
|
+
var origPromiseFromFetch = fn.apply(this, args);
|
|
78
|
+
ee.emit(prefix + 'start', [args, dtPayload], origPromiseFromFetch);
|
|
79
|
+
|
|
80
|
+
// Note we need to cast the returned (orig) Promise from native APIs into the current global Promise, which may or may not be our WrappedPromise.
|
|
81
|
+
return origPromiseFromFetch.then(function (val) {
|
|
82
|
+
ee.emit(prefix + 'end', [null, val], origPromiseFromFetch);
|
|
83
|
+
return val;
|
|
84
|
+
}, function (err) {
|
|
85
|
+
ee.emit(prefix + 'end', [err], origPromiseFromFetch);
|
|
86
|
+
throw err;
|
|
87
|
+
});
|
|
88
|
+
};
|
|
89
|
+
target[name][flag] = fn; // track original similar to in wrap-function.js, so that they can be unwrapped with ease
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return ee;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Returns an event emitter scoped specifically for the `fetch` context. This scoping is a remnant from when all the
|
|
98
|
+
* features shared the same group in the event, to isolate events between features. It will likely be revisited.
|
|
99
|
+
* @param {Object} sharedEE - Optional event emitter on which to base the scoped emitter.
|
|
100
|
+
* Uses `ee` on the global scope if undefined).
|
|
101
|
+
* @returns {Object} Scoped event emitter with a debug ID of 'fetch'.
|
|
102
|
+
*/
|
|
103
|
+
export function scopedEE(sharedEE) {
|
|
104
|
+
return (sharedEE || baseEE).get('fetch');
|
|
105
|
+
}
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2020 New Relic Corporation. All rights reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* @file Provides helper functions for wrapping functions in various scenarios.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { ee } from '../event-emitter/contextual-ee';
|
|
10
|
+
import slice from 'lodash._slice';
|
|
11
|
+
export const flag = 'nr@original';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* A convenience alias of `hasOwnProperty`.
|
|
15
|
+
* @type {function}
|
|
16
|
+
*/
|
|
17
|
+
var has = Object.prototype.hasOwnProperty;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* For tracking whether an event is already being emitted inside the wrapper.
|
|
21
|
+
* @type {boolean}
|
|
22
|
+
*/
|
|
23
|
+
var inWrapper = false;
|
|
24
|
+
|
|
25
|
+
// eslint-disable-next-line
|
|
26
|
+
export default createWrapperWithEmitter;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Wraps a function in order to emit events on start, end, and error.
|
|
30
|
+
* @param {Object} [emitter] - The desired emitter for events emitted by the wrapper. Defaults to the global emitter.
|
|
31
|
+
* @param {boolean} always - If `true`, emit events even if already emitting an event.
|
|
32
|
+
* @returns {function} The wrapped function.
|
|
33
|
+
*/
|
|
34
|
+
export function createWrapperWithEmitter(emitter, always) {
|
|
35
|
+
emitter || (emitter = ee);
|
|
36
|
+
wrapFn.inPlace = inPlace;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* A flag used to determine if a native function has already been wrapped.
|
|
40
|
+
* As a property on a wrapped function, contains the original function.
|
|
41
|
+
* @type {string}
|
|
42
|
+
*/
|
|
43
|
+
wrapFn.flag = flag;
|
|
44
|
+
return wrapFn;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Wraps a function with event emitting functionality.
|
|
48
|
+
* @param {function} fn - The function to wrap.
|
|
49
|
+
* @param {string} prefix - A prefix for the names of emitted events.
|
|
50
|
+
* @param {function|object} getContext - The function or object that will serve as the 'this' context for handlers of events emitted by this wrapper.
|
|
51
|
+
* @param {string} methodName - The name of the method being wrapped.
|
|
52
|
+
* @param {boolean} bubble - If true, emitted events should also bubble up to the old emitter upon which the `emitter` in the current scope was based (if it defines one).
|
|
53
|
+
* @returns {function} The wrapped function.
|
|
54
|
+
*/
|
|
55
|
+
function wrapFn(fn, prefix, getContext, methodName, bubble) {
|
|
56
|
+
// Unless fn is both wrappable and unwrapped, return it unchanged.
|
|
57
|
+
if (notWrappable(fn)) return fn;
|
|
58
|
+
if (!prefix) prefix = '';
|
|
59
|
+
nrWrapper[flag] = fn;
|
|
60
|
+
copy(fn, nrWrapper, emitter);
|
|
61
|
+
return nrWrapper;
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* A wrapper function that emits events before and after calling the wrapped function.
|
|
65
|
+
* Any arguments will be passed along to the original function.
|
|
66
|
+
* @returns {any} The return value of the wrapped function.
|
|
67
|
+
*/
|
|
68
|
+
function nrWrapper() {
|
|
69
|
+
var args;
|
|
70
|
+
var originalThis;
|
|
71
|
+
var ctx;
|
|
72
|
+
var result;
|
|
73
|
+
try {
|
|
74
|
+
originalThis = this;
|
|
75
|
+
args = slice(arguments);
|
|
76
|
+
if (typeof getContext === 'function') {
|
|
77
|
+
ctx = getContext(args, originalThis);
|
|
78
|
+
} else {
|
|
79
|
+
ctx = getContext || {};
|
|
80
|
+
}
|
|
81
|
+
} catch (e) {
|
|
82
|
+
report([e, '', [args, originalThis, methodName], ctx], emitter);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Warning: start events may mutate args!
|
|
86
|
+
safeEmit(prefix + 'start', [args, originalThis, methodName], ctx, bubble);
|
|
87
|
+
try {
|
|
88
|
+
result = fn.apply(originalThis, args);
|
|
89
|
+
return result;
|
|
90
|
+
} catch (err) {
|
|
91
|
+
safeEmit(prefix + 'err', [args, originalThis, err], ctx, bubble);
|
|
92
|
+
|
|
93
|
+
// rethrow error so we don't effect execution by observing.
|
|
94
|
+
throw err;
|
|
95
|
+
} finally {
|
|
96
|
+
// happens no matter what.
|
|
97
|
+
safeEmit(prefix + 'end', [args, originalThis, result], ctx, bubble);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Creates wrapper functions around each of an array of methods on a specified object.
|
|
104
|
+
* @param {Object} obj - The object to which the specified methods belong.
|
|
105
|
+
* @param {string[]} methods - An array of method names to be wrapped.
|
|
106
|
+
* @param {string} [prefix=''] - A prefix to add to the names of emitted events.
|
|
107
|
+
* @param {function|object} [getContext] - The function or object that will serve as the 'this' context for handlers
|
|
108
|
+
* of events emitted by this wrapper.
|
|
109
|
+
* @param {boolean} [bubble=false] - If `true`, emitted events should also bubble up to the old emitter upon which
|
|
110
|
+
* the `emitter` in the current scope was based (if it defines one).
|
|
111
|
+
*/
|
|
112
|
+
function inPlace(obj, methods, prefix, getContext, bubble) {
|
|
113
|
+
if (!prefix) prefix = '';
|
|
114
|
+
// If prefix starts with '-' set this boolean to add the method name to
|
|
115
|
+
// the prefix before passing each one to wrap.
|
|
116
|
+
var prependMethodPrefix = prefix.charAt(0) === '-';
|
|
117
|
+
var fn;
|
|
118
|
+
var method;
|
|
119
|
+
var i;
|
|
120
|
+
for (i = 0; i < methods.length; i++) {
|
|
121
|
+
method = methods[i];
|
|
122
|
+
fn = obj[method];
|
|
123
|
+
|
|
124
|
+
// Unless fn is both wrappable and unwrapped bail,
|
|
125
|
+
// so we don't add extra properties with undefined values.
|
|
126
|
+
if (notWrappable(fn)) continue;
|
|
127
|
+
obj[method] = wrapFn(fn, prependMethodPrefix ? method + prefix : prefix, getContext, method, bubble);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Emits an event using the `emit` method of the `emitter` object in the executing scope, but only if an event is not
|
|
133
|
+
* already being emitted (except when the executing scope defines `always` as `true`).
|
|
134
|
+
* @param {string} evt - The name of the event to be emitted.
|
|
135
|
+
* @param {array} arr - An array of arguments to pass with the event.
|
|
136
|
+
* @param {Object} store - The function or object that will serve as the 'this'
|
|
137
|
+
* context when applying handler functions for this event.
|
|
138
|
+
* @param {boolean} bubble - If `true`, emitted events should also
|
|
139
|
+
* bubble up to the old emitter upon which the `emitter` in the
|
|
140
|
+
* executing scope was based (if it defines one).
|
|
141
|
+
*/
|
|
142
|
+
function safeEmit(evt, arr, store, bubble) {
|
|
143
|
+
if (inWrapper && !always) return;
|
|
144
|
+
var prev = inWrapper;
|
|
145
|
+
inWrapper = true;
|
|
146
|
+
try {
|
|
147
|
+
emitter.emit(evt, arr, store, always, bubble);
|
|
148
|
+
} catch (e) {
|
|
149
|
+
report([e, evt, arr, store], emitter);
|
|
150
|
+
}
|
|
151
|
+
inWrapper = prev;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Emits an "internal-error" event. Used to report errors encountered when emitting events using `safeEmit`.
|
|
157
|
+
* @param {array} args - Arguments to be passed to the "internal-error" event.
|
|
158
|
+
* @param {Object} [emitter] - The (optional) desired event emitter. Defaults to the global event emitter.
|
|
159
|
+
*/
|
|
160
|
+
function report(args, emitter) {
|
|
161
|
+
emitter || (emitter = ee);
|
|
162
|
+
try {
|
|
163
|
+
emitter.emit('internal-error', args);
|
|
164
|
+
} catch (err) {
|
|
165
|
+
// do nothing
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Copies properties from one object to another. Used for creating a wrapper function from an original function and for
|
|
171
|
+
* copying an original function to a property of a wrapper function named by `flag` in the executing context.
|
|
172
|
+
* @param {Object} from - The source function or object.
|
|
173
|
+
* @param {Object} to - The destination function or object.
|
|
174
|
+
* @param {Object} [emitter] - The (optional) desired event emitter if errors are encountered while copying.
|
|
175
|
+
* Defaults to the global event emitter.
|
|
176
|
+
* @returns {object} - The destination founction or object with copied properties.
|
|
177
|
+
*/
|
|
178
|
+
function copy(from, to, emitter) {
|
|
179
|
+
if (Object.defineProperty && Object.keys) {
|
|
180
|
+
// Create accessors that proxy to actual function
|
|
181
|
+
try {
|
|
182
|
+
var keys = Object.keys(from);
|
|
183
|
+
// eslint-disable-next-line
|
|
184
|
+
keys.forEach(function (key) {
|
|
185
|
+
Object.defineProperty(to, key, {
|
|
186
|
+
get: function () {
|
|
187
|
+
return from[key];
|
|
188
|
+
},
|
|
189
|
+
// eslint-disable-next-line
|
|
190
|
+
set: function (val) {
|
|
191
|
+
from[key] = val;
|
|
192
|
+
return val;
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
});
|
|
196
|
+
return to;
|
|
197
|
+
} catch (e) {
|
|
198
|
+
report([e], emitter);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
// fall back to copying properties
|
|
202
|
+
for (var i in from) {
|
|
203
|
+
if (has.call(from, i)) {
|
|
204
|
+
to[i] = from[i];
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
return to;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Determines whether a function is eligible to be wrapped in part based on whether it has already been wrapped.
|
|
212
|
+
* @param {function} fn - The function in question.
|
|
213
|
+
* @returns {boolean} Whether the passed function is ineligible to be wrapped.
|
|
214
|
+
*/
|
|
215
|
+
function notWrappable(fn) {
|
|
216
|
+
return !(fn && fn instanceof Function && fn.apply && !fn[flag]);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Creates a wrapped version of a function using a specified wrapper function. The new wrapped function references the
|
|
221
|
+
* original function. Also copies the properties of the original function to the wrapped function.
|
|
222
|
+
* @param {function} fn - A function to be wrapped.
|
|
223
|
+
* @param {function} wrapper - A higher order function that returns a new function, which executes the function passed
|
|
224
|
+
* to the higher order function as an argument.
|
|
225
|
+
* @returns {function} A wrapped function with an internal reference to the original function.
|
|
226
|
+
*/
|
|
227
|
+
export function wrapFunction(fn, wrapper) {
|
|
228
|
+
var wrapped = wrapper(fn);
|
|
229
|
+
wrapped[flag] = fn;
|
|
230
|
+
copy(fn, wrapped, ee);
|
|
231
|
+
return wrapped;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Replaces a function with a wrapped version of itself. To preserve object references, rather than taking the function
|
|
236
|
+
* itself as an argument, takes the object on which the particular named function is a property.
|
|
237
|
+
* @param {Object} obj - The object on which the named function is a property.
|
|
238
|
+
* @param {string} fnName - The name of the function to be wrapped.
|
|
239
|
+
* @param {function} wrapper - A higher order function that returns a new function, which executes the function passed
|
|
240
|
+
* to the higher order function as an argument.
|
|
241
|
+
*/
|
|
242
|
+
export function wrapInPlace(obj, fnName, wrapper) {
|
|
243
|
+
var fn = obj[fnName];
|
|
244
|
+
obj[fnName] = wrapFunction(fn, wrapper);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* If a function property on an object (e.g. window) was previously wrapped (by this module), removes the wrapper.
|
|
249
|
+
* @param {Object} obj - The object on which the named function is a property.
|
|
250
|
+
* @param {string} fnName - The name of the function to be unwrapped.
|
|
251
|
+
*/
|
|
252
|
+
export function unwrapFunction(obj, fnName) {
|
|
253
|
+
if (obj?.[fnName]?.[flag]) {
|
|
254
|
+
// previous state of the function property is stored under our wrapper's "flag"; we don't wrap properties that *were* undefined to begin with
|
|
255
|
+
obj[fnName] = obj[fnName][flag];
|
|
256
|
+
}
|
|
257
|
+
}
|