@rushobservability/rum-sdk 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +70 -0
- package/dist/browser.d.ts +11 -0
- package/dist/browser.d.ts.map +1 -0
- package/dist/browser.js +63 -0
- package/dist/browser.js.map +1 -0
- package/dist/core.d.ts +6 -0
- package/dist/core.d.ts.map +1 -0
- package/dist/core.js +115 -0
- package/dist/core.js.map +1 -0
- package/dist/errors.d.ts +2 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +32 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +46 -0
- package/dist/index.js.map +1 -0
- package/dist/interactions.d.ts +2 -0
- package/dist/interactions.d.ts.map +1 -0
- package/dist/interactions.js +24 -0
- package/dist/interactions.js.map +1 -0
- package/dist/pageview.d.ts +2 -0
- package/dist/pageview.d.ts.map +1 -0
- package/dist/pageview.js +51 -0
- package/dist/pageview.js.map +1 -0
- package/dist/replay.d.ts +9 -0
- package/dist/replay.d.ts.map +1 -0
- package/dist/replay.js +62 -0
- package/dist/replay.js.map +1 -0
- package/dist/resources.d.ts +2 -0
- package/dist/resources.d.ts.map +1 -0
- package/dist/resources.js +97 -0
- package/dist/resources.js.map +1 -0
- package/dist/session.d.ts +3 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +39 -0
- package/dist/session.js.map +1 -0
- package/dist/types.d.ts +63 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/vitals.d.ts +2 -0
- package/dist/vitals.d.ts.map +1 -0
- package/dist/vitals.js +22 -0
- package/dist/vitals.js.map +1 -0
- package/package.json +38 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Rush Observability
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# @rushobservability/rum-sdk
|
|
2
|
+
|
|
3
|
+
Real User Monitoring (RUM) browser SDK for [Rush Observability](https://github.com/RushObservability). Lightweight, dependency-light, and framework-agnostic — it captures Web Vitals, JS errors, page views, interactions, resource timing, and optional session replay, then ships them to your Rush ingest endpoint.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @rushobservability/rum-sdk
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
import RushRUM from '@rushobservability/rum-sdk'
|
|
15
|
+
|
|
16
|
+
RushRUM.init({
|
|
17
|
+
endpoint: 'https://your-rush-host/rum/ingest',
|
|
18
|
+
app: { name: 'my-web-app', version: '1.4.2' },
|
|
19
|
+
environment: 'production',
|
|
20
|
+
|
|
21
|
+
// What to collect (defaults shown)
|
|
22
|
+
trackWebVitals: true, // LCP, INP, CLS, FCP, TTFB (via web-vitals)
|
|
23
|
+
trackErrors: true, // uncaught errors + unhandled rejections
|
|
24
|
+
trackPageViews: true, // SPA-aware page views
|
|
25
|
+
trackInteractions: false, // click/input interaction events
|
|
26
|
+
trackResources: false, // resource timing entries
|
|
27
|
+
trackSessionReplay: false,// DOM session replay (via rrweb)
|
|
28
|
+
|
|
29
|
+
// Optional
|
|
30
|
+
sampleRate: 1.0, // 0..1
|
|
31
|
+
user: () => ({ id: currentUserId }), // attach a user id
|
|
32
|
+
propagateTraces: { origins: [/^https:\/\/api\.example\.com/] },
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
// Custom events
|
|
36
|
+
RushRUM.trackEvent('checkout_completed', { plan: 'pro', amount: 49 })
|
|
37
|
+
|
|
38
|
+
// Flush the queue manually (e.g. before a hard navigation)
|
|
39
|
+
RushRUM.flush()
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Configuration
|
|
43
|
+
|
|
44
|
+
| Option | Type | Default | Description |
|
|
45
|
+
|---|---|---|---|
|
|
46
|
+
| `endpoint` | `string` | — (required) | Rush RUM ingest URL |
|
|
47
|
+
| `app` | `{ name, version? }` | — (required) | Application identity |
|
|
48
|
+
| `environment` | `string` | — | e.g. `production`, `staging` |
|
|
49
|
+
| `sampleRate` | `number` | `1.0` | Fraction of sessions to record (0–1) |
|
|
50
|
+
| `user` | `() => { id? } \| null` | — | Resolver for the current user id |
|
|
51
|
+
| `trackWebVitals` | `boolean` | `true` | Core Web Vitals |
|
|
52
|
+
| `trackErrors` | `boolean` | `true` | Uncaught errors + promise rejections |
|
|
53
|
+
| `trackPageViews` | `boolean` | `true` | SPA-aware page views |
|
|
54
|
+
| `trackInteractions` | `boolean` | `false` | Click/input events |
|
|
55
|
+
| `trackResources` | `boolean` | `false` | Resource timing |
|
|
56
|
+
| `trackSessionReplay` | `boolean` | `false` | DOM session replay (rrweb) |
|
|
57
|
+
| `propagateTraces` | `{ origins: RegExp[] }` | — | Inject trace headers on matching XHR/fetch origins |
|
|
58
|
+
| `replayEndpoint` | `string` | `<endpoint>/rum/replay/ingest` | Override the replay ingest URL |
|
|
59
|
+
|
|
60
|
+
## Build
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
npm install
|
|
64
|
+
npm run build # tsc → dist/
|
|
65
|
+
npm run typecheck # type-check only
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## License
|
|
69
|
+
|
|
70
|
+
[MIT](LICENSE)
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface BrowserInfo {
|
|
2
|
+
browserName: string;
|
|
3
|
+
browserVersion: string;
|
|
4
|
+
osName: string;
|
|
5
|
+
osVersion: string;
|
|
6
|
+
deviceType: 'desktop' | 'mobile' | 'tablet';
|
|
7
|
+
screenWidth: number;
|
|
8
|
+
screenHeight: number;
|
|
9
|
+
}
|
|
10
|
+
export declare function detectBrowser(): BrowserInfo;
|
|
11
|
+
//# sourceMappingURL=browser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,CAAA;IACnB,cAAc,EAAE,MAAM,CAAA;IACtB,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,SAAS,GAAG,QAAQ,GAAG,QAAQ,CAAA;IAC3C,WAAW,EAAE,MAAM,CAAA;IACnB,YAAY,EAAE,MAAM,CAAA;CACrB;AAED,wBAAgB,aAAa,IAAI,WAAW,CA0D3C"}
|
package/dist/browser.js
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
export function detectBrowser() {
|
|
2
|
+
const ua = navigator.userAgent;
|
|
3
|
+
let browserName = 'Unknown';
|
|
4
|
+
let browserVersion = '';
|
|
5
|
+
if (ua.includes('Firefox/')) {
|
|
6
|
+
browserName = 'Firefox';
|
|
7
|
+
browserVersion = ua.split('Firefox/')[1]?.split(' ')[0] ?? '';
|
|
8
|
+
}
|
|
9
|
+
else if (ua.includes('Edg/')) {
|
|
10
|
+
browserName = 'Edge';
|
|
11
|
+
browserVersion = ua.split('Edg/')[1]?.split(' ')[0] ?? '';
|
|
12
|
+
}
|
|
13
|
+
else if (ua.includes('Chrome/')) {
|
|
14
|
+
browserName = 'Chrome';
|
|
15
|
+
browserVersion = ua.split('Chrome/')[1]?.split(' ')[0] ?? '';
|
|
16
|
+
}
|
|
17
|
+
else if (ua.includes('Safari/') && !ua.includes('Chrome')) {
|
|
18
|
+
browserName = 'Safari';
|
|
19
|
+
browserVersion = ua.split('Version/')[1]?.split(' ')[0] ?? '';
|
|
20
|
+
}
|
|
21
|
+
let osName = 'Unknown';
|
|
22
|
+
let osVersion = '';
|
|
23
|
+
if (ua.includes('Windows')) {
|
|
24
|
+
osName = 'Windows';
|
|
25
|
+
const m = ua.match(/Windows NT (\d+\.\d+)/);
|
|
26
|
+
osVersion = m?.[1] ?? '';
|
|
27
|
+
}
|
|
28
|
+
else if (ua.includes('Mac OS X')) {
|
|
29
|
+
osName = 'macOS';
|
|
30
|
+
const m = ua.match(/Mac OS X (\d+[._]\d+[._]?\d*)/);
|
|
31
|
+
osVersion = m?.[1]?.replace(/_/g, '.') ?? '';
|
|
32
|
+
}
|
|
33
|
+
else if (ua.includes('Linux')) {
|
|
34
|
+
osName = 'Linux';
|
|
35
|
+
}
|
|
36
|
+
else if (ua.includes('Android')) {
|
|
37
|
+
osName = 'Android';
|
|
38
|
+
const m = ua.match(/Android (\d+(\.\d+)?)/);
|
|
39
|
+
osVersion = m?.[1] ?? '';
|
|
40
|
+
}
|
|
41
|
+
else if (/iPhone|iPad|iPod/.test(ua)) {
|
|
42
|
+
osName = 'iOS';
|
|
43
|
+
const m = ua.match(/OS (\d+_\d+)/);
|
|
44
|
+
osVersion = m?.[1]?.replace('_', '.') ?? '';
|
|
45
|
+
}
|
|
46
|
+
let deviceType = 'desktop';
|
|
47
|
+
if (/Mobi|Android.*Mobile/.test(ua)) {
|
|
48
|
+
deviceType = 'mobile';
|
|
49
|
+
}
|
|
50
|
+
else if (/iPad|Android(?!.*Mobile)|Tablet/.test(ua)) {
|
|
51
|
+
deviceType = 'tablet';
|
|
52
|
+
}
|
|
53
|
+
return {
|
|
54
|
+
browserName,
|
|
55
|
+
browserVersion,
|
|
56
|
+
osName,
|
|
57
|
+
osVersion,
|
|
58
|
+
deviceType,
|
|
59
|
+
screenWidth: window.screen.width,
|
|
60
|
+
screenHeight: window.screen.height,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=browser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser.js","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"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"}
|
package/dist/core.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { RumEvent, RushRUMConfig } from './types';
|
|
2
|
+
export declare function configure(cfg: RushRUMConfig): void;
|
|
3
|
+
export declare function getConfig(): RushRUMConfig | null;
|
|
4
|
+
export declare function pushEvent(event: RumEvent): void;
|
|
5
|
+
export declare function flush(): void;
|
|
6
|
+
//# sourceMappingURL=core.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAuB,aAAa,EAAE,MAAM,SAAS,CAAA;AAY3E,wBAAgB,SAAS,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI,CAKlD;AAED,wBAAgB,SAAS,IAAI,aAAa,GAAG,IAAI,CAEhD;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI,CAY/C;AA+BD,wBAAgB,KAAK,IAAI,IAAI,CAoB5B"}
|
package/dist/core.js
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { getSessionId } from './session';
|
|
2
|
+
import { detectBrowser } from './browser';
|
|
3
|
+
const MAX_BATCH = 30;
|
|
4
|
+
const FLUSH_INTERVAL_MS = 250;
|
|
5
|
+
let config = null;
|
|
6
|
+
let queue = [];
|
|
7
|
+
let flushTimer = null;
|
|
8
|
+
let browserInfo = null;
|
|
9
|
+
export function configure(cfg) {
|
|
10
|
+
config = cfg;
|
|
11
|
+
browserInfo = detectBrowser();
|
|
12
|
+
startFlushTimer();
|
|
13
|
+
setupBeaconFlush();
|
|
14
|
+
}
|
|
15
|
+
export function getConfig() {
|
|
16
|
+
return config;
|
|
17
|
+
}
|
|
18
|
+
export function pushEvent(event) {
|
|
19
|
+
if (!config)
|
|
20
|
+
return;
|
|
21
|
+
if (config.sampleRate !== undefined && config.sampleRate < 1) {
|
|
22
|
+
if (Math.random() > config.sampleRate)
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
event.timestamp = event.timestamp ?? Date.now() * 1000000; // ns
|
|
26
|
+
queue.push(event);
|
|
27
|
+
if (queue.length >= MAX_BATCH) {
|
|
28
|
+
flush();
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
function buildMeta() {
|
|
32
|
+
const cfg = config;
|
|
33
|
+
const bi = browserInfo;
|
|
34
|
+
let userId = '';
|
|
35
|
+
try {
|
|
36
|
+
const u = cfg.user?.();
|
|
37
|
+
userId = u?.id ?? '';
|
|
38
|
+
}
|
|
39
|
+
catch { /* ignore */ }
|
|
40
|
+
return {
|
|
41
|
+
app_name: cfg.app.name,
|
|
42
|
+
app_version: cfg.app.version ?? '',
|
|
43
|
+
environment: cfg.environment ?? '',
|
|
44
|
+
session_id: getSessionId(),
|
|
45
|
+
user_id: userId,
|
|
46
|
+
page_url: location.href,
|
|
47
|
+
page_path: location.pathname,
|
|
48
|
+
view_name: document.title,
|
|
49
|
+
referrer: document.referrer,
|
|
50
|
+
browser_name: bi.browserName,
|
|
51
|
+
browser_version: bi.browserVersion,
|
|
52
|
+
os_name: bi.osName,
|
|
53
|
+
os_version: bi.osVersion,
|
|
54
|
+
device_type: bi.deviceType,
|
|
55
|
+
screen_width: bi.screenWidth,
|
|
56
|
+
screen_height: bi.screenHeight,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
export function flush() {
|
|
60
|
+
if (!config || queue.length === 0)
|
|
61
|
+
return;
|
|
62
|
+
const events = queue.splice(0, MAX_BATCH);
|
|
63
|
+
const payload = {
|
|
64
|
+
meta: buildMeta(),
|
|
65
|
+
events,
|
|
66
|
+
};
|
|
67
|
+
const body = JSON.stringify(payload);
|
|
68
|
+
// Try fetch first, fallback silently
|
|
69
|
+
fetch(config.endpoint, {
|
|
70
|
+
method: 'POST',
|
|
71
|
+
headers: { 'Content-Type': 'application/json' },
|
|
72
|
+
body,
|
|
73
|
+
keepalive: true,
|
|
74
|
+
}).catch(() => {
|
|
75
|
+
// Silently drop — RUM data is best-effort
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
function startFlushTimer() {
|
|
79
|
+
if (flushTimer)
|
|
80
|
+
return;
|
|
81
|
+
flushTimer = setInterval(() => {
|
|
82
|
+
if (queue.length > 0)
|
|
83
|
+
flush();
|
|
84
|
+
}, FLUSH_INTERVAL_MS);
|
|
85
|
+
}
|
|
86
|
+
function setupBeaconFlush() {
|
|
87
|
+
if (typeof document === 'undefined')
|
|
88
|
+
return;
|
|
89
|
+
const beaconFlush = () => {
|
|
90
|
+
if (!config || queue.length === 0)
|
|
91
|
+
return;
|
|
92
|
+
const events = queue.splice(0);
|
|
93
|
+
const payload = { meta: buildMeta(), events };
|
|
94
|
+
const body = JSON.stringify(payload);
|
|
95
|
+
if (navigator.sendBeacon) {
|
|
96
|
+
navigator.sendBeacon(config.endpoint, body);
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
// Sync XHR as last resort (not recommended but works for unload)
|
|
100
|
+
try {
|
|
101
|
+
const xhr = new XMLHttpRequest();
|
|
102
|
+
xhr.open('POST', config.endpoint, false);
|
|
103
|
+
xhr.setRequestHeader('Content-Type', 'application/json');
|
|
104
|
+
xhr.send(body);
|
|
105
|
+
}
|
|
106
|
+
catch { /* ignore */ }
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
document.addEventListener('visibilitychange', () => {
|
|
110
|
+
if (document.visibilityState === 'hidden')
|
|
111
|
+
beaconFlush();
|
|
112
|
+
});
|
|
113
|
+
window.addEventListener('pagehide', beaconFlush);
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=core.js.map
|
package/dist/core.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"core.js","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"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"}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAEA,wBAAgB,UAAU,IAAI,IAAI,CA+BjC"}
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { pushEvent } from './core';
|
|
2
|
+
export function initErrors() {
|
|
3
|
+
window.addEventListener('error', (event) => {
|
|
4
|
+
pushEvent({
|
|
5
|
+
event_type: 'error',
|
|
6
|
+
error_message: event.message || 'Unknown error',
|
|
7
|
+
error_stack: event.error?.stack ?? '',
|
|
8
|
+
error_type: event.error?.name ?? 'Error',
|
|
9
|
+
});
|
|
10
|
+
});
|
|
11
|
+
window.addEventListener('unhandledrejection', (event) => {
|
|
12
|
+
const reason = event.reason;
|
|
13
|
+
let message = 'Unhandled promise rejection';
|
|
14
|
+
let stack = '';
|
|
15
|
+
let errorType = 'UnhandledRejection';
|
|
16
|
+
if (reason instanceof Error) {
|
|
17
|
+
message = reason.message;
|
|
18
|
+
stack = reason.stack ?? '';
|
|
19
|
+
errorType = reason.name;
|
|
20
|
+
}
|
|
21
|
+
else if (typeof reason === 'string') {
|
|
22
|
+
message = reason;
|
|
23
|
+
}
|
|
24
|
+
pushEvent({
|
|
25
|
+
event_type: 'error',
|
|
26
|
+
error_message: message,
|
|
27
|
+
error_stack: stack,
|
|
28
|
+
error_type: errorType,
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAA;AAElC,MAAM,UAAU,UAAU;IACxB,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC,KAAiB,EAAE,EAAE;QACrD,SAAS,CAAC;YACR,UAAU,EAAE,OAAO;YACnB,aAAa,EAAE,KAAK,CAAC,OAAO,IAAI,eAAe;YAC/C,WAAW,EAAE,KAAK,CAAC,KAAK,EAAE,KAAK,IAAI,EAAE;YACrC,UAAU,EAAE,KAAK,CAAC,KAAK,EAAE,IAAI,IAAI,OAAO;SACzC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,MAAM,CAAC,gBAAgB,CAAC,oBAAoB,EAAE,CAAC,KAA4B,EAAE,EAAE;QAC7E,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAA;QAC3B,IAAI,OAAO,GAAG,6BAA6B,CAAA;QAC3C,IAAI,KAAK,GAAG,EAAE,CAAA;QACd,IAAI,SAAS,GAAG,oBAAoB,CAAA;QAEpC,IAAI,MAAM,YAAY,KAAK,EAAE,CAAC;YAC5B,OAAO,GAAG,MAAM,CAAC,OAAO,CAAA;YACxB,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,EAAE,CAAA;YAC1B,SAAS,GAAG,MAAM,CAAC,IAAI,CAAA;QACzB,CAAC;aAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;YACtC,OAAO,GAAG,MAAM,CAAA;QAClB,CAAC;QAED,SAAS,CAAC;YACR,UAAU,EAAE,OAAO;YACnB,aAAa,EAAE,OAAO;YACtB,WAAW,EAAE,KAAK;YAClB,UAAU,EAAE,SAAS;SACtB,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { RushRUMConfig } from './types';
|
|
2
|
+
import { flush } from './core';
|
|
3
|
+
export type { RushRUMConfig, RumEvent, RumPayload } from './types';
|
|
4
|
+
export declare const RushRUM: {
|
|
5
|
+
init(config: RushRUMConfig): void;
|
|
6
|
+
/**
|
|
7
|
+
* Send a custom event.
|
|
8
|
+
*/
|
|
9
|
+
trackEvent(name: string, attributes?: Record<string, unknown>): void;
|
|
10
|
+
/**
|
|
11
|
+
* Force flush the event queue.
|
|
12
|
+
*/
|
|
13
|
+
flush: typeof flush;
|
|
14
|
+
};
|
|
15
|
+
export default RushRUM;
|
|
16
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAC5C,OAAO,EAAa,KAAK,EAAa,MAAM,QAAQ,CAAA;AAQpD,YAAY,EAAE,aAAa,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAElE,eAAO,MAAM,OAAO;iBACL,aAAa,GAAG,IAAI;IAuBjC;;OAEG;qBACc,MAAM,eAAe,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAQpE;;OAEG;;CAEJ,CAAA;AAED,eAAe,OAAO,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { configure, flush, pushEvent } from './core';
|
|
2
|
+
import { initVitals } from './vitals';
|
|
3
|
+
import { initErrors } from './errors';
|
|
4
|
+
import { initPageViews } from './pageview';
|
|
5
|
+
import { initInteractions } from './interactions';
|
|
6
|
+
import { initResources } from './resources';
|
|
7
|
+
import { initReplay } from './replay';
|
|
8
|
+
export const RushRUM = {
|
|
9
|
+
init(config) {
|
|
10
|
+
configure(config);
|
|
11
|
+
if (config.trackWebVitals !== false) {
|
|
12
|
+
initVitals();
|
|
13
|
+
}
|
|
14
|
+
if (config.trackErrors !== false) {
|
|
15
|
+
initErrors();
|
|
16
|
+
}
|
|
17
|
+
if (config.trackPageViews !== false) {
|
|
18
|
+
initPageViews();
|
|
19
|
+
}
|
|
20
|
+
if (config.trackInteractions === true) {
|
|
21
|
+
initInteractions();
|
|
22
|
+
}
|
|
23
|
+
if (config.trackResources === true) {
|
|
24
|
+
initResources();
|
|
25
|
+
}
|
|
26
|
+
if (config.trackSessionReplay === true) {
|
|
27
|
+
initReplay(config);
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
/**
|
|
31
|
+
* Send a custom event.
|
|
32
|
+
*/
|
|
33
|
+
trackEvent(name, attributes) {
|
|
34
|
+
pushEvent({
|
|
35
|
+
event_type: 'custom',
|
|
36
|
+
event_name: name,
|
|
37
|
+
attributes: attributes ? JSON.stringify(attributes) : undefined,
|
|
38
|
+
});
|
|
39
|
+
},
|
|
40
|
+
/**
|
|
41
|
+
* Force flush the event queue.
|
|
42
|
+
*/
|
|
43
|
+
flush,
|
|
44
|
+
};
|
|
45
|
+
export default RushRUM;
|
|
46
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAA;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AACrC,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAC1C,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAIrC,MAAM,CAAC,MAAM,OAAO,GAAG;IACrB,IAAI,CAAC,MAAqB;QACxB,SAAS,CAAC,MAAM,CAAC,CAAA;QAEjB,IAAI,MAAM,CAAC,cAAc,KAAK,KAAK,EAAE,CAAC;YACpC,UAAU,EAAE,CAAA;QACd,CAAC;QACD,IAAI,MAAM,CAAC,WAAW,KAAK,KAAK,EAAE,CAAC;YACjC,UAAU,EAAE,CAAA;QACd,CAAC;QACD,IAAI,MAAM,CAAC,cAAc,KAAK,KAAK,EAAE,CAAC;YACpC,aAAa,EAAE,CAAA;QACjB,CAAC;QACD,IAAI,MAAM,CAAC,iBAAiB,KAAK,IAAI,EAAE,CAAC;YACtC,gBAAgB,EAAE,CAAA;QACpB,CAAC;QACD,IAAI,MAAM,CAAC,cAAc,KAAK,IAAI,EAAE,CAAC;YACnC,aAAa,EAAE,CAAA;QACjB,CAAC;QACD,IAAI,MAAM,CAAC,kBAAkB,KAAK,IAAI,EAAE,CAAC;YACvC,UAAU,CAAC,MAAM,CAAC,CAAA;QACpB,CAAC;IACH,CAAC;IAED;;OAEG;IACH,UAAU,CAAC,IAAY,EAAE,UAAoC;QAC3D,SAAS,CAAC;YACR,UAAU,EAAE,QAAQ;YACpB,UAAU,EAAE,IAAI;YAChB,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,SAAS;SAChE,CAAC,CAAA;IACJ,CAAC;IAED;;OAEG;IACH,KAAK;CACN,CAAA;AAED,eAAe,OAAO,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interactions.d.ts","sourceRoot":"","sources":["../src/interactions.ts"],"names":[],"mappings":"AAIA,wBAAgB,gBAAgB,IAAI,IAAI,CAqBvC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { pushEvent } from './core';
|
|
2
|
+
const INTERACTIVE_SELECTORS = 'button, a, [role="button"], input[type="submit"], input[type="button"]';
|
|
3
|
+
export function initInteractions() {
|
|
4
|
+
document.addEventListener('click', (event) => {
|
|
5
|
+
const target = event.target;
|
|
6
|
+
if (!target)
|
|
7
|
+
return;
|
|
8
|
+
const interactive = target.closest(INTERACTIVE_SELECTORS);
|
|
9
|
+
if (!interactive)
|
|
10
|
+
return;
|
|
11
|
+
const tag = interactive.tagName.toLowerCase();
|
|
12
|
+
const text = (interactive.textContent ?? '').trim().slice(0, 100);
|
|
13
|
+
const id = interactive.id ? `#${interactive.id}` : '';
|
|
14
|
+
const classes = interactive.className
|
|
15
|
+
? `.${Array.from(interactive.classList).slice(0, 3).join('.')}`
|
|
16
|
+
: '';
|
|
17
|
+
pushEvent({
|
|
18
|
+
event_type: 'interaction',
|
|
19
|
+
interaction_type: 'click',
|
|
20
|
+
interaction_target: `${tag}${id}${classes}${text ? ` "${text}"` : ''}`,
|
|
21
|
+
});
|
|
22
|
+
}, { capture: true, passive: true });
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=interactions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interactions.js","sourceRoot":"","sources":["../src/interactions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAA;AAElC,MAAM,qBAAqB,GAAG,wEAAwE,CAAA;AAEtG,MAAM,UAAU,gBAAgB;IAC9B,QAAQ,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC,KAAiB,EAAE,EAAE;QACvD,MAAM,MAAM,GAAG,KAAK,CAAC,MAAwB,CAAA;QAC7C,IAAI,CAAC,MAAM;YAAE,OAAM;QAEnB,MAAM,WAAW,GAAG,MAAM,CAAC,OAAO,CAAC,qBAAqB,CAAC,CAAA;QACzD,IAAI,CAAC,WAAW;YAAE,OAAM;QAExB,MAAM,GAAG,GAAG,WAAW,CAAC,OAAO,CAAC,WAAW,EAAE,CAAA;QAC7C,MAAM,IAAI,GAAG,CAAC,WAAW,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;QACjE,MAAM,EAAE,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,WAAW,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;QACrD,MAAM,OAAO,GAAG,WAAW,CAAC,SAAS;YACnC,CAAC,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;YAC/D,CAAC,CAAC,EAAE,CAAA;QAEN,SAAS,CAAC;YACR,UAAU,EAAE,aAAa;YACzB,gBAAgB,EAAE,OAAO;YACzB,kBAAkB,EAAE,GAAG,GAAG,GAAG,EAAE,GAAG,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;SACvE,CAAC,CAAA;IACJ,CAAC,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAA;AACtC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pageview.d.ts","sourceRoot":"","sources":["../src/pageview.ts"],"names":[],"mappings":"AAEA,wBAAgB,aAAa,IAAI,IAAI,CAsBpC"}
|
package/dist/pageview.js
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { pushEvent } from './core';
|
|
2
|
+
export function initPageViews() {
|
|
3
|
+
// Track initial page load
|
|
4
|
+
trackPageView();
|
|
5
|
+
// SPA navigation: history.pushState / replaceState
|
|
6
|
+
const origPush = history.pushState.bind(history);
|
|
7
|
+
const origReplace = history.replaceState.bind(history);
|
|
8
|
+
history.pushState = function (...args) {
|
|
9
|
+
origPush(...args);
|
|
10
|
+
trackPageView();
|
|
11
|
+
};
|
|
12
|
+
history.replaceState = function (...args) {
|
|
13
|
+
origReplace(...args);
|
|
14
|
+
trackPageView();
|
|
15
|
+
};
|
|
16
|
+
// Back/forward navigation
|
|
17
|
+
window.addEventListener('popstate', () => {
|
|
18
|
+
trackPageView();
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
function generateTraceId() {
|
|
22
|
+
const bytes = new Uint8Array(16);
|
|
23
|
+
crypto.getRandomValues(bytes);
|
|
24
|
+
return Array.from(bytes).map((b) => b.toString(16).padStart(2, '0')).join('');
|
|
25
|
+
}
|
|
26
|
+
function generateSpanId() {
|
|
27
|
+
const bytes = new Uint8Array(8);
|
|
28
|
+
crypto.getRandomValues(bytes);
|
|
29
|
+
return Array.from(bytes).map((b) => b.toString(16).padStart(2, '0')).join('');
|
|
30
|
+
}
|
|
31
|
+
function trackPageView() {
|
|
32
|
+
const traceId = generateTraceId();
|
|
33
|
+
const spanId = generateSpanId();
|
|
34
|
+
pushEvent({
|
|
35
|
+
event_type: 'pageview',
|
|
36
|
+
event_name: document.title,
|
|
37
|
+
duration_ms: getNavigationLoadTime(),
|
|
38
|
+
trace_id: traceId,
|
|
39
|
+
span_id: spanId,
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
function getNavigationLoadTime() {
|
|
43
|
+
if (typeof performance === 'undefined')
|
|
44
|
+
return 0;
|
|
45
|
+
const entries = performance.getEntriesByType('navigation');
|
|
46
|
+
if (entries.length > 0) {
|
|
47
|
+
return entries[0].loadEventEnd - entries[0].startTime;
|
|
48
|
+
}
|
|
49
|
+
return 0;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=pageview.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pageview.js","sourceRoot":"","sources":["../src/pageview.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAA;AAElC,MAAM,UAAU,aAAa;IAC3B,0BAA0B;IAC1B,aAAa,EAAE,CAAA;IAEf,mDAAmD;IACnD,MAAM,QAAQ,GAAG,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;IAChD,MAAM,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;IAEtD,OAAO,CAAC,SAAS,GAAG,UAAU,GAAG,IAAiC;QAChE,QAAQ,CAAC,GAAG,IAAI,CAAC,CAAA;QACjB,aAAa,EAAE,CAAA;IACjB,CAAC,CAAA;IAED,OAAO,CAAC,YAAY,GAAG,UAAU,GAAG,IAAoC;QACtE,WAAW,CAAC,GAAG,IAAI,CAAC,CAAA;QACpB,aAAa,EAAE,CAAA;IACjB,CAAC,CAAA;IAED,0BAA0B;IAC1B,MAAM,CAAC,gBAAgB,CAAC,UAAU,EAAE,GAAG,EAAE;QACvC,aAAa,EAAE,CAAA;IACjB,CAAC,CAAC,CAAA;AACJ,CAAC;AAED,SAAS,eAAe;IACtB,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,EAAE,CAAC,CAAA;IAChC,MAAM,CAAC,eAAe,CAAC,KAAK,CAAC,CAAA;IAC7B,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;AAC/E,CAAC;AAED,SAAS,cAAc;IACrB,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,CAAA;IAC/B,MAAM,CAAC,eAAe,CAAC,KAAK,CAAC,CAAA;IAC7B,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;AAC/E,CAAC;AAED,SAAS,aAAa;IACpB,MAAM,OAAO,GAAG,eAAe,EAAE,CAAA;IACjC,MAAM,MAAM,GAAG,cAAc,EAAE,CAAA;IAE/B,SAAS,CAAC;QACR,UAAU,EAAE,UAAU;QACtB,UAAU,EAAE,QAAQ,CAAC,KAAK;QAC1B,WAAW,EAAE,qBAAqB,EAAE;QACpC,QAAQ,EAAE,OAAO;QACjB,OAAO,EAAE,MAAM;KAChB,CAAC,CAAA;AACJ,CAAC;AAED,SAAS,qBAAqB;IAC5B,IAAI,OAAO,WAAW,KAAK,WAAW;QAAE,OAAO,CAAC,CAAA;IAChD,MAAM,OAAO,GAAG,WAAW,CAAC,gBAAgB,CAAC,YAAY,CAAkC,CAAA;IAC3F,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,OAAO,OAAO,CAAC,CAAC,CAAC,CAAC,YAAY,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IACvD,CAAC;IACD,OAAO,CAAC,CAAA;AACV,CAAC"}
|
package/dist/replay.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session replay recorder — captures rrweb DOM snapshots and mutation events
|
|
3
|
+
* and streams them in chunks to the Rush replay ingest endpoint.
|
|
4
|
+
*
|
|
5
|
+
* Must be called only after `configure()` (i.e. inside `RushRUM.init`).
|
|
6
|
+
*/
|
|
7
|
+
import type { RushRUMConfig } from './types';
|
|
8
|
+
export declare function initReplay(config: RushRUMConfig): void;
|
|
9
|
+
//# sourceMappingURL=replay.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"replay.d.ts","sourceRoot":"","sources":["../src/replay.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAyC5C,wBAAgB,UAAU,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI,CAyBtD"}
|
package/dist/replay.js
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { getSessionId } from './session';
|
|
2
|
+
const CHUNK_SIZE = 50; // flush after this many events
|
|
3
|
+
const FLUSH_INTERVAL_MS = 5000; // flush every 5 s regardless
|
|
4
|
+
let _config = null;
|
|
5
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
6
|
+
let _buffer = [];
|
|
7
|
+
let _chunkIdx = 0;
|
|
8
|
+
let _flushTimer = null;
|
|
9
|
+
function replayEndpoint() {
|
|
10
|
+
const cfg = _config;
|
|
11
|
+
if (cfg.replayEndpoint)
|
|
12
|
+
return cfg.replayEndpoint;
|
|
13
|
+
// Derive from the event ingest endpoint: replace /rum/ingest with /rum/replay/ingest
|
|
14
|
+
return cfg.endpoint.replace(/\/rum\/ingest$/, '/rum/replay/ingest');
|
|
15
|
+
}
|
|
16
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
17
|
+
function sendChunk(events) {
|
|
18
|
+
if (!_config || events.length === 0)
|
|
19
|
+
return;
|
|
20
|
+
const payload = {
|
|
21
|
+
session_id: getSessionId(),
|
|
22
|
+
app_name: _config.app.name,
|
|
23
|
+
chunk_idx: _chunkIdx++,
|
|
24
|
+
events,
|
|
25
|
+
};
|
|
26
|
+
fetch(replayEndpoint(), {
|
|
27
|
+
method: 'POST',
|
|
28
|
+
headers: { 'Content-Type': 'application/json' },
|
|
29
|
+
body: JSON.stringify(payload),
|
|
30
|
+
keepalive: true,
|
|
31
|
+
}).catch(() => { });
|
|
32
|
+
}
|
|
33
|
+
function flushBuffer() {
|
|
34
|
+
if (_buffer.length === 0)
|
|
35
|
+
return;
|
|
36
|
+
sendChunk(_buffer.splice(0));
|
|
37
|
+
}
|
|
38
|
+
export function initReplay(config) {
|
|
39
|
+
_config = config;
|
|
40
|
+
// Dynamically import rrweb so it doesn't bloat pages that don't enable replay
|
|
41
|
+
import('rrweb').then(({ record }) => {
|
|
42
|
+
record({
|
|
43
|
+
emit(event) {
|
|
44
|
+
_buffer.push(event);
|
|
45
|
+
if (_buffer.length >= CHUNK_SIZE) {
|
|
46
|
+
flushBuffer();
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
maskAllInputs: true, // mask form fields for privacy
|
|
50
|
+
maskTextSelector: '[data-pii]', // opt-in masking of PII text nodes
|
|
51
|
+
});
|
|
52
|
+
}).catch(() => {
|
|
53
|
+
// rrweb not installed — replay silently disabled
|
|
54
|
+
});
|
|
55
|
+
_flushTimer = setInterval(flushBuffer, FLUSH_INTERVAL_MS);
|
|
56
|
+
document.addEventListener('visibilitychange', () => {
|
|
57
|
+
if (document.visibilityState === 'hidden')
|
|
58
|
+
flushBuffer();
|
|
59
|
+
});
|
|
60
|
+
window.addEventListener('pagehide', flushBuffer);
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=replay.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"replay.js","sourceRoot":"","sources":["../src/replay.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AAExC,MAAM,UAAU,GAAG,EAAE,CAAA,CAAU,+BAA+B;AAC9D,MAAM,iBAAiB,GAAG,IAAK,CAAA,CAAC,6BAA6B;AAE7D,IAAI,OAAO,GAAyB,IAAI,CAAA;AACxC,8DAA8D;AAC9D,IAAI,OAAO,GAAU,EAAE,CAAA;AACvB,IAAI,SAAS,GAAG,CAAC,CAAA;AACjB,IAAI,WAAW,GAA0C,IAAI,CAAA;AAE7D,SAAS,cAAc;IACrB,MAAM,GAAG,GAAG,OAAQ,CAAA;IACpB,IAAI,GAAG,CAAC,cAAc;QAAE,OAAO,GAAG,CAAC,cAAc,CAAA;IACjD,qFAAqF;IACrF,OAAO,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,gBAAgB,EAAE,oBAAoB,CAAC,CAAA;AACrE,CAAC;AAED,8DAA8D;AAC9D,SAAS,SAAS,CAAC,MAAa;IAC9B,IAAI,CAAC,OAAO,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAM;IAC3C,MAAM,OAAO,GAAG;QACd,UAAU,EAAE,YAAY,EAAE;QAC1B,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI;QAC1B,SAAS,EAAE,SAAS,EAAE;QACtB,MAAM;KACP,CAAA;IACD,KAAK,CAAC,cAAc,EAAE,EAAE;QACtB,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;QAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;QAC7B,SAAS,EAAE,IAAI;KAChB,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAqB,CAAC,CAAC,CAAA;AACvC,CAAC;AAED,SAAS,WAAW;IAClB,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAM;IAChC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAA;AAC9B,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,MAAqB;IAC9C,OAAO,GAAG,MAAM,CAAA;IAEhB,8EAA8E;IAC9E,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE;QAClC,MAAM,CAAC;YACL,IAAI,CAAC,KAAK;gBACR,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;gBACnB,IAAI,OAAO,CAAC,MAAM,IAAI,UAAU,EAAE,CAAC;oBACjC,WAAW,EAAE,CAAA;gBACf,CAAC;YACH,CAAC;YACD,aAAa,EAAE,IAAI,EAAM,+BAA+B;YACxD,gBAAgB,EAAE,YAAY,EAAE,mCAAmC;SACpE,CAAC,CAAA;IACJ,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;QACZ,iDAAiD;IACnD,CAAC,CAAC,CAAA;IAEF,WAAW,GAAG,WAAW,CAAC,WAAW,EAAE,iBAAiB,CAAC,CAAA;IAEzD,QAAQ,CAAC,gBAAgB,CAAC,kBAAkB,EAAE,GAAG,EAAE;QACjD,IAAI,QAAQ,CAAC,eAAe,KAAK,QAAQ;YAAE,WAAW,EAAE,CAAA;IAC1D,CAAC,CAAC,CAAA;IACF,MAAM,CAAC,gBAAgB,CAAC,UAAU,EAAE,WAAW,CAAC,CAAA;AAClD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resources.d.ts","sourceRoot":"","sources":["../src/resources.ts"],"names":[],"mappings":"AAEA,wBAAgB,aAAa,IAAI,IAAI,CAGpC"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { pushEvent, getConfig } from './core';
|
|
2
|
+
export function initResources() {
|
|
3
|
+
patchFetch();
|
|
4
|
+
patchXHR();
|
|
5
|
+
}
|
|
6
|
+
function shouldTraceOrigin(url) {
|
|
7
|
+
const cfg = getConfig();
|
|
8
|
+
if (!cfg?.propagateTraces?.origins)
|
|
9
|
+
return false;
|
|
10
|
+
return cfg.propagateTraces.origins.some((re) => re.test(url));
|
|
11
|
+
}
|
|
12
|
+
function generateTraceId() {
|
|
13
|
+
const bytes = new Uint8Array(16);
|
|
14
|
+
crypto.getRandomValues(bytes);
|
|
15
|
+
return Array.from(bytes).map((b) => b.toString(16).padStart(2, '0')).join('');
|
|
16
|
+
}
|
|
17
|
+
function generateSpanId() {
|
|
18
|
+
const bytes = new Uint8Array(8);
|
|
19
|
+
crypto.getRandomValues(bytes);
|
|
20
|
+
return Array.from(bytes).map((b) => b.toString(16).padStart(2, '0')).join('');
|
|
21
|
+
}
|
|
22
|
+
function patchFetch() {
|
|
23
|
+
const origFetch = window.fetch.bind(window);
|
|
24
|
+
window.fetch = async function (input, init) {
|
|
25
|
+
const url = typeof input === 'string' ? input : input instanceof URL ? input.href : input.url;
|
|
26
|
+
const start = performance.now();
|
|
27
|
+
let traceId = '';
|
|
28
|
+
let spanId = '';
|
|
29
|
+
if (shouldTraceOrigin(url)) {
|
|
30
|
+
traceId = generateTraceId();
|
|
31
|
+
spanId = generateSpanId();
|
|
32
|
+
const headers = new Headers(init?.headers);
|
|
33
|
+
headers.set('traceparent', `00-${traceId}-${spanId}-01`);
|
|
34
|
+
init = { ...init, headers };
|
|
35
|
+
}
|
|
36
|
+
try {
|
|
37
|
+
const response = await origFetch(input, init);
|
|
38
|
+
const durationMs = performance.now() - start;
|
|
39
|
+
pushEvent({
|
|
40
|
+
event_type: 'resource',
|
|
41
|
+
event_name: url,
|
|
42
|
+
duration_ms: durationMs,
|
|
43
|
+
trace_id: traceId,
|
|
44
|
+
span_id: spanId,
|
|
45
|
+
attributes: JSON.stringify({ status: response.status, method: init?.method ?? 'GET' }),
|
|
46
|
+
});
|
|
47
|
+
return response;
|
|
48
|
+
}
|
|
49
|
+
catch (err) {
|
|
50
|
+
const durationMs = performance.now() - start;
|
|
51
|
+
pushEvent({
|
|
52
|
+
event_type: 'resource',
|
|
53
|
+
event_name: url,
|
|
54
|
+
duration_ms: durationMs,
|
|
55
|
+
trace_id: traceId,
|
|
56
|
+
span_id: spanId,
|
|
57
|
+
error_message: err instanceof Error ? err.message : 'fetch failed',
|
|
58
|
+
error_type: 'NetworkError',
|
|
59
|
+
});
|
|
60
|
+
throw err;
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
function patchXHR() {
|
|
65
|
+
const origOpen = XMLHttpRequest.prototype.open;
|
|
66
|
+
const origSend = XMLHttpRequest.prototype.send;
|
|
67
|
+
XMLHttpRequest.prototype.open = function (method, url, ...rest) {
|
|
68
|
+
this.__wide_url = typeof url === 'string' ? url : url.href;
|
|
69
|
+
this.__wide_method = method;
|
|
70
|
+
return origOpen.apply(this, [method, url, ...rest]);
|
|
71
|
+
};
|
|
72
|
+
XMLHttpRequest.prototype.send = function (body) {
|
|
73
|
+
const url = this.__wide_url ?? '';
|
|
74
|
+
const method = this.__wide_method ?? 'GET';
|
|
75
|
+
const start = performance.now();
|
|
76
|
+
let traceId = '';
|
|
77
|
+
let spanId = '';
|
|
78
|
+
if (shouldTraceOrigin(url)) {
|
|
79
|
+
traceId = generateTraceId();
|
|
80
|
+
spanId = generateSpanId();
|
|
81
|
+
this.setRequestHeader('traceparent', `00-${traceId}-${spanId}-01`);
|
|
82
|
+
}
|
|
83
|
+
this.addEventListener('loadend', () => {
|
|
84
|
+
const durationMs = performance.now() - start;
|
|
85
|
+
pushEvent({
|
|
86
|
+
event_type: 'resource',
|
|
87
|
+
event_name: url,
|
|
88
|
+
duration_ms: durationMs,
|
|
89
|
+
trace_id: traceId,
|
|
90
|
+
span_id: spanId,
|
|
91
|
+
attributes: JSON.stringify({ status: this.status, method }),
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
return origSend.call(this, body);
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=resources.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resources.js","sourceRoot":"","sources":["../src/resources.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AAeA,wBAAgB,YAAY,IAAI,MAAM,CAmBrC;AAED,wBAAgB,YAAY,IAAI,IAAI,CAInC"}
|
package/dist/session.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
const SESSION_KEY = 'rush_rum_sid';
|
|
2
|
+
const SESSION_TS_KEY = 'rush_rum_sts';
|
|
3
|
+
const TIMEOUT_MS = 30 * 60 * 1000; // 30 minutes
|
|
4
|
+
function generateId() {
|
|
5
|
+
if (typeof crypto !== 'undefined' && crypto.randomUUID) {
|
|
6
|
+
return crypto.randomUUID();
|
|
7
|
+
}
|
|
8
|
+
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
|
|
9
|
+
const r = (Math.random() * 16) | 0;
|
|
10
|
+
const v = c === 'x' ? r : (r & 0x3) | 0x8;
|
|
11
|
+
return v.toString(16);
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
export function getSessionId() {
|
|
15
|
+
try {
|
|
16
|
+
const stored = sessionStorage.getItem(SESSION_KEY);
|
|
17
|
+
const ts = sessionStorage.getItem(SESSION_TS_KEY);
|
|
18
|
+
const now = Date.now();
|
|
19
|
+
if (stored && ts && now - Number(ts) < TIMEOUT_MS) {
|
|
20
|
+
sessionStorage.setItem(SESSION_TS_KEY, String(now));
|
|
21
|
+
return stored;
|
|
22
|
+
}
|
|
23
|
+
const id = generateId();
|
|
24
|
+
sessionStorage.setItem(SESSION_KEY, id);
|
|
25
|
+
sessionStorage.setItem(SESSION_TS_KEY, String(now));
|
|
26
|
+
return id;
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
// sessionStorage not available (e.g. incognito overflow)
|
|
30
|
+
return generateId();
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
export function touchSession() {
|
|
34
|
+
try {
|
|
35
|
+
sessionStorage.setItem(SESSION_TS_KEY, String(Date.now()));
|
|
36
|
+
}
|
|
37
|
+
catch { /* ignore */ }
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,GAAG,cAAc,CAAA;AAClC,MAAM,cAAc,GAAG,cAAc,CAAA;AACrC,MAAM,UAAU,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAA,CAAC,aAAa;AAE/C,SAAS,UAAU;IACjB,IAAI,OAAO,MAAM,KAAK,WAAW,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;QACvD,OAAO,MAAM,CAAC,UAAU,EAAE,CAAA;IAC5B,CAAC;IACD,OAAO,sCAAsC,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE;QACnE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAAA;QAClC,MAAM,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,GAAG,CAAA;QACzC,OAAO,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAA;IACvB,CAAC,CAAC,CAAA;AACJ,CAAC;AAED,MAAM,UAAU,YAAY;IAC1B,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,cAAc,CAAC,OAAO,CAAC,WAAW,CAAC,CAAA;QAClD,MAAM,EAAE,GAAG,cAAc,CAAC,OAAO,CAAC,cAAc,CAAC,CAAA;QACjD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QAEtB,IAAI,MAAM,IAAI,EAAE,IAAI,GAAG,GAAG,MAAM,CAAC,EAAE,CAAC,GAAG,UAAU,EAAE,CAAC;YAClD,cAAc,CAAC,OAAO,CAAC,cAAc,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAA;YACnD,OAAO,MAAM,CAAA;QACf,CAAC;QAED,MAAM,EAAE,GAAG,UAAU,EAAE,CAAA;QACvB,cAAc,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAA;QACvC,cAAc,CAAC,OAAO,CAAC,cAAc,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAA;QACnD,OAAO,EAAE,CAAA;IACX,CAAC;IAAC,MAAM,CAAC;QACP,yDAAyD;QACzD,OAAO,UAAU,EAAE,CAAA;IACrB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,YAAY;IAC1B,IAAI,CAAC;QACH,cAAc,CAAC,OAAO,CAAC,cAAc,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAA;IAC5D,CAAC;IAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;AAC1B,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
export interface RushRUMConfig {
|
|
2
|
+
endpoint: string;
|
|
3
|
+
app: {
|
|
4
|
+
name: string;
|
|
5
|
+
version?: string;
|
|
6
|
+
};
|
|
7
|
+
environment?: string;
|
|
8
|
+
user?: () => {
|
|
9
|
+
id?: string;
|
|
10
|
+
} | null;
|
|
11
|
+
sampleRate?: number;
|
|
12
|
+
trackWebVitals?: boolean;
|
|
13
|
+
trackErrors?: boolean;
|
|
14
|
+
trackInteractions?: boolean;
|
|
15
|
+
trackResources?: boolean;
|
|
16
|
+
trackPageViews?: boolean;
|
|
17
|
+
propagateTraces?: {
|
|
18
|
+
origins: RegExp[];
|
|
19
|
+
};
|
|
20
|
+
trackSessionReplay?: boolean;
|
|
21
|
+
/** Override the replay ingest endpoint (defaults to endpoint with /rum/replay/ingest) */
|
|
22
|
+
replayEndpoint?: string;
|
|
23
|
+
}
|
|
24
|
+
export interface RumMeta {
|
|
25
|
+
app_name: string;
|
|
26
|
+
app_version: string;
|
|
27
|
+
environment: string;
|
|
28
|
+
session_id: string;
|
|
29
|
+
user_id: string;
|
|
30
|
+
page_url: string;
|
|
31
|
+
page_path: string;
|
|
32
|
+
view_name: string;
|
|
33
|
+
referrer: string;
|
|
34
|
+
browser_name: string;
|
|
35
|
+
browser_version: string;
|
|
36
|
+
os_name: string;
|
|
37
|
+
os_version: string;
|
|
38
|
+
device_type: string;
|
|
39
|
+
screen_width: number;
|
|
40
|
+
screen_height: number;
|
|
41
|
+
}
|
|
42
|
+
export interface RumEvent {
|
|
43
|
+
event_type: string;
|
|
44
|
+
event_name?: string;
|
|
45
|
+
timestamp?: number;
|
|
46
|
+
vital_name?: string;
|
|
47
|
+
vital_value?: number;
|
|
48
|
+
vital_rating?: string;
|
|
49
|
+
error_message?: string;
|
|
50
|
+
error_stack?: string;
|
|
51
|
+
error_type?: string;
|
|
52
|
+
interaction_target?: string;
|
|
53
|
+
interaction_type?: string;
|
|
54
|
+
duration_ms?: number;
|
|
55
|
+
trace_id?: string;
|
|
56
|
+
span_id?: string;
|
|
57
|
+
attributes?: string;
|
|
58
|
+
}
|
|
59
|
+
export interface RumPayload {
|
|
60
|
+
meta: RumMeta;
|
|
61
|
+
events: RumEvent[];
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAA;IAChB,GAAG,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IACvC,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,IAAI,CAAC,EAAE,MAAM;QAAE,EAAE,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAA;IACnC,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,eAAe,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,EAAE,CAAA;KAAE,CAAA;IACvC,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAC5B,yFAAyF;IACzF,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AAED,MAAM,WAAW,OAAO;IACtB,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,MAAM,CAAA;IACnB,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,EAAE,MAAM,CAAA;IACpB,eAAe,EAAE,MAAM,CAAA;IACvB,OAAO,EAAE,MAAM,CAAA;IACf,UAAU,EAAE,MAAM,CAAA;IAClB,WAAW,EAAE,MAAM,CAAA;IACnB,YAAY,EAAE,MAAM,CAAA;IACpB,aAAa,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,QAAQ;IACvB,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,OAAO,CAAA;IACb,MAAM,EAAE,QAAQ,EAAE,CAAA;CACnB"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/dist/vitals.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vitals.d.ts","sourceRoot":"","sources":["../src/vitals.ts"],"names":[],"mappings":"AAEA,wBAAgB,UAAU,IAAI,IAAI,CAoBjC"}
|
package/dist/vitals.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { pushEvent } from './core';
|
|
2
|
+
export function initVitals() {
|
|
3
|
+
// Dynamic import so the SDK works even if web-vitals isn't available
|
|
4
|
+
import('web-vitals').then(({ onLCP, onCLS, onINP, onFCP, onTTFB }) => {
|
|
5
|
+
const report = (name) => (metric) => {
|
|
6
|
+
pushEvent({
|
|
7
|
+
event_type: 'web_vital',
|
|
8
|
+
vital_name: name,
|
|
9
|
+
vital_value: metric.value,
|
|
10
|
+
vital_rating: metric.rating,
|
|
11
|
+
});
|
|
12
|
+
};
|
|
13
|
+
onLCP(report('LCP'));
|
|
14
|
+
onCLS(report('CLS'));
|
|
15
|
+
onINP(report('INP'));
|
|
16
|
+
onFCP(report('FCP'));
|
|
17
|
+
onTTFB(report('TTFB'));
|
|
18
|
+
}).catch(() => {
|
|
19
|
+
// web-vitals not available — skip
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=vitals.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vitals.js","sourceRoot":"","sources":["../src/vitals.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAA;AAElC,MAAM,UAAU,UAAU;IACxB,qEAAqE;IACrE,MAAM,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE;QACnE,MAAM,MAAM,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,CAAC,MAAyC,EAAE,EAAE;YAC7E,SAAS,CAAC;gBACR,UAAU,EAAE,WAAW;gBACvB,UAAU,EAAE,IAAI;gBAChB,WAAW,EAAE,MAAM,CAAC,KAAK;gBACzB,YAAY,EAAE,MAAM,CAAC,MAAM;aAC5B,CAAC,CAAA;QACJ,CAAC,CAAA;QAED,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAA;QACpB,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAA;QACpB,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAA;QACpB,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAA;QACpB,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAA;IACxB,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;QACZ,kCAAkC;IACpC,CAAC,CAAC,CAAA;AACJ,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@rushobservability/rum-sdk",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Rush RUM (Real User Monitoring) browser SDK",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/RushObservability/rum-sdk.git"
|
|
9
|
+
},
|
|
10
|
+
"homepage": "https://github.com/RushObservability/rum-sdk#readme",
|
|
11
|
+
"publishConfig": {
|
|
12
|
+
"access": "public"
|
|
13
|
+
},
|
|
14
|
+
"main": "dist/index.js",
|
|
15
|
+
"module": "dist/index.js",
|
|
16
|
+
"types": "dist/index.d.ts",
|
|
17
|
+
"exports": {
|
|
18
|
+
".": {
|
|
19
|
+
"import": "./dist/index.js",
|
|
20
|
+
"types": "./dist/index.d.ts"
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"files": [
|
|
24
|
+
"dist"
|
|
25
|
+
],
|
|
26
|
+
"scripts": {
|
|
27
|
+
"build": "tsc",
|
|
28
|
+
"typecheck": "tsc --noEmit"
|
|
29
|
+
},
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"rrweb": "^2.0.0-alpha.20",
|
|
32
|
+
"web-vitals": "^4.2.0"
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"typescript": "^5.5.0"
|
|
36
|
+
},
|
|
37
|
+
"license": "MIT"
|
|
38
|
+
}
|