Skip to content
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

structuredClone and jsdom #88

Closed
joshkel opened this issue Oct 16, 2023 · 7 comments
Closed

structuredClone and jsdom #88

joshkel opened this issue Oct 16, 2023 · 7 comments

Comments

@joshkel
Copy link
Contributor

joshkel commented Oct 16, 2023

I noticed that fakeIndexedDB 5.0 removes its structuredClone polyfill, since structuredClone is provided by Node 18, and fakeIndexedDB now depends on Node 18. However, as I understand it, a major use case of fakeIndexedDB is to simulate IndexedDB within jsdom (as used by, e.g., Jest), and jsdom does not implement structuredClone. (See jsdom/jsdom#3363.)

Therefore, the removal of structuredClone may be premature?

I realize that this change may be completely intended (because workarounds are available - users of fakeIndexedDB can polyfill structuredClone themselves within their jsdom environments, as discussed in jsdom/jsdom#3363); if so, feel free to close this issue.

Thank you.

@dumbmatter
Copy link
Owner

Hm I didn't realize that about jsdom. I figured since it's in all the browsers and Node.js, then it'd be everywhere.

Annoying jsdom users is bad. But it's also nice to have no dependencies.

I wonder how many people are using this with jsdom vs without, that would make it more clear what the best decision is. Maybe for now I will leave this issue open and see if other people are affected.

And to save people the trouble of reading the jsdom issue for workarounds, seems that you can just add this above your fake-indexeddb import:

import 'core-js/stable/structured-clone';

@dethstrobe
Copy link

I just implemented a workaround...which I've had to do a few times for JSDOM now.

In your jest.config you'll need to point the testEnvironment to local file.

Then you'll need to extends JSDOMEnvironment and add the node implementation for structuredClone to the JSDOM environment in the constructor.

Something like this:

import JSDOMEnvironment from "jest-environment-jsdom"

export default class FixJSDOMEnvironment extends JSDOMEnvironment {
  constructor(...args: ConstructorParameters<typeof JSDOMEnvironment>) {
    super(...args)

    this.global.structuredClone = structuredClone
  }
}

For a real world example, you can see my implementation in my project OMA3.

FixJSDOMEnvironment.ts
jest.config.js

@jamesgpearce
Copy link

Yep, this just broke tests for me (Jest, jsdom, 5.0). Nice workaround though, thanks! Guessing you'll probably get a few more reports of this though.

@j-mew-s
Copy link

j-mew-s commented Oct 20, 2023

This broke tests for us

@dumbmatter
Copy link
Owner

I added the above workarounds to README.md, I think that is good enough to close this issue. Although feel free to comment if you think I'm wrong!

@jamesgpearce
Copy link

By the way this now seems to mean that objects returned are null-prototyped, which I don't think the real IndexedDB objects technically are. No big deal unless (like me!) your isObject code wasn't smart enough to allow those.

@dumbmatter
Copy link
Owner

dumbmatter commented Oct 30, 2023

@jamesgpearce I tried this code:

import realisticStructuredClone from "realistic-structured-clone";

const x = {foo: 5};
const y = Object.create(null);
y.foo = 5;

console.log(Object.getPrototypeOf(x));
console.log(Object.getPrototypeOf(structuredClone(x)));
console.log(Object.getPrototypeOf(realisticStructuredClone(x)));
console.log(Object.getPrototypeOf(y));
console.log(Object.getPrototypeOf(structuredClone(y)));
console.log(Object.getPrototypeOf(realisticStructuredClone(y)));

And got this output:

[Object: null prototype] {}
[Object: null prototype] {}
[Object: null prototype] {}
null
[Object: null prototype] {}
[Object: null prototype] {}

So it seems the old (realisticStructuredClone) and new (structuredClone) are both doing the same thing to the prototype, which actually results in losing the null prototype when cloning.

If you think you're possibly seeing a bug, please create another issue with more info :)

dlech added a commit to pybricks/pybricks-code that referenced this issue Nov 18, 2023
dlech added a commit to pybricks/pybricks-code that referenced this issue Nov 18, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants