@spotify-confidence/csr-common 0.0.0 → 0.17.2
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/CHANGELOG.md +20 -0
- package/README.md +16 -0
- package/dist/index.cjs +116 -0
- package/dist/index.d.cts +239 -0
- package/dist/index.d.ts +239 -0
- package/dist/index.js +104 -0
- package/dist/types-BFkUa8kB.d.cts +111 -0
- package/dist/types-BFkUa8kB.d.ts +111 -0
- package/dist/uploader/index.cjs +276 -0
- package/dist/uploader/index.d.cts +9 -0
- package/dist/uploader/index.d.ts +9 -0
- package/dist/uploader/index.js +250 -0
- package/package.json +58 -1
- package/src/custom-event-limits.test.ts +79 -0
- package/src/custom-event-limits.ts +25 -0
- package/src/events.ts +252 -0
- package/src/index.ts +44 -0
- package/src/test-utils/index.ts +3 -0
- package/src/test-utils/mock-fetch.ts +34 -0
- package/src/test-utils/mock-port.ts +51 -0
- package/src/test-utils/mock-ws-server.ts +78 -0
- package/src/uploader/client-context.test.ts +149 -0
- package/src/uploader/client-context.ts +70 -0
- package/src/uploader/create-uploader.ts +309 -0
- package/src/uploader/index.ts +15 -0
- package/src/uploader/types.ts +101 -0
- package/src/uploader/worker/core.test.ts +247 -0
- package/src/uploader/worker/core.ts +386 -0
- package/src/uploader/worker/csr-client.test.ts +122 -0
- package/src/uploader/worker/csr-client.ts +67 -0
- package/src/uploader/worker/entry.ts +40 -0
- package/src/uploader/worker/web-socket-transport.test.ts +103 -0
- package/src/uploader/worker/web-socket-transport.ts +113 -0
- package/src/uploader/worker/worker-script.ts +3 -0
- package/src/url.ts +11 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [0.17.2](https://github.com/spotify/confidence-sdk-js/compare/csr-common-v0.17.1...csr-common-v0.17.2) (2026-06-15)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### 🐛 Bug Fixes
|
|
7
|
+
|
|
8
|
+
* improve csr package READMEs ([#367](https://github.com/spotify/confidence-sdk-js/issues/367)) ([3c5a254](https://github.com/spotify/confidence-sdk-js/commit/3c5a254b6b7bd23142ffe7ce6d99f327e67ff478))
|
|
9
|
+
|
|
10
|
+
## [0.17.1](https://github.com/spotify/confidence-sdk-js/compare/csr-common-v0.17.0...csr-common-v0.17.1) (2026-06-15)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### 🐛 Bug Fixes
|
|
14
|
+
|
|
15
|
+
* add csr packages to release-please ([#363](https://github.com/spotify/confidence-sdk-js/issues/363)) ([f868e03](https://github.com/spotify/confidence-sdk-js/commit/f868e036ee27fcdd26ee26c8a47d2466a47e2a60))
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### ✨ New Features
|
|
19
|
+
|
|
20
|
+
* add session recording packages ([#360](https://github.com/spotify/confidence-sdk-js/issues/360)) ([4584f50](https://github.com/spotify/confidence-sdk-js/commit/4584f502f17d01a15390789519c99308797a513d))
|
package/README.md
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# @spotify-confidence/csr-common
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+
|
|
5
|
+
Shared types, event definitions, and utilities for the Confidence session recording SDK. This package is a foundation dependency — most consumers should use `@spotify-confidence/session-recording` directly.
|
|
6
|
+
|
|
7
|
+
## What's in here
|
|
8
|
+
|
|
9
|
+
- **Event types** — `RecordingEvent`, `RecordingEventType`, `IncrementalSource`, and custom event data types used across the recording pipeline.
|
|
10
|
+
- **Validation** — `validateKey`, `validateTagValue`, `validateMeasureValue` for custom tags and measurements.
|
|
11
|
+
- **Uploader** — `createUploader` factory and WebSocket transport for streaming recording frames to the Confidence backend. Available via the `csr-common/uploader` subpath export.
|
|
12
|
+
- **Client context** — `collectUserAgentContext` for auto-collecting browser/OS/screen metadata.
|
|
13
|
+
|
|
14
|
+
## License
|
|
15
|
+
|
|
16
|
+
Apache 2.0 — see [LICENSE](../../LICENSE).
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
//#region src/events.ts
|
|
3
|
+
/**
|
|
4
|
+
* Mirrors rrweb's serialized-node types but decoupled — we own the enum.
|
|
5
|
+
*/
|
|
6
|
+
let SerializedNodeType = /* @__PURE__ */ function(SerializedNodeType) {
|
|
7
|
+
SerializedNodeType[SerializedNodeType["Document"] = 0] = "Document";
|
|
8
|
+
SerializedNodeType[SerializedNodeType["DocumentType"] = 1] = "DocumentType";
|
|
9
|
+
SerializedNodeType[SerializedNodeType["Element"] = 2] = "Element";
|
|
10
|
+
SerializedNodeType[SerializedNodeType["Text"] = 3] = "Text";
|
|
11
|
+
SerializedNodeType[SerializedNodeType["CDATA"] = 4] = "CDATA";
|
|
12
|
+
SerializedNodeType[SerializedNodeType["Comment"] = 5] = "Comment";
|
|
13
|
+
return SerializedNodeType;
|
|
14
|
+
}({});
|
|
15
|
+
/**
|
|
16
|
+
* Mirrors rrweb event types but decoupled — we own the enum.
|
|
17
|
+
*/
|
|
18
|
+
let RecordingEventType = /* @__PURE__ */ function(RecordingEventType) {
|
|
19
|
+
RecordingEventType[RecordingEventType["DomContentLoaded"] = 0] = "DomContentLoaded";
|
|
20
|
+
RecordingEventType[RecordingEventType["Load"] = 1] = "Load";
|
|
21
|
+
RecordingEventType[RecordingEventType["FullSnapshot"] = 2] = "FullSnapshot";
|
|
22
|
+
RecordingEventType[RecordingEventType["IncrementalSnapshot"] = 3] = "IncrementalSnapshot";
|
|
23
|
+
RecordingEventType[RecordingEventType["Meta"] = 4] = "Meta";
|
|
24
|
+
RecordingEventType[RecordingEventType["Custom"] = 5] = "Custom";
|
|
25
|
+
RecordingEventType[RecordingEventType["Plugin"] = 6] = "Plugin";
|
|
26
|
+
return RecordingEventType;
|
|
27
|
+
}({});
|
|
28
|
+
/**
|
|
29
|
+
* Incremental snapshot sub-types.
|
|
30
|
+
*/
|
|
31
|
+
let IncrementalSource = /* @__PURE__ */ function(IncrementalSource) {
|
|
32
|
+
IncrementalSource[IncrementalSource["Mutation"] = 0] = "Mutation";
|
|
33
|
+
IncrementalSource[IncrementalSource["MouseMove"] = 1] = "MouseMove";
|
|
34
|
+
IncrementalSource[IncrementalSource["MouseInteraction"] = 2] = "MouseInteraction";
|
|
35
|
+
IncrementalSource[IncrementalSource["Scroll"] = 3] = "Scroll";
|
|
36
|
+
IncrementalSource[IncrementalSource["ViewportResize"] = 4] = "ViewportResize";
|
|
37
|
+
IncrementalSource[IncrementalSource["Input"] = 5] = "Input";
|
|
38
|
+
IncrementalSource[IncrementalSource["TouchMove"] = 6] = "TouchMove";
|
|
39
|
+
IncrementalSource[IncrementalSource["MediaInteraction"] = 7] = "MediaInteraction";
|
|
40
|
+
IncrementalSource[IncrementalSource["StyleSheetRule"] = 8] = "StyleSheetRule";
|
|
41
|
+
IncrementalSource[IncrementalSource["CanvasMutation"] = 9] = "CanvasMutation";
|
|
42
|
+
IncrementalSource[IncrementalSource["Font"] = 10] = "Font";
|
|
43
|
+
IncrementalSource[IncrementalSource["Log"] = 11] = "Log";
|
|
44
|
+
IncrementalSource[IncrementalSource["Drag"] = 12] = "Drag";
|
|
45
|
+
IncrementalSource[IncrementalSource["StyleDeclaration"] = 13] = "StyleDeclaration";
|
|
46
|
+
IncrementalSource[IncrementalSource["Selection"] = 14] = "Selection";
|
|
47
|
+
IncrementalSource[IncrementalSource["AdoptedStyleSheet"] = 15] = "AdoptedStyleSheet";
|
|
48
|
+
return IncrementalSource;
|
|
49
|
+
}({});
|
|
50
|
+
/**
|
|
51
|
+
* From rrweb MouseInteractions.
|
|
52
|
+
*/
|
|
53
|
+
let MouseInteractions = /* @__PURE__ */ function(MouseInteractions) {
|
|
54
|
+
MouseInteractions[MouseInteractions["MouseUp"] = 0] = "MouseUp";
|
|
55
|
+
MouseInteractions[MouseInteractions["MouseDown"] = 1] = "MouseDown";
|
|
56
|
+
MouseInteractions[MouseInteractions["Click"] = 2] = "Click";
|
|
57
|
+
MouseInteractions[MouseInteractions["ContextMenu"] = 3] = "ContextMenu";
|
|
58
|
+
MouseInteractions[MouseInteractions["DblClick"] = 4] = "DblClick";
|
|
59
|
+
MouseInteractions[MouseInteractions["Focus"] = 5] = "Focus";
|
|
60
|
+
MouseInteractions[MouseInteractions["Blur"] = 6] = "Blur";
|
|
61
|
+
MouseInteractions[MouseInteractions["TouchStart"] = 7] = "TouchStart";
|
|
62
|
+
MouseInteractions[MouseInteractions["TouchMove_Departed"] = 8] = "TouchMove_Departed";
|
|
63
|
+
MouseInteractions[MouseInteractions["TouchEnd"] = 9] = "TouchEnd";
|
|
64
|
+
MouseInteractions[MouseInteractions["TouchCancel"] = 10] = "TouchCancel";
|
|
65
|
+
return MouseInteractions;
|
|
66
|
+
}({});
|
|
67
|
+
//#endregion
|
|
68
|
+
//#region src/url.ts
|
|
69
|
+
/**
|
|
70
|
+
* Extract only the pathname from a URL, stripping origin, query string, and
|
|
71
|
+
* hash. Used across recorder and analyzer to avoid capturing PII in route data.
|
|
72
|
+
*/
|
|
73
|
+
function stripUrl(url) {
|
|
74
|
+
try {
|
|
75
|
+
return new URL(url).pathname;
|
|
76
|
+
} catch (_e) {
|
|
77
|
+
return url;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
//#endregion
|
|
81
|
+
//#region src/custom-event-limits.ts
|
|
82
|
+
const MAX_KEY_LENGTH = 128;
|
|
83
|
+
const MAX_TAG_VALUE_LENGTH = 256;
|
|
84
|
+
const MAX_DISTINCT_KEYS = 100;
|
|
85
|
+
const MAX_VALUES_PER_KEY = 1e3;
|
|
86
|
+
const VALID_KEY_PATTERN = /^[a-zA-Z0-9_.-]+$/;
|
|
87
|
+
function validateKey(key) {
|
|
88
|
+
if (typeof key !== "string" || key.length === 0) return "key is empty";
|
|
89
|
+
if (key.length > 128) return `key exceeds 128 characters`;
|
|
90
|
+
if (!VALID_KEY_PATTERN.test(key)) return "key contains invalid characters (allowed: a-z A-Z 0-9 _ . -)";
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
function validateTagValue(value) {
|
|
94
|
+
if (value === void 0) return null;
|
|
95
|
+
if (typeof value !== "string") return "tag value is not a string";
|
|
96
|
+
if (value.length > 256) return `tag value exceeds 256 characters`;
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
function validateMeasureValue(value) {
|
|
100
|
+
if (value === void 0) return null;
|
|
101
|
+
if (typeof value !== "number" || !Number.isFinite(value)) return "measure value must be a finite number";
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
//#endregion
|
|
105
|
+
exports.IncrementalSource = IncrementalSource;
|
|
106
|
+
exports.MAX_DISTINCT_KEYS = MAX_DISTINCT_KEYS;
|
|
107
|
+
exports.MAX_KEY_LENGTH = MAX_KEY_LENGTH;
|
|
108
|
+
exports.MAX_TAG_VALUE_LENGTH = MAX_TAG_VALUE_LENGTH;
|
|
109
|
+
exports.MAX_VALUES_PER_KEY = MAX_VALUES_PER_KEY;
|
|
110
|
+
exports.MouseInteractions = MouseInteractions;
|
|
111
|
+
exports.RecordingEventType = RecordingEventType;
|
|
112
|
+
exports.SerializedNodeType = SerializedNodeType;
|
|
113
|
+
exports.stripUrl = stripUrl;
|
|
114
|
+
exports.validateKey = validateKey;
|
|
115
|
+
exports.validateMeasureValue = validateMeasureValue;
|
|
116
|
+
exports.validateTagValue = validateTagValue;
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
import { i as ClientContext, n as Frame, o as UserAgentContext } from "./types-BFkUa8kB.cjs";
|
|
2
|
+
|
|
3
|
+
//#region src/events.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Mirrors rrweb's serialized-node types but decoupled — we own the enum.
|
|
6
|
+
*/
|
|
7
|
+
declare enum SerializedNodeType {
|
|
8
|
+
Document = 0,
|
|
9
|
+
DocumentType = 1,
|
|
10
|
+
Element = 2,
|
|
11
|
+
Text = 3,
|
|
12
|
+
CDATA = 4,
|
|
13
|
+
Comment = 5
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Mirrors rrweb event types but decoupled — we own the enum.
|
|
17
|
+
*/
|
|
18
|
+
declare enum RecordingEventType {
|
|
19
|
+
DomContentLoaded = 0,
|
|
20
|
+
Load = 1,
|
|
21
|
+
FullSnapshot = 2,
|
|
22
|
+
IncrementalSnapshot = 3,
|
|
23
|
+
Meta = 4,
|
|
24
|
+
Custom = 5,
|
|
25
|
+
Plugin = 6
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Incremental snapshot sub-types.
|
|
29
|
+
*/
|
|
30
|
+
declare enum IncrementalSource {
|
|
31
|
+
Mutation = 0,
|
|
32
|
+
MouseMove = 1,
|
|
33
|
+
MouseInteraction = 2,
|
|
34
|
+
Scroll = 3,
|
|
35
|
+
ViewportResize = 4,
|
|
36
|
+
Input = 5,
|
|
37
|
+
TouchMove = 6,
|
|
38
|
+
MediaInteraction = 7,
|
|
39
|
+
StyleSheetRule = 8,
|
|
40
|
+
CanvasMutation = 9,
|
|
41
|
+
Font = 10,
|
|
42
|
+
Log = 11,
|
|
43
|
+
Drag = 12,
|
|
44
|
+
StyleDeclaration = 13,
|
|
45
|
+
Selection = 14,
|
|
46
|
+
AdoptedStyleSheet = 15
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* From rrweb MouseInteractions.
|
|
50
|
+
*/
|
|
51
|
+
declare enum MouseInteractions {
|
|
52
|
+
MouseUp = 0,
|
|
53
|
+
MouseDown = 1,
|
|
54
|
+
Click = 2,
|
|
55
|
+
ContextMenu = 3,
|
|
56
|
+
DblClick = 4,
|
|
57
|
+
Focus = 5,
|
|
58
|
+
Blur = 6,
|
|
59
|
+
TouchStart = 7,
|
|
60
|
+
TouchMove_Departed = 8,
|
|
61
|
+
TouchEnd = 9,
|
|
62
|
+
TouchCancel = 10
|
|
63
|
+
}
|
|
64
|
+
type RageClickCustomData = {
|
|
65
|
+
tag: "csr:rageClick";
|
|
66
|
+
payload: {
|
|
67
|
+
targetId: number;
|
|
68
|
+
clickCount: number;
|
|
69
|
+
durationMs: number;
|
|
70
|
+
element?: ElementDescriptor;
|
|
71
|
+
pathname?: string;
|
|
72
|
+
};
|
|
73
|
+
};
|
|
74
|
+
type FormFieldReEditCustomData = {
|
|
75
|
+
tag: "csr:formFieldReEdit";
|
|
76
|
+
payload: {
|
|
77
|
+
targetId: number;
|
|
78
|
+
editCount: number;
|
|
79
|
+
element?: ElementDescriptor;
|
|
80
|
+
pathname?: string;
|
|
81
|
+
};
|
|
82
|
+
};
|
|
83
|
+
type ScrollBackCustomData = {
|
|
84
|
+
tag: "csr:scrollBack";
|
|
85
|
+
payload: {
|
|
86
|
+
scrollBackPx: number;
|
|
87
|
+
fromY: number;
|
|
88
|
+
toY: number;
|
|
89
|
+
pathname?: string;
|
|
90
|
+
};
|
|
91
|
+
};
|
|
92
|
+
type ElementDescriptor = {
|
|
93
|
+
tagName: string;
|
|
94
|
+
classes?: string[];
|
|
95
|
+
textContent?: string;
|
|
96
|
+
attributes?: Record<string, string>;
|
|
97
|
+
};
|
|
98
|
+
type ClickCustomData = {
|
|
99
|
+
tag: "csr:click";
|
|
100
|
+
payload: {
|
|
101
|
+
targetId: number;
|
|
102
|
+
element?: ElementDescriptor;
|
|
103
|
+
pathname?: string;
|
|
104
|
+
};
|
|
105
|
+
};
|
|
106
|
+
type InputCustomData = {
|
|
107
|
+
tag: "csr:input";
|
|
108
|
+
payload: {
|
|
109
|
+
targetId: number;
|
|
110
|
+
element?: ElementDescriptor;
|
|
111
|
+
pathname?: string;
|
|
112
|
+
};
|
|
113
|
+
};
|
|
114
|
+
type DeadClickCustomData = {
|
|
115
|
+
tag: "csr:deadClick";
|
|
116
|
+
payload: {
|
|
117
|
+
targetId: number;
|
|
118
|
+
element?: ElementDescriptor;
|
|
119
|
+
pathname?: string;
|
|
120
|
+
};
|
|
121
|
+
};
|
|
122
|
+
type TabUnfocusCustomData = {
|
|
123
|
+
tag: "csr:tabUnfocus";
|
|
124
|
+
payload: {
|
|
125
|
+
pathname?: string;
|
|
126
|
+
};
|
|
127
|
+
};
|
|
128
|
+
type TabRefocusCustomData = {
|
|
129
|
+
tag: "csr:tabRefocus";
|
|
130
|
+
payload: {
|
|
131
|
+
awayDurationMs: number;
|
|
132
|
+
pathname?: string;
|
|
133
|
+
};
|
|
134
|
+
};
|
|
135
|
+
type RouteChangeTrigger = "pushState" | "replaceState" | "popstate" | "navigation";
|
|
136
|
+
type RouteChangePayload = {
|
|
137
|
+
from: string;
|
|
138
|
+
to: string;
|
|
139
|
+
trigger: RouteChangeTrigger;
|
|
140
|
+
};
|
|
141
|
+
type RouteChangeCustomData = {
|
|
142
|
+
tag: "csr:routeChange";
|
|
143
|
+
payload: RouteChangePayload;
|
|
144
|
+
};
|
|
145
|
+
/**
|
|
146
|
+
* Plugin event data emitted by the recorder for tab visibility changes.
|
|
147
|
+
*/
|
|
148
|
+
type TabVisibilityPluginData = {
|
|
149
|
+
plugin: "csr:tabVisibility";
|
|
150
|
+
payload: {
|
|
151
|
+
hidden: boolean;
|
|
152
|
+
};
|
|
153
|
+
};
|
|
154
|
+
type ConsoleLogLevel = "log" | "warn" | "error" | "debug" | "info";
|
|
155
|
+
/**
|
|
156
|
+
* Plugin event data emitted by rrweb's console record plugin.
|
|
157
|
+
* Shape matches `@rrweb/rrweb-plugin-console-record` LogData.
|
|
158
|
+
*/
|
|
159
|
+
type ConsoleLogPluginData = {
|
|
160
|
+
plugin: "rrweb/console@1";
|
|
161
|
+
payload: {
|
|
162
|
+
level: ConsoleLogLevel;
|
|
163
|
+
payload: string[];
|
|
164
|
+
trace: string[];
|
|
165
|
+
};
|
|
166
|
+
};
|
|
167
|
+
type NetworkRequestInitiator = "fetch" | "xhr";
|
|
168
|
+
/**
|
|
169
|
+
* Plugin event data emitted by the recorder for network requests.
|
|
170
|
+
*/
|
|
171
|
+
type NetworkRequestPluginData = {
|
|
172
|
+
plugin: "csr:networkRequest";
|
|
173
|
+
payload: {
|
|
174
|
+
initiator: NetworkRequestInitiator;
|
|
175
|
+
method: string;
|
|
176
|
+
url: string;
|
|
177
|
+
status: number;
|
|
178
|
+
durationMs: number;
|
|
179
|
+
requestSize?: number;
|
|
180
|
+
responseSize?: number;
|
|
181
|
+
};
|
|
182
|
+
};
|
|
183
|
+
type RouteChangePluginData = {
|
|
184
|
+
plugin: "csr:routeChange";
|
|
185
|
+
payload: RouteChangePayload;
|
|
186
|
+
};
|
|
187
|
+
type TagPluginData = {
|
|
188
|
+
plugin: "csr:tag";
|
|
189
|
+
payload: {
|
|
190
|
+
key: string;
|
|
191
|
+
value?: string;
|
|
192
|
+
};
|
|
193
|
+
};
|
|
194
|
+
type MeasurePluginData = {
|
|
195
|
+
plugin: "csr:measure";
|
|
196
|
+
payload: {
|
|
197
|
+
key: string;
|
|
198
|
+
value?: number;
|
|
199
|
+
};
|
|
200
|
+
};
|
|
201
|
+
/**
|
|
202
|
+
* Closed union of every Custom event we emit. Add a new variant here when
|
|
203
|
+
* introducing a new tag — emitting an unregistered tag is a TS error.
|
|
204
|
+
*/
|
|
205
|
+
type CustomEventData = ClickCustomData | InputCustomData | RageClickCustomData | FormFieldReEditCustomData | ScrollBackCustomData | DeadClickCustomData | TabUnfocusCustomData | TabRefocusCustomData | RouteChangeCustomData;
|
|
206
|
+
/**
|
|
207
|
+
* A single recorded event.
|
|
208
|
+
*
|
|
209
|
+
* For non-Custom events `data` is `unknown` (decoupled from rrweb internals).
|
|
210
|
+
* For Custom events `data.tag` discriminates the payload across the closed
|
|
211
|
+
* `CustomEventData` union.
|
|
212
|
+
*/
|
|
213
|
+
type RecordingEvent = {
|
|
214
|
+
type: RecordingEventType.Custom;
|
|
215
|
+
timestamp: number;
|
|
216
|
+
data: CustomEventData;
|
|
217
|
+
} | {
|
|
218
|
+
type: Exclude<RecordingEventType, RecordingEventType.Custom>;
|
|
219
|
+
timestamp: number;
|
|
220
|
+
data: unknown;
|
|
221
|
+
};
|
|
222
|
+
//#endregion
|
|
223
|
+
//#region src/url.d.ts
|
|
224
|
+
/**
|
|
225
|
+
* Extract only the pathname from a URL, stripping origin, query string, and
|
|
226
|
+
* hash. Used across recorder and analyzer to avoid capturing PII in route data.
|
|
227
|
+
*/
|
|
228
|
+
declare function stripUrl(url: string): string;
|
|
229
|
+
//#endregion
|
|
230
|
+
//#region src/custom-event-limits.d.ts
|
|
231
|
+
declare const MAX_KEY_LENGTH = 128;
|
|
232
|
+
declare const MAX_TAG_VALUE_LENGTH = 256;
|
|
233
|
+
declare const MAX_DISTINCT_KEYS = 100;
|
|
234
|
+
declare const MAX_VALUES_PER_KEY = 1e3;
|
|
235
|
+
declare function validateKey(key: string): string | null;
|
|
236
|
+
declare function validateTagValue(value: string | undefined): string | null;
|
|
237
|
+
declare function validateMeasureValue(value: number | undefined): string | null;
|
|
238
|
+
//#endregion
|
|
239
|
+
export { type ClickCustomData, type ClientContext, type ConsoleLogLevel, type ConsoleLogPluginData, type CustomEventData, type DeadClickCustomData, type ElementDescriptor, type FormFieldReEditCustomData, type Frame, IncrementalSource, type InputCustomData, MAX_DISTINCT_KEYS, MAX_KEY_LENGTH, MAX_TAG_VALUE_LENGTH, MAX_VALUES_PER_KEY, type MeasurePluginData, MouseInteractions, type NetworkRequestInitiator, type NetworkRequestPluginData, type RageClickCustomData, type RecordingEvent, RecordingEventType, type RouteChangeCustomData, type RouteChangePayload, type RouteChangePluginData, type RouteChangeTrigger, type ScrollBackCustomData, SerializedNodeType, type TabRefocusCustomData, type TabUnfocusCustomData, type TabVisibilityPluginData, type TagPluginData, type UserAgentContext, stripUrl, validateKey, validateMeasureValue, validateTagValue };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
import { i as ClientContext, n as Frame, o as UserAgentContext } from "./types-BFkUa8kB.js";
|
|
2
|
+
|
|
3
|
+
//#region src/events.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Mirrors rrweb's serialized-node types but decoupled — we own the enum.
|
|
6
|
+
*/
|
|
7
|
+
declare enum SerializedNodeType {
|
|
8
|
+
Document = 0,
|
|
9
|
+
DocumentType = 1,
|
|
10
|
+
Element = 2,
|
|
11
|
+
Text = 3,
|
|
12
|
+
CDATA = 4,
|
|
13
|
+
Comment = 5
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Mirrors rrweb event types but decoupled — we own the enum.
|
|
17
|
+
*/
|
|
18
|
+
declare enum RecordingEventType {
|
|
19
|
+
DomContentLoaded = 0,
|
|
20
|
+
Load = 1,
|
|
21
|
+
FullSnapshot = 2,
|
|
22
|
+
IncrementalSnapshot = 3,
|
|
23
|
+
Meta = 4,
|
|
24
|
+
Custom = 5,
|
|
25
|
+
Plugin = 6
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Incremental snapshot sub-types.
|
|
29
|
+
*/
|
|
30
|
+
declare enum IncrementalSource {
|
|
31
|
+
Mutation = 0,
|
|
32
|
+
MouseMove = 1,
|
|
33
|
+
MouseInteraction = 2,
|
|
34
|
+
Scroll = 3,
|
|
35
|
+
ViewportResize = 4,
|
|
36
|
+
Input = 5,
|
|
37
|
+
TouchMove = 6,
|
|
38
|
+
MediaInteraction = 7,
|
|
39
|
+
StyleSheetRule = 8,
|
|
40
|
+
CanvasMutation = 9,
|
|
41
|
+
Font = 10,
|
|
42
|
+
Log = 11,
|
|
43
|
+
Drag = 12,
|
|
44
|
+
StyleDeclaration = 13,
|
|
45
|
+
Selection = 14,
|
|
46
|
+
AdoptedStyleSheet = 15
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* From rrweb MouseInteractions.
|
|
50
|
+
*/
|
|
51
|
+
declare enum MouseInteractions {
|
|
52
|
+
MouseUp = 0,
|
|
53
|
+
MouseDown = 1,
|
|
54
|
+
Click = 2,
|
|
55
|
+
ContextMenu = 3,
|
|
56
|
+
DblClick = 4,
|
|
57
|
+
Focus = 5,
|
|
58
|
+
Blur = 6,
|
|
59
|
+
TouchStart = 7,
|
|
60
|
+
TouchMove_Departed = 8,
|
|
61
|
+
TouchEnd = 9,
|
|
62
|
+
TouchCancel = 10
|
|
63
|
+
}
|
|
64
|
+
type RageClickCustomData = {
|
|
65
|
+
tag: "csr:rageClick";
|
|
66
|
+
payload: {
|
|
67
|
+
targetId: number;
|
|
68
|
+
clickCount: number;
|
|
69
|
+
durationMs: number;
|
|
70
|
+
element?: ElementDescriptor;
|
|
71
|
+
pathname?: string;
|
|
72
|
+
};
|
|
73
|
+
};
|
|
74
|
+
type FormFieldReEditCustomData = {
|
|
75
|
+
tag: "csr:formFieldReEdit";
|
|
76
|
+
payload: {
|
|
77
|
+
targetId: number;
|
|
78
|
+
editCount: number;
|
|
79
|
+
element?: ElementDescriptor;
|
|
80
|
+
pathname?: string;
|
|
81
|
+
};
|
|
82
|
+
};
|
|
83
|
+
type ScrollBackCustomData = {
|
|
84
|
+
tag: "csr:scrollBack";
|
|
85
|
+
payload: {
|
|
86
|
+
scrollBackPx: number;
|
|
87
|
+
fromY: number;
|
|
88
|
+
toY: number;
|
|
89
|
+
pathname?: string;
|
|
90
|
+
};
|
|
91
|
+
};
|
|
92
|
+
type ElementDescriptor = {
|
|
93
|
+
tagName: string;
|
|
94
|
+
classes?: string[];
|
|
95
|
+
textContent?: string;
|
|
96
|
+
attributes?: Record<string, string>;
|
|
97
|
+
};
|
|
98
|
+
type ClickCustomData = {
|
|
99
|
+
tag: "csr:click";
|
|
100
|
+
payload: {
|
|
101
|
+
targetId: number;
|
|
102
|
+
element?: ElementDescriptor;
|
|
103
|
+
pathname?: string;
|
|
104
|
+
};
|
|
105
|
+
};
|
|
106
|
+
type InputCustomData = {
|
|
107
|
+
tag: "csr:input";
|
|
108
|
+
payload: {
|
|
109
|
+
targetId: number;
|
|
110
|
+
element?: ElementDescriptor;
|
|
111
|
+
pathname?: string;
|
|
112
|
+
};
|
|
113
|
+
};
|
|
114
|
+
type DeadClickCustomData = {
|
|
115
|
+
tag: "csr:deadClick";
|
|
116
|
+
payload: {
|
|
117
|
+
targetId: number;
|
|
118
|
+
element?: ElementDescriptor;
|
|
119
|
+
pathname?: string;
|
|
120
|
+
};
|
|
121
|
+
};
|
|
122
|
+
type TabUnfocusCustomData = {
|
|
123
|
+
tag: "csr:tabUnfocus";
|
|
124
|
+
payload: {
|
|
125
|
+
pathname?: string;
|
|
126
|
+
};
|
|
127
|
+
};
|
|
128
|
+
type TabRefocusCustomData = {
|
|
129
|
+
tag: "csr:tabRefocus";
|
|
130
|
+
payload: {
|
|
131
|
+
awayDurationMs: number;
|
|
132
|
+
pathname?: string;
|
|
133
|
+
};
|
|
134
|
+
};
|
|
135
|
+
type RouteChangeTrigger = "pushState" | "replaceState" | "popstate" | "navigation";
|
|
136
|
+
type RouteChangePayload = {
|
|
137
|
+
from: string;
|
|
138
|
+
to: string;
|
|
139
|
+
trigger: RouteChangeTrigger;
|
|
140
|
+
};
|
|
141
|
+
type RouteChangeCustomData = {
|
|
142
|
+
tag: "csr:routeChange";
|
|
143
|
+
payload: RouteChangePayload;
|
|
144
|
+
};
|
|
145
|
+
/**
|
|
146
|
+
* Plugin event data emitted by the recorder for tab visibility changes.
|
|
147
|
+
*/
|
|
148
|
+
type TabVisibilityPluginData = {
|
|
149
|
+
plugin: "csr:tabVisibility";
|
|
150
|
+
payload: {
|
|
151
|
+
hidden: boolean;
|
|
152
|
+
};
|
|
153
|
+
};
|
|
154
|
+
type ConsoleLogLevel = "log" | "warn" | "error" | "debug" | "info";
|
|
155
|
+
/**
|
|
156
|
+
* Plugin event data emitted by rrweb's console record plugin.
|
|
157
|
+
* Shape matches `@rrweb/rrweb-plugin-console-record` LogData.
|
|
158
|
+
*/
|
|
159
|
+
type ConsoleLogPluginData = {
|
|
160
|
+
plugin: "rrweb/console@1";
|
|
161
|
+
payload: {
|
|
162
|
+
level: ConsoleLogLevel;
|
|
163
|
+
payload: string[];
|
|
164
|
+
trace: string[];
|
|
165
|
+
};
|
|
166
|
+
};
|
|
167
|
+
type NetworkRequestInitiator = "fetch" | "xhr";
|
|
168
|
+
/**
|
|
169
|
+
* Plugin event data emitted by the recorder for network requests.
|
|
170
|
+
*/
|
|
171
|
+
type NetworkRequestPluginData = {
|
|
172
|
+
plugin: "csr:networkRequest";
|
|
173
|
+
payload: {
|
|
174
|
+
initiator: NetworkRequestInitiator;
|
|
175
|
+
method: string;
|
|
176
|
+
url: string;
|
|
177
|
+
status: number;
|
|
178
|
+
durationMs: number;
|
|
179
|
+
requestSize?: number;
|
|
180
|
+
responseSize?: number;
|
|
181
|
+
};
|
|
182
|
+
};
|
|
183
|
+
type RouteChangePluginData = {
|
|
184
|
+
plugin: "csr:routeChange";
|
|
185
|
+
payload: RouteChangePayload;
|
|
186
|
+
};
|
|
187
|
+
type TagPluginData = {
|
|
188
|
+
plugin: "csr:tag";
|
|
189
|
+
payload: {
|
|
190
|
+
key: string;
|
|
191
|
+
value?: string;
|
|
192
|
+
};
|
|
193
|
+
};
|
|
194
|
+
type MeasurePluginData = {
|
|
195
|
+
plugin: "csr:measure";
|
|
196
|
+
payload: {
|
|
197
|
+
key: string;
|
|
198
|
+
value?: number;
|
|
199
|
+
};
|
|
200
|
+
};
|
|
201
|
+
/**
|
|
202
|
+
* Closed union of every Custom event we emit. Add a new variant here when
|
|
203
|
+
* introducing a new tag — emitting an unregistered tag is a TS error.
|
|
204
|
+
*/
|
|
205
|
+
type CustomEventData = ClickCustomData | InputCustomData | RageClickCustomData | FormFieldReEditCustomData | ScrollBackCustomData | DeadClickCustomData | TabUnfocusCustomData | TabRefocusCustomData | RouteChangeCustomData;
|
|
206
|
+
/**
|
|
207
|
+
* A single recorded event.
|
|
208
|
+
*
|
|
209
|
+
* For non-Custom events `data` is `unknown` (decoupled from rrweb internals).
|
|
210
|
+
* For Custom events `data.tag` discriminates the payload across the closed
|
|
211
|
+
* `CustomEventData` union.
|
|
212
|
+
*/
|
|
213
|
+
type RecordingEvent = {
|
|
214
|
+
type: RecordingEventType.Custom;
|
|
215
|
+
timestamp: number;
|
|
216
|
+
data: CustomEventData;
|
|
217
|
+
} | {
|
|
218
|
+
type: Exclude<RecordingEventType, RecordingEventType.Custom>;
|
|
219
|
+
timestamp: number;
|
|
220
|
+
data: unknown;
|
|
221
|
+
};
|
|
222
|
+
//#endregion
|
|
223
|
+
//#region src/url.d.ts
|
|
224
|
+
/**
|
|
225
|
+
* Extract only the pathname from a URL, stripping origin, query string, and
|
|
226
|
+
* hash. Used across recorder and analyzer to avoid capturing PII in route data.
|
|
227
|
+
*/
|
|
228
|
+
declare function stripUrl(url: string): string;
|
|
229
|
+
//#endregion
|
|
230
|
+
//#region src/custom-event-limits.d.ts
|
|
231
|
+
declare const MAX_KEY_LENGTH = 128;
|
|
232
|
+
declare const MAX_TAG_VALUE_LENGTH = 256;
|
|
233
|
+
declare const MAX_DISTINCT_KEYS = 100;
|
|
234
|
+
declare const MAX_VALUES_PER_KEY = 1e3;
|
|
235
|
+
declare function validateKey(key: string): string | null;
|
|
236
|
+
declare function validateTagValue(value: string | undefined): string | null;
|
|
237
|
+
declare function validateMeasureValue(value: number | undefined): string | null;
|
|
238
|
+
//#endregion
|
|
239
|
+
export { type ClickCustomData, type ClientContext, type ConsoleLogLevel, type ConsoleLogPluginData, type CustomEventData, type DeadClickCustomData, type ElementDescriptor, type FormFieldReEditCustomData, type Frame, IncrementalSource, type InputCustomData, MAX_DISTINCT_KEYS, MAX_KEY_LENGTH, MAX_TAG_VALUE_LENGTH, MAX_VALUES_PER_KEY, type MeasurePluginData, MouseInteractions, type NetworkRequestInitiator, type NetworkRequestPluginData, type RageClickCustomData, type RecordingEvent, RecordingEventType, type RouteChangeCustomData, type RouteChangePayload, type RouteChangePluginData, type RouteChangeTrigger, type ScrollBackCustomData, SerializedNodeType, type TabRefocusCustomData, type TabUnfocusCustomData, type TabVisibilityPluginData, type TagPluginData, type UserAgentContext, stripUrl, validateKey, validateMeasureValue, validateTagValue };
|