@newrelic/browser-agent 1.232.1 → 1.233.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/dist/cjs/cdn/polyfills.js +5 -2
- package/dist/cjs/common/config/state/configurable.js +15 -26
- package/dist/cjs/common/config/state/info.js +1 -1
- package/dist/cjs/common/config/state/init.js +101 -56
- package/dist/cjs/common/config/state/loader-config.js +1 -1
- package/dist/cjs/common/config/state/runtime.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/drain/drain.js +1 -1
- package/dist/cjs/common/harvest/harvest-scheduler.js +30 -10
- package/dist/cjs/common/harvest/harvest.js +119 -55
- package/dist/cjs/common/session/session-entity.js +35 -22
- package/dist/cjs/common/session/session-entity.test.js +73 -49
- package/dist/cjs/common/timer/interaction-timer.js +9 -12
- package/dist/cjs/common/url/protocol.test.js +0 -1
- package/dist/cjs/common/util/feature-flags.js +2 -1
- package/dist/cjs/common/util/submit-data.js +57 -18
- package/dist/cjs/common/wrap/wrap-fetch.js +1 -1
- package/dist/cjs/common/wrap/wrap-function.js +1 -1
- package/dist/cjs/common/wrap/wrap-promise.js +1 -1
- package/dist/cjs/features/ajax/aggregate/index.js +2 -2
- package/dist/cjs/features/jserrors/aggregate/index.js +7 -5
- package/dist/cjs/features/metrics/aggregate/framework-detection.js +67 -0
- package/dist/cjs/features/metrics/aggregate/framework-detection.test.js +137 -0
- package/dist/cjs/features/metrics/aggregate/index.js +7 -3
- package/dist/cjs/features/metrics/aggregate/polyfill-detection.es5.js +14 -0
- package/dist/cjs/features/metrics/aggregate/polyfill-detection.es5.test.js +17 -0
- package/dist/cjs/features/metrics/aggregate/polyfill-detection.js +53 -0
- package/dist/cjs/features/metrics/aggregate/polyfill-detection.test.js +165 -0
- package/dist/cjs/features/page_action/aggregate/index.js +2 -2
- package/dist/cjs/features/page_view_event/aggregate/index.js +6 -3
- package/dist/cjs/features/page_view_timing/aggregate/index.js +2 -2
- package/dist/cjs/features/session_replay/aggregate/index.js +333 -0
- package/dist/cjs/features/session_replay/constants.js +9 -0
- package/dist/cjs/features/session_replay/index.js +12 -0
- package/dist/cjs/features/session_replay/instrument/index.js +29 -0
- package/dist/cjs/features/session_trace/aggregate/index.js +163 -162
- package/dist/cjs/features/session_trace/constants.js +2 -9
- package/dist/cjs/features/session_trace/instrument/index.js +24 -66
- package/dist/cjs/features/spa/aggregate/index.js +2 -2
- package/dist/cjs/features/utils/agent-session.js +1 -2
- package/dist/cjs/features/utils/aggregate-base.js +64 -0
- package/dist/cjs/features/utils/feature-base.js +0 -31
- package/dist/cjs/features/utils/handler-cache.js +3 -4
- package/dist/cjs/features/utils/instrument-base.js +42 -10
- package/dist/cjs/features/utils/{lazy-loader.js → lazy-feature-loader.js} +4 -2
- package/dist/cjs/loaders/agent.js +1 -1
- package/dist/cjs/loaders/api/apiAsync.js +3 -1
- package/dist/cjs/loaders/configure/configure.js +3 -3
- package/dist/cjs/loaders/features/featureDependencies.js +0 -12
- package/dist/cjs/loaders/features/features.js +3 -1
- package/dist/cjs/loaders/micro-agent.js +6 -6
- package/dist/esm/cdn/polyfills.js +5 -2
- package/dist/esm/common/config/state/configurable.js +14 -24
- package/dist/esm/common/config/state/info.js +2 -2
- package/dist/esm/common/config/state/init.js +102 -57
- package/dist/esm/common/config/state/loader-config.js +2 -2
- package/dist/esm/common/config/state/runtime.js +2 -4
- package/dist/esm/common/constants/env.cdn.js +1 -1
- package/dist/esm/common/constants/env.npm.js +1 -1
- package/dist/esm/common/drain/drain.js +1 -1
- package/dist/esm/common/harvest/harvest-scheduler.js +30 -10
- package/dist/esm/common/harvest/harvest.js +121 -56
- package/dist/esm/common/session/session-entity.js +35 -22
- package/dist/esm/common/session/session-entity.test.js +73 -49
- package/dist/esm/common/timer/interaction-timer.js +9 -12
- package/dist/esm/common/url/protocol.test.js +0 -1
- package/dist/esm/common/util/feature-flags.js +2 -1
- package/dist/esm/common/util/submit-data.js +57 -18
- package/dist/esm/common/wrap/wrap-fetch.js +1 -1
- package/dist/esm/common/wrap/wrap-function.js +1 -1
- package/dist/esm/common/wrap/wrap-promise.js +1 -1
- package/dist/esm/features/ajax/aggregate/index.js +2 -2
- package/dist/esm/features/jserrors/aggregate/index.js +7 -5
- package/dist/esm/features/metrics/aggregate/framework-detection.js +61 -0
- package/dist/esm/features/metrics/aggregate/framework-detection.test.js +133 -0
- package/dist/esm/features/metrics/aggregate/index.js +7 -3
- package/dist/esm/features/metrics/aggregate/polyfill-detection.es5.js +8 -0
- package/dist/esm/features/metrics/aggregate/polyfill-detection.es5.test.js +15 -0
- package/dist/esm/features/metrics/aggregate/polyfill-detection.js +47 -0
- package/dist/esm/features/metrics/aggregate/polyfill-detection.test.js +163 -0
- package/dist/esm/features/page_action/aggregate/index.js +2 -2
- package/dist/esm/features/page_view_event/aggregate/index.js +6 -3
- package/dist/esm/features/page_view_timing/aggregate/index.js +2 -2
- package/dist/esm/features/session_replay/aggregate/index.js +327 -0
- package/dist/esm/features/session_replay/constants.js +2 -0
- package/dist/esm/features/session_replay/index.js +12 -0
- package/dist/esm/features/session_replay/instrument/index.js +21 -0
- package/dist/esm/features/session_trace/aggregate/index.js +163 -162
- package/dist/esm/features/session_trace/constants.js +1 -5
- package/dist/esm/features/session_trace/instrument/index.js +24 -66
- package/dist/esm/features/spa/aggregate/index.js +2 -2
- package/dist/esm/features/utils/agent-session.js +1 -2
- package/dist/esm/features/utils/aggregate-base.js +57 -0
- package/dist/esm/features/utils/feature-base.js +1 -32
- package/dist/esm/features/utils/handler-cache.js +3 -4
- package/dist/esm/features/utils/instrument-base.js +42 -10
- package/dist/esm/features/utils/{lazy-loader.js → lazy-feature-loader.js} +3 -1
- package/dist/esm/loaders/agent.js +1 -1
- package/dist/esm/loaders/api/apiAsync.js +3 -1
- package/dist/esm/loaders/configure/configure.js +3 -3
- package/dist/esm/loaders/features/featureDependencies.js +0 -11
- package/dist/esm/loaders/features/features.js +3 -1
- package/dist/esm/loaders/micro-agent.js +6 -6
- package/dist/types/common/config/state/configurable.d.ts +1 -3
- package/dist/types/common/config/state/configurable.d.ts.map +1 -1
- package/dist/types/common/config/state/init.d.ts.map +1 -1
- package/dist/types/common/config/state/runtime.d.ts.map +1 -1
- package/dist/types/common/harvest/harvest-scheduler.d.ts.map +1 -1
- package/dist/types/common/harvest/harvest.d.ts +37 -34
- package/dist/types/common/harvest/harvest.d.ts.map +1 -1
- package/dist/types/common/session/session-entity.d.ts +6 -3
- package/dist/types/common/session/session-entity.d.ts.map +1 -1
- package/dist/types/common/timer/interaction-timer.d.ts +2 -1
- package/dist/types/common/timer/interaction-timer.d.ts.map +1 -1
- package/dist/types/common/util/feature-flags.d.ts.map +1 -1
- package/dist/types/common/util/submit-data.d.ts +40 -14
- package/dist/types/common/util/submit-data.d.ts.map +1 -1
- package/dist/types/features/ajax/aggregate/index.d.ts +2 -2
- package/dist/types/features/ajax/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/jserrors/aggregate/index.d.ts +2 -2
- package/dist/types/features/jserrors/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/metrics/aggregate/framework-detection.d.ts.map +1 -0
- package/dist/types/features/metrics/aggregate/index.d.ts +2 -2
- package/dist/types/features/metrics/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/metrics/aggregate/polyfill-detection.d.ts +6 -0
- package/dist/types/features/metrics/aggregate/polyfill-detection.d.ts.map +1 -0
- package/dist/types/features/metrics/aggregate/polyfill-detection.es5.d.ts +7 -0
- package/dist/types/features/metrics/aggregate/polyfill-detection.es5.d.ts.map +1 -0
- package/dist/types/features/page_action/aggregate/index.d.ts +2 -2
- package/dist/types/features/page_action/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/page_view_event/aggregate/index.d.ts +2 -2
- package/dist/types/features/page_view_event/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/page_view_timing/aggregate/index.d.ts +2 -2
- package/dist/types/features/page_view_timing/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/session_replay/aggregate/index.d.ts +96 -0
- package/dist/types/features/session_replay/aggregate/index.d.ts.map +1 -0
- package/dist/types/features/session_replay/constants.d.ts +2 -0
- package/dist/types/features/session_replay/constants.d.ts.map +1 -0
- package/dist/types/features/session_replay/index.d.ts +2 -0
- package/dist/types/features/session_replay/index.d.ts.map +1 -0
- package/dist/types/features/session_replay/instrument/index.d.ts +6 -0
- package/dist/types/features/session_replay/instrument/index.d.ts.map +1 -0
- package/dist/types/features/session_trace/aggregate/index.d.ts +8 -57
- package/dist/types/features/session_trace/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/session_trace/constants.d.ts +0 -3
- package/dist/types/features/session_trace/constants.d.ts.map +1 -1
- package/dist/types/features/session_trace/instrument/index.d.ts +1 -3
- package/dist/types/features/session_trace/instrument/index.d.ts.map +1 -1
- package/dist/types/features/spa/aggregate/index.d.ts +2 -2
- package/dist/types/features/spa/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/utils/agent-session.d.ts.map +1 -1
- package/dist/types/features/utils/aggregate-base.d.ts +11 -0
- package/dist/types/features/utils/aggregate-base.d.ts.map +1 -0
- package/dist/types/features/utils/feature-base.d.ts +0 -5
- package/dist/types/features/utils/feature-base.d.ts.map +1 -1
- package/dist/types/features/utils/handler-cache.d.ts.map +1 -1
- package/dist/types/features/utils/instrument-base.d.ts +3 -1
- package/dist/types/features/utils/instrument-base.d.ts.map +1 -1
- package/dist/types/features/utils/{lazy-loader.d.ts → lazy-feature-loader.d.ts} +2 -2
- package/dist/types/features/utils/lazy-feature-loader.d.ts.map +1 -0
- package/dist/types/loaders/configure/configure.d.ts.map +1 -1
- package/dist/types/loaders/features/featureDependencies.d.ts +0 -1
- package/dist/types/loaders/features/featureDependencies.d.ts.map +1 -1
- package/dist/types/loaders/features/features.d.ts +1 -0
- package/dist/types/loaders/features/features.d.ts.map +1 -1
- package/package.json +28 -19
- package/src/cdn/polyfills.js +4 -1
- package/src/common/config/state/configurable.js +18 -24
- package/src/common/config/state/info.js +2 -2
- package/src/common/config/state/init.js +62 -28
- package/src/common/config/state/loader-config.js +2 -2
- package/src/common/config/state/runtime.js +2 -4
- package/src/common/drain/drain.js +1 -1
- package/src/common/harvest/harvest-scheduler.js +35 -10
- package/src/common/harvest/harvest.js +73 -50
- package/src/common/session/session-entity.js +34 -23
- package/src/common/session/session-entity.test.js +57 -51
- package/src/common/timer/interaction-timer.js +9 -12
- package/src/common/url/protocol.test.js +0 -1
- package/src/common/util/feature-flags.js +2 -2
- package/src/common/util/submit-data.js +28 -17
- package/src/common/wrap/wrap-fetch.js +1 -1
- package/src/common/wrap/wrap-function.js +1 -1
- package/src/common/wrap/wrap-promise.js +1 -1
- package/src/features/ajax/aggregate/index.js +2 -2
- package/src/features/jserrors/aggregate/index.js +7 -5
- package/src/features/metrics/aggregate/framework-detection.js +73 -0
- package/src/features/metrics/aggregate/framework-detection.test.js +201 -0
- package/src/features/metrics/aggregate/index.js +8 -3
- package/src/features/metrics/aggregate/polyfill-detection.es5.js +9 -0
- package/src/features/metrics/aggregate/polyfill-detection.es5.test.js +16 -0
- package/src/features/metrics/aggregate/polyfill-detection.js +48 -0
- package/src/features/metrics/aggregate/polyfill-detection.test.js +163 -0
- package/src/features/page_action/aggregate/index.js +2 -2
- package/src/features/page_view_event/aggregate/index.js +5 -5
- package/src/features/page_view_timing/aggregate/index.js +2 -2
- package/src/features/session_replay/aggregate/index.js +314 -0
- package/src/features/session_replay/constants.js +3 -0
- package/src/features/session_replay/index.js +12 -0
- package/src/features/session_replay/instrument/index.js +22 -0
- package/src/features/session_trace/aggregate/index.js +148 -187
- package/src/features/session_trace/constants.js +0 -4
- package/src/features/session_trace/instrument/index.js +17 -69
- package/src/features/spa/aggregate/index.js +2 -2
- package/src/features/utils/agent-session.js +1 -2
- package/src/features/utils/aggregate-base.js +51 -0
- package/src/features/utils/feature-base.js +1 -31
- package/src/features/utils/handler-cache.js +3 -4
- package/src/features/utils/instrument-base.js +40 -8
- package/src/features/utils/{lazy-loader.js → lazy-feature-loader.js} +3 -1
- package/src/loaders/agent.js +1 -1
- package/src/loaders/api/apiAsync.js +1 -1
- package/src/loaders/configure/configure.js +4 -3
- package/src/loaders/features/featureDependencies.js +0 -12
- package/src/loaders/features/features.js +3 -1
- package/src/loaders/micro-agent.js +4 -4
- package/dist/cjs/common/metrics/framework-detection.js +0 -72
- package/dist/cjs/common/util/user-agent.js +0 -57
- package/dist/cjs/common/window/supports-performance-observer.js +0 -15
- package/dist/esm/common/metrics/framework-detection.js +0 -66
- package/dist/esm/common/util/user-agent.js +0 -48
- package/dist/esm/common/window/supports-performance-observer.js +0 -9
- package/dist/types/common/metrics/framework-detection.d.ts.map +0 -1
- package/dist/types/common/util/user-agent.d.ts +0 -5
- package/dist/types/common/util/user-agent.d.ts.map +0 -1
- package/dist/types/common/window/supports-performance-observer.d.ts +0 -2
- package/dist/types/common/window/supports-performance-observer.d.ts.map +0 -1
- package/dist/types/features/utils/lazy-loader.d.ts.map +0 -1
- package/src/common/metrics/framework-detection.js +0 -71
- package/src/common/util/user-agent.js +0 -56
- package/src/common/window/supports-performance-observer.js +0 -10
- /package/dist/types/{common/metrics → features/metrics/aggregate}/framework-detection.d.ts +0 -0
|
@@ -8,19 +8,27 @@ import { DEFAULT_EXPIRES_MS, DEFAULT_INACTIVE_MS, PREFIX } from './constants';
|
|
|
8
8
|
import { LocalMemory } from '../storage/local-memory';
|
|
9
9
|
import { InteractionTimer } from '../timer/interaction-timer';
|
|
10
10
|
import { wrapEvents } from '../wrap';
|
|
11
|
-
import {
|
|
11
|
+
import { getModeledObject } from '../config/state/configurable';
|
|
12
12
|
import { handle } from '../event-emitter/handle';
|
|
13
13
|
import { SUPPORTABILITY_METRIC_CHANNEL } from '../../features/metrics/constants';
|
|
14
14
|
import { FEATURE_NAMES } from '../../loaders/features/features';
|
|
15
|
+
|
|
16
|
+
// this is what can be stored in local storage (not enforced but probably should be)
|
|
17
|
+
// these values should sync between local storage and the parent class props
|
|
15
18
|
const model = {
|
|
16
19
|
value: '',
|
|
17
20
|
inactiveAt: 0,
|
|
18
21
|
expiresAt: 0,
|
|
19
22
|
updatedAt: Date.now(),
|
|
20
|
-
|
|
23
|
+
sessionReplay: 0,
|
|
21
24
|
sessionTraceActive: false,
|
|
22
25
|
custom: {}
|
|
23
26
|
};
|
|
27
|
+
export const SESSION_EVENTS = {
|
|
28
|
+
PAUSE: 'session-pause',
|
|
29
|
+
RESET: 'session-reset',
|
|
30
|
+
RESUME: 'session-resume'
|
|
31
|
+
};
|
|
24
32
|
export class SessionEntity {
|
|
25
33
|
/**
|
|
26
34
|
* Create a self-managing Session Entity. This entity is scoped to the agent identifier which triggered it, allowing for multiple simultaneous session objects to exist.
|
|
@@ -42,13 +50,13 @@ export class SessionEntity {
|
|
|
42
50
|
} = _ref;
|
|
43
51
|
if (!agentIdentifier || !key) throw new Error('Missing Required Fields');
|
|
44
52
|
if (!isBrowserScope) this.storage = new LocalMemory();else this.storage = storageAPI;
|
|
53
|
+
this.state = {};
|
|
45
54
|
this.sync(model);
|
|
46
55
|
this.agentIdentifier = agentIdentifier;
|
|
47
|
-
|
|
48
56
|
// key is intended to act as the k=v pair
|
|
49
57
|
this.key = key;
|
|
50
58
|
// value is intended to act as the primary value of the k=v pair
|
|
51
|
-
this.value = value;
|
|
59
|
+
this.state.value = value;
|
|
52
60
|
this.expiresMs = expiresMs;
|
|
53
61
|
this.inactiveMs = inactiveMs;
|
|
54
62
|
this.ee = ee.get(agentIdentifier);
|
|
@@ -65,7 +73,7 @@ export class SessionEntity {
|
|
|
65
73
|
// the set-up of the timer used to expire the session "naturally" at a certain time
|
|
66
74
|
// this gets ignored if the value is falsy, allowing for session entities that do not expire
|
|
67
75
|
if (expiresMs) {
|
|
68
|
-
this.expiresAt = initialRead?.expiresAt || this.getFutureTimestamp(expiresMs);
|
|
76
|
+
this.state.expiresAt = initialRead?.expiresAt || this.getFutureTimestamp(expiresMs);
|
|
69
77
|
this.expiresTimer = new Timer({
|
|
70
78
|
// When the inactive timer ends, collect a SM and reset the session
|
|
71
79
|
onEnd: () => {
|
|
@@ -73,16 +81,16 @@ export class SessionEntity {
|
|
|
73
81
|
this.collectSM('duration', this);
|
|
74
82
|
this.reset();
|
|
75
83
|
}
|
|
76
|
-
}, this.expiresAt - Date.now());
|
|
84
|
+
}, this.state.expiresAt - Date.now());
|
|
77
85
|
} else {
|
|
78
|
-
this.expiresAt = Infinity;
|
|
86
|
+
this.state.expiresAt = Infinity;
|
|
79
87
|
}
|
|
80
88
|
|
|
81
89
|
// the set-up of the timer used to expire the session due to "inactivity" at a certain time
|
|
82
90
|
// this gets ignored if the value is falsy, allowing for session entities that do not expire
|
|
83
91
|
// this gets "refreshed" when "activity" is observed
|
|
84
92
|
if (inactiveMs) {
|
|
85
|
-
this.inactiveAt = initialRead?.inactiveAt || this.getFutureTimestamp(inactiveMs);
|
|
93
|
+
this.state.inactiveAt = initialRead?.inactiveAt || this.getFutureTimestamp(inactiveMs);
|
|
86
94
|
this.inactiveTimer = new InteractionTimer({
|
|
87
95
|
// When the inactive timer ends, collect a SM and reset the session
|
|
88
96
|
onEnd: () => {
|
|
@@ -92,21 +100,27 @@ export class SessionEntity {
|
|
|
92
100
|
},
|
|
93
101
|
// When the inactive timer refreshes, it will update the storage values with an update timestamp
|
|
94
102
|
onRefresh: this.refresh.bind(this),
|
|
103
|
+
onResume: () => {
|
|
104
|
+
this.ee.emit(SESSION_EVENTS.RESUME);
|
|
105
|
+
},
|
|
95
106
|
// When the inactive timer pauses, update the storage values with an update timestamp
|
|
96
|
-
onPause: () =>
|
|
107
|
+
onPause: () => {
|
|
108
|
+
if (this.initialized) this.ee.emit(SESSION_EVENTS.PAUSE);
|
|
109
|
+
this.write(getModeledObject(this.state, model));
|
|
110
|
+
},
|
|
97
111
|
ee: this.ee,
|
|
98
112
|
refreshEvents: ['click', 'keydown', 'scroll']
|
|
99
|
-
}, this.inactiveAt - Date.now());
|
|
113
|
+
}, this.state.inactiveAt - Date.now());
|
|
100
114
|
} else {
|
|
101
|
-
this.inactiveAt = Infinity;
|
|
115
|
+
this.state.inactiveAt = Infinity;
|
|
102
116
|
}
|
|
103
117
|
|
|
104
118
|
// The fact that the session is "new" or pre-existing is used in some places in the agent. Session Replay and Trace
|
|
105
119
|
// can use this info to inform whether to trust a new sampling decision vs continue a previous tracking effort.
|
|
106
|
-
this.isNew = !Object.keys(initialRead).length;
|
|
120
|
+
if (this.isNew === undefined) this.isNew = !Object.keys(initialRead).length;
|
|
107
121
|
// if its a "new" session, we write to storage API with the default values. These values may change over the lifespan of the agent run.
|
|
108
|
-
// we can use
|
|
109
|
-
if (this.isNew) this.write(
|
|
122
|
+
// we can use a modeled object here to help us know and manage what values are being used. -- see "model" above
|
|
123
|
+
if (this.isNew) this.write(getModeledObject(this.state, model), true);else this.sync(initialRead);
|
|
110
124
|
this.initialized = true;
|
|
111
125
|
}
|
|
112
126
|
|
|
@@ -115,7 +129,7 @@ export class SessionEntity {
|
|
|
115
129
|
return "".concat(PREFIX, "_").concat(this.key);
|
|
116
130
|
}
|
|
117
131
|
sync(data) {
|
|
118
|
-
Object.assign(this, data);
|
|
132
|
+
Object.assign(this.state, data);
|
|
119
133
|
}
|
|
120
134
|
|
|
121
135
|
/**
|
|
@@ -162,7 +176,8 @@ export class SessionEntity {
|
|
|
162
176
|
if (!data || typeof data !== 'object') return;
|
|
163
177
|
// everytime we update, we can update a timestamp for sanity
|
|
164
178
|
data.updatedAt = Date.now();
|
|
165
|
-
this.sync(data);
|
|
179
|
+
this.sync(data); // update the parent class "state" properties with the local storage values
|
|
180
|
+
//
|
|
166
181
|
// TODO - compression would need happen here if we decide to do it
|
|
167
182
|
this.storage.set(this.lookupKey, stringify(data));
|
|
168
183
|
return data;
|
|
@@ -178,12 +193,11 @@ export class SessionEntity {
|
|
|
178
193
|
// * stop recording (stn and sr)...
|
|
179
194
|
// * delete the session and start over
|
|
180
195
|
try {
|
|
181
|
-
if (this.initialized) this.ee.emit(
|
|
196
|
+
if (this.initialized) this.ee.emit(SESSION_EVENTS.RESET);
|
|
182
197
|
this.storage.remove(this.lookupKey);
|
|
183
198
|
this.inactiveTimer?.abort?.();
|
|
184
199
|
this.expiresTimer?.clear?.();
|
|
185
|
-
delete this.
|
|
186
|
-
delete this.value;
|
|
200
|
+
delete this.isNew;
|
|
187
201
|
this.setup({
|
|
188
202
|
agentIdentifier: this.agentIdentifier,
|
|
189
203
|
key: this.key,
|
|
@@ -203,10 +217,9 @@ export class SessionEntity {
|
|
|
203
217
|
refresh() {
|
|
204
218
|
// read here & invalidate
|
|
205
219
|
const existingData = this.read();
|
|
206
|
-
this.inactiveAt = this.getFutureTimestamp(this.inactiveMs);
|
|
207
220
|
this.write({
|
|
208
221
|
...existingData,
|
|
209
|
-
inactiveAt: this.
|
|
222
|
+
inactiveAt: this.getFutureTimestamp(this.inactiveMs)
|
|
210
223
|
});
|
|
211
224
|
}
|
|
212
225
|
|
|
@@ -223,7 +236,7 @@ export class SessionEntity {
|
|
|
223
236
|
* @returns {boolean}
|
|
224
237
|
*/
|
|
225
238
|
isInvalid(data) {
|
|
226
|
-
const requiredKeys =
|
|
239
|
+
const requiredKeys = Object.keys(model);
|
|
227
240
|
return !requiredKeys.every(x => Object.keys(data).includes(x));
|
|
228
241
|
}
|
|
229
242
|
collectSM(type, data, useUpdatedAt) {
|
|
@@ -36,17 +36,19 @@ describe('constructor', () => {
|
|
|
36
36
|
expect(session).toMatchObject({
|
|
37
37
|
agentIdentifier: expect.any(String),
|
|
38
38
|
key: expect.any(String),
|
|
39
|
-
value: expect.any(String),
|
|
40
39
|
expiresMs: expect.any(Number),
|
|
41
|
-
expiresAt: expect.any(Number),
|
|
42
40
|
expiresTimer: expect.any(Object),
|
|
43
41
|
inactiveMs: expect.any(Number),
|
|
44
|
-
inactiveAt: expect.any(Number),
|
|
45
42
|
inactiveTimer: expect.any(Object),
|
|
46
43
|
isNew: expect.any(Boolean),
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
44
|
+
storage: expect.any(Object),
|
|
45
|
+
state: expect.objectContaining({
|
|
46
|
+
value: expect.any(String),
|
|
47
|
+
expiresAt: expect.any(Number),
|
|
48
|
+
inactiveAt: expect.any(Number),
|
|
49
|
+
sessionReplay: expect.any(Number),
|
|
50
|
+
sessionTraceActive: expect.any(Boolean)
|
|
51
|
+
})
|
|
50
52
|
});
|
|
51
53
|
});
|
|
52
54
|
test('can use sane defaults', () => {
|
|
@@ -54,11 +56,12 @@ describe('constructor', () => {
|
|
|
54
56
|
agentIdentifier,
|
|
55
57
|
key
|
|
56
58
|
});
|
|
57
|
-
expect(session).toEqual(expect.objectContaining({
|
|
59
|
+
expect(session.state).toEqual(expect.objectContaining({
|
|
58
60
|
value: expect.any(String),
|
|
59
61
|
expiresAt: expect.any(Number),
|
|
60
62
|
inactiveAt: expect.any(Number),
|
|
61
|
-
|
|
63
|
+
updatedAt: expect.any(Number),
|
|
64
|
+
sessionReplay: expect.any(Number),
|
|
62
65
|
sessionTraceActive: expect.any(Boolean)
|
|
63
66
|
}));
|
|
64
67
|
});
|
|
@@ -79,7 +82,7 @@ describe('constructor', () => {
|
|
|
79
82
|
key,
|
|
80
83
|
expiresMs: 100
|
|
81
84
|
});
|
|
82
|
-
expect(session.expiresAt).toEqual(now + 100);
|
|
85
|
+
expect(session.state.expiresAt).toEqual(now + 100);
|
|
83
86
|
});
|
|
84
87
|
test('expiresAt is the correct future timestamp - existing session', () => {
|
|
85
88
|
const now = Date.now();
|
|
@@ -88,7 +91,11 @@ describe('constructor', () => {
|
|
|
88
91
|
["".concat(PREFIX, "_").concat(key)]: {
|
|
89
92
|
value,
|
|
90
93
|
expiresAt: now + 5000,
|
|
91
|
-
inactiveAt: Infinity
|
|
94
|
+
inactiveAt: Infinity,
|
|
95
|
+
updatedAt: now,
|
|
96
|
+
sessionReplay: 0,
|
|
97
|
+
sessionTraceActive: false,
|
|
98
|
+
custom: {}
|
|
92
99
|
}
|
|
93
100
|
});
|
|
94
101
|
const session = new SessionEntity({
|
|
@@ -97,7 +104,7 @@ describe('constructor', () => {
|
|
|
97
104
|
expiresMs: 100,
|
|
98
105
|
storageAPI: existingData
|
|
99
106
|
});
|
|
100
|
-
expect(session.expiresAt).toEqual(now + 5000);
|
|
107
|
+
expect(session.state.expiresAt).toEqual(now + 5000);
|
|
101
108
|
});
|
|
102
109
|
test('expiresAt never expires if 0', () => {
|
|
103
110
|
const session = new SessionEntity({
|
|
@@ -105,7 +112,7 @@ describe('constructor', () => {
|
|
|
105
112
|
key,
|
|
106
113
|
expiresMs: 0
|
|
107
114
|
});
|
|
108
|
-
expect(session.expiresAt).toEqual(Infinity);
|
|
115
|
+
expect(session.state.expiresAt).toEqual(Infinity);
|
|
109
116
|
});
|
|
110
117
|
test('inactiveAt is the correct future timestamp - new session', () => {
|
|
111
118
|
const now = Date.now();
|
|
@@ -115,7 +122,7 @@ describe('constructor', () => {
|
|
|
115
122
|
key,
|
|
116
123
|
inactiveMs: 100
|
|
117
124
|
});
|
|
118
|
-
expect(session.inactiveAt).toEqual(now + 100);
|
|
125
|
+
expect(session.state.inactiveAt).toEqual(now + 100);
|
|
119
126
|
});
|
|
120
127
|
test('inactiveAt is the correct future timestamp - existing session', () => {
|
|
121
128
|
const now = Date.now();
|
|
@@ -124,7 +131,11 @@ describe('constructor', () => {
|
|
|
124
131
|
["".concat(PREFIX, "_").concat(key)]: {
|
|
125
132
|
value,
|
|
126
133
|
inactiveAt: now + 5000,
|
|
127
|
-
expiresAt: Infinity
|
|
134
|
+
expiresAt: Infinity,
|
|
135
|
+
updatedAt: now,
|
|
136
|
+
sessionReplay: 0,
|
|
137
|
+
sessionTraceActive: false,
|
|
138
|
+
custom: {}
|
|
128
139
|
}
|
|
129
140
|
});
|
|
130
141
|
const session = new SessionEntity({
|
|
@@ -133,7 +144,7 @@ describe('constructor', () => {
|
|
|
133
144
|
inactiveMs: 100,
|
|
134
145
|
storageAPI: existingData
|
|
135
146
|
});
|
|
136
|
-
expect(session.inactiveAt).toEqual(now + 5000);
|
|
147
|
+
expect(session.state.inactiveAt).toEqual(now + 5000);
|
|
137
148
|
});
|
|
138
149
|
test('inactiveAt never expires if 0', () => {
|
|
139
150
|
const session = new SessionEntity({
|
|
@@ -141,7 +152,7 @@ describe('constructor', () => {
|
|
|
141
152
|
key,
|
|
142
153
|
inactiveMs: 0
|
|
143
154
|
});
|
|
144
|
-
expect(session.inactiveAt).toEqual(Infinity);
|
|
155
|
+
expect(session.state.inactiveAt).toEqual(Infinity);
|
|
145
156
|
});
|
|
146
157
|
test('should handle isNew', () => {
|
|
147
158
|
const newSession = new SessionEntity({
|
|
@@ -154,7 +165,11 @@ describe('constructor', () => {
|
|
|
154
165
|
["".concat(PREFIX, "_").concat(key)]: {
|
|
155
166
|
value,
|
|
156
167
|
expiresAt: Infinity,
|
|
157
|
-
inactiveAt: Infinity
|
|
168
|
+
inactiveAt: Infinity,
|
|
169
|
+
updatedAt: Date.now(),
|
|
170
|
+
sessionReplay: 0,
|
|
171
|
+
sessionTraceActive: false,
|
|
172
|
+
custom: {}
|
|
158
173
|
}
|
|
159
174
|
});
|
|
160
175
|
const existingSession = new SessionEntity({
|
|
@@ -177,11 +192,12 @@ describe('constructor', () => {
|
|
|
177
192
|
key,
|
|
178
193
|
storageAPI
|
|
179
194
|
});
|
|
180
|
-
expect(session).toEqual(expect.objectContaining({
|
|
195
|
+
expect(session.state).toEqual(expect.objectContaining({
|
|
181
196
|
value: expect.any(String),
|
|
182
197
|
expiresAt: expect.any(Number),
|
|
183
198
|
inactiveAt: expect.any(Number),
|
|
184
|
-
|
|
199
|
+
updatedAt: expect.any(Number),
|
|
200
|
+
sessionReplay: expect.any(Number),
|
|
185
201
|
sessionTraceActive: expect.any(Boolean)
|
|
186
202
|
}));
|
|
187
203
|
});
|
|
@@ -200,11 +216,12 @@ describe('constructor', () => {
|
|
|
200
216
|
key,
|
|
201
217
|
storageAPI
|
|
202
218
|
});
|
|
203
|
-
expect(session).toEqual(expect.objectContaining({
|
|
219
|
+
expect(session.state).toEqual(expect.objectContaining({
|
|
204
220
|
value: expect.any(String),
|
|
205
221
|
expiresAt: expect.any(Number),
|
|
206
222
|
inactiveAt: expect.any(Number),
|
|
207
|
-
|
|
223
|
+
updatedAt: expect.any(Number),
|
|
224
|
+
sessionReplay: expect.any(Number),
|
|
208
225
|
sessionTraceActive: expect.any(Boolean)
|
|
209
226
|
}));
|
|
210
227
|
});
|
|
@@ -223,11 +240,12 @@ describe('constructor', () => {
|
|
|
223
240
|
key,
|
|
224
241
|
storageAPI
|
|
225
242
|
});
|
|
226
|
-
expect(session).toEqual(expect.objectContaining({
|
|
243
|
+
expect(session.state).toEqual(expect.objectContaining({
|
|
227
244
|
value: expect.any(String),
|
|
228
245
|
expiresAt: expect.any(Number),
|
|
229
246
|
inactiveAt: expect.any(Number),
|
|
230
|
-
|
|
247
|
+
updatedAt: expect.any(Number),
|
|
248
|
+
sessionReplay: expect.any(Number),
|
|
231
249
|
sessionTraceActive: expect.any(Boolean)
|
|
232
250
|
}));
|
|
233
251
|
});
|
|
@@ -242,10 +260,10 @@ describe('reset()', () => {
|
|
|
242
260
|
expiresMs: 10
|
|
243
261
|
});
|
|
244
262
|
const sessionVal = session.value;
|
|
245
|
-
expect(session.value).toBeTruthy();
|
|
263
|
+
expect(session.state.value).toBeTruthy();
|
|
246
264
|
session.reset();
|
|
247
|
-
expect(session.value).toBeTruthy();
|
|
248
|
-
expect(session.value).not.toEqual(sessionVal);
|
|
265
|
+
expect(session.state.value).toBeTruthy();
|
|
266
|
+
expect(session.state.value).not.toEqual(sessionVal);
|
|
249
267
|
});
|
|
250
268
|
test('custom data should be wiped on reset', () => {
|
|
251
269
|
const now = Date.now();
|
|
@@ -256,12 +274,12 @@ describe('reset()', () => {
|
|
|
256
274
|
expiresMs: 10
|
|
257
275
|
});
|
|
258
276
|
session.syncCustomAttribute('test', 123);
|
|
259
|
-
expect(session.custom.test).toEqual(123);
|
|
277
|
+
expect(session.state.custom.test).toEqual(123);
|
|
260
278
|
expect(session.read().custom.test).toEqual(123);
|
|
261
279
|
|
|
262
280
|
// simulate a timer expiring
|
|
263
281
|
session.reset();
|
|
264
|
-
expect(session.custom?.test).toEqual(undefined);
|
|
282
|
+
expect(session.state.custom?.test).toEqual(undefined);
|
|
265
283
|
expect(session.read()?.custom?.test).toEqual(undefined);
|
|
266
284
|
});
|
|
267
285
|
});
|
|
@@ -277,7 +295,7 @@ describe('read()', () => {
|
|
|
277
295
|
value: expect.any(String),
|
|
278
296
|
expiresAt: expect.any(Number),
|
|
279
297
|
inactiveAt: expect.any(Number),
|
|
280
|
-
|
|
298
|
+
sessionReplay: expect.any(Number),
|
|
281
299
|
sessionTraceActive: expect.any(Boolean)
|
|
282
300
|
}));
|
|
283
301
|
});
|
|
@@ -286,7 +304,11 @@ describe('read()', () => {
|
|
|
286
304
|
["".concat(PREFIX, "_").concat(key)]: {
|
|
287
305
|
value,
|
|
288
306
|
expiresAt: Infinity,
|
|
289
|
-
inactiveAt: Infinity
|
|
307
|
+
inactiveAt: Infinity,
|
|
308
|
+
updatedAt: Date.now(),
|
|
309
|
+
sessionReplay: 0,
|
|
310
|
+
sessionTraceActive: false,
|
|
311
|
+
custom: {}
|
|
290
312
|
}
|
|
291
313
|
});
|
|
292
314
|
const session = new SessionEntity({
|
|
@@ -308,17 +330,18 @@ describe('write()', () => {
|
|
|
308
330
|
agentIdentifier,
|
|
309
331
|
key
|
|
310
332
|
});
|
|
311
|
-
expect(session.value).not.toEqual(value);
|
|
312
|
-
expect(session.expiresAt).not.toEqual(Infinity);
|
|
313
|
-
expect(session.inactiveAt).not.toEqual(Infinity);
|
|
333
|
+
expect(session.state.value).not.toEqual(value);
|
|
334
|
+
expect(session.state.expiresAt).not.toEqual(Infinity);
|
|
335
|
+
expect(session.state.inactiveAt).not.toEqual(Infinity);
|
|
314
336
|
session.write({
|
|
337
|
+
...session.state,
|
|
315
338
|
value,
|
|
316
339
|
expiresAt: Infinity,
|
|
317
340
|
inactiveAt: Infinity
|
|
318
341
|
});
|
|
319
|
-
expect(session.value).toEqual(value);
|
|
320
|
-
expect(session.expiresAt).toEqual(Infinity);
|
|
321
|
-
expect(session.inactiveAt).toEqual(Infinity);
|
|
342
|
+
expect(session.state.value).toEqual(value);
|
|
343
|
+
expect(session.state.expiresAt).toEqual(Infinity);
|
|
344
|
+
expect(session.state.inactiveAt).toEqual(Infinity);
|
|
322
345
|
});
|
|
323
346
|
test('write() sets data that read() can access', () => {
|
|
324
347
|
const now = Date.now();
|
|
@@ -328,6 +351,7 @@ describe('write()', () => {
|
|
|
328
351
|
key
|
|
329
352
|
});
|
|
330
353
|
session.write({
|
|
354
|
+
...session.state,
|
|
331
355
|
value,
|
|
332
356
|
expiresAt: now + 100,
|
|
333
357
|
inactiveAt: now + 100
|
|
@@ -363,10 +387,10 @@ describe('refresh()', () => {
|
|
|
363
387
|
key,
|
|
364
388
|
inactiveMs: 100
|
|
365
389
|
});
|
|
366
|
-
expect(session.inactiveAt).toEqual(now + 100);
|
|
390
|
+
expect(session.state.inactiveAt).toEqual(now + 100);
|
|
367
391
|
jest.setSystemTime(now + 1000);
|
|
368
392
|
session.refresh();
|
|
369
|
-
expect(session.inactiveAt).toEqual(now + 100 + 1000);
|
|
393
|
+
expect(session.state.inactiveAt).toEqual(now + 100 + 1000);
|
|
370
394
|
});
|
|
371
395
|
test('refresh resets the entity if expiresTimer is invalid', () => {
|
|
372
396
|
const now = Date.now();
|
|
@@ -376,13 +400,13 @@ describe('refresh()', () => {
|
|
|
376
400
|
key,
|
|
377
401
|
value
|
|
378
402
|
});
|
|
379
|
-
expect(session.value).toEqual(value);
|
|
403
|
+
expect(session.state.value).toEqual(value);
|
|
380
404
|
session.write({
|
|
381
|
-
...session.
|
|
405
|
+
...session.state,
|
|
382
406
|
expiresAt: now - 1
|
|
383
407
|
});
|
|
384
408
|
session.refresh();
|
|
385
|
-
expect(session.value).not.toEqual(value);
|
|
409
|
+
expect(session.state.value).not.toEqual(value);
|
|
386
410
|
});
|
|
387
411
|
test('refresh resets the entity if inactiveTimer is invalid', () => {
|
|
388
412
|
const now = Date.now();
|
|
@@ -392,13 +416,13 @@ describe('refresh()', () => {
|
|
|
392
416
|
key,
|
|
393
417
|
value
|
|
394
418
|
});
|
|
395
|
-
expect(session.value).toEqual(value);
|
|
419
|
+
expect(session.state.value).toEqual(value);
|
|
396
420
|
session.write({
|
|
397
|
-
...session.
|
|
421
|
+
...session.state,
|
|
398
422
|
inactiveAt: now - 1
|
|
399
423
|
});
|
|
400
424
|
session.refresh();
|
|
401
|
-
expect(session.value).not.toEqual(value);
|
|
425
|
+
expect(session.state.value).not.toEqual(value);
|
|
402
426
|
});
|
|
403
427
|
});
|
|
404
428
|
describe('syncCustomAttribute()', () => {
|
|
@@ -410,17 +434,17 @@ describe('syncCustomAttribute()', () => {
|
|
|
410
434
|
|
|
411
435
|
// if custom has never been set, and a "delete" action is triggered, do nothing
|
|
412
436
|
session.syncCustomAttribute('test', null);
|
|
413
|
-
expect(session?.custom?.test).toEqual(undefined);
|
|
437
|
+
expect(session?.state?.custom?.test).toEqual(undefined);
|
|
414
438
|
session.syncCustomAttribute('test', 1);
|
|
415
|
-
expect(session?.custom?.test).toEqual(1);
|
|
439
|
+
expect(session?.state?.custom?.test).toEqual(1);
|
|
416
440
|
session.syncCustomAttribute('test', 'string');
|
|
417
|
-
expect(session?.custom?.test).toEqual('string');
|
|
441
|
+
expect(session?.state?.custom?.test).toEqual('string');
|
|
418
442
|
session.syncCustomAttribute('test', false);
|
|
419
|
-
expect(session?.custom?.test).toEqual(false);
|
|
443
|
+
expect(session?.state?.custom?.test).toEqual(false);
|
|
420
444
|
|
|
421
445
|
// null specifically deletes the object completely
|
|
422
446
|
session.syncCustomAttribute('test', null);
|
|
423
|
-
expect(session?.custom?.test).toEqual(undefined);
|
|
447
|
+
expect(session?.state?.custom?.test).toEqual(undefined);
|
|
424
448
|
});
|
|
425
449
|
test('Only runs in browser scope', () => {
|
|
426
450
|
mockBrowserScope.mockReturnValue(false);
|
|
@@ -5,8 +5,9 @@ import { isBrowserScope } from '../util/global-scope';
|
|
|
5
5
|
export class InteractionTimer extends Timer {
|
|
6
6
|
constructor(opts, ms) {
|
|
7
7
|
super(opts, ms);
|
|
8
|
-
this.
|
|
9
|
-
this.
|
|
8
|
+
this.onPause = typeof opts.onPause === 'function' ? opts.onPause : () => {/* noop */};
|
|
9
|
+
this.onRefresh = typeof opts.onRefresh === 'function' ? opts.onRefresh : () => {/* noop */};
|
|
10
|
+
this.onResume = typeof opts.onResume === 'function' ? opts.onResume : () => {/* noop */};
|
|
10
11
|
|
|
11
12
|
// used by pause/resume
|
|
12
13
|
this.remainingMs = undefined;
|
|
@@ -41,7 +42,10 @@ export class InteractionTimer extends Timer {
|
|
|
41
42
|
subscribeToVisibilityChange(state => {
|
|
42
43
|
if (state === 'hidden') this.pause();
|
|
43
44
|
// vis change --> visible is treated like a new interaction with the page
|
|
44
|
-
else
|
|
45
|
+
else {
|
|
46
|
+
this.onResume();
|
|
47
|
+
this.refresh();
|
|
48
|
+
}
|
|
45
49
|
}, false, false, this.abortController?.signal);
|
|
46
50
|
}
|
|
47
51
|
}
|
|
@@ -50,7 +54,7 @@ export class InteractionTimer extends Timer {
|
|
|
50
54
|
this.abortController?.abort();
|
|
51
55
|
}
|
|
52
56
|
pause() {
|
|
53
|
-
this.onPause
|
|
57
|
+
this.onPause();
|
|
54
58
|
clearTimeout(this.timer);
|
|
55
59
|
this.remainingMs = this.initialMs - (Date.now() - this.startTimestamp);
|
|
56
60
|
}
|
|
@@ -59,13 +63,6 @@ export class InteractionTimer extends Timer {
|
|
|
59
63
|
this.timer = this.create(cb, ms);
|
|
60
64
|
this.startTimestamp = Date.now();
|
|
61
65
|
this.remainingMs = undefined;
|
|
62
|
-
this.onRefresh
|
|
66
|
+
this.onRefresh();
|
|
63
67
|
}
|
|
64
|
-
|
|
65
|
-
// NOT CURRENTLY UTILIZED BY ANYTHING
|
|
66
|
-
// resume () {
|
|
67
|
-
// if (!this.remainingMs || !this.isValid()) return
|
|
68
|
-
// this.timer = this.create(this.cb, this.remainingMs)
|
|
69
|
-
// this.remainingMs = undefined
|
|
70
|
-
// }
|
|
71
68
|
}
|
|
@@ -11,7 +11,8 @@ const bucketMap = {
|
|
|
11
11
|
stn: [FEATURE_NAMES.sessionTrace],
|
|
12
12
|
err: [FEATURE_NAMES.jserrors, FEATURE_NAMES.metrics],
|
|
13
13
|
ins: [FEATURE_NAMES.pageAction],
|
|
14
|
-
spa: [FEATURE_NAMES.spa]
|
|
14
|
+
spa: [FEATURE_NAMES.spa],
|
|
15
|
+
sr: [FEATURE_NAMES.sessionReplay]
|
|
15
16
|
};
|
|
16
17
|
export function activateFeatures(flags, agentIdentifier) {
|
|
17
18
|
var sharedEE = ee.get(agentIdentifier);
|
|
@@ -7,11 +7,17 @@ export const submitData = {};
|
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Send via JSONP. Do NOT call this function outside of a guaranteed web window environment.
|
|
10
|
-
* @param {
|
|
11
|
-
* @param {string}
|
|
10
|
+
* @param {Object} args - The args
|
|
11
|
+
* @param {string} args.url - The URL to send to
|
|
12
|
+
* @param {string} args.jsonp - The string name of the jsonp cb method
|
|
13
|
+
* @returns {XMLHttpRequest}
|
|
12
14
|
* @returns {Element}
|
|
13
15
|
*/
|
|
14
|
-
submitData.jsonp = function jsonp(
|
|
16
|
+
submitData.jsonp = function jsonp(_ref) {
|
|
17
|
+
let {
|
|
18
|
+
url,
|
|
19
|
+
jsonp
|
|
20
|
+
} = _ref;
|
|
15
21
|
try {
|
|
16
22
|
if (isWorkerScope) {
|
|
17
23
|
try {
|
|
@@ -19,7 +25,9 @@ submitData.jsonp = function jsonp(url, jsonp) {
|
|
|
19
25
|
} catch (e) {
|
|
20
26
|
// for now theres no other way to execute the callback from ingest without jsonp, or unsafe eval / new Function calls
|
|
21
27
|
// future work needs to be conducted to allow ingest to return a more traditional JSON API-like experience for the entitlement flags
|
|
22
|
-
submitData.xhrGet(
|
|
28
|
+
submitData.xhrGet({
|
|
29
|
+
url: url + '&jsonp=' + jsonp
|
|
30
|
+
});
|
|
23
31
|
return false;
|
|
24
32
|
}
|
|
25
33
|
} else {
|
|
@@ -34,19 +42,38 @@ submitData.jsonp = function jsonp(url, jsonp) {
|
|
|
34
42
|
// do nothing
|
|
35
43
|
}
|
|
36
44
|
};
|
|
37
|
-
submitData.xhrGet = function xhrGet(
|
|
38
|
-
|
|
45
|
+
submitData.xhrGet = function xhrGet(_ref2) {
|
|
46
|
+
let {
|
|
47
|
+
url
|
|
48
|
+
} = _ref2;
|
|
49
|
+
return submitData.xhr({
|
|
50
|
+
url,
|
|
51
|
+
sync: false,
|
|
52
|
+
method: 'GET'
|
|
53
|
+
});
|
|
39
54
|
};
|
|
40
55
|
|
|
41
56
|
/**
|
|
42
57
|
* Send via XHR
|
|
43
|
-
* @param {
|
|
44
|
-
* @param {string}
|
|
45
|
-
* @param {
|
|
58
|
+
* @param {Object} args - The args
|
|
59
|
+
* @param {string} args.url - The URL to send to
|
|
60
|
+
* @param {string=} args.body - The Stringified body
|
|
61
|
+
* @param {boolean=} args.sync - Run XHR as Synchronous
|
|
62
|
+
* @param {string=} [args.method=POST] - The XHR method to use
|
|
63
|
+
* @param {{key: string, value: string}[]} [args.headers] - The headers to attach
|
|
46
64
|
* @returns {XMLHttpRequest}
|
|
47
65
|
*/
|
|
48
|
-
submitData.xhr = function xhr(
|
|
49
|
-
let
|
|
66
|
+
submitData.xhr = function xhr(_ref3) {
|
|
67
|
+
let {
|
|
68
|
+
url,
|
|
69
|
+
body,
|
|
70
|
+
sync,
|
|
71
|
+
method = 'POST',
|
|
72
|
+
headers = [{
|
|
73
|
+
key: 'content-type',
|
|
74
|
+
value: 'text/plain'
|
|
75
|
+
}]
|
|
76
|
+
} = _ref3;
|
|
50
77
|
var request = new XMLHttpRequest();
|
|
51
78
|
request.open(method, url, !sync);
|
|
52
79
|
try {
|
|
@@ -55,7 +82,9 @@ submitData.xhr = function xhr(url, body, sync) {
|
|
|
55
82
|
} catch (e) {
|
|
56
83
|
// do nothing
|
|
57
84
|
}
|
|
58
|
-
|
|
85
|
+
headers.forEach(header => {
|
|
86
|
+
request.setRequestHeader(header.key, header.value);
|
|
87
|
+
});
|
|
59
88
|
request.send(body);
|
|
60
89
|
return request;
|
|
61
90
|
};
|
|
@@ -69,10 +98,15 @@ submitData.xhr = function xhr(url, body, sync) {
|
|
|
69
98
|
|
|
70
99
|
/**
|
|
71
100
|
* Send by appending an <img> element to the page. Do NOT call this function outside of a guaranteed web window environment.
|
|
72
|
-
* @param {
|
|
73
|
-
* @
|
|
101
|
+
* @param {Object} args - The args
|
|
102
|
+
* @param {string} args.url - The URL to send to
|
|
103
|
+
* @returns {HTMLImageElement}
|
|
74
104
|
*/
|
|
75
|
-
submitData.img = function img(
|
|
105
|
+
submitData.img = function img(_ref4) {
|
|
106
|
+
let {
|
|
107
|
+
url
|
|
108
|
+
} = _ref4;
|
|
109
|
+
console.log('img url', url);
|
|
76
110
|
var element = new Image();
|
|
77
111
|
element.src = url;
|
|
78
112
|
return element;
|
|
@@ -80,11 +114,16 @@ submitData.img = function img(url) {
|
|
|
80
114
|
|
|
81
115
|
/**
|
|
82
116
|
* Send via sendBeacon. Do NOT call this function outside of a guaranteed web window environment.
|
|
83
|
-
* @param {
|
|
84
|
-
* @param {string}
|
|
117
|
+
* @param {Object} args - The args
|
|
118
|
+
* @param {string} args.url - The URL to send to
|
|
119
|
+
* @param {string=} args.body - The Stringified body
|
|
85
120
|
* @returns {boolean}
|
|
86
121
|
*/
|
|
87
|
-
submitData.beacon = function (
|
|
122
|
+
submitData.beacon = function (_ref5) {
|
|
123
|
+
let {
|
|
124
|
+
url,
|
|
125
|
+
body
|
|
126
|
+
} = _ref5;
|
|
88
127
|
// Navigator has to be bound to ensure it does not error in some browsers
|
|
89
128
|
// https://xgwang.me/posts/you-may-not-know-beacon/#it-may-throw-error%2C-be-sure-to-catch
|
|
90
129
|
const send = window.navigator.sendBeacon.bind(window.navigator);
|