11import { jsonEscaper } from '../../../common/jsonEscaper.js' ;
2+ import { jsonSize } from '../../../common/jsonSize.js' ;
23import { TimeHelper } from '../../../common/TimeHelper.js' ;
34import { OverwritingArray } from '../../../dataStructures/OverwritingArray.js' ;
45import { BacktraceAttachment } from '../../../model/attachment/index.js' ;
@@ -20,9 +21,11 @@ export class InMemoryBreadcrumbsStorage implements BreadcrumbsStorage, Backtrace
2021
2122 private _lastBreadcrumbId : number = TimeHelper . toTimestampInSec ( TimeHelper . now ( ) ) ;
2223 private _breadcrumbs : OverwritingArray < Breadcrumb > ;
24+ private _breadcrumbSizes : OverwritingArray < number > ;
2325
2426 constructor ( private readonly _limits : BreadcrumbsStorageLimits ) {
2527 this . _breadcrumbs = new OverwritingArray < Breadcrumb > ( _limits . maximumBreadcrumbs ?? 100 ) ;
28+ this . _breadcrumbSizes = new OverwritingArray < number > ( this . _breadcrumbs . capacity ) ;
2629 }
2730
2831 public getAttachments ( ) : BacktraceAttachment < unknown > [ ] {
@@ -47,26 +50,7 @@ export class InMemoryBreadcrumbsStorage implements BreadcrumbsStorage, Backtrace
4750 * @returns Breadcrumbs JSON
4851 */
4952 public get ( ) : string {
50- const sizeLimit = this . _limits . maximumBreadcrumbsSize ;
51- const breadcrumbs = [ ...this . _breadcrumbs . values ( ) ] ;
52- if ( sizeLimit === undefined ) {
53- return JSON . stringify ( breadcrumbs , jsonEscaper ( ) ) ;
54- }
55-
56- let breadcrumbsSize = 2 ;
57- const breadcrumbsToSubmit : string [ ] = [ ] ;
58- for ( let i = breadcrumbs . length - 1 ; i >= 0 ; i -- ) {
59- const json = JSON . stringify ( breadcrumbs [ i ] , jsonEscaper ( ) ) ;
60- const length = json . length + ( i === 0 ? 0 : 1 ) ; // Add the comma if not first element
61- if ( breadcrumbsSize + length > sizeLimit ) {
62- break ;
63- }
64-
65- breadcrumbsToSubmit . unshift ( json ) ;
66- breadcrumbsSize += length ;
67- }
68-
69- return `[${ breadcrumbsToSubmit . join ( ',' ) } ]` ;
53+ return JSON . stringify ( [ ...this . _breadcrumbs ] , jsonEscaper ( ) ) ;
7054 }
7155
7256 public add ( rawBreadcrumb : RawBreadcrumb ) : number {
@@ -86,6 +70,33 @@ export class InMemoryBreadcrumbsStorage implements BreadcrumbsStorage, Backtrace
8670
8771 this . _breadcrumbs . add ( breadcrumb ) ;
8872
73+ if ( this . _limits . maximumBreadcrumbsSize ) {
74+ const size = jsonSize ( breadcrumb , jsonEscaper ( ) ) ;
75+ this . _breadcrumbSizes . add ( size ) ;
76+
77+ let totalSize = this . totalSize ( ) ;
78+ while ( totalSize > this . _limits . maximumBreadcrumbsSize ) {
79+ this . _breadcrumbs . shift ( ) ;
80+ const removedSize = this . _breadcrumbSizes . shift ( ) ?? 0 ;
81+
82+ // We subtract removedSize plus comma in JSON
83+ totalSize -= removedSize + 1 ;
84+ }
85+ }
86+
8987 return id ;
9088 }
89+
90+ private totalSize ( ) {
91+ let sum = 0 ;
92+ for ( const size of this . _breadcrumbSizes ) {
93+ sum += size ;
94+ }
95+
96+ // Sum of:
97+ // - all breadcrumbs
98+ // - comma count
99+ // - brackets
100+ return sum + Math . max ( 0 , this . _breadcrumbSizes . length - 1 ) + 2 ;
101+ }
91102}
0 commit comments