@@ -70,7 +70,7 @@ export async function serialize(serializationContext: SerializationContext): Pro
70
70
const preloadQrls = new Set < QRLInternal > ( ) ;
71
71
const s11nWeakRefs = new Map < unknown , number > ( ) ;
72
72
let parent : unknown = null ;
73
- const isRootObject = ( ) => depth === 0 ;
73
+ const qrlMap = new Map < string , QRLInternal > ( ) ;
74
74
75
75
const outputArray = ( value : unknown [ ] , writeFn : ( value : unknown , idx : number ) => void ) => {
76
76
$writer$ . write ( '[' ) ;
@@ -168,13 +168,21 @@ export async function serialize(serializationContext: SerializationContext): Pro
168
168
} else if ( isQrl ( value ) ) {
169
169
if ( ! outputAsRootRef ( value ) ) {
170
170
const qrl = qrlToString ( serializationContext , value ) ;
171
- const type = preloadQrls . has ( value ) ? TypeIds . PreloadQRL : TypeIds . QRL ;
172
- if ( isRootObject ( ) ) {
173
- output ( type , qrl ) ;
171
+
172
+ // Since we map QRLs to strings, we need to keep track of this secondary mapping
173
+ const existing = qrlMap . get ( qrl ) ;
174
+ if ( existing ) {
175
+ // We encountered the same QRL again, make it a root
176
+ $addRoot$ ( existing ) ;
177
+ // We need to force because we might be adding the same root again
178
+ if ( outputAsRootRef ( existing , 0 , true ) ) {
179
+ return ;
180
+ }
174
181
} else {
175
- const id = serializationContext . $addRoot$ ( qrl ) ;
176
- output ( type , id ) ;
182
+ qrlMap . set ( qrl , value ) ;
177
183
}
184
+ const type = preloadQrls . has ( value ) ? TypeIds . PreloadQRL : TypeIds . QRL ;
185
+ output ( type , qrl ) ;
178
186
}
179
187
} else if ( isQwikComponent ( value ) ) {
180
188
const [ qrl ] : [ QRLInternal ] = ( value as any ) [ SERIALIZABLE_STATE ] ;
@@ -672,7 +680,8 @@ export function shouldTrackObj(obj: unknown) {
672
680
*/
673
681
( typeof obj === 'string' && obj . length > 1 ) ||
674
682
/** Same reasoning but for bigint */
675
- ( typeof obj === 'bigint' && ( obj > 9 || obj < 0 ) )
683
+ ( typeof obj === 'bigint' && ( obj > 9 || obj < 0 ) ) ||
684
+ isQrl ( obj )
676
685
) ;
677
686
} /**
678
687
* When serializing the object we need check if it is URL, RegExp, Map, Set, etc. This is time
@@ -697,8 +706,5 @@ export function isResource<T = unknown>(value: object): value is ResourceReturnI
697
706
}
698
707
699
708
export const frameworkType = ( obj : any ) => {
700
- return (
701
- ( isObject ( obj ) && ( obj instanceof SignalImpl || obj instanceof Task || isJSXNode ( obj ) ) ) ||
702
- isQrl ( obj )
703
- ) ;
709
+ return obj && ( obj instanceof SignalImpl || obj instanceof Task || isJSXNode ( obj ) ) ;
704
710
} ;
0 commit comments