@@ -4,8 +4,9 @@ import type { EncodingFormat } from '../types'
44/**
55 * Map codec - handles Maps with any key type (including Uint8Array, bigint, number)
66 * Depending on the encoding format, the map is encoded differently:
7- * - json: Only supports string keys and is represented as an object when encoding.
8- * An exception is thrown upon encountering a non-string key.
7+ * - json: Supports string and bigint keys. The map is represented as an object when encoding.
8+ * Bigint keys are converted to/from strings (e.g., 1n becomes "1").
9+ * An exception is thrown upon encountering an unsupported key type.
910 * - msgpack: Preserves key types and is represented as a Map when encoding.
1011 */
1112export class MapCodec < K , V , KEncoded = K , VEncoded = V > extends Codec < Map < K , V > , Map < KEncoded , VEncoded > | Record < string , VEncoded > > {
@@ -28,7 +29,7 @@ export class MapCodec<K, V, KEncoded = K, VEncoded = V> extends Codec<Map<K, V>,
2829 if ( format === 'msgpack' ) {
2930 return true
3031 }
31- if ( this . keyType !== 'string' ) {
32+ if ( this . keyType !== 'string' && this . keyType !== 'bigint' ) {
3233 throw new Error ( `Map key of type '${ this . keyType } ' is not supported in ${ format } format` )
3334 }
3435 }
@@ -68,7 +69,11 @@ export class MapCodec<K, V, KEncoded = K, VEncoded = V> extends Codec<Map<K, V>,
6869 }
6970
7071 for ( const [ encodedKey , encodedValue ] of entries ) {
71- const key = this . keyCodec . decode ( encodedKey as KEncoded , format )
72+ let keyToDecode = encodedKey as KEncoded
73+ if ( format === 'json' && this . keyType === 'bigint' && typeof encodedKey === 'string' ) {
74+ keyToDecode = BigInt ( encodedKey ) as KEncoded
75+ }
76+ const key = this . keyCodec . decode ( keyToDecode , format )
7277 const val = this . valueCodec . decode ( encodedValue , format )
7378 result . set ( key , val )
7479 }
0 commit comments