Rich-Harris/devalue

`.uneval()` does not handle nested maps properly

BigAB opened this issue · 0 comments

BigAB commented

Though devalue.stringify() appears to work on nested Maps correctly, devalue.uneval() does not handle the references correctly.

From a setup like this:

import * as devalue from 'devalue';

const node1 = { id: 1 };
const node2 = { id: 2 };
const node3 = { id: 3 };

const map = new Map([
  [node1, new Map([
    [node2, 1],
    [node3, 1]
  ])],
  [node2, new Map([
    [node1, 1],
    [node3, 1]
  ])],
  [node3, new Map([
    [node1, 1],
    [node2, 1]
  ])]
]);

const result = devalue.uneval(map);

I would expect a result like (extrapolated from how arrays are handled):

(function(a, b, c){
  a.id=1;
  b.id=2;
  c.id=3;
  return new Map([
    [a, new Map([
      [b, 1],
      [c, 1]
    ])],
    [b, new Map([
      [a, 1],
      [c, 1]
    ])],
    [c, new Map([
      [a, 1],
      [b, 1]
    ])]
  ]);
})({}, {}, {}))

...but instead the result is

new Map([
  [{id:1}, new Map([
    [{id:2},1],
    [{id:3},1]
  ])],
  [{id:2}, new Map([
    [{id:1}, 1],
    [{id:3}, 1]
  ])],
  [{id:3}, new Map([
    [{id:1}, 1],
    [{id:2}, 1]
  ])]
])

Demonstration: https://svelte.dev/repl/771c6728b27240c486c8c6a3fbc9e280?version=3.49.0