jupyter-xeus / xeus-javascript

A JavaScript kernel for JupyterLite, powered by Xeus
https://jupyter-xeus.github.io/xeus-javascript/lab/index.html?path=xeus-javascript.ipynb
BSD 3-Clause "New" or "Revised" License
9 stars 5 forks source link

Jupyter Widgets support #17

Open MRYingLEE opened 7 months ago

MRYingLEE commented 7 months ago

Jupyter Widgets are an impressive part of Jupyter ecosystem.

For Widgets are developed in TypeScript / Javascript. At the same time, HTML along with javascript can be displayed directly.

Is it needed to support it with this kernel? Or we may have a better option? If it is needed, do you have a plan to do so?

Please clarify. Thanks,

DerThorsten commented 7 months ago

Is it needed to support it with this kernel?

Not sure what you mean by "it".

Or we may have a better option?

Better option than what?

So not sure what you are asking, but if the question is, if we will add widget support to this kernel, then the answer is "Probably yes".

Greetings

MRYingLEE commented 7 months ago

Widget is developed in TypeScript/JavaScript for IPython. For JavaScript kernel maybe there are some other ways to bring interactive GUI without widget development. For example, some JavaScript code to display some GUI. Widget is a kind of heavy development while Javascript is a kind of light one. So I am wondering whether there is a better way. I found an interesting repo, https://github.com/manzt/anywidget. Also, https://github.com/wangqianwen0418/anywidget_react_demo. Maybe they are good starting point.

DerThorsten commented 7 months ago

Widget is developed in TypeScript/JavaScript for IPython. For JavaScript kernel maybe there are some other ways to bring interactive GUI without widget development. For example, some JavaScript code to display some GUI. Widget is a kind of heavy development while Javascript is a kind of light one. So I am wondering whether there is a better way.

Any potential widget will still be implemented in the usual way. The fact that the language of the kernel itself if is Javascript will not change that much

MRYingLEE commented 7 months ago

Got it. Maybe copying all related code of xeus-python is an easy way to have widgets support. Thanks for your clarification.

MRYingLEE commented 6 months ago

For reference, Anywidget can run on Deno, another JavaScript/TypeScript kernel. (https://github.com/manzt/anywidget/tree/main/packages/deno)

DerThorsten commented 6 months ago

thanks for the hint, but as for most of these issues, it is not a lack of knowledge, but rather a lack of time/funding for such work

DerThorsten commented 6 months ago

I have a branch where I started to work on widget support, but not sure when I have time to continue on it

DerThorsten commented 6 months ago

https://github.com/jupyter-xeus/xeus-javascript/tree/v2

DerThorsten commented 6 months ago

with the current main one can try experiment with with comms. I have not managed to get smth working.

function display_widget(data){
    const protocol_version_major = 2
    const protocol_version_minor = 1
    const target_name =  "jupyter.widget"
    const metadata =  {
        version: `${protocol_version_major}.${protocol_version_minor}.0`
    }
    comm = new Module.Comm(target_name, data, metadata, [],{})
    console.log(comm.comm_id())
    const widget_json = {
        version_major:  protocol_version_major,
        version_minor: protocol_version_minor,
        model_id: comm.comm_id()
    }
    const mime_bundle = {
        "application/vnd.jupyter.widget-view+json": widget_json
    }

    //  display via com id
    Module.interpreter.display_data(mime_bundle, {}, [])

}

const anywidget_version = "0.9.2"

const data =  {
    state: {
        _model_module: "anywidget",
        _model_name: "AnyModel",
        _model_module_version: anywidget_version,
        _view_module: "anywidget",
        _view_name: "AnyView",
        _view_module_version: anywidget_version,
        _view_count: null,
    },
}
display_widget(data)

So far this still fails with

134.fe2572ece3b7955c…572ece3b7955c89bb:1 Error: widget model not found
    at f.get_model (336.0a90bd910629a565…0629a565bb7e:1:3460)
    at w.renderModel (134.fe2572ece3b7955c…3b7955c89bb:1:72097)

( of course, anywidget is installed, I also tried with ipywidgets, but also no success so far)

MRYingLEE commented 6 months ago

I tried to migrate the working widget demo of Deno (https://github.com/manzt/anywidget/tree/main/packages/deno). But I failed for the same error of "Error displaying widget: model not found".

You may check my tried code at https://github.com/MRYingLEE/xeus-javascript/blob/main/notebooks/widget_js_xeus.ipynb .

MRYingLEE commented 4 months ago

Some progress. I slightly changed your code as follows:

function display_widget(data){
    const protocol_version_major = 2
    const protocol_version_minor = 1
    const target_name =  "jupyter.widget"
    const metadata =  {
        version: `${protocol_version_major}.${protocol_version_minor}.0`
    }
    // comm = new Module.Comm(target_name, data, metadata, [],{})
    const uuid=crypto.randomUUID();
    comm = new Module.Comm(target_name,{comm_id: uuid});

    console.log(comm.comm_id())
    const widget_json = {
        version_major:  protocol_version_major,
        version_minor: protocol_version_minor,
        model_id: comm.comm_id()
    }
    const mime_bundle = {
        "application/vnd.jupyter.widget-view+json": widget_json
    }
    console.log(`"application/vnd.jupyter.widget-view+json": ${JSON.stringify(widget_json)}`);
    //  display via com id
    Module.interpreter.display_data(Module.get_request_context(),mime_bundle, {}, [])

    comm.open(Module.get_request_context().header(), data, metadata, []); // No message is triggered!
}

const anywidget_version = "0.9.3"

const data =  {
    state: {
        _model_module: "anywidget",
        _model_name: "AnyModel",
        _model_module_version: anywidget_version,
        _view_module: "anywidget",
        _view_name: "AnyView",
        _view_module_version: anywidget_version,
        _view_count: null,
    },
}
display_widget(data)

No more errors. The UI shows "Loading widget...".

Then I tried to enable the communication by

comm.open(Module.get_request_context().header(), data, metadata, []);

But no any kernel message is triggered.

DerThorsten commented 4 months ago

Thanks for the experimentation and progress! Can you make a branch with your code such that I could do some experimentation on top?

MRYingLEE commented 4 months ago

My code runs in a notebook, https://github.com/MRYingLEE/xeus-javascript/blob/main/notebooks/display_widget.ipynb.

To avoid version conflicts, I use the same version (0.9.3) of anywidget for Deno.