Skip to content

Commit 0f69d71

Browse files
authored
Merge pull request #10 from Rich-Harris/minify
Shrink output
2 parents 3bc4211 + d73708c commit 0f69d71

File tree

2 files changed

+28
-15
lines changed

2 files changed

+28
-15
lines changed

src/index.ts

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ const escaped: Record<string, string> = { '<': '\\u003C', '>' : '\\u003E', '/':
55
const objectProtoOwnPropertyNames = Object.getOwnPropertyNames(Object.prototype).sort().join('\0');
66

77
export default function devalue(value: any) {
8-
const repeated = new Map();
9-
const seen = new Set();
8+
const counts = new Map();
109

1110
let n = 0;
1211

@@ -15,12 +14,12 @@ export default function devalue(value: any) {
1514
throw new Error(`Cannot stringify a function`);
1615
}
1716

18-
if (seen.has(thing)) {
19-
repeated.set(thing, getName(n++));
17+
if (counts.has(thing)) {
18+
counts.set(thing, counts.get(thing) + 1);
2019
return;
2120
}
2221

23-
seen.add(thing);
22+
counts.set(thing, 1);
2423

2524
if (!isPrimitive(thing)) {
2625
const type = getType(thing);
@@ -46,11 +45,11 @@ export default function devalue(value: any) {
4645
const proto = Object.getPrototypeOf(thing);
4746

4847
if (
49-
proto !== Object.prototype &&
50-
proto !== null &&
51-
Object.getOwnPropertyNames(proto).sort().join('\0') !== objectProtoOwnPropertyNames
48+
proto !== Object.prototype &&
49+
proto !== null &&
50+
Object.getOwnPropertyNames(proto).sort().join('\0') !== objectProtoOwnPropertyNames
5251
) {
53-
throw new Error(`Cannot stringify arbitrary non-POJOs`);
52+
throw new Error(`Cannot stringify arbitrary non-POJOs`);
5453
}
5554

5655
if (Object.getOwnPropertySymbols(thing).length > 0) {
@@ -62,9 +61,20 @@ export default function devalue(value: any) {
6261
}
6362
}
6463

64+
walk(value);
65+
66+
const names = new Map();
67+
68+
Array.from(counts)
69+
.filter(entry => entry[1] > 1)
70+
.sort((a, b) => b[1] - a[1])
71+
.forEach((entry, i) => {
72+
names.set(entry[0], getName(i));
73+
});
74+
6575
function stringify(thing: any): string {
66-
if (repeated.has(thing)) {
67-
return repeated.get(thing);
76+
if (names.has(thing)) {
77+
return names.get(thing);
6878
}
6979

7080
if (isPrimitive(thing)) {
@@ -107,15 +117,14 @@ export default function devalue(value: any) {
107117
}
108118
}
109119

110-
walk(value);
111120
const str = stringify(value);
112121

113-
if (repeated.size) {
122+
if (names.size) {
114123
const params: string[] = [];
115124
const statements: string[] = [];
116125
const values: string[] = [];
117126

118-
repeated.forEach((name, thing) => {
127+
names.forEach((name, thing) => {
119128
params.push(name);
120129

121130
if (isPrimitive(thing)) {
@@ -196,7 +205,9 @@ function stringifyPrimitive(thing: any) {
196205
if (typeof thing === 'string') return JSON.stringify(thing).replace(unsafe, escape);
197206
if (thing === void 0) return 'void 0';
198207
if (thing === 0 && 1 / thing < 0) return '-0';
199-
return String(thing);
208+
const str = String(thing);
209+
if (typeof thing === 'number') return str.replace(/^(-)?0\./, '$1.');
210+
return str;
200211
}
201212

202213
function getType(thing: any) {

test/test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ describe('devalue', () => {
1414
test('number', 42, '42');
1515
test('negative number', -42, '-42');
1616
test('negative zero', -0, '-0');
17+
test('positive decimal', 0.1, '.1');
18+
test('negative decimal', -0.1, '-.1');
1719
test('string', 'woo!!!', '"woo!!!"');
1820
test('boolean', true, 'true');
1921
test('Number', new Number(42), 'Object(42)');

0 commit comments

Comments
 (0)