Skip to content

Commit 46ee86e

Browse files
committed
WIP parse
1 parent 4c231ac commit 46ee86e

File tree

5 files changed

+121
-26
lines changed

5 files changed

+121
-26
lines changed

src/constants.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
export const UNDEFINED = -1;
2+
export const HOLE = -2;
3+
export const NAN = -3;
4+
export const POSITIVE_INFINITY = -4;
5+
export const NEGATIVE_INFINITY = -5;
6+
export const NEGATIVE_ZERO = -6;

src/parse.js

Lines changed: 89 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,95 @@
1+
import {
2+
HOLE,
3+
NAN,
4+
NEGATIVE_INFINITY,
5+
NEGATIVE_ZERO,
6+
POSITIVE_INFINITY,
7+
UNDEFINED
8+
} from './constants.js';
9+
110
/**
211
* Revive a value serialized with `devalue.stringify`
312
* @param {string} serialized
413
*/
514
export function parse(serialized) {
6-
return 'TODO';
15+
const values = JSON.parse(serialized);
16+
17+
if (typeof values === 'number') return get_value(values);
18+
19+
/** @param {number} index */
20+
function get_value(index) {
21+
if (index === UNDEFINED) return undefined;
22+
if (index === NAN) return NaN;
23+
if (index === POSITIVE_INFINITY) return Infinity;
24+
if (index === NEGATIVE_INFINITY) return -Infinity;
25+
if (index === NEGATIVE_ZERO) return -0;
26+
27+
return values[index];
28+
}
29+
30+
let i = values.length;
31+
while (i--) {
32+
const value = values[i];
33+
34+
if (!value || typeof value !== 'object') continue;
35+
36+
if (Array.isArray(value)) {
37+
if (typeof value[0] === 'string') {
38+
const type = value[0];
39+
40+
switch (type) {
41+
case 'Date':
42+
values[i] = new Date(value[1]);
43+
break;
44+
45+
case 'Set':
46+
const set = new Set();
47+
values[i] = set;
48+
for (let j = 1; j < value.length; j += 1) {
49+
set.add(get_value(value[j]));
50+
}
51+
break;
52+
53+
case 'RegExp':
54+
values[i] = new RegExp(value[1], value[2]);
55+
break;
56+
57+
case 'Object':
58+
values[i] = Object(value[1]);
59+
break;
60+
61+
case 'BigInt':
62+
values[i] = BigInt(value[1]);
63+
break;
64+
65+
case 'null':
66+
const object = Object.create(null);
67+
}
68+
} else {
69+
const array = new Array(value.length);
70+
71+
for (let i = 0; i < value.length; i += 1) {
72+
const n = value[i];
73+
if (n === HOLE) continue;
74+
75+
array[i] = get_value(n);
76+
}
77+
78+
values[i] = array;
79+
}
80+
} else {
81+
/** @type {Record<string, any>} */
82+
const object = {};
83+
84+
for (const key in value) {
85+
const n = value[key];
86+
object[key] = get_value(n);
87+
}
88+
89+
values[i] = object;
90+
}
91+
}
92+
93+
console.log(values);
94+
return values[0];
795
}

src/stringify.js

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,14 @@ import {
55
is_primitive,
66
stringify_string
77
} from './utils.js';
8-
9-
const UNDEFINED = -1;
10-
const HOLE = -2;
11-
const NAN = -3;
12-
const POSITIVE_INFINITY = -4;
13-
const NEGATIVE_INFINITY = -5;
14-
const NEGATIVE_ZERO = -6;
8+
import {
9+
HOLE,
10+
NAN,
11+
NEGATIVE_INFINITY,
12+
NEGATIVE_ZERO,
13+
POSITIVE_INFINITY,
14+
UNDEFINED
15+
} from './constants.js';
1516

1617
/**
1718
* Turn a value into a JSON string that can be parsed with `devalue.parse`
@@ -156,7 +157,7 @@ export function stringify(value) {
156157
const index = flatten(value);
157158

158159
// special case — value is represented as a negative index
159-
if (index < 0) return `[${index}]`;
160+
if (index < 0) return `${index}`;
160161

161162
return `[${stringified.join(',')}]`;
162163
}

test/test.js

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ const fixtures = {
2121
name: 'negative zero',
2222
value: -0,
2323
js: '-0',
24-
json: '[-6]'
24+
json: '-6'
2525
},
2626
{
2727
name: 'positive decimal',
@@ -69,7 +69,7 @@ const fixtures = {
6969
name: 'undefined',
7070
value: undefined,
7171
js: 'void 0',
72-
json: '[-1]'
72+
json: '-1'
7373
},
7474
{
7575
name: 'null',
@@ -81,13 +81,13 @@ const fixtures = {
8181
name: 'NaN',
8282
value: NaN,
8383
js: 'NaN',
84-
json: '[-3]'
84+
json: '-3'
8585
},
8686
{
8787
name: 'Infinity',
8888
value: Infinity,
8989
js: 'Infinity',
90-
json: '[-4]'
90+
json: '-4'
9191
},
9292
{
9393
name: 'RegExp',
@@ -342,17 +342,17 @@ for (const [name, tests] of Object.entries(fixtures)) {
342342
test.run();
343343
}
344344

345-
// for (const [name, tests] of Object.entries(fixtures)) {
346-
// const test = uvu.suite(`parse: ${name}`);
347-
// for (const t of tests) {
348-
// test(t.name, () => {
349-
// const actual = parse(t.json);
350-
// const expected = t.value;
351-
// assert.equal(actual, expected);
352-
// });
353-
// }
354-
// test.run();
355-
// }
345+
for (const [name, tests] of Object.entries(fixtures)) {
346+
const test = uvu.suite(`parse: ${name}`);
347+
for (const t of tests) {
348+
test(t.name, () => {
349+
const actual = parse(t.json);
350+
const expected = t.value;
351+
assert.equal(actual, expected);
352+
});
353+
}
354+
test.run();
355+
}
356356

357357
for (const fn of [devalue, stringify]) {
358358
uvu.test(`${fn.name} throws for non-POJOs`, () => {

tsconfig.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@
99
"diagnostics": true,
1010
"noImplicitThis": true,
1111
"noEmitOnError": true,
12-
"lib": ["es5", "es6", "dom"]
12+
"lib": ["es2022"],
13+
"target": "es2022"
1314
},
14-
"target": "ES2018",
1515
"module": "ES6",
1616
"include": ["index.js", "src/*.js"],
1717
"exclude": ["node_modules"]

0 commit comments

Comments
 (0)