Skip to content

Commit 1fb4435

Browse files
feat(json): add support for Symbol serialization and deserialization
1 parent ae78685 commit 1fb4435

File tree

3 files changed

+21
-3
lines changed

3 files changed

+21
-3
lines changed

packages/operators/src/json.test.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ describe('log', () => {
4242
date: new Date(),
4343
url: new URL('https://example.com'),
4444
regexp: /\w/g,
45+
globalSymbol: Symbol.for('foo'),
46+
symbol: Symbol('bar'),
4547
image: readFile('./packages/operators/fixtures/images/test_image.jpg'),
4648
array: [
4749
Promise.resolve('hello world'),
@@ -66,5 +68,7 @@ describe('log', () => {
6668

6769
const deserialized = await lastValueFrom(of(serialized).pipe(deserialize(reviver)));
6870
console.log('DESERIALIZED', deserialized);
71+
72+
console.log((await data).globalSymbol === deserialized.globalSymbol);
6973
});
7074
});

packages/operators/src/json/replacer.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ export const syncReplacer = [
99
{ validator: value => isDate(value), handler: value => value.toISOString() },
1010
{ validator: value => isBigInt(value), handler: value => `${value.toString()}n` },
1111
{ validator: value => isRegExp(value), handler: value => value.toString() },
12+
{ validator: value => isRegExp(value), handler: value => value.toString() },
13+
{ validator: value => isSymbol(value), handler: value => symbolToString(value) },
1214
{ validator: () => true, handler: value => value }
1315
];
1416

@@ -19,3 +21,6 @@ const isURL = value => value?.constructor === URL;
1921
const isDate = value => value?.constructor === Date;
2022
const isBigInt = value => value?.constructor === BigInt;
2123
const isRegExp = value => value?.constructor === RegExp;
24+
const isSymbol = value => value?.constructor === Symbol;
25+
26+
const symbolToString = value => `${Symbol.keyFor(value) && 'g'}${value.toString()}`;

packages/operators/src/json/reviver.js

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export const syncReviver = [
99
{ validator: value => isValidISODateString(value), handler: value => new Date(value) },
1010
{ validator: value => isBigInt(value), handler: value => BigInt(value.slice(0, -1)) },
1111
{ validator: value => isRegExp(value), handler: value => regExpFromString(value) },
12+
{ validator: value => isSymbol(value), handler: value => symbolFromString(value) },
1213
{ validator: () => true, handler: value => value }
1314
];
1415

@@ -24,11 +25,11 @@ const isValidISODateString = value => {
2425
};
2526

2627
const isBigInt = value => value?.constructor === String && /^\d+n$/.test(value);
27-
2828
const isRegExp = value => value?.constructor === String && /^\/.*\/[gimuy]*$/.test(value);
29+
const isSymbol = value => value?.constructor === String && /(\w?)Symbol\((\w+)\)/g.test(value);
2930

30-
const regExpFromString = q => {
31-
const match = q.match(/^\/(.*)\/([gimuy]*)$/);
31+
const regExpFromString = value => {
32+
const match = value.match(/^\/(.*)\/([gimuy]*)$/);
3233
if (!match) return null;
3334
const [, pattern, flags] = match;
3435
try {
@@ -37,3 +38,11 @@ const regExpFromString = q => {
3738
return null;
3839
}
3940
};
41+
42+
const symbolFromString = value => {
43+
const { prefix, name } = /(?<prefix>\w?)Symbol\((?<name>\w+)\)/g.exec(value).groups;
44+
if (prefix === 'g') {
45+
return Symbol.for(name);
46+
}
47+
return Symbol(name);
48+
};

0 commit comments

Comments
 (0)