txiki.js icon indicating copy to clipboard operation
txiki.js copied to clipboard

URL.createObjectURL

Open EmixamPP opened this issue 1 year ago • 7 comments

Hey, I would like to ask your help concerning the missing URL.createObjectURL browser feature.

Here's some background, I would like to use the MQTT.js library (https://github.com/mqttjs/MQTT.js), which is compatible with browsers. However, I encountered two problems:

  1. The lib detects whether it's in the browser by checking whether a document variable is defined in the global scope (because it is also compatible with Node.js by using the ws lib instead of "native" WebSocket). Thus I just added:
    Object.defineProperty(globalThis, 'document', {
     enumerable: true,
     get() {
         return globalThis;
     },
     set() {}
    });
    
    in the src/js/polyfills/global.js file
  2. The lib requires the URL.createObjectURL https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL_static and URL.revokeObjectURL https://developer.mozilla.org/en-US/docs/Web/API/URL/revokeObjectURL_static functions

This is where I ask for your help, do you think there is a way to make this feature work in txiki.js?

Here is what I've tried (this is really naïve); I've added:

const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
function generateString(length) {
    let result = '';
    for (let i = 0; i < length; ++i) {
        result += chars.charAt(Math.floor(Math.random() * chars.length));
    }
    return result;
}

URL.createObjectURL = (obj) => {
    const url = generateString(32);
    globalThis[url] = obj;
    return url;
};

URL.revokeObjectURL = (url) => {
    delete globalThis[url];
};

to src/js/polyfills/url.js

After that, the lib does not require additional feature, and even work in some way, but it logs the following error: ReferenceError: could not load '<the random string generated>' - ENOENT: no such file or directory

EmixamPP avatar Apr 09 '24 14:04 EmixamPP

I suspect the problem is that the URL represents a FIle or Blob, and it tries to read the file, which fails with a nu such file error.

Do you know where in mqtt.js the failure occurs?

saghul avatar Apr 09 '24 15:04 saghul

Correct, this is a Blob

EmixamPP avatar Apr 09 '24 15:04 EmixamPP

After further analysis, the generated blob object url is passed as argument to a new Worker(url) object

EmixamPP avatar Apr 10 '24 08:04 EmixamPP

Got it. Looks like txiki.js would need to implement a Blob store so those URLs are mapped to something that other APIs can read.

I see Deno has it, we could borrow some inspiration from there...

saghul avatar Apr 10 '24 09:04 saghul

For reference: https://github.com/saghul/txiki.js/issues/545#issuecomment-2162699222

KaruroChori avatar Jun 13 '24 07:06 KaruroChori

I'm working on a simple solution. I should PR in the coming days. But I would need review/help for sure to improve the quality of the solution.

EmixamPP avatar Jun 13 '24 07:06 EmixamPP

Sure thing!

saghul avatar Jun 13 '24 08:06 saghul