@newtalaria/browser 0.1.1 → 0.1.5

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.
@@ -0,0 +1,35 @@
1
+ import { type RrwebEvent } from './segment_buffer.js';
2
+ export type CompressEvents = (events: RrwebEvent[]) => Promise<Uint8Array>;
3
+ /**
4
+ * Absolute error-clip wall: upload start + afterMs + flush slack.
5
+ * Callers must set this once; later errors must not recompute a later wall.
6
+ */
7
+ export declare function computeErrorClipDeadlineMs(uploadStartedAtMs: number, afterMs: number, slackMs?: number): number;
8
+ /** True when error-clip segment or compressed-byte budget is exhausted. */
9
+ export declare function isErrorClipBudgetExhausted(opts: {
10
+ segmentIndex: number;
11
+ uploadedCompressedBytes: number;
12
+ maxSegments?: number;
13
+ maxBytes?: number;
14
+ }): boolean;
15
+ /**
16
+ * How to handle a segment rejected as oversized.
17
+ * Never re-queue an identical single-event payload (that loops forever).
18
+ */
19
+ export declare function planOversizedRetry(events: RrwebEvent[]): {
20
+ action: 'drop';
21
+ } | {
22
+ action: 'bisect';
23
+ left: RrwebEvent[];
24
+ right: RrwebEvent[];
25
+ };
26
+ /**
27
+ * Binary-search the largest prefix that gzips under the pack target.
28
+ * Remainder is returned for re-queue; null means every event was dropped.
29
+ */
30
+ export declare function fitCompressedPrefix(events: RrwebEvent[], compress: CompressEvents, targetBytes?: number, hardCap?: number): Promise<{
31
+ events: RrwebEvent[];
32
+ gzip: Uint8Array;
33
+ remainder: RrwebEvent[];
34
+ } | null>;
35
+ //# sourceMappingURL=fit_segment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fit_segment.d.ts","sourceRoot":"","sources":["../../src/replay/fit_segment.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,UAAU,EAChB,MAAM,qBAAqB,CAAC;AAE7B,MAAM,MAAM,cAAc,GAAG,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;AAE3E;;;GAGG;AACH,wBAAgB,0BAA0B,CACxC,iBAAiB,EAAE,MAAM,EACzB,OAAO,EAAE,MAAM,EACf,OAAO,SAA4B,GAClC,MAAM,CAER;AAED,2EAA2E;AAC3E,wBAAgB,0BAA0B,CAAC,IAAI,EAAE;IAC/C,YAAY,EAAE,MAAM,CAAC;IACrB,uBAAuB,EAAE,MAAM,CAAC;IAChC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,GAAG,OAAO,CAOV;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,UAAU,EAAE,GACnB;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,UAAU,EAAE,CAAC;IAAC,KAAK,EAAE,UAAU,EAAE,CAAA;CAAE,CAUpF;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,UAAU,EAAE,EACpB,QAAQ,EAAE,cAAc,EACxB,WAAW,SAAkC,EAC7C,OAAO,SAA+B,GACrC,OAAO,CAAC;IACT,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,IAAI,EAAE,UAAU,CAAC;IACjB,SAAS,EAAE,UAAU,EAAE,CAAC;CACzB,GAAG,IAAI,CAAC,CAkCR"}
@@ -1 +1 @@
1
- {"version":3,"file":"privacy.d.ts","sourceRoot":"","sources":["../../src/replay/privacy.ts"],"names":[],"mappings":"AAEA,wEAAwE;AACxE,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAY7C;AAED,wBAAgB,oBAAoB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAI3D"}
1
+ {"version":3,"file":"privacy.d.ts","sourceRoot":"","sources":["../../src/replay/privacy.ts"],"names":[],"mappings":"AAEA,wEAAwE;AACxE,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAY7C;AAED,wBAAgB,oBAAoB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAU3D"}
@@ -1,11 +1,15 @@
1
1
  import type { RrwebEvent } from './segment_buffer.js';
2
2
  export interface RecorderOptions {
3
3
  maskAllInputs: boolean;
4
+ /** Embed accessible stylesheet rules into the snapshot. Default false at resolve time. */
5
+ inlineStylesheet: boolean;
4
6
  blockSelector?: string;
5
7
  onEvent: (event: RrwebEvent) => void;
6
8
  }
7
9
  export interface RecorderHandle {
8
10
  stop: () => void;
11
+ /** Force Meta + FullSnapshot so the next replay has a paint base. */
12
+ takeFullSnapshot: () => void;
9
13
  }
10
14
  export declare function startRecorder(options: RecorderOptions): RecorderHandle;
11
15
  //# sourceMappingURL=recorder.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"recorder.d.ts","sourceRoot":"","sources":["../../src/replay/recorder.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEtD,MAAM,WAAW,eAAe;IAC9B,aAAa,EAAE,OAAO,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;CACtC;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,IAAI,CAAC;CAClB;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,eAAe,GAAG,cAAc,CAmBtE"}
1
+ {"version":3,"file":"recorder.d.ts","sourceRoot":"","sources":["../../src/replay/recorder.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEtD,MAAM,WAAW,eAAe;IAC9B,aAAa,EAAE,OAAO,CAAC;IACvB,0FAA0F;IAC1F,gBAAgB,EAAE,OAAO,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;CACtC;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,qEAAqE;IACrE,gBAAgB,EAAE,MAAM,IAAI,CAAC;CAC9B;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,eAAe,GAAG,cAAc,CA0CtE"}
@@ -4,26 +4,76 @@ export interface RrwebEvent {
4
4
  data: unknown;
5
5
  timestamp: number;
6
6
  }
7
- /** Flush when uncompressed JSON is roughly this large. */
8
- export declare const SEGMENT_SIZE_BYTES = 100000;
7
+ /**
8
+ * Soft uncompressed take size before gzip fitting.
9
+ * Keep in sync with ReplayLimits.maxUncompressedSegmentBytes intent.
10
+ */
11
+ export declare const SEGMENT_SIZE_BYTES = 400000;
12
+ /**
13
+ * Server hard cap — keep in sync with ReplayLimits.maxCompressedSegmentBytes.
14
+ * Restart Serverpod after changing this constant pair.
15
+ */
16
+ export declare const MAX_COMPRESSED_SEGMENT_BYTES: number;
17
+ /** Pack under hard cap minus margin (never disagree with a live 512KiB server). */
18
+ export declare const TARGET_COMPRESSED_SEGMENT_BYTES: number;
19
+ /**
20
+ * Absolute max segments per replay (session / long error mode).
21
+ * Keep in sync with ReplayLimits.maxSegmentsPerReplay.
22
+ */
23
+ export declare const MAX_SEGMENTS_PER_REPLAY = 200;
24
+ /**
25
+ * Error-clip mode: hard segment budget so one heavy page cannot spam ingest.
26
+ */
27
+ export declare const MAX_SEGMENTS_ERROR_CLIP = 12;
28
+ /** Error-clip mode: hard compressed-byte budget for the whole clip. */
29
+ export declare const MAX_ERROR_CLIP_COMPRESSED_BYTES: number;
30
+ /** Slack added to the error-clip wall for in-flight flush. */
31
+ export declare const ERROR_CLIP_FLUSH_SLACK_MS = 5000;
9
32
  /** Periodic flush interval. */
10
33
  export declare const SEGMENT_FLUSH_MS = 5000;
11
34
  /** Keep ~60s of events while buffering (error-only sample path). */
12
35
  export declare const RING_BUFFER_MS = 60000;
13
- /** After an error-sample hit, keep uploading for this long, then finish. */
36
+ /** Cap ring buffer size so one error flush stays bounded. */
37
+ export declare const RING_BUFFER_MAX_BYTES = 1500000;
38
+ /** Default post-error upload window (cheap error clip). */
14
39
  export declare const ERROR_REPLAY_AFTER_MS = 15000;
40
+ /**
41
+ * Hard cap for continuous upload (session sample or error-continue mode).
42
+ * Keep in sync with ReplayLimits.defaultMaxDurationMs on the server.
43
+ */
44
+ export declare const MAX_REPLAY_DURATION_MS: number;
45
+ /** rrweb EventType.FullSnapshot */
46
+ export declare const RRWEB_FULL_SNAPSHOT = 2;
47
+ /** rrweb EventType.Meta */
48
+ export declare const RRWEB_META = 4;
15
49
  export declare class SegmentBuffer {
16
50
  private events;
17
51
  private pendingBytes;
18
52
  get length(): number;
19
53
  get estimatedBytes(): number;
20
54
  push(event: RrwebEvent): void;
21
- /** Drop events older than the ring window (buffer-only mode). */
22
- trimRing(now?: number): void;
55
+ hasFullSnapshot(): boolean;
56
+ /**
57
+ * Drop leading events until Meta+FullSnapshot (or FullSnapshot alone).
58
+ * Returns false if no FullSnapshot is present (replay would paint blank).
59
+ */
60
+ trimToFullSnapshot(): boolean;
61
+ /**
62
+ * Drop events older than the ring window and/or over the byte cap
63
+ * (buffer-only mode). Prefer keeping the newest events.
64
+ */
65
+ trimRing(now?: number, maxBytes?: number): void;
23
66
  shouldFlushBySize(): boolean;
67
+ /**
68
+ * Take a prefix of events whose estimated JSON size is ~maxBytes.
69
+ * Always returns at least one event when the buffer is non-empty (caller
70
+ * must handle a single oversized event).
71
+ */
72
+ takeByEstimatedBytes(maxBytes: number): RrwebEvent[];
24
73
  takeAll(): RrwebEvent[];
25
- /** Re-queue events at the front (failed upload retry). */
74
+ /** Re-queue events at the front (failed upload retry / bisect remainder). */
26
75
  prepend(events: RrwebEvent[]): void;
76
+ clear(): void;
27
77
  peekTimes(): {
28
78
  startedAt: Date;
29
79
  endedAt: Date;
@@ -1 +1 @@
1
- {"version":3,"file":"segment_buffer.d.ts","sourceRoot":"","sources":["../../src/replay/segment_buffer.ts"],"names":[],"mappings":"AAEA,oDAAoD;AACpD,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,OAAO,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,0DAA0D;AAC1D,eAAO,MAAM,kBAAkB,SAAU,CAAC;AAC1C,+BAA+B;AAC/B,eAAO,MAAM,gBAAgB,OAAQ,CAAC;AACtC,oEAAoE;AACpE,eAAO,MAAM,cAAc,QAAS,CAAC;AACrC,4EAA4E;AAC5E,eAAO,MAAM,qBAAqB,QAAS,CAAC;AAE5C,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,YAAY,CAAK;IAEzB,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED,IAAI,cAAc,IAAI,MAAM,CAE3B;IAED,IAAI,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAK7B,iEAAiE;IACjE,QAAQ,CAAC,GAAG,SAAa,GAAG,IAAI;IAYhC,iBAAiB,IAAI,OAAO;IAI5B,OAAO,IAAI,UAAU,EAAE;IAOvB,0DAA0D;IAC1D,OAAO,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,IAAI;IAMnC,SAAS,IAAI;QAAE,SAAS,EAAE,IAAI,CAAC;QAAC,OAAO,EAAE,IAAI,CAAA;KAAE,GAAG,IAAI;IAUtD,OAAO,CAAC,cAAc;CAGvB"}
1
+ {"version":3,"file":"segment_buffer.d.ts","sourceRoot":"","sources":["../../src/replay/segment_buffer.ts"],"names":[],"mappings":"AAEA,oDAAoD;AACpD,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,OAAO,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,eAAO,MAAM,kBAAkB,SAAU,CAAC;AAC1C;;;GAGG;AACH,eAAO,MAAM,4BAA4B,QAAa,CAAC;AACvD,mFAAmF;AACnF,eAAO,MAAM,+BAA+B,QACF,CAAC;AAC3C;;;GAGG;AACH,eAAO,MAAM,uBAAuB,MAAM,CAAC;AAC3C;;GAEG;AACH,eAAO,MAAM,uBAAuB,KAAK,CAAC;AAC1C,uEAAuE;AACvE,eAAO,MAAM,+BAA+B,QAAkB,CAAC;AAC/D,8DAA8D;AAC9D,eAAO,MAAM,yBAAyB,OAAQ,CAAC;AAC/C,+BAA+B;AAC/B,eAAO,MAAM,gBAAgB,OAAQ,CAAC;AACtC,oEAAoE;AACpE,eAAO,MAAM,cAAc,QAAS,CAAC;AACrC,6DAA6D;AAC7D,eAAO,MAAM,qBAAqB,UAAY,CAAC;AAC/C,2DAA2D;AAC3D,eAAO,MAAM,qBAAqB,QAAS,CAAC;AAC5C;;;GAGG;AACH,eAAO,MAAM,sBAAsB,QAAgB,CAAC;AAEpD,mCAAmC;AACnC,eAAO,MAAM,mBAAmB,IAAI,CAAC;AACrC,2BAA2B;AAC3B,eAAO,MAAM,UAAU,IAAI,CAAC;AAE5B,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,YAAY,CAAK;IAEzB,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED,IAAI,cAAc,IAAI,MAAM,CAE3B;IAED,IAAI,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAK7B,eAAe,IAAI,OAAO;IAI1B;;;OAGG;IACH,kBAAkB,IAAI,OAAO;IAc7B;;;OAGG;IACH,QAAQ,CAAC,GAAG,SAAa,EAAE,QAAQ,SAAwB,GAAG,IAAI;IAiBlE,iBAAiB,IAAI,OAAO;IAI5B;;;;OAIG;IACH,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,EAAE;IAyBpD,OAAO,IAAI,UAAU,EAAE;IAOvB,6EAA6E;IAC7E,OAAO,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,IAAI;IAMnC,KAAK,IAAI,IAAI;IAKb,SAAS,IAAI;QAAE,SAAS,EAAE,IAAI,CAAC;QAAC,OAAO,EAAE,IAAI,CAAA;KAAE,GAAG,IAAI;IAUtD,OAAO,CAAC,cAAc;CAGvB"}