-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
Implement serializable and transferrable web platform APIs #12067
Comments
I don't know if we would need to have have extensions to const denoSerialize = Symbol("Deno.serialize");
const denoDeserialize = Symbol("Deno.deserialize");
class DOMException {
static [denoSeralize](instance) {
// serialize steps that return a v8 serialization
}
static [denoDeseralize](value) {
// returns a hydrated instance from a v8 serialization
}
} And if we put the |
That wouldn't be enough, at least for serializable interfaces, because the serializable platform objects might be deep into the object graph. Edit: Rereading the post above, I see that maybe @kitsonk meant adding custom symbols in addition to creating the object with |
I hadn't but I understand the point better about |
Curious if deep freeze objects can be safely considered as |
User-created objects, whether frozen or not, are automatically serializable (not transferable, which in this context means that the original object is no longer usable after you transfer it, as happens with But this issue is about the web APIs that Deno implements, and how their behavior with the structured clone algorithm doesn't match browsers. For these APIs, browsers do preserve their prototype, as well as associated state – and Deno should do the same. |
So one of the problems with the symbols that @kitsonk suggested is that we need to be able to find the right class when deserializing an object – if you create a subclass of, say, |
A map registry of transferabld prototypes? The only problem with that is they wouldn't have access to private fields, though I believe we don't use them for web platform prototypes, but instead use symbols again. |
Since registering an interface as serializable or transferable is going to be needed either way, why not register it together with (de)serialization functions? Deno.core.registerPlatformInterface({
name: "Blob",
serialize(instance) {
// TODO
},
deserialize(value) {
// TODO
},
// Transferable interfaces would have the `transfer` and `transferRecv` functions.
}); and Doing the serialization based on an object's prototype hierarchy would lead to const fakeBlob = {};
Object.setPrototypeOf(fakeBlob, Blob.prototype);
Deno.core.serialize(fakeBlob); |
We make extensive use of both Workers and |
hited a roadblock b/c |
IMHO, serializable support for |
Hmm, aren't File and blob transferable either? Anyhow if any body wish to build a polyfill for supporting transferring blob and files in a sync manner and also build a fix for cloning blobs with structuralClone today without waiting for Deno to fix it (or just want to support older versions for backward comp.), then i got just the thing for you... i have created As it turns out worker share ObjectURL i(unlike in NodeJS - which is a bug) import { createWorker } from 'https://cdn.jsdelivr.net/gh/jimmywarting/await-sync/mod.js'
const awaitSync = createWorker()
// Create our little util function
const readUrlSync = awaitSync(url => {
const res = await fetch(url)
const ab = await res.arrayBuffer()
return new Uint8Array(ab)
})
// Create a blob
const blob = new Blob(['abc'])
const url = URL.createObjectURL(blob)
// Read it while main thread gets blocked
const uint8array = readUrlSync(url)
// create a copy (clone)
const ab = uint8array.buffer
const copy = new Blob([ab])
// Don't forget to clean up
URL.revokeObjectURL(url)
// should be the same data.
await blob.text() === await copy.text() // true
// send the data in your own (de)serializable format
postMessage({
$blob: {
data: ab,
type: blob.type
}
}, [ ab ]) // Transfer ArrayBuffer instead of copying
// worker.js
onmessage = evt => {
const b = evt.data.$blob
const blob = new Blob([b.data], { type: b.type })
// olé - you have copied a blob over.
} ofc this is really such a inefficient way of copying the hole blob. |
Avoids substantial slowdown caused by host objects with embedder fields. * Depends on: denoland/rusty_v8#1322 * Depends on: denoland/rusty_v8#1324 * Deno bug: denoland/deno#12067
Avoids substantial slowdown caused by host objects with embedder fields. * Depends on: denoland/rusty_v8#1322 * Depends on: denoland/rusty_v8#1324 * Deno bug: denoland/deno#12067
Avoids substantial slowdown caused by host objects with embedder fields. * Depends on: denoland/rusty_v8#1322 * Depends on: denoland/rusty_v8#1324 * Deno bug: denoland/deno#12067
Avoids substantial slowdown caused by host objects with embedder fields. * Depends on: denoland/rusty_v8#1322 * Depends on: denoland/rusty_v8#1324 * Deno bug: denoland/deno#12067
Avoids substantial slowdown caused by host objects with embedder fields. * Depends on: denoland/rusty_v8#1322 * Depends on: denoland/rusty_v8#1324 * Deno bug: denoland/deno#12067
Avoids substantial slowdown caused by host objects with embedder fields. * Depends on: denoland/rusty_v8#1322 * Depends on: denoland/rusty_v8#1324 * Deno bug: denoland/deno#12067
Avoids substantial slowdown caused by host objects with embedder fields. * Depends on: denoland/rusty_v8#1322 * Depends on: denoland/rusty_v8#1324 * Deno bug: denoland/deno#12067
Avoids substantial slowdown caused by host objects with embedder fields. * Depends on: denoland/rusty_v8#1322 * Depends on: denoland/rusty_v8#1324 * Deno bug: denoland/deno#12067
Avoids substantial slowdown caused by host objects with embedder fields. * Depends on: denoland/rusty_v8#1322 * Depends on: denoland/rusty_v8#1324 * Deno bug: denoland/deno#12067
Avoids substantial slowdown caused by host objects with embedder fields. * Depends on: denoland/rusty_v8#1322 * Depends on: denoland/rusty_v8#1324 * Deno bug: denoland/deno#12067
I opened another issue which is effectively this one, noticing the limitation of what can be stored in Deno KV that should/could. I listed the web APIs that should be cloneable, but aren't:
|
This should be easier to implement now with #21358 and its dependencies having landed. |
Deno's implementation of structured serialize currently supports serializing the JS built-in
SharedArrayBuffer
, and transferring the JS built-inArrayBuffer
as well as theMessagePort
web API. With #11823 it will also support serializing the wasm built-inWebAssembly.Module
.But Deno also implements some web APIs that per the spec should be serializable or transferable but aren't in Deno's implementation. In particular,
DOMException
,File
,Blob
andCryptoKey
should be serializable; andReadableStream
,WritableStream
andTransformStream
should be transferable.Implementing this would probably need adding some
Deno.core
API to define serialization and transfer steps, possibly in connection to the existingDeno.core.createHostObject()
. This would also allow refactoring the implementation ofMessagePort
.The text was updated successfully, but these errors were encountered: