Skip to content

Commit ebda69b

Browse files
authored
feat: use serialize and deserialize from v8 api (#7)
1 parent 78d3e44 commit ebda69b

File tree

2 files changed

+59
-15
lines changed

2 files changed

+59
-15
lines changed

README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,20 @@ const orm = await MikroORM.init({
5353
},
5454
});
5555
```
56+
57+
## Serializing
58+
59+
This package uses [`serialize`](https://nodejs.org/api/v8.html#v8serializevalue) and [`deserialize`](https://nodejs.org/api/v8.html#v8deserializebuffer) functions from the Node.js v8 API instead of `JSON.stringify` and `JSON.parse`.
60+
61+
They are inadequate for certain primitive data types like Buffer and Typed Array, as they cannot accurately reproduce same data after serialization.
62+
You can checkout its limitation [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#description).
63+
64+
But, there're still some primitives that `serialize` cannot handle.
65+
66+
- function
67+
- symbol
68+
- any uncopyable data
69+
70+
If you need to serialize these types of data, you should using a custom [serializer](https://mikro-orm.io/docs/serializing#property-serializers) or [custom type](https://mikro-orm.io/docs/custom-types)
71+
72+
If you're in debug mode, you will see JSON stringified data at your console. This is solely for debugging purposes. `serialize` is used for actual cache.

src/RedisCacheAdapter.ts

Lines changed: 42 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
import type { CacheAdapter } from "@mikro-orm/core";
1+
import { serialize, deserialize } from "node:v8";
22
import IORedis from "ioredis";
3+
4+
import type { CacheAdapter } from "@mikro-orm/core";
35
import type { Redis, RedisOptions } from "ioredis";
46

57
export interface BaseOptions {
@@ -67,32 +69,57 @@ export class RedisCacheAdapter implements CacheAdapter {
6769
return `${this.keyPrefix}:${name}`;
6870
}
6971

70-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
71-
async get<T = any>(key: string): Promise<T | undefined> {
72+
async get<T = unknown>(key: string): Promise<T | undefined> {
7273
const completeKey = this._getKey(key);
73-
const data = await this.client.get(completeKey);
74-
this.logDebugMessage(`Get "${completeKey}": "${data}"`);
75-
if (!data) return undefined;
76-
return JSON.parse(data);
74+
const data = await this.client.getBuffer(completeKey);
75+
76+
if (!data) {
77+
this.logDebugMessage(`Get "${completeKey}": "null"`);
78+
return undefined;
79+
}
80+
81+
let deserialized: T;
82+
try {
83+
deserialized = deserialize(data) as T;
84+
} catch (error) {
85+
this.logDebugMessage(`Failed to deserialize data: ${data}`);
86+
return undefined;
87+
}
88+
89+
this.logDebugMessage(
90+
`Get "${completeKey}": "${JSON.stringify(deserialized)}"`
91+
);
92+
93+
return deserialized;
7794
}
7895

7996
async set(
8097
key: string,
81-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
82-
data: any,
98+
data: unknown,
8399
_origin: string,
84100
expiration = this.expiration
85101
): Promise<void> {
86-
const stringData = JSON.stringify(data);
102+
let serialized: Buffer;
103+
try {
104+
serialized = serialize(data);
105+
} catch (error) {
106+
this.logDebugMessage(`Failed to serialize data: ${data}`);
107+
return;
108+
}
109+
87110
const completeKey = this._getKey(key);
88-
this.logDebugMessage(
89-
`Set "${completeKey}": "${stringData}" with cache expiration ${expiration}ms`
90-
);
111+
91112
if (expiration) {
92-
await this.client.set(completeKey, stringData, "PX", expiration);
113+
await this.client.set(completeKey, serialized, "PX", expiration);
93114
} else {
94-
await this.client.set(completeKey, stringData);
115+
await this.client.set(completeKey, serialized);
95116
}
117+
118+
this.logDebugMessage(
119+
`Set "${completeKey}": "${JSON.stringify(
120+
data
121+
)}" with cache expiration ${expiration}ms`
122+
);
96123
}
97124

98125
async remove(name: string): Promise<void> {

0 commit comments

Comments
 (0)