@newtalaria/browser 0.1.7 → 0.1.9

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,18 @@
1
+ import { type RrwebEvent } from './segment_buffer.js';
2
+ /** Size diagnostics when segment 0 cannot ship a paint base. */
3
+ export type PaintBaseSizeDetails = {
4
+ segmentEventTypes: number[];
5
+ /** Estimated JSON bytes of the Meta event, if present. */
6
+ metaEstimatedBytes?: number;
7
+ /** Estimated JSON bytes of the FullSnapshot, if present. */
8
+ fullSnapshotEstimatedBytes?: number;
9
+ /** Actual gzip size of FullSnapshot alone, when measured. */
10
+ fullSnapshotCompressedBytes?: number;
11
+ maxUncompressedSegmentBytes: number;
12
+ targetCompressedSegmentBytes: number;
13
+ maxCompressedSegmentBytes: number;
14
+ } & Record<string, unknown>;
15
+ export declare function paintBaseSizeDetails(events: RrwebEvent[], opts?: {
16
+ fullSnapshotCompressedBytes?: number;
17
+ }): PaintBaseSizeDetails;
18
+ //# sourceMappingURL=paint_base_size.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paint_base_size.d.ts","sourceRoot":"","sources":["../../src/replay/paint_base_size.ts"],"names":[],"mappings":"AACA,OAAO,EAML,KAAK,UAAU,EAChB,MAAM,qBAAqB,CAAC;AAE7B,gEAAgE;AAChE,MAAM,MAAM,oBAAoB,GAAG;IACjC,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,0DAA0D;IAC1D,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,4DAA4D;IAC5D,0BAA0B,CAAC,EAAE,MAAM,CAAC;IACpC,6DAA6D;IAC7D,2BAA2B,CAAC,EAAE,MAAM,CAAC;IACrC,2BAA2B,EAAE,MAAM,CAAC;IACpC,4BAA4B,EAAE,MAAM,CAAC;IACrC,yBAAyB,EAAE,MAAM,CAAC;CACnC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE5B,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,UAAU,EAAE,EACpB,IAAI,CAAC,EAAE;IAAE,2BAA2B,CAAC,EAAE,MAAM,CAAA;CAAE,GAC9C,oBAAoB,CAsBtB"}
@@ -53,6 +53,8 @@ export declare class SegmentBuffer {
53
53
  get estimatedBytes(): number;
54
54
  push(event: RrwebEvent): void;
55
55
  hasFullSnapshot(): boolean;
56
+ /** First FullSnapshot still queued (does not remove it). */
57
+ peekFullSnapshot(): RrwebEvent | undefined;
56
58
  /**
57
59
  * Drop leading events until Meta+FullSnapshot (or FullSnapshot alone).
58
60
  * Returns false if no FullSnapshot is present (replay would paint blank).
@@ -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;;;GAGG;AACH,eAAO,MAAM,kBAAkB,SAAU,CAAC;AAC1C;;;GAGG;AACH,eAAO,MAAM,4BAA4B,QAAc,CAAC;AACxD,iFAAiF;AACjF,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"}
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,QAAc,CAAC;AACxD,iFAAiF;AACjF,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,4DAA4D;IAC5D,gBAAgB,IAAI,UAAU,GAAG,SAAS;IAI1C;;;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"}
@@ -17,6 +17,14 @@
17
17
  return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
18
18
  }
19
19
 
20
+ // src/utils/opaque_script_error.ts
21
+ function isOpaqueCrossOriginScriptError(event) {
22
+ const msg = (event.message ?? "").trim();
23
+ if (!/^script error\.?$/i.test(msg)) return false;
24
+ if (event.error instanceof Error) return false;
25
+ return true;
26
+ }
27
+
20
28
  // src/transport/serverpod.ts
21
29
  var ServerpodTransport = class {
22
30
  constructor(options) {
@@ -155,6 +163,10 @@
155
163
  hasFullSnapshot() {
156
164
  return this.events.some((e) => e.type === RRWEB_FULL_SNAPSHOT);
157
165
  }
166
+ /** First FullSnapshot still queued (does not remove it). */
167
+ peekFullSnapshot() {
168
+ return this.events.find((e) => e.type === RRWEB_FULL_SNAPSHOT);
169
+ }
158
170
  /**
159
171
  * Drop leading events until Meta+FullSnapshot (or FullSnapshot alone).
160
172
  * Returns false if no FullSnapshot is present (replay would paint blank).
@@ -384,6 +396,28 @@
384
396
  };
385
397
  }
386
398
 
399
+ // src/replay/paint_base_size.ts
400
+ function paintBaseSizeDetails(events, opts) {
401
+ const meta = events.find((e) => e.type === RRWEB_META);
402
+ const full = events.find((e) => e.type === RRWEB_FULL_SNAPSHOT);
403
+ const details = {
404
+ segmentEventTypes: events.map((e) => e.type),
405
+ maxUncompressedSegmentBytes: SEGMENT_SIZE_BYTES,
406
+ targetCompressedSegmentBytes: TARGET_COMPRESSED_SEGMENT_BYTES,
407
+ maxCompressedSegmentBytes: MAX_COMPRESSED_SEGMENT_BYTES
408
+ };
409
+ if (meta) {
410
+ details.metaEstimatedBytes = estimateJsonBytes(meta);
411
+ }
412
+ if (full) {
413
+ details.fullSnapshotEstimatedBytes = estimateJsonBytes(full);
414
+ }
415
+ if (opts?.fullSnapshotCompressedBytes !== void 0) {
416
+ details.fullSnapshotCompressedBytes = opts.fullSnapshotCompressedBytes;
417
+ }
418
+ return details;
419
+ }
420
+
387
421
  // ../../node_modules/rrweb/dist/rrweb.js
388
422
  var __defProp = Object.defineProperty;
389
423
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
@@ -13925,6 +13959,7 @@
13925
13959
  installGlobalHandlers() {
13926
13960
  if (typeof window === "undefined") return;
13927
13961
  const onError = (event) => {
13962
+ if (isOpaqueCrossOriginScriptError(event)) return;
13928
13963
  const error = event.error instanceof Error ? event.error : new Error(event.message || "window.onerror");
13929
13964
  void this.captureException(error, {
13930
13965
  extra: {
@@ -13968,7 +14003,11 @@
13968
14003
  if (!this.options || !this.transport || !this.replayId) return;
13969
14004
  if (!this.startedOnServer || this.finishedOnServer) return;
13970
14005
  if (!this.prepareBufferForNewReplay()) {
13971
- await this.abortUnusableClip("no_full_snapshot");
14006
+ const leftover = this.buffer.peekFullSnapshot();
14007
+ await this.abortUnusableClip(
14008
+ "no_full_snapshot",
14009
+ paintBaseSizeDetails(leftover ? [leftover] : [])
14010
+ );
13972
14011
  return;
13973
14012
  }
13974
14013
  while (this.buffer.length > 0) {
@@ -14016,9 +14055,21 @@
14016
14055
  }
14017
14056
  const { events, gzip } = fitted;
14018
14057
  if (this.segmentIndex === 0 && !events.some((e) => e.type === RRWEB_FULL_SNAPSHOT)) {
14019
- await this.abortUnusableClip("no_full_snapshot", {
14020
- segmentEventTypes: events.map((e) => e.type)
14021
- });
14058
+ const leftoverFs = this.buffer.peekFullSnapshot();
14059
+ let compressedBytes;
14060
+ if (leftoverFs) {
14061
+ try {
14062
+ compressedBytes = (await compressReplayEvents([leftoverFs])).length;
14063
+ } catch {
14064
+ }
14065
+ }
14066
+ await this.abortUnusableClip(
14067
+ "no_full_snapshot",
14068
+ paintBaseSizeDetails(
14069
+ leftoverFs ? [...events, leftoverFs] : events,
14070
+ { fullSnapshotCompressedBytes: compressedBytes }
14071
+ )
14072
+ );
14022
14073
  return;
14023
14074
  }
14024
14075
  if (this.isErrorClipMode() && this.uploadedCompressedBytes + gzip.length > MAX_ERROR_CLIP_COMPRESSED_BYTES && this.segmentIndex > 0) {
@@ -14070,9 +14121,14 @@
14070
14121
  { type: droppedType }
14071
14122
  );
14072
14123
  if (this.segmentIndex === 0 && droppedType === RRWEB_FULL_SNAPSHOT) {
14073
- await this.abortUnusableClip("oversized_full_snapshot", {
14074
- source: "server_reject"
14075
- });
14124
+ await this.abortUnusableClip(
14125
+ "oversized_full_snapshot",
14126
+ {
14127
+ source: "server_reject",
14128
+ ...paintBaseSizeDetails(events),
14129
+ rejectedCompressedBytes: gzip.length
14130
+ }
14131
+ );
14076
14132
  return;
14077
14133
  }
14078
14134
  continue;
@@ -14121,11 +14177,21 @@
14121
14177
  { type: dropped?.type }
14122
14178
  );
14123
14179
  if (this.segmentIndex === 0 && dropped?.type === RRWEB_FULL_SNAPSHOT) {
14180
+ let compressedBytes;
14181
+ try {
14182
+ compressedBytes = (await compressReplayEvents([dropped])).length;
14183
+ } catch {
14184
+ }
14124
14185
  return {
14125
14186
  events: [],
14126
14187
  gzip: new Uint8Array(),
14127
14188
  abortReason: "oversized_full_snapshot",
14128
- abortDetails: { source: "fit_compressed_prefix" }
14189
+ abortDetails: {
14190
+ source: "fit_compressed_prefix",
14191
+ ...paintBaseSizeDetails(chunk, {
14192
+ fullSnapshotCompressedBytes: compressedBytes
14193
+ })
14194
+ }
14129
14195
  };
14130
14196
  }
14131
14197
  if (chunk.length > 1) {
@@ -14134,11 +14200,24 @@
14134
14200
  return this.takeFittedSegment();
14135
14201
  }
14136
14202
  if (this.segmentIndex === 0 && chunk.some((e) => e.type === RRWEB_FULL_SNAPSHOT) && !fitted.events.some((e) => e.type === RRWEB_FULL_SNAPSHOT)) {
14203
+ const full = chunk.find((e) => e.type === RRWEB_FULL_SNAPSHOT);
14204
+ let compressedBytes;
14205
+ if (full) {
14206
+ try {
14207
+ compressedBytes = (await compressReplayEvents([full])).length;
14208
+ } catch {
14209
+ }
14210
+ }
14137
14211
  return {
14138
14212
  events: [],
14139
14213
  gzip: new Uint8Array(),
14140
14214
  abortReason: "oversized_full_snapshot",
14141
- abortDetails: { source: "fit_dropped_full_snapshot" }
14215
+ abortDetails: {
14216
+ source: "fit_dropped_full_snapshot",
14217
+ ...paintBaseSizeDetails(chunk, {
14218
+ fullSnapshotCompressedBytes: compressedBytes
14219
+ })
14220
+ }
14142
14221
  };
14143
14222
  }
14144
14223
  if (fitted.remainder.length > 0) {