Skip to content
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

URL.createObjectURL #479

Open
EmixamPP opened this issue Apr 9, 2024 · 7 comments
Open

URL.createObjectURL #479

EmixamPP opened this issue Apr 9, 2024 · 7 comments

Comments

@EmixamPP
Copy link

EmixamPP commented Apr 9, 2024

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

@saghul
Copy link
Owner

saghul commented Apr 9, 2024

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?

@EmixamPP
Copy link
Author

EmixamPP commented Apr 9, 2024

Correct, this is a Blob

@EmixamPP
Copy link
Author

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

@saghul
Copy link
Owner

saghul commented Apr 10, 2024

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...

@KaruroChori
Copy link
Contributor

For reference: #545 (comment)

@EmixamPP
Copy link
Author

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.

@saghul
Copy link
Owner

saghul commented Jun 13, 2024

Sure thing!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants