Bonito.Asset
— TypeRepresent an asset stored at an URL. We try to always have online & local files for assets
diff --git a/previews/PR284/.documenter-siteinfo.json b/previews/PR284/.documenter-siteinfo.json
index 425fad33..2a25eaa4 100644
--- a/previews/PR284/.documenter-siteinfo.json
+++ b/previews/PR284/.documenter-siteinfo.json
@@ -1 +1 @@
-{"documenter":{"julia_version":"1.11.3","generation_timestamp":"2025-01-24T12:33:49","documenter_version":"1.8.0"}}
\ No newline at end of file
+{"documenter":{"julia_version":"1.11.3","generation_timestamp":"2025-01-24T16:40:08","documenter_version":"1.8.0"}}
\ No newline at end of file
diff --git a/previews/PR284/api.html b/previews/PR284/api.html
index 47763a3c..4df71b45 100644
--- a/previews/PR284/api.html
+++ b/previews/PR284/api.html
@@ -11,7 +11,7 @@
App() do session::Session
bound_global = bind_global(session, some_observable)
return DOM.div(bound_global)
-endsource Represent an asset stored at an URL. We try to always have online & local files for assets Defaults for Represent an asset stored at an URL. We try to always have online & local files for assets Defaults for A simple Dropdown, which can be styled via the Example A simple Dropdown, which can be styled via the Example We don't serve files and include anything directly as raw bytes. Interpolating the same asset many times, will only upload the file to JS one time though. A web session with a user We don't serve files and include anything directly as raw bytes. Interpolating the same asset many times, will only upload the file to JS one time though. A web session with a user Creates a Styles object, which represents a Set of CSS objects. You can insert the Styles object into a DOM node, and it will be rendered as a Creates a Styles object, which represents a Set of CSS objects. You can insert the Styles object into a DOM node, and it will be rendered as a For styling components, it's recommended, to always allow user to merge in customizations of a Style, like this: All Bonito components are stylable this way. Why not A simple button, which can be styled a Example All Bonito components are stylable this way. Why not A simple button, which can be styled a Example A simple Checkbox, which can be styled via the A simple NumberInput, which can be styled via the Example A simple Checkbox, which can be styled via the A simple NumberInput, which can be styled via the Example A simple TextField, which can be styled via the Example A simple TextField, which can be styled via the Example Creates an element where the content is centered via Places objects in a column, based on Creates an element where the content is centered via Places objects in a column, based on A Grid is a container that lays out its children in a grid, based on the powerful css A Labeled container with a simople layout to put a label next to an object. A Grid is a container that lays out its children in a grid, based on the powerful css A Labeled container with a simople layout to put a label next to an object. A Page can be used for resetting the Bonito state in a multi page display outputs, like it's the case for Pluto/IJulia/Documenter. For Documenter, the page needs to be set to Places objects in a row, based on A Page can be used for resetting the Bonito state in a multi page display outputs, like it's the case for Pluto/IJulia/Documenter. For Documenter, the page needs to be set to Places objects in a row, based on Evaluate a javascript script in Evals Exports the app defined by Revise base server that will serve a static side based on Bonito and will update on any code change! Usage: Evaluate a javascript script in Evals Exports the app defined by Revise base server that will serve a static side based on Bonito and will update on any code change! Usage: For the complete code, visit the Makie website repository which is using Bonito: MakieOrg/Website for an open session, link a and b on the javascript side. This will also Link the observables in Julia, but only as long as the session is active. Register a javascript function with Bonito.Asset
— TypeBonito.CodeEditor
— MethodCodeEditor(language::String; initial_source="", theme="chrome", editor_options...)
editor_options
:(
+end
Bonito.Asset
— TypeBonito.CodeEditor
— MethodCodeEditor(language::String; initial_source="", theme="chrome", editor_options...)
editor_options
:(
autoScrollEditorIntoView = true,
copyWithEmptySelection = true,
wrapBehavioursEnabled = true,
@@ -21,7 +21,7 @@
fontSize = 16,
wrap = 80,
mergeUndoDeltas = "always"
-)
Bonito.Dropdown
— TypeDropdown(options; index=1, option_to_string=string, style=Styles(), dom_attributes...)
style::Styles
attribute.App() do
+)
Bonito.Dropdown
— TypeDropdown(options; index=1, option_to_string=string, style=Styles(), dom_attributes...)
style::Styles
attribute.App() do
style = Styles(
CSS("font-weight" => "500"),
CSS(":hover", "background-color" => "silver"),
@@ -33,7 +33,7 @@
end
return dropdown
end
-
Bonito.NoServer
— TypeBonito.Session
— TypeBonito.StylableSlider
— MethodStylableSlider(
+
Bonito.NoServer
— TypeBonito.Session
— TypeBonito.StylableSlider
— MethodStylableSlider(
range::AbstractVector;
value=first(range),
slider_height=15,
@@ -71,10 +71,10 @@
),
)
end
-
Bonito.Styles
— TypeStyles(css::CSS...)
<style>
node. If you assign it directly to DOM.div(style=Style(...))
, the styling will be applied to the specific div. Note, that per Session
, each unique css object in all Styles
across the session will only be rendered once. This makes it easy to create Styling inside of components, while not worrying about creating lots of Style nodes on the page. There are a two more convenience constructors to make Styles
a bit easier to use:Styles(pairs::Pair...) = Styles(CSS(pairs...))
+
Bonito.Styles
— TypeStyles(css::CSS...)
<style>
node. If you assign it directly to DOM.div(style=Style(...))
, the styling will be applied to the specific div. Note, that per Session
, each unique css object in all Styles
across the session will only be rendered once. This makes it easy to create Styling inside of components, while not worrying about creating lots of Style nodes on the page. There are a two more convenience constructors to make Styles
a bit easier to use:Styles(pairs::Pair...) = Styles(CSS(pairs...))
Styles(priority::Styles, defaults...) = merge(Styles(defaults...), priority)
function MyComponent(; style=Styles())
return DOM.div(style=Styles(style, "color" => "red"))
-end
Hyperscript.Style
? While the scoped styling via Hyperscript.Style
is great, it makes it harder to create stylable components, since it doesn't allow the deduplication of CSS objects across the session. It's also significantly slower, since it's not as specialized on the deduplication and the camelcase keyword to css attribute conversion is pretty costly. That's also why CSS
uses pairs of strings instead of keyword arguments.Bonito.WebSocketConnection
— Methodhandles a new websocket connection to a session
WidgetsBase.Button
— TypeButton(name; style=Styles(), dom_attributes...)
style::Styles
.App() do
+end
Hyperscript.Style
? While the scoped styling via Hyperscript.Style
is great, it makes it harder to create stylable components, since it doesn't allow the deduplication of CSS objects across the session. It's also significantly slower, since it's not as specialized on the deduplication and the camelcase keyword to css attribute conversion is pretty costly. That's also why CSS
uses pairs of strings instead of keyword arguments.Bonito.WebSocketConnection
— Methodhandles a new websocket connection to a session
WidgetsBase.Button
— TypeButton(name; style=Styles(), dom_attributes...)
style::Styles
.App() do
style = Styles(
CSS("font-weight" => "500"),
CSS(":hover", "background-color" => "silver"),
@@ -86,7 +86,7 @@
end
return button
end
-
WidgetsBase.Checkbox
— TypeCheckbox(default_value; style=Styles(), dom_attributes...)
style::Styles
attribute.WidgetsBase.NumberInput
— TypeNumberInput(default_value; style=Styles(), dom_attributes...)
style::Styles
attribute.App() do
+
WidgetsBase.Checkbox
— TypeCheckbox(default_value; style=Styles(), dom_attributes...)
style::Styles
attribute.WidgetsBase.NumberInput
— TypeNumberInput(default_value; style=Styles(), dom_attributes...)
style::Styles
attribute.App() do
style = Styles(
CSS("font-weight" => "500"),
CSS(":hover", "background-color" => "silver"),
@@ -98,7 +98,7 @@
end
return numberinput
end
-
WidgetsBase.TextField
— TypeTextField(default_text; style=Styles(), dom_attributes...)
style::Styles
attribute.App() do
+
WidgetsBase.TextField
— TypeTextField(default_text; style=Styles(), dom_attributes...)
style::Styles
attribute.App() do
style = Styles(
CSS("font-weight" => "500"),
CSS(":hover", "background-color" => "silver"),
@@ -110,7 +110,7 @@
end
return textfield
end
-
Bonito.Card
— MethodCard(
+
Bonito.Card
— MethodCard(
content;
style::Styles=Styles(),
backgroundcolor=RGBA(1, 1, 1, 0.2),
@@ -138,7 +138,7 @@
)
)
end
-
Bonito.Centered
— MethodCentered(content; style=Styles(), grid_attributes...)
Grid
.Bonito.Col
— MethodCol(elems...; grid_attributes...)
Grid
.Bonito.Grid
— MethodGrid(
+
Bonito.Centered
— MethodCentered(content; style=Styles(), grid_attributes...)
Grid
.Bonito.Col
— MethodCol(elems...; grid_attributes...)
Grid
.Bonito.Grid
— MethodGrid(
elems...;
gap="10px",
width="100%",
@@ -153,7 +153,7 @@
align_items="legacy",
style::Styles=Styles(),
div_attributes...,
-)
display: grid
property.Bonito.Labeled
— MethodLabeled(object, label; label_style=Styles(), attributes...)
App() do
+)
display: grid
property.Bonito.Labeled
— MethodLabeled(object, label; label_style=Styles(), attributes...)
App() do
label_style = Styles(
"color" => "white",
"padding" => "3px",
@@ -162,11 +162,11 @@
slider = StylableSlider(1:10)
Card(Labeled(slider, slider.value; label_style=label_style, width="auto"); backgroundcolor="gray")
end
-
Bonito.Page
— MethodPage(;
+
Bonito.Page
— MethodPage(;
offline=false, exportable=true,
connection::Union{Nothing, FrontendConnection}=nothing,
server_config...
-)
exportable=true, offline=true
, but doesn't need to, since Page defaults to the most common parameters for known Packages. Exportable has the effect of inlining all data & js dependencies, so that everything can be loaded in a single HTML object. offline=true
will make the Page not even try to connect to a running Julia process, which makes sense for the kind of static export we do in Documenter. For convenience, one can also pass additional server configurations, which will directly get put into configure_server!(;server_config...)
. Have a look at the docs for configure_server!
to see the parameters.Bonito.Row
— MethodRow(elems...; grid_attributes...)
Grid
.Bonito.configure_server!
— Methodconfigure_server!(;
+)
exportable=true, offline=true
, but doesn't need to, since Page defaults to the most common parameters for known Packages. Exportable has the effect of inlining all data & js dependencies, so that everything can be loaded in a single HTML object. offline=true
will make the Page not even try to connect to a running Julia process, which makes sense for the kind of static export we do in Documenter. For convenience, one can also pass additional server configurations, which will directly get put into configure_server!(;server_config...)
. Have a look at the docs for configure_server!
to see the parameters.Bonito.Row
— MethodRow(elems...; grid_attributes...)
Grid
.Bonito.configure_server!
— Methodconfigure_server!(;
listen_url::String=SERVER_CONFIGURATION.listen_url[],
listen_port::Integer=SERVER_CONFIGURATION.listen_port[],
forwarded_port::Integer=listen_port,
@@ -192,8 +192,8 @@
if listen_url is "0.0.0.0", this will default to http://$(Sockets.getipaddr()):forwarded_port
so that the server is reachable inside the local network.
If the server should be reachable from some external dns server,
- this needs to be set here.
Bonito.evaljs
— Methodevaljs(session::Session, jss::JSCode)
session
.Bonito.evaljs_value
— Methodevaljs_value(session::Session, js::JSCode)
js
code and returns the jsonified value. Blocks until value is returned. May block indefinitely, when called with a session that doesn't have a connection to the browser.Bonito.export_static
— Methodexport_static(html_file::Union{IO, String}, app::App)
-export_static(folder::String, routes::Routes)
app
with all its assets a single HTML file. Or exports all routes defined by routes
to folder
.Bonito.interactive_server
— Functioninteractive_server(f, paths, modules=[]; url="127.0.0.1", port=8081, all=true)
using Revise, Website
+ this needs to be set here.
Bonito.evaljs
— Methodevaljs(session::Session, jss::JSCode)
session
.Bonito.evaljs_value
— Methodevaljs_value(session::Session, js::JSCode)
js
code and returns the jsonified value. Blocks until value is returned. May block indefinitely, when called with a session that doesn't have a connection to the browser.Bonito.export_static
— Methodexport_static(html_file::Union{IO, String}, app::App)
+export_static(folder::String, routes::Routes)
app
with all its assets a single HTML file. Or exports all routes defined by routes
to folder
.Bonito.interactive_server
— Functioninteractive_server(f, paths, modules=[]; url="127.0.0.1", port=8081, all=true)
using Revise, Website
using Website.Bonito
# Start the interactive server and develop your website!
@@ -210,25 +210,25 @@
dir = joinpath(@__DIR__, "docs")
# only delete the bonito generated files
rm(joinpath(dir, "bonito"); recursive=true, force=true)
-Bonito.export_static(dir, routes)
Bonito.linkjs
— Methodlinkjs(session::Session, a::Observable, b::Observable)
Bonito.onjs
— Methodonjs(session::Session, obs::Observable, func::JSCode)
session
, that get's called when obs
gets a new value. If the observable gets updated from the JS side, the calling of func
will be triggered entirely in javascript, without any communication with the Julia session
.
Bonito.AbstractWebsocketConnection
— TypeWebsocket based connection type
Bonito.CleanupPolicy
— Typeabstract type CleanupPolicy end
You can create a custom cleanup policy by subclassing this type. Implementing the should_cleanup
and allow_soft_close
methods is required. You can also implement set_cleanup_time!
if it makes sense for your policy.
function should_cleanup(policy::MyCleanupPolicy, session::Session)
+Bonito.export_static(dir, routes)
For the complete code, visit the Makie website repository which is using Bonito: MakieOrg/Website
Bonito.linkjs
— Methodlinkjs(session::Session, a::Observable, b::Observable)
for an open session, link a and b on the javascript side. This will also Link the observables in Julia, but only as long as the session is active.
Bonito.onjs
— Methodonjs(session::Session, obs::Observable, func::JSCode)
Register a javascript function with session
, that get's called when obs
gets a new value. If the observable gets updated from the JS side, the calling of func
will be triggered entirely in javascript, without any communication with the Julia session
.
Bonito.AbstractWebsocketConnection
— TypeWebsocket based connection type
Bonito.CleanupPolicy
— Typeabstract type CleanupPolicy end
You can create a custom cleanup policy by subclassing this type. Implementing the should_cleanup
and allow_soft_close
methods is required. You can also implement set_cleanup_time!
if it makes sense for your policy.
function should_cleanup(policy::MyCleanupPolicy, session::Session)
function allow_soft_close(policy::MyCleanupPolicy)
-function set_cleanup_time!(policy::MyCleanupPolicy, time_in_hrs::Real)
This is quite low level, and you implementaiton should probably start by copying DefaultCleanupPolicy
.
Bonito.DefaultCleanupPolicy
— Typemutable struct DefaultCleanupPolicy <: CleanupPolicy
+function set_cleanup_time!(policy::MyCleanupPolicy, time_in_hrs::Real)
This is quite low level, and you implementaiton should probably start by copying DefaultCleanupPolicy
.
Bonito.DefaultCleanupPolicy
— Typemutable struct DefaultCleanupPolicy <: CleanupPolicy
session_open_wait_time=30
cleanup_time=0.0
-end
This is the default cleanup policy. It closes sessions after session_open_wait_time
seconds (default 30) if the browser didn't connect back to the displayed session. It also closes sessions after cleanup_time
hours (default 0) if the session closes cleanly, indicating that the browser may reconnect if a tab is later restored. It returns true for allowsoftclose(...) when cleanup_time
is non-zero.
Bonito.DualWebsocket
— Methodhandles a new websocket connection to a session
Bonito.FrontendConnection
— TypeInteface for FrontendConnection
struct MyConnection <: FrontendConnection
-end
Needs to have a constructor with 0 arguments:
MyConnection()
Needs to overload Base.write
for sending binary data
Base.write(connection::MyConnection, bytes::AbstractVector{UInt8})
Needs to implement isopen to indicate status of connection
Base.isopen(c::MyConnection)
Setup connection will be called before rendering any dom with session
. The return value will be inserted into the DOM of the rendered App and can be used to do the JS part of opening the connection.
Bonito.setup_connection(session::Session{IJuliaConnection})::Union{JSCode, Nothing}
One can overload use_parent_session
, to turn on rendering dom objects inside sub-sessions while keeping one parent session managing the connection alive. This is handy for IJulia/Pluto, since the parent session just needs to be initialized one time and can stay active and globally store objects used multiple times across doms.
Bonito.use_parent_session(::Session{MyConnection}) = false/false
Bonito.JSCode
— TypeJavascript code that supports interpolation of Julia Objects. Construction of JSCode via string macro:
jsc = js"console.log($(some_julia_variable))"
This will decompose into:
jsc.source == [JSString("console.log("), some_julia_variable, JSString(""")]
Bonito.JSException
— MethodCreates a Julia exception from data passed to us by the frondend!
Bonito.JSString
— TypeThe string part of JSCode.
Bonito.JSUpdateObservable
— TypeFunctor to update JS part when an observable changes. We make this a Functor, so we can clearly identify it and don't sent any updates, if the JS side requires to update an Observable (so we don't get an endless update cycle)
Bonito.Table
— TypeA simple wrapper for types that conform to the Tables.jl Table interface, which gets rendered nicely!
Bonito.Label
— MethodLabel(value; style=Styles(), attributes...)
A Label is a simple text element, with a bold font and a font size of 1rem.
Bonito.add_cached!
— Methodadd_cached!(create_cached_object::Function, session::Session, message_cache::Dict{String, Any}, key::String)
Checks if key is already cached by the session or it's root session (we skip any child session between root -> this session). If not cached already, we call create_cached_object
to create a serialized form of the object corresponding to key
and cache it. We return nothing if already cached, or the serialized object if not cached. We also handle the part of adding things to the message_cache from the serialization context.
Bonito.dependency_path
— Methoddependency_path(paths...)
Path to serve downloaded dependencies
Bonito.export_standalone
— Methodexport_standaloneexport_standalone(
+end
This is the default cleanup policy. It closes sessions after session_open_wait_time
seconds (default 30) if the browser didn't connect back to the displayed session. It also closes sessions after cleanup_time
hours (default 0) if the session closes cleanly, indicating that the browser may reconnect if a tab is later restored. It returns true for allowsoftclose(...) when cleanup_time
is non-zero.
Bonito.DualWebsocket
— Methodhandles a new websocket connection to a session
Bonito.FrontendConnection
— TypeInteface for FrontendConnection
struct MyConnection <: FrontendConnection
+end
Needs to have a constructor with 0 arguments:
MyConnection()
Needs to overload Base.write
for sending binary data
Base.write(connection::MyConnection, bytes::AbstractVector{UInt8})
Needs to implement isopen to indicate status of connection
Base.isopen(c::MyConnection)
Setup connection will be called before rendering any dom with session
. The return value will be inserted into the DOM of the rendered App and can be used to do the JS part of opening the connection.
Bonito.setup_connection(session::Session{IJuliaConnection})::Union{JSCode, Nothing}
One can overload use_parent_session
, to turn on rendering dom objects inside sub-sessions while keeping one parent session managing the connection alive. This is handy for IJulia/Pluto, since the parent session just needs to be initialized one time and can stay active and globally store objects used multiple times across doms.
Bonito.use_parent_session(::Session{MyConnection}) = false/false
Bonito.JSCode
— TypeJavascript code that supports interpolation of Julia Objects. Construction of JSCode via string macro:
jsc = js"console.log($(some_julia_variable))"
This will decompose into:
jsc.source == [JSString("console.log("), some_julia_variable, JSString(""")]
Bonito.JSException
— MethodCreates a Julia exception from data passed to us by the frondend!
Bonito.JSString
— TypeThe string part of JSCode.
Bonito.JSUpdateObservable
— TypeFunctor to update JS part when an observable changes. We make this a Functor, so we can clearly identify it and don't sent any updates, if the JS side requires to update an Observable (so we don't get an endless update cycle)
Bonito.Table
— TypeA simple wrapper for types that conform to the Tables.jl Table interface, which gets rendered nicely!
Bonito.Label
— MethodLabel(value; style=Styles(), attributes...)
A Label is a simple text element, with a bold font and a font size of 1rem.
Bonito.add_cached!
— Methodadd_cached!(create_cached_object::Function, session::Session, message_cache::Dict{String, Any}, key::String)
Checks if key is already cached by the session or it's root session (we skip any child session between root -> this session). If not cached already, we call create_cached_object
to create a serialized form of the object corresponding to key
and cache it. We return nothing if already cached, or the serialized object if not cached. We also handle the part of adding things to the message_cache from the serialization context.
Bonito.dependency_path
— Methoddependency_path(paths...)
Path to serve downloaded dependencies
Bonito.export_standalone
— Methodexport_standaloneexport_standalone(
app::App, folder::String;
clear_folder=false, write_index_html=true,
absolute_urls=false, content_delivery_url="file://" * folder * "/",
- single_html=false)
Exports the app defined by app::Application
with all its assets to folder
. Will write the main html out into folder/index.html
. Overwrites all existing files! If this gets served behind a proxy, set absolute_urls=true
and set content_delivery_url
to your proxy url. If clear_folder=true
all files in folder
will get deleted before exporting again! single_html=true
will write out a single html instead of writing out JS depencies as separate files.
Bonito.getextension
— Methodgetextension(path)
Get the file extension of the path. The extension is defined to be the bit after the last dot, excluding any query string.
Examples
julia> Bonito.getextension("foo.bar.js")
+ single_html=false)
Exports the app defined by app::Application
with all its assets to folder
. Will write the main html out into folder/index.html
. Overwrites all existing files! If this gets served behind a proxy, set absolute_urls=true
and set content_delivery_url
to your proxy url. If clear_folder=true
all files in folder
will get deleted before exporting again! single_html=true
will write out a single html instead of writing out JS depencies as separate files.
Bonito.getextension
— Methodgetextension(path)
Get the file extension of the path. The extension is defined to be the bit after the last dot, excluding any query string.
Examples
julia> Bonito.getextension("foo.bar.js")
"js"
julia> Bonito.getextension("https://my-cdn.net/foo.bar.css?version=1")
-"css"
Taken from WebIO.jl
Bonito.is_online
— Methodis_online(path)
Determine whether or not the specified path is a local filesystem path (and not a remote resource that is hosted on, for example, a CDN).
Bonito.jsrender
— Methodjsrender([::Session], x::Any)
Internal render method to create a valid dom. Registers used observables with a session And makes sure the dom only contains valid elements. Overload jsrender(::YourType) To enable putting YourType into a dom element/div. You can also overload it to take a session as first argument, to register messages with the current web session (e.g. via onjs).
Bonito.on_document_load
— Methodon_document_load(session::Session, js::JSCode)
executes javascript after document is loaded
Bonito.onload
— Methodonload(session::Session, node::Node, func::JSCode)
calls javascript func
with node, once node has been displayed.
Bonito.page_html
— Methodpage_html(session::Session, html_body)
Embeds the html_body in a standalone html document!
Bonito.process_message
— Methodprocess_message(session::Session, bytes::AbstractVector{UInt8})
Handles the incoming websocket messages from the frontend. Messages are expected to be gzip compressed and packed via MsgPack.
Bonito.record_states
— Methodrecord_states(session::Session, dom::Hyperscript.Node)
Records the states of all widgets in the dom. Any widget that implements the following interface will be found in the DOM and can be recorded:
# Implementing interface for Bonito.Slider!
+"css"
Taken from WebIO.jl
Bonito.is_online
— Methodis_online(path)
Determine whether or not the specified path is a local filesystem path (and not a remote resource that is hosted on, for example, a CDN).
Bonito.jsrender
— Methodjsrender([::Session], x::Any)
Internal render method to create a valid dom. Registers used observables with a session And makes sure the dom only contains valid elements. Overload jsrender(::YourType) To enable putting YourType into a dom element/div. You can also overload it to take a session as first argument, to register messages with the current web session (e.g. via onjs).
Bonito.on_document_load
— Methodon_document_load(session::Session, js::JSCode)
executes javascript after document is loaded
Bonito.onload
— Methodonload(session::Session, node::Node, func::JSCode)
calls javascript func
with node, once node has been displayed.
Bonito.page_html
— Methodpage_html(session::Session, html_body)
Embeds the html_body in a standalone html document!
Bonito.process_message
— Methodprocess_message(session::Session, bytes::AbstractVector{UInt8})
Handles the incoming websocket messages from the frontend. Messages are expected to be gzip compressed and packed via MsgPack.
Bonito.record_states
— Methodrecord_states(session::Session, dom::Hyperscript.Node)
Records the states of all widgets in the dom. Any widget that implements the following interface will be found in the DOM and can be recorded:
# Implementing interface for Bonito.Slider!
is_widget(::Slider) = true
value_range(slider::Slider) = 1:length(slider.values[])
-to_watch(slider::Slider) = slider.index # the observable that will trigger JS state change
This is experimental and might change in the future! It can also create really large HTML files, since it needs to record all combinations of widget states. It's also not well optimized yet and may create a lot of duplicated messages.
Bonito.register_asset_server!
— Methodregister_asset_server!(condition::Function, ::Type{<: AbstractAssetServer})
Registers a new asset server type. condition
is a function that should return nothing
, if the asset server type shouldn't be used, and an initialized asset server object, if the conditions are right. E.g. The Bonito.NoServer
be used inside an IJulia notebook so it's registered like this:
register_asset_server!(NoServer) do
+to_watch(slider::Slider) = slider.index # the observable that will trigger JS state change
This is experimental and might change in the future! It can also create really large HTML files, since it needs to record all combinations of widget states. It's also not well optimized yet and may create a lot of duplicated messages.
Bonito.register_asset_server!
— Methodregister_asset_server!(condition::Function, ::Type{<: AbstractAssetServer})
Registers a new asset server type. condition
is a function that should return nothing
, if the asset server type shouldn't be used, and an initialized asset server object, if the conditions are right. E.g. The Bonito.NoServer
be used inside an IJulia notebook so it's registered like this:
register_asset_server!(NoServer) do
if isdefined(Main, :IJulia)
return NoServer()
end
@@ -239,7 +239,7 @@
# which is the same as:
force_asset_server!(YourAssetServer)
...
-force_asset_server!()
Bonito.register_connection!
— Methodregister_connection!(condition::Function, ::Type{<: FrontendConnection})
Registers a new Connection type.
condition is a function that should return nothing
, if the connection type shouldn't be used, and an initialized Connection, if the conditions are right. E.g. The IJulia connection should only be used inside an IJulia notebook so it's registered like this:
register_connection!(IJuliaConnection) do
+force_asset_server!()
Bonito.register_connection!
— Methodregister_connection!(condition::Function, ::Type{<: FrontendConnection})
Registers a new Connection type.
condition is a function that should return nothing
, if the connection type shouldn't be used, and an initialized Connection, if the conditions are right. E.g. The IJulia connection should only be used inside an IJulia notebook so it's registered like this:
register_connection!(IJuliaConnection) do
if isdefined(Main, :IJulia)
return IJuliaConnection()
end
@@ -250,4 +250,4 @@
# which is the same as:
force_connection!(YourConnectionType)
...
-force_connection!()
Bonito.replace_expressions
— Methodreplace_expressions(markdown, context)
Replaces all expressions inside markdown
savely, by only supporting getindex/getfield expression that will index into context
Bonito.run_connection_loop
— Methodruns the main connection loop for the websocket
Bonito.set_cleanup_policy!
— Methodset_cleanup_policy!(policy::CleanupPolicy)
You can set a custom cleanup policy by calling this function.
Bonito.set_cleanup_time!
— Methodset_cleanup_time!(time_in_hrs::Real)
Sets the time that sessions remain open after the browser tab is closed. This allows reconnecting to the same session. Only works for Websocket connection inside VSCode right now, and will display the same App again from first display. State that isn't stored in Observables inside that app is lost.
Bonito.setup_websocket_connection_js
— Methodreturns the javascript snippet to setup the connection
Bonito.string_to_markdown
— Functionstring_to_markdown(session::Session, source::String; eval_julia_code=false)
Replaces all interpolation expressions inside markdown
savely, by only supporting getindex/getfield expression that will index into context
. You can eval Julia code blocks by setting eval_julia_code
to a Module, into which the code gets evaluated!
Bonito.update_nocycle!
— MethodUpdate the value of an observable, without sending changes to the JS frontend. This will be used to update updates from the forntend.
Sockets.send
— Methodsend(session::Session; attributes...)
Send values to the frontend via MsgPack for now
Bonito.HTTPServer.Server
— TypeHTTP server with websocket & http routes
Bonito.HTTPServer.Server
— MethodServer( dom, url::String, port::Int; verbose = -1 )
Creates an application that manages the global server state!
Base.wait
— Methodwait(server::Server)
Wait on the server task, i.e. block execution by bringing the server event loop to the foreground.
Bonito.HTTPServer.browser_display
— Methodbrowser_display()
Forces Bonito.App to be displayed in a browser window that gets opened.
Bonito.HTTPServer.local_url
— Methodlocal_url(server::Server, url)
The local url to reach the server, on the server
Bonito.HTTPServer.online_url
— Methodonline_url(server::Server, url)
The url to connect to the server from the internet. Needs to have server.proxy_url
set to the IP or dns route of the server
Bonito.HTTPServer.tryrun
— Methodtryrun(cmd::Cmd)
Try to run a command. Return true
if cmd
runs and is successful (exits with a code of 0
). Return false
otherwise.
Settings
This document was generated with Documenter.jl version 1.8.0 on Friday 24 January 2025. Using Julia version 1.11.3.