π File detail
ink/node-cache.ts
π§© .tsπ 55 linesπΎ 1,654 bytesπ text
β Back to All Filesπ― Use case
This file lives under βink/β, which covers Ink terminal UI (layouts, TTY IO, keyboard, renderer components). On the API surface it exposes CachedLayout, nodeCache, pendingClears, addPendingClear, and consumeAbsoluteRemovedFlag β mainly functions, hooks, or classes. It composes internal code from dom and layout (relative imports).
Generated from folder role, exports, dependency roots, and inline comments β not hand-reviewed for every path.
π§ Inline summary
import type { DOMElement } from './dom.js' import type { Rectangle } from './layout/geometry.js' /** * Cached layout bounds for each rendered node (used for blit + clearing).
π€ Exports (heuristic)
CachedLayoutnodeCachependingClearsaddPendingClearconsumeAbsoluteRemovedFlag
π₯οΈ Source preview
import type { DOMElement } from './dom.js'
import type { Rectangle } from './layout/geometry.js'
/**
* Cached layout bounds for each rendered node (used for blit + clearing).
* `top` is the yoga-local getComputedTop() β stored so ScrollBox viewport
* culling can skip yoga reads for clean children whose position hasn't
* shifted (O(dirty) instead of O(mounted) first-pass).
*/
export type CachedLayout = {
x: number
y: number
width: number
height: number
top?: number
}
export const nodeCache = new WeakMap<DOMElement, CachedLayout>()
/** Rects of removed children that need clearing on next render */
export const pendingClears = new WeakMap<DOMElement, Rectangle[]>()
/**
* Set when a pendingClear is added for an absolute-positioned node.
* Signals renderer to disable blit for the next frame: the removed node
* may have painted over non-siblings (e.g. an overlay over a ScrollBox
* earlier in tree order), so their blits from prevScreen would restore
* the overlay's pixels. Normal-flow removals are already handled by
* hasRemovedChild at the parent level; only absolute positioning paints
* cross-subtree. Reset at the start of each render.
*/
let absoluteNodeRemoved = false
export function addPendingClear(
parent: DOMElement,
rect: Rectangle,
isAbsolute: boolean,
): void {
const existing = pendingClears.get(parent)
if (existing) {
existing.push(rect)
} else {
pendingClears.set(parent, [rect])
}
if (isAbsolute) {
absoluteNodeRemoved = true
}
}
export function consumeAbsoluteRemovedFlag(): boolean {
const had = absoluteNodeRemoved
absoluteNodeRemoved = false
return had
}