@newtalaria/browser 0.1.1 → 0.1.4
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 +58 -11
- package/dist/client.d.ts +42 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/index.d.ts +5 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +527 -79
- package/dist/index.js.map +3 -3
- package/dist/replay/fit_segment.d.ts +35 -0
- package/dist/replay/fit_segment.d.ts.map +1 -0
- package/dist/replay/privacy.d.ts.map +1 -1
- package/dist/replay/recorder.d.ts +2 -0
- package/dist/replay/recorder.d.ts.map +1 -1
- package/dist/replay/segment_buffer.d.ts +56 -6
- package/dist/replay/segment_buffer.d.ts.map +1 -1
- package/dist/transport/replays.d.ts +3 -0
- package/dist/transport/replays.d.ts.map +1 -1
- package/dist/transport/serverpod.d.ts.map +1 -1
- package/dist/types.d.ts +9 -4
- package/dist/types.d.ts.map +1 -1
- package/package.json +6 -2
package/README.md
CHANGED
|
@@ -29,8 +29,11 @@ Talaria.init({
|
|
|
29
29
|
release: '1.0.0',
|
|
30
30
|
// Continuous session upload (0–1). Default 0 = buffer only until an error.
|
|
31
31
|
replaysSessionSampleRate: 0,
|
|
32
|
-
// On error,
|
|
32
|
+
// On error, promote the ~60s ring buffer (0–1). Default 1.
|
|
33
33
|
replaysOnErrorSampleRate: 1,
|
|
34
|
+
// Post-error upload window. Default 15000 (cheap clip). Use 0 to continue
|
|
35
|
+
// until the 5-minute max duration (Sentry-like, more expensive).
|
|
36
|
+
replaysErrorAfterMs: 15_000,
|
|
34
37
|
maskAllInputs: true, // default
|
|
35
38
|
});
|
|
36
39
|
|
|
@@ -49,6 +52,32 @@ await Talaria.close();
|
|
|
49
52
|
|
|
50
53
|
`Talaria.init` also installs `window.onerror` / `unhandledrejection` handlers unless you pass `disableDefaultIntegrations: true`.
|
|
51
54
|
|
|
55
|
+
## Recommended sampling (cost)
|
|
56
|
+
|
|
57
|
+
You pay for **uploaded + retained** bytes, not for local buffering. Prefer error clips in production; keep full-session sampling low.
|
|
58
|
+
|
|
59
|
+
| Traffic | `replaysSessionSampleRate` | `replaysOnErrorSampleRate` | `replaysErrorAfterMs` |
|
|
60
|
+
| --- | --- | --- | --- |
|
|
61
|
+
| High (100k+/day) | `0.01` | `1.0` | `15000` (default clip) |
|
|
62
|
+
| Medium (10k–100k/day) | `0.1` | `1.0` | `15000` |
|
|
63
|
+
| Low (under 10k/day) | `0.25` | `1.0` | `15000` |
|
|
64
|
+
| Marketing / docs site | `0` | `1.0` | `15000` |
|
|
65
|
+
| Rich post-error context | `0` | `1.0` | `0` (continue to 5 min cap) |
|
|
66
|
+
|
|
67
|
+
**Defaults (`session=0`, `onError=1`, `errorAfterMs=15000`)** are the cheapest useful profile: quiet traffic costs nothing; each sampled error keeps ~60s before + ~15s after.
|
|
68
|
+
|
|
69
|
+
## Replay sampling behavior
|
|
70
|
+
|
|
71
|
+
| Mode | Behavior |
|
|
72
|
+
| --- | --- |
|
|
73
|
+
| Session sample hit | `replays/start` immediately; segments upload every ~5s or ~100KB until unload or **5 min** max |
|
|
74
|
+
| Session sample miss | Record into a ~60s ring buffer; nothing uploaded until an error sample hits |
|
|
75
|
+
| Error sample + `replaysErrorAfterMs > 0` | Upload buffer (≤480KiB gzip pack target / 512KiB server cap) + trailing window, hard caps **12 segments** or **2MiB** compressed, attach `replayId` only if segments landed, `finish`, return to buffer mode |
|
|
76
|
+
| Error sample + `replaysErrorAfterMs = 0` | Upload buffer then continue like session mode until **5 min** / unload / size caps |
|
|
77
|
+
| Server limit (replay segments / total size / duration) | Stop uploading that replay; no retries |
|
|
78
|
+
| Oversized single rrweb event | Dropped with a console warning (cannot fit under segment cap) |
|
|
79
|
+
| `pagehide` / `close` | Flush pending segments with `fetch` `keepalive`, then `replays/finish`; `close` fully resets so `init()` works again (React Strict Mode) |
|
|
80
|
+
|
|
52
81
|
## Serverpod URL pattern
|
|
53
82
|
|
|
54
83
|
Talaria uses **Serverpod RPC**, not REST resource URLs:
|
|
@@ -91,16 +120,6 @@ decode('<base64>', 'base64')
|
|
|
91
120
|
|
|
92
121
|
Segment payloads are a **gzip-compressed JSON array** of rrweb events.
|
|
93
122
|
|
|
94
|
-
## Replay sampling
|
|
95
|
-
|
|
96
|
-
| Mode | Behavior |
|
|
97
|
-
| --- | --- |
|
|
98
|
-
| Session sample hit | `replays/start` immediately; segments upload every ~5s or ~100KB until unload |
|
|
99
|
-
| Session sample miss | Record into a ~60s ring buffer; nothing uploaded until an error sample hits |
|
|
100
|
-
| Error sample hit | Upload the ring buffer + ~15s after the error, attach `replayId`, then `finish` and return to buffer-only mode |
|
|
101
|
-
| Server limit (segments / size / duration) | Stop uploading that replay; no retries |
|
|
102
|
-
| `pagehide` / `close` | Flush pending segments with `fetch` `keepalive`, then `replays/finish` |
|
|
103
|
-
|
|
104
123
|
Custom rrweb events:
|
|
105
124
|
|
|
106
125
|
- `talaria-console` — console level + args (truncated)
|
|
@@ -122,3 +141,31 @@ Privacy defaults: `maskAllInputs: true`, password fields masked, `[data-talaria-
|
|
|
122
141
|
## Example
|
|
123
142
|
|
|
124
143
|
See [`../../examples/sdk-spa`](../../examples/sdk-spa) for a minimal page wired to `localhost:8080`.
|
|
144
|
+
|
|
145
|
+
## Local `file:` install (marketing / monorepo)
|
|
146
|
+
|
|
147
|
+
`dist/` is gitignored. After editing SDK `src/`, rebuild before the consumer picks up changes:
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
cd new_talaria_js/packages/browser
|
|
151
|
+
npm run build
|
|
152
|
+
# or: npm install in the consumer — `prepare` runs build for file: installs
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Then restart the Next app with a clean cache:
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
cd ../new_talaria_marketing # sibling repo
|
|
159
|
+
rm -rf .next
|
|
160
|
+
npm run dev
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
**Serverpod must be restarted** after changing `ReplayLimits` (compressed cap is 512KiB). A live process still on 256KiB will 400 every near-max segment.
|
|
164
|
+
|
|
165
|
+
### Verify error-clip ingest
|
|
166
|
+
|
|
167
|
+
1. Restart Serverpod (512KiB live).
|
|
168
|
+
2. Rebuild the browser package; restart marketing with clean `.next`.
|
|
169
|
+
3. Browse `/docs/**` ~30s, throw one test exception.
|
|
170
|
+
4. Expect: a few `ingestSegment` 200s, one `finish`, **zero** compressed-size 400 spam, dashboard replay plays.
|
|
171
|
+
5. Throw again later: a new bounded clip is allowed (buffer mode reset).
|
package/dist/client.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import type { CaptureContext, SeverityLevel, TalariaInitOptions } from './types.js';
|
|
2
|
+
export { computeErrorClipDeadlineMs, fitCompressedPrefix, isErrorClipBudgetExhausted, planOversizedRetry, } from './replay/fit_segment.js';
|
|
3
|
+
export { MAX_SEGMENTS_ERROR_CLIP, MAX_ERROR_CLIP_COMPRESSED_BYTES, TARGET_COMPRESSED_SEGMENT_BYTES, MAX_COMPRESSED_SEGMENT_BYTES, } from './replay/segment_buffer.js';
|
|
2
4
|
export declare class TalariaClient {
|
|
3
5
|
private options;
|
|
4
6
|
private transport;
|
|
@@ -12,11 +14,22 @@ export declare class TalariaClient {
|
|
|
12
14
|
private startedOnServer;
|
|
13
15
|
private finishedOnServer;
|
|
14
16
|
private segmentIndex;
|
|
17
|
+
private uploadedCompressedBytes;
|
|
18
|
+
/** Wall clock when continuous upload began (session or error promote). */
|
|
19
|
+
private uploadStartedAtMs;
|
|
20
|
+
/** Absolute deadline for error-clip mode (not extended by later errors). */
|
|
21
|
+
private errorClipDeadlineMs;
|
|
15
22
|
private flushTimer;
|
|
16
23
|
private errorClipTimer;
|
|
24
|
+
private maxDurationTimer;
|
|
17
25
|
private uploadChain;
|
|
18
26
|
private closed;
|
|
19
27
|
private teardowns;
|
|
28
|
+
/**
|
|
29
|
+
* Replay id that just finished with segments — kept briefly so capture can
|
|
30
|
+
* attach it to the error event after budget/timer finish resets buffer mode.
|
|
31
|
+
*/
|
|
32
|
+
private linkableReplayId;
|
|
20
33
|
init(options: TalariaInitOptions): void;
|
|
21
34
|
getReplayId(): string | null;
|
|
22
35
|
captureException(error: unknown, context?: CaptureContext): Promise<void>;
|
|
@@ -26,20 +39,49 @@ export declare class TalariaClient {
|
|
|
26
39
|
keepalive?: boolean;
|
|
27
40
|
finish?: boolean;
|
|
28
41
|
}): Promise<void>;
|
|
42
|
+
/**
|
|
43
|
+
* Stop recording, flush while still open, then fully reset so `init()` can
|
|
44
|
+
* run again (React Strict Mode remount).
|
|
45
|
+
*/
|
|
29
46
|
close(): Promise<void>;
|
|
30
47
|
private onRrwebEvent;
|
|
31
48
|
private capture;
|
|
49
|
+
private markUploadStarted;
|
|
50
|
+
private isPastMaxDuration;
|
|
51
|
+
private isPastErrorClipDeadline;
|
|
52
|
+
private isErrorClipMode;
|
|
53
|
+
private scheduleMaxDurationStop;
|
|
54
|
+
private clearMaxDurationTimer;
|
|
55
|
+
private runStopForMaxDuration;
|
|
56
|
+
/**
|
|
57
|
+
* Schedule end of the cheap error clip against a fixed absolute deadline.
|
|
58
|
+
* Subsequent errors re-arm the timer but never push the wall later.
|
|
59
|
+
*/
|
|
32
60
|
private scheduleErrorClipEnd;
|
|
33
61
|
private clearErrorClipTimer;
|
|
34
62
|
/** Flush trailing post-error window, finish replay, return to ring buffer. */
|
|
35
63
|
private endErrorClip;
|
|
64
|
+
private runEndErrorClip;
|
|
36
65
|
/** After an error clip (or terminal limit), buffer locally until the next error. */
|
|
37
66
|
private resetToBufferMode;
|
|
67
|
+
/** Emit a checkout FullSnapshot into the ring buffer (sync via rrweb emit). */
|
|
68
|
+
private checkoutFullSnapshot;
|
|
69
|
+
/**
|
|
70
|
+
* Ensure segment 0 begins at Meta+FullSnapshot. Orphan increments alone
|
|
71
|
+
* produce a blank rrweb player.
|
|
72
|
+
*/
|
|
73
|
+
private prepareBufferForNewReplay;
|
|
38
74
|
private stopUploadingAfterLimit;
|
|
39
75
|
private installGlobalHandlers;
|
|
40
76
|
private enqueueUpload;
|
|
41
77
|
private ensureStarted;
|
|
42
78
|
private uploadPendingSegments;
|
|
79
|
+
private maxSegmentsAllowed;
|
|
80
|
+
/**
|
|
81
|
+
* Pull the largest event prefix that gzips under the target compressed size.
|
|
82
|
+
* Drops a single event that can never fit.
|
|
83
|
+
*/
|
|
84
|
+
private takeFittedSegment;
|
|
43
85
|
private finishOnServer;
|
|
44
86
|
}
|
|
45
87
|
//# sourceMappingURL=client.d.ts.map
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EAEd,aAAa,EACb,kBAAkB,EACnB,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EAEd,aAAa,EACb,kBAAkB,EACnB,MAAM,YAAY,CAAC;AAoCpB,OAAO,EACL,0BAA0B,EAC1B,mBAAmB,EACnB,0BAA0B,EAC1B,kBAAkB,GACnB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,uBAAuB,EACvB,+BAA+B,EAC/B,+BAA+B,EAC/B,4BAA4B,GAC7B,MAAM,4BAA4B,CAAC;AAuEpC,qBAAa,aAAa;IACxB,OAAO,CAAC,OAAO,CAAgC;IAC/C,OAAO,CAAC,SAAS,CAAmC;IACpD,OAAO,CAAC,QAAQ,CAAuB;IACvC,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,QAAQ,CAA+B;IAC/C,OAAO,CAAC,MAAM,CAAuB;IACrC,yEAAyE;IACzE,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,gBAAgB,CAAS;IACjC,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,uBAAuB,CAAK;IACpC,0EAA0E;IAC1E,OAAO,CAAC,iBAAiB,CAAuB;IAChD,4EAA4E;IAC5E,OAAO,CAAC,mBAAmB,CAAuB;IAClD,OAAO,CAAC,UAAU,CAA+C;IACjE,OAAO,CAAC,cAAc,CAA8C;IACpE,OAAO,CAAC,gBAAgB,CAA8C;IACtE,OAAO,CAAC,WAAW,CAAoC;IACvD,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,SAAS,CAAkB;IACnC;;;OAGG;IACH,OAAO,CAAC,gBAAgB,CAAuB;IAE/C,IAAI,CAAC,OAAO,EAAE,kBAAkB,GAAG,IAAI;IAgEvC,WAAW,IAAI,MAAM,GAAG,IAAI;IAKtB,gBAAgB,CACpB,KAAK,EAAE,OAAO,EACd,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,IAAI,CAAC;IAcV,cAAc,CAClB,OAAO,EAAE,MAAM,EACf,KAAK,GAAE,aAAsB,EAC7B,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,IAAI,CAAC;IASV,KAAK,CAAC,IAAI,CAAC,EAAE;QACjB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,SAAS,CAAC,EAAE,OAAO,CAAC;QACpB,MAAM,CAAC,EAAE,OAAO,CAAC;KAClB,GAAG,OAAO,CAAC,IAAI,CAAC;IA0CjB;;;OAGG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAmD5B,OAAO,CAAC,YAAY;YAwBN,OAAO;IA4ErB,OAAO,CAAC,iBAAiB;IAkBzB,OAAO,CAAC,iBAAiB;IAKzB,OAAO,CAAC,uBAAuB;IAK/B,OAAO,CAAC,eAAe;IAQvB,OAAO,CAAC,uBAAuB;IAiB/B,OAAO,CAAC,qBAAqB;YAOf,qBAAqB;IAsBnC;;;OAGG;IACH,OAAO,CAAC,oBAAoB;IAmB5B,OAAO,CAAC,mBAAmB;IAO3B,8EAA8E;YAChE,YAAY;YAgBZ,eAAe;IAW7B,oFAAoF;IACpF,OAAO,CAAC,iBAAiB;IAiBzB,+EAA+E;IAC/E,OAAO,CAAC,oBAAoB;IAI5B;;;OAGG;IACH,OAAO,CAAC,yBAAyB;IAYjC,OAAO,CAAC,uBAAuB;IAc/B,OAAO,CAAC,qBAAqB;IA6B7B,OAAO,CAAC,aAAa;YAKP,aAAa;YAkBb,qBAAqB;IA8HnC,OAAO,CAAC,kBAAkB;IAQ1B;;;OAGG;YACW,iBAAiB;YA2BjB,cAAc;CAuB7B"}
|
package/dist/index.d.ts
CHANGED
|
@@ -9,8 +9,9 @@ import type { CaptureContext, SeverityLevel, TalariaInitOptions } from './types.
|
|
|
9
9
|
* dsn: 'http://localhost:8080',
|
|
10
10
|
* apiKey: 'tal_live_…',
|
|
11
11
|
* environment: 'development',
|
|
12
|
-
* // Error clip: ~60s before + ~15s after (not full-session upload).
|
|
13
12
|
* replaysOnErrorSampleRate: 1,
|
|
13
|
+
* // Default 15s post-error clip; set 0 to continue until 5 min cap.
|
|
14
|
+
* replaysErrorAfterMs: 15_000,
|
|
14
15
|
* });
|
|
15
16
|
*
|
|
16
17
|
* try {
|
|
@@ -28,7 +29,9 @@ export declare const Talaria: {
|
|
|
28
29
|
flush(): Promise<void>;
|
|
29
30
|
close(): Promise<void>;
|
|
30
31
|
};
|
|
31
|
-
export type { CaptureContext, Environment, SeverityLevel, TalariaInitOptions, } from './types.js';
|
|
32
32
|
export { TalariaClient } from './client.js';
|
|
33
|
+
export { computeErrorClipDeadlineMs, fitCompressedPrefix, isErrorClipBudgetExhausted, planOversizedRetry, } from './replay/fit_segment.js';
|
|
34
|
+
export { MAX_SEGMENTS_ERROR_CLIP, MAX_ERROR_CLIP_COMPRESSED_BYTES, TARGET_COMPRESSED_SEGMENT_BYTES, MAX_COMPRESSED_SEGMENT_BYTES, } from './replay/segment_buffer.js';
|
|
35
|
+
export type { CaptureContext, Environment, SeverityLevel, TalariaInitOptions, } from './types.js';
|
|
33
36
|
export default Talaria;
|
|
34
37
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,cAAc,EACd,aAAa,EACb,kBAAkB,EACnB,MAAM,YAAY,CAAC;AAIpB
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,cAAc,EACd,aAAa,EACb,kBAAkB,EACnB,MAAM,YAAY,CAAC;AAIpB;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,OAAO;kBACJ,kBAAkB,GAAG,IAAI;4BAIf,OAAO,YAAY,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;4BAK9D,MAAM,UACP,aAAa,YACX,cAAc,GACvB,OAAO,CAAC,IAAI,CAAC;mBAID,MAAM,GAAG,IAAI;aAInB,OAAO,CAAC,IAAI,CAAC;aAIb,OAAO,CAAC,IAAI,CAAC;CAGvB,CAAC;AAEF,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EACL,0BAA0B,EAC1B,mBAAmB,EACnB,0BAA0B,EAC1B,kBAAkB,GACnB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,uBAAuB,EACvB,+BAA+B,EAC/B,+BAA+B,EAC/B,4BAA4B,GAC7B,MAAM,4BAA4B,CAAC;AAEpC,YAAY,EACV,cAAc,EACd,WAAW,EACX,aAAa,EACb,kBAAkB,GACnB,MAAM,YAAY,CAAC;AAEpB,eAAe,OAAO,CAAC"}
|