@dynatrace/rum-javascript-sdk 1.329.3 → 1.329.4
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/docs/USERACTIONS.md +990 -0
- package/docs/testing.md +123 -0
- package/docs/types.md +44 -0
- package/package.json +2 -2
- package/AGENTS.md +0 -585
package/AGENTS.md
DELETED
|
@@ -1,585 +0,0 @@
|
|
|
1
|
-
# RUM JavaScript API Development
|
|
2
|
-
|
|
3
|
-
**Read the root `AGENTS.md` first** - this file contains only rum-javascript-api-specific additions.
|
|
4
|
-
|
|
5
|
-
## Package Purpose
|
|
6
|
-
|
|
7
|
-
Customer-facing npm package that provides **safe wrapper functions** around the Dynatrace RUM JavaScript API. This is NOT the agent implementation itself, but a convenience library customers can install via npm to:
|
|
8
|
-
|
|
9
|
-
1. **Safely call RUM APIs** without checking if the agent is loaded (synchronous API).
|
|
10
|
-
2. **Wait for RUM availability** with Promise-based async API.
|
|
11
|
-
3. **Get TypeScript support** for RUM API types and IntelliSense.
|
|
12
|
-
4. **Test RUM integration** using Playwright testing utilities.
|
|
13
|
-
|
|
14
|
-
This package wraps the global `dynatrace` namespace that the actual RUM JavaScript agent provides.
|
|
15
|
-
|
|
16
|
-
## API Approaches
|
|
17
|
-
|
|
18
|
-
### Two Wrapper Patterns
|
|
19
|
-
|
|
20
|
-
**Synchronous API (`@dynatrace/rum-javascript-api/api`)**:
|
|
21
|
-
- Safe no-op wrappers that gracefully handle missing RUM JavaScript.
|
|
22
|
-
- Functions execute silently if agent not loaded.
|
|
23
|
-
- Recommended for most use cases (graceful degradation).
|
|
24
|
-
- Example: `sendEvent()`, `identifyUser()`, `addEventModifier()`
|
|
25
|
-
|
|
26
|
-
**Asynchronous API (`@dynatrace/rum-javascript-api/api/promises`)**:
|
|
27
|
-
- Promise-based wrappers that wait for RUM JavaScript availability.
|
|
28
|
-
- Throws `DynatraceError` if agent not available within timeout.
|
|
29
|
-
- Useful for critical instrumentation or consent-based loading.
|
|
30
|
-
- Same functions with async signatures and configurable timeouts.
|
|
31
|
-
|
|
32
|
-
### Key Difference
|
|
33
|
-
|
|
34
|
-
Both call the same underlying `dynatrace` API, but:
|
|
35
|
-
- **Sync**: Returns immediately, may be no-op if agent unavailable.
|
|
36
|
-
- **Async**: Waits up to timeout for agent, throws if unavailable.
|
|
37
|
-
|
|
38
|
-
## API Stability
|
|
39
|
-
|
|
40
|
-
**Critical Requirements**:
|
|
41
|
-
- **No Breaking Changes**: Customers install this via npm and depend on stable API.
|
|
42
|
-
- **Backward Compatibility**: Wrapper must work with old and new agent versions.
|
|
43
|
-
- **Deprecation Process**: Warn before removal, provide migration path.
|
|
44
|
-
|
|
45
|
-
## Core Wrapper Functions
|
|
46
|
-
|
|
47
|
-
### Synchronous Wrappers
|
|
48
|
-
|
|
49
|
-
Located in `source/api/`:
|
|
50
|
-
- `sendEvent(fields, eventContext?)`: Send custom event with properties.
|
|
51
|
-
- `addEventModifier(eventModifier)`: Register function to modify events before sending.
|
|
52
|
-
- `runHealthCheck(config?)`: Run RUM JavaScript health diagnostics.
|
|
53
|
-
- `identifyUser(value)`: Associate session with user identifier.
|
|
54
|
-
- `sendSessionPropertyEvent(fields)`: Send session-level properties.
|
|
55
|
-
|
|
56
|
-
**Implementation Pattern**:
|
|
57
|
-
- Check if `dynatrace` namespace exists.
|
|
58
|
-
- Return early (no-op) if not available.
|
|
59
|
-
- Call actual RUM API function if available.
|
|
60
|
-
- Return `undefined` for functions that would return values.
|
|
61
|
-
|
|
62
|
-
### Asynchronous Wrappers
|
|
63
|
-
|
|
64
|
-
Located in `source/api/promises/`:
|
|
65
|
-
- Same function names as synchronous versions.
|
|
66
|
-
- Additional `timeout` parameter (default 10,000ms).
|
|
67
|
-
- Returns `Promise` that resolves when RUM API called.
|
|
68
|
-
- Throws `DynatraceError` if timeout exceeded.
|
|
69
|
-
|
|
70
|
-
**Implementation Pattern**:
|
|
71
|
-
- Register property listener for `dynatrace` namespace availability.
|
|
72
|
-
- Wait up to timeout milliseconds.
|
|
73
|
-
- Call namespace function once available.
|
|
74
|
-
- Throw error if timeout reached without availability.
|
|
75
|
-
|
|
76
|
-
## Type Definitions
|
|
77
|
-
|
|
78
|
-
### Type Exports
|
|
79
|
-
|
|
80
|
-
### Global Type Augmentation
|
|
81
|
-
|
|
82
|
-
Types exported from `@dynatrace/rum-javascript-api/types`.
|
|
83
|
-
Package provides global `window.dynatrace` type augmentation:
|
|
84
|
-
- Automatically available when package installed.
|
|
85
|
-
- No import needed for `window.dynatrace` IntelliSense.
|
|
86
|
-
- Type inference works out-of-the-box.
|
|
87
|
-
|
|
88
|
-
### TypeScript Configuration
|
|
89
|
-
|
|
90
|
-
Add to `tsconfig.json` under `compilerOptions`:
|
|
91
|
-
```json
|
|
92
|
-
"typeRoots": ["./node_modules/@types", "./node_modules/@dynatrace/"]
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
**Reference**: `types.md` for detailed type usage examples and integration guide.
|
|
96
|
-
|
|
97
|
-
### Type Safety for Customers
|
|
98
|
-
|
|
99
|
-
- Full TypeScript IntelliSense support for wrapper functions.
|
|
100
|
-
- Global `window.dynatrace` namespace typed automatically.
|
|
101
|
-
- Compile-time validation of event property names.
|
|
102
|
-
- Catch API usage errors before runtime.
|
|
103
|
-
|
|
104
|
-
## Testing Framework
|
|
105
|
-
|
|
106
|
-
### Playwright Test Utilities
|
|
107
|
-
|
|
108
|
-
Exported from `@dynatrace/rum-javascript-api/test`:
|
|
109
|
-
- **Purpose**: Test RUM integration in Playwright end-to-end tests.
|
|
110
|
-
- **Functionality**: Wait for and validate RUM events and beacons in automated tests.
|
|
111
|
-
- **Use Cases**: Assert on event properties, validate beacon sending, test RUM workflows.
|
|
112
|
-
|
|
113
|
-
**Reference**: `testing.md` for complete API documentation and examples.
|
|
114
|
-
|
|
115
|
-
### Setup Requirements
|
|
116
|
-
|
|
117
|
-
**Dynatrace Configuration** needed for testing:
|
|
118
|
-
1. **Access Token**: Create token with `Read RUM manual insertion tags` permission (API V2 scope).
|
|
119
|
-
2. **Environment URL**: Dynatrace API endpoint (e.g., `https://{env-id}.live.dynatrace.com`).
|
|
120
|
-
3. **Application ID**: Frontend application ID (e.g., `APPLICATION-ABCDEF0123456789`).
|
|
121
|
-
|
|
122
|
-
Configure in Playwright test:
|
|
123
|
-
```typescript
|
|
124
|
-
import { test } from "@dynatrace/rum-javascript-api/test";
|
|
125
|
-
|
|
126
|
-
test.use({
|
|
127
|
-
dynatraceConfig: {
|
|
128
|
-
appId: process.env.DT_APP_ID!,
|
|
129
|
-
token: process.env.DT_TOKEN!,
|
|
130
|
-
endpointUrl: process.env.DT_ENDPOINT_URL!
|
|
131
|
-
}
|
|
132
|
-
});
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
### DynatraceTesting Fixture API
|
|
136
|
-
|
|
137
|
-
**`waitForBeacons(options?)`**: Wait for beacon requests.
|
|
138
|
-
- `minCount`: Minimum number of beacons to wait for.
|
|
139
|
-
- `timeout`: Maximum wait time (default: 30,000ms).
|
|
140
|
-
- Returns: `Promise<BeaconRequest[]>`
|
|
141
|
-
|
|
142
|
-
**`expectToHaveSentEvent(event, options?)`**: Assert specific event sent.
|
|
143
|
-
- `event`: Event object to match (uses Playwright's `toMatchObject`).
|
|
144
|
-
- `timeout`: Maximum wait time (default: 30,000ms).
|
|
145
|
-
- Returns: `Promise<void>`
|
|
146
|
-
|
|
147
|
-
**`expectToHaveSentEventTimes(event, times, options?)`**: Assert event sent N times.
|
|
148
|
-
- `event`: Event object to match.
|
|
149
|
-
- `times`: Expected number of times event sent.
|
|
150
|
-
- `timeout`: Maximum wait time (default: 30,000ms).
|
|
151
|
-
- Returns: `Promise<void>`
|
|
152
|
-
|
|
153
|
-
**`clearEvents()`**: Clear all events and beacons.
|
|
154
|
-
- Resets event tracking for subsequent assertions.
|
|
155
|
-
- Useful for testing multiple scenarios in one test.
|
|
156
|
-
|
|
157
|
-
### Testing Patterns
|
|
158
|
-
|
|
159
|
-
**Basic Event Assertion**:
|
|
160
|
-
```typescript
|
|
161
|
-
test("sends custom event", async ({ page, dynatraceTesting }) => {
|
|
162
|
-
await page.goto("http://localhost:3000");
|
|
163
|
-
await page.getByText("Submit").click();
|
|
164
|
-
|
|
165
|
-
await dynatraceTesting.expectToHaveSentEvent({
|
|
166
|
-
"event_properties.action": "submit"
|
|
167
|
-
});
|
|
168
|
-
});
|
|
169
|
-
```
|
|
170
|
-
|
|
171
|
-
**Multiple Event Assertions**:
|
|
172
|
-
```typescript
|
|
173
|
-
test("sends event multiple times", async ({ page, dynatraceTesting }) => {
|
|
174
|
-
await page.goto("http://localhost:3000");
|
|
175
|
-
|
|
176
|
-
// Click button 3 times
|
|
177
|
-
for (let i = 0; i < 3; i++) {
|
|
178
|
-
await page.getByText("Add").click();
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
await dynatraceTesting.expectToHaveSentEventTimes({
|
|
182
|
-
"event_properties.button": "add"
|
|
183
|
-
}, 3);
|
|
184
|
-
});
|
|
185
|
-
```
|
|
186
|
-
|
|
187
|
-
**Testing with Event Clearing**:
|
|
188
|
-
```typescript
|
|
189
|
-
test("test scenarios separately", async ({ page, dynatraceTesting }) => {
|
|
190
|
-
// First scenario
|
|
191
|
-
await page.goto("http://localhost:3000");
|
|
192
|
-
await dynatraceTesting.expectToHaveSentEvent({
|
|
193
|
-
"event_properties.page": "home"
|
|
194
|
-
});
|
|
195
|
-
|
|
196
|
-
// Clear and test second scenario
|
|
197
|
-
dynatraceTesting.clearEvents();
|
|
198
|
-
await page.goto("http://localhost:3000/about");
|
|
199
|
-
await dynatraceTesting.expectToHaveSentEvent({
|
|
200
|
-
"event_properties.page": "about"
|
|
201
|
-
});
|
|
202
|
-
});
|
|
203
|
-
```
|
|
204
|
-
|
|
205
|
-
### Routing Considerations
|
|
206
|
-
|
|
207
|
-
**Important**: Testing fixture registers asterisk route `"**"` to inject RUM JavaScript.
|
|
208
|
-
- May interfere with existing Playwright routing rules.
|
|
209
|
-
- Order of fixture destructuring matters.
|
|
210
|
-
- Be aware of potential route conflicts in tests.
|
|
211
|
-
|
|
212
|
-
**Reference**: `testing.md` troubleshooting section for routing issues.
|
|
213
|
-
|
|
214
|
-
## Event Property Naming
|
|
215
|
-
|
|
216
|
-
### Required Prefixes
|
|
217
|
-
|
|
218
|
-
**Custom Event Properties**:
|
|
219
|
-
- Must be prefixed with `event_properties.`
|
|
220
|
-
- Properties without prefix are ignored by agent.
|
|
221
|
-
- Naming: lowercase, numbers, underscores, dots only.
|
|
222
|
-
|
|
223
|
-
**Session Properties**:
|
|
224
|
-
- Must be prefixed with `session_properties.`
|
|
225
|
-
- Same naming conventions as event properties.
|
|
226
|
-
|
|
227
|
-
### Valid Examples
|
|
228
|
-
|
|
229
|
-
```typescript
|
|
230
|
-
// ✅ Correct event properties
|
|
231
|
-
sendEvent({
|
|
232
|
-
'event_properties.action': 'login',
|
|
233
|
-
'event_properties.method': 'oauth',
|
|
234
|
-
'event_properties.page_name': 'dashboard'
|
|
235
|
-
});
|
|
236
|
-
|
|
237
|
-
// ✅ Correct session properties
|
|
238
|
-
sendSessionPropertyEvent({
|
|
239
|
-
'session_properties.user_type': 'premium',
|
|
240
|
-
'session_properties.region': 'us_east'
|
|
241
|
-
});
|
|
242
|
-
|
|
243
|
-
// ❌ Wrong - missing prefix
|
|
244
|
-
sendEvent({
|
|
245
|
-
'action': 'login', // Will be ignored
|
|
246
|
-
'method': 'oauth' // Will be ignored
|
|
247
|
-
});
|
|
248
|
-
```
|
|
249
|
-
|
|
250
|
-
## Documentation
|
|
251
|
-
|
|
252
|
-
### Customer-Facing Documentation
|
|
253
|
-
|
|
254
|
-
**README.md** (Primary documentation):
|
|
255
|
-
- Installation instructions via npm.
|
|
256
|
-
- Quick start examples for sync and async APIs.
|
|
257
|
-
- Complete API reference for all wrapper functions.
|
|
258
|
-
- Error handling patterns and `DynatraceError` usage.
|
|
259
|
-
- Best practices: when to use sync vs async.
|
|
260
|
-
- Event property naming conventions.
|
|
261
|
-
- Common integration patterns.
|
|
262
|
-
|
|
263
|
-
**types.md** (TypeScript integration guide):
|
|
264
|
-
- TypeScript configuration setup (`typeRoots`).
|
|
265
|
-
- Type inference examples for `window.dynatrace`.
|
|
266
|
-
- Importing specific types from package.
|
|
267
|
-
- Global type augmentation explanation.
|
|
268
|
-
- Usage examples with type safety.
|
|
269
|
-
|
|
270
|
-
**testing.md** (Playwright testing framework):
|
|
271
|
-
- Setup instructions: access token, environment URL, app ID.
|
|
272
|
-
- `DynatraceTesting` fixture API reference.
|
|
273
|
-
- Test configuration with `test.use()`.
|
|
274
|
-
- Event assertion methods with examples.
|
|
275
|
-
- Troubleshooting: routing conflicts, beacon delays.
|
|
276
|
-
- Complete testing patterns and best practices.
|
|
277
|
-
|
|
278
|
-
### JSDoc Requirements
|
|
279
|
-
|
|
280
|
-
Every exported function must have:
|
|
281
|
-
- Clear description of purpose and behavior.
|
|
282
|
-
- Parameter documentation with types.
|
|
283
|
-
- Return value description.
|
|
284
|
-
- Usage examples via `@example` tag.
|
|
285
|
-
- Notes about RUM JavaScript availability handling.
|
|
286
|
-
|
|
287
|
-
## Wrapper Design Principles
|
|
288
|
-
|
|
289
|
-
### Safe Defaults
|
|
290
|
-
|
|
291
|
-
**Synchronous API Philosophy**:
|
|
292
|
-
- Fail silently if RUM JavaScript unavailable.
|
|
293
|
-
- Never throw errors that break customer code.
|
|
294
|
-
- Graceful degradation for missing agent.
|
|
295
|
-
- No runtime overhead checking availability.
|
|
296
|
-
|
|
297
|
-
**Asynchronous API Philosophy**:
|
|
298
|
-
- Explicitly handle agent availability.
|
|
299
|
-
- Timeout to prevent infinite waiting.
|
|
300
|
-
- Clear error when agent unavailable.
|
|
301
|
-
- Used when reliability is critical.
|
|
302
|
-
|
|
303
|
-
### Minimal Overhead
|
|
304
|
-
|
|
305
|
-
- Wrapper functions are thin shims.
|
|
306
|
-
- No data transformation or validation.
|
|
307
|
-
- Direct pass-through to underlying API.
|
|
308
|
-
- Negligible performance impact.
|
|
309
|
-
|
|
310
|
-
### TypeScript First
|
|
311
|
-
|
|
312
|
-
- All functions have complete type definitions.
|
|
313
|
-
- Types match underlying RUM API exactly.
|
|
314
|
-
- IntelliSense support for all methods.
|
|
315
|
-
- Compile-time safety for customers.
|
|
316
|
-
|
|
317
|
-
## Testing
|
|
318
|
-
|
|
319
|
-
### Unit Tests (Vitest)
|
|
320
|
-
|
|
321
|
-
Run: `pnpm test` with coverage.
|
|
322
|
-
|
|
323
|
-
**Test Coverage**:
|
|
324
|
-
- Synchronous wrappers handle missing `dynatrace`.
|
|
325
|
-
- Asynchronous wrappers wait and timeout correctly.
|
|
326
|
-
- `DynatraceError` thrown at correct times.
|
|
327
|
-
- Type definitions compile correctly.
|
|
328
|
-
- Event modifiers return unsubscribers.
|
|
329
|
-
|
|
330
|
-
**Mock Strategy**:
|
|
331
|
-
- Mock global `dynatrace` namespace.
|
|
332
|
-
- Test both presence and absence scenarios.
|
|
333
|
-
- Verify correct underlying API called.
|
|
334
|
-
- Test timeout behavior for async wrappers.
|
|
335
|
-
|
|
336
|
-
### Testing Applications Using This Package
|
|
337
|
-
|
|
338
|
-
**Playwright Test Fixtures**:
|
|
339
|
-
- Use testing utilities from `@dynatrace/rum-javascript-api/test`.
|
|
340
|
-
- Wait for RUM events in test assertions.
|
|
341
|
-
- Validate event properties sent correctly.
|
|
342
|
-
- Test RUM integration without mocking.
|
|
343
|
-
|
|
344
|
-
**Reference**: `testing.md` for complete testing framework documentation.
|
|
345
|
-
|
|
346
|
-
## Relationship to RUM JavaScript Agent
|
|
347
|
-
|
|
348
|
-
### Wrapper vs Implementation
|
|
349
|
-
|
|
350
|
-
**This package (`@dynatrace/rum-javascript-api`)**:
|
|
351
|
-
- npm package customers install in their applications.
|
|
352
|
-
- Provides safe wrapper functions around global `dynatrace` API.
|
|
353
|
-
- Adds TypeScript types and convenience methods.
|
|
354
|
-
- Independent of agent loading mechanism.
|
|
355
|
-
|
|
356
|
-
**RUM JavaScript Agent**:
|
|
357
|
-
- Injected script that runs in customer browsers.
|
|
358
|
-
- Provides actual implementation via `dynatrace` global namespace.
|
|
359
|
-
- Monitors page activity and sends beacons.
|
|
360
|
-
- This wrapper calls into it when available.
|
|
361
|
-
|
|
362
|
-
### Coordination Requirements
|
|
363
|
-
|
|
364
|
-
When RUM Agent API changes:
|
|
365
|
-
1. Update type definitions in this package.
|
|
366
|
-
2. Update wrapper function signatures if needed.
|
|
367
|
-
3. Add new wrappers for new APIs.
|
|
368
|
-
4. Maintain backward compatibility.
|
|
369
|
-
5. Test wrappers with both Gen2 and Gen3 agents.
|
|
370
|
-
|
|
371
|
-
**Important**: This package must work with multiple agent versions deployed in customer environments.
|
|
372
|
-
|
|
373
|
-
## Versioning
|
|
374
|
-
|
|
375
|
-
### Compatibility Matrix
|
|
376
|
-
|
|
377
|
-
Wrapper versions must be tested against:
|
|
378
|
-
- Current production agent versions.
|
|
379
|
-
- Previous agent versions (backward compatibility).
|
|
380
|
-
|
|
381
|
-
### Deprecation Process
|
|
382
|
-
|
|
383
|
-
1. Mark wrapper function as deprecated in JSDoc.
|
|
384
|
-
2. Document replacement wrapper or pattern.
|
|
385
|
-
3. Remove in next major version with migration guide.
|
|
386
|
-
|
|
387
|
-
## Customer Usage Patterns
|
|
388
|
-
|
|
389
|
-
### When to Use Sync vs Async API
|
|
390
|
-
|
|
391
|
-
**Use Synchronous API When**:
|
|
392
|
-
- Graceful degradation acceptable (events may be lost).
|
|
393
|
-
- Agent might not be loaded (opt-in scenarios).
|
|
394
|
-
- Adding instrumentation to existing code.
|
|
395
|
-
|
|
396
|
-
**Use Asynchronous API When**:
|
|
397
|
-
- Critical events must be sent.
|
|
398
|
-
- Need explicit error handling for missing agent.
|
|
399
|
-
- Consent-based agent loading.
|
|
400
|
-
- Testing/debugging scenarios requiring guarantees.
|
|
401
|
-
|
|
402
|
-
### Common Integration Patterns
|
|
403
|
-
|
|
404
|
-
**Standard Usage**:
|
|
405
|
-
```typescript
|
|
406
|
-
import { sendEvent, identifyUser } from '@dynatrace/rum-javascript-api/api';
|
|
407
|
-
|
|
408
|
-
// Safe - no-op if agent not loaded
|
|
409
|
-
identifyUser('user@example.com');
|
|
410
|
-
sendEvent({ 'event_properties.action': 'checkout' });
|
|
411
|
-
```
|
|
412
|
-
|
|
413
|
-
**Consent-Based Loading**:
|
|
414
|
-
```typescript
|
|
415
|
-
import { sendEvent } from '@dynatrace/rum-javascript-api/api/promises';
|
|
416
|
-
|
|
417
|
-
async function afterConsent() {
|
|
418
|
-
try {
|
|
419
|
-
// Wait for agent, throw if not available
|
|
420
|
-
await sendEvent({ 'event_properties.consent_given': 'analytics' });
|
|
421
|
-
} catch (error) {
|
|
422
|
-
console.warn('RUM not available:', error);
|
|
423
|
-
}
|
|
424
|
-
}
|
|
425
|
-
```
|
|
426
|
-
|
|
427
|
-
**Event Modification**:
|
|
428
|
-
```typescript
|
|
429
|
-
import { addEventModifier } from '@dynatrace/rum-javascript-api/api';
|
|
430
|
-
|
|
431
|
-
// Add context to all events
|
|
432
|
-
const unsubscribe = addEventModifier((event) => ({
|
|
433
|
-
...event,
|
|
434
|
-
'event_properties.app_version': '2.1.0'
|
|
435
|
-
}));
|
|
436
|
-
```
|
|
437
|
-
|
|
438
|
-
## Error Handling
|
|
439
|
-
|
|
440
|
-
### DynatraceError Class
|
|
441
|
-
|
|
442
|
-
Custom error thrown by asynchronous wrappers:
|
|
443
|
-
- Thrown when RUM JavaScript not available within timeout.
|
|
444
|
-
- Exported from both `api` and `api/promises` modules.
|
|
445
|
-
- Includes descriptive error message.
|
|
446
|
-
- Allows `instanceof` checking for error handling.
|
|
447
|
-
|
|
448
|
-
### Error Handling Patterns
|
|
449
|
-
|
|
450
|
-
```typescript
|
|
451
|
-
import { sendEvent, DynatraceError } from '@dynatrace/rum-javascript-api/api/promises';
|
|
452
|
-
|
|
453
|
-
try {
|
|
454
|
-
await sendEvent({ 'event_properties.test': 'value' }, undefined, 5000);
|
|
455
|
-
} catch (error) {
|
|
456
|
-
if (error instanceof DynatraceError) {
|
|
457
|
-
// RUM JavaScript not available
|
|
458
|
-
}
|
|
459
|
-
}
|
|
460
|
-
```
|
|
461
|
-
|
|
462
|
-
## Common Pitfalls
|
|
463
|
-
|
|
464
|
-
### Wrapper Development
|
|
465
|
-
|
|
466
|
-
- **Not handling missing `dynatrace`**: Sync wrappers must check availability.
|
|
467
|
-
- **Breaking type compatibility**: Types must match RUM agent API exactly.
|
|
468
|
-
- **Adding validation logic**: Wrappers are pass-through only, no validation.
|
|
469
|
-
- **Incorrect timeout defaults**: Async wrappers need reasonable defaults (10s).
|
|
470
|
-
- **Missing JSDoc**: Every function needs complete documentation.
|
|
471
|
-
|
|
472
|
-
### Customer Usage Mistakes
|
|
473
|
-
|
|
474
|
-
- **Forgetting property prefixes**: `event_properties.` required for custom events.
|
|
475
|
-
- **Using async API unnecessarily**: Sync API simpler for most cases.
|
|
476
|
-
- **Not handling async errors**: Async API can throw `DynatraceError`.
|
|
477
|
-
- **Calling before DOM ready**: Agent might not be loaded yet.
|
|
478
|
-
- **Invalid property names**: Lowercase, numbers, underscores, dots only.
|
|
479
|
-
|
|
480
|
-
## Development Workflow
|
|
481
|
-
|
|
482
|
-
### Adding New Wrapper Function
|
|
483
|
-
|
|
484
|
-
1. **Identify new RUM API** in agent (`dynatrace` namespace).
|
|
485
|
-
2. **Add types** in `source/types/` directory.
|
|
486
|
-
3. **Implement synchronous wrapper** in `source/api/`:
|
|
487
|
-
- Check `dynatrace` namespace availability.
|
|
488
|
-
- Call underlying API if available.
|
|
489
|
-
- Return appropriate value or undefined.
|
|
490
|
-
4. **Implement asynchronous wrapper** in `source/api/promises/`:
|
|
491
|
-
- Wait for `dynatrace` with timeout.
|
|
492
|
-
- Call underlying API if available.
|
|
493
|
-
- Throw `DynatraceError` on timeout.
|
|
494
|
-
5. **Add JSDoc documentation** with examples.
|
|
495
|
-
6. **Write unit tests** for both sync and async versions.
|
|
496
|
-
7. **Update README.md** with usage examples.
|
|
497
|
-
8. **Test with actual agent** (Gen3).
|
|
498
|
-
9. **Update types.md** if new types added.
|
|
499
|
-
|
|
500
|
-
### Updating Existing Wrapper
|
|
501
|
-
|
|
502
|
-
1. **Check backward compatibility** implications.
|
|
503
|
-
2. **Update type definitions** if signatures changed.
|
|
504
|
-
3. **Modify wrapper implementations** in sync and async.
|
|
505
|
-
4. **Update tests** for new behavior.
|
|
506
|
-
5. **Update documentation** (README, JSDoc).
|
|
507
|
-
6. **Test with existing agent versions** (compatibility).
|
|
508
|
-
7. **Consider deprecation** if breaking change needed.
|
|
509
|
-
|
|
510
|
-
### Testing Changes
|
|
511
|
-
|
|
512
|
-
1. **Run unit tests**: `pnpm test`
|
|
513
|
-
2. **Type check**: Ensure TypeScript compiles.
|
|
514
|
-
3. **Test with mock agent**: Verify wrapper behavior.
|
|
515
|
-
4. **Test with real agent**: Load actual RUM JavaScript.
|
|
516
|
-
5. **Test edge cases**: Missing agent, timeout scenarios.
|
|
517
|
-
6. **Validate examples**: Run README examples.
|
|
518
|
-
7. **Test Playwright fixtures**: Verify testing framework still works.
|
|
519
|
-
- Configure test environment with access token and app ID.
|
|
520
|
-
- Run sample test using `dynatraceTesting` fixture.
|
|
521
|
-
- Verify event assertions function correctly.
|
|
522
|
-
- **Reference**: `testing.md` for testing framework validation.
|
|
523
|
-
|
|
524
|
-
## Build and Distribution
|
|
525
|
-
|
|
526
|
-
### Build Process
|
|
527
|
-
|
|
528
|
-
- **TypeScript compilation**: Source compiled to JavaScript.
|
|
529
|
-
- **Type generation**: `.d.ts` files generated for TypeScript users.
|
|
530
|
-
- **Multiple exports**: Separate entry points for api, promises, types, test.
|
|
531
|
-
- **Tree-shakeable**: Side-effect free, customers only bundle what they use.
|
|
532
|
-
|
|
533
|
-
### Package Exports
|
|
534
|
-
|
|
535
|
-
- `@dynatrace/rum-javascript-api` - Main export (types re-export).
|
|
536
|
-
- `@dynatrace/rum-javascript-api/api` - Synchronous wrappers.
|
|
537
|
-
- `@dynatrace/rum-javascript-api/api/promises` - Asynchronous wrappers.
|
|
538
|
-
- `@dynatrace/rum-javascript-api/types` - TypeScript type definitions.
|
|
539
|
-
- `@dynatrace/rum-javascript-api/test` - Playwright testing utilities.
|
|
540
|
-
|
|
541
|
-
### Build Commands
|
|
542
|
-
|
|
543
|
-
- `pnpm build`: Compile TypeScript to JavaScript.
|
|
544
|
-
- `pnpm test`: Run Vitest unit tests with coverage.
|
|
545
|
-
- `pnpm lint`: Lint TypeScript source files.
|
|
546
|
-
|
|
547
|
-
## Documentation Maintenance
|
|
548
|
-
|
|
549
|
-
### Keep in Sync
|
|
550
|
-
|
|
551
|
-
Update documentation when:
|
|
552
|
-
- **New wrapper added**: Update README API reference with function signature and examples.
|
|
553
|
-
- **Type changed**: Update types.md with new type exports and usage patterns.
|
|
554
|
-
- **Testing utilities updated**: Update testing.md with new fixture methods and examples.
|
|
555
|
-
- **TypeScript configuration changed**: Update types.md `tsconfig.json` setup instructions.
|
|
556
|
-
- **Test setup changed**: Update testing.md setup requirements (token, environment, app ID).
|
|
557
|
-
- **Best practices identified**: Add to README best practices section.
|
|
558
|
-
- **Common issue found**: Add to README troubleshooting or testing.md troubleshooting.
|
|
559
|
-
- **New testing pattern discovered**: Add example to testing.md patterns section.
|
|
560
|
-
|
|
561
|
-
### Documentation Files
|
|
562
|
-
|
|
563
|
-
- **README.md**: Primary customer documentation.
|
|
564
|
-
- Installation via npm.
|
|
565
|
-
- API reference for all wrapper functions (sync and async).
|
|
566
|
-
- Error handling with `DynatraceError`.
|
|
567
|
-
- Usage examples and best practices.
|
|
568
|
-
- Event property naming conventions.
|
|
569
|
-
|
|
570
|
-
- **types.md**: TypeScript integration guide.
|
|
571
|
-
- TypeScript configuration (`typeRoots` setup).
|
|
572
|
-
- Global `window.dynatrace` type augmentation.
|
|
573
|
-
- Type import examples from package.
|
|
574
|
-
- Type inference patterns.
|
|
575
|
-
|
|
576
|
-
- **testing.md**: Playwright testing framework.
|
|
577
|
-
- Setup: access token, environment URL, app ID.
|
|
578
|
-
- `DynatraceTesting` fixture complete API reference.
|
|
579
|
-
- Test configuration with `test.use()`.
|
|
580
|
-
- Event assertion methods with timeout options.
|
|
581
|
-
- Testing patterns and troubleshooting.
|
|
582
|
-
|
|
583
|
-
- **AGENTS.md** (this file): Internal development guide for maintainers.
|
|
584
|
-
|
|
585
|
-
**Note**: Any enhancement must maintain backward compatibility and not add significant overhead.
|