diff --git a/src/RedisStringsHandler.ts b/src/RedisStringsHandler.ts index 494a156..262c4bd 100644 --- a/src/RedisStringsHandler.ts +++ b/src/RedisStringsHandler.ts @@ -2,7 +2,7 @@ import { commandOptions, createClient, RedisClientOptions } from 'redis'; import { SyncedMap } from './SyncedMap'; import { DeduplicatedRequestHandler } from './DeduplicatedRequestHandler'; import { debug } from './utils/debug'; -import { bufferReviver, bufferReplacer } from './utils/json'; +import { bufferAndMapReviver, bufferAndMapReplacer } from './utils/json'; export type CommandOptions = ReturnType; export type Client = ReturnType; @@ -405,7 +405,7 @@ export default class RedisStringsHandler { const cacheEntry: CacheEntry | null = JSON.parse( serializedCacheEntry, - bufferReviver, + bufferAndMapReviver, ); debug( @@ -606,7 +606,10 @@ export default class RedisStringsHandler { tags: ctx?.tags || [], value: data, }; - const serializedCacheEntry = JSON.stringify(cacheEntry, bufferReplacer); + const serializedCacheEntry = JSON.stringify( + cacheEntry, + bufferAndMapReplacer, + ); // pre seed data into deduplicated get client. This will reduce redis load by not requesting // the same value from redis which was just set. diff --git a/src/utils/json.ts b/src/utils/json.ts index fd1e7bc..94e70e1 100644 --- a/src/utils/json.ts +++ b/src/utils/json.ts @@ -1,12 +1,25 @@ // eslint-disable-next-line @typescript-eslint/no-explicit-any -export function bufferReviver(_: string, value: any): any { +export function bufferAndMapReviver(_: string, value: any): any { if (value && typeof value === 'object' && typeof value.$binary === 'string') { return Buffer.from(value.$binary, 'base64'); } + if ( + value && + typeof value === 'object' && + typeof value.$map === 'object' && + !!value.$map + ) { + return new Map( + Object.entries(value.$map).map(([key, value]) => { + const revivedValue = bufferAndMapReviver('', value); + return [key, revivedValue]; + }), + ); + } return value; } // eslint-disable-next-line @typescript-eslint/no-explicit-any -export function bufferReplacer(_: string, value: any): any { +export function bufferAndMapReplacer(_: string, value: any): any { if (Buffer.isBuffer(value)) { return { $binary: value.toString('base64'), @@ -22,5 +35,15 @@ export function bufferReplacer(_: string, value: any): any { $binary: Buffer.from(value.data).toString('base64'), }; } + if (value && typeof value === 'object' && value instanceof Map) { + return { + $map: Object.fromEntries( + Array.from(value.entries()).map(([key, value]) => { + const replacedValue = bufferAndMapReplacer('', value); + return [key, replacedValue]; + }), + ), + }; + } return value; }