dumbmatter / fakeIndexedDB

A pure JS in-memory implementation of the IndexedDB API
Apache License 2.0
563 stars 69 forks source link

File support #102

Open azangru opened 1 month ago

azangru commented 1 month ago

fake-indexeddb seems to support the storage of blobs (https://github.com/dumbmatter/fakeIndexedDB/issues/56); however, if one attempts to store a File, then the file, when retrieved, will be converted into a Blob, and part of its information, such as file name, will be lost.

Example:

require('fake-indexeddb/auto');

const STORE_NAME = 'TEST';
const testId = 'test-id';
const file = new File([
  'hello world!'
], 'file.txt');

console.log('File prototype:', Object.getPrototypeOf(file)); //  Blob [File] { name: [Getter], lastModified: [Getter] }

const request = indexedDB.open("test", 3);
request.onupgradeneeded = function () {
  const db = request.result;
  const store = db.createObjectStore(STORE_NAME);

  store.put({
    title: "My test record",
    file
  }, testId);
}
request.onsuccess = function (event) {
    const db = event.target.result;

    const tx = db.transaction(STORE_NAME);

    tx.objectStore(STORE_NAME).get(testId).addEventListener("success", function (event) {
      const result = event.target.result;
      console.log("RETRIEVED:", result); // prints { title: 'My test record', file: Blob { size: 12, type: '' } }
      console.log('File prototype', Object.getPrototypeOf(result.file)); // the prototype of the file is now Object [Blob]
    });
    tx.oncomplete = function () {
      console.log("All done!");
    };
};
dumbmatter commented 1 month ago

This seems to be because of Node's structuredClone function works. More minimal example:

const file = new File([
  'hello world!'
], 'file.txt');

console.log(Object.getPrototypeOf(file));
console.log(Object.getPrototypeOf(structuredClone(file)));

If you run that in Node, you see the 2nd log is just a Blob rather than a File, but if you run it in a web browser then both are Files.

fake-indexeddb internally uses structuredClone from Node, which does work very similar to the web browser version which is used in the IndexedDB spec, but IIRC there are some minor differences and I guess this is one.

Whether this is a bug in Node or it's intended behavior, I'm not sure, I haven't had a chance to investigate further.

azangru commented 1 month ago

This issue in the Node repo suggests that it may be a Node bug.