Closed StrangeBytesDev closed 4 weeks ago
Thanks for checking out my project! And yes it's fairly easy to do so using the Worker threads API. Here's a very simple example to demonstrate that,
index.ts
const server = Bun.serve({
fetch() {
return new Response(`Hello from Bun v${Bun.version}!`);
}
});
const worker = new Worker("./webview.ts");
worker.addEventListener("close", () => server.stop(true));
webview.ts
import { Webview } from "webview-bun";
const webview = new Webview();
webview.navigate("http://localhost:3000/");
webview.run();
Compiling the above example into a single executable will also work just fine.
Please re-open this issue. That code won't actually work compiled. In your example, webview.ts isn't included in the compiled binary. You would need to use something like Bun's embed to get the webview.ts file to actually be included for it to work.
const server = Bun.serve({
fetch() {
return new Response(`Hello from Bun v${Bun.version}!`);
}
});
import workerFile from './webview.ts' with {type: 'file'}
const worker = new Worker(URL.createObjectURL(Bun.file(workerFile)))
worker.addEventListener("close", () => server.stop(true));
But embeded workers cannot run any imports, which is why the repo I linked above exists as a proof of concept to get Webview's working in worker threads. As is, I can't come up with any way to run webview-bun without blocking the main thread.
Compiling the above example into a single executable will also work just fine.
I obviously wrote this only after I actually tried compiling it.
Note that you can also inline file as a blob content as told here https://bun.sh/docs/api/workers#blob-urls
Compiling the above example into a single executable will also work just fine.
I obviously wrote this only after I actually tried compiling it.
If you're just compiling it into the same folder where the source files exist it will appear to work fine. But as soon as you try and run it from anywhere else it will not work.
Oh you're right, reopening.
So far the closest thing I have to a working solution is to combine ffi.ts and webview.ts into a single file plus the actual setup code for the webview, embed that, and then run it with "node:worker_threads" rather than Bun's builtin Worker api. That approach won't embed the webview libraries though, so I was only able to make it work using the WEBVIEW_PATH env var approach. If you could embed the webview libraries from the main process and access them from the worker, you could probably get to a clean solution. Documentation on how the virtual filesystem works for embedding is pretty sparse though and I couldn't figure out a way to make that work.
@StrangeBytesDev this is actually tricky to get right, and I haven't got yet a good, reusable solution.
The problem is that you can only load an so
etc. as a compile-time binary (with { type: "file" }
) and pass its URL to the worker, having the worker make a BunFile out of it inside its event, such that it can dynamically be passed to dlopen
(as seen in https://github.com/primatejs/worker-bin).
In contrast, you cannot, at least currently, do the same for a JS import. This results in a silent failure inside the worker. Not being able to do it inside the worker means you cannot import the JS from elsewhere, in particular from another package such as this one. So no reusability.
As long as this isn't resolved, the usefulness of webview without worker support in Bun/Deno/Node in general is questionable... unless of course you're willing to vendor the logic into your own project, as unfortunately I'm forced to do now.
Please also note that even in its current state (vendoring the webview logic), this doesn't work on Mac x64 yet, see https://github.com/oven-sh/bun/issues/11959. If you're able to test it on Mac Arm and provide feedback in that issue, it would be helpful to delineate that problem, namely if it's just a Mac x64 or a general Mac problem.
@StrangeBytesDev FYI, @rcompat/webview
just added support for compiling with workers (just Bun, Deno/Node support will follow later):
// detect current platform
import Webview from "@rcompat/webview/worker";
// or cross-compile
// import Webview from "@rcompat/webview/worker/windows-x64";
// start server
Bun.serve({ port: 6161, fetch: () => new Response("hi") });
const webview = new Webview();
webview.navigate("http://localhost:6161");
webview.run();
@tr1ckydev feel free to reuse any code from @rcompat/webview
to resolve this issue, it's MIT-licensed.
@terrablue Interesting work 👏! I'll definitely check it out. Im too trying to find some other easier way to do it. If you are on bun discord, you can find my progress in the showcase channel for webview-bun.
Fixed in Bun v1.1.25. https://bun.sh/blog/bun-v1.1.25#worker-in-standalone-executables
FYI, Bun 1.1.25 did not really fix the accompanying Mac issue: it is still impossible to run a webview from within a worker, on Mac. 1.1.25 only made importing in worker files easier, but I wouldn't consider this issue done until Bun fixes https://github.com/oven-sh/bun/issues/11959, or a workaround is found.
Currently webview.run() blocks the main thread, which limits your ability to run any kind of backend code, like a web server. Additionally, this currently doesn't work in a Worker script, although there is potentially a solution to this implemented here: https://github.com/primatejs/worker-bin
If it was possible to either run without block main or in a Worker, it'd make this much more useful for developing full on applications. I'm currently experimenting with using alternative methods for running the webview outside of the main thread, like node's worker_threads. I'll report back if I get anything working.
(Thanks for the great work on this! I'm extremely excited to use this in applications.)