Skip to content

Commit

Permalink
Support for .theme file, commented-out precompilation flow (causing p…
Browse files Browse the repository at this point in the history
…recompilation to hang)
  • Loading branch information
essenciary committed Nov 10, 2024
1 parent 7510149 commit 3eee449
Show file tree
Hide file tree
Showing 4 changed files with 140 additions and 65 deletions.
4 changes: 2 additions & 2 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "Stipple"
uuid = "4acbeb90-81a0-11ea-1966-bdaff8155998"
authors = ["Adrian <[email protected]> and the Stipple contributors"]
version = "0.28.18"
version = "0.28.19"

[deps]
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
Expand Down Expand Up @@ -38,7 +38,7 @@ StippleOffsetArraysExt = "OffsetArrays"
DataFrames = "1"
Dates = "1.6"
FilePathsBase = "0.9"
Genie = "5.31"
Genie = "5.31.1"
GenieSession = "1"
GenieSessionFileSession = "1"
JSON = "0.20, 0.21"
Expand Down
92 changes: 89 additions & 3 deletions src/Layout.jl
Original file line number Diff line number Diff line change
Expand Up @@ -319,15 +319,27 @@ function set_theme!(theme::Symbol)
else
THEMES[][Stipple.Theme.THEME_INDEX[]] = Stipple.Theme.to_asset(theme)
end

theme == :usertheme && ! Stipple.Theme.theme_exists(:usertheme) && register_usertheme()
Stipple.Theme.set_theme(theme)

try
read_theme_dotfile() != theme && write_theme_dotfile(theme)
catch ex
@warn "Could not write theme to dotfile: $ex"
end

nothing
end
const set_theme = set_theme!


const THEME_DOTFILE = joinpath(".theme")
const DEFAULT_USER_THEME_FILE = joinpath("css", Stipple.THEMES_FOLDER, "theme.css")
const USER_THEME_WATCHER = Ref(false)
const DOTTHEME_WATCHER = Ref(false)


function set_user_theme_watcher() :: Bool
(USER_THEME_WATCHER[] || ! Genie.Configuration.isdev()) && return false

Expand All @@ -344,6 +356,64 @@ function set_user_theme_watcher() :: Bool
end


function set_dottheme_watcher() :: Bool
(DOTTHEME_WATCHER[] || ! Genie.Configuration.isdev()) && return false

@async Genie.Revise.entr([THEME_DOTFILE]) do
theme_from_dotfile = read_theme_dotfile()
if theme_from_dotfile !== nothing && Stipple.Theme.get_theme() != theme_from_dotfile
if theme_from_dotfile == :usertheme && ! Stipple.Theme.theme_exists(:usertheme)
register_usertheme()
end
set_theme!(theme_from_dotfile)
end
end
DOTTHEME_WATCHER[] = true

true
end


function read_theme_dotfile() :: Union{Symbol,Nothing}
if ! isfile(THEME_DOTFILE)
try
touch(THEME_DOTFILE) # create the file if it doesn't exist
catch ex
@warn "Could not create theme dotfile: $ex"
end

return nothing
end

try
Symbol(open(THEME_DOTFILE, "r") do file
read(file, String)
end)
catch
nothing
end
end


function write_theme_dotfile(theme::Symbol)
isfile(THEME_DOTFILE) || return

open(THEME_DOTFILE, "w") do file
write(file, string(theme))
end

nothing
end


function register_usertheme() :: Bool
isfile(joinpath(Genie.config.server_document_root, DEFAULT_USER_THEME_FILE)) || return false
register_theme(:usertheme, "/" * join(splitpath(DEFAULT_USER_THEME_FILE), "/")) # make this a relative URL

true
end


"""
function theme() :: String
Expand Down Expand Up @@ -375,15 +445,31 @@ function theme(; core_theme::Bool = true) :: Vector{String}

unique!(THEMES[])

has_custom_theme = false
has_dottheme = false

user_theme_file = joinpath(Genie.config.server_document_root, DEFAULT_USER_THEME_FILE)
if isfile(user_theme_file)
register_theme(:usertheme, "/" * join(splitpath(DEFAULT_USER_THEME_FILE), "/")) # make this a relative URL
register_usertheme()
has_custom_theme = true
end

theme_from_dotfile = read_theme_dotfile()
if theme_from_dotfile !== nothing && Stipple.Theme.theme_exists(theme_from_dotfile)
has_dottheme = true
end

if has_dottheme
set_theme!(theme_from_dotfile)
elseif has_custom_theme
set_theme!(:usertheme)
set_user_theme_watcher()
else
set_theme!(Stipple.Theme.get_theme()) # set the default theme
set_theme!(:default)
end

set_dottheme_watcher()
set_user_theme_watcher()

for f in THEMES[]
_o = f()
if _o isa Vector || _o isa Tuple
Expand Down
82 changes: 41 additions & 41 deletions src/Stipple.jl
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ existing Vue.js libraries.
"""
module Stipple

using PrecompileTools
const PRECOMPILE = Ref(false)
const ALWAYS_REGISTER_CHANNELS = Ref(true)
const USE_MODEL_STORAGE = Ref(true)

Expand Down Expand Up @@ -526,7 +524,7 @@ function init(t::Type{M};
# add a timer that checks if the model is outdated and if so prepare the model to be garbage collected
LAST_ACTIVITY[Symbol(getchannel(model))] = now()

PRECOMPILE[] || Timer(setup_purge_checker(model), PURGE_CHECK_DELAY[], interval = PURGE_CHECK_DELAY[])
# PRECOMPILE[] || Timer(setup_purge_checker(model), PURGE_CHECK_DELAY[], interval = PURGE_CHECK_DELAY[])

# register channels and routes only if within a request
if haskey(Genie.Router.params(), :CHANNEL) || haskey(Genie.Router.params(), :ROUTE) || always_register_channels
Expand Down Expand Up @@ -1316,46 +1314,48 @@ include("Layout.jl")
@reexport using .Theme
@reexport using .Layout

# precompilation ...

using Stipple.ReactiveTools

@setup_workload begin
# Putting some things in `setup` can reduce the size of the
# precompile file and potentially make loading faster.
using Genie.HTTPUtils.HTTP
PRECOMPILE[] = true
@compile_workload begin
# all calls in this block will be precompiled, regardless of whether
# they belong to your package or not (on Julia 1.8 and higher)
ui() = [cell("hello"), row("world"), htmldiv("Hello World")]

@app PrecompileApp begin
@in demo_i = 1
@out demo_s = "Hi"

@onchange demo_i begin
println(demo_i)
end
end
# precompilation ...

route("/") do
model = Stipple.ReactiveTools.@init PrecompileApp
page(model, ui) |> html
end
port = tryparse(Int, get(ENV, "STIPPLE_PRECOMPILE_PORT", ""))
port === nothing && (port = rand(8081:8999))
up(port)

precompile_get = tryparse(Bool, get(ENV, "STIPPLE_PRECOMPILE_GET", "1"))
precompile_get === true && HTTP.get("http://localhost:$port")
# The following lines (still) produce an error although
# they pass at the repl. Not very important though.
# HTTP.get("http://localhost:$port$(Genie.Assets.asset_path(Genie.assets_config, :js, file = "channels"))")
# HTTP.get("http://localhost:$port$(Genie.Assets.asset_path(assets_config, :js, file = "stipplecore"))")
down()
end
PRECOMPILE[] = false
end
# using PrecompileTools
# const PRECOMPILE = Ref(false)
# @setup_workload begin
# # Putting some things in `setup` can reduce the size of the
# # precompile file and potentially make loading faster.
# using Genie.HTTPUtils.HTTP
# PRECOMPILE[] = true
# @compile_workload begin
# # all calls in this block will be precompiled, regardless of whether
# # they belong to your package or not (on Julia 1.8 and higher)
# ui() = [cell("hello"), row("world"), htmldiv("Hello World")]

# @app PrecompileApp begin
# @in demo_i = 1
# @out demo_s = "Hi"

# @onchange demo_i begin
# println(demo_i)
# end
# end

# route("/") do
# model = Stipple.ReactiveTools.@init PrecompileApp
# page(model, ui) |> html
# end
# port = tryparse(Int, get(ENV, "STIPPLE_PRECOMPILE_PORT", ""))
# port === nothing && (port = rand(8081:8999))
# up(port)

# precompile_get = tryparse(Bool, get(ENV, "STIPPLE_PRECOMPILE_GET", "1"))
# precompile_get === true && HTTP.get("http://localhost:$port")
# # The following lines (still) produce an error although
# # they pass at the repl. Not very important though.
# # HTTP.get("http://localhost:$port$(Genie.Assets.asset_path(Genie.assets_config, :js, file = "channels"))")
# # HTTP.get("http://localhost:$port$(Genie.Assets.asset_path(assets_config, :js, file = "stipplecore"))")
# down()
# end
# PRECOMPILE[] = false
# end

end
27 changes: 8 additions & 19 deletions src/Theme.jl
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,13 @@ end
"""
Get the current theme.
"""
function set_theme(theme::Symbol)
function set_theme(theme::Symbol) :: Bool
if haskey(get_themes(), theme)
CURRENT_THEME[] = theme
else
error("Theme not found: $theme")
end
return true
end

return false
end


Expand All @@ -68,7 +69,7 @@ end
Unregister a theme.
"""
function unregister_theme(name::Symbol)
theme_exists!(name) && delete!(get_themes(), name)
theme_exists(name) && delete!(get_themes(), name)
end


Expand All @@ -80,23 +81,11 @@ function theme_exists(theme::Symbol)
end


"""
Check if a theme exists, and throw an error if it doesn't.
"""
function theme_exists!(theme::Symbol)
if ! theme_exists(theme)
error("Theme not found: $theme")
end

return true
end


"""
Get the URL or path to the theme's stylesheet.
"""
function to_path(theme::Symbol = CURRENT_THEME[]) :: String
theme_path = theme_exists!(theme) && get_themes()[theme]
theme_path = theme_exists(theme) ? get_themes()[theme] : return ""

return if startswith(theme_path, "http://") || startswith(theme_path, "https://") # external URL
theme_path
Expand All @@ -112,7 +101,7 @@ end
Get the current theme as a stylesheet to be loaded into Stipple.Layout.THEMES[]
"""
function to_asset(theme::Symbol = CURRENT_THEME[]) :: Function
theme_path = theme_exists!(theme) && get_themes()[theme]
theme_path = theme_exists(theme) ? get_themes()[theme] : return () -> ""

return if startswith(theme_path, "http://") || startswith(theme_path, "https://") || startswith(theme_path, "/")
() -> stylesheet(theme_path)
Expand Down

2 comments on commit 3eee449

@essenciary
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/119104

Tip: Release Notes

Did you know you can add release notes too? Just add markdown formatted text underneath the comment after the text
"Release notes:" and it will be added to the registry PR, and if TagBot is installed it will also be added to the
release that TagBot creates. i.e.

@JuliaRegistrator register

Release notes:

## Breaking changes

- blah

To add them here just re-invoke and the PR will be updated.

Tagging

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v0.28.19 -m "<description of version>" 3eee44942fd322981593be570ca51a612a019c8a
git push origin v0.28.19

Please sign in to comment.