agnostic/vdom/cache
Types
pub opaque type DecodedEvent(message)
Event handlers form a tree.
Whenever we encounter a Map node, the transformation on the final
message type changes. Instead of transforming the handlers directly,
we generate isolated event subtrees. This keeps subtrees stable even
when a parent Map node updates.
This is necessary for Memo to function, since Memo does not update the old events when its dependencies don’t change.
🚨 This means that the message type in handlers is a lie until we actually
handle an evnet!
pub opaque type Events(message)
pub type Mapper =
fn(dynamic.Dynamic) -> dynamic.Dynamic
Values
pub fn add_child(
cache: Cache(message),
events: Events(message),
parent: path.Path,
index: Int,
child: vnode.Element(message),
) -> #(Cache(message), Events(message))
pub fn add_children(
cache: Cache(message),
events: Events(message),
path: path.Path,
child_index: Int,
nodes: List(vnode.Element(message)),
) -> #(Cache(message), Events(message))
pub fn add_event(
events: Events(message),
path: path.Path,
name: String,
handler: decode.Decoder(vattr.Handler(message)),
) -> Events(message)
pub fn add_memo(
cache: Cache(message),
new new: fn() -> vnode.Element(message),
node node: vnode.Element(message),
) -> Cache(message)
Caches a newly computed element when dependencies changed.
pub fn compose_mapper(
mapper: fn(dynamic.Dynamic) -> dynamic.Dynamic,
child_mapper: fn(dynamic.Dynamic) -> dynamic.Dynamic,
) -> fn(dynamic.Dynamic) -> dynamic.Dynamic
pub fn decode(
cache: Cache(message),
path: String,
name: String,
event: dynamic.Dynamic,
) -> DecodedEvent(message)
pub fn dispatch(
cache: Cache(message),
event: DecodedEvent(message),
) -> #(Cache(message), Result(vattr.Handler(message), Nil))
pub fn from_node(root: vnode.Element(message)) -> Cache(message)
pub fn get_old_memo(
cache: Cache(message),
old old: fn() -> vnode.Element(message),
new new: fn() -> vnode.Element(message),
) -> vnode.Element(message)
pub fn get_subtree(
events: Events(message),
path: String,
old_mapper old_mapper: fn(dynamic.Dynamic) -> dynamic.Dynamic,
) -> Events(message)
Gets the isolated event subtree for a Map node.
pub fn handle(
cache: Cache(message),
path: String,
name: String,
event: dynamic.Dynamic,
) -> #(Cache(message), Result(vattr.Handler(message), Nil))
pub fn keep_memo(
cache: Cache(message),
old old: fn() -> vnode.Element(message),
new new: fn() -> vnode.Element(message),
) -> Cache(message)
Reuses the cached element when dependencies are unchanged.
Also walks the kept node and copies any nested memos’ cached vdoms from
old_vdoms into the new vdoms. Without this, an outer-memo True branch
(deps unchanged) would skip diffing the inner content, and the inner
memo’s view-fn would fall out of the cache on the next tick. A later
outer-memo False branch (deps differ) would then recurse into the cached
inner memo, call get_old_memo on the inner view-fn, miss the cache,
and fall back to evaluating the previous render’s closure — which can
return a structure that no longer matches the live metadata tree,
producing a flattened patch path with steps that overrun the metadata.
pub fn memos(
cache: Cache(message),
) -> mutable_map.MutableMap(
fn() -> vnode.Element(message),
vnode.Element(message),
)
Get a dictionary of all materialised Memo views.
pub fn new_events() -> Events(message)
pub fn remove_child(
cache: Cache(message),
events: Events(message),
parent: path.Path,
child_index: Int,
child: vnode.Element(message),
) -> Events(message)
pub fn replace_child(
cache: Cache(message),
events: Events(message),
parent: path.Path,
child_index: Int,
prev: vnode.Element(message),
next: vnode.Element(message),
) -> #(Cache(message), Events(message))
pub fn update_subtree(
parent: Events(message),
path: String,
mapper mapper: fn(dynamic.Dynamic) -> dynamic.Dynamic,
events events: Events(message),
) -> Events(message)
Updates the Map node’s isolated event subtree after diffing its child.