@anyreplay/browser 0.1.1 → 0.1.3
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 +23 -6
- package/dist/index.cjs +301 -93
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +53 -6
- package/dist/index.d.ts +53 -6
- package/dist/index.js +300 -93
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.cts
CHANGED
|
@@ -5,8 +5,42 @@ interface AnyReplayOptions {
|
|
|
5
5
|
ingestUrl?: string;
|
|
6
6
|
/** Fraction of visitors recorded, 0–1. Decided once per visitor, not per page. */
|
|
7
7
|
sampleRate?: number;
|
|
8
|
-
/**
|
|
8
|
+
/**
|
|
9
|
+
* Mask the value of every form control.
|
|
10
|
+
*
|
|
11
|
+
* Off by default: a recording shows what a visitor typed into inputs,
|
|
12
|
+
* textareas and rich-text editors, because a replay of a form nobody could
|
|
13
|
+
* finish is worth watching only if you can see what they were trying to put
|
|
14
|
+
* in it. Turn this on for a site whose forms carry anything you would not
|
|
15
|
+
* want a teammate to read, and mark individual fields with the `maskClass`
|
|
16
|
+
* when it is only some of them.
|
|
17
|
+
*
|
|
18
|
+
* Some fields are masked whatever this says, in every mode: passwords,
|
|
19
|
+
* one-time codes, payment fields (card number, CVV, expiry, IBAN, routing
|
|
20
|
+
* number, sort code), anything inside an element with the mask class, and any
|
|
21
|
+
* value that looks like a card number. Email and telephone fields are not on
|
|
22
|
+
* that list — they are ordinary fields, recorded by default and masked by this
|
|
23
|
+
* option. See `isSensitiveField` in `masking.ts` for the exact list.
|
|
24
|
+
*/
|
|
9
25
|
maskAllInputs?: boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Mask everything a person types, wherever they type it.
|
|
28
|
+
*
|
|
29
|
+
* `maskAllInputs` covers form controls. This covers those *and* the other
|
|
30
|
+
* place a person can type — an element with `contenteditable`, which is what
|
|
31
|
+
* a rich-text editor, a comment box or a chat composer is made of. Their text
|
|
32
|
+
* is not an input value but ordinary page text, so input masking does not
|
|
33
|
+
* reach it. With this on, the text of every editable region is replaced with
|
|
34
|
+
* asterisks in the first snapshot and in every change after it.
|
|
35
|
+
*
|
|
36
|
+
* The stricter of the two options, and a superset of it: `maskAllTyping: true`
|
|
37
|
+
* masks form fields too, whatever `maskAllInputs` says. It is separate
|
|
38
|
+
* because masking an editable region masks *all* of its text, including
|
|
39
|
+
* whatever the page put there before anyone typed — a loaded document, a
|
|
40
|
+
* quoted message — which is a bigger thing to ask for than hiding field
|
|
41
|
+
* values.
|
|
42
|
+
*/
|
|
43
|
+
maskAllTyping?: boolean;
|
|
10
44
|
/** Elements with this class have their text masked. */
|
|
11
45
|
maskClass?: string;
|
|
12
46
|
/** Elements with this class are not recorded at all. */
|
|
@@ -40,14 +74,15 @@ declare class ConfigError extends Error {
|
|
|
40
74
|
declare function resolveOptions(input: AnyReplayOptions): ResolvedOptions;
|
|
41
75
|
|
|
42
76
|
type RecorderStatus = 'idle' | 'awaiting-consent' | 'recording' | 'sampled-out' | 'stopped';
|
|
77
|
+
interface IdentifyTraits {
|
|
78
|
+
userId?: string;
|
|
79
|
+
email?: string;
|
|
80
|
+
}
|
|
43
81
|
interface RecorderHandle {
|
|
44
82
|
status: () => RecorderStatus;
|
|
45
83
|
sessionId: () => string | null;
|
|
46
84
|
consent: (granted: boolean) => void;
|
|
47
|
-
identify: (traits:
|
|
48
|
-
userId?: string;
|
|
49
|
-
email?: string;
|
|
50
|
-
}) => void;
|
|
85
|
+
identify: (traits: IdentifyTraits) => void;
|
|
51
86
|
/**
|
|
52
87
|
* Tags this moment of the recording so it shows on the player's timeline.
|
|
53
88
|
*
|
|
@@ -199,6 +234,18 @@ interface Identity {
|
|
|
199
234
|
* id resets after a period of inactivity.
|
|
200
235
|
*/
|
|
201
236
|
declare function resolveIdentity(local: Storage, session: Storage, now?: number): Identity;
|
|
237
|
+
/**
|
|
238
|
+
* Removes everything the recorder has stored in this browser.
|
|
239
|
+
*
|
|
240
|
+
* Called when consent is refused. A refusal has to undo an earlier acceptance,
|
|
241
|
+
* not merely stop the current page: the visitor id written last week is
|
|
242
|
+
* exactly what the visitor is now saying no to, and leaving it in place would
|
|
243
|
+
* make "we store nothing without consent" untrue for as long as it sat there.
|
|
244
|
+
* The cool-down goes too — it is a fact about a session that no longer exists.
|
|
245
|
+
* Removing a key that is not there creates nothing, so this is safe to call
|
|
246
|
+
* before anything was ever written.
|
|
247
|
+
*/
|
|
248
|
+
declare function forgetVisitor(local: Storage, session: Storage): void;
|
|
202
249
|
|
|
203
250
|
/**
|
|
204
251
|
* Custom events: the moments a page tags with `track()`.
|
|
@@ -225,4 +272,4 @@ interface TrackPayload {
|
|
|
225
272
|
*/
|
|
226
273
|
declare function validateTrack(name: unknown, properties: unknown): TrackPayload | string;
|
|
227
274
|
|
|
228
|
-
export { type AnyReplayOptions, ConfigError, DEFAULTS, EVENT_NAME_PATTERN, MAX_PROPERTIES_BYTES, NAVIGATE_TAG, type RecordedEvent, type RecorderHandle, type RecorderStatus, type ResolvedOptions, type SessionMeta, TRACK_TAG, type TrackPayload, Transport, createRecorder, hashToUnitInterval, isSampledIn, resolveIdentity, resolveOptions, safeStorage, uuidv4, validateTrack };
|
|
275
|
+
export { type AnyReplayOptions, ConfigError, DEFAULTS, EVENT_NAME_PATTERN, MAX_PROPERTIES_BYTES, NAVIGATE_TAG, type RecordedEvent, type RecorderHandle, type RecorderStatus, type ResolvedOptions, type SessionMeta, TRACK_TAG, type TrackPayload, Transport, createRecorder, forgetVisitor, hashToUnitInterval, isSampledIn, resolveIdentity, resolveOptions, safeStorage, uuidv4, validateTrack };
|
package/dist/index.d.ts
CHANGED
|
@@ -5,8 +5,42 @@ interface AnyReplayOptions {
|
|
|
5
5
|
ingestUrl?: string;
|
|
6
6
|
/** Fraction of visitors recorded, 0–1. Decided once per visitor, not per page. */
|
|
7
7
|
sampleRate?: number;
|
|
8
|
-
/**
|
|
8
|
+
/**
|
|
9
|
+
* Mask the value of every form control.
|
|
10
|
+
*
|
|
11
|
+
* Off by default: a recording shows what a visitor typed into inputs,
|
|
12
|
+
* textareas and rich-text editors, because a replay of a form nobody could
|
|
13
|
+
* finish is worth watching only if you can see what they were trying to put
|
|
14
|
+
* in it. Turn this on for a site whose forms carry anything you would not
|
|
15
|
+
* want a teammate to read, and mark individual fields with the `maskClass`
|
|
16
|
+
* when it is only some of them.
|
|
17
|
+
*
|
|
18
|
+
* Some fields are masked whatever this says, in every mode: passwords,
|
|
19
|
+
* one-time codes, payment fields (card number, CVV, expiry, IBAN, routing
|
|
20
|
+
* number, sort code), anything inside an element with the mask class, and any
|
|
21
|
+
* value that looks like a card number. Email and telephone fields are not on
|
|
22
|
+
* that list — they are ordinary fields, recorded by default and masked by this
|
|
23
|
+
* option. See `isSensitiveField` in `masking.ts` for the exact list.
|
|
24
|
+
*/
|
|
9
25
|
maskAllInputs?: boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Mask everything a person types, wherever they type it.
|
|
28
|
+
*
|
|
29
|
+
* `maskAllInputs` covers form controls. This covers those *and* the other
|
|
30
|
+
* place a person can type — an element with `contenteditable`, which is what
|
|
31
|
+
* a rich-text editor, a comment box or a chat composer is made of. Their text
|
|
32
|
+
* is not an input value but ordinary page text, so input masking does not
|
|
33
|
+
* reach it. With this on, the text of every editable region is replaced with
|
|
34
|
+
* asterisks in the first snapshot and in every change after it.
|
|
35
|
+
*
|
|
36
|
+
* The stricter of the two options, and a superset of it: `maskAllTyping: true`
|
|
37
|
+
* masks form fields too, whatever `maskAllInputs` says. It is separate
|
|
38
|
+
* because masking an editable region masks *all* of its text, including
|
|
39
|
+
* whatever the page put there before anyone typed — a loaded document, a
|
|
40
|
+
* quoted message — which is a bigger thing to ask for than hiding field
|
|
41
|
+
* values.
|
|
42
|
+
*/
|
|
43
|
+
maskAllTyping?: boolean;
|
|
10
44
|
/** Elements with this class have their text masked. */
|
|
11
45
|
maskClass?: string;
|
|
12
46
|
/** Elements with this class are not recorded at all. */
|
|
@@ -40,14 +74,15 @@ declare class ConfigError extends Error {
|
|
|
40
74
|
declare function resolveOptions(input: AnyReplayOptions): ResolvedOptions;
|
|
41
75
|
|
|
42
76
|
type RecorderStatus = 'idle' | 'awaiting-consent' | 'recording' | 'sampled-out' | 'stopped';
|
|
77
|
+
interface IdentifyTraits {
|
|
78
|
+
userId?: string;
|
|
79
|
+
email?: string;
|
|
80
|
+
}
|
|
43
81
|
interface RecorderHandle {
|
|
44
82
|
status: () => RecorderStatus;
|
|
45
83
|
sessionId: () => string | null;
|
|
46
84
|
consent: (granted: boolean) => void;
|
|
47
|
-
identify: (traits:
|
|
48
|
-
userId?: string;
|
|
49
|
-
email?: string;
|
|
50
|
-
}) => void;
|
|
85
|
+
identify: (traits: IdentifyTraits) => void;
|
|
51
86
|
/**
|
|
52
87
|
* Tags this moment of the recording so it shows on the player's timeline.
|
|
53
88
|
*
|
|
@@ -199,6 +234,18 @@ interface Identity {
|
|
|
199
234
|
* id resets after a period of inactivity.
|
|
200
235
|
*/
|
|
201
236
|
declare function resolveIdentity(local: Storage, session: Storage, now?: number): Identity;
|
|
237
|
+
/**
|
|
238
|
+
* Removes everything the recorder has stored in this browser.
|
|
239
|
+
*
|
|
240
|
+
* Called when consent is refused. A refusal has to undo an earlier acceptance,
|
|
241
|
+
* not merely stop the current page: the visitor id written last week is
|
|
242
|
+
* exactly what the visitor is now saying no to, and leaving it in place would
|
|
243
|
+
* make "we store nothing without consent" untrue for as long as it sat there.
|
|
244
|
+
* The cool-down goes too — it is a fact about a session that no longer exists.
|
|
245
|
+
* Removing a key that is not there creates nothing, so this is safe to call
|
|
246
|
+
* before anything was ever written.
|
|
247
|
+
*/
|
|
248
|
+
declare function forgetVisitor(local: Storage, session: Storage): void;
|
|
202
249
|
|
|
203
250
|
/**
|
|
204
251
|
* Custom events: the moments a page tags with `track()`.
|
|
@@ -225,4 +272,4 @@ interface TrackPayload {
|
|
|
225
272
|
*/
|
|
226
273
|
declare function validateTrack(name: unknown, properties: unknown): TrackPayload | string;
|
|
227
274
|
|
|
228
|
-
export { type AnyReplayOptions, ConfigError, DEFAULTS, EVENT_NAME_PATTERN, MAX_PROPERTIES_BYTES, NAVIGATE_TAG, type RecordedEvent, type RecorderHandle, type RecorderStatus, type ResolvedOptions, type SessionMeta, TRACK_TAG, type TrackPayload, Transport, createRecorder, hashToUnitInterval, isSampledIn, resolveIdentity, resolveOptions, safeStorage, uuidv4, validateTrack };
|
|
275
|
+
export { type AnyReplayOptions, ConfigError, DEFAULTS, EVENT_NAME_PATTERN, MAX_PROPERTIES_BYTES, NAVIGATE_TAG, type RecordedEvent, type RecorderHandle, type RecorderStatus, type ResolvedOptions, type SessionMeta, TRACK_TAG, type TrackPayload, Transport, createRecorder, forgetVisitor, hashToUnitInterval, isSampledIn, resolveIdentity, resolveOptions, safeStorage, uuidv4, validateTrack };
|