@newrelic/browser-agent 0.1.231 → 1.232.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.
Files changed (210) hide show
  1. package/README.md +2 -2
  2. package/dist/cjs/common/config/state/configurable.js +27 -21
  3. package/dist/cjs/common/config/state/init.js +8 -0
  4. package/dist/cjs/common/config/state/runtime.js +24 -26
  5. package/dist/cjs/common/constants/env.cdn.js +1 -1
  6. package/dist/cjs/common/constants/env.npm.js +1 -1
  7. package/dist/cjs/common/context/shared-context.js +2 -1
  8. package/dist/cjs/common/event-emitter/contextual-ee.test.js +2 -2
  9. package/dist/cjs/common/event-emitter/register-handler.test.js +1 -1
  10. package/dist/cjs/common/event-listener/event-listener-opts.js +4 -2
  11. package/dist/cjs/common/harvest/harvest-scheduler.js +14 -11
  12. package/dist/cjs/common/harvest/harvest.js +3 -1
  13. package/dist/cjs/common/session/constants.js +12 -0
  14. package/dist/cjs/common/session/session-entity.js +278 -0
  15. package/dist/cjs/common/session/session-entity.test.js +436 -0
  16. package/dist/cjs/common/storage/first-party-cookies.js +35 -0
  17. package/dist/cjs/common/storage/local-memory.js +35 -0
  18. package/dist/cjs/common/storage/local-memory.test.js +20 -0
  19. package/dist/cjs/common/storage/local-storage.js +33 -0
  20. package/dist/cjs/common/storage/local-storage.test.js +14 -0
  21. package/dist/cjs/common/timer/interaction-timer.js +78 -0
  22. package/dist/cjs/common/timer/interaction-timer.test.js +216 -0
  23. package/dist/cjs/common/timer/timer.js +32 -0
  24. package/dist/cjs/common/timer/timer.test.js +105 -0
  25. package/dist/cjs/common/unload/eol.js +2 -2
  26. package/dist/cjs/common/util/data-size.js +6 -0
  27. package/dist/cjs/common/util/data-size.test.js +47 -0
  28. package/dist/cjs/common/util/invoke.js +73 -0
  29. package/dist/cjs/common/util/invoke.test.js +49 -0
  30. package/dist/cjs/common/util/obfuscate.js +0 -4
  31. package/dist/cjs/common/window/page-visibility.js +3 -1
  32. package/dist/cjs/common/wrap/wrap-timer.js +1 -1
  33. package/dist/cjs/features/ajax/aggregate/index.js +2 -2
  34. package/dist/cjs/features/jserrors/aggregate/index.js +3 -3
  35. package/dist/cjs/features/metrics/aggregate/index.js +13 -2
  36. package/dist/cjs/features/page_action/aggregate/index.js +2 -2
  37. package/dist/cjs/features/page_view_event/aggregate/index.js +6 -3
  38. package/dist/cjs/features/page_view_timing/aggregate/index.js +6 -6
  39. package/dist/cjs/features/session_trace/aggregate/index.js +2 -2
  40. package/dist/cjs/features/spa/aggregate/index.js +6 -5
  41. package/dist/cjs/features/utils/agent-session.js +73 -0
  42. package/dist/cjs/features/utils/feature-base.js +1 -1
  43. package/dist/cjs/features/utils/instrument-base.js +7 -2
  44. package/dist/cjs/features/utils/lazy-loader.js +1 -1
  45. package/dist/cjs/loaders/agent.js +1 -1
  46. package/dist/cjs/loaders/api/api.js +1 -4
  47. package/dist/cjs/loaders/api/apiAsync.js +3 -2
  48. package/dist/cjs/loaders/configure/configure.js +0 -6
  49. package/dist/esm/common/config/state/configurable.js +26 -20
  50. package/dist/esm/common/config/state/init.js +8 -0
  51. package/dist/esm/common/config/state/runtime.js +24 -26
  52. package/dist/esm/common/constants/env.cdn.js +1 -1
  53. package/dist/esm/common/constants/env.npm.js +1 -1
  54. package/dist/esm/common/context/shared-context.js +2 -1
  55. package/dist/esm/common/event-emitter/contextual-ee.test.js +2 -2
  56. package/dist/esm/common/event-emitter/register-handler.test.js +1 -1
  57. package/dist/esm/common/event-listener/event-listener-opts.js +4 -2
  58. package/dist/esm/common/harvest/harvest-scheduler.js +14 -11
  59. package/dist/esm/common/harvest/harvest.js +3 -1
  60. package/dist/esm/common/session/constants.js +3 -0
  61. package/dist/esm/common/session/session-entity.js +271 -0
  62. package/dist/esm/common/session/session-entity.test.js +434 -0
  63. package/dist/esm/common/storage/first-party-cookies.js +28 -0
  64. package/dist/esm/common/storage/local-memory.js +28 -0
  65. package/dist/esm/common/storage/local-memory.test.js +18 -0
  66. package/dist/esm/common/storage/local-storage.js +26 -0
  67. package/dist/esm/common/storage/local-storage.test.js +12 -0
  68. package/dist/esm/common/timer/interaction-timer.js +71 -0
  69. package/dist/esm/common/timer/interaction-timer.test.js +214 -0
  70. package/dist/esm/common/timer/timer.js +25 -0
  71. package/dist/esm/common/timer/timer.test.js +103 -0
  72. package/dist/esm/common/unload/eol.js +1 -1
  73. package/dist/esm/common/util/data-size.js +7 -0
  74. package/dist/esm/common/util/data-size.test.js +45 -0
  75. package/dist/esm/common/util/invoke.js +66 -0
  76. package/dist/esm/common/util/invoke.test.js +47 -0
  77. package/dist/esm/common/util/obfuscate.js +0 -4
  78. package/dist/esm/common/window/page-visibility.js +3 -1
  79. package/dist/esm/common/wrap/wrap-timer.js +1 -1
  80. package/dist/esm/features/ajax/aggregate/index.js +2 -2
  81. package/dist/esm/features/jserrors/aggregate/index.js +3 -3
  82. package/dist/esm/features/metrics/aggregate/index.js +14 -3
  83. package/dist/esm/features/page_action/aggregate/index.js +2 -2
  84. package/dist/esm/features/page_view_event/aggregate/index.js +6 -3
  85. package/dist/esm/features/page_view_timing/aggregate/index.js +6 -6
  86. package/dist/esm/features/session_trace/aggregate/index.js +2 -2
  87. package/dist/esm/features/spa/aggregate/index.js +6 -5
  88. package/dist/esm/features/utils/agent-session.js +67 -0
  89. package/dist/esm/features/utils/feature-base.js +1 -1
  90. package/dist/esm/features/utils/instrument-base.js +7 -2
  91. package/dist/esm/features/utils/lazy-loader.js +1 -1
  92. package/dist/esm/loaders/agent.js +1 -1
  93. package/dist/esm/loaders/api/api.js +2 -5
  94. package/dist/esm/loaders/api/apiAsync.js +2 -1
  95. package/dist/esm/loaders/configure/configure.js +2 -8
  96. package/dist/types/common/config/state/configurable.d.ts.map +1 -1
  97. package/dist/types/common/config/state/init.d.ts.map +1 -1
  98. package/dist/types/common/config/state/runtime.d.ts.map +1 -1
  99. package/dist/types/common/context/shared-context.d.ts.map +1 -1
  100. package/dist/types/common/event-listener/event-listener-opts.d.ts +2 -2
  101. package/dist/types/common/event-listener/event-listener-opts.d.ts.map +1 -1
  102. package/dist/types/common/harvest/harvest-scheduler.d.ts +1 -0
  103. package/dist/types/common/harvest/harvest-scheduler.d.ts.map +1 -1
  104. package/dist/types/common/harvest/harvest.d.ts.map +1 -1
  105. package/dist/types/common/session/constants.d.ts +4 -0
  106. package/dist/types/common/session/constants.d.ts.map +1 -0
  107. package/dist/types/common/session/session-entity.d.ts +72 -0
  108. package/dist/types/common/session/session-entity.d.ts.map +1 -0
  109. package/dist/types/common/storage/first-party-cookies.d.ts +8 -0
  110. package/dist/types/common/storage/first-party-cookies.d.ts.map +1 -0
  111. package/dist/types/common/storage/local-memory.d.ts +8 -0
  112. package/dist/types/common/storage/local-memory.d.ts.map +1 -0
  113. package/dist/types/common/storage/local-storage.d.ts +6 -0
  114. package/dist/types/common/storage/local-storage.d.ts.map +1 -0
  115. package/dist/types/common/timer/interaction-timer.d.ts +11 -0
  116. package/dist/types/common/timer/interaction-timer.d.ts.map +1 -0
  117. package/dist/types/common/timer/timer.d.ts +12 -0
  118. package/dist/types/common/timer/timer.d.ts.map +1 -0
  119. package/dist/types/common/util/data-size.d.ts +7 -1
  120. package/dist/types/common/util/data-size.d.ts.map +1 -1
  121. package/dist/types/common/util/invoke.d.ts +35 -0
  122. package/dist/types/common/util/invoke.d.ts.map +1 -0
  123. package/dist/types/common/util/obfuscate.d.ts.map +1 -1
  124. package/dist/types/common/window/page-visibility.d.ts +1 -1
  125. package/dist/types/common/window/page-visibility.d.ts.map +1 -1
  126. package/dist/types/features/ajax/aggregate/index.d.ts +2 -2
  127. package/dist/types/features/ajax/aggregate/index.d.ts.map +1 -1
  128. package/dist/types/features/jserrors/aggregate/index.d.ts +2 -2
  129. package/dist/types/features/jserrors/aggregate/index.d.ts.map +1 -1
  130. package/dist/types/features/metrics/aggregate/index.d.ts +2 -2
  131. package/dist/types/features/metrics/aggregate/index.d.ts.map +1 -1
  132. package/dist/types/features/page_action/aggregate/index.d.ts +2 -2
  133. package/dist/types/features/page_action/aggregate/index.d.ts.map +1 -1
  134. package/dist/types/features/page_view_event/aggregate/index.d.ts +2 -2
  135. package/dist/types/features/page_view_event/aggregate/index.d.ts.map +1 -1
  136. package/dist/types/features/page_view_timing/aggregate/index.d.ts +2 -2
  137. package/dist/types/features/page_view_timing/aggregate/index.d.ts.map +1 -1
  138. package/dist/types/features/session_trace/aggregate/index.d.ts +2 -2
  139. package/dist/types/features/session_trace/aggregate/index.d.ts.map +1 -1
  140. package/dist/types/features/spa/aggregate/index.d.ts +2 -2
  141. package/dist/types/features/spa/aggregate/index.d.ts.map +1 -1
  142. package/dist/types/features/utils/agent-session.d.ts +2 -0
  143. package/dist/types/features/utils/agent-session.d.ts.map +1 -0
  144. package/dist/types/features/utils/instrument-base.d.ts.map +1 -1
  145. package/dist/types/features/utils/lazy-loader.d.ts +2 -2
  146. package/dist/types/features/utils/lazy-loader.d.ts.map +1 -1
  147. package/dist/types/loaders/api/api.d.ts.map +1 -1
  148. package/dist/types/loaders/api/apiAsync.d.ts.map +1 -1
  149. package/dist/types/loaders/configure/configure.d.ts.map +1 -1
  150. package/package.json +6 -5
  151. package/src/common/config/state/configurable.js +26 -19
  152. package/src/common/config/state/init.js +7 -0
  153. package/src/common/config/state/runtime.js +22 -27
  154. package/src/common/context/shared-context.js +2 -1
  155. package/src/common/event-emitter/contextual-ee.test.js +2 -2
  156. package/src/common/event-emitter/register-handler.test.js +1 -1
  157. package/src/common/event-listener/event-listener-opts.js +4 -4
  158. package/src/common/harvest/harvest-scheduler.js +12 -8
  159. package/src/common/harvest/harvest.js +3 -1
  160. package/src/common/session/constants.js +3 -0
  161. package/src/common/session/session-entity.js +271 -0
  162. package/src/common/session/session-entity.test.js +317 -0
  163. package/src/common/storage/first-party-cookies.js +31 -0
  164. package/src/common/storage/local-memory.js +30 -0
  165. package/src/common/storage/local-memory.test.js +19 -0
  166. package/src/common/storage/local-storage.js +28 -0
  167. package/src/common/storage/local-storage.test.js +17 -0
  168. package/src/common/timer/interaction-timer.js +75 -0
  169. package/src/common/timer/interaction-timer.test.js +167 -0
  170. package/src/common/timer/timer.js +31 -0
  171. package/src/common/timer/timer.test.js +100 -0
  172. package/src/common/unload/eol.js +1 -1
  173. package/src/common/util/data-size.js +6 -0
  174. package/src/common/util/data-size.test.js +50 -0
  175. package/src/common/util/invoke.js +55 -0
  176. package/src/common/util/invoke.test.js +65 -0
  177. package/src/common/util/obfuscate.js +0 -4
  178. package/src/common/window/page-visibility.js +2 -2
  179. package/src/common/wrap/wrap-timer.js +1 -1
  180. package/src/features/ajax/aggregate/index.js +2 -2
  181. package/src/features/jserrors/aggregate/index.js +3 -3
  182. package/src/features/metrics/aggregate/index.js +18 -3
  183. package/src/features/page_action/aggregate/index.js +2 -2
  184. package/src/features/page_view_event/aggregate/index.js +6 -3
  185. package/src/features/page_view_timing/aggregate/index.js +6 -6
  186. package/src/features/session_trace/aggregate/index.js +2 -2
  187. package/src/features/spa/aggregate/index.js +5 -5
  188. package/src/features/utils/agent-session.js +68 -0
  189. package/src/features/utils/feature-base.js +1 -1
  190. package/src/features/utils/instrument-base.js +5 -2
  191. package/src/features/utils/lazy-loader.js +1 -1
  192. package/src/loaders/agent.js +1 -1
  193. package/src/loaders/api/api.js +2 -5
  194. package/src/loaders/api/apiAsync.js +2 -1
  195. package/src/loaders/configure/configure.js +2 -7
  196. package/dist/cjs/common/util/single.js +0 -23
  197. package/dist/cjs/common/window/session-storage.js +0 -87
  198. package/dist/cjs/features/utils/aggregate-base.js +0 -13
  199. package/dist/esm/common/util/single.js +0 -16
  200. package/dist/esm/common/window/session-storage.js +0 -77
  201. package/dist/esm/features/utils/aggregate-base.js +0 -6
  202. package/dist/types/common/util/single.d.ts +0 -2
  203. package/dist/types/common/util/single.d.ts.map +0 -1
  204. package/dist/types/common/window/session-storage.d.ts +0 -18
  205. package/dist/types/common/window/session-storage.d.ts.map +0 -1
  206. package/dist/types/features/utils/aggregate-base.d.ts +0 -4
  207. package/dist/types/features/utils/aggregate-base.d.ts.map +0 -1
  208. package/src/common/util/single.js +0 -18
  209. package/src/common/window/session-storage.js +0 -75
  210. package/src/features/utils/aggregate-base.js +0 -7
@@ -0,0 +1,216 @@
1
+ "use strict";
2
+
3
+ var _interactionTimer = require("./interaction-timer");
4
+ jest.useFakeTimers();
5
+ let now;
6
+ beforeEach(() => {
7
+ now = Date.now();
8
+ jest.setSystemTime(now);
9
+ });
10
+ afterEach(() => {
11
+ jest.clearAllMocks();
12
+ });
13
+ describe('constructor', () => {
14
+ test('appropriate properties are set with valid values -- no refresh', () => {
15
+ const timer = new _interactionTimer.InteractionTimer({
16
+ onEnd: jest.fn()
17
+ }, 100);
18
+ const requiredKeys = ['onEnd', 'initialMs', 'startTimestamp', 'timer'];
19
+ expect(requiredKeys.every(rk => !!timer[rk])).toBeTruthy();
20
+ });
21
+ test('appropriate properties are set with valid values -- with refresh', () => {
22
+ const timer = new _interactionTimer.InteractionTimer({
23
+ onEnd: jest.fn()
24
+ }, 100);
25
+ const requiredKeys = ['onEnd', 'refresh', 'initialMs', 'startTimestamp', 'timer'];
26
+ expect(requiredKeys.every(rk => !!timer[rk])).toBeTruthy();
27
+ });
28
+ test('required keys are enforced', () => {
29
+ try {
30
+ new _interactionTimer.InteractionTimer({}, 100);
31
+ } catch (e) {
32
+ expect(e).toEqual(new Error('onEnd handler is required'));
33
+ }
34
+ try {
35
+ new _interactionTimer.InteractionTimer({
36
+ onEnd: jest.fn()
37
+ });
38
+ } catch (e) {
39
+ expect(e).toEqual(new Error('ms duration is required'));
40
+ }
41
+ });
42
+ test('refresh type timers set event listeners', () => {
43
+ // eslint-disable-next-line
44
+ let ee = {
45
+ on: jest.fn().mockImplementation((evt, cb) => {
46
+ cb([{
47
+ type: 'click'
48
+ }]);
49
+ })
50
+ };
51
+ let it = new _interactionTimer.InteractionTimer({
52
+ onEnd: jest.fn(),
53
+ onRefresh: jest.fn(),
54
+ ee
55
+ }, 100);
56
+ // scroll, keypress, click
57
+ expect(ee.on).toHaveBeenCalledTimes(1);
58
+ expect(it.onRefresh).toHaveBeenCalledTimes(1);
59
+
60
+ // eslint-disable-next-line
61
+ ee = {
62
+ on: jest.fn().mockImplementation((evt, cb) => {
63
+ cb([{
64
+ type: 'scroll'
65
+ }]);
66
+ })
67
+ };
68
+ it = new _interactionTimer.InteractionTimer({
69
+ onEnd: jest.fn(),
70
+ onRefresh: jest.fn(),
71
+ ee
72
+ }, 100);
73
+ // scroll, keypress, click
74
+ expect(ee.on).toHaveBeenCalledTimes(1);
75
+ expect(it.onRefresh).toHaveBeenCalledTimes(1);
76
+
77
+ // eslint-disable-next-line
78
+ ee = {
79
+ on: jest.fn().mockImplementation((evt, cb) => {
80
+ cb([{
81
+ type: 'keydown'
82
+ }]);
83
+ })
84
+ };
85
+ it = new _interactionTimer.InteractionTimer({
86
+ onEnd: jest.fn(),
87
+ onRefresh: jest.fn(),
88
+ ee
89
+ }, 100);
90
+ // scroll, keypress, click
91
+ expect(ee.on).toHaveBeenCalledTimes(1);
92
+ expect(it.onRefresh).toHaveBeenCalledTimes(1);
93
+ const aelSpy = jest.spyOn(document, 'addEventListener');
94
+ // eslint-disable-next-line
95
+ ee = {
96
+ on: jest.fn().mockImplementation((evt, cb) => {
97
+ cb([{
98
+ type: 'keydown'
99
+ }]);
100
+ })
101
+ };
102
+ it = new _interactionTimer.InteractionTimer({
103
+ onEnd: jest.fn(),
104
+ onRefresh: jest.fn(),
105
+ ee
106
+ }, 100);
107
+ // visibility change
108
+ expect(aelSpy).toHaveBeenCalledTimes(1);
109
+ });
110
+ });
111
+ describe('create()', () => {
112
+ test('Create sets a timeout that can execute a cb', () => {
113
+ const timer = new _interactionTimer.InteractionTimer({
114
+ onEnd: jest.fn()
115
+ }, 100);
116
+ expect(timer.timer).toBeTruthy();
117
+ expect(timer.onEnd).toHaveBeenCalledTimes(0);
118
+ jest.runOnlyPendingTimers();
119
+ expect(timer.onEnd).toHaveBeenCalledTimes(1);
120
+ });
121
+ test('Create can fallback to use defaults', () => {
122
+ let called = 0;
123
+ const timer1 = new _interactionTimer.InteractionTimer({
124
+ onEnd: jest.fn()
125
+ }, 100);
126
+ timer1.create();
127
+ const timer2 = new _interactionTimer.InteractionTimer({
128
+ onEnd: jest.fn()
129
+ }, 100);
130
+ timer2.create(timer2.onEnd);
131
+ const timer3 = new _interactionTimer.InteractionTimer({
132
+ onEnd: jest.fn()
133
+ }, 100);
134
+ timer3.create(undefined, 100);
135
+ jest.runAllTimers(200);
136
+ expect(timer1.onEnd).toHaveBeenCalledTimes(1);
137
+ expect(timer2.onEnd).toHaveBeenCalledTimes(1);
138
+ expect(timer3.onEnd).toHaveBeenCalledTimes(1);
139
+ });
140
+ });
141
+ describe('refresh()', () => {
142
+ test('refresh prevents the callback from firing', () => {
143
+ const timer = new _interactionTimer.InteractionTimer({
144
+ onEnd: jest.fn(),
145
+ onRefresh: jest.fn()
146
+ }, 100);
147
+ expect(timer.onEnd).toHaveBeenCalledTimes(0);
148
+ jest.advanceTimersByTime(75);
149
+ expect(timer.onEnd).toHaveBeenCalledTimes(0);
150
+ timer.refresh();
151
+ jest.advanceTimersByTime(75);
152
+ expect(timer.onEnd).toHaveBeenCalledTimes(0);
153
+ jest.advanceTimersByTime(100);
154
+ expect(timer.onEnd).toHaveBeenCalledTimes(1);
155
+ });
156
+ test('refresh executes a callback for consumers', () => {
157
+ const timer = new _interactionTimer.InteractionTimer({
158
+ onEnd: jest.fn(),
159
+ onRefresh: jest.fn()
160
+ }, 100);
161
+ timer.refresh();
162
+ expect(timer.onRefresh).toHaveBeenCalledTimes(1);
163
+ });
164
+ });
165
+ describe('pause()', () => {
166
+ test('pause prevents the callback from firing', () => {
167
+ const timer = new _interactionTimer.InteractionTimer({
168
+ onEnd: jest.fn()
169
+ }, 100);
170
+ expect(timer.onEnd).toHaveBeenCalledTimes(0);
171
+ timer.pause();
172
+ jest.advanceTimersByTime(150);
173
+ expect(timer.onEnd).toHaveBeenCalledTimes(0);
174
+ });
175
+ test('pause sets remainingMs timestamp', () => {
176
+ const timer = new _interactionTimer.InteractionTimer({
177
+ onEnd: jest.fn()
178
+ }, 100);
179
+ expect(timer.remainingMs).toEqual(undefined);
180
+ timer.pause();
181
+ expect(timer.remainingMs).toEqual(timer.initialMs - (now - timer.startTimestamp));
182
+ });
183
+ });
184
+ describe('clear()', () => {
185
+ test('clear prevents the callback from firing and deletes the pointer', () => {
186
+ const timer = new _interactionTimer.InteractionTimer({
187
+ onEnd: jest.fn()
188
+ }, 100);
189
+ expect(timer.onEnd).toHaveBeenCalledTimes(0);
190
+ timer.clear();
191
+ jest.advanceTimersByTime(150);
192
+ expect(timer.onEnd).toHaveBeenCalledTimes(0);
193
+ expect(timer.timer).toEqual(null);
194
+ });
195
+ });
196
+ describe('end()', () => {
197
+ test('end clears the callback and calls the onEnd callback', () => {
198
+ const timer = new _interactionTimer.InteractionTimer({
199
+ onEnd: jest.fn()
200
+ }, 100);
201
+ expect(timer.onEnd).toHaveBeenCalledTimes(0);
202
+ timer.end();
203
+ expect(timer.onEnd).toHaveBeenCalledTimes(1);
204
+ expect(timer.timer).toEqual(null);
205
+ });
206
+ });
207
+ describe('isValid', () => {
208
+ test('isValid validates timeStamps', () => {
209
+ const timer = new _interactionTimer.InteractionTimer({
210
+ onEnd: jest.fn()
211
+ }, 100);
212
+ expect(timer.isValid()).toEqual(true);
213
+ timer.startTimestamp -= 100;
214
+ expect(timer.isValid()).toEqual(false);
215
+ });
216
+ });
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.Timer = void 0;
7
+ class Timer {
8
+ constructor(opts, ms) {
9
+ if (!opts.onEnd) throw new Error('onEnd handler is required');
10
+ if (!ms) throw new Error('ms duration is required');
11
+ this.onEnd = opts.onEnd;
12
+ this.initialMs = ms;
13
+ this.startTimestamp = Date.now();
14
+ this.timer = this.create(this.onEnd, ms);
15
+ }
16
+ create(cb, ms) {
17
+ if (this.timer) this.clear();
18
+ return setTimeout(() => cb ? cb() : this.onEnd(), ms || this.initialMs);
19
+ }
20
+ clear() {
21
+ clearTimeout(this.timer);
22
+ this.timer = null;
23
+ }
24
+ end() {
25
+ this.clear();
26
+ this.onEnd();
27
+ }
28
+ isValid() {
29
+ return this.initialMs - (Date.now() - this.startTimestamp) > 0;
30
+ }
31
+ }
32
+ exports.Timer = Timer;
@@ -0,0 +1,105 @@
1
+ "use strict";
2
+
3
+ var _timer = require("./timer");
4
+ jest.useFakeTimers();
5
+ let now;
6
+ beforeEach(() => {
7
+ now = Date.now();
8
+ jest.setSystemTime(now);
9
+ });
10
+ afterEach(() => {
11
+ jest.clearAllMocks();
12
+ });
13
+ describe('constructor', () => {
14
+ test('appropriate properties are set with valid values -- no refresh', () => {
15
+ const timer = new _timer.Timer({
16
+ onEnd: jest.fn()
17
+ }, 100);
18
+ const requiredKeys = ['onEnd', 'initialMs', 'startTimestamp', 'timer'];
19
+ expect(requiredKeys.every(rk => !!timer[rk])).toBeTruthy();
20
+ });
21
+ test('appropriate properties are set with valid values -- with refresh', () => {
22
+ const timer = new _timer.Timer({
23
+ onEnd: jest.fn()
24
+ }, 100);
25
+ const requiredKeys = ['onEnd', 'initialMs', 'startTimestamp', 'timer'];
26
+ expect(requiredKeys.every(rk => !!timer[rk])).toBeTruthy();
27
+ });
28
+ test('required keys are enforced', () => {
29
+ try {
30
+ new _timer.Timer({}, 100);
31
+ } catch (e) {
32
+ expect(e).toEqual(new Error('onEnd handler is required'));
33
+ }
34
+ try {
35
+ new _timer.Timer({
36
+ onEnd: jest.fn()
37
+ });
38
+ } catch (e) {
39
+ expect(e).toEqual(new Error('ms duration is required'));
40
+ }
41
+ });
42
+ });
43
+ describe('create()', () => {
44
+ test('Create sets a timeout that can execute a cb', () => {
45
+ const timer = new _timer.Timer({
46
+ onEnd: jest.fn()
47
+ }, 100);
48
+ expect(timer.timer).toBeTruthy();
49
+ expect(timer.onEnd).toHaveBeenCalledTimes(0);
50
+ jest.runOnlyPendingTimers();
51
+ expect(timer.onEnd).toHaveBeenCalledTimes(1);
52
+ });
53
+ test('Create can fallback to use defaults', () => {
54
+ let called = 0;
55
+ const timer1 = new _timer.Timer({
56
+ onEnd: jest.fn()
57
+ }, 100);
58
+ timer1.create();
59
+ const timer2 = new _timer.Timer({
60
+ onEnd: jest.fn()
61
+ }, 100);
62
+ timer2.create(timer2.onEnd);
63
+ const timer3 = new _timer.Timer({
64
+ onEnd: jest.fn()
65
+ }, 100);
66
+ timer3.create(undefined, 100);
67
+ jest.runAllTimers(200);
68
+ expect(timer1.onEnd).toHaveBeenCalledTimes(1);
69
+ expect(timer2.onEnd).toHaveBeenCalledTimes(1);
70
+ expect(timer3.onEnd).toHaveBeenCalledTimes(1);
71
+ });
72
+ });
73
+ describe('clear()', () => {
74
+ test('clear prevents the callback from firing and deletes the pointer', () => {
75
+ const timer = new _timer.Timer({
76
+ onEnd: jest.fn()
77
+ }, 100);
78
+ expect(timer.onEnd).toHaveBeenCalledTimes(0);
79
+ timer.clear();
80
+ jest.advanceTimersByTime(150);
81
+ expect(timer.onEnd).toHaveBeenCalledTimes(0);
82
+ expect(timer.timer).toEqual(null);
83
+ });
84
+ });
85
+ describe('end()', () => {
86
+ test('end clears the callback and calls the onEnd callback', () => {
87
+ const timer = new _timer.Timer({
88
+ onEnd: jest.fn()
89
+ }, 100);
90
+ expect(timer.onEnd).toHaveBeenCalledTimes(0);
91
+ timer.end();
92
+ expect(timer.onEnd).toHaveBeenCalledTimes(1);
93
+ expect(timer.timer).toEqual(null);
94
+ });
95
+ });
96
+ describe('isValid', () => {
97
+ test('isValid validates timeStamps', () => {
98
+ const timer = new _timer.Timer({
99
+ onEnd: jest.fn()
100
+ }, 100);
101
+ expect(timer.isValid()).toEqual(true);
102
+ timer.startTimestamp -= 100;
103
+ expect(timer.isValid()).toEqual(false);
104
+ });
105
+ });
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.subscribeToEOL = subscribeToEOL;
7
7
  var _firefoxVersion = require("../browser-version/firefox-version");
8
8
  var _eventListenerOpts = require("../event-listener/event-listener-opts");
9
- var _single = require("../util/single");
9
+ var _invoke = require("../util/invoke");
10
10
  var _globalScope = require("../util/global-scope");
11
11
  var _pageVisibility = require("../window/page-visibility");
12
12
  /*
@@ -40,7 +40,7 @@ function subscribeToEOL(cb, allowBFCache) {
40
40
  (0, _eventListenerOpts.windowAddEventListener)('pagehide', cb); // when user navigates away, and because safari iOS v14.4- doesn't fully support vis change
41
41
  // --this ought to be removed once support for version below 14.5 phases out
42
42
  } else {
43
- var oneCall = (0, _single.single)(cb);
43
+ var oneCall = (0, _invoke.single)(cb);
44
44
 
45
45
  // Firefox has a bug wherein a slow-loading resource loaded from the 'pagehide'
46
46
  // or 'unload' event will delay the 'load' event firing on the next page load.
@@ -10,6 +10,12 @@ var _stringify = require("./stringify");
10
10
  * SPDX-License-Identifier: Apache-2.0
11
11
  */
12
12
 
13
+ /**
14
+ * Returns the size of the provided data. Designed for measuring XHR responses.
15
+ *
16
+ * @param {*} data - The data to be measured.
17
+ * @returns {(number|undefined)} - The size of the data or undefined if size cannot be determined.
18
+ */
13
19
  function dataSize(data) {
14
20
  if (typeof data === 'string' && data.length) return data.length;
15
21
  if (typeof data !== 'object') return undefined;
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+
3
+ var _dataSize = require("./data-size");
4
+ describe('dataSize', () => {
5
+ test('returns length of string', () => {
6
+ const str = 'Hello, world!';
7
+ expect((0, _dataSize.dataSize)(str)).toBe(str.length);
8
+ });
9
+ test('returns undefined for non-object, number, or empty string', () => {
10
+ expect((0, _dataSize.dataSize)(Infinity)).toBeUndefined();
11
+ expect((0, _dataSize.dataSize)(12345)).toBeUndefined(); // might not actually be by design, but this is how it works today
12
+ expect((0, _dataSize.dataSize)('')).toBeUndefined();
13
+ });
14
+ test('returns byte length of ArrayBuffer object', () => {
15
+ const buffer = new ArrayBuffer(8);
16
+ expect((0, _dataSize.dataSize)(buffer)).toBe(8);
17
+ });
18
+ test('returns size of Blob object', () => {
19
+ const blob = new Blob(['Hello, world!'], {
20
+ type: 'text/plain'
21
+ });
22
+ expect((0, _dataSize.dataSize)(blob)).toBe(blob.size);
23
+ });
24
+ test('returns undefined for FormData object', () => {
25
+ const formData = new FormData();
26
+ expect((0, _dataSize.dataSize)(formData)).toBeUndefined();
27
+ });
28
+ test('returns length of JSON string representation of object', () => {
29
+ const obj = {
30
+ str: 'Hello, world!',
31
+ num: 12345,
32
+ nestedObj: {
33
+ arr: [1, 2, 3]
34
+ }
35
+ };
36
+ const expectedSize = JSON.stringify(obj).length;
37
+ expect((0, _dataSize.dataSize)(obj)).toBe(expectedSize);
38
+ });
39
+ test('returns undefined for object with toJSON method that throws an error', () => {
40
+ const obj = {
41
+ toJSON: () => {
42
+ throw new Error('Error in toJSON');
43
+ }
44
+ };
45
+ expect((0, _dataSize.dataSize)(obj)).toBeUndefined();
46
+ });
47
+ });
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.debounce = debounce;
7
+ exports.single = single;
8
+ /**
9
+ * Reduce the invocation of the supplied function so that it is only invoked
10
+ * once within a given timeout.
11
+ *
12
+ * If `wait` is `0`, the function will be invoked during the next tick.
13
+ * If `options.leading` is false or not provided, the function will be invoked
14
+ * N milliseconds after the last invocation of the returned function where
15
+ * N is the `timeout` value.
16
+ * If `options.leading` is true, the function will be invoked immediately upon
17
+ * the first invocation of the returned function and not again for N milliseconds
18
+ * where N is the `timeout` value.
19
+ * @param {function} func Function whose invocation should be limited so it is only invoked
20
+ * once within a given timeout period.
21
+ * @param {number} timeout Time in milliseconds that the function should only be invoked
22
+ * once within.
23
+ * @param {object} options Debounce options
24
+ * @param {boolean} options.leading Forces the function to be invoked on the first
25
+ * invocation of the returned function instead of N milliseconds after the last
26
+ * invocation.
27
+ * @returns {function} A wrapping function that will ensure the provided function
28
+ * is invoked only once within the given timeout.
29
+ */
30
+ function debounce(func) {
31
+ var _this = this;
32
+ let timeout = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 500;
33
+ let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
34
+ const leading = options?.leading || false;
35
+ let timer;
36
+ return function () {
37
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
38
+ args[_key] = arguments[_key];
39
+ }
40
+ if (leading && timer === undefined) {
41
+ func.apply(_this, args);
42
+ timer = setTimeout(() => timer = clearTimeout(timer), timeout);
43
+ }
44
+ if (!leading) {
45
+ clearTimeout(timer);
46
+ timer = setTimeout(() => {
47
+ func.apply(_this, args);
48
+ }, timeout);
49
+ }
50
+ };
51
+ }
52
+
53
+ /**
54
+ * Reduce the invocation of the supplied function so that it is only invoked
55
+ * once.
56
+ * @param {function} func Function whose invocation should be limited so it is only invoked
57
+ * once.
58
+ * @returns {function} A wrapping function that will ensure the provided function
59
+ * is invoked only once.
60
+ */
61
+ function single(func) {
62
+ var _this2 = this;
63
+ let called = false;
64
+ return function () {
65
+ if (!called) {
66
+ called = true;
67
+ for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
68
+ args[_key2] = arguments[_key2];
69
+ }
70
+ func.apply(_this2, args);
71
+ }
72
+ };
73
+ }
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+
3
+ var _invoke = require("./invoke");
4
+ jest.useFakeTimers();
5
+ describe('debounce', () => {
6
+ test('should run the supplied function after 100ms', () => {
7
+ let mockCallback = jest.fn();
8
+ let debouncedMethod = (0, _invoke.debounce)(mockCallback, 100);
9
+ execFnTimes(debouncedMethod, 100);
10
+ expect(mockCallback).not.toHaveBeenCalled();
11
+ jest.advanceTimersByTime(1000);
12
+ expect(mockCallback).toHaveBeenCalledTimes(1);
13
+ });
14
+ test('should rerun the supplied function when called again after 100ms', () => {
15
+ let mockCallback = jest.fn();
16
+ let debouncedMethod = (0, _invoke.debounce)(mockCallback, 100);
17
+ execFnTimes(debouncedMethod, 100);
18
+ jest.advanceTimersByTime(200);
19
+ execFnTimes(debouncedMethod, 100);
20
+ jest.advanceTimersByTime(2000);
21
+ expect(mockCallback).toHaveBeenCalledTimes(2);
22
+ });
23
+ test('should run the supplied function on the first event and debounce subsequent events', () => {
24
+ let mockCallback = jest.fn();
25
+ let debouncedMethod = (0, _invoke.debounce)(mockCallback, 100, {
26
+ leading: true
27
+ });
28
+ execFnTimes(debouncedMethod, 100);
29
+ expect(mockCallback).toHaveBeenCalledTimes(1);
30
+ jest.advanceTimersByTime(200);
31
+ expect(mockCallback).toHaveBeenCalledTimes(1);
32
+ execFnTimes(debouncedMethod, 100);
33
+ jest.advanceTimersByTime(200);
34
+ expect(mockCallback).toHaveBeenCalledTimes(2);
35
+ });
36
+ });
37
+ describe('single', () => {
38
+ test('should run the supplied function only once', () => {
39
+ let mockCallback = jest.fn();
40
+ let singleMethod = (0, _invoke.single)(mockCallback, 100);
41
+ execFnTimes(singleMethod, 100);
42
+ expect(mockCallback).toHaveBeenCalledTimes(1);
43
+ });
44
+ });
45
+ function execFnTimes(fn, count) {
46
+ for (let i = 0; i < count; i++) {
47
+ fn();
48
+ }
49
+ }
@@ -15,10 +15,6 @@ var fileProtocolRule = {
15
15
  replacement: 'file://OBFUSCATED'
16
16
  };
17
17
  class Obfuscator extends _sharedContext.SharedContext {
18
- constructor(parent) {
19
- super(parent); // gets any allowed properties from the parent and stores them in `sharedContext`
20
- }
21
-
22
18
  shouldObfuscate() {
23
19
  return getRules(this.sharedContext.agentIdentifier).length > 0;
24
20
  }
@@ -17,7 +17,9 @@ var _eventListenerOpts = require("../event-listener/event-listener-opts");
17
17
  */
18
18
  function subscribeToVisibilityChange(cb) {
19
19
  let toHiddenOnly = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
20
- (0, _eventListenerOpts.documentAddEventListener)('visibilitychange', handleVisibilityChange);
20
+ let capture = arguments.length > 2 ? arguments[2] : undefined;
21
+ let abortSignal = arguments.length > 3 ? arguments[3] : undefined;
22
+ (0, _eventListenerOpts.documentAddEventListener)('visibilitychange', handleVisibilityChange, capture, abortSignal);
21
23
  return;
22
24
  function handleVisibilityChange() {
23
25
  if (toHiddenOnly) {
@@ -32,7 +32,7 @@ const TIMER_FNS = [SET_TIMEOUT, 'setImmediate', SET_INTERVAL, CLEAR_TIMEOUT, 'cl
32
32
  * @param {Object} sharedEE - The shared event emitter on which a new scoped event emitter will be based.
33
33
  * @returns {Object} Scoped event emitter with a debug ID of `timer`.
34
34
  */
35
- //eslint-disable-next-line
35
+ // eslint-disable-next-line
36
36
  function wrapTimer(sharedEE) {
37
37
  const ee = scopedEE(sharedEE);
38
38
 
@@ -11,17 +11,17 @@ var _handle = require("../../../common/event-emitter/handle");
11
11
  var _config = require("../../../common/config/config");
12
12
  var _harvestScheduler = require("../../../common/harvest/harvest-scheduler");
13
13
  var _denyList = require("../../../common/deny-list/deny-list");
14
- var _aggregateBase = require("../../utils/aggregate-base");
15
14
  var _constants = require("../constants");
16
15
  var _drain = require("../../../common/drain/drain");
17
16
  var _features = require("../../../loaders/features/features");
18
17
  var _constants2 = require("../../metrics/constants");
18
+ var _featureBase = require("../../utils/feature-base");
19
19
  /*
20
20
  * Copyright 2020 New Relic Corporation. All rights reserved.
21
21
  * SPDX-License-Identifier: Apache-2.0
22
22
  */
23
23
 
24
- class Aggregate extends _aggregateBase.AggregateBase {
24
+ class Aggregate extends _featureBase.FeatureBase {
25
25
  static featureName = _constants.FEATURE_NAME;
26
26
  constructor(agentIdentifier, aggregator) {
27
27
  super(agentIdentifier, aggregator, _constants.FEATURE_NAME);
@@ -17,16 +17,16 @@ var _mapOwn = require("../../../common/util/map-own");
17
17
  var _config = require("../../../common/config/config");
18
18
  var _now = require("../../../common/timing/now");
19
19
  var _globalScope = require("../../../common/util/global-scope");
20
- var _aggregateBase = require("../../utils/aggregate-base");
21
20
  var _constants = require("../constants");
22
21
  var _drain = require("../../../common/drain/drain");
23
22
  var _features = require("../../../loaders/features/features");
23
+ var _featureBase = require("../../utils/feature-base");
24
24
  /*
25
25
  * Copyright 2020 New Relic Corporation. All rights reserved.
26
26
  * SPDX-License-Identifier: Apache-2.0
27
27
  */
28
28
 
29
- class Aggregate extends _aggregateBase.AggregateBase {
29
+ class Aggregate extends _featureBase.FeatureBase {
30
30
  static featureName = _constants.FEATURE_NAME;
31
31
  constructor(agentIdentifier, aggregator) {
32
32
  var _this;
@@ -216,6 +216,7 @@ class Aggregate extends _aggregateBase.AggregateBase {
216
216
 
217
217
  // still send EE events for other features such as above, but stop this one from aggregating internal data
218
218
  if (this.blocked) return;
219
+ var att = (0, _config.getInfo)(this.agentIdentifier).jsAttributes;
219
220
  if (params._interactionId != null) {
220
221
  // hold on to the error until the interaction finishes
221
222
  this.errorCache[params._interactionId] = this.errorCache[params._interactionId] || [];
@@ -223,7 +224,6 @@ class Aggregate extends _aggregateBase.AggregateBase {
223
224
  } else {
224
225
  // store custom attributes
225
226
  var customParams = {};
226
- var att = (0, _config.getInfo)(this.agentIdentifier).jsAttributes;
227
227
  (0, _mapOwn.mapOwn)(att, setCustom);
228
228
  if (customAttributes) {
229
229
  (0, _mapOwn.mapOwn)(customAttributes, setCustom);