@observtech/rum 0.1.32 → 0.1.34
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/README.md +85 -7
- package/dist/chunk-P6VK4P6W.js +42 -0
- package/dist/chunk-P6VK4P6W.js.map +1 -0
- package/dist/index.d.ts +123 -1
- package/dist/index.js +711 -118
- package/dist/index.js.map +1 -1
- package/dist/user-interaction-HZJLQRUN.js +25 -0
- package/dist/user-interaction-HZJLQRUN.js.map +1 -0
- package/package.json +5 -2
package/dist/index.js
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { registerInstrumentations } from './chunk-P6VK4P6W.js';
|
|
2
|
+
import { SeverityNumber } from '@opentelemetry/api-logs';
|
|
2
3
|
import { OTLPLogExporter } from '@opentelemetry/exporter-logs-otlp-http';
|
|
3
4
|
import { LoggerProvider, BatchLogRecordProcessor } from '@opentelemetry/sdk-logs';
|
|
4
5
|
import { resourceFromAttributes } from '@opentelemetry/resources';
|
|
6
|
+
import { ATTR_EXCEPTION_MESSAGE, ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION, ATTR_EXCEPTION_TYPE, ATTR_EXCEPTION_STACKTRACE } from '@opentelemetry/semantic-conventions';
|
|
5
7
|
import { ATTR_SESSION_ID } from '@opentelemetry/semantic-conventions/incubating';
|
|
6
|
-
import
|
|
8
|
+
import '@opentelemetry/api';
|
|
7
9
|
import { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-http';
|
|
8
10
|
import { PeriodicExportingMetricReader, MeterProvider } from '@opentelemetry/sdk-metrics';
|
|
9
11
|
import { onLCP, onINP, onFCP, onTTFB, onCLS } from 'web-vitals';
|
|
10
12
|
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
|
|
11
|
-
import { logs } from '@opentelemetry/api-logs';
|
|
12
13
|
import { DocumentLoadInstrumentation } from '@opentelemetry/instrumentation-document-load';
|
|
13
14
|
import { FetchInstrumentation } from '@opentelemetry/instrumentation-fetch';
|
|
14
15
|
import { XMLHttpRequestInstrumentation } from '@opentelemetry/instrumentation-xml-http-request';
|
|
@@ -63,6 +64,57 @@ function installBaggagePropagation(getId, backendUrls, ignoreUrls = []) {
|
|
|
63
64
|
window.fetch = originalFetch;
|
|
64
65
|
};
|
|
65
66
|
}
|
|
67
|
+
|
|
68
|
+
// src/consent.ts
|
|
69
|
+
var DEFAULT_KEY = "observ.consent";
|
|
70
|
+
var DEFAULT_GRANTED = ["granted", "true", "1", "yes", "all"];
|
|
71
|
+
function readCookie(key) {
|
|
72
|
+
if (typeof document === "undefined" || !document.cookie) return void 0;
|
|
73
|
+
for (const part of document.cookie.split(";")) {
|
|
74
|
+
const idx = part.indexOf("=");
|
|
75
|
+
if (idx === -1) continue;
|
|
76
|
+
if (part.slice(0, idx).trim() === key) {
|
|
77
|
+
try {
|
|
78
|
+
return decodeURIComponent(part.slice(idx + 1).trim());
|
|
79
|
+
} catch {
|
|
80
|
+
return part.slice(idx + 1).trim();
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return void 0;
|
|
85
|
+
}
|
|
86
|
+
function readStorage(key) {
|
|
87
|
+
try {
|
|
88
|
+
return globalThis.localStorage?.getItem(key) ?? void 0;
|
|
89
|
+
} catch {
|
|
90
|
+
return void 0;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
function consentKey(opts) {
|
|
94
|
+
return opts.consentKey || DEFAULT_KEY;
|
|
95
|
+
}
|
|
96
|
+
function grantedValue(opts) {
|
|
97
|
+
return opts.consentGrantedValues?.[0] ?? "granted";
|
|
98
|
+
}
|
|
99
|
+
function hasAnalyticsConsent(opts) {
|
|
100
|
+
if (!opts.requireConsent) return true;
|
|
101
|
+
const key = consentKey(opts);
|
|
102
|
+
const granted = (opts.consentGrantedValues ?? DEFAULT_GRANTED).map((v) => v.toLowerCase());
|
|
103
|
+
const value = readCookie(key) ?? readStorage(key);
|
|
104
|
+
return value != null && granted.includes(value.toLowerCase());
|
|
105
|
+
}
|
|
106
|
+
function writeConsent(opts) {
|
|
107
|
+
try {
|
|
108
|
+
globalThis.localStorage?.setItem(consentKey(opts), grantedValue(opts));
|
|
109
|
+
} catch {
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
function clearConsent(opts) {
|
|
113
|
+
try {
|
|
114
|
+
globalThis.localStorage?.removeItem(consentKey(opts));
|
|
115
|
+
} catch {
|
|
116
|
+
}
|
|
117
|
+
}
|
|
66
118
|
function buildResource(options) {
|
|
67
119
|
const attrs = {
|
|
68
120
|
"telemetry.sdk.language": "webjs"
|
|
@@ -81,11 +133,8 @@ function buildResource(options) {
|
|
|
81
133
|
}
|
|
82
134
|
var SESSION_ID_ATTRIBUTE = ATTR_SESSION_ID;
|
|
83
135
|
|
|
84
|
-
// src/
|
|
85
|
-
|
|
86
|
-
var SESSION_INACTIVITY_TIMEOUT_MS = 30 * 60 * 1e3;
|
|
87
|
-
var current = null;
|
|
88
|
-
function generateSessionId() {
|
|
136
|
+
// src/random-id.ts
|
|
137
|
+
function generateUuid() {
|
|
89
138
|
const c = globalThis.crypto;
|
|
90
139
|
if (c && typeof c.randomUUID === "function") {
|
|
91
140
|
try {
|
|
@@ -106,16 +155,58 @@ function generateSessionId() {
|
|
|
106
155
|
return v.toString(16);
|
|
107
156
|
});
|
|
108
157
|
}
|
|
158
|
+
|
|
159
|
+
// src/session.ts
|
|
160
|
+
var SESSION_STORAGE_KEY = "observ.rum.session";
|
|
161
|
+
var SESSION_INACTIVITY_TIMEOUT_MS = 30 * 60 * 1e3;
|
|
162
|
+
var SESSION_MAX_DURATION_MS = 4 * 60 * 60 * 1e3;
|
|
163
|
+
var current = null;
|
|
164
|
+
var inactivityTimeoutMs = SESSION_INACTIVITY_TIMEOUT_MS;
|
|
165
|
+
var maxDurationMs = SESSION_MAX_DURATION_MS;
|
|
166
|
+
var storageMode = "session";
|
|
167
|
+
var listeners = /* @__PURE__ */ new Set();
|
|
168
|
+
function configureSession(opts) {
|
|
169
|
+
if (typeof opts.inactivityTimeoutMs === "number" && opts.inactivityTimeoutMs > 0) {
|
|
170
|
+
inactivityTimeoutMs = opts.inactivityTimeoutMs;
|
|
171
|
+
}
|
|
172
|
+
if (typeof opts.maxDurationMs === "number" && opts.maxDurationMs > 0) {
|
|
173
|
+
maxDurationMs = opts.maxDurationMs;
|
|
174
|
+
}
|
|
175
|
+
if (typeof opts.crossTab === "boolean") {
|
|
176
|
+
storageMode = opts.crossTab ? "local" : "session";
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
function addSessionListener(fn) {
|
|
180
|
+
listeners.add(fn);
|
|
181
|
+
return () => {
|
|
182
|
+
listeners.delete(fn);
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
function notify(event) {
|
|
186
|
+
for (const fn of listeners) {
|
|
187
|
+
try {
|
|
188
|
+
fn(event);
|
|
189
|
+
} catch {
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
function backend() {
|
|
194
|
+
try {
|
|
195
|
+
return storageMode === "local" ? globalThis.localStorage : globalThis.sessionStorage;
|
|
196
|
+
} catch {
|
|
197
|
+
return void 0;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
109
200
|
function safeRead() {
|
|
110
201
|
try {
|
|
111
|
-
return
|
|
202
|
+
return backend()?.getItem(SESSION_STORAGE_KEY) ?? null;
|
|
112
203
|
} catch {
|
|
113
204
|
return null;
|
|
114
205
|
}
|
|
115
206
|
}
|
|
116
207
|
function safeWrite(value) {
|
|
117
208
|
try {
|
|
118
|
-
|
|
209
|
+
backend()?.setItem(SESSION_STORAGE_KEY, value);
|
|
119
210
|
} catch {
|
|
120
211
|
}
|
|
121
212
|
}
|
|
@@ -139,22 +230,110 @@ function save(session) {
|
|
|
139
230
|
current = session;
|
|
140
231
|
safeWrite(JSON.stringify(session));
|
|
141
232
|
}
|
|
233
|
+
function isExpired(session, now) {
|
|
234
|
+
if (!session) return true;
|
|
235
|
+
const inactiveFor = Math.max(0, now - session.lastActivityAt);
|
|
236
|
+
const ageFor = Math.max(0, now - session.startedAt);
|
|
237
|
+
return inactiveFor > inactivityTimeoutMs || ageFor > maxDurationMs;
|
|
238
|
+
}
|
|
142
239
|
function ensureSession(now = Date.now()) {
|
|
143
240
|
const existing = load();
|
|
144
|
-
if (existing) {
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
}
|
|
241
|
+
if (existing && !isExpired(existing, now)) {
|
|
242
|
+
save({ ...existing, lastActivityAt: now });
|
|
243
|
+
return existing.id;
|
|
244
|
+
}
|
|
245
|
+
if (existing && existing.endedAt == null) {
|
|
246
|
+
notify({ type: "end", id: existing.id, durationMs: Math.max(0, now - existing.startedAt) });
|
|
150
247
|
}
|
|
151
|
-
const fresh = {
|
|
248
|
+
const fresh = {
|
|
249
|
+
id: generateUuid(),
|
|
250
|
+
startedAt: now,
|
|
251
|
+
lastActivityAt: now,
|
|
252
|
+
...existing ? { previousId: existing.id } : {}
|
|
253
|
+
};
|
|
152
254
|
save(fresh);
|
|
255
|
+
notify({ type: "start", id: fresh.id, ...existing ? { previousId: existing.id } : {} });
|
|
153
256
|
return fresh.id;
|
|
154
257
|
}
|
|
155
258
|
function getSessionId(now = Date.now()) {
|
|
156
259
|
return ensureSession(now);
|
|
157
260
|
}
|
|
261
|
+
function touchSession(now = Date.now()) {
|
|
262
|
+
ensureSession(now);
|
|
263
|
+
}
|
|
264
|
+
function endSessionIfExpired(now = Date.now()) {
|
|
265
|
+
const session = load();
|
|
266
|
+
if (!session || session.endedAt != null || !isExpired(session, now)) return;
|
|
267
|
+
save({ ...session, endedAt: now });
|
|
268
|
+
notify({ type: "end", id: session.id, durationMs: Math.max(0, now - session.startedAt) });
|
|
269
|
+
}
|
|
270
|
+
function adoptStoredSession() {
|
|
271
|
+
const raw = safeRead();
|
|
272
|
+
if (raw === null) return;
|
|
273
|
+
try {
|
|
274
|
+
const parsed = JSON.parse(raw);
|
|
275
|
+
if (isPersistedSession(parsed)) current = parsed;
|
|
276
|
+
} catch {
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// src/user.ts
|
|
281
|
+
var ATTR_ENDUSER_ID = "enduser.id";
|
|
282
|
+
var ATTR_ENDUSER_ROLE = "enduser.role";
|
|
283
|
+
var ATTR_ENDUSER_NAME = "enduser.name";
|
|
284
|
+
var ATTR_ENDUSER_PSEUDO_ID = "enduser.pseudo.id";
|
|
285
|
+
var PSEUDO_USER_STORAGE_KEY = "observ.rum.pseudo";
|
|
286
|
+
var currentUser = null;
|
|
287
|
+
var pseudoEnabled = true;
|
|
288
|
+
var pseudoId;
|
|
289
|
+
function configureUser(opts) {
|
|
290
|
+
if (typeof opts.disablePseudoUser === "boolean") {
|
|
291
|
+
pseudoEnabled = !opts.disablePseudoUser;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
function setUser(user) {
|
|
295
|
+
currentUser = user;
|
|
296
|
+
}
|
|
297
|
+
function clearUser() {
|
|
298
|
+
currentUser = null;
|
|
299
|
+
}
|
|
300
|
+
function getPseudoUserId() {
|
|
301
|
+
if (!pseudoEnabled) return void 0;
|
|
302
|
+
if (pseudoId) return pseudoId;
|
|
303
|
+
try {
|
|
304
|
+
const existing = globalThis.localStorage?.getItem(PSEUDO_USER_STORAGE_KEY);
|
|
305
|
+
if (existing) {
|
|
306
|
+
pseudoId = existing;
|
|
307
|
+
return pseudoId;
|
|
308
|
+
}
|
|
309
|
+
} catch {
|
|
310
|
+
}
|
|
311
|
+
pseudoId = generateUuid();
|
|
312
|
+
try {
|
|
313
|
+
globalThis.localStorage?.setItem(PSEUDO_USER_STORAGE_KEY, pseudoId);
|
|
314
|
+
} catch {
|
|
315
|
+
}
|
|
316
|
+
return pseudoId;
|
|
317
|
+
}
|
|
318
|
+
function userAttributes() {
|
|
319
|
+
const attrs = {};
|
|
320
|
+
const pseudo = getPseudoUserId();
|
|
321
|
+
if (pseudo) attrs[ATTR_ENDUSER_PSEUDO_ID] = pseudo;
|
|
322
|
+
if (currentUser) {
|
|
323
|
+
attrs[ATTR_ENDUSER_ID] = String(currentUser.id);
|
|
324
|
+
if (currentUser.role) attrs[ATTR_ENDUSER_ROLE] = currentUser.role;
|
|
325
|
+
if (currentUser.name) attrs[ATTR_ENDUSER_NAME] = currentUser.name;
|
|
326
|
+
}
|
|
327
|
+
return attrs;
|
|
328
|
+
}
|
|
329
|
+
function applyUserAttributes(setAttribute) {
|
|
330
|
+
try {
|
|
331
|
+
for (const [key, value] of Object.entries(userAttributes())) {
|
|
332
|
+
setAttribute(key, value);
|
|
333
|
+
}
|
|
334
|
+
} catch {
|
|
335
|
+
}
|
|
336
|
+
}
|
|
158
337
|
|
|
159
338
|
// src/otel-logs.ts
|
|
160
339
|
function buildLogsUrl(endpoint) {
|
|
@@ -200,12 +379,17 @@ function currentSessionId() {
|
|
|
200
379
|
}
|
|
201
380
|
return cachedSessionId;
|
|
202
381
|
}
|
|
382
|
+
function resetSessionIdCache() {
|
|
383
|
+
cachedSessionId = "";
|
|
384
|
+
cachedSessionIdAt = 0;
|
|
385
|
+
}
|
|
203
386
|
function emitSessionEvent(logger, eventName, attrs = {}) {
|
|
204
387
|
try {
|
|
205
388
|
logger.emit({
|
|
206
389
|
attributes: {
|
|
207
390
|
"event.name": eventName,
|
|
208
391
|
[SESSION_ID_ATTRIBUTE]: currentSessionId(),
|
|
392
|
+
...userAttributes(),
|
|
209
393
|
...attrs
|
|
210
394
|
}
|
|
211
395
|
});
|
|
@@ -213,6 +397,20 @@ function emitSessionEvent(logger, eventName, attrs = {}) {
|
|
|
213
397
|
console.warn("[observ] semantic event emit failed", err);
|
|
214
398
|
}
|
|
215
399
|
}
|
|
400
|
+
function emitLogRecord(logger, severityNumber, severityText, body) {
|
|
401
|
+
try {
|
|
402
|
+
logger.emit({
|
|
403
|
+
severityNumber,
|
|
404
|
+
severityText,
|
|
405
|
+
body,
|
|
406
|
+
attributes: {
|
|
407
|
+
[SESSION_ID_ATTRIBUTE]: currentSessionId(),
|
|
408
|
+
...userAttributes()
|
|
409
|
+
}
|
|
410
|
+
});
|
|
411
|
+
} catch {
|
|
412
|
+
}
|
|
413
|
+
}
|
|
216
414
|
async function shutdownOtelLogs() {
|
|
217
415
|
const p = provider;
|
|
218
416
|
provider = null;
|
|
@@ -220,7 +418,84 @@ async function shutdownOtelLogs() {
|
|
|
220
418
|
await p?.shutdown();
|
|
221
419
|
}
|
|
222
420
|
|
|
223
|
-
// src/
|
|
421
|
+
// src/console-forward.ts
|
|
422
|
+
var LEVELS = {
|
|
423
|
+
debug: { number: SeverityNumber.DEBUG, text: "DEBUG" },
|
|
424
|
+
log: { number: SeverityNumber.INFO, text: "INFO" },
|
|
425
|
+
info: { number: SeverityNumber.INFO, text: "INFO" },
|
|
426
|
+
warn: { number: SeverityNumber.WARN, text: "WARN" },
|
|
427
|
+
error: { number: SeverityNumber.ERROR, text: "ERROR" }
|
|
428
|
+
};
|
|
429
|
+
var ALL_LEVELS = Object.keys(LEVELS);
|
|
430
|
+
var MAX_BODY = 4096;
|
|
431
|
+
var NOOP = { stop: () => {
|
|
432
|
+
} };
|
|
433
|
+
var active = null;
|
|
434
|
+
function resolveLevels(forwardConsole) {
|
|
435
|
+
if (forwardConsole === true) return ALL_LEVELS;
|
|
436
|
+
if (Array.isArray(forwardConsole)) return forwardConsole.filter((l) => l in LEVELS);
|
|
437
|
+
return [];
|
|
438
|
+
}
|
|
439
|
+
function formatArg(arg) {
|
|
440
|
+
if (arg instanceof Error) return `${arg.name}: ${arg.message}`;
|
|
441
|
+
if (typeof arg === "object" && arg !== null) {
|
|
442
|
+
try {
|
|
443
|
+
return JSON.stringify(arg) ?? String(arg);
|
|
444
|
+
} catch {
|
|
445
|
+
return String(arg);
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
return String(arg);
|
|
449
|
+
}
|
|
450
|
+
function formatBody(args) {
|
|
451
|
+
const body = args.map(formatArg).join(" ");
|
|
452
|
+
return body.length > MAX_BODY ? body.slice(0, MAX_BODY) : body;
|
|
453
|
+
}
|
|
454
|
+
function startConsoleForward(options) {
|
|
455
|
+
if (active) return active;
|
|
456
|
+
const levels = resolveLevels(options.forwardConsole);
|
|
457
|
+
if (levels.length === 0 || typeof console === "undefined") return NOOP;
|
|
458
|
+
let logger;
|
|
459
|
+
try {
|
|
460
|
+
logger = setupOtelLogs(options);
|
|
461
|
+
} catch {
|
|
462
|
+
return NOOP;
|
|
463
|
+
}
|
|
464
|
+
let emitting = false;
|
|
465
|
+
const originals = /* @__PURE__ */ new Map();
|
|
466
|
+
for (const level of levels) {
|
|
467
|
+
const original = console[level];
|
|
468
|
+
if (typeof original !== "function") continue;
|
|
469
|
+
originals.set(level, original);
|
|
470
|
+
const { number, text } = LEVELS[level];
|
|
471
|
+
console[level] = (...args) => {
|
|
472
|
+
if (!emitting) {
|
|
473
|
+
emitting = true;
|
|
474
|
+
try {
|
|
475
|
+
emitLogRecord(logger, number, text, formatBody(args));
|
|
476
|
+
} catch {
|
|
477
|
+
} finally {
|
|
478
|
+
emitting = false;
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
original.apply(console, args);
|
|
482
|
+
};
|
|
483
|
+
}
|
|
484
|
+
let stopped = false;
|
|
485
|
+
const handle = {
|
|
486
|
+
stop() {
|
|
487
|
+
if (stopped) return;
|
|
488
|
+
stopped = true;
|
|
489
|
+
active = null;
|
|
490
|
+
for (const [level, original] of originals) {
|
|
491
|
+
console[level] = original;
|
|
492
|
+
}
|
|
493
|
+
originals.clear();
|
|
494
|
+
}
|
|
495
|
+
};
|
|
496
|
+
active = handle;
|
|
497
|
+
return handle;
|
|
498
|
+
}
|
|
224
499
|
var MAX_JS_ERRORS = 50;
|
|
225
500
|
var RATE_WINDOW_MS = 6e4;
|
|
226
501
|
var MAX_MESSAGE = 1024;
|
|
@@ -236,21 +511,21 @@ function reasonToMessage(reason) {
|
|
|
236
511
|
}
|
|
237
512
|
return String(reason);
|
|
238
513
|
}
|
|
239
|
-
var
|
|
514
|
+
var NOOP2 = { stop: () => {
|
|
240
515
|
} };
|
|
241
|
-
var
|
|
516
|
+
var active2 = null;
|
|
242
517
|
function truncate(s, max) {
|
|
243
518
|
return s.length > max ? s.slice(0, max) : s;
|
|
244
519
|
}
|
|
245
520
|
function startJsErrorCapture(options) {
|
|
246
|
-
if (
|
|
247
|
-
if (typeof window === "undefined") return
|
|
521
|
+
if (active2) return active2;
|
|
522
|
+
if (typeof window === "undefined") return NOOP2;
|
|
248
523
|
let logger;
|
|
249
524
|
try {
|
|
250
525
|
logger = setupOtelLogs(options);
|
|
251
526
|
} catch (err) {
|
|
252
527
|
console.warn("[observ] js-errors: logs setup failed", err);
|
|
253
|
-
return
|
|
528
|
+
return NOOP2;
|
|
254
529
|
}
|
|
255
530
|
let windowStart = 0;
|
|
256
531
|
let inWindow = 0;
|
|
@@ -293,10 +568,10 @@ function startJsErrorCapture(options) {
|
|
|
293
568
|
stop() {
|
|
294
569
|
window.removeEventListener("error", onError);
|
|
295
570
|
window.removeEventListener("unhandledrejection", onRejection);
|
|
296
|
-
|
|
571
|
+
active2 = null;
|
|
297
572
|
}
|
|
298
573
|
};
|
|
299
|
-
|
|
574
|
+
active2 = handle;
|
|
300
575
|
return handle;
|
|
301
576
|
}
|
|
302
577
|
var METRIC_EXPORT_INTERVAL_MS = 3e4;
|
|
@@ -378,40 +653,6 @@ async function shutdownOtelMetrics() {
|
|
|
378
653
|
provider2 = null;
|
|
379
654
|
await p?.shutdown();
|
|
380
655
|
}
|
|
381
|
-
|
|
382
|
-
// node_modules/@opentelemetry/instrumentation/build/esm/autoLoaderUtils.js
|
|
383
|
-
function enableInstrumentations(instrumentations, tracerProvider, meterProvider, loggerProvider) {
|
|
384
|
-
for (let i = 0, j = instrumentations.length; i < j; i++) {
|
|
385
|
-
const instrumentation = instrumentations[i];
|
|
386
|
-
if (tracerProvider) {
|
|
387
|
-
instrumentation.setTracerProvider(tracerProvider);
|
|
388
|
-
}
|
|
389
|
-
if (meterProvider) {
|
|
390
|
-
instrumentation.setMeterProvider(meterProvider);
|
|
391
|
-
}
|
|
392
|
-
if (loggerProvider && instrumentation.setLoggerProvider) {
|
|
393
|
-
instrumentation.setLoggerProvider(loggerProvider);
|
|
394
|
-
}
|
|
395
|
-
if (!instrumentation.getConfig().enabled) {
|
|
396
|
-
instrumentation.enable();
|
|
397
|
-
}
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
|
-
function disableInstrumentations(instrumentations) {
|
|
401
|
-
instrumentations.forEach((instrumentation) => instrumentation.disable());
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
// node_modules/@opentelemetry/instrumentation/build/esm/autoLoader.js
|
|
405
|
-
function registerInstrumentations(options) {
|
|
406
|
-
const tracerProvider = options.tracerProvider || trace.getTracerProvider();
|
|
407
|
-
const meterProvider = options.meterProvider || metrics.getMeterProvider();
|
|
408
|
-
const loggerProvider = options.loggerProvider || logs.getLoggerProvider();
|
|
409
|
-
const instrumentations = options.instrumentations?.flat() ?? [];
|
|
410
|
-
enableInstrumentations(instrumentations, tracerProvider, meterProvider, loggerProvider);
|
|
411
|
-
return () => {
|
|
412
|
-
disableInstrumentations(instrumentations);
|
|
413
|
-
};
|
|
414
|
-
}
|
|
415
656
|
function buildSampler(options) {
|
|
416
657
|
const rate = options.sampleRate;
|
|
417
658
|
if (typeof rate === "number" && Number.isFinite(rate) && rate >= 0 && rate < 1) {
|
|
@@ -450,9 +691,37 @@ var SessionAttributeSpanProcessor = class {
|
|
|
450
691
|
return Promise.resolve();
|
|
451
692
|
}
|
|
452
693
|
};
|
|
694
|
+
var UserAttributeSpanProcessor = class {
|
|
695
|
+
onStart(span) {
|
|
696
|
+
applyUserAttributes((key, value) => span.setAttribute(key, value));
|
|
697
|
+
}
|
|
698
|
+
onEnd(_span) {
|
|
699
|
+
}
|
|
700
|
+
forceFlush() {
|
|
701
|
+
return Promise.resolve();
|
|
702
|
+
}
|
|
703
|
+
shutdown() {
|
|
704
|
+
return Promise.resolve();
|
|
705
|
+
}
|
|
706
|
+
};
|
|
453
707
|
var provider3 = null;
|
|
454
|
-
var
|
|
708
|
+
var disableInstrumentations = null;
|
|
455
709
|
var activeConfig = null;
|
|
710
|
+
var userInteractionReady = null;
|
|
711
|
+
function buildBaseInstrumentations(options, ignoreUrls) {
|
|
712
|
+
return [
|
|
713
|
+
// Page-load timing: documentLoad / documentFetch / resourceFetch spans.
|
|
714
|
+
new DocumentLoadInstrumentation(),
|
|
715
|
+
new FetchInstrumentation({
|
|
716
|
+
propagateTraceHeaderCorsUrls: options.propagateTraceHeaderCorsUrls,
|
|
717
|
+
ignoreUrls
|
|
718
|
+
}),
|
|
719
|
+
new XMLHttpRequestInstrumentation({
|
|
720
|
+
propagateTraceHeaderCorsUrls: options.propagateTraceHeaderCorsUrls,
|
|
721
|
+
ignoreUrls
|
|
722
|
+
})
|
|
723
|
+
];
|
|
724
|
+
}
|
|
456
725
|
function setupOtelRum(options) {
|
|
457
726
|
if (provider3) {
|
|
458
727
|
if (activeConfig && (activeConfig.endpoint !== options.endpoint || activeConfig.key !== options.key)) {
|
|
@@ -476,28 +745,38 @@ function setupOtelRum(options) {
|
|
|
476
745
|
const p = new WebTracerProvider({
|
|
477
746
|
resource: buildResource(options),
|
|
478
747
|
sampler: buildSampler(options),
|
|
479
|
-
spanProcessors: [
|
|
748
|
+
spanProcessors: [
|
|
749
|
+
new SessionAttributeSpanProcessor(),
|
|
750
|
+
new UserAttributeSpanProcessor(),
|
|
751
|
+
new BatchSpanProcessor(exporter)
|
|
752
|
+
]
|
|
480
753
|
});
|
|
754
|
+
const base = buildBaseInstrumentations(options, ignoreUrls);
|
|
755
|
+
if (options.userInteraction) {
|
|
756
|
+
provider3 = p;
|
|
757
|
+
activeConfig = { endpoint: options.endpoint, key: options.key };
|
|
758
|
+
userInteractionReady = import('./user-interaction-HZJLQRUN.js').then(({ setupUserInteraction }) => {
|
|
759
|
+
if (provider3 !== p) return;
|
|
760
|
+
disableInstrumentations = setupUserInteraction(p, base);
|
|
761
|
+
}).catch((err) => {
|
|
762
|
+
console.warn("[observ] user-interaction setup failed; tracing degraded.", err);
|
|
763
|
+
if (provider3 === p) {
|
|
764
|
+
provider3 = null;
|
|
765
|
+
activeConfig = null;
|
|
766
|
+
void p.shutdown();
|
|
767
|
+
}
|
|
768
|
+
});
|
|
769
|
+
return;
|
|
770
|
+
}
|
|
481
771
|
try {
|
|
482
772
|
p.register();
|
|
483
|
-
|
|
773
|
+
disableInstrumentations = registerInstrumentations({
|
|
484
774
|
tracerProvider: p,
|
|
485
|
-
instrumentations:
|
|
486
|
-
// Page-load timing: documentLoad / documentFetch / resourceFetch spans.
|
|
487
|
-
new DocumentLoadInstrumentation(),
|
|
488
|
-
new FetchInstrumentation({
|
|
489
|
-
propagateTraceHeaderCorsUrls: options.propagateTraceHeaderCorsUrls,
|
|
490
|
-
ignoreUrls
|
|
491
|
-
}),
|
|
492
|
-
new XMLHttpRequestInstrumentation({
|
|
493
|
-
propagateTraceHeaderCorsUrls: options.propagateTraceHeaderCorsUrls,
|
|
494
|
-
ignoreUrls
|
|
495
|
-
})
|
|
496
|
-
]
|
|
775
|
+
instrumentations: base
|
|
497
776
|
});
|
|
498
777
|
} catch (err) {
|
|
499
|
-
|
|
500
|
-
|
|
778
|
+
disableInstrumentations?.();
|
|
779
|
+
disableInstrumentations = null;
|
|
501
780
|
void p.shutdown();
|
|
502
781
|
throw err;
|
|
503
782
|
}
|
|
@@ -505,17 +784,147 @@ function setupOtelRum(options) {
|
|
|
505
784
|
activeConfig = { endpoint: options.endpoint, key: options.key };
|
|
506
785
|
}
|
|
507
786
|
async function shutdownOtelRum() {
|
|
787
|
+
const pending = userInteractionReady;
|
|
788
|
+
userInteractionReady = null;
|
|
789
|
+
if (pending) {
|
|
790
|
+
try {
|
|
791
|
+
await pending;
|
|
792
|
+
} catch {
|
|
793
|
+
}
|
|
794
|
+
}
|
|
508
795
|
const p = provider3;
|
|
509
796
|
try {
|
|
510
|
-
|
|
797
|
+
disableInstrumentations?.();
|
|
511
798
|
} finally {
|
|
512
|
-
|
|
799
|
+
disableInstrumentations = null;
|
|
513
800
|
provider3 = null;
|
|
514
801
|
activeConfig = null;
|
|
515
802
|
await p?.shutdown();
|
|
516
803
|
}
|
|
517
804
|
}
|
|
518
805
|
|
|
806
|
+
// src/history-nav.ts
|
|
807
|
+
var subscribers = /* @__PURE__ */ new Set();
|
|
808
|
+
var patched = false;
|
|
809
|
+
var originalPush = null;
|
|
810
|
+
var originalReplace = null;
|
|
811
|
+
var popStateHandler = null;
|
|
812
|
+
function notify2(type) {
|
|
813
|
+
for (const fn of subscribers) {
|
|
814
|
+
try {
|
|
815
|
+
fn({ type });
|
|
816
|
+
} catch {
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
function patch() {
|
|
821
|
+
if (patched || typeof window === "undefined" || typeof history === "undefined") return;
|
|
822
|
+
try {
|
|
823
|
+
originalPush = history.pushState;
|
|
824
|
+
originalReplace = history.replaceState;
|
|
825
|
+
history.pushState = function(...args) {
|
|
826
|
+
originalPush?.apply(this, args);
|
|
827
|
+
notify2("pushState");
|
|
828
|
+
};
|
|
829
|
+
history.replaceState = function(...args) {
|
|
830
|
+
originalReplace?.apply(this, args);
|
|
831
|
+
notify2("replaceState");
|
|
832
|
+
};
|
|
833
|
+
} catch {
|
|
834
|
+
if (originalPush) history.pushState = originalPush;
|
|
835
|
+
if (originalReplace) history.replaceState = originalReplace;
|
|
836
|
+
originalPush = null;
|
|
837
|
+
originalReplace = null;
|
|
838
|
+
}
|
|
839
|
+
popStateHandler = () => notify2("popstate");
|
|
840
|
+
window.addEventListener("popstate", popStateHandler);
|
|
841
|
+
patched = true;
|
|
842
|
+
}
|
|
843
|
+
function unpatch() {
|
|
844
|
+
if (!patched) return;
|
|
845
|
+
try {
|
|
846
|
+
if (originalPush) history.pushState = originalPush;
|
|
847
|
+
if (originalReplace) history.replaceState = originalReplace;
|
|
848
|
+
if (popStateHandler) window.removeEventListener("popstate", popStateHandler);
|
|
849
|
+
} catch {
|
|
850
|
+
}
|
|
851
|
+
originalPush = null;
|
|
852
|
+
originalReplace = null;
|
|
853
|
+
popStateHandler = null;
|
|
854
|
+
patched = false;
|
|
855
|
+
}
|
|
856
|
+
function onHistoryNavigation(listener) {
|
|
857
|
+
if (typeof window === "undefined") return () => {
|
|
858
|
+
};
|
|
859
|
+
subscribers.add(listener);
|
|
860
|
+
patch();
|
|
861
|
+
return () => {
|
|
862
|
+
subscribers.delete(listener);
|
|
863
|
+
if (subscribers.size === 0) unpatch();
|
|
864
|
+
};
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
// src/page-views.ts
|
|
868
|
+
var PAGE_VIEW_EVENT = "app.page_view";
|
|
869
|
+
var NOOP3 = { stop: () => {
|
|
870
|
+
} };
|
|
871
|
+
var active3 = null;
|
|
872
|
+
function sanitizePath(path) {
|
|
873
|
+
return (path.split("?")[0] ?? path).split("#")[0] ?? "";
|
|
874
|
+
}
|
|
875
|
+
function nowMs() {
|
|
876
|
+
return typeof performance !== "undefined" && typeof performance.now === "function" ? performance.now() : Date.now();
|
|
877
|
+
}
|
|
878
|
+
function startPageViews(options) {
|
|
879
|
+
if (active3) return active3;
|
|
880
|
+
if (typeof window === "undefined" || typeof document === "undefined") return NOOP3;
|
|
881
|
+
let logger;
|
|
882
|
+
try {
|
|
883
|
+
logger = setupOtelLogs(options);
|
|
884
|
+
} catch {
|
|
885
|
+
return NOOP3;
|
|
886
|
+
}
|
|
887
|
+
let currentPath = sanitizePath(typeof location !== "undefined" ? location.pathname : "/");
|
|
888
|
+
let enteredAt = nowMs();
|
|
889
|
+
try {
|
|
890
|
+
const loadAttrs = {
|
|
891
|
+
"url.path": currentPath,
|
|
892
|
+
"app.page_view.navigation_type": "load"
|
|
893
|
+
};
|
|
894
|
+
if (document.referrer) loadAttrs["app.page_view.referrer"] = document.referrer;
|
|
895
|
+
emitSessionEvent(logger, PAGE_VIEW_EVENT, loadAttrs);
|
|
896
|
+
} catch {
|
|
897
|
+
}
|
|
898
|
+
const unsubscribe = onHistoryNavigation(() => {
|
|
899
|
+
try {
|
|
900
|
+
const toPath = sanitizePath(typeof location !== "undefined" ? location.pathname : currentPath);
|
|
901
|
+
touchSession();
|
|
902
|
+
if (toPath === currentPath) return;
|
|
903
|
+
const now = nowMs();
|
|
904
|
+
emitSessionEvent(logger, PAGE_VIEW_EVENT, {
|
|
905
|
+
"url.path": toPath,
|
|
906
|
+
"app.page_view.referrer_path": currentPath,
|
|
907
|
+
"app.page_view.time_on_previous_ms": String(Math.round(now - enteredAt)),
|
|
908
|
+
"app.page_view.navigation_type": "spa"
|
|
909
|
+
});
|
|
910
|
+
currentPath = toPath;
|
|
911
|
+
enteredAt = now;
|
|
912
|
+
} catch {
|
|
913
|
+
}
|
|
914
|
+
});
|
|
915
|
+
let stopped = false;
|
|
916
|
+
const handle = {
|
|
917
|
+
stop() {
|
|
918
|
+
if (stopped) return;
|
|
919
|
+
stopped = true;
|
|
920
|
+
active3 = null;
|
|
921
|
+
unsubscribe();
|
|
922
|
+
}
|
|
923
|
+
};
|
|
924
|
+
active3 = handle;
|
|
925
|
+
return handle;
|
|
926
|
+
}
|
|
927
|
+
|
|
519
928
|
// src/privacy.ts
|
|
520
929
|
var DEFAULT_MASK_TEXT_CLASS = "observ-mask";
|
|
521
930
|
var DEFAULT_BLOCK_CLASS = "observ-block";
|
|
@@ -704,22 +1113,22 @@ function elementText(el) {
|
|
|
704
1113
|
var RAGE_CLICK_WINDOW_MS = 1e3;
|
|
705
1114
|
var RAGE_CLICK_THRESHOLD = 3;
|
|
706
1115
|
var MAX_TRACKED_SELECTORS = 100;
|
|
707
|
-
var
|
|
708
|
-
var
|
|
1116
|
+
var active4 = null;
|
|
1117
|
+
var NOOP4 = { stop: () => Promise.resolve() };
|
|
709
1118
|
function toElement(target) {
|
|
710
1119
|
if (target instanceof Element) return target;
|
|
711
1120
|
const node = target;
|
|
712
1121
|
return node && node.parentElement ? node.parentElement : null;
|
|
713
1122
|
}
|
|
714
1123
|
function startSemanticEvents(options) {
|
|
715
|
-
if (
|
|
716
|
-
if (typeof document === "undefined" || typeof window === "undefined") return
|
|
1124
|
+
if (active4) return active4;
|
|
1125
|
+
if (typeof document === "undefined" || typeof window === "undefined") return NOOP4;
|
|
717
1126
|
let logger;
|
|
718
1127
|
try {
|
|
719
1128
|
logger = setupOtelLogs(options);
|
|
720
1129
|
} catch (err) {
|
|
721
1130
|
console.warn("[observ] semantic events: logs setup failed", err);
|
|
722
|
-
return
|
|
1131
|
+
return NOOP4;
|
|
723
1132
|
}
|
|
724
1133
|
const clickTimes = /* @__PURE__ */ new Map();
|
|
725
1134
|
const onClick = (event) => {
|
|
@@ -744,45 +1153,124 @@ function startSemanticEvents(options) {
|
|
|
744
1153
|
} catch {
|
|
745
1154
|
}
|
|
746
1155
|
};
|
|
747
|
-
|
|
1156
|
+
document.addEventListener("click", onClick, { capture: true });
|
|
1157
|
+
const unsubscribeNav = onHistoryNavigation(() => {
|
|
748
1158
|
emitSessionEvent(logger, "observ.session.navigate", { url: location.href });
|
|
1159
|
+
});
|
|
1160
|
+
let stopped = false;
|
|
1161
|
+
const handle = {
|
|
1162
|
+
async stop() {
|
|
1163
|
+
if (stopped) return;
|
|
1164
|
+
stopped = true;
|
|
1165
|
+
active4 = null;
|
|
1166
|
+
document.removeEventListener("click", onClick, { capture: true });
|
|
1167
|
+
unsubscribeNav();
|
|
1168
|
+
}
|
|
749
1169
|
};
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
1170
|
+
active4 = handle;
|
|
1171
|
+
return handle;
|
|
1172
|
+
}
|
|
1173
|
+
|
|
1174
|
+
// src/session-lifecycle.ts
|
|
1175
|
+
var SESSION_START_EVENT = "session.start";
|
|
1176
|
+
var SESSION_END_EVENT = "session.end";
|
|
1177
|
+
var SWEEP_INTERVAL_MS = 6e4;
|
|
1178
|
+
var MOUSEMOVE_THROTTLE_MS = 1e3;
|
|
1179
|
+
var ACTIVITY_EVENTS = ["click", "keydown", "scroll"];
|
|
1180
|
+
var active5 = null;
|
|
1181
|
+
function emitLifecycle(logger, event) {
|
|
1182
|
+
if (event.type === "start") {
|
|
1183
|
+
resetSessionIdCache();
|
|
1184
|
+
const attrs = { [SESSION_ID_ATTRIBUTE]: event.id };
|
|
1185
|
+
if (event.previousId) attrs["session.previous_id"] = event.previousId;
|
|
1186
|
+
emitSessionEvent(logger, SESSION_START_EVENT, attrs);
|
|
1187
|
+
} else {
|
|
1188
|
+
emitSessionEvent(logger, SESSION_END_EVENT, {
|
|
1189
|
+
[SESSION_ID_ATTRIBUTE]: event.id,
|
|
1190
|
+
"session.duration_ms": String(event.durationMs)
|
|
1191
|
+
});
|
|
1192
|
+
}
|
|
1193
|
+
}
|
|
1194
|
+
function startSessionLifecycle(options) {
|
|
1195
|
+
if (active5) return active5;
|
|
1196
|
+
let logger = null;
|
|
756
1197
|
try {
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
1198
|
+
logger = setupOtelLogs(options);
|
|
1199
|
+
} catch (err) {
|
|
1200
|
+
console.warn("[observ] session lifecycle: logs setup failed; events disabled.", err);
|
|
1201
|
+
}
|
|
1202
|
+
const unsubscribe = addSessionListener((event) => {
|
|
1203
|
+
if (logger) emitLifecycle(logger, event);
|
|
1204
|
+
});
|
|
1205
|
+
if (typeof window === "undefined" || typeof document === "undefined") {
|
|
1206
|
+
const handle2 = {
|
|
1207
|
+
stop() {
|
|
1208
|
+
unsubscribe();
|
|
1209
|
+
active5 = null;
|
|
1210
|
+
}
|
|
764
1211
|
};
|
|
765
|
-
|
|
766
|
-
|
|
1212
|
+
active5 = handle2;
|
|
1213
|
+
return handle2;
|
|
767
1214
|
}
|
|
1215
|
+
const onActivity = () => {
|
|
1216
|
+
try {
|
|
1217
|
+
touchSession();
|
|
1218
|
+
} catch {
|
|
1219
|
+
}
|
|
1220
|
+
};
|
|
1221
|
+
let lastMove = 0;
|
|
1222
|
+
const onMouseMove = () => {
|
|
1223
|
+
const now = Date.now();
|
|
1224
|
+
if (now - lastMove < MOUSEMOVE_THROTTLE_MS) return;
|
|
1225
|
+
lastMove = now;
|
|
1226
|
+
onActivity();
|
|
1227
|
+
};
|
|
1228
|
+
for (const evt of ACTIVITY_EVENTS) {
|
|
1229
|
+
window.addEventListener(evt, onActivity, { passive: true });
|
|
1230
|
+
}
|
|
1231
|
+
window.addEventListener("mousemove", onMouseMove, { passive: true });
|
|
1232
|
+
const onHide = () => {
|
|
1233
|
+
try {
|
|
1234
|
+
endSessionIfExpired();
|
|
1235
|
+
} catch {
|
|
1236
|
+
}
|
|
1237
|
+
};
|
|
1238
|
+
const onVisibility = () => {
|
|
1239
|
+
if (document.visibilityState === "hidden") onHide();
|
|
1240
|
+
};
|
|
1241
|
+
window.addEventListener("pagehide", onHide);
|
|
1242
|
+
document.addEventListener("visibilitychange", onVisibility);
|
|
1243
|
+
const onStorage = (e) => {
|
|
1244
|
+
if (e.key !== SESSION_STORAGE_KEY || e.newValue == null) return;
|
|
1245
|
+
try {
|
|
1246
|
+
adoptStoredSession();
|
|
1247
|
+
resetSessionIdCache();
|
|
1248
|
+
} catch {
|
|
1249
|
+
}
|
|
1250
|
+
};
|
|
1251
|
+
window.addEventListener("storage", onStorage);
|
|
1252
|
+
const sweepTimer = setInterval(() => {
|
|
1253
|
+
try {
|
|
1254
|
+
endSessionIfExpired();
|
|
1255
|
+
} catch {
|
|
1256
|
+
}
|
|
1257
|
+
}, SWEEP_INTERVAL_MS);
|
|
768
1258
|
let stopped = false;
|
|
769
1259
|
const handle = {
|
|
770
|
-
|
|
1260
|
+
stop() {
|
|
771
1261
|
if (stopped) return;
|
|
772
1262
|
stopped = true;
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
}
|
|
782
|
-
}
|
|
1263
|
+
active5 = null;
|
|
1264
|
+
unsubscribe();
|
|
1265
|
+
clearInterval(sweepTimer);
|
|
1266
|
+
for (const evt of ACTIVITY_EVENTS) window.removeEventListener(evt, onActivity);
|
|
1267
|
+
window.removeEventListener("mousemove", onMouseMove);
|
|
1268
|
+
window.removeEventListener("pagehide", onHide);
|
|
1269
|
+
document.removeEventListener("visibilitychange", onVisibility);
|
|
1270
|
+
window.removeEventListener("storage", onStorage);
|
|
783
1271
|
}
|
|
784
1272
|
};
|
|
785
|
-
|
|
1273
|
+
active5 = handle;
|
|
786
1274
|
return handle;
|
|
787
1275
|
}
|
|
788
1276
|
|
|
@@ -790,10 +1278,40 @@ function startSemanticEvents(options) {
|
|
|
790
1278
|
var replayRecorder = null;
|
|
791
1279
|
var semanticEvents = null;
|
|
792
1280
|
var jsErrors = null;
|
|
793
|
-
var
|
|
1281
|
+
var metrics = null;
|
|
794
1282
|
var baggageUninstall = null;
|
|
1283
|
+
var sessionLifecycle = null;
|
|
1284
|
+
var consoleForward = null;
|
|
1285
|
+
var pageViews = null;
|
|
1286
|
+
var pendingConsentOptions = null;
|
|
1287
|
+
var lastStartedOptions = null;
|
|
1288
|
+
var consentWatcherCleanup = null;
|
|
1289
|
+
var CONSENT_POLL_MS = 1500;
|
|
795
1290
|
function init(options) {
|
|
796
1291
|
try {
|
|
1292
|
+
if (options.requireConsent && !hasAnalyticsConsent(options)) {
|
|
1293
|
+
pendingConsentOptions = options;
|
|
1294
|
+
installConsentWatcher(options);
|
|
1295
|
+
return;
|
|
1296
|
+
}
|
|
1297
|
+
startSdk(options);
|
|
1298
|
+
} catch (err) {
|
|
1299
|
+
console.warn("[observ] RUM init failed; telemetry disabled.", err);
|
|
1300
|
+
}
|
|
1301
|
+
}
|
|
1302
|
+
function startSdk(options) {
|
|
1303
|
+
try {
|
|
1304
|
+
lastStartedOptions = options;
|
|
1305
|
+
configureSession({
|
|
1306
|
+
inactivityTimeoutMs: options.sessionInactivityMs,
|
|
1307
|
+
maxDurationMs: options.sessionMaxDurationMs,
|
|
1308
|
+
crossTab: options.crossTabSessions
|
|
1309
|
+
});
|
|
1310
|
+
configureUser({ disablePseudoUser: options.disablePseudoUser });
|
|
1311
|
+
getPseudoUserId();
|
|
1312
|
+
if (!sessionLifecycle) {
|
|
1313
|
+
sessionLifecycle = startSessionLifecycle(options);
|
|
1314
|
+
}
|
|
797
1315
|
ensureSession();
|
|
798
1316
|
setupOtelRum(options);
|
|
799
1317
|
if (!options.disableReplay && !replayRecorder) {
|
|
@@ -802,11 +1320,17 @@ function init(options) {
|
|
|
802
1320
|
if (!semanticEvents) {
|
|
803
1321
|
semanticEvents = startSemanticEvents(options);
|
|
804
1322
|
}
|
|
1323
|
+
if (!options.disablePageViews && !pageViews) {
|
|
1324
|
+
pageViews = startPageViews(options);
|
|
1325
|
+
}
|
|
805
1326
|
if (!jsErrors) {
|
|
806
1327
|
jsErrors = startJsErrorCapture(options);
|
|
807
1328
|
}
|
|
808
|
-
if (
|
|
809
|
-
|
|
1329
|
+
if (options.forwardConsole && !consoleForward) {
|
|
1330
|
+
consoleForward = startConsoleForward(options);
|
|
1331
|
+
}
|
|
1332
|
+
if (!options.disableMetrics && !metrics) {
|
|
1333
|
+
metrics = setupOtelMetrics(options);
|
|
810
1334
|
}
|
|
811
1335
|
if (options.propagateBaggage && !baggageUninstall) {
|
|
812
1336
|
const backends = [...options.propagateTraceHeaderCorsUrls ?? []];
|
|
@@ -821,17 +1345,79 @@ function init(options) {
|
|
|
821
1345
|
console.warn("[observ] RUM setup failed; tracing/replay/events degraded.", err);
|
|
822
1346
|
}
|
|
823
1347
|
}
|
|
1348
|
+
function removeConsentWatcher() {
|
|
1349
|
+
const cleanup = consentWatcherCleanup;
|
|
1350
|
+
consentWatcherCleanup = null;
|
|
1351
|
+
try {
|
|
1352
|
+
cleanup?.();
|
|
1353
|
+
} catch {
|
|
1354
|
+
}
|
|
1355
|
+
}
|
|
1356
|
+
function startFromConsent(options) {
|
|
1357
|
+
removeConsentWatcher();
|
|
1358
|
+
pendingConsentOptions = null;
|
|
1359
|
+
startSdk(options);
|
|
1360
|
+
}
|
|
1361
|
+
function installConsentWatcher(options) {
|
|
1362
|
+
if (consentWatcherCleanup || typeof window === "undefined") return;
|
|
1363
|
+
const key = consentKey(options);
|
|
1364
|
+
const tryStart = () => {
|
|
1365
|
+
if (hasAnalyticsConsent(options)) startFromConsent(options);
|
|
1366
|
+
};
|
|
1367
|
+
const onStorage = (e) => {
|
|
1368
|
+
if (e.key === key) tryStart();
|
|
1369
|
+
};
|
|
1370
|
+
window.addEventListener("storage", onStorage);
|
|
1371
|
+
const interval = setInterval(tryStart, CONSENT_POLL_MS);
|
|
1372
|
+
consentWatcherCleanup = () => {
|
|
1373
|
+
window.removeEventListener("storage", onStorage);
|
|
1374
|
+
clearInterval(interval);
|
|
1375
|
+
};
|
|
1376
|
+
}
|
|
1377
|
+
function grantConsent() {
|
|
1378
|
+
const options = pendingConsentOptions;
|
|
1379
|
+
if (!options) return;
|
|
1380
|
+
writeConsent(options);
|
|
1381
|
+
startFromConsent(options);
|
|
1382
|
+
}
|
|
1383
|
+
function revokeConsent() {
|
|
1384
|
+
const options = pendingConsentOptions ?? lastStartedOptions;
|
|
1385
|
+
if (options) clearConsent(options);
|
|
1386
|
+
removeConsentWatcher();
|
|
1387
|
+
pendingConsentOptions = null;
|
|
1388
|
+
void shutdown();
|
|
1389
|
+
}
|
|
824
1390
|
async function shutdown() {
|
|
1391
|
+
removeConsentWatcher();
|
|
1392
|
+
pendingConsentOptions = null;
|
|
825
1393
|
const recorder = replayRecorder;
|
|
826
1394
|
const events = semanticEvents;
|
|
827
1395
|
const errors = jsErrors;
|
|
828
|
-
const metricsHandle =
|
|
1396
|
+
const metricsHandle = metrics;
|
|
829
1397
|
const uninstallBaggage = baggageUninstall;
|
|
1398
|
+
const lifecycle = sessionLifecycle;
|
|
1399
|
+
const consoleHandle = consoleForward;
|
|
1400
|
+
const pageViewsHandle = pageViews;
|
|
830
1401
|
replayRecorder = null;
|
|
831
1402
|
semanticEvents = null;
|
|
832
1403
|
jsErrors = null;
|
|
833
|
-
|
|
1404
|
+
metrics = null;
|
|
834
1405
|
baggageUninstall = null;
|
|
1406
|
+
sessionLifecycle = null;
|
|
1407
|
+
consoleForward = null;
|
|
1408
|
+
pageViews = null;
|
|
1409
|
+
try {
|
|
1410
|
+
consoleHandle?.stop();
|
|
1411
|
+
} catch {
|
|
1412
|
+
}
|
|
1413
|
+
try {
|
|
1414
|
+
pageViewsHandle?.stop();
|
|
1415
|
+
} catch {
|
|
1416
|
+
}
|
|
1417
|
+
try {
|
|
1418
|
+
lifecycle?.stop();
|
|
1419
|
+
} catch {
|
|
1420
|
+
}
|
|
835
1421
|
try {
|
|
836
1422
|
uninstallBaggage?.();
|
|
837
1423
|
} catch {
|
|
@@ -861,9 +1447,16 @@ async function shutdown() {
|
|
|
861
1447
|
} catch {
|
|
862
1448
|
}
|
|
863
1449
|
}
|
|
864
|
-
var observ = {
|
|
1450
|
+
var observ = {
|
|
1451
|
+
init,
|
|
1452
|
+
shutdown,
|
|
1453
|
+
setUser,
|
|
1454
|
+
clearUser,
|
|
1455
|
+
grantConsent,
|
|
1456
|
+
revokeConsent
|
|
1457
|
+
};
|
|
865
1458
|
var index_default = observ;
|
|
866
1459
|
|
|
867
|
-
export { SESSION_ID_ATTRIBUTE, index_default as default, init, observ, shutdown };
|
|
1460
|
+
export { SESSION_ID_ATTRIBUTE, clearUser, index_default as default, grantConsent, init, observ, revokeConsent, setUser, shutdown };
|
|
868
1461
|
//# sourceMappingURL=index.js.map
|
|
869
1462
|
//# sourceMappingURL=index.js.map
|