w3c / FileAPI

File API
https://w3c.github.io/FileAPI/
Other
104 stars 44 forks source link

Async factory methods for Blob and File #157

Open pwnall opened 3 years ago

pwnall commented 3 years ago

Blob and File objects are currently created using the Blob constructor and File constructor. While this is very intuitive, the synchronous aspect of the creation makes it difficult to integrate these object with modern storage systems.

Motivation

Here are two concrete problems I'm trying to address.

1) I would like Blobs and Files to be quota-managed. This means we'd charge them against the origin's quota, and error out if creating a Blob / File would drive the origin out of quota. In Chrome, computing the origin's quota usage is an expensive operation the first time we do it, so having to do it synchronously during Blob / File creation would be quite unfortunate.

Background: In Chrome, Blobs and Files objects can store more data than would fit in RAM. This is accomplished by spilling the content to disk when needed. Since they write to disk

2) In Chrome, Blobs and Files need to be registered in a browser-global registry, in order to serve requests to blob:// URLs. This is currently done by invoking a synchronous IPC in the Blob and File constructors.

Alternative: This problem might also be addressed by migrating to an asynchronous flavor of URL.createObjectURL(), and having Blobs and Files added to the registry on-demand. I think this leads to more implementation complexity, and doesn't address the desire of charging Blobs and Files against quota.

Proposed solution

Let's add create factory methods to Blob and File. The factor methods will take the same parameters as the corresponding constructors, and will return Promise<Blob> and Promise<File>.

const blob = await Blob.create(["Message text."], { type: "text/plain" });
const file = await File.create(
    ["Attachment data"], "attachment.txt",
    { type: "text/plain", lastModified: Date.now() });
domenic commented 3 years ago

I'm confused. Why would web developers ever use these async factories instead of using the existing sync ones?

mkruisselbrink commented 3 years ago

I think the difference would be that with the sync constructors you wouldn't know if construction failed; you'd only get an error as soon as something tries to read from the blob (that's already how it works today in chrome; blob construction can already fail). While with these async factories you could detect and handle these errors sooner. While I agree that most developers probably wouldn't care/bother, it does seem like some subset of developers would probably like to be able to detect these kinds of errors.

annevk commented 3 years ago

Are these kind of blobs you cannot read from defined properly? Does their existence mean we could bring back close() and some kind of promise-returning status getter?

mkruisselbrink commented 3 years ago

https://github.com/w3c/FileAPI/pull/154 is trying to define "blobs you can't read from" properly. Although not specifically these blobs. Some kind of status getter might make sense (especially for things like IDB, file and cache storage backed blobs that can start out readable, and later become unreadable). Not sure about close; or at least close with any guarantees on effects on quota, memory usage etc.