swetrix 4.2.0 → 4.3.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 +49 -8
- package/dist/esnext/Lib.d.ts +73 -11
- package/dist/esnext/Lib.js +414 -11
- package/dist/esnext/Lib.js.map +1 -1
- package/dist/esnext/index.d.ts +18 -15
- package/dist/esnext/index.js +23 -15
- package/dist/esnext/index.js.map +1 -1
- package/dist/replaylibrary.min.js +173 -0
- package/dist/swetrix.cjs.js +441 -25
- package/dist/swetrix.cjs.js.map +1 -1
- package/dist/swetrix.es5.js +441 -26
- package/dist/swetrix.es5.js.map +1 -1
- package/dist/swetrix.js +1 -1
- package/dist/swetrix.js.map +1 -1
- package/jest.config.js +2 -0
- package/package.json +10 -7
- package/rollup.config.mjs +20 -0
- package/src/Lib.ts +579 -12
- package/src/index.ts +29 -14
- package/src/types/rrweb-shim.d.ts +11 -0
- package/tests/sessionReplay.test.ts +389 -0
- package/tsconfig.esnext.json +5 -1
- package/tsconfig.json +6 -1
- package/tsconfig.test.json +7 -0
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
[](https://www.npmjs.com/package/swetrix)
|
|
8
8
|
[](https://bundlephobia.com/package/swetrix)
|
|
9
|
-
[](https://
|
|
9
|
+
[](https://www.jsdelivr.com/package/npm/swetrix)
|
|
10
10
|
[](https://github.com/swetrix/swetrix-js/issues)
|
|
11
11
|
|
|
12
12
|
# Swetrix Tracking Script
|
|
@@ -65,6 +65,7 @@ init('YOUR_PROJECT_ID', {
|
|
|
65
65
|
disabled: false,
|
|
66
66
|
respectDNT: false,
|
|
67
67
|
profileId: 'user-123',
|
|
68
|
+
preloadSessionReplay: false,
|
|
68
69
|
})
|
|
69
70
|
```
|
|
70
71
|
|
|
@@ -75,6 +76,7 @@ init('YOUR_PROJECT_ID', {
|
|
|
75
76
|
| `disabled` | When `true`, no data is sent. Useful for dev environments. | `false` |
|
|
76
77
|
| `respectDNT` | When `true`, disables tracking for users with Do Not Track enabled. | `false` |
|
|
77
78
|
| `profileId` | Profile ID for long-term user tracking (MAU/DAU). | `undefined` |
|
|
79
|
+
| `preloadSessionReplay` | Preload the session replay recorder after `init()`. Recording only starts after `startSessionReplay()`. | `undefined` |
|
|
78
80
|
|
|
79
81
|
### `trackViews(options?)`
|
|
80
82
|
|
|
@@ -110,6 +112,7 @@ track({
|
|
|
110
112
|
ev: 'signup',
|
|
111
113
|
unique: true,
|
|
112
114
|
meta: { plan: 'pro', source: 'landing' },
|
|
115
|
+
profileId: 'user-123',
|
|
113
116
|
})
|
|
114
117
|
```
|
|
115
118
|
|
|
@@ -118,6 +121,7 @@ track({
|
|
|
118
121
|
| `ev` | Event name (max 256 chars). | **required** |
|
|
119
122
|
| `unique` | Only count once per session. | `false` |
|
|
120
123
|
| `meta` | Key-value metadata (max 20 keys, 1000 chars total). | `{}` |
|
|
124
|
+
| `profileId` | Optional profile ID. Overrides the global `profileId` for this event. | `undefined` |
|
|
121
125
|
|
|
122
126
|
### `trackErrors(options?)`
|
|
123
127
|
|
|
@@ -161,29 +165,66 @@ pageview({
|
|
|
161
165
|
### Feature Flags
|
|
162
166
|
|
|
163
167
|
```javascript
|
|
164
|
-
// Get all flags
|
|
168
|
+
// Get all flags. Results are cached for 5 minutes.
|
|
165
169
|
const flags = await getFeatureFlags({ profileId: 'user-123' })
|
|
166
170
|
|
|
167
|
-
//
|
|
171
|
+
// Force a fresh fetch
|
|
172
|
+
const freshFlags = await getFeatureFlags({ profileId: 'user-123' }, true)
|
|
173
|
+
|
|
174
|
+
// Get a single flag. The third argument is an optional fallback value.
|
|
168
175
|
const enabled = await getFeatureFlag('dark-mode', { profileId: 'user-123' })
|
|
176
|
+
const enabledWithFallback = await getFeatureFlag('dark-mode', { profileId: 'user-123' }, false)
|
|
169
177
|
|
|
170
|
-
// Clear cache
|
|
178
|
+
// Clear the shared feature flag / experiment cache
|
|
171
179
|
clearFeatureFlagsCache()
|
|
172
180
|
```
|
|
173
181
|
|
|
174
182
|
### A/B Experiments
|
|
175
183
|
|
|
176
184
|
```javascript
|
|
177
|
-
// Get all
|
|
185
|
+
// Get all running experiment assignments. Results are cached for 5 minutes.
|
|
178
186
|
const experiments = await getExperiments({ profileId: 'user-123' })
|
|
179
187
|
|
|
180
|
-
//
|
|
181
|
-
const
|
|
188
|
+
// Force a fresh fetch
|
|
189
|
+
const freshExperiments = await getExperiments({ profileId: 'user-123' }, true)
|
|
182
190
|
|
|
183
|
-
//
|
|
191
|
+
// Get a specific experiment variant. The third argument is an optional fallback variant.
|
|
192
|
+
const variant = await getExperiment('checkout-redesign-experiment-id', { profileId: 'user-123' })
|
|
193
|
+
const variantWithFallback = await getExperiment('checkout-redesign-experiment-id', { profileId: 'user-123' }, 'control')
|
|
194
|
+
|
|
195
|
+
// Clear the shared feature flag / experiment cache
|
|
184
196
|
clearExperimentsCache()
|
|
185
197
|
```
|
|
186
198
|
|
|
199
|
+
### `startSessionReplay(options?)`
|
|
200
|
+
|
|
201
|
+
Start recording a session replay. Session replays use `total` privacy by default, which masks text and inputs and blocks media/canvas capture unless you explicitly choose another mode.
|
|
202
|
+
|
|
203
|
+
If you use the npm package, rrweb is dynamically imported from your installed dependencies only when the recorder is preloaded or started. If you use the CDN/script-tag build, the standalone replay recorder is loaded with an async script tag.
|
|
204
|
+
|
|
205
|
+
```javascript
|
|
206
|
+
const replay = await startSessionReplay({
|
|
207
|
+
privacy: 'total',
|
|
208
|
+
sampleRate: 0.25,
|
|
209
|
+
maxDurationMs: 10 * 60 * 1000,
|
|
210
|
+
idleTimeoutMs: 2 * 60 * 1000,
|
|
211
|
+
})
|
|
212
|
+
|
|
213
|
+
// Stop or flush manually when needed
|
|
214
|
+
await replay.flush()
|
|
215
|
+
await replay.stop()
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
| Option | Description | Default |
|
|
219
|
+
|---|---|---|
|
|
220
|
+
| `privacy` | Privacy mode: `total`, `normal`, or `none`. | `'total'` |
|
|
221
|
+
| `sampleRate` | Fraction of sessions to record (`0` to `1`). | `1` |
|
|
222
|
+
| `maxDurationMs` | Stop recording after this duration. | `undefined` |
|
|
223
|
+
| `idleTimeoutMs` | Stop recording after this much visitor inactivity. | `undefined` |
|
|
224
|
+
| `flushIntervalMs` | Upload buffered replay events at this interval. | `5000` |
|
|
225
|
+
| `maxEventsPerChunk` | Upload once this many events are buffered. | `100` |
|
|
226
|
+
| `rrweb` | Additional rrweb record options. | `undefined` |
|
|
227
|
+
|
|
187
228
|
### Session & Profile IDs
|
|
188
229
|
|
|
189
230
|
```javascript
|
package/dist/esnext/Lib.d.ts
CHANGED
|
@@ -1,3 +1,22 @@
|
|
|
1
|
+
type RrwebEvent = Record<string, unknown>;
|
|
2
|
+
type RrwebEmit = (event: RrwebEvent) => void;
|
|
3
|
+
interface RrwebRecordOptions {
|
|
4
|
+
emit?: RrwebEmit;
|
|
5
|
+
[key: string]: unknown;
|
|
6
|
+
}
|
|
7
|
+
interface RrwebGlobal {
|
|
8
|
+
record?: (options: RrwebRecordOptions) => (() => void) | undefined;
|
|
9
|
+
Replayer?: unknown;
|
|
10
|
+
}
|
|
11
|
+
type SessionReplayPreloadOption = boolean | {
|
|
12
|
+
rrwebUrl?: string;
|
|
13
|
+
};
|
|
14
|
+
declare global {
|
|
15
|
+
interface Window {
|
|
16
|
+
rrweb?: RrwebGlobal;
|
|
17
|
+
__SWETRIX_RRWEB_LOADING__?: Promise<void>;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
1
20
|
export interface LibOptions {
|
|
2
21
|
/**
|
|
3
22
|
* When set to `true`, localhost events will be sent to server.
|
|
@@ -19,6 +38,10 @@ export interface LibOptions {
|
|
|
19
38
|
* If set, it will be used for all pageviews and events unless overridden per-call.
|
|
20
39
|
*/
|
|
21
40
|
profileId?: string;
|
|
41
|
+
/**
|
|
42
|
+
* Preload session replay recorder code. Recording only starts after calling startSessionReplay().
|
|
43
|
+
*/
|
|
44
|
+
preloadSessionReplay?: SessionReplayPreloadOption;
|
|
22
45
|
}
|
|
23
46
|
export interface TrackEventOptions {
|
|
24
47
|
/** The custom event name. */
|
|
@@ -117,6 +140,21 @@ export interface ErrorActions {
|
|
|
117
140
|
/** Stops the tracking of errors. */
|
|
118
141
|
stop: () => void;
|
|
119
142
|
}
|
|
143
|
+
declare const SESSION_REPLAY_PRIVACY_VALUES: readonly ["total", "normal", "none"];
|
|
144
|
+
export type SessionReplayPrivacy = (typeof SESSION_REPLAY_PRIVACY_VALUES)[number];
|
|
145
|
+
export interface SessionReplayOptions {
|
|
146
|
+
privacy?: SessionReplayPrivacy;
|
|
147
|
+
rrweb?: RrwebRecordOptions;
|
|
148
|
+
flushIntervalMs?: number;
|
|
149
|
+
maxEventsPerChunk?: number;
|
|
150
|
+
sampleRate?: number;
|
|
151
|
+
maxDurationMs?: number;
|
|
152
|
+
idleTimeoutMs?: number;
|
|
153
|
+
}
|
|
154
|
+
export interface SessionReplayActions {
|
|
155
|
+
stop: () => Promise<void>;
|
|
156
|
+
flush: () => Promise<void>;
|
|
157
|
+
}
|
|
120
158
|
export interface PageData {
|
|
121
159
|
/** Current URL path. */
|
|
122
160
|
path: string;
|
|
@@ -169,6 +207,7 @@ export interface PageViewsOptions {
|
|
|
169
207
|
export declare const defaultActions: {
|
|
170
208
|
stop(): void;
|
|
171
209
|
};
|
|
210
|
+
export declare const defaultSessionReplayActions: SessionReplayActions;
|
|
172
211
|
export declare class Lib {
|
|
173
212
|
private projectID;
|
|
174
213
|
private options?;
|
|
@@ -179,6 +218,9 @@ export declare class Lib {
|
|
|
179
218
|
private activePage;
|
|
180
219
|
private errorListenerExists;
|
|
181
220
|
private cachedData;
|
|
221
|
+
private rrwebLoader;
|
|
222
|
+
private sessionReplayActions;
|
|
223
|
+
private sessionReplayInitPromise;
|
|
182
224
|
constructor(projectID: string, options?: LibOptions | undefined);
|
|
183
225
|
captureError(event: ErrorEvent): void;
|
|
184
226
|
trackErrors(options?: ErrorOptions): ErrorActions;
|
|
@@ -187,10 +229,10 @@ export declare class Lib {
|
|
|
187
229
|
trackPageViews(options?: PageViewsOptions): PageActions;
|
|
188
230
|
getPerformanceStats(): IPerfPayload | {};
|
|
189
231
|
/**
|
|
190
|
-
* Fetches all feature flags
|
|
191
|
-
* Results are cached for 5 minutes by default.
|
|
232
|
+
* Fetches all feature flags for the project.
|
|
233
|
+
* Results are cached for 5 minutes by default and share a cache with experiments.
|
|
192
234
|
*
|
|
193
|
-
* @param options - Options for evaluating feature flags.
|
|
235
|
+
* @param options - Options for evaluating feature flags (`profileId` only).
|
|
194
236
|
* @param forceRefresh - If true, bypasses the cache and fetches fresh data.
|
|
195
237
|
* @returns A promise that resolves to a record of flag keys to boolean values.
|
|
196
238
|
*/
|
|
@@ -203,8 +245,8 @@ export declare class Lib {
|
|
|
203
245
|
* Gets the value of a single feature flag.
|
|
204
246
|
*
|
|
205
247
|
* @param key - The feature flag key.
|
|
206
|
-
* @param options - Options for evaluating the feature flag.
|
|
207
|
-
* @param defaultValue -
|
|
248
|
+
* @param options - Options for evaluating the feature flag (`profileId` only).
|
|
249
|
+
* @param defaultValue - Optional default value to return if the flag is not found. Defaults to false.
|
|
208
250
|
* @returns A promise that resolves to the boolean value of the flag.
|
|
209
251
|
*/
|
|
210
252
|
getFeatureFlag(key: string, options?: FeatureFlagsOptions, defaultValue?: boolean): Promise<boolean>;
|
|
@@ -213,16 +255,16 @@ export declare class Lib {
|
|
|
213
255
|
*/
|
|
214
256
|
clearFeatureFlagsCache(): void;
|
|
215
257
|
/**
|
|
216
|
-
* Fetches
|
|
258
|
+
* Fetches variant assignments for running A/B test experiments returned by feature flag evaluation.
|
|
217
259
|
* Results are cached for 5 minutes by default (shared cache with feature flags).
|
|
218
260
|
*
|
|
219
|
-
* @param options - Options for evaluating experiments.
|
|
261
|
+
* @param options - Options for evaluating experiments (`profileId` only).
|
|
220
262
|
* @param forceRefresh - If true, bypasses the cache and fetches fresh data.
|
|
221
263
|
* @returns A promise that resolves to a record of experiment IDs to variant keys.
|
|
222
264
|
*
|
|
223
265
|
* @example
|
|
224
266
|
* ```typescript
|
|
225
|
-
* const experiments = await getExperiments()
|
|
267
|
+
* const experiments = await getExperiments({ profileId: 'user-123' })
|
|
226
268
|
* // experiments = { 'exp-123': 'variant-a', 'exp-456': 'control' }
|
|
227
269
|
* ```
|
|
228
270
|
*/
|
|
@@ -231,13 +273,16 @@ export declare class Lib {
|
|
|
231
273
|
* Gets the variant key for a specific A/B test experiment.
|
|
232
274
|
*
|
|
233
275
|
* @param experimentId - The experiment ID.
|
|
234
|
-
* @param options - Options for evaluating the experiment.
|
|
235
|
-
* @param defaultVariant -
|
|
276
|
+
* @param options - Options for evaluating the experiment (`profileId` only).
|
|
277
|
+
* @param defaultVariant - Optional default variant key to return if the experiment is not found. Defaults to null.
|
|
236
278
|
* @returns A promise that resolves to the variant key assigned to this user, or defaultVariant if not found.
|
|
237
279
|
*
|
|
238
280
|
* @example
|
|
239
281
|
* ```typescript
|
|
240
|
-
* const variant = await getExperiment('checkout-redesign')
|
|
282
|
+
* const variant = await getExperiment('checkout-redesign', { profileId: 'user-123' })
|
|
283
|
+
*
|
|
284
|
+
* // Optional fallback variant:
|
|
285
|
+
* const variantWithFallback = await getExperiment('checkout-redesign', undefined, 'control')
|
|
241
286
|
*
|
|
242
287
|
* if (variant === 'new-checkout') {
|
|
243
288
|
* // Show new checkout flow
|
|
@@ -298,6 +343,10 @@ export declare class Lib {
|
|
|
298
343
|
* ```
|
|
299
344
|
*/
|
|
300
345
|
getSessionId(): Promise<string | null>;
|
|
346
|
+
startSessionReplay(options?: SessionReplayOptions): Promise<SessionReplayActions>;
|
|
347
|
+
private initialiseSessionReplay;
|
|
348
|
+
private shouldSampleSessionReplay;
|
|
349
|
+
private getSessionReplayPrivacy;
|
|
301
350
|
/**
|
|
302
351
|
* Gets the API base URL (without /log suffix).
|
|
303
352
|
*/
|
|
@@ -307,6 +356,19 @@ export declare class Lib {
|
|
|
307
356
|
private trackPage;
|
|
308
357
|
submitPageView(payload: Partial<IPageViewPayload>, unique: boolean, perf: IPerfPayload | {}, evokeCallback?: boolean): void;
|
|
309
358
|
private canTrack;
|
|
359
|
+
private getSessionReplayUrl;
|
|
360
|
+
private getSessionReplayPreloadOption;
|
|
361
|
+
private getDefaultSessionReplayUrl;
|
|
362
|
+
private getTrackerScript;
|
|
363
|
+
private preloadSessionReplay;
|
|
364
|
+
private loadSessionReplayRecorder;
|
|
365
|
+
private loadSessionReplayPackage;
|
|
366
|
+
private loadSessionReplayScript;
|
|
367
|
+
private getSessionReplayRecordOptions;
|
|
368
|
+
private mergeSelectors;
|
|
369
|
+
private createReplayId;
|
|
370
|
+
private sendSessionReplayStart;
|
|
371
|
+
private sendSessionReplayChunk;
|
|
310
372
|
private sendRequest;
|
|
311
373
|
}
|
|
312
374
|
export {};
|