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

Webui as an interlanguage adapter to the js ecosystem and browser capabilities. #128

Closed
delphius opened this issue Jun 29, 2023 · 13 comments

Comments

@delphius
Copy link

I have been working with webui for some time, using it for its intended purpose, as the output of the program interface. Recently, I have discovered that using a browser (we understand that in fact this is not just a form for the output of our program and user input, but the full power of modern browsers hidden under the hood) I solve problems that are solved with difficulties or not solved at all in the native programming language. From the latter - html parsing and xpath extraction, it turned out to be elementary to solve on the browser side, while the cumbersome bundle on the native side: the language - library wrapper to webdriver - webdriver itself (hello, Selenium) - browser - and the same difficult road in the opposite direction, was replaced by a couple of functions on js, directly related to language via webui.
Hence the question, since, it is already obvious, webui is not just a form for output, but a full-fledged step towards seamless interlanguage interaction, it would be logical to implement the possibility of either headless launching of a browser instance with all the capabilities of webui or just a hidden browser window so that you can use your programs with ordinary forms or in simple ones console applications, use the capabilities of libraries on js and the browser itself via webui, without using the browser's capabilities as a form of interface output and user data input

@AlbertShown
Copy link
Contributor

I agree with you. It will be helpful to have this feature. But it's not possible. I think web browsers do not allow running hidden, even with OS APIs.

The issue is when the Application runs the web browser in a hidden mode window, The web browser first process may start hidden... but it runs another detached new process in normal shown mode.

@delphius
Copy link
Author

delphius commented Jun 30, 2023

I think web browsers do not allow running hidden

And what about Headless Mode?

Headless browser

Thus, you will need to add a startup parameter to the _webui_browser_start_chrome function...

sprintf(arg, " --user-data-dir="%s" --no-first-run --disable-gpu --disable-software-rasterizer --no-proxy-server --safe-mode --disable-extensions --disable-background-mode --disable-plugins --disable-plugins-discovery --disable-translate --bwsi --disable-sync --disable-sync-preferences %s --app=", win->profile_path, kiosk_arg);

  • --headless

I understand that this changes the mode of interaction with the browser, but is it not critical?

@AlbertShown
Copy link
Contributor

This is great! Thank you @delphius 👍

We should add --headless by a new public API webui_set_hidden():

webui_set_hidden(_webui_window_t* win, bool status) {
    // Set {win->hidden_mode} = {status}
}

_webui_get_browser_args {
    // Add
    if (win->hidden_mode)
            c += sprintf(buffer + c, " %s", "--headless");
}

@petabyt, @JOTSR, What do you think guys?

@JOTSR
Copy link
Contributor

JOTSR commented Jul 14, 2023

I think that implementing headless mode to webui is a very good idea, apart from interlanguage issue I thinking on implementing tests and to also provide end users to tests their app without rendering interface.

For the interoperability between js and other languages I think it can be interesting in some specific cases when all browsers API are necessary or an UI is needed in some point. However, I think that solution like Deno already provides better solution as it support almost all major browser API, natively typescript, comes with all in one toolchain and support FFI and wasm. Thinking of browser to solve this is debatable knowing that the memory footprint and startup time are bigger, and as you don't control which JS VM and browser API will be used and disponible you have to add boilerplate polyfill and checks.

Using headless mode make me think of BroadcastChannel that share memory between tabs without putting hight pressure on webui websocket, maybe there is something to investigate.

@AlbertShown
Copy link
Contributor

I guess if WebUI can provide a browser headless mode + full TypeScript support that will be very helpful in many projects. Combining Deno FFI and Browser headless mode will give better results.

@JOTSR
Copy link
Contributor

JOTSR commented Jul 17, 2023

It can be useful but currently the bridge loading is not suited for wroking with js module (<script type="module"> block webui injection through globalThis due to scope isolation) and html size is very limited (webui_show crash for too big string).

  • An interresting point would be to port webui on android (and iphone).
  • Maybe a std lib or plugins can also be added in the future and provides cross language API either by FFI or TS.
  • Also, a way to call WASM from any language through the browser can be very useful for interoperability.
  • As browser support WebGPU it provides a cross architecture GPU API and their is maybe future work arround it.

@AlbertShown
Copy link
Contributor

An interresting point would be to port webui on android (and iPhone).

How? Apps can use the native mobile OS web-view with no issue

Maybe a std lib or plugins can also be added in the future and provides cross language API either by FFI or TS

Yep, that's sound possible

Also, a way to call WASM from any language through the browser can be very useful for interoperability
As browser support WebGPU it provides a cross architecture GPU API and their is maybe future work arround it

If we do this in a 480Kb lib, that will be fantastic honestly!

@AlbertShown
Copy link
Contributor

webui_show crash for too big string

I will investigate into this

@JOTSR
Copy link
Contributor

JOTSR commented Jul 17, 2023

webui_show crash for too big string

I will investigate into this

It would be great, I'm trying to port my Deno module Deplot on webui (instead of webview) but as soon as I charge Plotly (3.6 Mo even so) the internal webui server stops.

How? Apps can use the native mobile OS web-view with no issue

Building a cross plateform app could be an advantage. No need to change framework depending of the targetted device. But it just an idea as I don't know the complexity and even the possibility to launch a browser with custom config on these systems.

If we do this in a 480Kb lib, that will be fantastic honestly!

As WASM and WebGPU are embedded into the browser it is only for adding a gateway to the JS API. The idea is to provides some very useful and critical browser API directly to the end user without requiring to setup is own js bridge. So, it is more a feat to add in last as a plus.

@AlbertShown
Copy link
Contributor

soon as I charge Plotly (3.6 Mo even so) the internal webui server stops.

Did you try to increase WEBUI_MAX_BUF?

#define WEBUI_MAX_BUF (1024000) // 1024 Kb max dynamic memory allocation

1024000 = 1 MB
4096000 = 4 MB

If 4096000 works, then we should increase the limit in the repo as many other users may have bigger strings too.

@JOTSR
Copy link
Contributor

JOTSR commented Jul 17, 2023

Yes it solves the problem but maybe there is some performance issue to investigate as datas are allocating in user code then in webui and finally in browser. In a first time it could be a good idea but maybe a way to let the end user to specify memory constraints or allocations needs.

As webui serves ressources only internaly and don't allow url navigation, a new API to extends internal served url can reduce backpressure on device memory.

Example something like:

void webui_map_url(size_t window, char* url, struct webui_http_response *reponse);

typedef webui_http_response {
  char* content_type;
  char* body;
  //avoid dealing with raw headers...
}

@AlbertShown
Copy link
Contributor

About the memory management, I suggest keeping it like this because I read many comments in the core source code explaining that the user data reference (pointer) is not guaranteed to stay valid when the call ends because of different language wrappers or simply the end-user clean the reference. So, WebUI makes a copy of the data before using it.

Another reason is when the multi-access mode is enabled. The browser can repeatedly ask for the same data (HTML page code), so WebUI keeps serving all requests using the saved copy.

About webui_map_url() suggestion, I guess it's already implemented in webui_set_file_handler(), where filename are simply URLs.
Example:

const void* my_files_handler(const char* filename, int* length) {

@hassandraga
Copy link
Member

Added webui_set_hide(size_t window, bool status).

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

4 participants