-
Notifications
You must be signed in to change notification settings - Fork 949
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: deepcopy with structuredClone
over JSON.parse/stringify
#3689
Conversation
You can see this bug with anywidget in Google Colab. import anywidget
import traitlets
class BinaryTextArea(anywidget.AnyWidget):
_esm = """
let decoder = new TextDecoder(), encoder = new TextEncoder();
export function render(view) {
let text = document.createElement("textarea");
text.oninput = () => {
let bytes = encoder.encode(text.value);
view.model.set("text", new DataView(bytes.buffer));
view.model.save_changes();
};
function on_change() {
text.value = decoder.decode(view.model.get("text"));
}
on_change();
view.model.on("change:text", on_change);
view.el.appendChild(text);
}
"""
text = traitlets.Any(b'hello, world').tag(sync=True)
area = BinaryTextArea()
area |
Whow, this is good news. This makes it much better to implement binary support on the front end. I think it would be good to backport this to 7. |
I think it's fine to backport to 7.x. It's definitely backwards compatible, right? Especially with the fallback. |
Updating Galata seems to do the trick for getting rid of this new notification. We had the same in bqplot. |
Visual regression fixed in #3694. Thanks @martinRenou |
Thanks @manzt! |
I know this caused a lot of issues, and I'm very sorry for that. Since anywidget doesn't have the same backward compat requirements, I decided to use |
No need to say sorry, thank you for contributing! The burden of breaking changes rests on the maintainers, we are all responsible. |
structuredClone
is now the preferred way to deeply copy objects in JS. It is widely supported across browsers, minus some edge cases like in Safari web-workers (see the table in the linked documentation).The old
JSON.parse
+JSON.stringify
trick deletes anyDataView
s (without a custom serializer) withinWidgetModel.serialize
, leading to a serious bug when using raw "binary" traitlets. With the{remove,put}_buffers
implementations, extra serializers are not required for transferring binary data. The following example should work without custom serializers but immediately deletestext
value whenthis.model.save_changes()
is called for the first time.