vscode-javascript-repl-docs icon indicating copy to clipboard operation
vscode-javascript-repl-docs copied to clipboard

Proxying objects?: REPL doesn't play nice with Immer

Open kredati opened this issue 4 years ago • 2 comments

First: thank you for a brilliant extension. I use this all the time, and it makes my life much, much happier.

The issue is this: I've started using Immer to achieve immutability in a codebase. Immer checks that the objects it receives are "immerable," usually meaning that they are "plain" objects (i.e., object literals). The following work in VSCode running the REPL:

import produce from 'immer';

produce([1, 2, 3], draft => { draft.push(4); }); //=> [1, 2, 3, 4]

produce(Object.create(null), draft => { draft.foo = 42; }); //=> [Object: null prototype] { foo: 42 }

However, the following should work. And it does work just fine in Node, and in the command line Node REPL (14.6.0):

produce({}, draft => { draft.foo = 42; }); //=> { foo: 42 }

Using the JavaScript REPL, however, I get the following error when I run that code:

[Immer] produce can only be called on things that are draftable: plain objects, arrays, Map, Set or classes that are marked with '[immerable]: true'. Got '[object Object]'

Of course, I just passed in an empty object literal, a plain object.

I suspect the REPL is modifying the object literal in a way that is triggering this error because it fails some test in Immer. (Immer's source is not very easily navigable; I can dig into the code if you'd like.) Of course, ({}).constructor === Object.

Is the REPL proxying object literals? (But not objects with null prototypes?) Is there something else going on?

And again—thanks for a really, really useful plugin. I've been using it intensively for months and am really delighted by it.

kredati avatar Jul 27 '20 17:07 kredati

Hi, @kredati thank you so much for your feedback, I really appreciate it.

I have reproduced this successfully, so it is a bug!

The JavaScript REPL does not modify the object literal, so I checked the source code of Immer and I am thinking that for some reason the extension maybe fails on this check https://github.com/immerjs/immer/blob/467ea5d3b5d062c084ce6d875f8d77e21f26965c/src/utils/common.ts#L40

Until this bug will be fixed, a solution to your issue is to change the "JavaScript-repl: Context" option in vscode preferences-settings https://github.com/axilleasiv/vscode-javascript-repl-docs/wiki/Configuration#context and use 'Node' instead of the default 'VM'. I have tested your example and it works properly.

Thanks again for you feedback and feel free to post again if you have any issue or question.

axilleasiv avatar Jul 28 '20 00:07 axilleasiv

Thanks for the quick reply. The workaround works on my end. And thanks again for the extension!

kredati avatar Jul 28 '20 03:07 kredati