Skip to content

Commit

Permalink
support Inf and NaN for Floats, BE to FE still needs a patched JSON3,…
Browse files Browse the repository at this point in the history
… PR pending
  • Loading branch information
hhaensel committed Jan 2, 2025
1 parent ab2bb74 commit 0b83710
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 5 deletions.
25 changes: 25 additions & 0 deletions src/stipple/jsmethods.jl
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,31 @@ function js_add_reviver(revivername::String)
"""
end

"""
js_add_serializer(serializername::String)
Add a serializer function to the list of Genie's serializers.
This function is meant for package developer who want to make additional js content available for the user.
This resulting script needs to be added to the dependencies of an app in order to be executed.
If you want to add a custom serializer to your model you should rather consider using `@mounted`, e.g.
```julia
@methods \"\"\"
myserializer: function(value) { return value + 1 }
\"\"\"
@mounted "Genie.Serializers.addSerializer(this.myserializer)"
```
"""
function js_add_serializer(serializername::String)
"""
document.addEventListener('DOMContentLoaded', () => Genie.WebChannels.subscriptionHandlers.push(function(event) {
Genie.Serializers.addSerializer($serializername);
}));
"""
end

"""
js_initscript(initscript::String)
Expand Down
5 changes: 4 additions & 1 deletion src/stipple/json.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
const JSONParser = JSON3
const json = JSON3.write

# for inf values no reviver is necessary, but
stipple_inf_mapping(x) = x == Inf ? "1e1000" : x == -Inf ? "-1e1000" : "\"__nan__\""
json(args; inf_mapping::Function = stipple_inf_mapping, kwargs...) = JSON3.write(args; inf_mapping, kwargs...)

struct JSONText
s::String
Expand Down
10 changes: 9 additions & 1 deletion src/stipple/parsers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,15 @@ end

#String to AbstractFloat
function stipple_parse(::Type{T}, value::String) where T<:AbstractFloat
Base.parse(T, value)
if value == "__nan__"
NaN
elseif value == "__inf__"
Inf
elseif value == "__neginf__"
-Inf
else
Base.parse(T, value)
end
end

# Union with Nothing
Expand Down
2 changes: 1 addition & 1 deletion src/stipple/rendering.jl
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ function Stipple.render(app::M)::Dict{Symbol,Any} where {M<:ReactiveModel}
end

# convert :data to () => ({ })
data = JSON3.write(merge(result, client_data(app)))
data = json(merge(result, client_data(app)))

vue = Dict(
:mixins => JSONText("[watcherMixin, reviveMixin, eventMixin, filterMixin]"),
Expand Down
4 changes: 2 additions & 2 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -621,7 +621,7 @@ end
@test exported_values[:s] == "Hello"
@test exported_values[:x] == 4

values_json = JSON3.write(exported_values)
values_json = Stipple.json(exported_values)
exported_values_json = Stipple.ModelStorage.model_values(model, json = true)
@test values_json == exported_values_json

Expand All @@ -631,7 +631,7 @@ end
@test model.s[] == "world"
@test model.x[] == 5

values_json = Dict(:i => 30, :s => "zero", :x => 50) |> JSON3.write |> string
values_json = Dict(:i => 30, :s => "zero", :x => 50) |> Stipple.json |> string
Stipple.ModelStorage.load_model_values!(model, values_json)
@test model.i[] == 30
@test model.s[] == "zero"
Expand Down

0 comments on commit 0b83710

Please sign in to comment.