@@ -137,6 +137,9 @@ import binaryToComparableString from 'shared/binaryToComparableString';
137137
138138import { SuspenseException , getSuspendedThenable } from './ReactFlightThenable' ;
139139
140+ // DEV-only set containing internal objects that should not be limited and turned into getters.
141+ const doNotLimit : WeakSet < Reference > = __DEV__ ? new WeakSet() : (null: any);
142+
140143function defaultFilterStackFrame(
141144 filename: string,
142145 functionName: string,
@@ -2153,6 +2156,22 @@ function serializeConsoleMap(
21532156) : string {
21542157 // Like serializeMap but for renderConsoleValue.
21552158 const entries = Array . from ( map ) ;
2159+ // The Map itself doesn't take up any space but the outlined object does.
2160+ counter . objectLimit ++ ;
2161+ for ( let i = 0 ; i < entries . length ; i ++ ) {
2162+ // Outline every object entry in case we run out of space to serialize them.
2163+ // Because we can't mark these values as limited.
2164+ const entry = entries [ i ] ;
2165+ doNotLimit . add ( entry ) ;
2166+ const key = entry [ 0 ] ;
2167+ const value = entry [ 1 ] ;
2168+ if ( typeof key === 'object' && key !== null ) {
2169+ doNotLimit . add ( key ) ;
2170+ }
2171+ if ( typeof value === 'object' && value !== null ) {
2172+ doNotLimit . add ( value ) ;
2173+ }
2174+ }
21562175 const id = outlineConsoleValue ( request , counter , entries ) ;
21572176 return '$Q' + id . toString ( 16 ) ;
21582177}
@@ -2164,6 +2183,16 @@ function serializeConsoleSet(
21642183) : string {
21652184 // Like serializeMap but for renderConsoleValue.
21662185 const entries = Array . from ( set ) ;
2186+ // The Set itself doesn't take up any space but the outlined object does.
2187+ counter . objectLimit ++ ;
2188+ for ( let i = 0 ; i < entries . length ; i ++ ) {
2189+ // Outline every object entry in case we run out of space to serialize them.
2190+ // Because we can't mark these values as limited.
2191+ const entry = entries [ i ] ;
2192+ if ( typeof entry === 'object' && entry !== null ) {
2193+ doNotLimit . add ( entry ) ;
2194+ }
2195+ }
21672196 const id = outlineConsoleValue ( request , counter , entries ) ;
21682197 return '$W ' + id . toString ( 16 ) ;
21692198}
@@ -3376,20 +3405,15 @@ function renderConsoleValue(
33763405 parentPropertyName : string ,
33773406 value : ReactClientValue ,
33783407) : ReactJSONValue {
3379- // Make sure that `parent[parentPropertyName]` wasn't JSONified before `value` was passed to us
3380- // $FlowFixMe[incompatible-use]
3381- const originalValue = parent [ parentPropertyName ] ;
3382- if (
3383- typeof originalValue === 'object' &&
3384- originalValue !== value &&
3385- ! ( originalValue instanceof Date )
3386- ) {
3387- }
3388-
33893408 if ( value === null ) {
33903409 return null ;
33913410 }
33923411
3412+ // Special Symbol, that's very common.
3413+ if ( value === REACT_ELEMENT_TYPE ) {
3414+ return '$ ';
3415+ }
3416+
33933417 if ( typeof value === 'object' ) {
33943418 if ( isClientReference ( value ) ) {
33953419 // We actually have this value on the client so we could import it.
@@ -3421,7 +3445,7 @@ function renderConsoleValue(
34213445 return existingReference ;
34223446 }
34233447
3424- if ( counter . objectLimit <= 0 ) {
3448+ if ( counter . objectLimit <= 0 && ! doNotLimit . has ( value ) ) {
34253449 // We've reached our max number of objects to serialize across the wire so we serialize this
34263450 // as a marker so that the client can error when this is accessed by the console.
34273451 return serializeLimitedObject ( ) ;
@@ -3441,13 +3465,12 @@ function renderConsoleValue(
34413465 if ( element . _debugStack != null ) {
34423466 // Outline the debug stack so that it doesn't get cut off.
34433467 debugStack = filterStackTrace ( request , element . _debugStack , 1 ) ;
3444- const stackId = outlineConsoleValue (
3445- request ,
3446- { objectLimit : debugStack . length + 2 } ,
3447- debugStack ,
3448- ) ;
3449- request . writtenObjects . set ( debugStack , serializeByValueID ( stackId ) ) ;
3468+ doNotLimit . add ( debugStack ) ;
3469+ for ( let i = 0 ; i < debugStack . length ; i ++ ) {
3470+ doNotLimit . add ( debugStack [ i ] ) ;
3471+ }
34503472 }
3473+ doNotLimit . add ( element . props ) ;
34513474 return [
34523475 REACT_ELEMENT_TYPE ,
34533476 element . type ,
@@ -3592,6 +3615,9 @@ function renderConsoleValue(
35923615 if ( typeof value === 'string' ) {
35933616 if ( value [ value . length - 1 ] === 'Z' ) {
35943617 // Possibly a Date, whose toJSON automatically calls toISOString
3618+ // Make sure that `parent[parentPropertyName]` wasn't JSONified before `value` was passed to us
3619+ // $FlowFixMe[incompatible-use]
3620+ const originalValue = parent [ parentPropertyName ] ;
35953621 if ( originalValue instanceof Date ) {
35963622 return serializeDateFromDateJSON ( value ) ;
35973623 }
@@ -3680,6 +3706,11 @@ function outlineConsoleValue(
36803706 ) ;
36813707 }
36823708
3709+ if ( typeof model === 'object' && model !== null ) {
3710+ // We can't limit outlined values.
3711+ doNotLimit . add ( model ) ;
3712+ }
3713+
36833714 function replacer (
36843715 this :
36853716 | { + [ key : string | number ] : ReactClientValue }
0 commit comments