Skip to content

Commit fefa0a5

Browse files
committed
feat(serdes): dedupe bigint
1 parent 232a303 commit fefa0a5

File tree

2 files changed

+44
-2
lines changed

2 files changed

+44
-2
lines changed

packages/qwik/src/core/shared/serdes/serdes.unit.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -909,6 +909,43 @@ describe('shared-serialization', () => {
909909
});
910910
});
911911

912+
describe('dedupe', () => {
913+
it('should dedupe identical objects/strings', async () => {
914+
const a = { hello: 1 };
915+
const objs = await serialize([
916+
'hello',
917+
'hello',
918+
a,
919+
a,
920+
12345678901234567890n,
921+
12345678901234567890n,
922+
// small bigint are not deduped
923+
9n,
924+
9n,
925+
]);
926+
expect(dumpState(objs)).toMatchInlineSnapshot(`
927+
"
928+
0 Array [
929+
{string} "hello"
930+
RootRef 1
931+
Object [
932+
RootRef 1
933+
{number} 1
934+
]
935+
RootRef 2
936+
BigInt "12345678901234567890"
937+
RootRef 3
938+
BigInt "9"
939+
BigInt "9"
940+
]
941+
1 RootRef "0 0"
942+
2 RootRef "0 2"
943+
3 RootRef "0 4"
944+
(103 chars)"
945+
`);
946+
});
947+
});
948+
912949
describe('Serialization Weak Ref', () => {
913950
const dump = async (...value: any) => dumpState(await serialize(...value));
914951
it('should not serialize object', async () => {

packages/qwik/src/core/shared/serdes/serialize.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,9 @@ export async function serialize(serializationContext: SerializationContext): Pro
155155
if (fastSkipSerialize(value as object | Function)) {
156156
output(TypeIds.Constant, Constants.Undefined);
157157
} else if (typeof value === 'bigint') {
158-
output(TypeIds.BigInt, value.toString());
158+
if (!outputAsRootRef(value)) {
159+
output(TypeIds.BigInt, value.toString());
160+
}
159161
} else if (typeof value === 'boolean') {
160162
output(TypeIds.Constant, value ? Constants.True : Constants.False);
161163
} else if (typeof value === 'function') {
@@ -667,7 +669,10 @@ export function shouldTrackObj(obj: unknown) {
667669
* We track all strings greater than 1 character, because those take at least 6 bytes to encode
668670
* and even with 999 root objects it saves one byte per reference. Tracking more objects makes
669671
* the map bigger so we want to strike a balance
670-
*/ (typeof obj === 'string' && obj.length > 1)
672+
*/
673+
(typeof obj === 'string' && obj.length > 1) ||
674+
/** Same reasoning but for bigint */
675+
(typeof obj === 'bigint' && (obj > 9 || obj < 0))
671676
);
672677
} /**
673678
* When serializing the object we need check if it is URL, RegExp, Map, Set, etc. This is time

0 commit comments

Comments
 (0)