@softprobe/web-record 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/README.md +55 -0
- package/dist/http-interceptor.d.ts +12 -0
- package/dist/http-interceptor.d.ts.map +1 -0
- package/dist/http-interceptor.js +126 -0
- package/dist/http-interceptor.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/otlp.d.ts +37 -0
- package/dist/otlp.d.ts.map +1 -0
- package/dist/otlp.js +81 -0
- package/dist/otlp.js.map +1 -0
- package/dist/sdk.d.ts +53 -0
- package/dist/sdk.d.ts.map +1 -0
- package/dist/sdk.js +356 -0
- package/dist/sdk.js.map +1 -0
- package/dist/types.d.ts +79 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +56 -0
package/README.md
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# @softprobe/web-record
|
|
2
|
+
|
|
3
|
+
Browser session recording SDK. Captures DOM mutations with [rrweb](https://github.com/rrweb-io/rrweb)
|
|
4
|
+
and exports batches to Softprobe **thelake** via OTLP `POST {baseUrl}/v1/traces`.
|
|
5
|
+
|
|
6
|
+
## Install
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
npm install @softprobe/web-record
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Usage
|
|
13
|
+
|
|
14
|
+
```ts
|
|
15
|
+
import { RecordSdk } from "@softprobe/web-record";
|
|
16
|
+
|
|
17
|
+
const recorder = RecordSdk.init({
|
|
18
|
+
publicKey: process.env.SOFTPROBE_PUBLIC_KEY!,
|
|
19
|
+
baseUrl: process.env.SOFTPROBE_BASE_URL!,
|
|
20
|
+
sessionId: openCodeSessionId, // becomes sp.session.id
|
|
21
|
+
serviceName: "softprobe-code",
|
|
22
|
+
maskAllInputs: true,
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
// When the chat session changes:
|
|
26
|
+
recorder.setSessionId(nextSessionId);
|
|
27
|
+
|
|
28
|
+
// On teardown:
|
|
29
|
+
recorder.stop();
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Missing credentials soft-disable the SDK (warn + no-op) so hosts keep running.
|
|
33
|
+
|
|
34
|
+
## Session header
|
|
35
|
+
|
|
36
|
+
While recording is enabled, the SDK patches `fetch` / XHR to inject
|
|
37
|
+
`x-sp-session-id` on **same-origin** requests only (relative URLs and
|
|
38
|
+
`location.origin`). Third-party / CDN calls are left untouched.
|
|
39
|
+
|
|
40
|
+
## OTLP contract
|
|
41
|
+
|
|
42
|
+
Each flush emits one span:
|
|
43
|
+
|
|
44
|
+
| Field | Value |
|
|
45
|
+
|---|---|
|
|
46
|
+
| name | `softprobe.web.recording` |
|
|
47
|
+
| `sp.observation.type` | `recording` |
|
|
48
|
+
| `sp.session.id` | correlation id |
|
|
49
|
+
| `sp.recording.batch_index` | monotonic batch counter |
|
|
50
|
+
| event `sp.recording.batch` | attribute `sp.recording.events` = JSON rrweb events |
|
|
51
|
+
|
|
52
|
+
Auth: `Authorization: Bearer <publicKey>`.
|
|
53
|
+
|
|
54
|
+
Credentials and `{baseUrl}/v1/traces` derivation come from `@softprobe/tracing/config`
|
|
55
|
+
(same product semantics as the LLM SDK).
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
type SessionIdProvider = () => string;
|
|
2
|
+
export declare function getSessionIdHeaderName(): string;
|
|
3
|
+
/**
|
|
4
|
+
* Patches XHR + fetch to inject `x-sp-session-id` on same-origin requests only.
|
|
5
|
+
* Provider is consulted on each request so session switches take effect.
|
|
6
|
+
*/
|
|
7
|
+
export declare function initializeHttpInterceptor(getSessionId: SessionIdProvider): void;
|
|
8
|
+
export declare function updateHttpInterceptorSessionId(getSessionId: SessionIdProvider): void;
|
|
9
|
+
/** Relative URLs and same `location.origin` only — skip third-party/CDN. */
|
|
10
|
+
export declare function isSameOriginRequest(resource: RequestInfo | URL): boolean;
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=http-interceptor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http-interceptor.d.ts","sourceRoot":"","sources":["../src/http-interceptor.ts"],"names":[],"mappings":"AAEA,KAAK,iBAAiB,GAAG,MAAM,MAAM,CAAC;AAItC,wBAAgB,sBAAsB,IAAI,MAAM,CAE/C;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,YAAY,EAAE,iBAAiB,GAAG,IAAI,CAI/E;AAED,wBAAgB,8BAA8B,CAAC,YAAY,EAAE,iBAAiB,GAAG,IAAI,CAEpF;AAMD,4EAA4E;AAC5E,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,WAAW,GAAG,GAAG,GAAG,OAAO,CA2BxE"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
const HEADER_X_SP_SESSION_ID = "x-sp-session-id";
|
|
2
|
+
let sessionIdProvider = null;
|
|
3
|
+
export function getSessionIdHeaderName() {
|
|
4
|
+
return HEADER_X_SP_SESSION_ID;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Patches XHR + fetch to inject `x-sp-session-id` on same-origin requests only.
|
|
8
|
+
* Provider is consulted on each request so session switches take effect.
|
|
9
|
+
*/
|
|
10
|
+
export function initializeHttpInterceptor(getSessionId) {
|
|
11
|
+
sessionIdProvider = getSessionId;
|
|
12
|
+
patchXMLHttpRequest();
|
|
13
|
+
patchFetchAPI();
|
|
14
|
+
}
|
|
15
|
+
export function updateHttpInterceptorSessionId(getSessionId) {
|
|
16
|
+
sessionIdProvider = getSessionId;
|
|
17
|
+
}
|
|
18
|
+
function currentSessionId() {
|
|
19
|
+
return sessionIdProvider?.() ?? "";
|
|
20
|
+
}
|
|
21
|
+
/** Relative URLs and same `location.origin` only — skip third-party/CDN. */
|
|
22
|
+
export function isSameOriginRequest(resource) {
|
|
23
|
+
try {
|
|
24
|
+
let href;
|
|
25
|
+
if (typeof Request !== "undefined" && resource instanceof Request) {
|
|
26
|
+
href = resource.url;
|
|
27
|
+
}
|
|
28
|
+
else if (resource instanceof URL) {
|
|
29
|
+
href = resource.href;
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
href = String(resource);
|
|
33
|
+
}
|
|
34
|
+
// Scheme-relative or absolute with a scheme → compare origins.
|
|
35
|
+
// Bare paths (`/api`, `./x`) resolve against location and are same-origin.
|
|
36
|
+
if (typeof location === "undefined") {
|
|
37
|
+
// No browsing context (e.g. unit tests without jsdom location): treat
|
|
38
|
+
// relative paths as same-origin; absolute http(s) as cross-origin.
|
|
39
|
+
if (!/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(href) && !href.startsWith("//")) {
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
const resolved = new URL(href, location.href);
|
|
45
|
+
return resolved.origin === location.origin;
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function patchXMLHttpRequest() {
|
|
52
|
+
if (typeof XMLHttpRequest === "undefined")
|
|
53
|
+
return;
|
|
54
|
+
if (XMLHttpRequest.__sp_sdk_patched_xhr) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
const originalOpen = XMLHttpRequest.prototype.open;
|
|
58
|
+
const originalSend = XMLHttpRequest.prototype.send;
|
|
59
|
+
XMLHttpRequest.prototype.open = function (method, url, async, username, password) {
|
|
60
|
+
this.__sp_request_url =
|
|
61
|
+
url;
|
|
62
|
+
return originalOpen.call(this, method, url, async ?? true, username, password);
|
|
63
|
+
};
|
|
64
|
+
XMLHttpRequest.prototype.send = function (body) {
|
|
65
|
+
const sid = currentSessionId();
|
|
66
|
+
const url = this
|
|
67
|
+
.__sp_request_url;
|
|
68
|
+
if (sid && url !== undefined && isSameOriginRequest(url)) {
|
|
69
|
+
try {
|
|
70
|
+
this.setRequestHeader(HEADER_X_SP_SESSION_ID, sid);
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
// Headers may already be sent; never block the request.
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return originalSend.call(this, body);
|
|
77
|
+
};
|
|
78
|
+
XMLHttpRequest.__sp_sdk_patched_xhr = true;
|
|
79
|
+
}
|
|
80
|
+
function patchFetchAPI() {
|
|
81
|
+
if (typeof globalThis.fetch === "undefined")
|
|
82
|
+
return;
|
|
83
|
+
const g = globalThis;
|
|
84
|
+
if (g.fetch.__sp_sdk_patched_fetch)
|
|
85
|
+
return;
|
|
86
|
+
const originalFetch = g.fetch.bind(globalThis);
|
|
87
|
+
g.fetch = (async function patchedFetch(resource, options) {
|
|
88
|
+
const sid = currentSessionId();
|
|
89
|
+
if (!sid || !isSameOriginRequest(resource)) {
|
|
90
|
+
return originalFetch(resource, options);
|
|
91
|
+
}
|
|
92
|
+
try {
|
|
93
|
+
if (typeof Request !== "undefined" && resource instanceof Request) {
|
|
94
|
+
const headers = new Headers(resource.headers);
|
|
95
|
+
if (options?.headers) {
|
|
96
|
+
new Headers(options.headers).forEach((value, key) => {
|
|
97
|
+
headers.set(key, value);
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
headers.set(HEADER_X_SP_SESSION_ID, sid);
|
|
101
|
+
return originalFetch(resource, { ...options, headers });
|
|
102
|
+
}
|
|
103
|
+
const next = { ...(options ?? {}) };
|
|
104
|
+
const headers = next.headers ?? {};
|
|
105
|
+
if (headers instanceof Headers) {
|
|
106
|
+
headers.set(HEADER_X_SP_SESSION_ID, sid);
|
|
107
|
+
next.headers = headers;
|
|
108
|
+
}
|
|
109
|
+
else if (Array.isArray(headers)) {
|
|
110
|
+
next.headers = [...headers, [HEADER_X_SP_SESSION_ID, sid]];
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
next.headers = {
|
|
114
|
+
...headers,
|
|
115
|
+
[HEADER_X_SP_SESSION_ID]: sid,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
return originalFetch(resource, next);
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
return originalFetch(resource, options);
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
g.fetch.__sp_sdk_patched_fetch = true;
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=http-interceptor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http-interceptor.js","sourceRoot":"","sources":["../src/http-interceptor.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { RecordSdk } from "./sdk.js";
|
|
2
|
+
export { buildRecordingExport, msToUnixNano, randomHexId, EVENT_NAME, EVENTS_ATTR, SPAN_NAME, } from "./otlp.js";
|
|
3
|
+
export { getSessionIdHeaderName, initializeHttpInterceptor, updateHttpInterceptorSessionId, } from "./http-interceptor.js";
|
|
4
|
+
export type { CompressedRrwebEvent, RecordingHandle, RrwebEventBatchItem, SystemInfo, Tags, WebRecordController, WebRecordCredentials, WebRecordInitOptions, } from "./types.js";
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EACL,oBAAoB,EACpB,YAAY,EACZ,WAAW,EACX,UAAU,EACV,WAAW,EACX,SAAS,GACV,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,sBAAsB,EACtB,yBAAyB,EACzB,8BAA8B,GAC/B,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EACV,oBAAoB,EACpB,eAAe,EACf,mBAAmB,EACnB,UAAU,EACV,IAAI,EACJ,mBAAmB,EACnB,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,YAAY,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { RecordSdk } from "./sdk.js";
|
|
2
|
+
export { buildRecordingExport, msToUnixNano, randomHexId, EVENT_NAME, EVENTS_ATTR, SPAN_NAME, } from "./otlp.js";
|
|
3
|
+
export { getSessionIdHeaderName, initializeHttpInterceptor, updateHttpInterceptorSessionId, } from "./http-interceptor.js";
|
|
4
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EACL,oBAAoB,EACpB,YAAY,EACZ,WAAW,EACX,UAAU,EACV,WAAW,EACX,SAAS,GACV,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,sBAAsB,EACtB,yBAAyB,EACzB,8BAA8B,GAC/B,MAAM,uBAAuB,CAAC"}
|
package/dist/otlp.d.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { RrwebEventBatchItem } from "./types.js";
|
|
2
|
+
declare const SPAN_NAME = "softprobe.web.recording";
|
|
3
|
+
declare const EVENT_NAME = "sp.recording.batch";
|
|
4
|
+
declare const EVENTS_ATTR = "sp.recording.events";
|
|
5
|
+
export type OtlpStringAttr = {
|
|
6
|
+
key: string;
|
|
7
|
+
value: {
|
|
8
|
+
stringValue: string;
|
|
9
|
+
};
|
|
10
|
+
};
|
|
11
|
+
export type OtlpIntAttr = {
|
|
12
|
+
key: string;
|
|
13
|
+
value: {
|
|
14
|
+
intValue: string;
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
export type OtlpAttr = OtlpStringAttr | OtlpIntAttr;
|
|
18
|
+
export type BuildRecordingSpanInput = {
|
|
19
|
+
traceId: string;
|
|
20
|
+
spanId: string;
|
|
21
|
+
sessionId: string;
|
|
22
|
+
batchIndex: number;
|
|
23
|
+
startTimeUnixNano: string;
|
|
24
|
+
endTimeUnixNano: string;
|
|
25
|
+
events: RrwebEventBatchItem[];
|
|
26
|
+
attributes: Record<string, string | number | boolean | null | undefined>;
|
|
27
|
+
serviceName?: string;
|
|
28
|
+
environment?: string;
|
|
29
|
+
};
|
|
30
|
+
/** Build an OTLP JSON ExportTraceServiceRequest for one recording flush. */
|
|
31
|
+
export declare function buildRecordingExport(input: BuildRecordingSpanInput): {
|
|
32
|
+
resourceSpans: unknown[];
|
|
33
|
+
};
|
|
34
|
+
export declare function randomHexId(bytes: number): string;
|
|
35
|
+
export declare function msToUnixNano(ms: number): string;
|
|
36
|
+
export { SPAN_NAME, EVENT_NAME, EVENTS_ATTR };
|
|
37
|
+
//# sourceMappingURL=otlp.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"otlp.d.ts","sourceRoot":"","sources":["../src/otlp.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEtD,QAAA,MAAM,SAAS,4BAA4B,CAAC;AAC5C,QAAA,MAAM,UAAU,uBAAuB,CAAC;AACxC,QAAA,MAAM,WAAW,wBAAwB,CAAC;AAE1C,MAAM,MAAM,cAAc,GAAG;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;CAC7B,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG,cAAc,GAAG,WAAW,CAAC;AAEpD,MAAM,MAAM,uBAAuB,GAAG;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,mBAAmB,EAAE,CAAC;IAC9B,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;IACzE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAyBF,4EAA4E;AAC5E,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,uBAAuB,GAAG;IACpE,aAAa,EAAE,OAAO,EAAE,CAAC;CAC1B,CAmDA;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAIjD;AAED,wBAAgB,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,WAAW,EAAE,CAAC"}
|
package/dist/otlp.js
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
const SPAN_NAME = "softprobe.web.recording";
|
|
2
|
+
const EVENT_NAME = "sp.recording.batch";
|
|
3
|
+
const EVENTS_ATTR = "sp.recording.events";
|
|
4
|
+
function stringAttr(key, value) {
|
|
5
|
+
return { key, value: { stringValue: value } };
|
|
6
|
+
}
|
|
7
|
+
function intAttr(key, value) {
|
|
8
|
+
return { key, value: { intValue: String(Math.trunc(value)) } };
|
|
9
|
+
}
|
|
10
|
+
function toAttrs(attributes) {
|
|
11
|
+
const out = [];
|
|
12
|
+
for (const [key, raw] of Object.entries(attributes)) {
|
|
13
|
+
if (raw === undefined || raw === null)
|
|
14
|
+
continue;
|
|
15
|
+
if (typeof raw === "number" && Number.isFinite(raw)) {
|
|
16
|
+
out.push(intAttr(key, raw));
|
|
17
|
+
continue;
|
|
18
|
+
}
|
|
19
|
+
out.push(stringAttr(key, String(raw)));
|
|
20
|
+
}
|
|
21
|
+
return out;
|
|
22
|
+
}
|
|
23
|
+
/** Build an OTLP JSON ExportTraceServiceRequest for one recording flush. */
|
|
24
|
+
export function buildRecordingExport(input) {
|
|
25
|
+
const attrs = [
|
|
26
|
+
stringAttr("sp.session.id", input.sessionId),
|
|
27
|
+
stringAttr("sp.observation.type", "recording"),
|
|
28
|
+
intAttr("sp.recording.batch_index", input.batchIndex),
|
|
29
|
+
...toAttrs(input.attributes),
|
|
30
|
+
];
|
|
31
|
+
const resourceAttrs = [];
|
|
32
|
+
if (input.serviceName) {
|
|
33
|
+
resourceAttrs.push(stringAttr("service.name", input.serviceName));
|
|
34
|
+
}
|
|
35
|
+
if (input.environment) {
|
|
36
|
+
resourceAttrs.push(stringAttr("deployment.environment.name", input.environment));
|
|
37
|
+
}
|
|
38
|
+
return {
|
|
39
|
+
resourceSpans: [
|
|
40
|
+
{
|
|
41
|
+
resource: { attributes: resourceAttrs },
|
|
42
|
+
scopeSpans: [
|
|
43
|
+
{
|
|
44
|
+
scope: { name: "softprobe.web.record", version: "0.1.0" },
|
|
45
|
+
spans: [
|
|
46
|
+
{
|
|
47
|
+
traceId: input.traceId,
|
|
48
|
+
spanId: input.spanId,
|
|
49
|
+
name: SPAN_NAME,
|
|
50
|
+
kind: 1,
|
|
51
|
+
startTimeUnixNano: input.startTimeUnixNano,
|
|
52
|
+
endTimeUnixNano: input.endTimeUnixNano,
|
|
53
|
+
attributes: attrs,
|
|
54
|
+
events: [
|
|
55
|
+
{
|
|
56
|
+
timeUnixNano: input.endTimeUnixNano,
|
|
57
|
+
name: EVENT_NAME,
|
|
58
|
+
attributes: [
|
|
59
|
+
stringAttr(EVENTS_ATTR, JSON.stringify(input.events)),
|
|
60
|
+
],
|
|
61
|
+
},
|
|
62
|
+
],
|
|
63
|
+
status: { code: 1 },
|
|
64
|
+
},
|
|
65
|
+
],
|
|
66
|
+
},
|
|
67
|
+
],
|
|
68
|
+
},
|
|
69
|
+
],
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
export function randomHexId(bytes) {
|
|
73
|
+
const buf = new Uint8Array(bytes);
|
|
74
|
+
crypto.getRandomValues(buf);
|
|
75
|
+
return Array.from(buf, (b) => b.toString(16).padStart(2, "0")).join("");
|
|
76
|
+
}
|
|
77
|
+
export function msToUnixNano(ms) {
|
|
78
|
+
return `${BigInt(Math.trunc(ms)) * 1000000n}`;
|
|
79
|
+
}
|
|
80
|
+
export { SPAN_NAME, EVENT_NAME, EVENTS_ATTR };
|
|
81
|
+
//# sourceMappingURL=otlp.js.map
|
package/dist/otlp.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"otlp.js","sourceRoot":"","sources":["../src/otlp.ts"],"names":[],"mappings":"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"}
|
package/dist/sdk.d.ts
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { type eventWithTime } from "@rrweb/types";
|
|
2
|
+
import type { RecordingHandle, Tags, WebRecordController, WebRecordInitOptions } from "./types.js";
|
|
3
|
+
type Compressible = eventWithTime & {
|
|
4
|
+
data?: unknown;
|
|
5
|
+
isCompressed?: boolean;
|
|
6
|
+
eventIndex?: number;
|
|
7
|
+
};
|
|
8
|
+
export declare class RecordSdk implements WebRecordController {
|
|
9
|
+
readonly enabled: boolean;
|
|
10
|
+
private _sessionId;
|
|
11
|
+
private readonly otlpEndpoint;
|
|
12
|
+
private readonly publicKey;
|
|
13
|
+
private readonly intervalMs;
|
|
14
|
+
private readonly serviceName?;
|
|
15
|
+
private readonly environment?;
|
|
16
|
+
private readonly userId?;
|
|
17
|
+
private readonly maskAllInputs;
|
|
18
|
+
private readonly recordOptions;
|
|
19
|
+
private readonly replacers;
|
|
20
|
+
private tags;
|
|
21
|
+
private events;
|
|
22
|
+
private eventIndex;
|
|
23
|
+
private lastSnapshotIndex;
|
|
24
|
+
private batchIndex;
|
|
25
|
+
private visitorId;
|
|
26
|
+
private systemInfo;
|
|
27
|
+
private stopHandle;
|
|
28
|
+
private saving;
|
|
29
|
+
private fetchImpl;
|
|
30
|
+
/** Serializes setSessionId drains so overlapping navigations cannot race. */
|
|
31
|
+
private sessionSwitch;
|
|
32
|
+
private constructor();
|
|
33
|
+
get sessionId(): string;
|
|
34
|
+
static init(options?: WebRecordInitOptions): WebRecordController;
|
|
35
|
+
record(opts?: {
|
|
36
|
+
tags?: Tags;
|
|
37
|
+
}): RecordingHandle | null;
|
|
38
|
+
stop(): void;
|
|
39
|
+
setTags(tags: Tags, override?: boolean): void;
|
|
40
|
+
setSessionId(sessionId: string): Promise<void>;
|
|
41
|
+
private switchSessionId;
|
|
42
|
+
/**
|
|
43
|
+
* Wait out in-flight exports, then flush until the buffer is empty.
|
|
44
|
+
* Stops after a failed flush so we do not spin forever when OTLP is down
|
|
45
|
+
* (events stay queued under the old session for a later attempt / stop).
|
|
46
|
+
*/
|
|
47
|
+
private drainFlush;
|
|
48
|
+
compressEvent(event: Compressible): Compressible;
|
|
49
|
+
flush(): Promise<boolean>;
|
|
50
|
+
private collectSystemInfo;
|
|
51
|
+
}
|
|
52
|
+
export {};
|
|
53
|
+
//# sourceMappingURL=sdk.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sdk.d.ts","sourceRoot":"","sources":["../src/sdk.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,KAAK,aAAa,EAAE,MAAM,cAAc,CAAC;AAiB7D,OAAO,KAAK,EACV,eAAe,EAEf,IAAI,EACJ,mBAAmB,EACnB,oBAAoB,EACrB,MAAM,YAAY,CAAC;AAMpB,KAAK,YAAY,GAAG,aAAa,GAAG;IAClC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,qBAAa,SAAU,YAAW,mBAAmB;IACnD,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAU;IACxC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAA0B;IACxD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAyB;IACnD,OAAO,CAAC,IAAI,CAAO;IACnB,OAAO,CAAC,MAAM,CAA6B;IAC3C,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,iBAAiB,CAAK;IAC9B,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,UAAU,CAAuD;IACzE,OAAO,CAAC,UAAU,CAAgC;IAClD,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,SAAS,CAAe;IAChC,6EAA6E;IAC7E,OAAO,CAAC,aAAa,CAAoC;IAEzD,OAAO;IAgCP,IAAI,SAAS,IAAI,MAAM,CAEtB;IAED,MAAM,CAAC,IAAI,CAAC,OAAO,GAAE,oBAAiD,GAAG,mBAAmB;IAsC5F,MAAM,CAAC,IAAI,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,IAAI,CAAA;KAAE,GAAG,eAAe,GAAG,IAAI;IA2CtD,IAAI,IAAI,IAAI;IAIZ,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,UAAQ,GAAG,IAAI;IAI3C,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAUhC,eAAe;IAQ7B;;;;OAIG;YACW,UAAU;IAcxB,aAAa,CAAC,KAAK,EAAE,YAAY,GAAG,YAAY;IAkB1C,KAAK,IAAI,OAAO,CAAC,OAAO,CAAC;YA0DjB,iBAAiB;CAqDhC"}
|
package/dist/sdk.js
ADDED
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
import { EventType } from "@rrweb/types";
|
|
2
|
+
import { pack, record as rrwebRecord } from "rrweb";
|
|
3
|
+
import { asNonEmptyString, deriveOtlpEndpoint, resolveSoftprobeConfigFromObject, MissingSoftprobeCredentialsError, } from "@softprobe/tracing/config";
|
|
4
|
+
import { initializeHttpInterceptor, updateHttpInterceptorSessionId, } from "./http-interceptor.js";
|
|
5
|
+
import { buildRecordingExport, msToUnixNano, randomHexId, } from "./otlp.js";
|
|
6
|
+
const MAX_EVENTS = 500;
|
|
7
|
+
const COOKIE_NAME = "_sp_vid";
|
|
8
|
+
const COOKIE_MAX_AGE = 365 * 24 * 60 * 60;
|
|
9
|
+
export class RecordSdk {
|
|
10
|
+
enabled;
|
|
11
|
+
_sessionId;
|
|
12
|
+
otlpEndpoint;
|
|
13
|
+
publicKey;
|
|
14
|
+
intervalMs;
|
|
15
|
+
serviceName;
|
|
16
|
+
environment;
|
|
17
|
+
userId;
|
|
18
|
+
maskAllInputs;
|
|
19
|
+
recordOptions;
|
|
20
|
+
replacers;
|
|
21
|
+
tags;
|
|
22
|
+
events = [];
|
|
23
|
+
eventIndex = 0;
|
|
24
|
+
lastSnapshotIndex = 0;
|
|
25
|
+
batchIndex = 0;
|
|
26
|
+
visitorId;
|
|
27
|
+
systemInfo = null;
|
|
28
|
+
stopHandle = null;
|
|
29
|
+
saving = false;
|
|
30
|
+
fetchImpl;
|
|
31
|
+
/** Serializes setSessionId drains so overlapping navigations cannot race. */
|
|
32
|
+
sessionSwitch = Promise.resolve();
|
|
33
|
+
constructor(options) {
|
|
34
|
+
this.enabled = options.enabled;
|
|
35
|
+
this.publicKey = options.publicKey ?? "";
|
|
36
|
+
this.otlpEndpoint = options.otlpEndpoint;
|
|
37
|
+
this._sessionId = asNonEmptyString(options.sessionId) ?? uuid();
|
|
38
|
+
this.intervalMs = Math.max(options.interval ?? 5000, 5000);
|
|
39
|
+
this.serviceName = options.serviceName;
|
|
40
|
+
this.environment = options.environment;
|
|
41
|
+
this.userId = options.userId;
|
|
42
|
+
this.maskAllInputs = options.maskAllInputs !== false;
|
|
43
|
+
this.recordOptions = options.recordOptions ?? {};
|
|
44
|
+
this.replacers = options.replacers ?? {};
|
|
45
|
+
this.tags = { ...(options.tags ?? {}) };
|
|
46
|
+
if (this.userId && !this.tags.userId)
|
|
47
|
+
this.tags.userId = this.userId;
|
|
48
|
+
this.visitorId = getOrCreateVisitorId();
|
|
49
|
+
this.fetchImpl =
|
|
50
|
+
typeof globalThis.fetch === "function"
|
|
51
|
+
? globalThis.fetch.bind(globalThis)
|
|
52
|
+
: (async () => {
|
|
53
|
+
throw new Error("fetch is not available");
|
|
54
|
+
});
|
|
55
|
+
if (this.enabled) {
|
|
56
|
+
initializeHttpInterceptor(() => this._sessionId);
|
|
57
|
+
if (!options.manual) {
|
|
58
|
+
this.record();
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
get sessionId() {
|
|
63
|
+
return this._sessionId;
|
|
64
|
+
}
|
|
65
|
+
static init(options = {}) {
|
|
66
|
+
const softDisable = options.softDisable !== false;
|
|
67
|
+
try {
|
|
68
|
+
const resolved = resolveSoftprobeConfigFromObject({
|
|
69
|
+
publicKey: options.publicKey,
|
|
70
|
+
baseUrl: options.baseUrl,
|
|
71
|
+
otlpEndpoint: options.otlpEndpoint,
|
|
72
|
+
environment: options.environment,
|
|
73
|
+
userId: options.userId,
|
|
74
|
+
serviceName: options.serviceName ?? "softprobe-web",
|
|
75
|
+
});
|
|
76
|
+
return new RecordSdk({
|
|
77
|
+
...options,
|
|
78
|
+
publicKey: resolved.publicKey,
|
|
79
|
+
baseUrl: resolved.baseUrl,
|
|
80
|
+
otlpEndpoint: resolved.otlpEndpoint,
|
|
81
|
+
environment: resolved.environment,
|
|
82
|
+
userId: resolved.userId,
|
|
83
|
+
serviceName: resolved.serviceName,
|
|
84
|
+
enabled: true,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
catch (err) {
|
|
88
|
+
if (softDisable && err instanceof MissingSoftprobeCredentialsError) {
|
|
89
|
+
console.warn("[@softprobe/web-record] Softprobe credentials missing; recording disabled.");
|
|
90
|
+
return new RecordSdk({
|
|
91
|
+
publicKey: "",
|
|
92
|
+
baseUrl: "",
|
|
93
|
+
otlpEndpoint: deriveOtlpEndpoint("http://127.0.0.1"),
|
|
94
|
+
enabled: false,
|
|
95
|
+
manual: true,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
throw err;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
record(opts) {
|
|
102
|
+
if (!this.enabled)
|
|
103
|
+
return null;
|
|
104
|
+
if (this.stopHandle)
|
|
105
|
+
return this.stopHandle;
|
|
106
|
+
if (opts?.tags)
|
|
107
|
+
this.setTags(opts.tags);
|
|
108
|
+
const stopFn = rrwebRecord({
|
|
109
|
+
maskAllInputs: this.maskAllInputs,
|
|
110
|
+
...this.recordOptions,
|
|
111
|
+
emit: (raw) => {
|
|
112
|
+
const event = raw;
|
|
113
|
+
if (this.events.length >= MAX_EVENTS)
|
|
114
|
+
this.events.shift();
|
|
115
|
+
const withIndex = this.compressEvent({
|
|
116
|
+
...event,
|
|
117
|
+
eventIndex: ++this.eventIndex,
|
|
118
|
+
});
|
|
119
|
+
this.events.push(withIndex);
|
|
120
|
+
},
|
|
121
|
+
});
|
|
122
|
+
const intervalId = setInterval(() => {
|
|
123
|
+
void this.flush();
|
|
124
|
+
if (this.events.length) {
|
|
125
|
+
const last = this.events[this.events.length - 1];
|
|
126
|
+
const lastIndex = Number(last?.eventIndex ?? 0);
|
|
127
|
+
if (this.lastSnapshotIndex + 50 < lastIndex) {
|
|
128
|
+
rrwebRecord.takeFullSnapshot();
|
|
129
|
+
this.lastSnapshotIndex = lastIndex;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}, this.intervalMs);
|
|
133
|
+
this.stopHandle = {
|
|
134
|
+
stop: () => {
|
|
135
|
+
clearInterval(intervalId);
|
|
136
|
+
stopFn?.();
|
|
137
|
+
void this.flush();
|
|
138
|
+
this.stopHandle = null;
|
|
139
|
+
},
|
|
140
|
+
};
|
|
141
|
+
return this.stopHandle;
|
|
142
|
+
}
|
|
143
|
+
stop() {
|
|
144
|
+
this.stopHandle?.stop();
|
|
145
|
+
}
|
|
146
|
+
setTags(tags, override = false) {
|
|
147
|
+
this.tags = override ? { ...tags } : { ...this.tags, ...tags };
|
|
148
|
+
}
|
|
149
|
+
setSessionId(sessionId) {
|
|
150
|
+
const next = asNonEmptyString(sessionId);
|
|
151
|
+
if (!next || next === this._sessionId)
|
|
152
|
+
return Promise.resolve();
|
|
153
|
+
// Serialize switches so overlapping navigations cannot race the drain.
|
|
154
|
+
this.sessionSwitch = this.sessionSwitch
|
|
155
|
+
.catch(() => undefined)
|
|
156
|
+
.then(() => this.switchSessionId(next));
|
|
157
|
+
return this.sessionSwitch;
|
|
158
|
+
}
|
|
159
|
+
async switchSessionId(next) {
|
|
160
|
+
await this.drainFlush();
|
|
161
|
+
this._sessionId = next;
|
|
162
|
+
if (this.enabled) {
|
|
163
|
+
updateHttpInterceptorSessionId(() => this._sessionId);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Wait out in-flight exports, then flush until the buffer is empty.
|
|
168
|
+
* Stops after a failed flush so we do not spin forever when OTLP is down
|
|
169
|
+
* (events stay queued under the old session for a later attempt / stop).
|
|
170
|
+
*/
|
|
171
|
+
async drainFlush() {
|
|
172
|
+
for (;;) {
|
|
173
|
+
while (this.saving) {
|
|
174
|
+
await new Promise((r) => setTimeout(r, 0));
|
|
175
|
+
}
|
|
176
|
+
if (this.events.length === 0)
|
|
177
|
+
return;
|
|
178
|
+
const before = this.events.length;
|
|
179
|
+
const ok = await this.flush();
|
|
180
|
+
if (!ok)
|
|
181
|
+
return;
|
|
182
|
+
// flush is a no-op when saving raced; avoid busy-loop.
|
|
183
|
+
if (this.events.length >= before)
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
compressEvent(event) {
|
|
188
|
+
if (event.type === EventType.FullSnapshot) {
|
|
189
|
+
try {
|
|
190
|
+
const compressedData = pack(event.data);
|
|
191
|
+
return {
|
|
192
|
+
type: event.type,
|
|
193
|
+
data: compressedData,
|
|
194
|
+
timestamp: event.timestamp,
|
|
195
|
+
isCompressed: true,
|
|
196
|
+
eventIndex: event.eventIndex,
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
catch (e) {
|
|
200
|
+
console.error("Failed to compress FullSnapshot:", e);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
return event;
|
|
204
|
+
}
|
|
205
|
+
async flush() {
|
|
206
|
+
if (!this.enabled || this.events.length === 0 || this.saving)
|
|
207
|
+
return true;
|
|
208
|
+
this.saving = true;
|
|
209
|
+
// Splice out the batch BEFORE await so events recorded while export is in
|
|
210
|
+
// flight stay in `this.events` and are not dropped on success.
|
|
211
|
+
const batch = this.events.splice(0, this.events.length);
|
|
212
|
+
const batchIndex = this.batchIndex;
|
|
213
|
+
try {
|
|
214
|
+
if (!this.systemInfo)
|
|
215
|
+
this.systemInfo = await this.collectSystemInfo();
|
|
216
|
+
const tags = {
|
|
217
|
+
...this.systemInfo,
|
|
218
|
+
...this.tags,
|
|
219
|
+
};
|
|
220
|
+
for (const [key, value] of Object.entries(this.replacers)) {
|
|
221
|
+
if (key in tags && value)
|
|
222
|
+
tags[key] = value;
|
|
223
|
+
}
|
|
224
|
+
const now = Date.now();
|
|
225
|
+
const startMs = typeof batch[0]?.timestamp === "number" ? batch[0].timestamp : now;
|
|
226
|
+
const body = buildRecordingExport({
|
|
227
|
+
traceId: randomHexId(16),
|
|
228
|
+
spanId: randomHexId(8),
|
|
229
|
+
sessionId: this._sessionId,
|
|
230
|
+
batchIndex,
|
|
231
|
+
startTimeUnixNano: msToUnixNano(startMs),
|
|
232
|
+
endTimeUnixNano: msToUnixNano(now),
|
|
233
|
+
events: batch,
|
|
234
|
+
attributes: tags,
|
|
235
|
+
serviceName: this.serviceName,
|
|
236
|
+
environment: this.environment,
|
|
237
|
+
});
|
|
238
|
+
const res = await this.fetchImpl(this.otlpEndpoint, {
|
|
239
|
+
method: "POST",
|
|
240
|
+
headers: {
|
|
241
|
+
"Content-Type": "application/json",
|
|
242
|
+
Authorization: `Bearer ${this.publicKey}`,
|
|
243
|
+
},
|
|
244
|
+
body: JSON.stringify(body),
|
|
245
|
+
redirect: "follow",
|
|
246
|
+
});
|
|
247
|
+
if (!res.ok) {
|
|
248
|
+
throw new Error(`OTLP export failed: ${res.status} ${await res.text()}`);
|
|
249
|
+
}
|
|
250
|
+
this.batchIndex = batchIndex + 1;
|
|
251
|
+
return true;
|
|
252
|
+
}
|
|
253
|
+
catch (error) {
|
|
254
|
+
console.error("[@softprobe/web-record] Failed to flush recording:", error);
|
|
255
|
+
this.events.unshift(...batch);
|
|
256
|
+
return false;
|
|
257
|
+
}
|
|
258
|
+
finally {
|
|
259
|
+
this.saving = false;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
async collectSystemInfo() {
|
|
263
|
+
let ua = "";
|
|
264
|
+
let os = "Unknown";
|
|
265
|
+
let osVersion = "Unknown";
|
|
266
|
+
let browser = "Unknown";
|
|
267
|
+
let browserVersion = "Unknown";
|
|
268
|
+
let cpu = "Unknown";
|
|
269
|
+
let device = "desktop";
|
|
270
|
+
try {
|
|
271
|
+
const { UAParser } = await import("ua-parser-js");
|
|
272
|
+
const parser = new UAParser();
|
|
273
|
+
const result = await parser.getResult().withClientHints();
|
|
274
|
+
ua = result.ua;
|
|
275
|
+
os = result.os.name || "Unknown";
|
|
276
|
+
osVersion = result.os.version || "Unknown";
|
|
277
|
+
browser = result.browser.name || "Unknown";
|
|
278
|
+
browserVersion = result.browser.version || "Unknown";
|
|
279
|
+
cpu = result.cpu.architecture || "Unknown";
|
|
280
|
+
device = result.device.type || "desktop";
|
|
281
|
+
}
|
|
282
|
+
catch {
|
|
283
|
+
ua = typeof navigator !== "undefined" ? navigator.userAgent : "";
|
|
284
|
+
}
|
|
285
|
+
return {
|
|
286
|
+
_sp_ua: ua,
|
|
287
|
+
_sp_url: typeof window !== "undefined"
|
|
288
|
+
? window.location.hostname + window.location.pathname
|
|
289
|
+
: "",
|
|
290
|
+
_sp_search: typeof window !== "undefined" ? window.location.search : "",
|
|
291
|
+
_sp_referer: typeof document !== "undefined" ? document.referrer || null : null,
|
|
292
|
+
_sp_os: os,
|
|
293
|
+
_sp_osVersion: osVersion,
|
|
294
|
+
_sp_browser: browser,
|
|
295
|
+
_sp_browserVersion: browserVersion,
|
|
296
|
+
_sp_cpu: cpu,
|
|
297
|
+
_sp_device: device,
|
|
298
|
+
_sp_width: typeof window !== "undefined" ? window.innerWidth : 0,
|
|
299
|
+
_sp_height: typeof window !== "undefined" ? window.innerHeight : 0,
|
|
300
|
+
_sp_scrollWidth: typeof document !== "undefined"
|
|
301
|
+
? document.documentElement.scrollWidth
|
|
302
|
+
: 0,
|
|
303
|
+
_sp_scrollHeight: typeof document !== "undefined"
|
|
304
|
+
? document.documentElement.scrollHeight
|
|
305
|
+
: 0,
|
|
306
|
+
_sp_vid: this.visitorId,
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
function uuid() {
|
|
311
|
+
return "10000000-1000-4000-8000-100000000000".replace(/[018]/g, (c) => {
|
|
312
|
+
const n = Number(c);
|
|
313
|
+
return (n ^
|
|
314
|
+
(crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (n / 4)))).toString(16);
|
|
315
|
+
});
|
|
316
|
+
}
|
|
317
|
+
function getOrCreateVisitorId() {
|
|
318
|
+
if (typeof document === "undefined")
|
|
319
|
+
return uuid();
|
|
320
|
+
const existing = getCookie(COOKIE_NAME);
|
|
321
|
+
if (existing)
|
|
322
|
+
return existing;
|
|
323
|
+
const id = uuid();
|
|
324
|
+
setCookie(COOKIE_NAME, id);
|
|
325
|
+
return id;
|
|
326
|
+
}
|
|
327
|
+
function setCookie(name, value) {
|
|
328
|
+
try {
|
|
329
|
+
const isLocalhost = typeof window !== "undefined" && window.location.hostname === "localhost";
|
|
330
|
+
const parts = [
|
|
331
|
+
`${name}=${encodeURIComponent(value)}`,
|
|
332
|
+
`max-age=${COOKIE_MAX_AGE}`,
|
|
333
|
+
"path=/",
|
|
334
|
+
];
|
|
335
|
+
if (!isLocalhost && typeof window !== "undefined") {
|
|
336
|
+
const host = window.location.hostname;
|
|
337
|
+
const base = host.split(".").slice(-2).join(".");
|
|
338
|
+
parts.push(`domain=.${base}`, "SameSite=None", "Secure");
|
|
339
|
+
}
|
|
340
|
+
document.cookie = parts.join("; ");
|
|
341
|
+
}
|
|
342
|
+
catch {
|
|
343
|
+
// ignore cookie failures
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
function getCookie(name) {
|
|
347
|
+
if (typeof document === "undefined")
|
|
348
|
+
return null;
|
|
349
|
+
for (const cookie of document.cookie.split(";")) {
|
|
350
|
+
const [cookieName, cookieValue] = cookie.trim().split("=");
|
|
351
|
+
if (cookieName === name)
|
|
352
|
+
return cookieValue ?? null;
|
|
353
|
+
}
|
|
354
|
+
return null;
|
|
355
|
+
}
|
|
356
|
+
//# sourceMappingURL=sdk.js.map
|
package/dist/sdk.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sdk.js","sourceRoot":"","sources":["../src/sdk.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/** Browser session metadata tags collected from UA / viewport. */
|
|
2
|
+
export type SystemInfo = {
|
|
3
|
+
_sp_ua: string;
|
|
4
|
+
_sp_url: string;
|
|
5
|
+
_sp_search: string;
|
|
6
|
+
_sp_referer: string | null;
|
|
7
|
+
_sp_os: string;
|
|
8
|
+
_sp_osVersion: string;
|
|
9
|
+
_sp_browser: string;
|
|
10
|
+
_sp_browserVersion: string;
|
|
11
|
+
_sp_cpu: string;
|
|
12
|
+
_sp_device: string;
|
|
13
|
+
_sp_width: number;
|
|
14
|
+
_sp_height: number;
|
|
15
|
+
_sp_scrollWidth: number;
|
|
16
|
+
_sp_scrollHeight: number;
|
|
17
|
+
_sp_vid: string;
|
|
18
|
+
};
|
|
19
|
+
export type Tags = {
|
|
20
|
+
userId?: string;
|
|
21
|
+
clientId?: string;
|
|
22
|
+
email?: string;
|
|
23
|
+
phoneNo?: string;
|
|
24
|
+
[key: string]: string | undefined;
|
|
25
|
+
};
|
|
26
|
+
export type WebRecordCredentials = {
|
|
27
|
+
publicKey: string;
|
|
28
|
+
baseUrl: string;
|
|
29
|
+
/** Defaults to `{baseUrl}/v1/traces`. */
|
|
30
|
+
otlpEndpoint?: string;
|
|
31
|
+
environment?: string;
|
|
32
|
+
userId?: string;
|
|
33
|
+
serviceName?: string;
|
|
34
|
+
};
|
|
35
|
+
export type WebRecordInitOptions = WebRecordCredentials & {
|
|
36
|
+
/** Correlate with LLM / OpenCode session (`sp.session.id`). */
|
|
37
|
+
sessionId?: string;
|
|
38
|
+
/** Flush interval in ms (minimum 5000). */
|
|
39
|
+
interval?: number;
|
|
40
|
+
/** When true, do not auto-start rrweb. */
|
|
41
|
+
manual?: boolean;
|
|
42
|
+
tags?: Tags;
|
|
43
|
+
replacers?: Record<string, string>;
|
|
44
|
+
/** Soft-disable instead of throwing when credentials are incomplete. Default true. */
|
|
45
|
+
softDisable?: boolean;
|
|
46
|
+
/** rrweb: mask all inputs. Default true for agent IDEs. */
|
|
47
|
+
maskAllInputs?: boolean;
|
|
48
|
+
/** Extra rrweb record options (emit is owned by the SDK). */
|
|
49
|
+
recordOptions?: Record<string, unknown>;
|
|
50
|
+
};
|
|
51
|
+
export type CompressedRrwebEvent = {
|
|
52
|
+
type: number;
|
|
53
|
+
data: string;
|
|
54
|
+
timestamp: number;
|
|
55
|
+
isCompressed: true;
|
|
56
|
+
eventIndex?: number;
|
|
57
|
+
};
|
|
58
|
+
export type RrwebEventBatchItem = Record<string, unknown> & {
|
|
59
|
+
type: number;
|
|
60
|
+
timestamp: number;
|
|
61
|
+
eventIndex?: number;
|
|
62
|
+
isCompressed?: boolean;
|
|
63
|
+
};
|
|
64
|
+
export type RecordingHandle = {
|
|
65
|
+
stop: () => void;
|
|
66
|
+
};
|
|
67
|
+
export type WebRecordController = {
|
|
68
|
+
readonly enabled: boolean;
|
|
69
|
+
readonly sessionId: string;
|
|
70
|
+
record: (opts?: {
|
|
71
|
+
tags?: Tags;
|
|
72
|
+
}) => RecordingHandle | null;
|
|
73
|
+
stop: () => void;
|
|
74
|
+
setTags: (tags: Tags, override?: boolean) => void;
|
|
75
|
+
/** Switch correlation id (e.g. when OpenCode chat session changes). */
|
|
76
|
+
setSessionId: (sessionId: string) => void | Promise<void>;
|
|
77
|
+
flush: () => Promise<boolean>;
|
|
78
|
+
};
|
|
79
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@softprobe/web-record",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Browser session recording SDK that exports rrweb batches to Softprobe via OTLP",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist",
|
|
16
|
+
"README.md"
|
|
17
|
+
],
|
|
18
|
+
"engines": {
|
|
19
|
+
"node": ">=20"
|
|
20
|
+
},
|
|
21
|
+
"scripts": {
|
|
22
|
+
"build": "tsc -p tsconfig.json",
|
|
23
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
24
|
+
"test": "vitest run",
|
|
25
|
+
"lint": "tsc -p tsconfig.json --noEmit"
|
|
26
|
+
},
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"@rrweb/types": "2.0.0-alpha.4",
|
|
29
|
+
"@softprobe/tracing": "0.1.5",
|
|
30
|
+
"rrweb": "2.0.0-alpha.4",
|
|
31
|
+
"ua-parser-js": "^2.0.3"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@types/node": "^22.13.10",
|
|
35
|
+
"jsdom": "^26.0.0",
|
|
36
|
+
"typescript": "^5.8.2",
|
|
37
|
+
"vitest": "^3.0.8"
|
|
38
|
+
},
|
|
39
|
+
"publishConfig": {
|
|
40
|
+
"access": "public",
|
|
41
|
+
"provenance": true
|
|
42
|
+
},
|
|
43
|
+
"keywords": [
|
|
44
|
+
"softprobe",
|
|
45
|
+
"session-replay",
|
|
46
|
+
"rrweb",
|
|
47
|
+
"opentelemetry",
|
|
48
|
+
"otlp"
|
|
49
|
+
],
|
|
50
|
+
"repository": {
|
|
51
|
+
"type": "git",
|
|
52
|
+
"url": "git+https://github.com/softprobe/softprobe-js.git",
|
|
53
|
+
"directory": "packages/web-record"
|
|
54
|
+
},
|
|
55
|
+
"license": "MIT"
|
|
56
|
+
}
|