mirror of
https://github.com/centau/vide.git
synced 2026-08-20 14:41:37 +00:00
Fix show() edge case
This commit is contained in:
parent
46a2043356
commit
a383c4ce69
2 changed files with 93 additions and 14 deletions
|
|
@ -1,28 +1,33 @@
|
||||||
|
local source = require "./source"
|
||||||
local derive = require "./derive"
|
local derive = require "./derive"
|
||||||
|
local effect = require "./effect"
|
||||||
local untrack = require "./untrack"
|
local untrack = require "./untrack"
|
||||||
|
|
||||||
local function show<T, U>(source: () -> T?, component: (() -> T) -> U, fallback: (() -> U)?): () -> U?
|
local function show<T, U>(input: () -> T?, component: (() -> T) -> U, fallback: (() -> U)?): () -> U?
|
||||||
local truthy = derive(function()
|
local filtered_input = source()
|
||||||
return not not source()
|
|
||||||
|
effect(function()
|
||||||
|
local v = input()
|
||||||
|
if v then
|
||||||
|
filtered_input(v)
|
||||||
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
-- seemingly redundant derivation to extend the reactive graph so that
|
local input_is_truthy = derive(function()
|
||||||
-- the propogation of the source's update is delayed, giving time for
|
return not not input()
|
||||||
-- the show() scope to be destroyed before potential effects registered
|
|
||||||
-- by the component can run when they should not run
|
|
||||||
-- todo: are there cases this method does not cover?
|
|
||||||
local derived = derive(function()
|
|
||||||
return source()
|
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
-- todo: is this needed?
|
||||||
|
-- local filtered_input_is_truthy = derive(function()
|
||||||
|
-- return not not filtered_input()
|
||||||
|
-- end)
|
||||||
|
|
||||||
return derive(function()
|
return derive(function()
|
||||||
return
|
return
|
||||||
if truthy() then untrack(function() return component(derived :: () -> T) end)
|
if input_is_truthy() then untrack(function() return component(filtered_input :: () -> T) end)
|
||||||
elseif fallback then untrack(fallback)
|
elseif fallback then untrack(fallback)
|
||||||
else nil
|
else nil
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
return show :: (
|
return show
|
||||||
( <T, U>(source: () -> T?, component: (() -> T) -> U) -> () -> U? )
|
|
||||||
)
|
|
||||||
|
|
|
||||||
|
|
@ -1153,6 +1153,80 @@ TEST("show()", wrap_root(function()
|
||||||
CHECK(count == 3)
|
CHECK(count == 3)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
do CASE "special strict case"
|
||||||
|
type Weapon = {
|
||||||
|
id: string,
|
||||||
|
enchant: string?
|
||||||
|
}
|
||||||
|
|
||||||
|
vide.strict = true
|
||||||
|
|
||||||
|
local count = 0
|
||||||
|
local branch = 0
|
||||||
|
|
||||||
|
local weapon = source(nil :: Weapon?)
|
||||||
|
|
||||||
|
effect(function()
|
||||||
|
weapon()
|
||||||
|
end)
|
||||||
|
|
||||||
|
effect(function()
|
||||||
|
weapon()
|
||||||
|
end)
|
||||||
|
|
||||||
|
show(weapon, function(weapon: () -> Weapon)
|
||||||
|
local enchant = function() return weapon().enchant end
|
||||||
|
|
||||||
|
show(enchant, function(enchant: () -> string)
|
||||||
|
effect(function()
|
||||||
|
local e = enchant()
|
||||||
|
count += 1
|
||||||
|
CHECK(e ~= nil)
|
||||||
|
if branch == 1 then
|
||||||
|
CHECK(e == "fire")
|
||||||
|
elseif branch == 2 then
|
||||||
|
CHECK(e == "poison")
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
return {}
|
||||||
|
end)
|
||||||
|
|
||||||
|
return {}
|
||||||
|
end)
|
||||||
|
|
||||||
|
effect(function()
|
||||||
|
weapon()
|
||||||
|
end)
|
||||||
|
|
||||||
|
effect(function()
|
||||||
|
weapon()
|
||||||
|
end)
|
||||||
|
|
||||||
|
branch = 1
|
||||||
|
weapon { id = "1", enchant = "fire" }
|
||||||
|
CHECK(count == 8)
|
||||||
|
|
||||||
|
branch = 2
|
||||||
|
weapon { id = "1", enchant = "poison" }
|
||||||
|
CHECK(count == 10)
|
||||||
|
|
||||||
|
weapon { id = "1", enchant = nil }
|
||||||
|
CHECK(count == 10)
|
||||||
|
|
||||||
|
branch = 1
|
||||||
|
weapon { id = "1", enchant = "fire" }
|
||||||
|
CHECK(count == 14)
|
||||||
|
|
||||||
|
weapon(nil)
|
||||||
|
|
||||||
|
branch = 2
|
||||||
|
weapon { id = "1", enchant = "poison" }
|
||||||
|
CHECK(count == 22)
|
||||||
|
|
||||||
|
vide.strict = false
|
||||||
|
end
|
||||||
|
|
||||||
do CASE "alt" -- todo: move test
|
do CASE "alt" -- todo: move test
|
||||||
local visible = vide.source(true)
|
local visible = vide.source(true)
|
||||||
local count = vide.source(0)
|
local count = vide.source(0)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue