mirror of
https://github.com/littensy/charm.git
synced 2026-10-20 17:51:37 +00:00
feat: pass cleanup function to effect (#40)
This commit is contained in:
parent
6be2fbb746
commit
89f1dfeaa5
3 changed files with 35 additions and 11 deletions
|
|
@ -9,9 +9,11 @@ type Cleanup = () -> ()
|
|||
@param callback The function to run.
|
||||
@return A function that unsubscribes the callback.
|
||||
]=]
|
||||
local function effect(callback: () -> Cleanup?): Cleanup
|
||||
local dependencies, cleanup = store.capture(callback)
|
||||
local function effect(callback: (cleanup: Cleanup) -> Cleanup?): Cleanup
|
||||
local dependencies = {}
|
||||
local cleanup: Cleanup?
|
||||
local disconnected = false
|
||||
local disconnect
|
||||
|
||||
local function listener()
|
||||
if cleanup then
|
||||
|
|
@ -19,16 +21,14 @@ local function effect(callback: () -> Cleanup?): Cleanup
|
|||
end
|
||||
|
||||
store.disconnect(dependencies, listener)
|
||||
dependencies, cleanup = store.capture(callback)
|
||||
dependencies, cleanup = store.capture(callback, disconnect)
|
||||
|
||||
if not disconnected then
|
||||
store.connect(dependencies, listener)
|
||||
end
|
||||
end
|
||||
|
||||
store.connect(dependencies, listener)
|
||||
|
||||
return function()
|
||||
function disconnect()
|
||||
if disconnected then
|
||||
return
|
||||
end
|
||||
|
|
@ -40,6 +40,14 @@ local function effect(callback: () -> Cleanup?): Cleanup
|
|||
cleanup()
|
||||
end
|
||||
end
|
||||
|
||||
dependencies, cleanup = store.capture(callback, disconnect)
|
||||
|
||||
if not disconnected then
|
||||
store.connect(dependencies, listener)
|
||||
end
|
||||
|
||||
return disconnect
|
||||
end
|
||||
|
||||
return effect :: (callback: (() -> ()) | (() -> Cleanup)) -> Cleanup
|
||||
return effect :: (callback: ((cleanup: Cleanup) -> ()) | ((cleanup: Cleanup) -> Cleanup?)) -> Cleanup
|
||||
|
|
|
|||
|
|
@ -133,9 +133,10 @@ end
|
|||
@param callback The function to run.
|
||||
@return A tuple containing the captured atoms and the result of the function.
|
||||
]=]
|
||||
local function capture<T>(callback: () -> T): (Set<Atom<any>>, T)
|
||||
if listeners[callback] then
|
||||
return { [callback] = true }, peek(callback)
|
||||
local function capture<T, U...>(callback: (U...) -> T, ...: U...): (Set<Atom<any>>, T)
|
||||
-- If the callback is an atom, return it immediately
|
||||
if listeners[callback :: any] then
|
||||
return { [callback :: any] = true }, peek(callback)
|
||||
end
|
||||
|
||||
local dependencies: Set<Atom<any>> = {}
|
||||
|
|
@ -146,7 +147,7 @@ local function capture<T>(callback: () -> T): (Set<Atom<any>>, T)
|
|||
local result = try(callback, function()
|
||||
capturing.stack[capturing.index] = nil
|
||||
capturing.index -= 1
|
||||
end)
|
||||
end, ...)
|
||||
|
||||
return dependencies, result
|
||||
end
|
||||
|
|
|
|||
|
|
@ -93,4 +93,19 @@ return function()
|
|||
a(2)
|
||||
a(3)
|
||||
end)
|
||||
|
||||
it("allows immediate self-cleanup", function()
|
||||
local a = atom(1)
|
||||
local cleanedUp = false
|
||||
|
||||
effect(function(cleanup)
|
||||
assert(not cleanedUp, "cleanup ran twice")
|
||||
cleanup()
|
||||
cleanedUp = true
|
||||
a()
|
||||
end)
|
||||
|
||||
a(2)
|
||||
a(3)
|
||||
end)
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue