@sailfish-ai/recorder 1.11.0 → 1.11.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 +94 -0
- package/dist/chunks/{chunkSerializer-ZzIoYlP2.js → chunkSerializer-CV4nkb5-.js} +1 -1
- package/dist/chunks/chunkSerializer-CV4nkb5-.js.br +0 -0
- package/dist/chunks/chunkSerializer-CV4nkb5-.js.gz +0 -0
- package/dist/chunks/{chunkSerializer-CRDpgzTs.js → chunkSerializer-jzbHv2wf.js} +1 -1
- package/dist/chunks/chunkSerializer-jzbHv2wf.js.br +0 -0
- package/dist/chunks/chunkSerializer-jzbHv2wf.js.gz +0 -0
- package/dist/chunks/{index-BQn1Q-2-.js → index-BP-kNUGS.js} +174 -134
- package/dist/chunks/index-BP-kNUGS.js.br +0 -0
- package/dist/chunks/index-BP-kNUGS.js.gz +0 -0
- package/dist/chunks/{index-Dq_tjmkZ.js → index-BynFTRFv.js} +130 -87
- package/dist/chunks/index-BynFTRFv.js.br +0 -0
- package/dist/chunks/index-BynFTRFv.js.gz +0 -0
- package/dist/chunks/rrweb-plugin-performance-record-BYWkWb25.js +188 -0
- package/dist/chunks/rrweb-plugin-performance-record-BYWkWb25.js.br +0 -0
- package/dist/chunks/rrweb-plugin-performance-record-BYWkWb25.js.gz +0 -0
- package/dist/chunks/rrweb-plugin-performance-record-Dekf6xUi.js +186 -0
- package/dist/chunks/rrweb-plugin-performance-record-Dekf6xUi.js.br +0 -0
- package/dist/chunks/rrweb-plugin-performance-record-Dekf6xUi.js.gz +0 -0
- package/dist/constants.js +1 -0
- package/dist/constants.js.br +0 -0
- package/dist/constants.js.gz +0 -0
- package/dist/inAppReportIssueModal/index.js +15 -14
- package/dist/inAppReportIssueModal/index.js.br +0 -0
- package/dist/inAppReportIssueModal/index.js.gz +0 -0
- package/dist/inAppReportIssueModal/integrations.js +56 -4
- package/dist/inAppReportIssueModal/integrations.js.br +0 -0
- package/dist/inAppReportIssueModal/integrations.js.gz +0 -0
- package/dist/index.js +68 -42
- package/dist/index.js.br +0 -0
- package/dist/index.js.gz +0 -0
- package/dist/recorder.cjs +2 -2
- package/dist/recorder.cjs.br +0 -0
- package/dist/recorder.cjs.gz +0 -0
- package/dist/recorder.js +27 -25
- package/dist/recorder.js.br +0 -0
- package/dist/recorder.js.gz +0 -0
- package/dist/recorder.umd.cjs +4994 -4776
- package/dist/recorder.umd.cjs.br +0 -0
- package/dist/recorder.umd.cjs.gz +0 -0
- package/dist/recording.js +33 -3
- package/dist/recording.js.br +0 -0
- package/dist/recording.js.gz +0 -0
- package/dist/sendSailfishMessages.js +4 -0
- package/dist/sendSailfishMessages.js.br +0 -0
- package/dist/sendSailfishMessages.js.gz +0 -0
- package/dist/snippet-auto-init.js +147 -18
- package/dist/snippet-auto-init.js.br +0 -0
- package/dist/snippet-auto-init.js.gz +0 -0
- package/dist/types/constants.d.ts +1 -0
- package/dist/types/inAppReportIssueModal/integrations.d.ts +7 -0
- package/dist/types/index.d.ts +23 -1
- package/dist/types/recording.d.ts +1 -0
- package/dist/types/sendSailfishMessages.d.ts +4 -0
- package/dist/types/snippet-auto-init.d.ts +30 -0
- package/dist/types/types.d.ts +1 -0
- package/package.json +7 -4
- package/dist/chunks/chunkSerializer-CRDpgzTs.js.br +0 -0
- package/dist/chunks/chunkSerializer-CRDpgzTs.js.gz +0 -0
- package/dist/chunks/chunkSerializer-ZzIoYlP2.js.br +0 -0
- package/dist/chunks/chunkSerializer-ZzIoYlP2.js.gz +0 -0
- package/dist/chunks/index-BQn1Q-2-.js.br +0 -0
- package/dist/chunks/index-BQn1Q-2-.js.gz +0 -0
- package/dist/chunks/index-Dq_tjmkZ.js.br +0 -0
- package/dist/chunks/index-Dq_tjmkZ.js.gz +0 -0
package/README.md
CHANGED
|
@@ -140,6 +140,7 @@ await initRecorder({
|
|
|
140
140
|
| `deferRecording` | `boolean` | `true` | Defers the initial DOM snapshot until after first paint / idle. |
|
|
141
141
|
| `chunkSnapshot` | `boolean` | `false` | Yield to the browser every 500 nodes during the initial snapshot (smoother on very large pages). |
|
|
142
142
|
| `useWsWorker` | `boolean` | `true` | Run the WebSocket sender in a Web Worker. Disable if your CSP blocks `worker-src blob:`. |
|
|
143
|
+
| `capturePerformanceMetrics` | `boolean` | `true` | Capture FCP / LCP / TBT / DCL / LOAD per `page_visit_uuid` via the performance plugin. Set `false` to skip — the plugin is dynamically imported, so opting out also skips loading `web-vitals` and the observers. |
|
|
143
144
|
| `reportIssueShortcuts` | `ShortcutsConfig` | — | Custom keyboard shortcuts for the report-issue modal. |
|
|
144
145
|
| `showEngTicketFieldsInReportIssueModalDefault` | `boolean` | `false` | Pre-expand Jira / Linear fields in the in-app issue modal. |
|
|
145
146
|
|
|
@@ -185,6 +186,98 @@ if (isFunctionSpanTrackingEnabled()) disableFunctionSpanTracking();
|
|
|
185
186
|
enableFunctionSpanTracking();
|
|
186
187
|
```
|
|
187
188
|
|
|
189
|
+
## Performance metrics
|
|
190
|
+
|
|
191
|
+
The recorder automatically captures real-user performance metrics per page visit and emits them through the same WebSocket pipeline as everything else. No additional configuration is required; capture is skipped in Lighthouse / headless / WebDriver environments to avoid polluting synthetic audits.
|
|
192
|
+
|
|
193
|
+
| Metric | Meaning | Source |
|
|
194
|
+
|---|---|---|
|
|
195
|
+
| **FCP** — First Contentful Paint | Time to first text/image paint. | `web-vitals` `onFCP` |
|
|
196
|
+
| **LCP** — Largest Contentful Paint | Time to the largest above-the-fold element. Closest proxy for "content is visible". | `web-vitals` `onLCP` |
|
|
197
|
+
| **TBT** — Total Blocking Time | Sum of blocking time from long tasks, emitted at `load`. | `PerformanceObserver({type:'longtask', buffered:true})` summing `max(0, duration − 50)` |
|
|
198
|
+
| **DCL** — DOMContentLoaded | `navigation.domContentLoadedEventEnd` (ms since `timeOrigin`). | Navigation Timing Level 2 |
|
|
199
|
+
| **LOAD** — load event | `navigation.loadEventEnd` (ms since `timeOrigin`). | Navigation Timing Level 2 |
|
|
200
|
+
|
|
201
|
+
FCP and LCP re-emit on SPA soft-navigations (via `web-vitals`' native history-API / BFCache support) — each emission is keyed to the current `page_visit_uuid`. TBT, DCL, and LOAD fire once per hard load.
|
|
202
|
+
|
|
203
|
+
Events arrive on the recorder WebSocket with `type: 28` (the numeric id reserved for performance metrics — see `backend/sailfish/rrweb/enums.py` on the Sailfish backend) and the shape:
|
|
204
|
+
|
|
205
|
+
```json
|
|
206
|
+
{
|
|
207
|
+
"type": 28,
|
|
208
|
+
"timestamp": 1700000000000,
|
|
209
|
+
"sessionId": "<session_id>",
|
|
210
|
+
"page_visit_uuid": "<uuid>",
|
|
211
|
+
"href": "https://example.com/path",
|
|
212
|
+
"data": {
|
|
213
|
+
"plugin": "@sailfish-rrweb/rrweb/performance@1",
|
|
214
|
+
"payload": {
|
|
215
|
+
"metric": "FCP" | "LCP" | "TBT" | "DCL" | "LOAD",
|
|
216
|
+
"value": 1234.5,
|
|
217
|
+
"rating": "good" | "needs-improvement" | "poor",
|
|
218
|
+
"navigationType": "navigate" | "reload" | "back-forward" | "back-forward-cache" | "prerender" | "restore",
|
|
219
|
+
"pageVisitUuid": "<uuid>",
|
|
220
|
+
"href": "https://example.com/path",
|
|
221
|
+
"timestamp": 1700000000000
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
### Disabling capture
|
|
228
|
+
|
|
229
|
+
Pass `capturePerformanceMetrics: false` to `initRecorder` to skip the plugin entirely. Because the plugin code is dynamically imported, this also avoids loading `web-vitals` and the long-task observer:
|
|
230
|
+
|
|
231
|
+
```ts
|
|
232
|
+
initRecorder({
|
|
233
|
+
apiKey: "YOUR_API_KEY",
|
|
234
|
+
capturePerformanceMetrics: false,
|
|
235
|
+
});
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
### Benchmarking the plugin's overhead
|
|
239
|
+
|
|
240
|
+
`scripts/bench-perf.js` loads the same page twice — once with capture on, once with capture off — under headless Chrome, and reports CPU, JS heap, FCP/LCP, long-task time, and total load time side-by-side.
|
|
241
|
+
|
|
242
|
+
#### One-time app change (required before running the bench)
|
|
243
|
+
|
|
244
|
+
The bench needs a way to flip capture on/off without rebuilding your app between variants. Wire `?sf_perf=off` in your `initRecorder` call so the URL controls the option — paste this where you call `initRecorder`:
|
|
245
|
+
|
|
246
|
+
```ts
|
|
247
|
+
const capturePerformanceMetrics =
|
|
248
|
+
new URLSearchParams(window.location.search).get("sf_perf") !== "off";
|
|
249
|
+
|
|
250
|
+
initRecorder({
|
|
251
|
+
apiKey: "YOUR_API_KEY",
|
|
252
|
+
// …your other options…
|
|
253
|
+
capturePerformanceMetrics,
|
|
254
|
+
});
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
Anything other than `?sf_perf=off` (including the param being absent) leaves capture enabled, so day-to-day usage is unaffected. The toggle exists only so the bench can switch variants by URL.
|
|
258
|
+
|
|
259
|
+
#### Run the bench
|
|
260
|
+
|
|
261
|
+
```bash
|
|
262
|
+
# 1. Start your app's dev server (separate terminal). Default port 3000.
|
|
263
|
+
npm run start
|
|
264
|
+
|
|
265
|
+
# 2. Run the bench (defaults to http://localhost:3000, 5 runs/variant):
|
|
266
|
+
cd veritas/jsts-frontend
|
|
267
|
+
npm install # first time only — installs puppeteer
|
|
268
|
+
npm run bench-perf
|
|
269
|
+
|
|
270
|
+
# Override URL or sample count:
|
|
271
|
+
npm run bench-perf -- --url http://localhost:3000/some/page --runs 10
|
|
272
|
+
|
|
273
|
+
# Watch the runs in a real browser window (slower, useful for sanity-checking):
|
|
274
|
+
npm run bench-perf -- --headed
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
Output is a table of medians, p95, and Δ% between the two variants for: wall load time, DCL, load event, FCP, LCP, long-task total, long-task blocking (the TBT proxy), CDP `TaskDuration` / `ScriptDuration` / `LayoutDuration`, and `usedJSHeapSize` (MB).
|
|
278
|
+
|
|
279
|
+
Sample interpretation: a Δ ≤ noise (typically ±5% on the smaller numbers, ±2 MB on heap) means the plugin is essentially free; anything larger is a regression worth profiling.
|
|
280
|
+
|
|
188
281
|
## Framework examples
|
|
189
282
|
|
|
190
283
|
### React / Vite
|
|
@@ -311,4 +404,5 @@ ReferenceError: localStorage is not defined
|
|
|
311
404
|
|
|
312
405
|
## License
|
|
313
406
|
|
|
407
|
+
|
|
314
408
|
Proprietary. See [sailfishqa.com/terms](https://sailfishqa.com) for terms of service.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { y as e } from "./index-
|
|
1
|
+
import { y as e } from "./index-BynFTRFv.js";
|
|
2
2
|
async function chunkedSnapshot(t, n, o = {}) {
|
|
3
3
|
const s = o.chunkSize ?? 500, r = o.maxChunkMs ?? 16, { blockClass: c, blockSelector: a, maskTextClass: i, maskTextSelector: d } = o;
|
|
4
4
|
let u = 100001, l = 0, N = performance.now();
|
|
Binary file
|
|
Binary file
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
-
const e = require("./index-
|
|
3
|
+
const e = require("./index-BP-kNUGS.js");
|
|
4
4
|
exports.chunkedSnapshot = async function chunkedSnapshot(t, n, o = {}) {
|
|
5
5
|
const s = o.chunkSize ?? 500, r = o.maxChunkMs ?? 16, { blockClass: c, blockSelector: a, maskTextClass: i, maskTextSelector: d } = o;
|
|
6
6
|
let u = 100001, l = 0, N = performance.now();
|
|
Binary file
|
|
Binary file
|