mirror of
https://github.com/littensy/charm.git
synced 2026-10-21 03:36:11 +00:00
fix: avoid reconnecting to dependencies after cleanup (#14)
* fix: cancel reconnection when unsubscribing * test: remove print * feat: allow factory to return nil * perf: use `next` iteration
This commit is contained in:
parent
62be3e496d
commit
c6762a6525
14 changed files with 87 additions and 63 deletions
|
|
@ -2,6 +2,8 @@ local effect = require(script.Parent.effect)
|
|||
local types = require(script.Parent.types)
|
||||
type Molecule<T> = types.Molecule<T>
|
||||
|
||||
local function noop() end
|
||||
|
||||
--[=[
|
||||
Creates an instance of `factory` for each item in the atom's state, and
|
||||
cleans up the instance when the item is removed. Returns a cleanup function
|
||||
|
|
@ -11,34 +13,38 @@ type Molecule<T> = types.Molecule<T>
|
|||
@param factory The function that tracks the lifecycle of each item.
|
||||
@return A function that unsubscribes all instances.
|
||||
]=]
|
||||
local function observe<K, V>(molecule: Molecule<{ [K]: V }>, factory: (value: V, key: K) -> () -> ()): () -> ()
|
||||
local function observe<K, V>(molecule: Molecule<{ [K]: V }>, factory: (value: V, key: K) -> (() -> ())?): () -> ()
|
||||
local connections: { [K]: () -> () } = {}
|
||||
|
||||
local unsubscribe = effect(function()
|
||||
local state = molecule()
|
||||
|
||||
for key, disconnect in connections do
|
||||
for key, disconnect in next, connections do
|
||||
if state[key] == nil then
|
||||
connections[key] = nil
|
||||
disconnect()
|
||||
end
|
||||
end
|
||||
|
||||
for key, value in state do
|
||||
for key, value in next, state do
|
||||
if not connections[key] then
|
||||
connections[key] = factory(value, key)
|
||||
connections[key] = factory(value, key) or noop
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
local function cleanup()
|
||||
unsubscribe()
|
||||
for _, disconnect in connections do
|
||||
for _, disconnect in next, connections do
|
||||
disconnect()
|
||||
end
|
||||
table.clear(connections)
|
||||
end
|
||||
|
||||
return cleanup
|
||||
end
|
||||
|
||||
return observe
|
||||
return observe :: <K, V>(
|
||||
molecule: Molecule<{ [K]: V }>,
|
||||
factory: ((value: V, key: K) -> () -> ()) | (value: V, key: K) -> ()
|
||||
) -> () -> ()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue