Fix show() edge case

This commit is contained in:
aaron 2025-01-06 23:56:49 +00:00
parent 46a2043356
commit a383c4ce69
2 changed files with 93 additions and 14 deletions

View file

@ -1,28 +1,33 @@
local source = require "./source"
local derive = require "./derive"
local effect = require "./effect"
local untrack = require "./untrack"
local function show<T, U>(source: () -> T?, component: (() -> T) -> U, fallback: (() -> U)?): () -> U?
local truthy = derive(function()
return not not source()
local function show<T, U>(input: () -> T?, component: (() -> T) -> U, fallback: (() -> U)?): () -> U?
local filtered_input = source()
effect(function()
local v = input()
if v then
filtered_input(v)
end
end)
-- seemingly redundant derivation to extend the reactive graph so that
-- the propogation of the source's update is delayed, giving time for
-- 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()
local input_is_truthy = derive(function()
return not not input()
end)
-- todo: is this needed?
-- local filtered_input_is_truthy = derive(function()
-- return not not filtered_input()
-- end)
return derive(function()
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)
else nil
end)
end
return show :: (
( <T, U>(source: () -> T?, component: (() -> T) -> U) -> () -> U? )
)
return show