Giter Club home page Giter Club logo

webio.jl's People

Contributors

balinus avatar cstjean avatar djsegal avatar femtocleaner[bot] avatar fonsp avatar giordano avatar halleysfifthinc avatar ilanpillemer avatar jefffessler avatar jlumpe avatar jobjob avatar juliatagbot avatar jw3126 avatar kristofferc avatar masonprotter avatar mbauman avatar mosullivan93 avatar nhdaly avatar nilshg avatar olegshtch avatar pankgeorg avatar pfitzseb avatar piever avatar rdeits avatar schneiderl avatar shashi avatar simondanisch avatar tkelman avatar tkoolen avatar travigd avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

webio.jl's Issues

Better sync API

right now we do on(identity, observable) to get observable to start sending updates to Julia.

I bet it's easy to make this asynchronous -- one should be able to add the handler after a widget has been displayed -- this would allow InteractNext to not send stuff to Julia by default allowing it to be used entirely client-sided.

Integrate with HTTP.jl

From Slack:

Eric Forgy [3:15 PM]
Maybe I can help adapt it to HTTP 😊

Shashi Gowda [3:19 PM]
A PR for that would be welcome!
https://github.com/JuliaGizmos/WebIO.jl/blob/master/src/providers/mux_setup.jl is how I do it in Mux. WebIO integration also generally requires that package assets be available at /pkg/. /pkg/Foo/bar.js which corresponds to the file Foo/assets/bar.js in Foo.jl directory.
GitHub
JuliaGizmos/WebIO.jl
WebIO.jl - a DSL for web-based widgets in Julia
I ended up adding this directly to Mux -- JuliaWeb/Mux.jl#34
GitHub
Serve package asset files by shashi · Pull Request #34 · JuliaWeb/Mux.jl
A file at MyPkg/assets/js/test.js will be served at /pkg/MyPkg/js/test.js supersedes JuliaGizmos/Blink.jl#55

using Mux
using WebIO
webio_serve(req -> TableView.showtable(t))

jupyterlab

The current IJulia code works great in jupyter notebook, but will have to be re-packaged into a lab extension for use in jupyter lab

Dependency injection

We need to be able to load JavaScript files from Julia packages and the web, as and when required by components being displayed. Components provided by packages should be able to do this on their own. For example, if I'm using a PlotlyJS plot in my app, I should not worry about loading Plotly.js, PlotlyJS should ask WebIO to do that where it is invoked.

  • Get /pkg/PKG/ to serve assets directory in Mux and Blink
  • Create a Jupyter server plugin to allow serving asset files at /pkg/PKG
  • decide AMD based dynamic loader script to use (options: LABjs, RaveJS, RequireJS)
  • Make node creation asynchronous (promise-based or callback based)
  • Create life cycle events during node creation on node dependency satisfaction, ready connection and creation completed.

onimport example fails

From the README, with the JSExpr master:

using WebIO, JSExpr

w = Scope(imports=["//cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.11/p5.js"])

onimport(w, @js function (p5)
    function sketch(s)
        s.setup = () -> s.createCanvas(640, 480)

        s.draw = function ()
          if s.mouseIsPressed
            s.fill(0)
          else
            s.fill(255)
          end
          s.ellipse(s.mouseX, s.mouseY, 80, 80)
        end
    end
    @new p5(sketch, this.dom.querySelector("#container"))
end)

w(dom"div#container"())

gives

MethodError: no method matching @js(::Expr)
Closest candidates are:
  @js(::ANY, ::ANY) at /home/cedric/.julia/v0.6/Blink/src/rpc/rpc.jl:54

`send_sync()` tries to call nonexistent `send(::Channel, ::Dict)` method

Here's a MWE:

julia> using WebIO

julia> s = Scope()
WebIO.Scope("scope-1", WebIO.Node{WebIO.DOM}(WebIO.DOM(:html, :span), Any[], Dict{Any,Any}(), 0), Channel{Any}(sz_max:32,sz_curr:0), Dict{String,Tuple{Observables.Observable,Union{Bool, Void}}}(), Set{String}(), nothing, Any[], Dict{Any,Any}())

julia> WebIO.send_sync(s, "foo", "bar")
ERROR: MethodError: no method matching send(::Channel{Any}, ::Dict{String,Any})
Closest candidates are:
  send(::UDPSocket, ::Any, ::Any, ::Any) at socket.jl:558
  send(::WebIO.Scope, ::Any, ::Any) at /home/rdeits/.julia/v0.6/WebIO/src/scope.jl:179
  send(::WebIO.AbstractConnection, ::Any) at /home/rdeits/.julia/v0.6/WebIO/src/connection.jl:4
Stacktrace:
 [1] send_sync(::WebIO.Scope, ::String, ::String) at /home/rdeits/.julia/v0.6/WebIO/src/scope.jl:226

It doesn't look like there are any send(::Channel, x...) methods defined anywhere. Is send_sync actually being used?

Way to host non-{html,css,js} assets

Let's say you have a mp3 file in the assets directory.


Why does the following javascript:

var music = new Howl({
  src: ['pkg/<PkgName>/song.mp3'],
  autoplay: true,
  loop: true
});

cause the javascript console error

GET http://localhost:8888/notebooks/pkg/<PkgName>/song.mp3 404 (Not Found)

how do you get rid of the /notebooks/ part of the url?

RFH: Making Javascript package management even more painless

Right now WebIO.devsetup() and WebIO.bundlejs() works on Linux if nodejs is installed.

I would wager it works on Mac as well if nodejs is installed (would be great if someone can confirm this!)

Hopefully it will be possible to get this working on Windows in a self-contained way. (see https://yarnpkg.com/docs/install for more info)

Work items:

On Linux and Mac

  • Check to see if node is installed and try to install it if not in user space

On Windows

  • Get devsetup to work on Windows albeit with more steps
  • Document this

IJulia connection does not survive page reload

For instance, if I execute

using WebIO, JSExpr

function random_print_button()
    w = Scope()

    obs = Observable(w, "rand-value", 0.0)

    on(obs) do x
        println("JS sent $x")
    end

    w(
      dom"button"(
        "generate random",
        events=Dict("click"=>@js () -> $obs[] = Math.random()),
      ),
    )
end

random_print_button()

then it works, but after refreshing the page, the button doesn't do anything anymore. And if I reexecute the cell, then I get no button/output at all.

[RFC] WebIO

@MikeInnes and I discussed the possibility of a small "hub" package at JuliaCon which would allow package developers to "display something and update it" - something that would work on all web interfaces to Julia (IJulia, Atom, Blink, Escher). This way package authors won't have to worry about setting up fragile @require IJulia and @require Blink blocks for each interfacre. Or buy into the bureaucracy of wrapping JS libraries in something like Escher (and then have it not work in anything else). WebIO is my take on this hub package.

The idea is to on the one end have IJulia, Atom, Blink and Escher depend on this package and implement the Provider interface. On the other end Graphics packages like PlotlyJS, Vega, Compose, (even Escher) could use the Node and Context API to make interactive gizmos.

Dependency trees

Only flat dependencies can be specified at the moment, and all dependencies are loaded asynchronously.

Most use cases however require some dependencies to loaded after others. e.g. jquery-ui must be loaded after jquery.

The suggested implementation from the SystemJS gitter is to create a tree of dependencies using promises. The julia API could be something like Async(Sync("jquery.js", "jquery-ui.js"), "moment.js"), ondependencies will get the flattened modules i.e. jQuery, jQueryUI and Moment.

setup issue

I am trying to install this to use InteractNext. When setting up:

julia> using WebIO

julia> WebIO.devsetup()
INFO: No packages to install, update or remove
npm WARN deprecated nomnom@1.8.1: Package no longer supported. Contact support@npmjs.com for more info.
npm WARN deprecated babel-preset-es2015@6.24.1: 🙌  Thanks for using Babel: we recommend using babel-preset-env now: please read babeljs.io/env to update! 
npm WARN bootstrap@4.0.0 requires a peer of popper.js@^1.12.9 but none is installed. You must install peer dependencies yourself.
npm WARN abradley@1.0.0 No description
npm WARN abradley@1.0.0 No repository field.

+ webpack-cli@2.0.13
+ webpack@4.2.0
updated 2 packages in 22.707s
INFO: Removing NodeJS v0.4.0

julia> WebIO.bundlejs(watch=false)
INFO: Installing NodeJS v0.4.0
INFO: Building NodeJS
up to date in 2.58s
module.js:549
    throw err;
    ^

Error: Cannot find module '/Users/abradley/.julia/v0.6/WebIO/deps/node_modules/webpack-cli/bin/webpack.js'
    at Function.Module._resolveFilename (module.js:547:15)
    at Function.Module._load (module.js:474:25)
    at Function.Module.runMain (module.js:693:10)
    at startup (bootstrap_node.js:188:16)
    at bootstrap_node.js:609:3
ERROR: LoadError: failed process: Process(`/Users/abradley/.julia/v0.6/NodeJS/deps/bin/node-v8.10.0-darwin-x64/bin/node ../../deps/node_modules/webpack-cli/bin/webpack.js`, ProcessExited(1)) [1]
Stacktrace:
 [1] pipeline_error(::Base.Process) at ./process.jl:682
 [2] run(::Cmd) at ./process.jl:651
 [3] include_from_node1(::String) at ./loading.jl:576
 [4] include(::String) at /Applications/Julia-0.6.app/Contents/Resources/julia/lib/julia/sys.dylib:?
 [5] #bundlejs#42(::Bool, ::Function) at /Users/abradley/.julia/v0.6/WebIO/src/devsetup.jl:12
 [6] (::WebIO.#kw##bundlejs)(::Array{Any,1}, ::WebIO.#bundlejs) at ./<missing>:0
while loading /Users/abradley/.julia/v0.6/WebIO/deps/_bundlejs.jl, in expression starting on line 22

wrong yarn path in Mac OS

I don't know if the install instructions have been tested on Mac OS but at least on my machine one path was wrong.

Instead of:

run(`./.yarn/dist/bin/yarn install`)

I had to run:

run(`./.yarn/yarn-v1.0.1/bin/yarn install`)

As that was the folder structure that I had on my computer. After that everything worked and I could run the examples.

Here is the output of versioninfo() if it's helpful:

julia> versioninfo()
Julia Version 0.6.0
Commit 903644385b (2017-06-19 13:05 UTC)
Platform Info:
  OS: macOS (x86_64-apple-darwin13.4.0)
  CPU: Intel(R) Core(TM) i5-4278U CPU @ 2.60GHz
  WORD_SIZE: 64
  BLAS: libopenblas (USE64BITINT DYNAMIC_ARCH NO_AFFINITY Haswell)
  LAPACK: libopenblas64_
  LIBM: libopenlibm
  LLVM: libLLVM-3.9.1 (ORCJIT, haswell)

PS: really cool package, I've just started checking it out but it looks very promising!

Get Binder working across all browsers

Continuation of issue #68 // was just too cluttered

Scenario now is:

I have a binder that serves assets, but can't correctly find them


i.e.

website looks for assets at:

but if you hunt around with chrome, you find they're actually at:

and this is because the user is at the jupyter notebook:


What part of the code do you think is responsible for this?

jupyter server doesn't work with large javascript assets

Trying to load /pkg/PlotlyJS/plotly-latest.min.js in jupyter errors.

In the terminal console (where I started jupyter) I see:

[E 15:34:34.221 NotebookApp] Uncaught exception GET /pkg/PlotlyJS/plotly-latest.min.js (::1)
    HTTPServerRequest(protocol='http', host='localhost:8890', method='GET', uri='/pkg/PlotlyJS/plotly-latest.min.js', version='HTTP/1.1', remote_ip='::1', headers={'Host': 'localhost:8890', 'Connection': 'keep-alive', 'Upgrade-Insecure-Requests': '1', 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8', 'Dnt': '1', 'Accept-Encoding': 'gzip, deflate, br', 'Accept-Language': 'en-US,en;q=0.9', 'Cookie': 'username-localhost-8888="2|1:0|10:1519331658|23:username-localhost-8888|44:NzRlNjU4NTY3ZWRlNGI4MmE3Y2IyMzlmMDM0N2FlMWI=|02d5a4d778974478c4349bf954cb877feeb1298f8e19e828ec39120fa7e1d696"; username-localhost-9271="2|1:0|10:1519670215|23:username-localhost-9271|44:ZDFkYzc4MWIzZDQ5NDkyOGJhMTkxYjc1YTI4YWFkZGQ=|eec64cf784e6e7b2cd8d362a5930e87823aa6a0482bf075eda7f63deea932400"; username-localhost-8890="2|1:0|10:1519857878|23:username-localhost-8890|44:YjFjOTNiN2YzYjkyNDMzNzg4NWM2ZDE0N2M4MGExOTI=|0d61933cd0232a5498984afcda76522224c18987a37c255d6c0f3f75bd0b9d4e"; _xsrf=2|e2288e49|b6e414a95688acfca1065dbd59450ce6|1519936253'})
    Traceback (most recent call last):
      File "/Users/sglyon/anaconda3/lib/python3.6/site-packages/tornado/web.py", line 1513, in _execute
        self.finish()
      File "/Users/sglyon/anaconda3/lib/python3.6/site-packages/tornado/web.py", line 992, in finish
        self.request.finish()
      File "/Users/sglyon/anaconda3/lib/python3.6/site-packages/tornado/httputil.py", line 419, in finish
        self.connection.finish()
      File "/Users/sglyon/anaconda3/lib/python3.6/site-packages/tornado/http1connection.py", line 448, in finish
        self._expected_content_remaining)
    tornado.httputil.HTTPOutputError: Tried to write 1554499 bytes less than Content-Length
[E 15:34:34.222 NotebookApp] Cannot send error response after headers written

In the javascript console of the browser I see

jquery.min.js:5 [Violation] Added synchronous DOM mutation listener to a 'DOMNodeInserted' event. Consider using MutationObserver to make the page more responsive.
add @ jquery.min.js:5
(anonymous) @ jquery.min.js:5
each @ jquery.min.js:4
each @ jquery.min.js:4
on @ jquery.min.js:5
KeyboardManager.register_events @ keyboardmanager.js:254
append_html @ outputarea.js:690
OutputArea.append_mime_type @ outputarea.js:671
OutputArea.append_execute_result @ outputarea.js:472
OutputArea.append_output @ outputarea.js:310
OutputArea.handle_output @ outputarea.js:243
output @ codecell.js:365
Kernel._handle_output_message @ kernel.js:1196
i @ jquery.min.js:4
Kernel._handle_iopub_message @ kernel.js:1223
Kernel._finish_ws_message @ kernel.js:1015
(anonymous) @ kernel.js:1006
VM93:2572 Uncaught (in promise) Error: Failed to fetch
  Instantiating http://localhost:8890/pkg/PlotlyJS/plotly-latest.min.js
  Loading /pkg/PlotlyJS/plotly-latest.min.js
t @ VM93:2572
(anonymous) @ VM93:2572
Promise.then (async)
createScope @ VM93:2903
createNode @ VM93:148
mount @ VM93:192
(anonymous) @ VM306:2
(anonymous) @ VM57:3003
evalInContext @ VM57:3003
proto.attachedCallback @ VM57:3011
(anonymous) @ jquery.min.js:5
domManip @ jquery.min.js:5
append @ jquery.min.js:5
OutputArea._safe_append @ outputarea.js:440
OutputArea.append_execute_result @ outputarea.js:476
OutputArea.append_output @ outputarea.js:310
OutputArea.handle_output @ outputarea.js:243
output @ codecell.js:365
Kernel._handle_output_message @ kernel.js:1196
i @ jquery.min.js:4
Kernel._handle_iopub_message @ kernel.js:1223
Kernel._finish_ws_message @ kernel.js:1015
(anonymous) @ kernel.js:1006
Promise.then (async)
Kernel._handle_ws_message @ kernel.js:1006
i @ jquery.min.js:4
VM93:2572 Uncaught (in promise) Error: Failed to fetch
  Instantiating http://localhost:8890/pkg/PlotlyJS/plotly-latest.min.js
  Loading /pkg/PlotlyJS/plotly-latest.min.js

Way to invalidate assets (i.e. css)

If I have a css file in my assets folder it gets served correctly the first time.

But if I update the css file while I'm working on stuff, each call only finds the cached version.

Is there a way to delete the assets cache (for development)?

No output in IJulia

Ubuntu, IJulia 1.7.0 and WebIO 1.5.0, I don't get anything in IJulia

image

Here's the JSON in the .ipynb file:

  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div class='display:none'></div><unsafe-script style='display:none'>\n",
       "WebIO.mount(this.previousSibling,{&quot;props&quot;:{},&quot;nodeType&quot;:&quot;DOM&quot;,&quot;type&quot;:&quot;node&quot;,&quot;instanceArgs&quot;:{&quot;namespace&quot;:&quot;html&quot;,&quot;tag&quot;:&quot;div&quot;},&quot;children&quot;:[&quot;Hello, World&quot;]})</unsafe-script>"
      ],
      "text/plain": [
       "(div\n",
       "  \"Hello, World\")"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "Node(:div, \"Hello, World\")"
   ]
  }
 ],

I did Pkg.build("WebIO"). Also tried devsetup(); bundlejs(); build("WebIO"). All of that works without error, but it doesn't help even after restart.

`register_renderable` is not ideal

I think the right way to go about this is to provide a trait:

WebIO.renderable(x::T) = true # and WebIO.renderable(x::Any) = false

Then the backends are to be hooked up to always use WebIO.render when this trait is true.

Best way to do this is have backends depend on WebIO.

No home

config_file = joinpath(ENV["HOME"], ".jupyter", "jupyter_notebook_config.py")

This line assumes ENV["HOME"] is defined - which it isn't?! At least on windows it isn't ;)

Not rendering HTML in jupyter notebook

w = WebIO.Widget()
ob = Observable(w, "keys", 0)
on(println, ob)
w(
    dom"div[tabindex=1]"(style=Dict("height"=>"100px", "width"=>"100px"),
                                     events=Dict("keyup" => @js e -> $ob[] = e.keyCode))
)

inside a cell produces this output string:

WebIO.mount('context-1', '#context-1',{"props":{},"nodeType":"Widget","type":"node","instanceArgs":{"imports":{"data":[],"type":"async_block"},"id":"context-1","handlers":{},"observables":{"keys":{"sync":true,"id":"ob_01","value":0}}},"children":[{"props":{"attributes":{"tabindex":"1"},"events":{"keyup":(function (e){return WebIO.setval({"name":"keys","id":"ob_01","context":"context-1","type":"observable"},e.keyCode)})},"style":{"height":"100px","width":"100px"}},"nodeType":"DOM","type":"node","instanceArgs":{"namespace":"html","tag":"div"},"children":[]}]})


is this because of something on master?

JavaScript module management

This package is at a point where it needs to commit to a javascript workflow. This is a draft of my current thinking:

  • Individual JS files in assets/ should follow the AMD module format CommonJS format
  • The default files should be compiled into a single assets/webio.bundle.js for production use, and by default all front ends should load this.
  • every Julia release of this package MUST build this file and commit it.
  • Calling WebIO.devsetup() should:
    • install yarn
    • install development dependencies (webpack, RequireJS)
    • install project dependencies (bluebird)
    • ~switch all clients to using RequireJS + AMD modules (probably by creating a dummy .dev file) ~ provide WebIO.bundlejs(watch=true) that starts a webpack bundler.

Way to include google fonts

Is there a way to add google fonts to a Scope through imports?

<link href="https://fonts.googleapis.com/css?family=Press+Start+2P" rel="stylesheet">

a render generic function?

One way to leverage this package is:

using WebIO

function Base.show(io, m::MIME"text/html", x::MyType)
     # create some widget using WebIO
     gizmo = withcontext(Context()) do ctx
         # load some dependencies
         # run some js setup, setup some interaction
         dom"div.mytype-widget"(...)
     end
     show(io, m, x)
end

It would be considerably nicer to have just:

using WebIO

function WebIO.render(x::MyType)
     withcontext(Context()) do ctx
         # load some dependencies
         # run some js setup, setup some interaction
         dom"div.mytype-widget"(...)
     end
end

And display systems gave preference to this over text/html

Release roadmap/plan

I feel a little strange initiating this conversation as an "outsider", but I was hoping to start a discussion about what needs to happen before WebIO can be released on metadata.

Perhaps once a concrete list is laid out, people can contribute to making it happen?

WebIO not defined javascript error

getting the following error after typing:

Pkg.build("WebIO")
using WebIO

Node(:div,
      Node(:h1, "Clickbait!", className="title", style=Dict(:color=>"red")),
      Node(:p, "You will not believe what happens when you click this link!", className="description"),
      className="article"
)

Javascript error adding output!
ReferenceError: WebIO is not defined
See your browser Javascript console for more details.

demo site?

The landing page (README) is great. It would be nice to have a catchy demo site too that could show off what features it provides / what it can do.

(fyi) no method matching unsafe_length

I understand this is a work in progress. Just following the README (after cloning this repo, using v0.5):

julia> using WebDisplay

julia> Node(:div,
             Node(:h1, "Clickbait!", className="title", style=Dict(:color=>"red")),
             Node(:p, "You will not believe what happens when you click this link!", className="description"),
             className="article"
       )
WebDisplay.Node{WebDisplay.DOM}(WebDisplay.DOM(:html,:div),WebDisplay.Node{WebDisplay.DOM}Error showing value of type WebDisplay.Node{WebDisplay.DOM}:
ERROR: MethodError: no method matching unsafe_length(::Int64)
Closest candidates are:
  unsafe_length(::StepRange{T,S}) at range.jl:361
  unsafe_length(::Base.OneTo{T<:Integer}) at range.jl:366
  unsafe_length(::AbstractUnitRange{T}) at range.jl:365
  ...
 in _collect(::Base.OneTo{Int64}, ::Base.Generator{Base.OneTo{Int64},Base.#unsafe_length}, ::Base.EltypeUnknown, ::Base.HasShape) at ./array.jl:320
 in _length at ./abstractarray.jl:126 [inlined]
 in show_vector(::IOContext{Base.Terminals.TTYTerminal}, ::FunctionalCollections.PersistentVector{WebDisplay.Node{WebDisplay.DOM}}, ::String, ::String) at ./show.jl:1665
 in #showarray#330(::Bool, ::Function, ::IOContext{Base.Terminals.TTYTerminal}, ::FunctionalCollections.PersistentVector{WebDisplay.Node{WebDisplay.DOM}}, ::Bool) at ./show.jl:1590
 in show(::IOContext{Base.Terminals.TTYTerminal}, ::FunctionalCollections.PersistentVector{WebDisplay.Node{WebDisplay.DOM}}) at ./show.jl:1586
 in show_default(::IOContext{Base.Terminals.TTYTerminal}, ::Any) at ./show.jl:130
 in display(::Base.REPL.REPLDisplay{Base.REPL.LineEditREPL}, ::MIME{Symbol("text/plain")}, ::WebDisplay.Node{WebDisplay.DOM}) at ./REPL.jl:132
 in display(::Base.REPL.REPLDisplay{Base.REPL.LineEditREPL}, ::WebDisplay.Node{WebDisplay.DOM}) at ./REPL.jl:135
 in display(::WebDisplay.Node{WebDisplay.DOM}) at ./multimedia.jl:143
 in print_response(::Base.Terminals.TTYTerminal, ::Any, ::Void, ::Bool, ::Bool, ::Void) at ./REPL.jl:154
 in print_response(::Base.REPL.LineEditREPL, ::Any, ::Void, ::Bool, ::Bool) at ./REPL.jl:139
 in (::Base.REPL.##22#23{Bool,Base.REPL.##33#42{Base.REPL.LineEditREPL,Base.REPL.REPLHistoryProvider},Base.REPL.LineEditREPL,Base.LineEdit.Prompt})(::Base.LineEdit.MIState, ::Base.AbstractIOBuffer{Array{UInt8,1}}, ::Bool) at ./REPL.jl:652
 in run_interface(::Base.Terminals.TTYTerminal, ::Base.LineEdit.ModalInterface) at ./LineEdit.jl:1579
 in run_frontend(::Base.REPL.LineEditREPL, ::Base.REPL.REPLBackendRef) at ./REPL.jl:903
 in run_repl(::Base.REPL.LineEditREPL, ::Base.##930#931) at ./REPL.jl:188
 in _start() at ./client.jl:360

The same thing happens if I use IJulia first

Module not found: Can't resolve 'fs'

after installing nodejs and npm and WebIO.jl (linux, nightly)
using WebIO; WebIO.devsetup(); # ok

WebIO.bundlejs(watch=false)
julia> WebIO.bundlejs(watch=false)
Hash: d2858bdd8fdf0540c8b1
Version: webpack 2.5.1
Time: 219ms
          Asset    Size  Chunks             Chunk Names
webio.bundle.js  123 kB       0  [emitted]  WebIO
   [0] ./basics/webio.js 3.24 kB {0} [built]
   [1] (webpack)/buildin/global.js 509 bytes {0} [built]
   [2] ./basics/node.js 8.26 kB {0} [built]
   [3] ./index.js 74 bytes {0} [built]
   [4] ./~/base64-js/index.js 3.48 kB {0} [built]
   [5] ./~/buffer/index.js 48.6 kB {0} [built]
   [6] ./~/ieee754/index.js 2.05 kB {0} [built]
   [7] ./~/isarray/index.js 132 bytes {0} [built]
   [8] ./~/process/browser.js 5.42 kB {0} [built]
   [9] ./~/systemjs/dist/system.js 47.3 kB {0} [built]

ERROR in ./~/systemjs/dist/system.js
Module not found: Error: Can't resolve 'fs' in '/home/jas/.julia/v0.7/WebIO/assets/node_modules/systemjs/dist'
 @ ./~/systemjs/dist/system.js 4:11982-11995
 @ ./basics/node.js
 @ ./index.js
ERROR: failed process: Process(`./webpack`, ProcessExited(2)) [2]
Stacktrace:
 [1] pipeline_error(::Base.Process) at ./process.jl:708
 [2] run(::Cmd) at ./process.jl:670
 [3] #30 at /home/jas/.julia/v0.7/WebIO/src/devsetup.jl:20 [inlined]
 [4] cd(::WebIO.##30#31{Bool}, ::String) at ./file.jl:70
 [5] (::WebIO.#kw##bundlejs)(::Array{Any,1}, ::WebIO.#bundlejs) at ./<missing>:0

(inconsequential) error when running bundlejs

julia> WebIO.bundlejs(watch=true)

Webpack is watching the files…

Hash: 283f6e34baa0f1142700
Version: webpack 2.2.1
Time: 306ms
          Asset    Size  Chunks             Chunk Names
webio.bundle.js  121 kB       0  [emitted]  WebIO
   [0] ./basics/webio.js 3.05 kB {0} [built]
   [1] (webpack)/buildin/global.js 509 bytes {0} [built]
   [2] ./basics/node.js 8.27 kB {0} [built]
   [3] ./~/base64-js/index.js 3.48 kB {0} [built]
   [4] ./~/buffer/index.js 48.6 kB {0} [built]
   [5] ./~/ieee754/index.js 2.05 kB {0} [built]
   [6] ./~/isarray/index.js 132 bytes {0} [built]
   [7] ./~/process/browser.js 5.3 kB {0} [built]
   [8] ./~/systemjs/dist/system.js 46.4 kB {0} [built]
   [9] ./index.js 74 bytes {0} [built]

ERROR in ./~/systemjs/dist/system.js
Module not found: Error: Can't resolve 'fs' in '/home/shashi/.julia/v0.5/WebIO/assets/node_modules/systemjs/dist'
 @ ./~/systemjs/dist/system.js 4:11220-11233
 @ ./basics/node.js
 @ ./index.js
^CERROR: InterruptException:
 in run at ./process.jl:592 [inlined]
 in (::WebIO.##27#28{Bool})() at /home/shashi/.julia/v0.5/WebIO/src/devsetup.jl:18
 in cd(::WebIO.##27#28{Bool}, ::String) at ./file.jl:59
 in (::WebIO.#kw##bundlejs)(::Array{Any,1}, ::WebIO.#bundlejs) at ./<missing>:0
 in eval_user_input(::Any, ::Base.REPL.REPLBackend) at ./REPL.jl:64
 in macro expansion at ./REPL.jl:95 [inlined]
 in (::Base.REPL.##3#4{Base.REPL.REPLBackend})() at ./event.jl:68

Installation fails on Windows

Thank you for developing this package!
However, I have problems installing it on windows: WebIO.devsetup() fails with the following:
ERROR: could not spawn 'tar zvxf yarn.tar.gz -C .yarn': no such file or directory (ENOENT)
Which is I guess expected given that tar is not installed in Windows.
However, a separately installed yarn, using the yarn install command in the assets/webio directory also gives an error, from the Windows Script Host:
Script: ...WebIO\assests\webio\node.js
Line: 253
Char: 29
Error: Expected identifier
Code: 800A03F2
Source: Microsoft JScript compilation error

Also, the modification of the jupyter_notebook_config.py does not take into account escaping of the windows path backslashes, which causes the script to fail.

jupyter server install

If a user has both ~/.jupyter/jupyter_notebook_config.py and ~/.jupyter/jupyter_notebook_config.json then the c.NotebookApp.nbserver_extensions section of the .py file will be ignored.

In that case we should have both what you currently do and add "jlstaticserve": true to the json file so it looks something like

{
  "NotebookApp": {
    "nbserver_extensions": {
      "jupyter_nbextensions_configurator": true,
      "egal": true,
      "jlstaticserve": true
    }
  }
}

API polish

  • Make sure all JS APIs take context as the first argument / this
  • The dependency promise resolver should splat the input module objects. (Implemented this as ondependencies)
  • the name adddeps! is awkward
  • allow interpolating into dom"..." string

Pushing updates to multiple web clients

I was investigating whether it's possible to have multiple web views receiving the same updates from Julia. It seems like, at least from the basic demos, this sort of works. That is, pushing an update from Julia to Javascript works, but only one web view receives the update, and which one appears to be random.

To reproduce, I started with the simple clock demo from the readme:

w = Scope()
obs = Observable(w, "clock-value", "")

timestr() = Dates.format(now(), "HH:MM:SS")

# update timestamp every second
@async while true
    sleep(1)
    obs[] = timestr()
end

# on every update to `obs`, replace the text content of #clock
onjs(obs, @js val -> begin
    @var clock = this.dom.querySelector("#clock")
    clock.textContent = val
end)

node = w(
  dom"div#clock"(
    timestr(),
  ),
)

I let IJulia display that final node variable, which results in the ticking clock. I then set up a Mux server to serve the same node:

using Mux
function myapp(req) # an "App" takes a request, returns the output
    node
end

webio_serve(page("/", myapp))

And then I opened localhost:8000 in a browser.

The result is that both clocks keep ticking, but only one of them ticks in a given second, so each individual clock only updates every few seconds.

Is this expected? Do we want to make this work? Or am I just doing it wrong? In MeshCat.jl I manage this by deliberately sending every update to all the connected websockets, and I suspect I could do something similar with WebIO, but only if that's actually desirable.

Thanks!

Other events besides click events

Throughout your docs you only talk about click events:

  dom"button"(
    "generate random",
    events=Dict("click"=>@js () -> $obs[] = Math.random()),
  )

However, I want to do keyboard click events on the actual jupyter cell.

The only way I can think about doing this in your framework is to have a onload function


Do you support load events?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.