@dynatrace/rum-javascript-sdk 1.333.15 → 1.337.1
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/api/index.d.ts +16 -0
- package/dist/api/index.js +25 -1
- package/dist/api/interactions.d.ts +25 -0
- package/dist/api/interactions.js +51 -0
- package/dist/api/promises/index.d.ts +23 -0
- package/dist/api/promises/index.js +36 -7
- package/dist/api/promises/interactions.d.ts +18 -0
- package/dist/api/promises/interactions.js +22 -0
- package/dist/api/promises/wait-for-interactions.d.ts +9 -0
- package/dist/api/promises/wait-for-interactions.js +18 -0
- package/dist/api/user-actions.d.ts +5 -5
- package/dist/api/user-actions.js +6 -6
- package/dist/testing/index.d.ts +3 -1
- package/dist/testing/index.js +1 -1
- package/dist/testing/install.js +1 -1
- package/dist/testing/test.d.ts +1 -119
- package/dist/testing/test.js +12 -11
- package/dist/testing/types/dynatrace-config.d.ts +36 -0
- package/dist/testing/types/dynatrace-config.js +2 -0
- package/dist/testing/types/dynatrace-testing-fixtures.d.ts +24 -0
- package/dist/testing/types/dynatrace-testing-fixtures.js +2 -0
- package/dist/testing/types/dynatrace-testing.d.ts +66 -0
- package/dist/testing/types/dynatrace-testing.js +2 -0
- package/dist/types/api/dynatrace-api-types.d.ts +126 -24
- package/dist/types/api/dynatrace-api-types.js +1 -1
- package/dist/types/index-typedoc.d.ts +1 -0
- package/dist/types/index-typedoc.js +2 -1
- package/dist/types/rum-events/index.d.ts +1 -0
- package/dist/types/rum-events/index.js +2 -1
- package/dist/types/rum-events/json-event.d.ts +0 -6
- package/dist/types/rum-events/json-event.js +1 -1
- package/dist/types/rum-events/open-fields.d.ts +74 -0
- package/dist/types/rum-events/open-fields.js +84 -0
- package/dist/types/rum-events/rum-internal-selfmonitoring-event.d.ts +21 -1
- package/dist/types/rum-events/rum-internal-selfmonitoring-event.js +21 -1
- package/dist/types/rum-events/rum-user-interaction-event.d.ts +47 -0
- package/dist/types/rum-events/rum-user-interaction-event.js +43 -1
- package/dist/types/rum-events/shared-namespaces-and-fields/general-rum-event-fields.d.ts +3 -2
- package/dist/types/rum-events/shared-namespaces-and-fields/general-rum-event-fields.js +1 -1
- package/dist/types/user-actions/user-action-start-options.d.ts +13 -0
- package/dist/types/user-actions/user-action-start-options.js +1 -1
- package/dist/types/user-actions/user-action-tracker.d.ts +35 -3
- package/dist/types/user-actions/user-action-tracker.js +1 -1
- package/docs/1-overview.md +95 -0
- package/docs/2-testing.md +3 -3
- package/docs/3-types.md +1 -0
- package/docs/4-useractions.md +94 -76
- package/docs/5-interactions.md +85 -0
- package/package.json +24 -8
package/docs/4-useractions.md
CHANGED
|
@@ -11,12 +11,24 @@ The User Actions API provides fine-grained control over user action creation and
|
|
|
11
11
|
The User Actions API is experimental and may change in future releases. The `dynatrace.userActions` property is `undefined` if the User Actions module is disabled.
|
|
12
12
|
:::
|
|
13
13
|
|
|
14
|
+
:::caution Deprecated names
|
|
15
|
+
The following API names have been renamed to align with the Mobile agent API. The old names continue to work but are deprecated and will be removed with version 341:
|
|
16
|
+
|
|
17
|
+
| Deprecated | Replacement |
|
|
18
|
+
|------------|-------------|
|
|
19
|
+
| `finish()` | `complete()` |
|
|
20
|
+
| `autoClose` | `completeAutomatically` |
|
|
21
|
+
| `name` | `customName` |
|
|
22
|
+
|
|
23
|
+
The same applies to `UserActionStartOptions`: use `completeAutomatically` instead of `autoClose` and `customName` instead of `name`. If both old and new names are provided, the **new name takes precedence**.
|
|
24
|
+
:::
|
|
25
|
+
|
|
14
26
|
## What you can do
|
|
15
27
|
|
|
16
28
|
With the User Actions API, you can:
|
|
17
29
|
|
|
18
30
|
- **Create** custom user actions to track specific workflows
|
|
19
|
-
- **Control** when user actions start and
|
|
31
|
+
- **Control** when user actions start and complete
|
|
20
32
|
- **Customize** user action names for better identification
|
|
21
33
|
- **Attach** custom properties to capture business context
|
|
22
34
|
- **Adjust** timing by setting the start time
|
|
@@ -51,7 +63,7 @@ User actions can complete for various reasons, indicated by the `user_action.com
|
|
|
51
63
|
|
|
52
64
|
- **`completed`** - The user action completed normally after the inactivity threshold was reached. This occurs when Dynatrace detects no more activity (DOM mutations, requests, etc.) related to the user interaction.
|
|
53
65
|
|
|
54
|
-
- **`completed_by_api`** - The user action was completed explicitly by calling the `
|
|
66
|
+
- **`completed_by_api`** - The user action was completed explicitly by calling the `complete()` function through the API.
|
|
55
67
|
|
|
56
68
|
- **`interrupted_by_api`** - The user action was interrupted when a new user action was created via the API using `create()`.
|
|
57
69
|
|
|
@@ -75,7 +87,7 @@ Access the API directly through the global `dynatrace.userActions` namespace:
|
|
|
75
87
|
|
|
76
88
|
```typescript
|
|
77
89
|
const userAction = dynatrace?.userActions?.create();
|
|
78
|
-
userAction?.
|
|
90
|
+
userAction?.complete();
|
|
79
91
|
```
|
|
80
92
|
|
|
81
93
|
This approach requires optional chaining (`?.`) to handle cases where RUM JavaScript or the module is not loaded.
|
|
@@ -87,9 +99,9 @@ Use the safe wrapper functions from `@dynatrace/rum-javascript-sdk/api` that gra
|
|
|
87
99
|
```typescript
|
|
88
100
|
import { create } from '@dynatrace/rum-javascript-sdk/api/user-actions';
|
|
89
101
|
|
|
90
|
-
const userAction = create({
|
|
102
|
+
const userAction = create({ completeAutomatically: false });
|
|
91
103
|
// No need for optional chaining - returns undefined if module is unavailable
|
|
92
|
-
userAction?.
|
|
104
|
+
userAction?.complete();
|
|
93
105
|
```
|
|
94
106
|
|
|
95
107
|
### Async API
|
|
@@ -100,9 +112,9 @@ Use the promise-based API from `@dynatrace/rum-javascript-sdk/api/promises` when
|
|
|
100
112
|
import { create } from '@dynatrace/rum-javascript-sdk/api/promises/user-actions';
|
|
101
113
|
|
|
102
114
|
try {
|
|
103
|
-
const userAction = await create({
|
|
115
|
+
const userAction = await create({ completeAutomatically: false });
|
|
104
116
|
// Guaranteed to have a user action or will throw
|
|
105
|
-
userAction.
|
|
117
|
+
userAction.complete();
|
|
106
118
|
} catch (error) {
|
|
107
119
|
console.error('User Actions module not available:', error);
|
|
108
120
|
}
|
|
@@ -118,7 +130,7 @@ You can create custom user actions to track specific interactions or workflows i
|
|
|
118
130
|
|
|
119
131
|
### Basic user action
|
|
120
132
|
|
|
121
|
-
Create a simple user action and
|
|
133
|
+
Create a simple user action and complete it manually:
|
|
122
134
|
|
|
123
135
|
```typescript
|
|
124
136
|
// Create a new user action with default settings
|
|
@@ -127,16 +139,16 @@ const userAction = dynatrace.userActions?.create();
|
|
|
127
139
|
// Perform your application logic here
|
|
128
140
|
performSomeWork();
|
|
129
141
|
|
|
130
|
-
// Manually
|
|
131
|
-
userAction?.
|
|
142
|
+
// Manually complete the user action
|
|
143
|
+
userAction?.complete();
|
|
132
144
|
```
|
|
133
145
|
|
|
134
146
|
By default, user actions are automatically closed when Dynatrace detects that the action is complete according to the RUM JavaScript user action [rules](#rules).
|
|
135
147
|
|
|
136
148
|
:::caution
|
|
137
|
-
Calling `
|
|
138
|
-
guarantee that the action would still be open when `
|
|
139
|
-
|
|
149
|
+
Calling `complete()` is reliable in this case because `performSomeWork()` is synchronous. If it was awaited, there is no
|
|
150
|
+
guarantee that the action would still be open when `complete()` is called, leading to unreliable action durations. See
|
|
151
|
+
[User action with manual control](#user-action-with-manual-control) below.
|
|
140
152
|
:::
|
|
141
153
|
|
|
142
154
|
### User action with manual control
|
|
@@ -144,19 +156,19 @@ guarantee that the action would still be open when `finish()` is called, leading
|
|
|
144
156
|
Disable automatic closing to maintain full control over when the user action completes:
|
|
145
157
|
|
|
146
158
|
```typescript
|
|
147
|
-
// Create a user action that won't auto-
|
|
148
|
-
const userAction = dynatrace.userActions?.create({
|
|
159
|
+
// Create a user action that won't auto-complete
|
|
160
|
+
const userAction = dynatrace.userActions?.create({ completeAutomatically: false });
|
|
149
161
|
|
|
150
162
|
// Execute async operations
|
|
151
163
|
await fetchData();
|
|
152
164
|
await processResults();
|
|
153
165
|
|
|
154
|
-
//
|
|
155
|
-
userAction?.
|
|
166
|
+
// Complete the user action when ready
|
|
167
|
+
userAction?.complete();
|
|
156
168
|
```
|
|
157
169
|
|
|
158
170
|
:::warning
|
|
159
|
-
When `
|
|
171
|
+
When `completeAutomatically` is set to `false`, you must call `complete()` manually. Otherwise, the user action will remain open until the next user action is created or the maximum duration is reached, which may lead to incorrect timing measurements.
|
|
160
172
|
:::
|
|
161
173
|
|
|
162
174
|
### Track user action completion
|
|
@@ -164,19 +176,19 @@ When `autoClose` is set to `false`, you must call `finish()` manually. Otherwise
|
|
|
164
176
|
Subscribe to user action completion events to understand when actions would have been completed automatically:
|
|
165
177
|
|
|
166
178
|
```typescript
|
|
167
|
-
const userAction = dynatrace.userActions?.create({
|
|
179
|
+
const userAction = dynatrace.userActions?.create({ completeAutomatically: false });
|
|
168
180
|
|
|
169
181
|
// Subscribe to completion events
|
|
170
182
|
const unsubscribe = userAction?.subscribe(currentUserAction => {
|
|
171
|
-
// This is just an informational log - we intentionally ignore automatic closing. We
|
|
183
|
+
// This is just an informational log - we intentionally ignore automatic closing. We complete the user action manually later on.
|
|
172
184
|
console.log(`User action would have been completed automatically`);
|
|
173
185
|
});
|
|
174
186
|
|
|
175
187
|
// Perform your operations
|
|
176
188
|
await router.navigate('/home');
|
|
177
189
|
|
|
178
|
-
//
|
|
179
|
-
userAction?.
|
|
190
|
+
// Complete the user action
|
|
191
|
+
userAction?.complete();
|
|
180
192
|
|
|
181
193
|
// Clean up the subscription when done
|
|
182
194
|
unsubscribe?.();
|
|
@@ -187,17 +199,17 @@ unsubscribe?.();
|
|
|
187
199
|
Set a custom name for your user action to make it more identifiable in Dynatrace:
|
|
188
200
|
|
|
189
201
|
```typescript
|
|
190
|
-
const userAction = dynatrace.userActions?.create({
|
|
202
|
+
const userAction = dynatrace.userActions?.create({ completeAutomatically: false });
|
|
191
203
|
|
|
192
204
|
// Set a descriptive name
|
|
193
205
|
if (userAction) {
|
|
194
|
-
userAction.
|
|
206
|
+
userAction.customName = 'Checkout Flow - Payment Processing';
|
|
195
207
|
}
|
|
196
208
|
|
|
197
209
|
// Perform payment processing
|
|
198
210
|
await processPayment();
|
|
199
211
|
|
|
200
|
-
userAction?.
|
|
212
|
+
userAction?.complete();
|
|
201
213
|
```
|
|
202
214
|
|
|
203
215
|
### Add custom properties
|
|
@@ -286,14 +298,14 @@ Change how user actions behave by modifying their properties:
|
|
|
286
298
|
```typescript
|
|
287
299
|
dynatrace.userActions?.subscribe(userAction => {
|
|
288
300
|
// Disable automatic completion for all user actions
|
|
289
|
-
userAction.
|
|
301
|
+
userAction.completeAutomatically = false;
|
|
290
302
|
|
|
291
303
|
// Perform custom logic
|
|
292
304
|
performCustomTracking(userAction);
|
|
293
305
|
|
|
294
306
|
// Manually control completion
|
|
295
307
|
setTimeout(() => {
|
|
296
|
-
userAction.
|
|
308
|
+
userAction.complete();
|
|
297
309
|
}, 5000);
|
|
298
310
|
});
|
|
299
311
|
```
|
|
@@ -305,18 +317,18 @@ Apply different behavior based on the user action context:
|
|
|
305
317
|
```typescript
|
|
306
318
|
dynatrace.userActions?.subscribe(userAction => {
|
|
307
319
|
// Only modify actions with name Add to Cart
|
|
308
|
-
if (userAction.
|
|
309
|
-
userAction.
|
|
320
|
+
if (userAction.customName === 'Add to Cart') {
|
|
321
|
+
userAction.completeAutomatically = false;
|
|
310
322
|
|
|
311
323
|
// Add custom completion logic
|
|
312
324
|
whenCustomConditionMet().then(() => {
|
|
313
|
-
userAction.
|
|
325
|
+
userAction.complete();
|
|
314
326
|
});
|
|
315
327
|
}
|
|
316
328
|
});
|
|
317
329
|
|
|
318
330
|
// some time later
|
|
319
|
-
dynatrace.userActions?.create({
|
|
331
|
+
dynatrace.userActions?.create({ customName: "Add to Cart"});
|
|
320
332
|
```
|
|
321
333
|
|
|
322
334
|
## Disable automatic detection
|
|
@@ -331,13 +343,13 @@ dynatrace.userActions?.setAutomaticDetection(false);
|
|
|
331
343
|
|
|
332
344
|
// Now you have full control over user action creation
|
|
333
345
|
async function handleNavigation(route) {
|
|
334
|
-
const userAction = dynatrace.userActions?.create({
|
|
346
|
+
const userAction = dynatrace.userActions?.create({ completeAutomatically: false });
|
|
335
347
|
|
|
336
348
|
// Navigate without triggering automatic user action
|
|
337
349
|
await router.navigate(route);
|
|
338
350
|
|
|
339
|
-
// Manually
|
|
340
|
-
userAction?.
|
|
351
|
+
// Manually complete when ready
|
|
352
|
+
userAction?.complete();
|
|
341
353
|
}
|
|
342
354
|
```
|
|
343
355
|
|
|
@@ -364,14 +376,14 @@ async function postMessage(message, channel) {
|
|
|
364
376
|
|
|
365
377
|
if (currentUserAction) {
|
|
366
378
|
// Prevent automatic completion
|
|
367
|
-
currentUserAction.
|
|
379
|
+
currentUserAction.completeAutomatically = false;
|
|
368
380
|
}
|
|
369
381
|
|
|
370
382
|
// Perform async operation
|
|
371
383
|
const response = await channel.send(message);
|
|
372
384
|
|
|
373
|
-
// Manually
|
|
374
|
-
currentUserAction?.
|
|
385
|
+
// Manually complete the user action
|
|
386
|
+
currentUserAction?.complete();
|
|
375
387
|
|
|
376
388
|
return response;
|
|
377
389
|
}
|
|
@@ -390,13 +402,13 @@ document.addEventListener('click', async (event) => {
|
|
|
390
402
|
const target = event.target as HTMLElement;
|
|
391
403
|
|
|
392
404
|
if (target.matches('[data-navigate]')) {
|
|
393
|
-
const userAction = dynatrace.userActions?.create({
|
|
405
|
+
const userAction = dynatrace.userActions?.create({ completeAutomatically: false });
|
|
394
406
|
|
|
395
407
|
const route = target.getAttribute('data-navigate');
|
|
396
408
|
|
|
397
409
|
// Set custom name and properties
|
|
398
410
|
if (userAction) {
|
|
399
|
-
userAction.
|
|
411
|
+
userAction.customName = `Navigate to ${route}`;
|
|
400
412
|
userAction.event_properties = {
|
|
401
413
|
'event_properties.target_route': route,
|
|
402
414
|
'event_properties.navigation_trigger': 'click'
|
|
@@ -409,8 +421,8 @@ document.addEventListener('click', async (event) => {
|
|
|
409
421
|
// Wait for the route to fully load
|
|
410
422
|
await waitForRouteReady();
|
|
411
423
|
|
|
412
|
-
// Now
|
|
413
|
-
userAction?.
|
|
424
|
+
// Now complete the user action
|
|
425
|
+
userAction?.complete();
|
|
414
426
|
}
|
|
415
427
|
});
|
|
416
428
|
```
|
|
@@ -422,11 +434,11 @@ Create a user action that spans multiple asynchronous operations:
|
|
|
422
434
|
```typescript
|
|
423
435
|
async function handleComplexWorkflow(workflowId: string, priority: string) {
|
|
424
436
|
const startTime = Date.now();
|
|
425
|
-
const userAction = dynatrace.userActions?.create({
|
|
437
|
+
const userAction = dynatrace.userActions?.create({ completeAutomatically: false });
|
|
426
438
|
|
|
427
439
|
if (userAction) {
|
|
428
440
|
// Set up user action metadata
|
|
429
|
-
userAction.
|
|
441
|
+
userAction.customName = 'Complex Data Workflow';
|
|
430
442
|
userAction.startTime = startTime;
|
|
431
443
|
userAction.event_properties = {
|
|
432
444
|
'event_properties.workflow_id': workflowId,
|
|
@@ -486,7 +498,7 @@ async function handleComplexWorkflow(workflowId: string, priority: string) {
|
|
|
486
498
|
}
|
|
487
499
|
} finally {
|
|
488
500
|
// make sure to complete the user action in any case
|
|
489
|
-
userAction?.
|
|
501
|
+
userAction?.complete();
|
|
490
502
|
}
|
|
491
503
|
}
|
|
492
504
|
```
|
|
@@ -504,18 +516,18 @@ await loadConfiguration();
|
|
|
504
516
|
await initializeServices();
|
|
505
517
|
|
|
506
518
|
// Create the user action and set the start time
|
|
507
|
-
const userAction = dynatrace.userActions?.create({
|
|
519
|
+
const userAction = dynatrace.userActions?.create({ completeAutomatically: false });
|
|
508
520
|
|
|
509
521
|
if (userAction) {
|
|
510
522
|
// Set the start time to when the actual work began
|
|
511
523
|
userAction.startTime = actualStartTime;
|
|
512
|
-
userAction.
|
|
524
|
+
userAction.customName = 'Data Processing Operation';
|
|
513
525
|
}
|
|
514
526
|
|
|
515
527
|
// Perform the actual measured work
|
|
516
528
|
await processData();
|
|
517
529
|
|
|
518
|
-
userAction?.
|
|
530
|
+
userAction?.complete();
|
|
519
531
|
```
|
|
520
532
|
|
|
521
533
|
### Handle framework-specific routing
|
|
@@ -537,12 +549,12 @@ function useManualUserActionTracking() {
|
|
|
537
549
|
}, []);
|
|
538
550
|
|
|
539
551
|
const trackedNavigate = async (path: string) => {
|
|
540
|
-
// Don't use
|
|
552
|
+
// Don't use completeAutomatically here to allow Dynatrace to determine when the navigation is complete
|
|
541
553
|
const userAction = dynatrace.userActions?.create();
|
|
542
554
|
|
|
543
555
|
// Add metadata if provided
|
|
544
556
|
if (userAction) {
|
|
545
|
-
userAction.
|
|
557
|
+
userAction.customName = `Route: ${path}`;
|
|
546
558
|
userAction.event_properties = {
|
|
547
559
|
'event_properties.route': path,
|
|
548
560
|
'event_properties.previous_route': location.pathname
|
|
@@ -569,10 +581,10 @@ class CheckoutTracker {
|
|
|
569
581
|
// Record the actual start time
|
|
570
582
|
const checkoutStartTime = Date.now();
|
|
571
583
|
|
|
572
|
-
this.checkoutAction = dynatrace.userActions?.create({
|
|
584
|
+
this.checkoutAction = dynatrace.userActions?.create({ completeAutomatically: false });
|
|
573
585
|
|
|
574
586
|
if (this.checkoutAction) {
|
|
575
|
-
this.checkoutAction.
|
|
587
|
+
this.checkoutAction.customName = 'Checkout Process';
|
|
576
588
|
this.checkoutAction.startTime = checkoutStartTime;
|
|
577
589
|
this.checkoutAction.event_properties = {
|
|
578
590
|
'event_properties.cart_id': cart.id,
|
|
@@ -630,7 +642,7 @@ class CheckoutTracker {
|
|
|
630
642
|
checkout_status: 'success'
|
|
631
643
|
});
|
|
632
644
|
|
|
633
|
-
this.checkoutAction.
|
|
645
|
+
this.checkoutAction.complete();
|
|
634
646
|
this.checkoutAction = undefined;
|
|
635
647
|
}
|
|
636
648
|
}
|
|
@@ -642,7 +654,7 @@ class CheckoutTracker {
|
|
|
642
654
|
cancellation_reason: reason
|
|
643
655
|
});
|
|
644
656
|
|
|
645
|
-
this.checkoutAction.
|
|
657
|
+
this.checkoutAction.complete();
|
|
646
658
|
this.checkoutAction = undefined;
|
|
647
659
|
}
|
|
648
660
|
}
|
|
@@ -697,11 +709,11 @@ function createTrackedAction() {
|
|
|
697
709
|
|
|
698
710
|
### Finish user actions in finally blocks
|
|
699
711
|
|
|
700
|
-
Ensure user actions are always
|
|
712
|
+
Ensure user actions are always completed if `completeAutomatically` is `false`, even when errors occur:
|
|
701
713
|
|
|
702
714
|
```typescript
|
|
703
715
|
async function performTrackedOperation() {
|
|
704
|
-
const userAction = dynatrace.userActions?.create({
|
|
716
|
+
const userAction = dynatrace.userActions?.create({ completeAutomatically: false });
|
|
705
717
|
|
|
706
718
|
try {
|
|
707
719
|
await riskyOperation();
|
|
@@ -709,8 +721,8 @@ async function performTrackedOperation() {
|
|
|
709
721
|
console.error('Operation failed:', error);
|
|
710
722
|
throw error;
|
|
711
723
|
} finally {
|
|
712
|
-
// Always
|
|
713
|
-
userAction?.
|
|
724
|
+
// Always complete the user action
|
|
725
|
+
userAction?.complete();
|
|
714
726
|
}
|
|
715
727
|
}
|
|
716
728
|
```
|
|
@@ -730,11 +742,11 @@ input.addEventListener('keypress', () => {
|
|
|
730
742
|
let userAction: UserActionTracker | undefined;
|
|
731
743
|
|
|
732
744
|
input.addEventListener('focus', () => {
|
|
733
|
-
userAction = dynatrace.userActions?.create({
|
|
745
|
+
userAction = dynatrace.userActions?.create({ completeAutomatically: false });
|
|
734
746
|
});
|
|
735
747
|
|
|
736
748
|
input.addEventListener('blur', () => {
|
|
737
|
-
userAction?.
|
|
749
|
+
userAction?.complete();
|
|
738
750
|
userAction = undefined;
|
|
739
751
|
});
|
|
740
752
|
```
|
|
@@ -805,7 +817,7 @@ If your user actions aren't appearing in Dynatrace:
|
|
|
805
817
|
|
|
806
818
|
1. Verify that the User Actions module is enabled
|
|
807
819
|
2. Check that `dynatrace.userActions` is defined
|
|
808
|
-
3. Ensure you're calling `
|
|
820
|
+
3. Ensure you're calling `complete()` on user actions with `completeAutomatically: false`
|
|
809
821
|
4. Check browser console for any errors
|
|
810
822
|
|
|
811
823
|
### User actions completing too early
|
|
@@ -813,8 +825,8 @@ If your user actions aren't appearing in Dynatrace:
|
|
|
813
825
|
If user actions are completing before your operations finish:
|
|
814
826
|
|
|
815
827
|
```typescript
|
|
816
|
-
// Ensure
|
|
817
|
-
const userAction = dynatrace.userActions?.create({
|
|
828
|
+
// Ensure completeAutomatically is set to false
|
|
829
|
+
const userAction = dynatrace.userActions?.create({ completeAutomatically: false });
|
|
818
830
|
|
|
819
831
|
// Make sure to await all async operations
|
|
820
832
|
await Promise.all([
|
|
@@ -823,8 +835,8 @@ await Promise.all([
|
|
|
823
835
|
operation3()
|
|
824
836
|
]);
|
|
825
837
|
|
|
826
|
-
// Then
|
|
827
|
-
userAction?.
|
|
838
|
+
// Then complete
|
|
839
|
+
userAction?.complete();
|
|
828
840
|
```
|
|
829
841
|
|
|
830
842
|
### Conflicts with automatic detection
|
|
@@ -849,11 +861,11 @@ If custom properties aren't showing up:
|
|
|
849
861
|
1. Check the console logs in your browser for any issues related to Dynatrace SDK usage.
|
|
850
862
|
2. Ensure property keys start with `event_properties.` prefix
|
|
851
863
|
3. Verify the property values are of supported types (string, number, boolean)
|
|
852
|
-
4. Check that properties are set before calling `
|
|
864
|
+
4. Check that properties are set before calling `complete()`
|
|
853
865
|
5. Make sure the user action state is `'active'` when setting properties
|
|
854
866
|
|
|
855
867
|
```typescript
|
|
856
|
-
const userAction = dynatrace.userActions?.create({
|
|
868
|
+
const userAction = dynatrace.userActions?.create({ completeAutomatically: false });
|
|
857
869
|
|
|
858
870
|
if (userAction) {
|
|
859
871
|
// ✅ Correct: Using proper prefix and supported types
|
|
@@ -867,7 +879,7 @@ if (userAction) {
|
|
|
867
879
|
console.log('User action state:', userAction.state);
|
|
868
880
|
|
|
869
881
|
// Complete the action
|
|
870
|
-
userAction.
|
|
882
|
+
userAction.complete();
|
|
871
883
|
}
|
|
872
884
|
```
|
|
873
885
|
|
|
@@ -889,8 +901,8 @@ Creates a new user action. Returns `undefined` if the module is not available.
|
|
|
889
901
|
```typescript
|
|
890
902
|
import { create } from '@dynatrace/rum-javascript-sdk/api/user-actions';
|
|
891
903
|
|
|
892
|
-
const userAction = create({
|
|
893
|
-
userAction?.
|
|
904
|
+
const userAction = create({ completeAutomatically: false });
|
|
905
|
+
userAction?.complete();
|
|
894
906
|
```
|
|
895
907
|
|
|
896
908
|
**`subscribe(subscriber): Unsubscriber | undefined`**
|
|
@@ -925,7 +937,7 @@ import { getCurrent } from '@dynatrace/rum-javascript-sdk/api/user-actions';
|
|
|
925
937
|
|
|
926
938
|
const current = getCurrent();
|
|
927
939
|
if (current) {
|
|
928
|
-
current.
|
|
940
|
+
current.completeAutomatically = false;
|
|
929
941
|
}
|
|
930
942
|
```
|
|
931
943
|
|
|
@@ -941,8 +953,8 @@ Creates a new user action, waiting up to `timeout` ms (default: 10000) for the m
|
|
|
941
953
|
import { create } from '@dynatrace/rum-javascript-sdk/api/promises/user-actions';
|
|
942
954
|
|
|
943
955
|
try {
|
|
944
|
-
const userAction = await create({
|
|
945
|
-
userAction.
|
|
956
|
+
const userAction = await create({ completeAutomatically: false });
|
|
957
|
+
userAction.complete();
|
|
946
958
|
} catch (error) {
|
|
947
959
|
console.error('User Actions module not available');
|
|
948
960
|
}
|
|
@@ -960,13 +972,16 @@ All async functions follow the same pattern, accepting an optional `timeout` par
|
|
|
960
972
|
|
|
961
973
|
| Property | Type | Access | Description |
|
|
962
974
|
|----------|-----------------------------------------------|--------|-------------|
|
|
963
|
-
| `
|
|
975
|
+
| `complete()` | Function | - | Completes the user action and sends the event |
|
|
976
|
+
| `finish()` | Function | - | **Deprecated.** Use `complete()` instead |
|
|
964
977
|
| `subscribe(callback)` | Function | - | Subscribes to automatic completion events |
|
|
965
|
-
| `
|
|
978
|
+
| `completeAutomatically` | `boolean` | Get/Set | Controls whether the action completes automatically |
|
|
979
|
+
| `autoClose` | `boolean` | Get/Set | **Deprecated.** Use `completeAutomatically` instead |
|
|
966
980
|
| `state` | `'active' \| 'complete'` | Get | Returns the current state of the user action |
|
|
967
981
|
| `event_properties` | `Record<string, string \| number \| boolean>` | Get/Set | Custom properties for business context |
|
|
968
982
|
| `startTime` | `number` | Get/Set | Start time in milliseconds (must not be in future) |
|
|
969
|
-
| `
|
|
983
|
+
| `customName` | `string \| undefined` | Get/Set | Display name for the user action |
|
|
984
|
+
| `name` | `string \| undefined` | Get/Set | **Deprecated.** Use `customName` instead |
|
|
970
985
|
|
|
971
986
|
### Key types and interfaces
|
|
972
987
|
|
|
@@ -977,7 +992,10 @@ All async functions follow the same pattern, accepting an optional `timeout` par
|
|
|
977
992
|
- `current` - Access the currently active user action
|
|
978
993
|
- `UserActionTracker` - Represents an individual user action (see properties table above)
|
|
979
994
|
- `UserActionStartOptions` - Configuration options for creating user actions
|
|
980
|
-
- `
|
|
995
|
+
- `completeAutomatically?: boolean` - Whether the action should complete automatically (default: `true`)
|
|
996
|
+
- `autoClose?: boolean` - **Deprecated.** Use `completeAutomatically` instead
|
|
997
|
+
- `customName?: string` - A human-readable custom name to identify the user action
|
|
998
|
+
- `name?: string` - **Deprecated.** Use `customName` instead
|
|
981
999
|
- `Unsubscriber` - Function type `() => void` for unsubscribing from events
|
|
982
1000
|
|
|
983
1001
|
## Additional resources
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Interactions API
|
|
3
|
+
---
|
|
4
|
+
# Interactions API
|
|
5
|
+
|
|
6
|
+
This guide explains how to report custom interaction events that are not automatically detected.
|
|
7
|
+
|
|
8
|
+
## What you can do
|
|
9
|
+
|
|
10
|
+
- Report custom keyboard shortcuts or key combinations via `sendKeyPressEvent`
|
|
11
|
+
- Attach `ui_element.custom_name` and `event_properties.*` fields
|
|
12
|
+
- Provide an `Element` or `KeyboardEvent` to capture UI element fields
|
|
13
|
+
|
|
14
|
+
## Prerequisites
|
|
15
|
+
|
|
16
|
+
- New RUM Experience is enabled for your application
|
|
17
|
+
|
|
18
|
+
## API approaches
|
|
19
|
+
|
|
20
|
+
You can use the Interactions API directly, or via its synchronous or asynchronous SDK functions, matching the pattern established in the [RUM JavaScript SDK Overview](./1-overview.md):
|
|
21
|
+
|
|
22
|
+
### Direct API (via `dynatrace.interactions`)
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
dynatrace?.interactions?.sendKeyPressEvent({
|
|
26
|
+
keys: ["A"]
|
|
27
|
+
});
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Safe Wrapper API (recommended)
|
|
31
|
+
|
|
32
|
+
```typescript
|
|
33
|
+
import * as interactions from "@dynatrace/rum-javascript-sdk/api/interactions";
|
|
34
|
+
import { UserInteractionSpecialKey } from "@dynatrace/rum-javascript-sdk/types/rum-events";
|
|
35
|
+
|
|
36
|
+
interactions.sendKeyPressEvent({
|
|
37
|
+
keys: [UserInteractionSpecialKey.CTRL, "S"],
|
|
38
|
+
"event_properties.context": "editor"
|
|
39
|
+
});
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Async API
|
|
43
|
+
|
|
44
|
+
```typescript
|
|
45
|
+
import { sendKeyPressEvent } from "@dynatrace/rum-javascript-sdk/api/promises/interactions";
|
|
46
|
+
import { UserInteractionSpecialKey } from "@dynatrace/rum-javascript-sdk/types/rum-events";
|
|
47
|
+
|
|
48
|
+
await sendKeyPressEvent({
|
|
49
|
+
keys: [UserInteractionSpecialKey.CTRL, "S"]
|
|
50
|
+
});
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## `UserInteractionSpecialKey`
|
|
54
|
+
|
|
55
|
+
The {@link UserInteractionSpecialKey} enum provides normalized string representations for specific [`KeyboardEvent.key`](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key) values (e.g. `" "` → `"space"`, `"Control"` → `"ctrl"`, `"Escape"` → `"esc"`, `"ArrowUp"` → `"arrow_up"`).
|
|
56
|
+
|
|
57
|
+
Using this enum is **optional** — raw [`KeyboardEvent.key`](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key) values are also accepted and normalized internally. The enum is a convenience for readability, especially when constructing key arrays manually without a real keyboard event.
|
|
58
|
+
|
|
59
|
+
```typescript
|
|
60
|
+
import { UserInteractionSpecialKey } from "@dynatrace/rum-javascript-sdk/types/rum-events";
|
|
61
|
+
|
|
62
|
+
// Modifier + regular key
|
|
63
|
+
dynatrace.interactions?.sendKeyPressEvent({
|
|
64
|
+
keys: [UserInteractionSpecialKey.CTRL, "S"]
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// Single special key
|
|
68
|
+
dynatrace.interactions?.sendKeyPressEvent({
|
|
69
|
+
keys: [UserInteractionSpecialKey.ESC]
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
// Regular key (passed as its KeyboardEvent.key value)
|
|
73
|
+
dynatrace.interactions?.sendKeyPressEvent({
|
|
74
|
+
keys: ["a"]
|
|
75
|
+
});
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## sendKeyPressEvent
|
|
79
|
+
|
|
80
|
+
`sendKeyPressEvent(fields, elementOrEvent?)` reports a custom key_press interaction.
|
|
81
|
+
|
|
82
|
+
- `fields` must be a JSON-serializable object with a non-empty `keys` array.
|
|
83
|
+
- Keys can be [`UserInteractionSpecialKey`](#userinteractionspecialkey) members or raw [`KeyboardEvent.key`](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key) strings — raw values are normalized internally.
|
|
84
|
+
- Optional `ui_element.custom_name` and `event_properties.*` entries are allowed.
|
|
85
|
+
- `elementOrEvent` may be an [`Element`](https://developer.mozilla.org/en-US/docs/Web/API/Element) or [`KeyboardEvent`](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent) to derive UI element fields. If omitted, no UI element fields are added.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dynatrace/rum-javascript-sdk",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.337.1",
|
|
4
4
|
"description": "JavaScript API for Real User Monitoring (RUM)",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"type": "module",
|
|
@@ -13,12 +13,18 @@
|
|
|
13
13
|
"api/user-actions": [
|
|
14
14
|
"./dist/api/user-actions.d.ts"
|
|
15
15
|
],
|
|
16
|
+
"api/interactions": [
|
|
17
|
+
"./dist/api/interactions.d.ts"
|
|
18
|
+
],
|
|
16
19
|
"api/promises": [
|
|
17
20
|
"./dist/api/promises/index.d.ts"
|
|
18
21
|
],
|
|
19
22
|
"api/promises/user-actions": [
|
|
20
23
|
"./dist/api/promises/user-actions.d.ts"
|
|
21
24
|
],
|
|
25
|
+
"api/promises/interactions": [
|
|
26
|
+
"./dist/api/promises/interactions.d.ts"
|
|
27
|
+
],
|
|
22
28
|
"test": [
|
|
23
29
|
"./dist/testing/index.d.ts"
|
|
24
30
|
],
|
|
@@ -63,11 +69,21 @@
|
|
|
63
69
|
"import": "./dist/api/user-actions.js",
|
|
64
70
|
"default": "./dist/api/user-actions.js"
|
|
65
71
|
},
|
|
72
|
+
"./api/interactions": {
|
|
73
|
+
"types": "./dist/api/interactions.d.ts",
|
|
74
|
+
"import": "./dist/api/interactions.js",
|
|
75
|
+
"default": "./dist/api/interactions.js"
|
|
76
|
+
},
|
|
66
77
|
"./api/promises/user-actions": {
|
|
67
78
|
"types": "./dist/api/promises/user-actions.d.ts",
|
|
68
79
|
"import": "./dist/api/promises/user-actions.js",
|
|
69
80
|
"default": "./dist/api/promises/user-actions.js"
|
|
70
81
|
},
|
|
82
|
+
"./api/promises/interactions": {
|
|
83
|
+
"types": "./dist/api/promises/interactions.d.ts",
|
|
84
|
+
"import": "./dist/api/promises/interactions.js",
|
|
85
|
+
"default": "./dist/api/promises/interactions.js"
|
|
86
|
+
},
|
|
71
87
|
"./api/promises": {
|
|
72
88
|
"types": "./dist/api/promises/index.d.ts",
|
|
73
89
|
"import": "./dist/api/promises/index.js",
|
|
@@ -131,15 +147,15 @@
|
|
|
131
147
|
"license": "ISC",
|
|
132
148
|
"devDependencies": {
|
|
133
149
|
"@types/node": "25.0.3",
|
|
134
|
-
"@vitest/coverage-v8": "4.1.0
|
|
135
|
-
"@vitest/ui": "4.1.0
|
|
150
|
+
"@vitest/coverage-v8": "4.1.0",
|
|
151
|
+
"@vitest/ui": "4.1.0",
|
|
136
152
|
"eslint": "9.38.0",
|
|
137
|
-
"jsdom": "
|
|
138
|
-
"knip": "5.
|
|
139
|
-
"typedoc": "0.28.
|
|
140
|
-
"typedoc-plugin-mdn-links": "5.
|
|
153
|
+
"jsdom": "29.0.1",
|
|
154
|
+
"knip": "5.85.0",
|
|
155
|
+
"typedoc": "0.28.17",
|
|
156
|
+
"typedoc-plugin-mdn-links": "5.1.1",
|
|
141
157
|
"typescript": "5.8.2",
|
|
142
|
-
"vitest": "4.1.0
|
|
158
|
+
"vitest": "4.1.0"
|
|
143
159
|
},
|
|
144
160
|
"scripts": {
|
|
145
161
|
"build:lib": "tsc -b tsconfig.build.json",
|