import { type BindingSpec, type Mountable, type SignalDoc } from './build-context.js'; import type { Renderable } from './element.js'; import { type RowCtx } from './row.js'; import type { TransitionOptions } from '../types.js'; export type { RowCtx } from './row.js'; /** Items source for `signalEach`: an accessor reading the array out of the * component state, plus the dep paths the list depends on — the items path AND * any component-state paths the rows read (so the list reconciles on either). */ export interface EachSource { items: (state: unknown) => readonly T[]; deps: readonly string[]; /** See {@link BindingSpec.componentRooted}: `true` when the items accessor reads * the COMPONENT state (so a nested each reads `ctx.state`, not the enclosing row * ctx). Set by the authoring layer from the items handle; unbranded → inference. */ componentRooted?: boolean; } /** A compiler-emitted (or hand-written) direct `each` row: real DOM nodes built * with direct ops + binding specs wired by DIRECT node reference — bypassing the * authoring-helper / `Mountable` / `populate` / `pathHandle` machinery the * generic row path runs per row. The factory runs per row under the build ctx; * each spec's `produce(ctx)` reads the row ctx (`{ item, state, index }`) and its * `commit` writes straight to the located node. See * `docs/proposals/v2-compiler/compiled-row-construction.md`. */ export interface DirectRow { nodes: Node[]; bindings: readonly BindingSpec[]; } /** Builds a fresh {@link DirectRow} (new nodes + binding closures) per row. * `getCtx` exposes the row's LIVE `{ item, state, index }` ctx (the same box the * binding `produce(ctx)` reads), so a row's event-handler closures can read the * current row item at event time — `onClick: () => send({ type: 'toggle', id: * getCtx().item.id })` — the direct-path analogue of the render path's * `pathHandle(getCtx, 'item')`. Rows with no item-referencing handlers ignore it. */ export type RowFactory = (doc: SignalDoc, getCtx: () => RowCtx) => DirectRow; /** * Keyed list primitive. A structural binding gated on the list's deps (items * path + row-state paths); on change it reconciles by key. Each row is its OWN * signal scope mounted on a combined `{ item, state }` context — so a row reacts * to its item AND to component state, with per-row, per-binding gating (a shared * state change fans out only to the row bindings that read it; item changes hit * only that row). Kept rows are mutated in place, never recreated. * * Reorder is move-minimizing via a longest-increasing-subsequence pass over the * rows' previous DOM positions: only `n − |LIS|` rows move, so a 2-row swap is 2 * DOM moves and a single removal is 0 — not the O(n) re-insert the naive cursor * walk degraded to (swap/remove were ~6×/4× slower than peer frameworks). */ export declare function signalEach(source: EachSource, key: (item: T) => string | number, renderRow: (getCtx: () => RowCtx) => Renderable, extraDeps?: readonly string[], transition?: TransitionOptions): Mountable; /** Direct-construction keyed list: same keyed reconcile as {@link signalEach}, * but each row is built by a {@link RowFactory} (direct DOM + direct binding * wiring) instead of running authoring helpers per row. The compiler-emitted fast * path for lowerable rows; also usable hand-written. */ export declare function signalEachDirect(source: EachSource, key: (item: T) => string | number, rowFactory: RowFactory, extraDeps?: readonly string[], transition?: TransitionOptions): Mountable; //# sourceMappingURL=each.d.ts.map