-
Notifications
You must be signed in to change notification settings - Fork 5.4k
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
Expose structured clone as serialization API #7957
Comments
Related to #3557 |
This specifically goes against what Deno is doing, they don't want to provide access to V8 directly like this. You can still send data between instances, workers, but I don't think Deno will have IndexedDB. |
we will, just it is a matter of time. see #1699 |
I suppose the fact that it's V8's structured cloning is just an implementation detail (it doesn't have to be, it just has to be implemented at the level where you have fast and deep access to js internals). Any sort of fast/binary serialization API would satisfy a lot of use cases, when the only alternative is That said, I see the other side of the argument as well.
This only lets you see the "deserialized" half of the object at both ends. Something that gives you access to the serialized half could be useful too. |
That's the root of the problem, providing any access to the "JS internals" results in implementation details one way or another, unless a very carefully setup API is provided. That API likely wouldn't be compatible with other JS runtimes. Yet I'm not sure where the line should be drawn between making an ECMAScript proposal or just asking that Deno provide such access. |
It isn't against what Deno is doing. We need structured cloning working properly before we could consider this though. The challenge is that unless you are doing something with it (like sending it between workers or putting in a db) it doesn't make sense in a runtime isolate. Having it be something that plugins have easy access to though would be more important. |
Ah, my apologies, I had rashly assumed that this would fall under
But by all means, if the need for it exists and it's put under std/ or the Deno namespace. |
I was unsure if it would ever end up on Deno's agenda, but it appears that there's already an issue for it. |
Structured cloning is not a V8 concept... it is an ECMAScript/JavaScript concept, though, like I said, its exposure as a runtime API is "questionable" because it isn't useful from within the isolate. Really useful for "behind the scenes" things like plugins though. |
Actually, that being said... for some of the web APIs that we provide in Deno, it can be useful there... so something on Lines 34 to 36 in 374d433
Which we have to use in streams and potentially other APIs when transferring/cloning objects. |
Yes, precisely what I thought of when I had last commented. Structured cloning is in the ES spec. Yet the requested API asks for raw access to bytes
I doubt V8 even uses raw memory to encode them, but if it does, an API like this would forcefully expose implementation details, although it could be used for rapidly creating your own object by simply modifying the correct bytes. The API exposed would have to be opaque in order to prevent it from leaking implementation, yet if it's opaque then it seems fundamentally useless, as it can't be stored (unless there is a storage mechanism provided by Deno). |
Most of the dynamic languages that JavaScript/Deno is competing with have some kind of clone function, and there has been a lot of demand to add one to browsers over the years. I've frequently wanted to reach for a built-in function to clone basic data structures, but It is unfortunate that none of the browser vendors have moved forward to directly expose structured cloning to users, whatwg/html#793, so there isn't an existing browser interface to follow. But that said, I think that a |
There actually is. You can use MessageChannel to structured clone objects. We just need to implement it. |
@lucacasonato True, and that will be good to have. However, that's only usable asynchronously, and it would be better if it could also be used from normal synchronous functions. As mentioned in the Stack Overflow post, browsers do technically expose the behaviour behind a couple of synchronous interfaces too, but they're both indirect and probably not in-scope for Deno:
(Although per Surma's post on the topic, the History API hack actually performs pretty well in Chrome... 🤔) |
This comment has been minimized.
This comment has been minimized.
@00ff0000red It looks like that repo hasn't been updated in seven years, and the language it's using has become outdated and inconsistent with the specifications it's referencing. I think that looking for consistency/consensus with TC39 or browser vendors would be great, but as far as I can tell there's no sign that any of them are moving this forward. (I'd be happy to be wrong!) |
@jeremyBanks Oops, yes, that is a very valid concern... back to what @lucacasonato suggested, what would be so bad about an asynchronous API? A large amount of Deno's API are already async, and with TLA, it's not that bad. The only concern that I would have regarding using |
@00ff0000red Having an async API (or both |
Hi, I've just published a module for serializing JavaScript data in browsers, Deno, and Node.js alike. It's meant for exchanging data between browsers and servers, but can also be used for structured cloning. Do you guys mind having a look? The module is based on a binary serialization scheme that I created (will upload the specs hopefully next week). The scheme covers all the data types and data structures supported by the Structured Clone Algorithm listed in this MDN page, except Blob, File, FileList. ImageBitmap and ImageData. The scheme also covers the "little" things like primitive wrapper objects, sparse arrays, signed zeros, and circular dependencies. |
Looks like we've got |
I am going to mark this as |
🎉 Excellent, thank you. 🙃 export const structuredClone = <Value extends StructuredClonable>(
value: Value,
): Value => {
// deno-lint-ignore no-explicit-any
const core = (Deno as any).core;
return core.deserialize(core.serialize(value));
};
export type StructuredClonable =
| { [key: string]: StructuredClonable }
| Array<StructuredClonable>
| ArrayBuffer
| ArrayBufferView
| BigInt
| bigint
| Blob
// deno-lint-ignore ban-types
| Boolean
| boolean
| Date
| Error
| EvalError
| Map<StructuredClonable, StructuredClonable>
// deno-lint-ignore ban-types
| Number
| number
| RangeError
| ReferenceError
| RegExp
| Set<StructuredClonable>
// deno-lint-ignore ban-types
| String
| string
| SyntaxError
| TypeError
| URIError; |
FWIW, my PR to the HTML spec to expose |
Superseded by #11539 |
I haven't quite convinced myself this is a good idea, but I think it is and might be worthy of consideration.
Exposing V8's implementation of the structured clone algorithm as an explicit serialization/deserialization API would be useful in a lot of contexts.
As an example: Cloudflare is implementing their transactional storage API by accepting naked js objects as values and serializing them internally with structured clone. Exposing this API would allow a reimplementation in Deno. It could also be used for low overhead storage and sending data between Deno instances.
https://developers.cloudflare.com/workers/runtime-apis/durable-objects#transactional-storage-api (see
put()
)Since this would need to be implemented for
Workers
and/orIndexedDB
anyway, it would add very small API surface area, something like:Obvious downsides:
The text was updated successfully, but these errors were encountered: