kerfjs 4.4.1 → 5.0.0-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +99 -0
- package/LICENSE +1 -1
- package/README.md +3 -3
- package/ai/cursorrules +46 -1
- package/ai/manifest.json +62 -5
- package/ai/skill.md +53 -2
- package/dist/actions.d.ts +1 -1
- package/dist/actions.js +4 -4
- package/dist/actions.js.map +1 -1
- package/dist/array-signal.js +5 -5
- package/dist/async.js +17 -10
- package/dist/async.js.map +1 -1
- package/dist/attach.d.ts +11 -8
- package/dist/attach.js +52 -4
- package/dist/attach.js.map +1 -1
- package/dist/chunk-GY4XV2UV.js +1 -1
- package/dist/{chunk-VVDJLWMP.js → chunk-HW7KSM2Y.js} +2 -2
- package/dist/chunk-HW7KSM2Y.js.map +1 -0
- package/dist/{chunk-KEZTD6H4.js → chunk-KPXIOG2C.js} +3 -3
- package/dist/{chunk-KEZTD6H4.js.map → chunk-KPXIOG2C.js.map} +1 -1
- package/dist/{chunk-SAYPJ6XR.js → chunk-KZJXHFIB.js} +10 -6
- package/dist/chunk-KZJXHFIB.js.map +1 -0
- package/dist/{chunk-MRYM3O3V.js → chunk-LVH3GC6B.js} +11 -8
- package/dist/chunk-LVH3GC6B.js.map +1 -0
- package/dist/chunk-QIP723L4.js +1 -1
- package/dist/{chunk-SRWQKB33.js → chunk-SVATPF5R.js} +97 -74
- package/dist/chunk-SVATPF5R.js.map +1 -0
- package/dist/{chunk-3APBEVHF.js → chunk-U6FK33SG.js} +3 -3
- package/dist/{chunk-3APBEVHF.js.map → chunk-U6FK33SG.js.map} +1 -1
- package/dist/{chunk-U32TFTGZ.js → chunk-UZJ6I4T6.js} +3 -3
- package/dist/chunk-UZJ6I4T6.js.map +1 -0
- package/dist/{chunk-YHH7OUFA.js → chunk-V46JKE44.js} +3 -3
- package/dist/chunk-V46JKE44.js.map +1 -0
- package/dist/{chunk-SUPUPSBE.js → chunk-ZDCJZCNO.js} +9 -8
- package/dist/chunk-ZDCJZCNO.js.map +1 -0
- package/dist/dev.d.ts +9 -6
- package/dist/dev.js +5 -5
- package/dist/dev.js.map +1 -1
- package/dist/html.d.ts +1 -1
- package/dist/html.js +5 -5
- package/dist/html.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +11 -11
- package/dist/jsx-runtime.js +5 -5
- package/dist/list.d.ts +1 -1
- package/dist/list.js +273 -211
- package/dist/list.js.map +1 -1
- package/dist/overlay.d.ts +190 -280
- package/dist/overlay.js +401 -361
- package/dist/overlay.js.map +1 -1
- package/dist/remount.d.ts +5 -3
- package/dist/remount.js +29 -10
- package/dist/remount.js.map +1 -1
- package/dist/router.d.ts +1 -1
- package/dist/router.js +44 -22
- package/dist/router.js.map +1 -1
- package/dist/scope.d.ts +4 -3
- package/dist/scope.js +10 -10
- package/dist/scope.js.map +1 -1
- package/dist/testing.js +4 -4
- package/dist/timing.d.ts +3 -2
- package/dist/timing.js +5 -5
- package/dist/timing.js.map +1 -1
- package/llms.txt +7 -4
- package/package.json +12 -8
- package/dist/chunk-MRYM3O3V.js.map +0 -1
- package/dist/chunk-SAYPJ6XR.js.map +0 -1
- package/dist/chunk-SRWQKB33.js.map +0 -1
- package/dist/chunk-SUPUPSBE.js.map +0 -1
- package/dist/chunk-U32TFTGZ.js.map +0 -1
- package/dist/chunk-VVDJLWMP.js.map +0 -1
- package/dist/chunk-YHH7OUFA.js.map +0 -1
- /package/dist/{attrSelector-Cmu2ZoGO.d.ts → attr-Cmu2ZoGO.d.ts} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/list-render-state.ts","../src/each.ts","../src/list-reconcile-focus.ts","../src/utils/moveNode.ts","../src/morph.ts","../src/list-binding.ts","../src/list-reconcile-fast-paths.ts","../src/list-reconcile-granular.ts","../src/list-reconcile-inplace.ts","../src/list-reconcile-snapshot.ts","../src/list-reconcile.ts","../src/mount.ts"],"names":["cache","TEXT_NODE","ELEMENT_NODE","isUserAgentOwnedAttr"],"mappings":"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","file":"chunk-SVATPF5R.js","sourcesContent":["/**\n * The list reconciler's dispatch state machine, reified (KF-336: the states\n * and transitions were previously implicit — inferred from `bindingCounts`\n * presence, `count === 0` sentinels, and patch-queue scans scattered across\n * `each.ts` and the reconciler files; a shipped transition bug (select-after-\n * delete / append-after-clear) motivated making them explicit and walkable).\n *\n * ## States (per list id, derived from the tracked binding count)\n *\n * - `unbound` — no successful reconcile recorded for this list id yet\n * (first render of the list, or the record was cleared by throw recovery).\n * - `empty` — the last reconcile left the binding with zero rows\n * (cleared / emptied list). Repopulating is structurally a first render.\n * - `bound` — the binding holds ≥ 1 live row the granular path can patch.\n *\n * ## Transition table (what the next render does)\n *\n * state + input → path (reason)\n * ─────────────────────────────────────────────────────────────────────────\n * unbound + anything → snapshot first-render\n * empty + anything → snapshot empty-binding\n * bound + no queued patches → snapshot no-patches\n * bound + queue contains a `replace` → snapshot replace\n * bound + count + netΔ(inserts−removes) ≠ snapshot → snapshot count-drift\n * bound + a bound row's `cacheKey` changed → snapshot cachekey-drift †\n * bound + a patch row's render() threw → snapshot render-threw †\n * any + this id now holds a DIFFERENT source → snapshot source-reuse †\n * bound + otherwise → granular\n *\n * † decided in `each.ts:eachGranular` around this module's structural\n * decision, because each needs side effects or context the pure\n * function must not own. `source-reuse` (KF-388) is checked FIRST and\n * short-circuits the rest: a list's id is its call-order index, so when a\n * render changes how many `each()` calls precede this one, this id's\n * recorded state belongs to a different list entirely — including the\n * count the drift arm above would otherwise trust. The other two: the `cacheKey` scan doubles as the dependency-tracking read that\n * keeps external selection signals subscribed, and the pre-render\n * try/catch drives throw recovery (which also resets the list to\n * `unbound` via `bindingCounts.delete(id)` so the NEXT render snapshot-\n * rebuilds instead of trusting a stale count).\n *\n * After every successful reconcile, `mount()` records the binding's row count,\n * which is what `deriveListRenderState` reads next render. `reconcileList`'s\n * routing (`list-reconcile.ts`) is the same machine observed from the DOM\n * side: a granular segment only applies when the live binding is non-empty —\n * `each()` guarantees that by never emitting patches from a non-`bound` state.\n */\n\n/** Per-list dispatch state, derived from the tracked post-reconcile row count. */\nexport type ListRenderState = 'unbound' | 'empty' | 'bound';\n\n/** Derive the list's dispatch state from `mount()`'s recorded binding count. */\nexport function deriveListRenderState(bindingCount: number | undefined): ListRenderState {\n if (bindingCount === undefined) return 'unbound';\n return bindingCount === 0 ? 'empty' : 'bound';\n}\n\n/** Why a render was routed to the snapshot path (see the transition table). */\nexport type SnapshotReason =\n | 'first-render'\n | 'empty-binding'\n | 'no-patches'\n | 'replace'\n | 'count-drift'\n | 'cachekey-drift'\n | 'render-threw';\n\nexport type ListPathDecision =\n | { path: 'snapshot'; reason: SnapshotReason }\n | { path: 'granular' };\n\n/**\n * The structural half of the dispatch: everything decidable from the state +\n * the drained patch queue + the snapshot length, with no side effects. The\n * two side-effectful reasons (`cachekey-drift`, `render-threw`) are layered\n * on by `eachGranular` after a `granular` decision here — see the † note in\n * the transition table above.\n *\n * `patches` must be the fully-drained queue for this render (drained BEFORE\n * deciding, so a snapshot route still consumes them — the snapshot already\n * reflects every queued mutation).\n */\nexport function decideListPath(\n state: ListRenderState,\n patches: ReadonlyArray<{ type: string }>,\n snapshotLength: number,\n previousBindingCount: number | undefined,\n): ListPathDecision {\n if (state === 'unbound') return { path: 'snapshot', reason: 'first-render' };\n if (state === 'empty') return { path: 'snapshot', reason: 'empty-binding' };\n if (patches.length === 0) return { path: 'snapshot', reason: 'no-patches' };\n // One pass: a `replace` wins immediately (wholesale reset — granular can't\n // help), otherwise accumulate the net structural delta for drift detection.\n let netDelta = 0;\n for (const p of patches) {\n if (p.type === 'insert') netDelta += 1;\n else if (p.type === 'remove') netDelta -= 1;\n else if (p.type === 'replace') return { path: 'snapshot', reason: 'replace' };\n }\n // `state === 'bound'` implies the count is a positive number; the cast-free\n // fallback keeps the function total for defensive callers.\n const count = previousBindingCount ?? 0;\n // Drift: after a clean prior reconcile, count + netΔ must equal the\n // snapshot. A mismatch means a granular DOM reconcile failed after its\n // patches were drained, or an external party drained/mutated behind the\n // signal's back — rebuild.\n if (count + netDelta !== snapshotLength) {\n return { path: 'snapshot', reason: 'count-drift' };\n }\n return { path: 'granular' };\n}\n","/**\n * `each(items, render, cacheKey?)` — keyed list iteration with per-item memoization.\n *\n * Drops in as the body of a list-rendering JSX expression inside a `mount()`\n * render function. Returns a `SafeHtml` carrying a structured list segment,\n * so `mount()` can run a native keyed reconciler instead of the general-\n * purpose morph for these children.\n *\n * Two layers of optimization:\n *\n * 1. Per-item memoization. `render(item)` is skipped for items whose object\n * identity (and optional `cacheKey`) are unchanged since the previous\n * call. Their HTML strings come from a `WeakMap` keyed by item reference.\n * The immutable-update style (\"replace the row object\" instead of \"mutate\n * it\") is the idiomatic way to invalidate a row and is what the memo is\n * built around. A same-ref `arraySignal.update()` (mutate the object and\n * return it) also works — it bumps a per-item content version (KF-418,\n * `item-version.ts`) that the memo checks — so it re-renders the row in\n * every consumer, not just the list that drained the patch.\n *\n * 2. Structural handoff. `mount()` recognizes the list segment and bypasses\n * the parse-the-whole-table round trip: only fresh items get parsed (one\n * at a time, into the smallest detached element), and only changed rows\n * get patched in the live DOM. Unchanged rows are physically the same\n * nodes they were before — never visited.\n *\n * `cacheKey` is a passive comparator — it covers the case where external\n * state, not the item itself, drives what the row should render (e.g. a\n * \"currently selected\" id flips a CSS class on one row). Same item identity\n * but a different `cacheKey` return value means \"the cached HTML is stale —\n * re-render this row.\" Not a reactive subscription: it's evaluated once per\n * mount-effect run and compared against the previous run's return value. If\n * you don't pass `cacheKey`, only object-identity changes invalidate the\n * cache. (Renamed from `key` for clarity — it shared a name with React's\n * `key` prop but has different semantics; the new name says what the\n * parameter actually does. Positional callers — the canonical form — are\n * unaffected.)\n *\n * Items must be objects (cache is a `WeakMap`); wrap primitives if you need\n * to iterate them. Each item's render output must produce exactly one\n * top-level element — the list reconciler binds one live DOM node per item.\n */\n\nimport type { ArrayPatch, ArraySignal } from './array-signal.js';\nimport { type Binding, captureRowBindings } from './bindings.js';\nimport { devHooks } from './dev-hooks.js';\nimport { itemVersion } from './item-version.js';\nimport type { SafeHtml } from './jsx-runtime.js';\nimport { granularListSafeHtml, isSafeHtml, listSafeHtml } from './jsx-runtime.js';\nimport { decideListPath, deriveListRenderState } from './list-render-state.js';\nimport type { ArrayPatchInternal } from './segment.js';\n\n/**\n * Cross-bundle brand check for `ArraySignal` instances (KF-95). The\n * `arraySignal` factory + class live in their own subpath\n * (`kerfjs/array-signal`); this module knows nothing about that\n * subpath at runtime — it identifies instances by the brand symbol\n * stamped on them. Apps that never import `arraySignal` shed the\n * ~1 KB of class code without breaking the structural contract here.\n */\nconst ARRAY_SIGNAL_BRAND = Symbol.for('kerfjs.ArraySignal');\n\nfunction isArraySignal<T extends object>(value: unknown): value is ArraySignal<T> {\n return typeof value === 'object'\n && value !== null\n && (value as Record<symbol, unknown>)[ARRAY_SIGNAL_BRAND] === true;\n}\n\ninterface CacheEntry {\n cacheKey: unknown;\n html: string;\n bindings: Binding[];\n /**\n * KF-418: the item's content version when this entry was rendered. A cache\n * hit requires it to still match, so a same-ref `arraySignal.update()` (which\n * bumps the version but keeps the identity the memo is keyed on) forces a\n * re-render here rather than serving stale HTML.\n */\n version: number;\n /**\n * KF-421: the index this entry's HTML was rendered at. The index is NOT part\n * of the memo key (a reorder keeps identity + cacheKey + version), so a cache\n * hit at a different index means the row's `index` argument is now stale. Used\n * only by the opt-in `KERF_DEV_WARN_STALE_INDEX` diagnostic.\n */\n index: number;\n}\n\n/**\n * Per-render context passed in by `mount()` for the duration of one render\n * pass. Carries (a) a counter that assigns a stable list id to the n-th\n * `each()` call across renders within a mount, and (b) a per-mount cache map\n * keyed on those list ids.\n *\n * Why per-(mount, listId) keying for the cache:\n * - Same `each()` callsite across renders within a mount → same id → same\n * cache → cache hits work, even when the JSX render fn is an inline arrow\n * that's a fresh function reference on every closure run (the typical\n * pattern; KF-87 fixed the regression where this broke).\n * - Different `each()` callsites within the same mount → different ids →\n * separate caches → no cross-callsite collision (the case KF-73 fixed,\n * preserved here).\n * - Different mounts → different `RenderContext` instances (the cache map\n * lives on `mount()`'s closure) → separate caches.\n *\n * Outside a `mount()` render (e.g. `each(...).toString()` for SSR string\n * production) `context` is null and items are rendered every call —\n * caching is a `mount()` feature, not a global one.\n */\nexport interface RenderContext {\n counter: number;\n caches: Map<string, WeakMap<object, CacheEntry>>;\n /**\n * Per-list-id record of the binding's `items.length` after the most recent\n * successful reconcile. Maintained by `mount()`, which writes\n * `renderCtx.bindingCounts.set(...)` directly after each `reconcileList`. The\n * granular path consults this to detect drift between the live binding and\n * the arraySignal — drift means a previous render threw mid-reconcile (or\n * a granular path was bypassed externally), so the next render forces a\n * snapshot rebuild rather than applying patches against a stale binding.\n */\n bindingCounts: Map<string, number>;\n /**\n * KF-388: per-list-id record of the data source (`arraySignal` instance, or\n * `undefined` for a plain array) the binding was last reconciled against.\n * Maintained by `mount()` alongside `bindingCounts`.\n *\n * A list's id is its call-order index, so a render that changes how many\n * `each()` calls precede this one silently hands this id's binding to a\n * DIFFERENT list. A queued patch is only meaningful against the binding it\n * was queued for, so `eachGranular` compares the source recorded here before\n * emitting patches — a mismatch means the id was reused and the list must\n * snapshot-rebuild instead. The check lives here, not in the reconciler,\n * because only `each()` can still produce the full item snapshot the\n * rebuild needs (granular segments deliberately carry `items: []`).\n */\n bindingSources: Map<string, object | undefined>;\n /**\n * Keys claimed by `each({ key })` calls in the CURRENT render, reset by\n * `mount()` alongside the counter. Two lists claiming one key would share\n * every keyed structure — a new silent-corruption footgun introduced by the\n * feature itself — so the second claim throws instead.\n */\n keysThisRender: Set<string>;\n /**\n * KF-394: unkeyed list ids whose data source changed THIS render. A source\n * change alone does not mean the id was reused — the same list swapping which\n * signal it renders (a filter or tab switch) changes source too, and warning\n * about that told authors to fix code that was already correct. `mount()`\n * only reports these when the render's `each()` call count also changed,\n * which is what an actual id shift requires.\n */\n shiftCandidates: string[];\n /** The previous render's total unkeyed `each()` count; `undefined` on first render. */\n previousCallCount?: number;\n /** Per-mount dedup for the shift warning — ids are per-mount, so this must be too. */\n warnedShiftIds: Set<string>;\n /**\n * KF-411: list ids whose container the morph rebuilt THIS render, so\n * `bindListsFromMarkers` self-healed their binding to empty. Populated during\n * the bind pass, read by `mount()` after it. A self-healed binding is empty,\n * but if that list emitted a GRANULAR segment (it looked `bound` when `each()`\n * ran, before the morph), the segment carries no items — so a snapshot\n * reconcile would empty the live rows. `mount()` resets these lists to\n * unbound and re-renders so `each()` re-emits a full snapshot. Cleared before\n * each bind pass.\n */\n rebuiltLists: Set<string>;\n}\n\nlet context: RenderContext | null = null;\n\n/**\n * True while a row's render function is executing. A keyed `each()` reached\n * from inside a row is a different mistake from two sibling lists sharing a\n * key, and used to be reported as the latter (KF-398).\n */\nlet renderingRow = false;\n\n/** Run `fn` marked as row-render scope, restoring the previous scope after. */\nfunction inRowScope<R>(fn: () => R): R {\n const prev = renderingRow;\n renderingRow = true;\n try {\n return fn();\n } finally {\n renderingRow = prev;\n }\n}\n\nexport function _setRenderContext(c: RenderContext | null): void {\n context = c;\n}\n\n/**\n * Drop every piece of per-list state that is keyed on a CALL-ORDER id, keeping\n * the keyed (`k:`-prefixed) ones.\n *\n * `mount()` calls this when a render changed how many unkeyed `each()` calls\n * ran, because at that moment every call-order id may be held by a different\n * list than it was, and each of these structures would otherwise be read as\n * that list's own:\n *\n * - `caches` — the per-item HTML memo. This is the one that produced visibly\n * wrong output: two lists over the same items hit each other's memo (same\n * refs, same `cacheKey`) and the surviving list rendered the departed list's\n * row markup. The recorded-source guard cannot see it, because a shared\n * source is identical by construction.\n * - `bindingCounts` — clearing it puts the list in the `unbound` state, so it\n * takes the snapshot path and rebuilds from its own items instead of\n * applying a patch queue against a stranger's row count.\n * - `bindingSources` — the record being invalidated; a stale entry here would\n * make the next render believe a genuine continuation was a reuse.\n *\n * Keyed lists are deliberately untouched: their identity does not depend on\n * call order, which is the entire reason `each(…, { key })` exists.\n */\nexport function _resetCallOrderListState(ctx: RenderContext): void {\n const isCallOrderId = (id: string): boolean => !id.startsWith('k:');\n for (const map of [ctx.caches, ctx.bindingCounts, ctx.bindingSources]) {\n for (const id of Array.from(map.keys())) {\n if (isCallOrderId(id)) map.delete(id);\n }\n }\n}\n\n/**\n * Options for `each()`. Supplied in place of the bare `cacheKey` third\n * argument, which remains supported.\n */\nexport interface EachOptions<T> {\n /**\n * Passive per-item comparator — the same value the bare third argument\n * takes. Invalidates an item's cached HTML when external state changes what\n * the row should render.\n */\n cacheKey?: (item: T, index: number) => unknown;\n /**\n * A stable identity for THIS list, unique within the mount.\n *\n * Without one, a list is identified by its call order (\"the n-th `each()`\n * this render\"), so any render that changes how many `each()` calls run\n * before it reassigns its identity — and the list is rebuilt from scratch,\n * losing row nodes, focus, scroll position and in-progress IME. Give a key\n * to any list that can be preceded by a conditional list.\n *\n * Keyed lists also do not consume a call-order slot, so keying a\n * *conditional* list additionally stabilizes its unkeyed siblings.\n */\n key?: string;\n}\n\nfunction isEachOptions<T>(\n v: ((item: T, index: number) => unknown) | EachOptions<T> | undefined,\n): v is EachOptions<T> {\n return typeof v === 'object' && v !== null;\n}\n\n/** Claim `key` for this render, or throw if another list already took it. */\n/**\n * A list key ends up verbatim inside the `<!--kf-list:…-->` marker comment, so\n * it must be something an HTML comment can actually hold. Anything else is\n * rejected up front (KF-395): a key containing a comment terminator used to\n * break out of the marker and land live markup in the mount before dying on an\n * internal TypeError — wrong twice over.\n *\n * The allowed set is deliberately narrow rather than \"everything that happens\n * to survive a parser\": keys are short author-chosen identifiers, and a\n * conservative set can be widened later without breaking anyone, whereas a\n * permissive one cannot be narrowed. `--` is excluded separately because it is\n * invalid inside a comment even when every character is individually fine.\n */\nconst VALID_KEY = /^[A-Za-z0-9_.:/-]+$/;\n\nfunction assertValidKey(key: string): void {\n if (typeof key !== 'string' || !VALID_KEY.test(key) || key.includes('--')) {\n throw new Error(\n `each(): invalid list key ${JSON.stringify(key)}. A key must be a non-empty string of `\n + 'letters, digits, or _ . : / - (and may not contain \"--\"), because kerf writes it into '\n + 'the list\\'s marker comment in the DOM. Use a short stable identifier, e.g. '\n + '{ key: \\'results\\' }.',\n );\n }\n}\n\nfunction claimKey(ctx: RenderContext, key: string): string {\n assertValidKey(key);\n if (renderingRow) {\n // KF-398: every row claims the same key, so this used to surface as\n // \"duplicate list key\" — which misdiagnoses. The real problem is that an\n // each() inside a row render is not reconciled at all: row HTML is\n // flattened to a string, so the inner list's marker and binding never\n // exist and it renders as inert static HTML. Following the duplicate-key\n // advice (a per-row key) silences the error and lands the author in that\n // silent degradation instead, which is worse.\n throw new Error(\n `each(): list key ${JSON.stringify(key)} was used by an each() inside a row render. `\n + 'A nested each() is not reconciled — the row is flattened to HTML, so the inner list '\n + 'never binds and would render as static markup. Render the inner collection with '\n + 'plain .map() (it re-renders with its row), or restructure to a flat list.',\n );\n }\n if (ctx.keysThisRender.has(key)) {\n throw new Error(\n `each(): duplicate list key ${JSON.stringify(key)}. Every keyed each() in a mount must `\n + 'have its own key — two lists sharing one would share the same cache, binding and DOM '\n + 'anchor. Give each list a distinct key.',\n );\n }\n ctx.keysThisRender.add(key);\n // Namespaced so an author key can never collide with a call-order id.\n return `k:${key}`;\n}\n\nexport function each<T extends object>(\n items: readonly T[] | ArraySignal<T>,\n render: (item: T, index: number) => SafeHtml | string,\n cacheKey?: (item: T, index: number) => unknown,\n): SafeHtml;\nexport function each<T extends object>(\n items: readonly T[] | ArraySignal<T>,\n render: (item: T, index: number) => SafeHtml | string,\n options?: EachOptions<T>,\n): SafeHtml;\nexport function each<T extends object>(\n items: readonly T[] | ArraySignal<T>,\n render: (item: T, index: number) => SafeHtml | string,\n cacheKeyOrOptions?: ((item: T, index: number) => unknown) | EachOptions<T>,\n): SafeHtml {\n const useOptions = isEachOptions(cacheKeyOrOptions);\n const cacheKey = useOptions ? cacheKeyOrOptions.cacheKey : cacheKeyOrOptions;\n const listKey = useOptions ? cacheKeyOrOptions.key : undefined;\n // KF-92 fast path: when items is an ArraySignal AND we're inside a mount\n // render context AND patches have queued since the last drain, emit a\n // granular list segment that the list reconciler applies in O(patches)\n // instead of O(N). Detection via the brand symbol (KF-95) — the\n // `arraySignal` class lives in the `kerfjs/array-signal` subpath and is\n // not imported here at runtime.\n if (isArraySignal<T>(items) && context !== null) {\n return eachGranular(items, render, cacheKey, listKey);\n }\n const snapshotItems: readonly T[] = isArraySignal<T>(items)\n ? items.value as readonly T[]\n : items;\n return eachSnapshot(snapshotItems, render, cacheKey, listKey);\n}\n\nfunction eachSnapshot<T extends object>(\n items: readonly T[],\n render: (item: T, index: number) => SafeHtml | string,\n cacheKey: ((item: T, index: number) => unknown) | undefined,\n listKey: string | undefined,\n): SafeHtml {\n let id: string;\n if (context !== null) {\n // A keyed list takes its identity from the key and does NOT consume a\n // call-order slot — so keying a conditional list also stops it shifting\n // its unkeyed siblings when it appears or disappears.\n id = listKey !== undefined ? claimKey(context, listKey) : String(context.counter++);\n } else {\n id = 'orphan';\n }\n return eachSnapshotById(items, render, cacheKey, id);\n}\n\n/**\n * The shared `each()` item contract: an item must be a non-null object so it can\n * key the per-item HTML `WeakMap`. Enforced identically by the snapshot path (over\n * the whole list) and the granular path (per insert/update patch), so the two\n * agree on what a valid item is and a bad item throws at the render its mutation\n * triggered — not at a later, unrelated one (KF-426). Note it rejects functions\n * too: they are valid WeakMap keys, but not valid `each()` rows, and admitting\n * them here without also supporting them as rows is the disagreement KF-426 fixed.\n */\nfunction assertObjectItem(item: unknown, index: number): asserts item is object {\n if (typeof item !== 'object' || item === null) {\n throw new Error(\n `each(): items must be objects (the per-item HTML cache is a WeakMap), got ${item === null ? 'null' : typeof item} at index ${index}. `\n + 'Wrap primitives if you need to iterate them, e.g. items.map(v => ({ v })).',\n );\n }\n}\n\n/**\n * Replay structural patches over the indices at which rows were rendered and\n * report whether any surviving row would occupy a different final index.\n * Pure transition stage extracted from `eachGranular` for direct coverage.\n */\nexport function _hasGranularIndexShift<T>(\n previousBindingCount: number,\n patches: readonly ArrayPatch<T>[],\n): boolean {\n const rendered: number[] = [];\n for (let i = 0; i < previousBindingCount; i++) rendered.push(i);\n for (const patch of patches) {\n if (patch.type === 'insert') rendered.splice(patch.index, 0, patch.index);\n else if (patch.type === 'remove') rendered.splice(patch.index, 1);\n else if (patch.type === 'move') {\n const [moved] = rendered.splice(patch.from, 1);\n rendered.splice(patch.to, 0, moved);\n }\n }\n return rendered.some((renderedAt, index) => renderedAt !== index);\n}\n\ninterface CacheKeyLookup {\n get(item: object): { cacheKey: unknown } | undefined;\n}\n\n/**\n * Re-evaluate cache keys to retain their reactive dependencies and report the\n * first bound row whose cached comparator has drifted. Does not mutate state.\n */\nexport function _hasGranularCacheKeyDrift<T extends object>(\n snapshot: readonly T[],\n cacheKey: (item: T, index: number) => unknown,\n cache: CacheKeyLookup,\n): boolean {\n for (let i = 0; i < snapshot.length; i++) {\n const item = snapshot[i];\n const nextKey = cacheKey(item, i);\n const cached = cache.get(item);\n if (cached !== undefined && cached.cacheKey !== nextKey) return true;\n }\n return false;\n}\n\n/**\n * Granular path for `arraySignal`-backed lists. Drains queued patches and\n * emits a list segment that the reconciler applies to the existing binding\n * directly — no full iteration of the snapshot, no O(N) classify pass.\n *\n * On the very first render of a list, the binding doesn't exist yet, so\n * the reconciler falls through to the snapshot path. Subsequent renders\n * of the same list (where the binding now exists) take the granular path\n * whenever there are patches to apply.\n */\nfunction eachGranular<T extends object>(\n sig: ArraySignal<T>,\n render: (item: T, index: number) => SafeHtml | string,\n cacheKey: ((item: T, index: number) => unknown) | undefined,\n listKey: string | undefined,\n): SafeHtml {\n // We're inside a mount context (caller-checked).\n const ctx = context as RenderContext;\n // Keyed lists are identified by their key and skip the call-order counter\n // (see eachSnapshot for why that also helps unkeyed siblings).\n const id = listKey !== undefined ? claimKey(ctx, listKey) : String(ctx.counter++);\n // KF-336: dispatch through the reified state machine (`list-render-state.ts`\n // holds the transition table). The state derives from the count `mount()`\n // recorded after this list's last successful reconcile; the patch queue is\n // drained BEFORE deciding so a snapshot route still consumes it (the\n // snapshot already reflects every queued mutation, including pre-mount\n // mutations on a first render — the KF-98 case).\n const previousBindingCount = ctx.bindingCounts.get(id);\n const patches = sig._consumePatches();\n const snapshot = sig.value as readonly T[];\n\n // Structural decision: first-render / empty-binding / no-patches / replace /\n // count-drift all route to the snapshot path (see the transition table for\n // why each one can't be patched granularly). The two side-effectful reasons\n // — cachekey-drift and render-threw — are layered on below. Count drift also\n // recovers a granular DOM reconcile that failed after patches were drained\n // (for example, row parsing rejected an insert), leaving the recorded live\n // binding count behind the source snapshot.\n // KF-388: before trusting the state at all, confirm this id still refers to\n // THIS list. Ids are call-order indexes, so a render that adds or drops an\n // `each()` call ahead of this one silently hands us the previous occupant's\n // binding — and its recorded count, which is what let a queued patch pass\n // the drift check and get applied to the wrong list's live rows. Comparing\n // the recorded source (identity only; the value is never read) catches the\n // reuse, and a `known` mismatch is treated as first-render so the snapshot\n // rebuilds this container from our own items.\n const previousSource = ctx.bindingSources.get(id);\n const sourceReused = ctx.bindingSources.has(id) && previousSource !== sig;\n // KF-394: routing on a source change is always right (below); WARNING about\n // it is not. A keyed list is identified by its key, so a source change there\n // is an ordinary data swap and never an identity shift. For unkeyed lists,\n // record a candidate and let `mount()` decide at end of render, when it can\n // see whether the call count actually moved.\n if (sourceReused && listKey === undefined) ctx.shiftCandidates.push(id);\n const decision = sourceReused\n ? { path: 'snapshot' as const }\n : decideListPath(\n deriveListRenderState(previousBindingCount), patches, snapshot.length, previousBindingCount,\n );\n if (decision.path === 'snapshot') {\n return eachSnapshotById(snapshot, render, cacheKey, id, sig);\n }\n\n // KF-421: the granular path leaves rows the patches don't touch in place with\n // their cached HTML — computed at their OLD index. If any applied patch shifts\n // an existing row's index (a non-tail insert/remove, or any move) and the\n // render fn reads the index, those carried rows now show a stale index. Opt-in\n // dev warning; `previousBindingCount` is the pre-batch row count (defined on\n // the granular path — the snapshot arms above own the `undefined` case).\n // KF-424: only DETECT the shift here; emit the warning at the granular-commit\n // point below. A cachekey-drift or render-threw reroute past this block hands\n // off to the snapshot path, which re-renders every displaced row at its correct\n // index — so warning here (before the reroute) was a false positive for a list\n // using the documented `cacheKey: (_, i) => i` workaround.\n //\n // Replay the patches over an array holding each row's RENDERED index — carried\n // rows are rendered at their original index, freshly-inserted rows at their\n // patch index — then flag if any row's rendered index ends up ≠ its final\n // position. This is exact where a transient running-length check was not: it\n // does NOT false-positive on a net-zero batch whose shifts cancel (KF-424), and\n // it DOES catch a fresh insert displaced by a later same-batch insert, whose\n // patch-time index the granular path can't retroactively fix (KF-425). The\n // O(rows) replay runs only in dev under the opt-in for an index-reading list.\n const staleIndexShift = render.length >= 2\n && devHooks.staleIndexEnabled?.() === true\n && _hasGranularIndexShift(previousBindingCount as number, patches);\n\n // The granular path applies arraySignal patches but never evaluates\n // `cacheKey` (or `render`) for the rows the patches don't touch. That has\n // two consequences this loop fixes:\n //\n // 1. Dependency tracking. A signal read ONLY inside `cacheKey` — the\n // documented \"external state drives the row\" pattern, e.g. a `selectedId`\n // flipping a row class — would drop out of the mount effect's dependency\n // set after a granular-only render, because nothing read it. A later\n // change to that signal would then silently fail to re-render. Concretely:\n // select a row, delete a *different* row (a granular remove), then row\n // selection stops working entirely. Re-reading every item's `cacheKey`\n // here keeps those signals tracked.\n //\n // 2. Drift the patches don't cover. If an already-bound row's `cacheKey`\n // changed, external state moved a row that this batch's structural\n // patches won't fix (e.g. a selection flip batched together with a\n // remove). Hand the whole render to the snapshot path, which reconciles\n // structure + content together. The patches are already drained and the\n // snapshot reflects every mutation, so the snapshot classify rebuilds the\n // binding correctly from the pre-render DOM.\n //\n // Only lists that pass `cacheKey` pay this O(N) scan, and they already pay\n // the same O(N) `cacheKey` evaluation on every snapshot render.\n if (cacheKey !== undefined) {\n // The cache is always populated here: the first render of any list takes\n // the snapshot path (previousBindingCount === undefined, handled above),\n // which creates the cache for `id`. So a granular render always has it. The\n // `as` cast asserts that instead of an `if (cache === undefined)` guard,\n // whose else-branch would be unreachable — and would drop us below the 99%\n // branch-coverage threshold.\n const cache = ctx.caches.get(id) as WeakMap<object, CacheEntry>;\n // Evaluate `cacheKey` for every row while looking for real drift. That read\n // keeps external signals in the mount effect's dependency set, including\n // for fresh refs with no cache entry. A drift reroutes the full render so\n // structure and content reconcile together.\n if (_hasGranularCacheKeyDrift(snapshot, cacheKey, cache)) {\n // Transition-table reason: `cachekey-drift` (list-render-state.ts).\n return eachSnapshotById(snapshot, render, cacheKey, id, sig);\n }\n }\n\n // Granular path: pre-render every insert/update HTML at JSX-eval time so\n // a throwing render is caught here and we can fall back to the snapshot\n // path (KF-99). Without this, a throw mid-batch would leave patches drained\n // (already done above), the signal mutated, and the live DOM unchanged —\n // permanent divergence with no recovery.\n // KF-294: capture each insert/update row's fine-grained bindings (signals\n // in row attrs/text) so the granular reconciler can wire them to the fresh\n // row node and dispose them on removal — same lifecycle as the snapshot path.\n const renderRow = (item: object, index: number): { html: string; bindings: Binding[] } =>\n captureRowBindings(() => inRowScope(() => {\n const out = render(item as T, index);\n return isSafeHtml(out) ? out.toString() : out;\n }));\n const internalPatches = new Array<ArrayPatchInternal>(patches.length);\n // KF-414: the per-item HTML memo. The granular path renders fresh HTML for\n // each insert/update below; it must write that back into the memo too, or a\n // later snapshot-routed render (the `no-patches` transition on an unrelated\n // re-render) finds the STALE entry — same ref, same cacheKey — and the\n // in-place fast path morphs the row back to its old HTML. \"What this row\n // renders\" cannot live in two places (`binding.items[].html` and this memo)\n // that are allowed to diverge. Always populated here (the first render of any\n // list took the snapshot path, which created it), so the `?.` is belt-only.\n const cache = ctx.caches.get(id);\n try {\n for (let i = 0; i < patches.length; i++) {\n const p = patches[i];\n if (p.type === 'insert' || p.type === 'update') {\n // KF-426: reject a non-object item here, at the render its insert/update\n // triggered, instead of letting a function item (a valid WeakMap key, so\n // `cache.set` below wouldn't throw) render and only surface the error on a\n // later unrelated snapshot render. The throw is caught by the render-threw\n // recovery below, which reroutes to the snapshot path — matching how a\n // primitive item already flows (its `cache.set` TypeError takes the same\n // route) and giving the same message at the same moment.\n assertObjectItem(p.item, p.index);\n const { html, bindings } = renderRow(p.item as object, p.index);\n internalPatches[i] = {\n type: p.type, index: p.index, item: p.item as object, html, bindings,\n };\n cache?.set(p.item as object, {\n cacheKey: cacheKey ? cacheKey(p.item as T, p.index) : undefined,\n html,\n bindings,\n version: itemVersion(p.item as object),\n index: p.index,\n });\n } else {\n internalPatches[i] = p as ArrayPatchInternal;\n }\n }\n } catch {\n // Transition-table reason: `render-threw` (list-render-state.ts). The\n // snapshot already reflects every mutation (arraySignal mutates _items\n // eagerly at the call site), but the snapshot path is going to throw on\n // the same bad item too — leaving the binding out of sync with the\n // signal. Deleting the count resets this list to the `unbound` state so\n // the NEXT render (after the user fixes the bad item) snapshot-rebuilds\n // from scratch instead of trusting the stale count.\n ctx.bindingCounts.delete(id);\n return eachSnapshotById(snapshot, render, cacheKey, id, sig);\n }\n // KF-424: the render has committed to the granular path (no cachekey-drift or\n // render-threw reroute fired above), so any detected index shift will actually\n // reach the DOM as stale HTML — now it's a true positive worth warning about.\n if (staleIndexShift) devHooks.staleIndex?.(id);\n // The `items` field is left empty for the granular case — the reconciler\n // doesn't need it; every insert/update patch carries pre-rendered HTML.\n return granularListSafeHtml(id, [], internalPatches, sig);\n}\n\n/** Like eachSnapshot but uses a pre-allocated id (caller already advanced the counter). */\nfunction eachSnapshotById<T extends object>(\n items: readonly T[],\n render: (item: T, index: number) => SafeHtml | string,\n cacheKey: ((item: T, index: number) => unknown) | undefined,\n id: string,\n source?: object,\n): SafeHtml {\n let cache: WeakMap<object, CacheEntry> | null = null;\n if (context !== null) {\n let c = context.caches.get(id);\n if (c === undefined) {\n c = new WeakMap<object, CacheEntry>();\n context.caches.set(id, c);\n }\n cache = c;\n }\n const segItems = new Array<{ ref: object; cacheKey: unknown; html: string; bindings: Binding[] }>(items.length);\n const seen = new Set<object>();\n for (let i = 0; i < items.length; i++) {\n const item = items[i];\n assertObjectItem(item, i);\n if (seen.has(item)) {\n throw new Error(\n `each(): the same object reference appears at multiple indices in items (first seen earlier, again at index ${i}). `\n + 'The per-item HTML cache is keyed on object identity, so duplicate references break the keyed reconciler and can leak DOM nodes on re-render. '\n + 'Use a fresh object per row (e.g. items.map(o => ({ ...o })) before passing to each()).',\n );\n }\n seen.add(item);\n const k = cacheKey ? cacheKey(item, i) : undefined;\n const version = itemVersion(item);\n let html: string;\n let bindings: Binding[];\n const cached = cache !== null ? cache.get(item) : undefined;\n // KF-418: the version guard is what makes a same-ref update visible here —\n // same identity, same cacheKey, but a bumped version misses the cache.\n if (cached !== undefined && cached.cacheKey === k && cached.version === version) {\n html = cached.html;\n bindings = cached.bindings;\n // KF-421: this row's HTML was memoized at `cached.index`; serving it at a\n // different `i` means its `index` argument is stale. Opt-in dev warning.\n if (cached.index !== i && render.length >= 2 && devHooks.staleIndexEnabled?.() === true) {\n devHooks.staleIndex?.(id);\n }\n } else {\n // KF-294: capture the row's fine-grained bindings (signals in row attrs\n // / text). The snapshot reconciler wires them to the row node on create\n // and disposes on remove, so a bound signal updates the row without a\n // render re-run. Cached by row identity alongside the html.\n const captured = captureRowBindings(() => inRowScope(() => {\n const out = render(item, i);\n return isSafeHtml(out) ? out.toString() : out;\n }));\n html = captured.html;\n bindings = captured.bindings;\n if (cache !== null) cache.set(item, { cacheKey: k, html, bindings, version, index: i });\n }\n segItems[i] = { ref: item, cacheKey: k, html, bindings };\n }\n if (cacheKey !== undefined) {\n devHooks.duplicateCacheKeys?.(id, segItems);\n }\n return listSafeHtml(id, segItems, source);\n}\n","/**\n * Focus snapshot/restore for the keyed list reconciler.\n *\n * Some engines drop focus state on `insertBefore`; Firefox's `moveBefore()`\n * keeps focus but can retarget a contenteditable Selection to the list parent.\n * The reconciler snapshots the active element + exact selection before its\n * move pass, then re-applies them afterwards.\n *\n * Lives in its own file (rather than inside `list-reconcile.ts`) to isolate\n * the engine-quirk handling — a concern separable from the reconcile\n * algorithm — described in `docs/4-render.md` §4.4.\n */\n\nexport type FocusSnapshot = [\n el: HTMLElement,\n selStart: number | null,\n selEnd: number | null,\n domSelection: [anchorNode: Node, anchorOffset: number, focusNode: Node, focusOffset: number] | null,\n];\n\n/**\n * Capture focus + selection on a focused descendant of `liveParent`.\n *\n * Returns null when the active element is outside the list (the diff path\n * handles those cases) or when there's no useful focus state to capture.\n */\nexport function captureFocus(liveParent: Element): FocusSnapshot | null {\n const active = document.activeElement;\n if (active === null || active === document.body) return null;\n if (!liveParent.contains(active)) return null;\n const el = active as HTMLElement;\n let selStart: number | null = null;\n let selEnd: number | null = null;\n let domSelection: FocusSnapshot[3] = null;\n if (el.tagName === 'INPUT' || el.tagName === 'TEXTAREA') {\n try {\n selStart = (el as HTMLInputElement).selectionStart;\n selEnd = (el as HTMLInputElement).selectionEnd;\n } catch {\n // Some input types (number, range, color, …) reject selection APIs.\n }\n }\n if (el.isContentEditable) {\n const selection = document.getSelection();\n if (selection !== null && selection.anchorNode !== null && selection.focusNode !== null) {\n // Keep the live boundary-node references and numeric offsets. Firefox's\n // moveBefore() can retarget both Selection and cloned Range boundaries\n // to the row's parent during a keyed move, so neither object is a safe\n // snapshot on that engine.\n domSelection = [\n selection.anchorNode,\n selection.anchorOffset,\n selection.focusNode,\n selection.focusOffset,\n ];\n }\n }\n return [el, selStart, selEnd, domSelection];\n}\n\nexport function restoreFocus(snap: FocusSnapshot): void {\n const [el, selStart, selEnd, domSelection] = snap;\n if (!el.isConnected) return;\n if (document.activeElement !== el) el.focus();\n if (selStart !== null && selEnd !== null) {\n try {\n (el as HTMLInputElement).setSelectionRange(selStart, selEnd);\n } catch {\n // Selection may have been clobbered by .focus(); not fatal.\n }\n }\n if (domSelection === null) return;\n const [anchorNode, anchorOffset, focusNode, focusOffset] = domSelection;\n try {\n // Preserve selection direction where the engine supports the direct API.\n document.getSelection()?.setBaseAndExtent(\n anchorNode,\n anchorOffset,\n focusNode,\n focusOffset,\n );\n } catch {\n // A caller may have mutated the editable subtree during reconciliation.\n }\n}\n","/**\n * State-preserving node move with a transparent fallback.\n *\n * `Node.prototype.moveBefore(node, ref)` (Chromium 133+, spreading to other\n * engines) performs an ATOMIC move: the node is never disconnected from the\n * document, so focus, selection, `<iframe>` document state, playing media,\n * running CSS transitions/animations, and open `popover`/`dialog`/fullscreen\n * state all survive. `insertBefore` on an already-connected node detaches and\n * re-attaches it, tearing every one of those down.\n *\n * kerf's keyed-list reconcilers and `morph()` move already-connected rows on\n * every reorder, so routing those moves through `moveBefore` preserves live row\n * state that the focus snapshot in `list-reconcile-focus.ts` can only\n * approximate (and only for text inputs). That module stays for the fallback\n * path; where `moveBefore` runs it self-no-ops (focus never left, so\n * `restoreFocus`'s `document.activeElement === snap.el` guard returns early).\n *\n * ## Why the `isConnected` guard, not a bare `moveBefore` call\n *\n * `moveBefore` is only valid for a node already connected in the same tree as\n * `parent`; it throws for a detached (freshly-parsed) node. Several kerf move\n * sites are *mixed* — a reverse pass that inserts brand-new rows AND relocates\n * surviving ones in one loop. Rather than force each caller to branch, this\n * helper routes per node: a connected node takes the atomic `moveBefore` path,\n * a detached one falls back to `insertBefore` (its state is fresh anyway, so\n * there is nothing to preserve). Callers still keep `insertBefore` directly at\n * pure-insert sites, where routing through here would only add a dead guard.\n *\n * The connected-node invariant kerf relies on: at every `moveNode` call site\n * the node's current parent IS `parent` (a live row being relocated within its\n * own list/container), so it is connected in the same document as `parent` and\n * `moveBefore` cannot throw. Engines without `moveBefore` fall back to\n * `insertBefore` everywhere, matching kerf's prior behavior byte-for-byte.\n */\n\ninterface MoveBeforeCapable {\n moveBefore(node: Node, ref: Node | null): void;\n}\n\n/**\n * Move `node` to sit before `ref` inside `parent` (or to the end when `ref` is\n * `null`), preserving the node's live state via `moveBefore` where the engine\n * supports it and the node is already connected; otherwise `insertBefore`.\n */\nexport function moveNode(parent: Node, node: Node, ref: Node | null): void {\n const move = (parent as Partial<MoveBeforeCapable>).moveBefore;\n if (move !== undefined && node.isConnected) {\n move.call(parent, node, ref);\n } else {\n parent.insertBefore(node, ref);\n }\n}\n","/**\n * `morph(liveRoot, template)` — minimum-mutation DOM reconciliation.\n *\n * Public primitive (KF-150): one-shot reconciliation against an\n * already-populated element. `mount()` first paints by writing\n * `innerHTML`; `morph()` is the \"I have a live tree and a template,\n * reconcile them in place\" sibling. Use it for SSR hydration of static\n * fragments, page-refresh diffs, third-party widget remounts, etc.\n *\n * Replaces our previous dependency on `morphdom`. The algorithm is the\n * classic two-tree walk: match children by key (id, then data-key, then\n * positional same-tag), morph matches in place, insert / remove / clone\n * the rest. Specialized for what kerf needs:\n *\n * - `childrenOnly` is always true; the live root is never replaced.\n * - Per-element short-circuits: `data-morph-skip` (library-owned, leave\n * element AND subtree verbatim), `data-morph-skip-children` (KF-152 —\n * morph attrs on the element, leave its subtree verbatim — for\n * client-hydrated slots whose loading/state classes still need to flow\n * through), and `isEqualNode` (byte-identical, no work needed).\n * - **`data-morph-preserve`** protects a node at ITS OWN level only — an\n * ancestor the template drops still takes the whole subtree, preserved\n * descendants included (KF-386: intended, but easy to over-read, so it is\n * pinned by tests and stated in docs/4-render.md §4.3).\n * - **`data-morph-preserve`** (KF-151) is honored in the trailing-removal\n * pass: an unmatched live element with this attribute is skipped instead\n * of removed. Lets imperatively-injected nodes (autoplay `<video>`s,\n * tour-widget tooltips, analytics pixels) survive across renders without\n * having to `data-morph-skip` the entire parent.\n * - **`ownedItems`** is the set of element nodes owned by an `each()`\n * list reconciler. The morph skips them in every children walk —\n * they're not added to the keyed-lookup map, the from-cursor advances\n * past them, and the trailing-removal pass leaves them in place. This\n * lets each() coexist with non-list siblings inside the same parent\n * (KF-102 round 2): the morph still walks the parent's children to\n * reconcile siblings, but never disturbs list rows. The parameter is an\n * internal coordination channel between `mount()` and the reconciler;\n * public callers should omit it (the default empty set is correct for\n * any tree that isn't being managed by an active `mount()`).\n * - Focused text inputs (`<input>`/`<textarea>`) keep their value +\n * selection across the morph; focused `[contenteditable]` keeps its\n * entire subtree (typed content + caret + multi-range selection).\n *\n * Algorithm credit: based on the design of\n * https://github.com/patrick-steele-idem/morphdom by Patrick Steele-Idem\n * (MIT licensed). Reimplemented here so kerf can specialize the hot paths\n * (segment-aware list dispatch, lighter callback surface) and drop the\n * runtime dependency. Original copyright preserved in `LICENSE`.\n */\n\nimport { boundTextNodeOf, ROW_TEXT_PREFIX, TEXT_MARKER_PREFIX } from './bindings.js';\nimport type { SafeHtml } from './jsx-runtime.js';\nimport { captureFocus, restoreFocus } from './list-reconcile-focus.js';\nimport { LIST_MARKER_PREFIX } from './segment.js';\nimport { moveNode } from './utils/moveNode.js';\nimport { syncFormProp } from './utils/syncFormProp.js';\n\nconst ID_KEY_PREFIX = 'id:';\nconst DATA_KEY_PREFIX = 'data-key:';\n// Local numeric copies of Node.ELEMENT_NODE etc. — the child-walk loop below\n// is the hottest path in the reconciler, and reading a module-scope const\n// avoids the Node global property lookup per visited node. Don't \"normalize\"\n// these to Node.* without re-checking the krausest partial-update numbers.\nconst ELEMENT_NODE = 1;\nconst TEXT_NODE = 3;\nconst COMMENT_NODE = 8;\n\nfunction getNodeKey(node: Node): string | undefined {\n if (node.nodeType !== ELEMENT_NODE) return undefined;\n const el = node as HTMLElement;\n if (el.id !== '') return `${ID_KEY_PREFIX}${el.id}`;\n if (el.dataset !== undefined && el.dataset.key !== undefined) {\n return `${DATA_KEY_PREFIX}${el.dataset.key}`;\n }\n return undefined;\n}\n\nconst EMPTY_OWNED: ReadonlySet<Element> = new Set();\n\n/**\n * Reconcile the children of `liveRoot` to match `template`.\n *\n * `template` can be an `Element` (used directly), a `SafeHtml`, or a raw\n * HTML string — the latter two are stringified and parsed into a transient\n * element whose tag matches `liveRoot`. The active text-entry / focused-\n * contenteditable preservation rules apply in all cases.\n *\n * `ownedItems` is an internal coordination channel for `mount()`'s list\n * reconciler; public callers should omit it.\n */\nexport function morph(\n liveRoot: Element,\n template: Element | SafeHtml | string,\n ownedItems: ReadonlySet<Element> = EMPTY_OWNED,\n): void {\n if (liveRoot == null) {\n throw new Error(\n 'morph: liveRoot is null/undefined — pass the live element, e.g. morph(document.getElementById(\"app\")!, template). '\n + 'A common cause is a typo in the id or selector that returns null at runtime even though the TypeScript types say Element.',\n );\n }\n const templateEl: Element = isElementNode(template)\n ? template\n : parseTemplate(liveRoot, template);\n // Some engines (older Safari, happy-dom) blur a focused descendant on\n // `insertBefore` even though the node survives the move connected. Every\n // move path in the walk below can hit that — the keyed match, the element\n // lookahead, the marker run — so capture once here and restore once after,\n // rather than per move. This is what makes mount()'s documented promise\n // (\"element identity, and thus focus, is preserved wherever the diff\n // matches\") true for moved subtrees and not just morphed-in-place ones.\n // One activeElement read per morph; `restoreFocus` no-ops when nothing moved.\n const focusSnap = captureFocus(liveRoot);\n morphChildren(liveRoot, templateEl, ownedItems);\n if (focusSnap !== null) restoreFocus(focusSnap);\n}\n\n/**\n * Internal: morph `fromEl` to match `toEl` including the element's own\n * attributes (which the public `morph()` does NOT touch — it only morphs\n * children of the live root). Used by `list-reconcile-granular.ts` to apply\n * an `update` patch in place via attribute + child morphing instead of\n * `replaceChild` discarding the whole subtree. Same short-circuits as\n * `morph()`: `data-morph-skip`, `data-morph-skip-children`, `isEqualNode`,\n * focused contenteditable / text-entry preservation. Tag mismatch falls\n * through to the same parent.replaceChild fallback the public API uses.\n *\n * Underscore-prefixed export (not part of the public API surface). Public\n * callers should use `morph(liveRoot, template)`.\n */\nexport function _morphElement(\n fromEl: Element,\n toEl: Element,\n ownedItems: ReadonlySet<Element> = EMPTY_OWNED,\n): void {\n morphElement(fromEl, toEl, ownedItems);\n}\n\nfunction isElementNode(t: Element | SafeHtml | string): t is Element {\n return typeof t === 'object' && t !== null\n && (t as Node).nodeType === ELEMENT_NODE;\n}\n\nfunction parseTemplate(liveRoot: Element, template: SafeHtml | string): Element {\n const el = liveRoot.cloneNode(false) as Element;\n el.innerHTML = String(template);\n return el;\n}\n\n/**\n * A canonical tag for the ways a live node is managed OUTSIDE the template, so\n * the positional diff must not repurpose it as some other element.\n *\n * Three attributes make a node \"something else\": `data-morph-skip` and\n * `data-morph-skip-children` mark a library-owned subtree, and\n * `data-morph-preserve` marks a node imperatively injected after render that\n * the template never emits. Steps 2 and 2.5 require this tag to be EQUAL on\n * both sides before pairing — so a template element carrying no such claim\n * never adopts a protected live node (it gets inserted fresh beside it), and a\n * protected live node pairs only with a template that declares the same\n * protection, i.e. it genuinely is that same widget across both renders.\n *\n * The keyed match (step 1) is unaffected: a protected node WITH an `id`/\n * `data-key` the template also emits still matches and morphs in place, which\n * is the \"attrs morph if matched\" the docs describe. This gate only governs the\n * *positional* fallback, where \"matched\" would otherwise mean \"happened to sit\n * at the same index as an unrelated template element\".\n */\nfunction protectionTag(node: Node): string {\n // Both call sites (step 2's element arm and step 2.5's element scan) only ever\n // reach here with an element, so `dataset` is always present — no non-element\n // guard, which would be an unreachable branch.\n const { dataset } = node as HTMLElement;\n return (dataset.morphSkip !== undefined ? 's' : '')\n + (dataset.morphSkipChildren !== undefined ? 'c' : '')\n + (dataset.morphPreserve !== undefined ? 'p' : '');\n}\n\nconst MARKER_PREFIXES = [LIST_MARKER_PREFIX, TEXT_MARKER_PREFIX, ROW_TEXT_PREFIX];\n\n/** True when `node` is a kerf anchor comment (list marker or binding marker). */\nfunction isMarker(node: Node): boolean {\n if (node.nodeType !== COMMENT_NODE) return false;\n const { data } = node as Comment;\n return MARKER_PREFIXES.some((prefix) => data.startsWith(prefix));\n}\n\n/**\n * Whether two nodes may be positionally paired as far as kerf's markers are\n * concerned. Elements and text carry no marker state, so they defer entirely to\n * the tag/key checks in the caller — this only constrains comments.\n *\n * A kerf marker comment (`kf-list:` / `kfb:` / `kfbr:`) is the comment\n * equivalent of a keyed element: it anchors live state — a list's rows, a bound\n * hole's inserted text node — that exists only in the DOM and is looked up by\n * the marker's EXACT data. So a marker pairs positionally only with the\n * identical marker, never with a different one.\n *\n * The reason is `morphNode`: pairing two mismatched comments overwrites the\n * live one's data (`from.data = to.data`), which re-points one list/binding's\n * anchor at another's id. Two shapes it produced, both silent:\n *\n * - a list marker paired with a text-binding marker (different KINDS) carried\n * the binding's inserted text node into the list — the value rendered twice.\n * - a list marker paired with a DIFFERENT list marker (same kind) — an empty\n * conditional list reappearing next to a sibling list overwrote the\n * sibling's marker id, so the sibling's binding could no longer find its own\n * marker and its whole row region emptied on the next reconcile.\n *\n * Ordinary comments carry no state and stay positionally matched (their data\n * just morphs), so a consumer's `<!-- … -->` is unaffected.\n */\nfunction markersPairable(a: Node, b: Node): boolean {\n if (!isMarker(a) && !isMarker(b)) return true;\n return (a as CharacterData).data === (b as CharacterData).data;\n}\n\n/**\n * Advance past any owned (list-reconciler-managed) element. Owned items\n * stay put across morphs — they're invisible to the morph's child cursor.\n */\nfunction skipOwned(node: Node | null, ownedItems: ReadonlySet<Element>): Node | null {\n while (node !== null && node.nodeType === ELEMENT_NODE\n && ownedItems.has(node as Element)) {\n node = node.nextSibling;\n }\n return node;\n}\n\nfunction isListMarker(node: Node): boolean {\n return node.nodeType === COMMENT_NODE\n && (node as Comment).data.startsWith(LIST_MARKER_PREFIX);\n}\n\n/**\n * The node just PAST a list's row region — an exclusive end, `null` at the end\n * of the parent. The region runs from the marker through its last owned row;\n * when the list is empty that's the marker alone. Nodes sitting BETWEEN rows\n * (something the consumer injected imperatively) are inside the region, so the\n * region is \"marker through last row,\" not \"the contiguous run of owned rows\"\n * (KF-385 — the contiguous reading let one interloper shrink the region to the\n * bare marker).\n *\n * The scan stops at the next list's marker so a sibling `each()` in the same\n * parent is never absorbed into this one's region.\n */\nfunction afterListRegion(marker: Comment, ownedItems: ReadonlySet<Element>): Node | null {\n let last: Node = marker;\n for (let r: Node | null = marker.nextSibling; r !== null; r = r.nextSibling) {\n if (isListMarker(r)) break;\n if (r.nodeType === ELEMENT_NODE && ownedItems.has(r as Element)) last = r;\n }\n return last.nextSibling;\n}\n\nfunction morphChildren(\n fromParent: Element,\n toParent: Element,\n ownedItems: ReadonlySet<Element>,\n): void {\n // Build a keyed lookup from the live children so we can match by key\n // even after reorders. Owned items don't participate in keyed matching\n // (they're not visible to the morph).\n const keyed = new Map<string, Element>();\n for (let c = fromParent.firstChild; c !== null; c = c.nextSibling) {\n if (c.nodeType === ELEMENT_NODE && ownedItems.has(c as Element)) continue;\n const k = getNodeKey(c);\n if (k !== undefined) keyed.set(k, c as Element);\n }\n\n let fromChild: Node | null = skipOwned(fromParent.firstChild, ownedItems);\n let toChild: Node | null = toParent.firstChild;\n\n while (toChild !== null) {\n const toNext = toChild.nextSibling;\n let matched: Node | null = null;\n\n // 1. Try key match.\n const toKey = getNodeKey(toChild);\n if (toKey !== undefined && keyed.has(toKey)) {\n matched = keyed.get(toKey) as Element;\n keyed.delete(toKey);\n if (matched !== fromChild) {\n // A keyed match found elsewhere is a genuine move of a connected node —\n // `moveNode` preserves its live state (focus / animation / iframe) via\n // `moveBefore` where supported.\n moveNode(fromParent, matched, fromChild);\n } else {\n fromChild = skipOwned(fromChild.nextSibling, ownedItems);\n }\n }\n\n // 2. Fall back to positional match — same nodeType, same tag (for\n // elements), and NEITHER side carries a key. A key on either side is a\n // statement of identity, so it must be honored in both directions:\n //\n // - live keyed: matches by key only, never positionally, so reorders\n // work rather than churning whatever happens to sit at the index.\n // - template keyed: step 1 already looked for its key among the live\n // children and didn't find it, so the element the template is asking\n // for is genuinely not here. Adopting an unkeyed same-tag neighbour\n // instead repurposes a node that is something else, and the rules that\n // protect a node's contents (`data-morph-skip`, `data-morph-preserve`,\n // a binding marker's inserted text node) then keep the wrong contents\n // alive inside it: a skipped widget swallows the element and gets\n // duplicated, a preserved child ends up under a foreign host, a bound\n // hole's text leaks. Those rules are each right; the pairing was not.\n if (matched === null && fromChild !== null\n && fromChild.nodeType === toChild.nodeType\n && markersPairable(fromChild, toChild)\n && (toChild.nodeType !== ELEMENT_NODE\n || ((fromChild as Element).tagName === (toChild as Element).tagName\n && getNodeKey(fromChild) === undefined\n && toKey === undefined\n && protectionTag(fromChild) === protectionTag(toChild)))) {\n matched = fromChild;\n // KF-385: a matched list marker carries its whole row region, so the\n // cursor must land AFTER the last row — not merely after the contiguous\n // owned run. Stopping at an interloper between rows parks the cursor\n // inside the list, where the next template sibling would be inserted\n // (a trailing <button> landing amongst the rows).\n fromChild = skipOwned(\n isListMarker(matched)\n ? afterListRegion(matched as Comment, ownedItems)\n : fromChild.nextSibling,\n ownedItems,\n );\n // KF-374: a binding marker comment OWNS the text node the wiring pass\n // inserted right after it — the template never contains that node\n // (templates carry only the marker). Step the cursor past it so a\n // template static sibling pairs with its real live counterpart instead\n // of the inserted node; behind the cursor, the inserted node also\n // survives the trailing-removal pass.\n if (matched.nodeType === COMMENT_NODE && fromChild !== null) {\n const owned = boundTextNodeOf(matched as Comment);\n if (owned !== null && fromChild === owned) {\n fromChild = skipOwned(owned.nextSibling, ownedItems);\n }\n }\n }\n\n // 2.5. Positional lookahead (KF-377: removing a conditional sibling ahead\n // of a keyed list must not rebuild the list's container). The\n // positional match failed, but the real counterpart may sit further\n // along the live children — the common case is a conditional element\n // this render removed, shifting everything after it one slot left.\n // Without this, the shifted element is cloned from scratch and the\n // original is dropped by the trailing-removal pass — catastrophic when\n // it (or a descendant) hosts an each() marker, whose ListBinding would\n // detach permanently. Scan forward for the first same-tag unkeyed\n // element and move it up, exactly the move the keyed branch performs;\n // skipped-over live nodes stay behind the cursor for later template\n // children or the trailing-removal pass. Elements only: comments/text\n // are stateless to rebuild, and binding-marker comments own an\n // inserted text sibling that must never be separated by a move. The\n // ONE comment exception is the each() list marker — see 2.6.\n // Keyed template elements are excluded for the same reason as step 2:\n // step 1 already searched every live child for that key, so moving up an\n // unkeyed stranger would repurpose a node that is something else.\n if (matched === null && toChild.nodeType === ELEMENT_NODE && fromChild !== null\n && toKey === undefined) {\n const toTag = (toChild as Element).tagName;\n for (let scan: Node | null = fromChild.nextSibling; scan !== null; scan = scan.nextSibling) {\n if (scan.nodeType !== ELEMENT_NODE) continue;\n const el = scan as Element;\n if (ownedItems.has(el)) continue;\n if (el.tagName !== toTag || getNodeKey(el) !== undefined) continue;\n if (protectionTag(el) !== protectionTag(toChild)) continue;\n matched = el;\n // Moving a connected same-tag element up to the cursor → state-preserving.\n moveNode(fromParent, el, fromChild);\n break;\n }\n }\n\n // 2.6. Marker-aware lookahead (KF-382: a sibling that shifts an each()\n // list's begin-anchor must not cost the rows their DOM identity). A\n // `kf-list:` comment is the one comment kind that is NOT stateless to\n // rebuild: it anchors a ListBinding, and its rows exist only in the live\n // tree (the template carries the bare marker). Cloning it instead of\n // moving it detaches the binding, so mount() self-heals by re-creating\n // every row — correct, but focus / scroll / IME / listeners are lost.\n // Scan forward for the SAME marker (matched on exact data, so sibling\n // lists in one parent can't cross-match) and move it up. The marker\n // travels WITH its whole row region: moving it alone would let a later\n // template sibling (a trailing <button>, say) match ahead of the rows\n // and wedge itself between the anchor and the rows it anchors.\n if (matched === null && fromChild !== null\n && toChild.nodeType === COMMENT_NODE\n && (toChild as Comment).data.startsWith(LIST_MARKER_PREFIX)) {\n const wantData = (toChild as Comment).data;\n for (let scan: Node | null = fromChild.nextSibling; scan !== null; scan = scan.nextSibling) {\n if (scan.nodeType !== COMMENT_NODE || (scan as Comment).data !== wantData) continue;\n // The run is the marker through its LAST owned row — interlopers in\n // between travel along (KF-385). Stopping at the first non-owned node\n // instead would truncate the run to the bare marker the moment anything\n // sat between the anchor and the rows (an imperatively-injected\n // `data-morph-preserve` node, say), silently reintroducing the unsafe\n // move-alone variant. Carrying interlopers also keeps them where the\n // consumer put them, relative to the list.\n const regionEnd = afterListRegion(scan as Comment, ownedItems);\n const run: Node[] = [];\n for (let r: Node | null = scan; r !== null && r !== regionEnd; r = r.nextSibling) {\n run.push(r);\n }\n // Some engines (older Safari, happy-dom) blur a focused descendant on\n // `insertBefore` even though the node survives the move connected —\n // the same quirk the list reconciler's move pass handles. Preserving\n // row identity is only half the promise; the caret has to survive too.\n // The run nodes are all connected children of `fromParent`, so `moveNode`\n // takes the atomic `moveBefore` path where supported (which preserves the\n // caret natively, leaving the snapshot below a no-op); the snapshot still\n // covers engines without `moveBefore`.\n const focusSnap = captureFocus(fromParent);\n for (const node of run) moveNode(fromParent, node, fromChild);\n if (focusSnap !== null) restoreFocus(focusSnap);\n matched = scan;\n break;\n }\n }\n\n if (matched !== null) {\n morphNode(matched, toChild, ownedItems);\n } else {\n // 3. No match — clone the new node and insert before fromChild\n // (which may be an owned item we deliberately stopped at; that's\n // fine — `insertBefore(node, ownedItem)` slots the new sibling\n // in immediately before the list region).\n const cloned = toChild.cloneNode(true);\n fromParent.insertBefore(cloned, fromChild);\n }\n\n toChild = toNext;\n }\n\n // 4. Anything past the cursor is unmatched — remove, except for owned\n // items (those stay; they belong to a list reconciler) and elements\n // marked `data-morph-preserve` (KF-151 — imperatively-injected nodes\n // whose lifetime the consumer manages outside kerf).\n while (fromChild !== null) {\n const next = fromChild.nextSibling;\n if (fromChild.nodeType === ELEMENT_NODE) {\n const el = fromChild as Element;\n if (!ownedItems.has(el)\n && (el as HTMLElement).dataset.morphPreserve === undefined) {\n fromParent.removeChild(fromChild);\n }\n } else {\n fromParent.removeChild(fromChild);\n }\n fromChild = next;\n }\n}\n\nfunction morphNode(\n fromNode: Node,\n toNode: Node,\n ownedItems: ReadonlySet<Element>,\n): void {\n if (fromNode.nodeType === ELEMENT_NODE) {\n morphElement(fromNode as Element, toNode as Element, ownedItems);\n return;\n }\n if (fromNode.nodeType === TEXT_NODE || fromNode.nodeType === COMMENT_NODE) {\n const fromText = fromNode as CharacterData;\n const toText = toNode as CharacterData;\n if (fromText.data !== toText.data) fromText.data = toText.data;\n }\n}\n\nfunction morphElement(\n fromEl: Element,\n toEl: Element,\n ownedItems: ReadonlySet<Element>,\n): void {\n if (fromEl.tagName !== toEl.tagName) {\n const replacement = toEl.cloneNode(true);\n fromEl.parentNode?.replaceChild(replacement, fromEl);\n return;\n }\n // 1. Library-owned subtree — leave verbatim.\n if ((fromEl as HTMLElement).dataset.morphSkip !== undefined) return;\n // 2. Byte-identical — nothing to do.\n if (fromEl.isEqualNode(toEl)) return;\n // 3. Focused contenteditable — preserve user's in-progress edit.\n if (fromEl === document.activeElement) {\n const ce = fromEl.getAttribute('contenteditable');\n if (ce !== null && ce.toLowerCase() !== 'false') return;\n if (isTextInputOrTextarea(fromEl)) preserveTextEntryState(fromEl, toEl);\n }\n morphAttributes(fromEl, toEl);\n // 4. Subtree-only skip (KF-152) — attributes have already morphed; leave\n // the children alone. Use for client-hydrated slots whose loading /\n // state classes still need to flow through.\n if ((fromEl as HTMLElement).dataset.morphSkipChildren !== undefined) return;\n // KF-335: a TEXTAREA's value lives in its child text, and the dirty-value\n // flag detaches the property once the user (or script) has touched it.\n // When the template's text genuinely differs — a template-driven change,\n // detected BEFORE the child morph rewrites the live text — carry the\n // property along after the morph. A focused textarea keeps the user's\n // in-progress edit (same exception as the input `value` sync), and an\n // unchanged template leaves a dirty textarea untouched (uncontrolled\n // usage preserved).\n const syncTextareaValue = fromEl.tagName === 'TEXTAREA'\n && fromEl !== document.activeElement\n && fromEl.textContent !== toEl.textContent;\n // 5. Recurse into children. List items inside `fromEl` (if any) are\n // skipped via `ownedItems` inside morphChildren — list reconciler\n // owns them — but non-list siblings are still morphed.\n morphChildren(fromEl, toEl, ownedItems);\n if (syncTextareaValue) {\n // `textContent` is only null for Document/DocumentType nodes — for an\n // element it's always a string, so the cast avoids an unreachable `?? ''`\n // branch under the coverage gate.\n (fromEl as HTMLTextAreaElement).value = toEl.textContent as string;\n }\n}\n\n/**\n * Attributes the user agent toggles in response to user interaction.\n * `<details>` and `<dialog>` add/remove `open=\"\"` themselves when the user\n * expands or closes the element. If the developer's JSX never mentions\n * `open`, treating that attribute as user-agent-owned and leaving it alone\n * during the morph keeps the user-driven state intact across re-renders.\n *\n * Trade-off (KF-84): controlled-style `<details open={signal.value}>` where\n * the signal flips false won't auto-collapse the element, because the\n * morph's remove pass no longer reaches `open`. Apps that need controlled\n * behavior should drive `open` imperatively (e.g. `el.removeAttribute('open')`\n * inside an action) or wrap with a state-toggle pattern. The uncontrolled\n * case is the common one and the one that was silently broken before.\n */\nfunction isUserAgentOwnedAttr(tagName: string, name: string): boolean {\n return name === 'open' && (tagName === 'DETAILS' || tagName === 'DIALOG');\n}\n\nfunction morphAttributes(fromEl: Element, toEl: Element): void {\n // Set/update every attribute on toEl.\n const toAttrs = toEl.attributes;\n for (let i = 0; i < toAttrs.length; i++) {\n const attr = toAttrs[i];\n const ns = attr.namespaceURI;\n const name = attr.localName;\n const value = attr.value;\n if (ns !== null) {\n if (fromEl.getAttributeNS(ns, name) !== value) {\n fromEl.setAttributeNS(ns, attr.name, value);\n }\n } else if (fromEl.getAttribute(name) !== value) {\n fromEl.setAttribute(name, value);\n // KF-335: a mutated checked/value/selected attribute must carry the live\n // property with it — after user interaction the dirty flag detaches the\n // property from the attribute, so an attribute-only write leaves the\n // visible state stale. Sync happens ONLY on actual attribute mutation,\n // so uncontrolled elements (JSX never mentions the attr) stay untouched.\n syncFormProp(fromEl, name, value, true);\n }\n }\n // Remove attributes that are no longer present on toEl.\n const fromAttrs = fromEl.attributes;\n const fromTag = fromEl.tagName;\n for (let i = fromAttrs.length - 1; i >= 0; i--) {\n const attr = fromAttrs[i];\n const ns = attr.namespaceURI;\n const name = attr.localName;\n if (ns !== null) {\n if (!toEl.hasAttributeNS(ns, name)) fromEl.removeAttributeNS(ns, name);\n } else if (!toEl.hasAttribute(name) && !isUserAgentOwnedAttr(fromTag, name)) {\n fromEl.removeAttribute(name);\n // KF-335: removed checked/value/selected attr → property follows (see\n // the set-side comment above).\n syncFormProp(fromEl, name, '', false);\n }\n }\n}\n\nfunction isTextInputOrTextarea(el: Element): boolean {\n if (el.tagName === 'TEXTAREA') return true;\n if (el.tagName === 'INPUT') {\n const type = (el as HTMLInputElement).type;\n return type === 'text' || type === 'search' || type === 'url' || type === 'email'\n || type === 'tel' || type === 'password' || type === '';\n }\n return false;\n}\n\nfunction preserveTextEntryState(fromEl: Element, toEl: Element): void {\n if (fromEl.tagName === 'TEXTAREA' || fromEl.tagName === 'INPUT') {\n const fromInput = fromEl as HTMLInputElement;\n const toInput = toEl as HTMLInputElement;\n toInput.value = fromInput.value;\n try {\n toInput.setSelectionRange(fromInput.selectionStart, fromInput.selectionEnd);\n } catch {\n // Some input types (number, range, color, …) reject selection APIs.\n }\n }\n}\n","/**\n * Per-list binding shape kept by `mount()` and consumed by both reconcile\n * paths in `list-reconcile-snapshot.ts` and `list-reconcile-granular.ts`.\n *\n * Living in its own file (not re-exported through `list-reconcile.ts`) so\n * the snapshot + granular paths can import it without creating a circular\n * dependency on `list-reconcile.ts` itself. ESM handles cycles via function\n * hoisting, but a cycle involving a non-function helper would be a temporal\n * dead zone — extracting the binding shape + `endAnchor` here keeps the\n * dependency graph acyclic.\n */\n\nimport type { Binding } from './bindings.js';\n\nexport interface BoundItem {\n ref: object;\n cacheKey: unknown;\n html: string;\n node: Element;\n /** KF-294: this row's fine-grained binding specs (undefined/empty if none). */\n bindings?: Binding[];\n /**\n * KF-294: live disposers for this row's bound effects. Set when the row node\n * is wired (first-render inline in `mount()`, or `buildFreshNodes` during a\n * reconcile) and called when the node is removed / the mount is torn down.\n */\n bindingDisposers?: Array<() => void>;\n}\n\nexport interface ListBinding {\n liveParent: Element;\n /**\n * One entry per item currently mounted under `liveParent`, in order.\n * Mirrors the segment's `items` length after each reconcile.\n */\n items: BoundItem[];\n /**\n * The list's `<!--kf-list:N-->` start marker, kept in the live DOM as\n * a permanent anchor (KF-102 round 2). The marker stays put across\n * static-surrounds diffs (it morphs as a comment node), so it gives\n * the list reconciler a stable \"begin\" position even when surrounding\n * siblings get inserted, removed, or reordered around the list.\n *\n * `endAnchor(binding)` derives the \"insert at end of list\" anchor from\n * `marker.nextSibling` (empty list) or `items[last].node.nextSibling`\n * (non-empty list) — picking up whatever the diff placed between the\n * list and the parent's tail.\n */\n marker: Comment;\n\n /**\n * KF-173: once we've emitted the missing-key dev warning for this list,\n * we suppress further warnings for the same binding. The flag is set\n * inside `maybeWarnMissingRowKey()` and never cleared — the list is\n * considered \"decided\" after the first row check.\n */\n warnedMissingKey?: boolean;\n}\n\n/**\n * Compute the live-DOM anchor that comes after the list's last item, used\n * by the apply* functions when inserting at the tail of the list.\n *\n * - Empty list: `marker.nextSibling`.\n * - Non-empty list: `items[last].node.nextSibling` — derived dynamically so\n * that siblings the diff inserted between the list's last item and the\n * parent's tail still anchor correctly.\n *\n * **`nextSibling`, not `nextElementSibling`.** The list's region ends at its\n * last row, and the very next node — of any type — is the boundary. Skipping\n * to the next *element* walks straight past the two things most likely to sit\n * there and appends at the parent's tail instead: static text or comments\n * after the list (so a new row jumps a trailing `footer`), and the next\n * sibling list's `<!--kf-list:…-->` marker (so two lists that are both empty\n * both anchor at `null` and interleave their rows in the wrong order — with\n * the *second* list's rows landing first, since the first list to fill has\n * nothing to anchor against).\n */\nexport function endAnchor(binding: ListBinding): Node | null {\n if (binding.items.length > 0) {\n return binding.items[binding.items.length - 1].node.nextSibling;\n }\n return binding.marker.nextSibling;\n}\n","/**\n * Fast paths for the granular update reconciler (KF-198 + KF-206).\n *\n * Two heuristics that catch common arraySignal-update shapes before the\n * standard parse + morph path runs and apply the change directly to the\n * live row:\n *\n * - **Attribute-only (KF-198)**: when the only diff between old and new\n * row HTML is in the top-level element's attribute values, call\n * setAttribute / removeAttribute on the live node. Targets the krausest\n * select-row scenario where 2 updates flip `class=\"\"` ↔ `class=\"danger\"`\n * on a `<tr>` with otherwise identical 4-child subtree. Skips parse +\n * morph entirely.\n *\n * - **Text-content-only (KF-206)**: when the only diff is inside one text\n * node's content (no entity touching, no structural or attribute\n * change), patch that text node's nodeValue. Targets the krausest\n * partial-update scenario where 100 updates each rewrite one label\n * text node deep inside the row.\n *\n * Both fast paths bail conservatively on anything that could go wrong —\n * namespaced attributes (`xmlns:*` etc.), `data-morph-skip` anywhere in the\n * row, user-agent-owned attributes (`<details open>`), entity-touching\n * diffs — and the granular path falls back to `_morphElement` or\n * `replaceChild`. The sanity check at the end of the text-content path\n * (live text node's nodeValue must equal what we extracted from oldHtml)\n * is the final safety net: if anything has drifted, we bail.\n *\n * Internal to kerf.\n */\n\nconst LT = 0x3C; // <\nconst GT = 0x3E; // >\nconst DQUOTE = 0x22; // \"\nconst SQUOTE = 0x27; // '\nconst AMP = 0x26; // &\nconst EQ = 0x3D; // =\nconst SLASH = 0x2F; // /\nconst TEXT_NODE = 3;\nimport { syncFormProp } from './utils/syncFormProp.js';\n\nconst ELEMENT_NODE = 1;\n\nfunction isWhitespace(cc: number): boolean {\n return cc === 0x20 || cc === 0x09 || cc === 0x0A || cc === 0x0D;\n}\n\ninterface ParsedTag {\n tagName: string;\n attrs: Map<string, string>;\n}\n\n/**\n * KF-198. Returns true if the diff between `oldHtml` and `newHtml` was an\n * attribute-only change on the top-level element AND was applied to\n * `liveNode` directly. Caller should NOT also run the parse + morph path.\n */\nexport function tryAttributeOnlyFastPath(\n liveNode: Element,\n oldHtml: string,\n newHtml: string,\n): boolean {\n // Kerf's JSX runtime escapes '>' to '>' in attribute values and text\n // content, so the first '>' in the row HTML is always the close of the\n // top-level opening tag.\n const oldGt = oldHtml.indexOf('>');\n const newGt = newHtml.indexOf('>');\n if (oldGt === -1 || newGt === -1) return false;\n\n // Everything from '>' onward (children + closing tag) must be byte-equal.\n // If not, the diff is structural or includes text-content changes — defer\n // to the morph path (or the text-content fast path).\n if (oldHtml.length - oldGt !== newHtml.length - newGt) return false;\n if (oldHtml.slice(oldGt) !== newHtml.slice(newGt)) return false;\n\n if (containsDataMorphSkip(oldHtml) || containsDataMorphSkip(newHtml)) return false;\n\n const oldTag = parseOpeningTag(oldHtml, oldGt);\n const newTag = parseOpeningTag(newHtml, newGt);\n if (oldTag === null || newTag === null) return false;\n if (oldTag.tagName !== newTag.tagName) return false;\n\n // Pre-validate: no namespaced attribute names on either side. Setting via\n // plain setAttribute on a namespaced attribute would land it in the null\n // namespace and not match the original; bail and let morph handle it.\n for (const name of oldTag.attrs.keys()) {\n if (name.indexOf(':') !== -1) return false;\n }\n for (const name of newTag.attrs.keys()) {\n if (name.indexOf(':') !== -1) return false;\n }\n\n // Apply the diff.\n const liveTagUpper = liveNode.tagName;\n for (const [name, rawValue] of newTag.attrs) {\n const oldValue = oldTag.attrs.get(name);\n if (oldValue === rawValue) continue;\n const value = unescapeAttrValue(rawValue);\n liveNode.setAttribute(name, value);\n // KF-390: this is the third attribute writer in the codebase, and it has\n // to honor the same rule as the morph's writer and the binding writer — a\n // mutated checked/value/selected attribute must carry the live property\n // with it, because the browser detaches the two once the control is dirty\n // (KF-335). Without this, whether a controlled row obeyed the app depended\n // on which internal route the diff happened to take.\n syncFormProp(liveNode, name, value, true);\n }\n for (const name of oldTag.attrs.keys()) {\n if (newTag.attrs.has(name)) continue;\n if (isUserAgentOwnedAttr(liveTagUpper, name)) continue;\n liveNode.removeAttribute(name);\n syncFormProp(liveNode, name, '', false);\n }\n return true;\n}\n\n/**\n * KF-206. Returns true if the diff between `oldHtml` and `newHtml` was a\n * single-text-node content change AND was applied to `liveNode`'s\n * corresponding live text node directly. Caller should NOT also run the\n * parse + morph path.\n */\nexport function tryTextContentFastPath(\n liveNode: Element,\n oldHtml: string,\n newHtml: string,\n): boolean {\n if (containsDataMorphSkip(oldHtml) || containsDataMorphSkip(newHtml)) return false;\n\n let p = 0;\n const minLen = Math.min(oldHtml.length, newHtml.length);\n while (p < minLen && oldHtml.charCodeAt(p) === newHtml.charCodeAt(p)) p++;\n let s = 0;\n const maxS = minLen - p;\n while (s < maxS\n && oldHtml.charCodeAt(oldHtml.length - 1 - s) === newHtml.charCodeAt(newHtml.length - 1 - s)) {\n s++;\n }\n\n const oldWinEnd = oldHtml.length - s;\n const newWinEnd = newHtml.length - s;\n\n // Diff windows must contain only text-content characters — no tag\n // delimiters, no quotes, no entities, no '=' (which would put us inside\n // an attribute). Either window having an unsafe char means this is not a\n // clean text-only change.\n if (!isPureTextWindow(oldHtml, p, oldWinEnd)) return false;\n if (!isPureTextWindow(newHtml, p, newWinEnd)) return false;\n\n // The char just before the equal-prefix boundary must be either '>'\n // (text node starts here) or another text-content char (we're mid-text).\n // '<' / '\"' / \"'\" / '=' / '&' would mean we're inside a tag or entity.\n if (p === 0) return false;\n const boundaryCc = oldHtml.charCodeAt(p - 1);\n if (boundaryCc === LT || boundaryCc === DQUOTE || boundaryCc === SQUOTE\n || boundaryCc === EQ || boundaryCc === AMP) return false;\n\n // Find the text node's HTML-string boundaries. Text node containing\n // position p starts after the most recent '>' before p in oldHtml; ends\n // at the next '<' at or after p.\n const textStart = lastIndexOfChar(oldHtml, GT, p - 1);\n if (textStart === -1) return false;\n const textEnd = oldHtml.indexOf('<', p);\n if (textEnd === -1) return false;\n // The diff window in oldHtml must lie entirely within this text node.\n if (textEnd < oldWinEnd) return false;\n // newHtml's corresponding `<` position is shifted by the length delta\n // (the diff window is entirely inside this text node, so everything after\n // it is in the equal-suffix region).\n const newTextEnd = textEnd + (newHtml.length - oldHtml.length);\n const oldText = oldHtml.slice(textStart + 1, textEnd);\n const newText = newHtml.slice(textStart + 1, newTextEnd);\n\n // KF-374: a binding TEXT marker (`<!--kfb:…-->` / `<!--kfbr:…-->`) earlier\n // in the row means the LIVE row carries an extra wiring-inserted text node\n // the HTML string doesn't contain — the HTML-position → nth-live-text-node\n // mapping below would be off by one, and the nodeValue safety net could be\n // defeated by a coincidental value match (patching the bound node instead\n // of the static one). Bail to the morph path, which pairs marker-owned\n // nodes correctly. Markers at/after the diff's text node don't shift the\n // index and stay on the fast path.\n if (oldHtml.lastIndexOf('<!--kfb', textStart) !== -1) return false;\n\n // Find the text-node-index in document order.\n const textIdx = countTextNodesBefore(oldHtml, textStart + 1);\n const targetNode = nthTextNodeDescendant(liveNode, textIdx);\n if (targetNode === null) return false;\n\n // Final safety net: the live text node's nodeValue must equal the text\n // we extracted from oldHtml. If it differs (HTML-string vs live drift,\n // browser whitespace normalization, imperative mutation, etc.), bail\n // so the morph path can do its safe thing.\n if (targetNode.nodeValue !== oldText) return false;\n\n targetNode.nodeValue = newText;\n // KF-397: a <textarea>'s value lives in its child text, and the dirty-value\n // flag detaches the property from that text once the control has been\n // touched. This is the FOURTH writer subject to the KF-335 rule (after the\n // morph's attribute writer, the binding writer, and the attribute-only fast\n // path) — the rule is about mutating form state, not specifically about\n // attributes, and a text mutation on a textarea is exactly that. The morph\n // route already syncs here, so without this the control's visible value\n // depended on which internal route the diff took.\n const host = targetNode.parentNode;\n if (host !== null && (host as Element).tagName === 'TEXTAREA'\n && host !== document.activeElement) {\n // A focused textarea holds the user's in-progress edit — the same\n // exception `syncFormProp` makes for `value`.\n (host as HTMLTextAreaElement).value = newText;\n }\n return true;\n}\n\nfunction containsDataMorphSkip(html: string): boolean {\n return html.indexOf('data-morph-skip') !== -1;\n}\n\nfunction isPureTextWindow(html: string, start: number, end: number): boolean {\n for (let i = start; i < end; i++) {\n const cc = html.charCodeAt(i);\n if (cc === LT || cc === GT || cc === DQUOTE || cc === SQUOTE\n || cc === AMP || cc === EQ) return false;\n }\n return true;\n}\n\nfunction lastIndexOfChar(html: string, target: number, beforeInclusive: number): number {\n for (let i = beforeInclusive; i >= 0; i--) {\n if (html.charCodeAt(i) === target) return i;\n }\n return -1;\n}\n\n/**\n * Count text-content runs (non-empty stretches between `>` and `<`) that\n * START before `beforePos` in `html`. Used to convert an HTML-string\n * position to the corresponding text-node-index in document order. Relies\n * on kerf-emitted HTML's invariant that `<` / `>` outside attribute values\n * always denote tag boundaries (entities escape them everywhere else).\n */\nfunction countTextNodesBefore(html: string, beforePos: number): number {\n let count = 0;\n let i = 0;\n while (i < beforePos) {\n if (html.charCodeAt(i) === LT) {\n while (i < beforePos && html.charCodeAt(i) !== GT) i++;\n i++;\n } else {\n const start = i;\n while (i < beforePos && html.charCodeAt(i) !== LT) i++;\n if (i > start) count++;\n }\n }\n return count;\n}\n\nfunction nthTextNodeDescendant(root: Element, n: number): Text | null {\n let count = 0;\n let result: Text | null = null;\n function walk(node: Node): void {\n for (let c = node.firstChild; c !== null; c = c.nextSibling) {\n if (result !== null) return;\n if (c.nodeType === TEXT_NODE) {\n if (count === n) {\n result = c as Text;\n return;\n }\n count++;\n } else if (c.nodeType === ELEMENT_NODE) {\n walk(c);\n }\n }\n }\n walk(root);\n return result;\n}\n\n/**\n * Parse the top-level opening tag of `html` whose closing `>` is at\n * `gtPos`. Returns null on any malformed shape (missing tag name,\n * unquoted attribute values, unterminated attribute, etc.) so the caller\n * bails to the morph path. Kerf's JSX runtime emits well-formed,\n * double-quoted attribute values, so the success path is the common one.\n */\nfunction parseOpeningTag(html: string, gtPos: number): ParsedTag | null {\n if (html.charCodeAt(0) !== LT) return null;\n let i = 1;\n let end = gtPos;\n // Self-closing slash (e.g. `<br/>`) — drop it from the parse range.\n if (i < end && html.charCodeAt(end - 1) === SLASH) end -= 1;\n\n const nameStart = i;\n while (i < end) {\n const cc = html.charCodeAt(i);\n if (isWhitespace(cc)) break;\n i++;\n }\n const tagName = html.slice(nameStart, i);\n if (tagName.length === 0) return null;\n\n const attrs = new Map<string, string>();\n while (i < end) {\n while (i < end && isWhitespace(html.charCodeAt(i))) i++;\n if (i >= end) break;\n const aNameStart = i;\n while (i < end) {\n const cc = html.charCodeAt(i);\n if (cc === EQ || isWhitespace(cc)) break;\n i++;\n }\n const aName = html.slice(aNameStart, i);\n if (aName.length === 0) return null;\n while (i < end && isWhitespace(html.charCodeAt(i))) i++;\n if (i < end && html.charCodeAt(i) === EQ) {\n i++;\n while (i < end && isWhitespace(html.charCodeAt(i))) i++;\n if (i >= end) return null;\n const q = html.charCodeAt(i);\n if (q !== DQUOTE && q !== SQUOTE) return null;\n i++;\n const vStart = i;\n while (i < end && html.charCodeAt(i) !== q) i++;\n if (i >= end) return null;\n attrs.set(aName, html.slice(vStart, i));\n i++;\n } else {\n attrs.set(aName, '');\n }\n }\n return { tagName, attrs };\n}\n\n/**\n * Reverse the five entities kerf's `escapeAttr` produces. Replace in safe\n * order (named entities first; `&` last so its decode doesn't pick up\n * the `&` we just emitted from a different decode).\n */\nfunction unescapeAttrValue(s: string): string {\n if (s.indexOf('&') === -1) return s;\n return s\n .replace(/"/g, '\"')\n .replace(/'/g, \"'\")\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/&/g, '&');\n}\n\n/**\n * `<details>` and `<dialog>` toggle `open` themselves in response to user\n * interaction. Mirror `morphAttributes`' rule: never remove `open` on them\n * during the fast path — the user-driven state would be wiped.\n */\nfunction isUserAgentOwnedAttr(tagNameUpper: string, name: string): boolean {\n return name === 'open' && (tagNameUpper === 'DETAILS' || tagNameUpper === 'DIALOG');\n}\n","/**\n * Granular reconcile path for `each(...)` bound to an `arraySignal` (KF-92).\n *\n * Applies the patch events emitted by `arraySignal` mutators directly to\n * the live DOM and to `binding.items`, without iterating the full snapshot\n * or doing a classify pass. Cost is O(patches), not O(N).\n *\n * Two perf optimizations:\n * - **KF-93**: contiguous insert runs (patches at index N, N+1, N+2, …) are\n * bulk-parsed in one `template.innerHTML` call and inserted as a single\n * fragment. Saves ~50 ms on append-1k.\n * - **KF-94**: consecutive update runs (any indices — `replaceChild`\n * operates on each row's existing live node independently) are bulk-\n * parsed in one `template.innerHTML` call. Saves the per-patch parse\n * cost on the krausest partial-update scenario.\n *\n * Patches with `type: 'replace'` are filtered out by `each()` upstream and\n * never reach this function (the runtime contract guarantees absence even\n * though the TypeScript type allows them).\n *\n * Internal to kerf — re-exported via `list-reconcile.ts`'s `reconcileList`.\n */\n\nimport { type Binding, carryOrRewireRowBindings, disposeRowBindings, wireRowBindings } from './bindings.js';\nimport { devHooks } from './dev-hooks.js';\nimport { type BoundItem, endAnchor, type ListBinding } from './list-binding.js';\nimport { tryAttributeOnlyFastPath, tryTextContentFastPath } from './list-reconcile-fast-paths.js';\nimport { captureFocus, restoreFocus } from './list-reconcile-focus.js';\nimport { _morphElement } from './morph.js';\nimport type { InsertPatch, ListSegment, UpdatePatch } from './segment.js';\nimport { moveNode } from './utils/moveNode.js';\nimport {\n collectTemplateChildren,\n parseRowTemplate,\n parseSingleRow,\n rowContractError,\n} from './utils/row-contract.js';\n\nexport function reconcileGranular(\n binding: ListBinding,\n patches: NonNullable<ListSegment['patches']>,\n): void {\n const { liveParent } = binding;\n const items = binding.items;\n\n // Capture/restore focus around the whole batch (mirrors the snapshot\n // path's KF-65 fix). Some engines (older Safari, happy-dom) blur a\n // focused descendant on `insertBefore` / `replaceChild` even when the\n // ancestor stays connected — covers the move patch (which moves an\n // existing row's <li>), and is a no-op on engines that already\n // preserve focus across DOM ops.\n const focusSnap = captureFocus(liveParent);\n\n let i = 0;\n while (i < patches.length) {\n const patch = patches[i];\n /* c8 ignore next 5 — replace is filtered upstream by each(); this branch\n is defensive type-completeness only. */\n if (patch.type === 'replace') {\n i += 1;\n continue;\n }\n if (patch.type === 'update') {\n // KF-94: detect a run of consecutive update patches (any indices —\n // replaceChild operates on each row's existing live node independently,\n // so contiguity isn't required) and bulk-parse all their HTML in a\n // single `template.innerHTML` call. Saves the per-patch parse overhead\n // on krausest's partial-update scenario (100 update patches at\n // indices 0, 10, 20, … — non-contiguous, so KF-93's run detector\n // doesn't kick in).\n let runEnd = i + 1;\n while (runEnd < patches.length && patches[runEnd].type === 'update') {\n runEnd += 1;\n }\n const runLen = runEnd - i;\n if (runLen === 1) {\n applySingleUpdate(liveParent, items, patch);\n } else {\n applyBulkUpdate(liveParent, items, patches, i, runEnd);\n }\n i = runEnd;\n continue;\n }\n if (patch.type === 'insert') {\n // KF-93: detect a contiguous run of inserts at adjacent indices (each\n // next insert at the previous one's index + 1) and bulk-parse all\n // their HTML in a single `template.innerHTML` call, followed by a\n // single `insertBefore(fragment, anchor)`.\n let runEnd = i + 1;\n while (runEnd < patches.length\n && patches[runEnd].type === 'insert'\n && (patches[runEnd] as InsertPatch).index\n === (patches[runEnd - 1] as InsertPatch).index + 1) {\n runEnd += 1;\n }\n const runLen = runEnd - i;\n if (runLen === 1) {\n applySingleInsert(liveParent, items, patch, endAnchor(binding));\n } else {\n applyBulkInsert(liveParent, items, patches, i, runEnd, endAnchor(binding));\n }\n i = runEnd;\n continue;\n }\n if (patch.type === 'remove') {\n const entry = items[patch.index];\n // Stop the removed row's effects before detaching its DOM so stale\n // signals cannot keep mutating a node the list no longer owns.\n disposeRowBindings(entry.bindingDisposers);\n liveParent.removeChild(entry.node);\n items.splice(patch.index, 1);\n i += 1;\n continue;\n }\n if (patch.type === 'move') {\n const moved = items[patch.from];\n // Compute the anchor BEFORE we splice, so the index references the\n // pre-move state.\n let anchorIdx = patch.to;\n if (patch.from < patch.to) anchorIdx += 1; // account for upcoming splice removal\n const anchor = anchorIdx < items.length ? items[anchorIdx].node : endAnchor(binding);\n // A move patch relocates an existing (connected) row, so `moveNode` takes\n // the state-preserving `moveBefore` path where supported.\n moveNode(liveParent, moved.node, anchor);\n items.splice(patch.from, 1);\n items.splice(patch.to, 0, moved);\n i += 1;\n continue;\n }\n }\n\n if (focusSnap !== null) restoreFocus(focusSnap);\n // KF-173: warn once per binding if rows lack id / data-key.\n if (items.length > 0) {\n devHooks.missingRowKey?.(items[0].node, items[0].html, binding);\n }\n}\n\nfunction applySingleInsert(\n liveParent: Element,\n items: BoundItem[],\n patch: InsertPatch,\n tailAnchor: Node | null,\n): void {\n const { html } = patch;\n const newNode = parseSingleRow(html, patch.index, liveParent);\n const anchor = patch.index < items.length ? items[patch.index].node : tailAnchor;\n liveParent.insertBefore(newNode, anchor);\n items.splice(patch.index, 0, {\n ref: patch.item, cacheKey: undefined, html, node: newNode,\n bindings: patch.bindings,\n // KF-294: wire the inserted row's fine-grained bindings to its new node.\n bindingDisposers: wireRowIfBound(newNode, patch.bindings),\n });\n}\n\n/** Wire a fresh row's bindings if it has any; undefined otherwise. */\nfunction wireRowIfBound(node: Element, bindings: Binding[] | undefined): Array<() => void> | undefined {\n return bindings !== undefined && bindings.length > 0 ? wireRowBindings(node, bindings) : undefined;\n}\n\nfunction applySingleUpdate(\n liveParent: Element,\n items: BoundItem[],\n patch: UpdatePatch,\n): void {\n const { html } = patch;\n const oldEntry = items[patch.index];\n if (html === oldEntry.html) {\n // Identical HTML is NOT a full no-op when the row has bound holes: a\n // self-reading hole's value lives behind a marker, so the string never\n // changes while the binding instances do (KF-347). Route through\n // reuseBound so instance drift re-wires; binding-free rows exit as\n // cheaply as the old early-return.\n items[patch.index] = reuseBound(patch, html, oldEntry);\n return;\n }\n // KF-198 + KF-206: surgical fast paths for the common arraySignal update\n // shapes — top-level attribute flip (krausest select-row) and one-text-\n // node content change (krausest partial-update). Both apply the change\n // directly to the live row, skipping the parse + morph entirely. They\n // bail conservatively on anything that could be unsafe and fall through\n // to the existing _morphElement / replaceChild routes below.\n if (tryAttributeOnlyFastPath(oldEntry.node, oldEntry.html, html)\n || tryTextContentFastPath(oldEntry.node, oldEntry.html, html)) {\n items[patch.index] = reuseBound(patch, html, oldEntry);\n return;\n }\n const newNode = parseSingleRow(html, patch.index, liveParent);\n applyParsedRowUpdate(liveParent, items, patch, html, newNode);\n}\n\n/**\n * Shared tail of both update paths (KF-201): morph the existing live node in\n * place when tags match, so structure-preserving updates (text-node change,\n * attribute flip) apply surgically — preserving DOM identity, focus, scroll,\n * IME state, and skipping the layout cost of a full subtree\n * discard-and-reinsert. For the rare tag-mismatch case (consumer's render fn\n * returns a different top-level tag for the same item), fall back to explicit\n * replaceChild so we keep a reference to the new live node.\n */\nfunction applyParsedRowUpdate(\n liveParent: Element,\n items: BoundItem[],\n patch: UpdatePatch,\n html: string,\n newNode: Element,\n): void {\n const oldEntry = items[patch.index];\n if (oldEntry.node.tagName === newNode.tagName) {\n _morphElement(oldEntry.node, newNode);\n items[patch.index] = reuseBound(patch, html, oldEntry);\n } else {\n disposeRowBindings(oldEntry.bindingDisposers); // KF-294: old node discarded\n liveParent.replaceChild(newNode, oldEntry.node);\n items[patch.index] = {\n ref: patch.item, cacheKey: undefined, html, node: newNode,\n bindings: patch.bindings, bindingDisposers: wireRowIfBound(newNode, patch.bindings),\n };\n }\n}\n\n/**\n * KF-294: build the updated `BoundItem` for an in-place update (node reused\n * via a fast path, `_morphElement`, or an html-identical no-op). The row's\n * DOM node survives; whether its live bound effects survive with it is\n * decided per hole by `carryOrRewireRowBindings` (KF-347): same signal\n * instances → carry the existing disposers forward for free; any changed\n * instance — the shape after `arraySignal.update()` swaps the row object and\n * fresh `computed`s close over the NEW item — → dispose + re-wire against\n * the surviving node, so self-reading bound holes update instead of going\n * silently stale.\n */\nfunction reuseBound(\n patch: { item: object; bindings?: Binding[] },\n html: string,\n oldEntry: BoundItem,\n): BoundItem {\n const kept = carryOrRewireRowBindings(\n oldEntry.node, oldEntry.bindings, oldEntry.bindingDisposers, patch.bindings,\n );\n return {\n ref: patch.item, cacheKey: undefined, html, node: oldEntry.node,\n bindings: kept.bindings, bindingDisposers: kept.bindingDisposers,\n };\n}\n\n/**\n * Bulk-parse a run of consecutive update patches (KF-94). Indices may be\n * scattered (non-contiguous). Renders all HTMLs first, filters out no-ops\n * where the new HTML matches the old, then bulk-parses the remaining HTMLs\n * in one `template.innerHTML` call. The replaceChild loop afterwards is\n * unavoidable (one DOM op per row), but we save the per-patch parse cost.\n */\nfunction applyBulkUpdate(\n liveParent: Element,\n items: BoundItem[],\n patches: NonNullable<ListSegment['patches']>,\n start: number,\n end: number,\n): void {\n // Patches already carry pre-rendered HTML (KF-99). One pass over the run:\n // skip no-ops, try the KF-198 / KF-206 fast paths (apply in place when\n // they fire), and collect everything else for one bulk parse + morph.\n interface Change { patchIdx: number; html: string }\n const morphChanges: Change[] = [];\n for (let k = start; k < end; k++) {\n const p = patches[k] as UpdatePatch;\n const oldEntry = items[p.index];\n if (p.html === oldEntry.html) {\n // Same as applySingleUpdate's no-op arm: identical HTML can still carry\n // changed binding instances (self-reading holes render as markers) —\n // reuseBound re-wires on instance drift (KF-347).\n items[p.index] = reuseBound(p, p.html, oldEntry);\n continue;\n }\n if (tryAttributeOnlyFastPath(oldEntry.node, oldEntry.html, p.html)\n || tryTextContentFastPath(oldEntry.node, oldEntry.html, p.html)) {\n items[p.index] = reuseBound(p, p.html, oldEntry); // KF-294: node reused\n continue;\n }\n morphChanges.push({ patchIdx: k, html: p.html });\n }\n if (morphChanges.length === 0) return;\n\n // Bulk-parse only the rows the fast paths couldn't handle.\n const { content, count } = parseRowTemplate(morphChanges.map((c) => c.html).join(''), liveParent);\n if (count !== morphChanges.length) {\n throw findOffendingChange(patches, morphChanges, liveParent);\n }\n const newNodes = collectTemplateChildren(content, morphChanges.length);\n\n // Shared KF-201 morph-vs-replace ladder per row (same tail as\n // applySingleUpdate).\n for (let k = 0; k < morphChanges.length; k++) {\n const c = morphChanges[k];\n const p = patches[c.patchIdx] as UpdatePatch;\n applyParsedRowUpdate(liveParent, items, p, c.html, newNodes[k]);\n }\n}\n\n/**\n * Bulk-parse a contiguous run of insert patches (KF-93). The run starts at\n * `start` (inclusive) and ends at `end` (exclusive); every patch in that\n * range is type `insert` with index === previous.index + 1. We render each\n * row's HTML, concatenate, parse the lot in one `template.innerHTML`, and\n * insert the resulting fragment in a single DOM op.\n */\nfunction applyBulkInsert(\n liveParent: Element,\n items: BoundItem[],\n patches: NonNullable<ListSegment['patches']>,\n start: number,\n end: number,\n tailAnchor: Node | null,\n): void {\n const startIdx = (patches[start] as InsertPatch).index;\n const htmls = new Array<string>(end - start);\n for (let k = start; k < end; k++) {\n htmls[k - start] = (patches[k] as InsertPatch).html;\n }\n const { content, count } = parseRowTemplate(htmls.join(''), liveParent);\n if (count !== htmls.length) {\n throw findOffendingInsert(patches, start, htmls, liveParent);\n }\n // Count matches; capture child refs BEFORE the fragment-insert empties\n // the fragment.\n const newNodes = collectTemplateChildren(content, end - start);\n const anchor = startIdx < items.length ? items[startIdx].node : tailAnchor;\n liveParent.insertBefore(content, anchor);\n // Splice all new entries into binding.items at the run's start index.\n const newEntries = new Array<BoundItem>(end - start);\n for (let k = 0; k < newEntries.length; k++) {\n const p = patches[start + k] as InsertPatch;\n newEntries[k] = {\n ref: p.item, cacheKey: undefined, html: htmls[k], node: newNodes[k],\n bindings: p.bindings,\n // Every fresh row needs its fine-grained holes wired to the newly parsed\n // node; otherwise later signal writes would target no live DOM binding.\n bindingDisposers: wireRowIfBound(newNodes[k], p.bindings),\n };\n }\n items.splice(startIdx, 0, ...newEntries);\n}\n\n/**\n * Slow-path helper for `applyBulkInsert`. Walks each pre-rendered insert\n * patch's html in isolation to find the offending row.\n */\nfunction findOffendingInsert(\n patches: NonNullable<ListSegment['patches']>,\n start: number,\n htmls: string[],\n liveParent: Element,\n): Error {\n for (let i = 0; i < htmls.length; i++) {\n // Parse in the live parent's namespace so the per-row count matches the bulk\n // parse (KF-420) — a namespace mismatch would otherwise miss the offender.\n if (parseRowTemplate(htmls[i], liveParent).count !== 1) {\n return rowContractError((patches[start + i] as InsertPatch).index, htmls[i], liveParent);\n }\n }\n /* c8 ignore start — unreachable: same-namespace per-row parse ⇒ a bulk mismatch has an offender. */\n return new Error('each(): bulk-insert mismatch with no per-row offender (kerf bug).');\n}\n/* c8 ignore stop */\n\n/**\n * Slow-path helper for `applyBulkUpdate`. Walks each non-no-op change to\n * find the offending row.\n */\nfunction findOffendingChange(\n patches: NonNullable<ListSegment['patches']>,\n changes: { patchIdx: number; html: string }[],\n liveParent: Element,\n): Error {\n for (const c of changes) {\n // Parse in the live parent's namespace so the per-row count matches the bulk\n // parse (KF-420) — a namespace mismatch would otherwise miss the offender.\n if (parseRowTemplate(c.html, liveParent).count !== 1) {\n return rowContractError((patches[c.patchIdx] as UpdatePatch).index, c.html, liveParent);\n }\n }\n /* c8 ignore start — unreachable: same-namespace per-row parse ⇒ a bulk mismatch has an offender. */\n return new Error('each(): bulk-update mismatch with no per-row offender (kerf bug).');\n}\n/* c8 ignore stop */\n","/**\n * In-place content-update fast path for the snapshot reconciler.\n *\n * When a re-render produces a list segment with the **same item refs in the\n * same order** as the current binding — no inserts, removes, or moves — then\n * only row CONTENT can have changed. The general snapshot path would treat a\n * same-ref/changed-html row as \"replaced\": remove the old DOM node and insert\n * a freshly-parsed one. In a large `<table>` that node swap forces a full\n * relayout, which is expensive even when only one attribute (e.g. a selection\n * class) flipped.\n *\n * This path instead updates each changed row **in place** — reusing the same\n * surgical/morph/replace ladder the granular path uses for `arraySignal`\n * updates (`list-reconcile-fast-paths.ts` + `_morphElement`). Preserving the\n * row's DOM node keeps focus/scroll/IME state and avoids the layout cost, so\n * external-state-driven row changes (e.g. a single `selectedId` signal read\n * via `each()`'s `cacheKey`) update as cheaply as every other framework does.\n *\n * Only the \"no structural change\" shape is handled here; anything with an\n * insert, remove, or move falls through to the full snapshot algorithm. The\n * rare \"row moved AND changed content\" case therefore stays on the general\n * (node-replacing) path.\n *\n * Internal to kerf — invoked from `reconcileSnapshot`.\n */\n\nimport { carryOrRewireRowBindings, disposeRowBindings } from './bindings.js';\nimport { devHooks } from './dev-hooks.js';\nimport { type BoundItem, type ListBinding } from './list-binding.js';\nimport { tryAttributeOnlyFastPath, tryTextContentFastPath } from './list-reconcile-fast-paths.js';\nimport { captureFocus, restoreFocus } from './list-reconcile-focus.js';\nimport { _morphElement } from './morph.js';\nimport type { ListItem, ListSegment } from './segment.js';\nimport { parseSingleRow } from './utils/row-contract.js';\n\n/**\n * If the new segment has the same refs in the same order as `binding.items`,\n * apply each changed row in place and return `true` (handled). Otherwise\n * return `false` so the caller runs the full classify + LIS + move algorithm.\n */\nexport function tryInPlaceContentUpdate(binding: ListBinding, listSeg: ListSegment): boolean {\n const oldItems = binding.items;\n const items = listSeg.items;\n const n = items.length;\n // Empty lists and any length change can't be a pure content update. Empty\n // is left to the main path (which also handles the missing-key warning edge).\n if (n === 0 || n !== oldItems.length) return false;\n for (let i = 0; i < n; i++) {\n if (items[i].ref !== oldItems[i].ref) return false;\n }\n\n const { liveParent } = binding;\n const newRecord: BoundItem[] = new Array(n);\n // Capture focus once: the surgical + morph routes preserve it inherently,\n // but the rare tag-mismatch `replaceChild` fallback would blur a focused\n // descendant. restoreFocus is a no-op when focus never moved.\n const focusSnap = captureFocus(liveParent);\n for (let i = 0; i < n; i++) {\n newRecord[i] = updateRowInPlace(liveParent, oldItems[i], items[i], i);\n }\n if (focusSnap !== null) restoreFocus(focusSnap);\n\n binding.items = newRecord;\n devHooks.missingRowKey?.(newRecord[0].node, newRecord[0].html, binding);\n return true;\n}\n\n/**\n * Apply one row's content change in place. Mirrors the granular path's\n * `applySingleUpdate` ladder: no-op if unchanged → surgical attribute/text\n * fast paths → `_morphElement` when the top-level tag matches → `replaceChild`\n * when it doesn't (consumer's render fn returned a different top-level tag).\n */\nfunction updateRowInPlace(\n liveParent: Element,\n old: BoundItem,\n ni: ListItem,\n index: number,\n): BoundItem {\n if (old.html === ni.html\n || tryAttributeOnlyFastPath(old.node, old.html, ni.html)\n || tryTextContentFastPath(old.node, old.html, ni.html)) {\n // KF-294: node reused. Whether the bound effects survive with it is\n // per-hole (KF-347): same signal instances → carried for free (the\n // cache-hit / stable-external-signal case); any changed instance —\n // fresh computeds closing over a replaced row object — → dispose +\n // re-wire against the surviving node so self-reading holes don't stale.\n const kept = carryOrRewireRowBindings(old.node, old.bindings, old.bindingDisposers, ni.bindings);\n return {\n ref: ni.ref, cacheKey: ni.cacheKey, html: ni.html, node: old.node,\n bindings: kept.bindings, bindingDisposers: kept.bindingDisposers,\n };\n }\n const newNode = parseSingleRow(ni.html, index, liveParent);\n if (old.node.tagName === newNode.tagName) {\n _morphElement(old.node, newNode);\n // Same carry-or-rewire decision as the fast-path arm above (KF-347).\n const kept = carryOrRewireRowBindings(old.node, old.bindings, old.bindingDisposers, ni.bindings);\n return {\n ref: ni.ref, cacheKey: ni.cacheKey, html: ni.html, node: old.node,\n bindings: kept.bindings, bindingDisposers: kept.bindingDisposers,\n };\n }\n // Tag changed → old node (and its bound effects) is discarded. KF-347 also\n // fixed a gap here: the fresh row's bindings were previously dropped\n // unwired, so a bound hole on a tag-changed row died silently — the helper\n // wires them against the brand-new node (old side empty → wire branch).\n disposeRowBindings(old.bindingDisposers);\n liveParent.replaceChild(newNode, old.node);\n const fresh = carryOrRewireRowBindings(newNode, undefined, undefined, ni.bindings);\n return {\n ref: ni.ref, cacheKey: ni.cacheKey, html: ni.html, node: newNode,\n bindings: fresh.bindings, bindingDisposers: fresh.bindingDisposers,\n };\n}\n","/**\n * Snapshot reconcile path for `each(...)` — the original (non-granular)\n * keyed-list algorithm. Used when:\n * - The list is rendered with a plain array (not an `arraySignal`).\n * - The list is rendered with an `arraySignal` but no patch queue is\n * present (first render, post-`replace()`, or post-drift recovery).\n *\n * Algorithm:\n * 1. Classify each new item as `stable` (cache hit on identity + html),\n * `replaced` (same ref, html changed), or `new` (never seen before).\n * 2. Bulk-parse every fresh row's HTML in ONE `innerHTML` call — for an\n * initial population of 10k rows that's 1 parse instead of 10k.\n * 3. Remove orphan refs (gone from the new list) + replaced rows' old nodes.\n * 4. Compute a longest-increasing-subsequence over old positions; items in\n * the LIS are already in the right relative order, so they don't move.\n * 5. Reverse-pass over the new record, `insertBefore` only the items that\n * didn't anchor the LIS.\n *\n * The KF-89 fast path short-circuits when nothing structural changed —\n * the live tree already matches the new segment, so we can return after\n * step 1 with just the binding update.\n *\n * Internal to kerf — re-exported via `list-reconcile.ts`'s `reconcileList`.\n */\n\nimport { disposeRowBindings, wireRowBindings } from './bindings.js';\nimport { devHooks } from './dev-hooks.js';\nimport { type BoundItem, endAnchor, type ListBinding } from './list-binding.js';\nimport { captureFocus, restoreFocus } from './list-reconcile-focus.js';\nimport { tryInPlaceContentUpdate } from './list-reconcile-inplace.js';\nimport type { ListSegment } from './segment.js';\nimport { moveNode } from './utils/moveNode.js';\nimport { parseRowTemplate, rowContractError } from './utils/row-contract.js';\n\ninterface Classification {\n newRecord: BoundItem[];\n prevIdx: number[];\n removedItems: BoundItem[];\n freshIndices: number[];\n freshHtmls: string[];\n}\n\n/**\n * Reconcile via the snapshot algorithm. Mutates `binding.items` to mirror\n * the new segment when done.\n *\n * Focus capture/restore lives in `list-reconcile-focus.ts` — `insertBefore`\n * of a focused descendant's ancestor blurs the element in some engines\n * (happy-dom, older Safari) even when it stays connected; the snapshot fixes\n * those engines and is a no-op on engines that already preserve focus.\n */\nexport function reconcileSnapshot(binding: ListBinding, listSeg: ListSegment): void {\n // In-place fast path: same refs in the same order (no inserts/removes/moves)\n // → only content changed, so morph changed rows in place instead of swapping\n // their DOM nodes. Avoids the table-relayout cost of node replacement for\n // external-state-driven row changes (e.g. a single selectedId + cacheKey).\n if (tryInPlaceContentUpdate(binding, listSeg)) return;\n\n // Anything reaching here has a structural change (insert, remove, or move);\n // the pure \"same refs in same order\" case — including the no-op re-render\n // where nothing changed — is handled earlier by tryInPlaceContentUpdate,\n // which keeps every surviving node and morphs only changed rows in place.\n const { liveParent } = binding;\n const { newRecord, prevIdx, removedItems, freshIndices, freshHtmls }\n = classifyItems(binding.items, listSeg);\n\n // Compute tail anchor BEFORE removing old nodes: once an item is\n // detached, its `.nextElementSibling` is null and we lose the\n // boundary. Capturing here uses the binding's current (pre-mutation)\n // items[last].node which is still attached.\n const tailAnchor = endAnchor(binding);\n buildFreshNodes(newRecord, freshIndices, freshHtmls, liveParent);\n const focusSnap = captureFocus(liveParent);\n removeOldNodes(liveParent, removedItems);\n applyMoves(liveParent, newRecord, prevIdx, lis(prevIdx), tailAnchor);\n if (focusSnap !== null) restoreFocus(focusSnap);\n binding.items = newRecord;\n if (newRecord.length > 0) {\n devHooks.missingRowKey?.(newRecord[0].node, newRecord[0].html, binding);\n }\n}\n\n/**\n * Classify each item in the new segment against the old binding. Items with\n * a cache-hit (same ref + same html) are reused; replaced/new items get a\n * placeholder `BoundItem` whose `node` is filled in by the bulk parse below.\n */\nfunction classifyItems(oldItems: BoundItem[], listSeg: ListSegment): Classification {\n // Single Map<ref, [item, index]> instead of two Maps over the same key set\n // (KF-90). Halves the .set() calls during the build, halves the lookup\n // probe count during classification. ~1-2 ms saved per render on 1k-row\n // lists.\n const oldByRef = new Map<object, [BoundItem, number]>();\n for (let i = 0; i < oldItems.length; i++) {\n oldByRef.set(oldItems[i].ref, [oldItems[i], i]);\n }\n\n const newRecord: BoundItem[] = new Array(listSeg.items.length);\n const prevIdx = new Array<number>(listSeg.items.length);\n const removedItems: BoundItem[] = [];\n const freshIndices: number[] = [];\n const freshHtmls: string[] = [];\n\n for (let i = 0; i < listSeg.items.length; i++) {\n const ni = listSeg.items[i];\n const oi = oldByRef.get(ni.ref);\n if (oi !== undefined) {\n oldByRef.delete(ni.ref);\n if (oi[0].html === ni.html) {\n newRecord[i] = oi[0];\n prevIdx[i] = oi[1];\n continue;\n }\n // Same ref, new html → the old node is replaced. Its bound effects go\n // with it (KF-294); `removeOldNodes` disposes them.\n removedItems.push(oi[0]);\n }\n newRecord[i] = {\n // `node` placeholder is filled by `buildFreshNodes`; its parse-count\n // check guarantees every fresh index gets a real element before use.\n ref: ni.ref, cacheKey: ni.cacheKey, html: ni.html, node: null as unknown as Element,\n bindings: ni.bindings,\n };\n prevIdx[i] = -1;\n freshIndices.push(i);\n freshHtmls.push(ni.html);\n }\n\n // Whatever's left in oldByRef is an orphan ref that disappeared from the\n // new list. The caller removes those nodes alongside the replaced ones.\n for (const [, orphan] of oldByRef) removedItems.push(orphan[0]);\n\n return { newRecord, prevIdx, removedItems, freshIndices, freshHtmls };\n}\n\n/**\n * Bulk-parse every fresh row's HTML in one `innerHTML` call, then walk the\n * parsed children in order and fill in each placeholder's `node` field.\n *\n * Enforces the \"exactly one top-level element per row\" contract (KF-103):\n * if the bulk parse produces a different number of top-level elements\n * than fresh rows, fall back to per-row parsing to identify the offending\n * row and throw a precise error. The success path stays a single parse.\n */\nfunction buildFreshNodes(\n newRecord: BoundItem[],\n freshIndices: number[],\n freshHtmls: string[],\n liveParent: Element,\n): void {\n if (freshHtmls.length === 0) return;\n const { content, count } = parseRowTemplate(freshHtmls.join(''), liveParent);\n if (count !== freshHtmls.length) {\n throw findOffendingRow(newRecord, freshIndices, freshHtmls, liveParent);\n }\n // After the count check above, we know the fragment's `children.length`\n // equals `freshIndices.length`, so the walk below always finds an element\n // for every index. No defensive null-guard needed.\n let node = content.firstElementChild;\n for (const idx of freshIndices) {\n const next = (node as Element).nextElementSibling;\n const item = newRecord[idx];\n item.node = node as Element;\n // KF-294: wire this fresh row's fine-grained bindings to its new node.\n if (item.bindings !== undefined && item.bindings.length > 0) {\n item.bindingDisposers = wireRowBindings(item.node, item.bindings);\n }\n node = next;\n }\n}\n\n/**\n * Walk per-row to find the offending row that violated the contract,\n * returning a precise error to throw. Only invoked when the bulk parse\n * detected a count mismatch — the success path is one parse with no\n * per-row work.\n */\nfunction findOffendingRow(\n newRecord: BoundItem[],\n freshIndices: number[],\n freshHtmls: string[],\n liveParent: Element,\n): Error {\n for (let i = 0; i < freshHtmls.length; i++) {\n // Parse in the live parent's namespace so the per-row count matches the bulk\n // parse (KF-420) — a namespace mismatch would otherwise miss the offender.\n if (parseRowTemplate(freshHtmls[i], liveParent).count !== 1) {\n return rowContractError(freshIndices[i], newRecord[freshIndices[i]].html, liveParent);\n }\n }\n /* c8 ignore next 2 — unreachable: bulk mismatch ⇒ at least one row violates. */\n return new Error('each(): bulk-parse mismatch with no per-row offender (kerf bug).');\n}\n\n/**\n * Remove every replaced/orphan node still attached to the live parent, and\n * dispose each removed row's fine-grained binding effects (KF-294) so they\n * don't leak subscriptions to now-detached nodes.\n */\nfunction removeOldNodes(liveParent: Element, removedItems: BoundItem[]): void {\n for (const item of removedItems) {\n disposeRowBindings(item.bindingDisposers);\n if (item.node.parentElement === liveParent) liveParent.removeChild(item.node);\n }\n}\n\n/**\n * Place everything that's not in the LIS. Walks the new record in reverse so\n * each move's anchor (`nextSibling`) is already in its final position by the\n * time we reach earlier items.\n *\n * Routed through `moveNode`: a surviving-but-reordered row is already connected,\n * so it takes the state-preserving `moveBefore` path where the engine supports\n * it (focus / selection / animation survive the reorder); a brand-new row\n * (`prevIdx[i] === -1`) is still in the parse fragment (`isConnected === false`)\n * and falls back to `insertBefore` — nothing to preserve. `moveNode`'s guard\n * discriminates the two per node, so this one loop handles both.\n *\n * `tailAnchor` is the node that comes AFTER the list inside `liveParent` (or\n * `null` if the list is at the end). The reconciler computes it via\n * `endAnchor(binding)` so it picks up whatever the diff placed between the\n * list and the parent's tail — including a static text sibling or the next\n * sibling list's marker, neither of which is an element.\n */\nfunction applyMoves(\n liveParent: Element,\n newRecord: BoundItem[],\n prevIdx: number[],\n stable: ReadonlySet<number>,\n tailAnchor: Node | null,\n): void {\n let nextSibling: Node | null = tailAnchor;\n for (let i = newRecord.length - 1; i >= 0; i--) {\n const node = newRecord[i].node;\n if (prevIdx[i] === -1 || !stable.has(i)) {\n moveNode(liveParent, node, nextSibling);\n }\n nextSibling = node;\n }\n}\n\n/**\n * Patience-sort LIS: returns the *set of indices* in `arr` that participate\n * in a longest strictly-increasing subsequence. `-1` entries (representing\n * brand-new items in the new list) are ignored — they can't anchor the\n * subsequence and shouldn't count as stable.\n */\nfunction lis(arr: ReadonlyArray<number>): ReadonlySet<number> {\n const tails: number[] = [];\n const tailIdx: number[] = [];\n const prev = new Array<number>(arr.length);\n for (let i = 0; i < arr.length; i++) {\n const v = arr[i];\n if (v === -1) {\n prev[i] = -1;\n continue;\n }\n let lo = 0;\n let hi = tails.length;\n while (lo < hi) {\n const mid = (lo + hi) >> 1;\n if (tails[mid] < v) lo = mid + 1;\n else hi = mid;\n }\n prev[i] = lo > 0 ? tailIdx[lo - 1] : -1;\n tails[lo] = v;\n tailIdx[lo] = i;\n }\n const out = new Set<number>();\n let k = tailIdx.length > 0 ? tailIdx[tailIdx.length - 1] : -1;\n while (k !== -1) {\n out.add(k);\n k = prev[k];\n }\n return out;\n}\n","/**\n * Keyed list reconciler — the engine behind `each(...)` inside `mount()`.\n *\n * Public surface (re-exported via the rest of the runtime):\n * - `BoundItem` / `ListBinding`: the binding shape `mount()` keeps\n * per-list, mapping `each()` items to their live DOM nodes.\n * Defined in `list-binding.ts` and re-exported here.\n * - `endAnchor(binding)`: dynamic \"insert at end of list\" anchor.\n * Also defined in `list-binding.ts` and re-exported here.\n * - `reconcileList(binding, listSeg)`: top-level dispatch.\n *\n * Implementation lives in two sibling files:\n * - `list-reconcile-snapshot.ts` — the original keyed algorithm\n * (classify / bulk-parse / LIS / move). Used for plain-array `each()`\n * and for arraySignal-backed `each()` when the patch path can't apply\n * (first render, post-`replace()`, post-drift recovery).\n * - `list-reconcile-granular.ts` — the KF-92 patch-driven path used\n * when an `arraySignal`'s queued patches can be applied directly to\n * the existing binding without iterating the snapshot.\n *\n * The split mirrors the two-axis nature of the reconciler: snapshot-vs-\n * granular path × shared bookkeeping (binding shape, end-of-list anchor,\n * focus capture/restore). The binding shape is in its own `list-binding.ts`\n * file so the two sibling reconcilers can import it without creating a\n * circular dependency back to `list-reconcile.ts`. Internal to kerf — not\n * part of the public API.\n */\n\nexport { type BoundItem, endAnchor, type ListBinding } from './list-binding.js';\nimport type { ListBinding } from './list-binding.js';\nimport { reconcileGranular } from './list-reconcile-granular.js';\nimport { reconcileSnapshot } from './list-reconcile-snapshot.js';\nimport type { ListSegment } from './segment.js';\n\n/**\n * Reconcile `binding`'s live parent against `listSeg`. Mutates `binding.items`\n * to mirror the new segment when done.\n *\n * Dispatch — the DOM-side half of the state machine reified in\n * `list-render-state.ts` (see its transition table):\n * - **Granular (KF-92)**: an `arraySignal`-backed `each()` whose patch\n * queue is non-empty AND the binding has at least one row — i.e. the list\n * was in the `bound` state when `each()` decided the path. `each()` only\n * emits a patch segment from that state and filters `replace` patches\n * upstream, so the patches reaching here are guaranteed to be\n * update/insert/remove/move only. The non-empty-binding check is the\n * DOM-side restatement of the same `bound` precondition.\n * - **Snapshot**: every other case — first render of a list (`unbound`),\n * plain-array `each()`, empty binding (`empty`), post-`replace()`,\n * post-drift recovery. Runs the keyed classify/build/move algorithm.\n */\nexport function reconcileList(binding: ListBinding, listSeg: ListSegment): void {\n if (listSeg.patches !== undefined && binding.items.length > 0) {\n reconcileGranular(binding, listSeg.patches);\n return;\n }\n reconcileSnapshot(binding, listSeg);\n}\n","/**\n * `mount(rootEl, render)` — kerf's render primitive.\n *\n * Wraps `effect()` so that whenever any signal read inside `render()`\n * changes, we re-run `render()` and apply the minimum DOM mutations against\n * the live tree. Element identity (and thus focus, selection, in-flight\n * pointer interactions, and event listeners on preserved nodes) is preserved\n * wherever the keyed/positional diff matches.\n *\n * Two phases per render:\n *\n * - Static surrounds (everything outside `each()` lists): kerf's native\n * `morph()` reconciler walks a freshly-built template against the live\n * tree. Conventions: id/data-key matching, `data-morph-skip`, focus\n * preservation.\n *\n * - List interiors (children of every `each()` parent): native keyed\n * reconciler operates directly on the live parent's children. No\n * re-parse, no morph walk for cache-hit rows. Cost is O(changes), not\n * O(rows).\n *\n * Compared to a `replaceChildren(...rows.map(toElement))` rebuild pattern,\n * the user-visible win is that an `<input>` the user is typing into\n * survives an unrelated re-render — its DOM node, focus state, and cursor\n * position are not destroyed and recreated on each tick.\n */\n\nimport {\n _setBindingContext,\n type Binding,\n type BindingContext,\n disposeRowBindings,\n newBindingContext,\n wireBindings,\n wireRowBindings,\n} from './bindings.js';\nimport { devHooks, type WarnOnceContext } from './dev-hooks.js';\nimport { _resetCallOrderListState, _setRenderContext, type RenderContext } from './each.js';\nimport type { SafeHtml } from './jsx-runtime.js';\nimport { isSafeHtml } from './jsx-runtime.js';\nimport {\n type BoundItem,\n type ListBinding,\n reconcileList,\n} from './list-reconcile.js';\nimport { morph } from './morph.js';\nimport { effect } from './reactive.js';\nimport {\n collectLists,\n flatten,\n flattenWithoutListItems,\n LIST_MARKER_PREFIX,\n type ListSegment,\n type Segment,\n} from './segment.js';\nimport { parseRowTemplate, rowContractError } from './utils/row-contract.js';\n\n/** What `mount()`'s render function may return; non-SafeHtml values coerce (nullish/boolean → render nothing). */\nexport type MountResult = SafeHtml | string | number | boolean | null | undefined;\n\n// KF-175 — non-enumerable marker placed on `mount()`'s rootEl so that a\n// second `mount()` call on a descendant, ancestor, or the same element can be\n// detected and rejected. `Symbol.for(...)` so the marker survives multiple\n// kerfjs imports in the same realm (e.g. the dist-full test suite running a\n// rebuilt bundle against the src test infrastructure).\nconst MOUNTED_MARKER = Symbol.for('kerfjs.mounted');\n\nconst NESTED_MOUNT_MSG\n = 'mount: rootEl is already inside (or contains) a mounted tree. '\n + 'kerf supports one mount per tree — compose with plain functions that return JSX instead of nesting mounts.';\n\nfunction isMounted(el: Element): boolean {\n return (el as unknown as Record<symbol, unknown>)[MOUNTED_MARKER] === true;\n}\n\nfunction setMounted(el: Element, on: boolean): void {\n if (on) {\n (el as unknown as Record<symbol, unknown>)[MOUNTED_MARKER] = true;\n } else {\n delete (el as unknown as Record<symbol, unknown>)[MOUNTED_MARKER];\n }\n}\n\nfunction describeEl(el: HTMLElement): string {\n const tag = el.tagName.toLowerCase();\n const id = el.id ? `#${el.id}` : '';\n return `<${tag}${id}>`;\n}\n\nfunction assertNotInsideMountedTree(rootEl: HTMLElement): void {\n // The element itself — same element mounted twice.\n if (isMounted(rootEl)) {\n throw new Error(\n `mount: ${describeEl(rootEl)} is already mounted. `\n + 'Call the disposer returned by the first mount() before mounting again. '\n + 'kerf supports one mount per element — compose with plain functions that return JSX instead of nesting mounts.',\n );\n }\n // Ancestors — walk up.\n let ancestor: Element | null = rootEl.parentElement;\n while (ancestor) {\n if (isMounted(ancestor)) throw new Error(NESTED_MOUNT_MSG);\n ancestor = ancestor.parentElement;\n }\n // Descendants — DFS.\n const stack: Element[] = [];\n for (let i = 0; i < rootEl.children.length; i++) stack.push(rootEl.children[i]);\n while (stack.length > 0) {\n const cur = stack.pop() as Element;\n if (isMounted(cur)) throw new Error(NESTED_MOUNT_MSG);\n for (let i = 0; i < cur.children.length; i++) stack.push(cur.children[i]);\n }\n}\n\n/**\n * Bind `render()` to the children of `rootEl`. Re-runs whenever any signal\n * read inside `render()` changes. Returns a disposer that tears down the\n * effect; call it when the host element is removed from the DOM.\n *\n * Conventions:\n *\n * - Diff keys: `id` and `data-key` are matched across the morph by key\n * rather than positionally, so list reorders move existing nodes instead\n * of churning unrelated siblings.\n * - `data-morph-skip`: any element with this attribute is left untouched\n * inside on subsequent renders. Used for library-owned subtrees (xterm-\n * style widgets, charts, third-party editors) where the library's own\n * lifecycle manages the children.\n * - Focused text-entry inputs (`<input>` of typing kinds, `<textarea>`)\n * keep their current value + selection range across morphs while focused.\n * The user never sees their cursor jump mid-keystroke.\n * - Focused `[contenteditable]` elements have their entire subtree\n * skipped (same mechanism as `data-morph-skip`). The user's in-progress\n * edit — typed content, caret position, multi-range selections, anything\n * else they did to the DOM — survives verbatim. The next render after\n * blur catches up.\n */\nexport function mount(rootEl: HTMLElement, render: () => MountResult): () => void {\n if (rootEl == null) {\n throw new Error(\n 'mount: rootEl is null/undefined — pass the live element, e.g. mount(document.getElementById(\"app\")!, render). '\n + 'A common cause is a typo in the id or selector that returns null at runtime even though the TypeScript types say HTMLElement.',\n );\n }\n // KF-243: defense-in-depth for inert-document roots. `toElement()` already\n // adopts its output into the live document, but a consumer can hand `mount()`\n // an element built some other way — their own `DOMParser`, a detached\n // `<template>.content` child, `document.implementation.createHTMLDocument()`\n // — whose `ownerDocument` has no browsing context. `mount()`'s first-render\n // `rootEl.innerHTML = …` on such an inert-document element trips the WebKit\n // fragment-parsing bug fixed in KF-240, so adopt it into the live document\n // first. Only genuinely inert owners (`defaultView === null`) are adopted; a\n // live element in another realm (e.g. an iframe, `defaultView !== null`) is\n // left in place — `mount()` works on it as-is, and we must never yank a node\n // out of its own window.\n const owner = rootEl.ownerDocument as Document;\n if (owner !== document) {\n /* c8 ignore start -- the defaultView!==null arm needs a second live browsing context (iframe element); not constructible in the unit environment */\n if (!owner.defaultView) document.adoptNode(rootEl);\n /* c8 ignore stop */\n }\n assertNotInsideMountedTree(rootEl);\n setMounted(rootEl, true);\n // KF-174: opt-in dev MutationObserver that warns when a node carrying an\n // imperative addEventListener listener is removed/rebuilt by the morph.\n const listenerWarnObserver = devHooks.listenerRebuild?.(rootEl) ?? null;\n const bindings = new Map<string, ListBinding>();\n // Per-mount render context: the list-id counter is reset at the start of\n // each render (so the n-th `each()` call gets the same id every render);\n // the `caches` map persists across renders so unchanged items skip the\n // JSX work via cache hits even when the JSX render function is an inline\n // arrow that's a fresh function reference on every closure run (KF-87).\n const renderCtx: RenderContext = {\n counter: 0,\n caches: new Map(),\n bindingCounts: new Map(),\n bindingSources: new Map(),\n keysThisRender: new Set(),\n shiftCandidates: [],\n warnedShiftIds: new Set(),\n rebuiltLists: new Set(),\n };\n // KF-294: per-mount fine-grained binding context + live-effect disposers.\n // `bindingCtx` is reset and repopulated each render; `bindingDisposers`\n // holds the per-hole effects so they're torn down on unmount.\n const bindingCtx: BindingContext = newBindingContext();\n let bindingDisposers: ReadonlyArray<() => void> = [];\n // KF-338: the global-hole binding list that is ACTUALLY wired (bound to live\n // effects) right now. On the fast path the effects aren't re-wired, so this\n // list — captured whenever `wireBindings` runs — describes the signal\n // instances the live effects are still bound to. The stale-binding dev warn\n // compares it against this render's registered holes. Retained only when the\n // warning is opted in, so the fast path stays allocation-free when it's off.\n let prevWiredBindings: Binding[] = [];\n let isFirst = true;\n // KF-88: the static-surrounds HTML string from the previous render. If a\n // re-render produces the same string (the common case when a signal flips\n // a class on one row but the page chrome is unchanged), we skip the\n // template clone, the innerHTML re-parse, and the morph() walk entirely\n // and go straight to the per-list reconcilers. Saves ~8 ms per update-\n // path render against the krausest harness.\n let prevStaticHtml = '';\n // Per-mount one-shot context for the opt-in value-only-re-render warning.\n const valueOnlyWarnCtx: WarnOnceContext = { warned: false };\n\n /** One pass of the user's render function with both collection contexts fresh. */\n const runRenderPass = (): MountResult => {\n renderCtx.counter = 0;\n renderCtx.keysThisRender.clear();\n renderCtx.shiftCandidates.length = 0;\n bindingCtx.counter = 0;\n bindingCtx.list = [];\n _setRenderContext(renderCtx);\n _setBindingContext(bindingCtx);\n try {\n return render();\n } finally {\n _setRenderContext(null);\n _setBindingContext(null);\n }\n };\n\n /** Recover list call order, then render/morph surrounds and align bindings. */\n function renderStaticPhase(): Segment {\n let result = runRenderPass();\n\n // An unkeyed list is identified by its position among the `each()` calls,\n // so a render that changed how many of them ran may have handed some ids to\n // a different list. Only now is this render's count known — and by now the\n // damage is in `result`, because the departed list's per-item HTML memo\n // lives under the id its successor just rendered with. Two lists over one\n // source hit each other's memo exactly (same refs, same cacheKey), so the\n // surviving list emitted the other list's row markup.\n //\n // The documented cost of an identity shift is a from-scratch rebuild, not\n // wrong output, so that is what happens: drop the call-order-keyed state\n // and render again. The discarded pass costs one extra render on precisely\n // the render that was already going to rebuild — and never on a steady-state\n // one, where the count is unchanged.\n if (renderCtx.previousCallCount !== undefined\n && renderCtx.previousCallCount !== renderCtx.counter) {\n // Warn from the FIRST pass: the reset clears the recorded sources the\n // shift detection compares against, so a second pass has nothing to spot.\n for (const id of renderCtx.shiftCandidates) {\n if (renderCtx.warnedShiftIds.has(id)) continue;\n renderCtx.warnedShiftIds.add(id);\n devHooks.listIdShift?.(id);\n }\n _resetCallOrderListState(renderCtx);\n result = runRenderPass();\n }\n\n // The `MountResult` union covers `null`, `undefined`, `false`, `true`,\n // and `number` so consumers can write `() => cond ? <jsx/> : null` and\n // `() => cond && <jsx/>` without a cast. `resultToSegment` collapses\n // nullish + boolean to `''` (render nothing) and stringifies numbers.\n let segment: Segment = resultToSegment(result);\n\n if (isFirst) {\n runFirstRender(rootEl, segment, bindings);\n prevStaticHtml = flattenWithoutListItems(segment);\n // Opt-in scan for markup the HTML parser silently restructures\n // (KERF_DEV_WARN_PARSER_REPAIR). First render only: the shape is a\n // property of the markup, not of any particular update.\n devHooks.parserRepair?.(prevStaticHtml);\n bindingDisposers = wireBindings(rootEl, bindingCtx, bindingDisposers);\n if (devHooks.staleBindingEnabled?.()) prevWiredBindings = bindingCtx.list;\n isFirst = false;\n } else {\n let nextStaticHtml = runSubsequentRender(\n rootEl, segment, bindings, renderCtx, prevStaticHtml, valueOnlyWarnCtx,\n );\n\n // KF-411: the morph just rebuilt one or more lists' containers, so their\n // bindings were self-healed to empty. A list that emitted a granular\n // segment (it looked `bound` when `each()` ran, before the morph) now has\n // items:[] against an empty binding — the reconcile below would render it\n // blank, discarding rows that still live in the arraySignal. Reset those\n // lists to unbound and render again: `each()` re-emits a full snapshot,\n // and the second bind pass finds the (now valid) self-healed binding and\n // reconciles it to the real rows. Only fires on a container-rebuild\n // render — already O(N) — never in steady state.\n if (anyRebuiltListIsGranular(segment, renderCtx.rebuiltLists)) {\n for (const id of renderCtx.rebuiltLists) renderCtx.bindingCounts.delete(id);\n result = runRenderPass();\n segment = resultToSegment(result);\n nextStaticHtml = runSubsequentRender(\n rootEl, segment, bindings, renderCtx, prevStaticHtml, valueOnlyWarnCtx,\n );\n }\n // A changed static-surrounds string means morph() ran, which strips\n // bound attributes (absent from the template) and removes inserted text\n // nodes. Re-wire against the post-morph DOM. When the surrounds are\n // unchanged (KF-88 fast path — the select-row / partial-update case),\n // morph is skipped and the existing binding effects stay live, so we\n // leave them untouched.\n //\n // KF-299 staleness note: leaving the effects untouched on the fast path\n // is correct for the canonical pattern — `class={computed(() => sig.value)}`\n // re-creates the `computed` each render, but the live effect stays bound\n // to the FIRST computed, which reads the SAME underlying signal(s), so\n // later changes still fire. It goes stale only if a render switches which\n // signal INSTANCE it binds (e.g. `class={cond ? sigA : sigB}` where the\n // surrounds byte-string is unchanged) — an anti-pattern; bind one\n // `computed` that switches internally instead. Same \"bound signal must be\n // stable across renders\" constraint as row bindings (see docs 2-reactivity\n // §2.9). Re-wiring here would need fast-path text-node reuse to avoid\n // duplicating inserted text nodes, so it's not worth it for an anti-pattern.\n if (nextStaticHtml !== prevStaticHtml) {\n bindingDisposers = wireBindings(rootEl, bindingCtx, bindingDisposers);\n if (devHooks.staleBindingEnabled?.()) prevWiredBindings = bindingCtx.list;\n } else {\n // KF-338: fast path — the effects stay bound to `prevWiredBindings`.\n // Dev-warn (opt-in) if this render tried to bind a DIFFERENT signal\n // instance to a hole, which silently goes stale (the effect isn't\n // re-wired). The warner short-circuits on its env gate first.\n devHooks.staleBinding?.(prevWiredBindings, bindingCtx.list);\n }\n prevStaticHtml = nextStaticHtml;\n }\n return segment;\n }\n\n /** Reconcile every list, commit bookkeeping, then audit the final DOM. */\n function reconcileAndCommitListPhase(segment: Segment): void {\n // KF-416: per-list expected row count, for the dev-mode row-count invariant.\n // Only built when the checks are enabled — otherwise the map would cost an\n // allocation per render for nothing, and this family promises zero prod cost.\n const expectedCounts = devHooks.listInvariantsEnabled?.() ? new Map<string, number>() : null;\n\n for (const listSeg of collectLists(segment).values()) {\n // Invariant: `bindListsFromMarkers` just ran over this segment, so every\n // list id has a binding — EXCEPT when the list's marker never reached the\n // live DOM because it sits inside a `data-morph-skip` subtree the morph\n // refused to update. Guard that edge with a descriptive error instead of\n // letting `reconcileList(undefined, …)` die on a bare TypeError.\n const binding = bindings.get(listSeg.id);\n if (!binding) {\n throw new Error(\n 'mount: an each() list appeared in the render output but its marker never reached the live DOM. '\n + 'The most common cause is an each() introduced inside a data-morph-skip subtree on a re-render — '\n + 'the morph leaves that subtree untouched, so the list can never bind. '\n + 'Move the each() outside the skipped subtree, or remove data-morph-skip from its ancestor.',\n );\n }\n reconcileList(binding, listSeg);\n // KF-99: record the post-reconcile binding length so the next render's\n // granular path can detect drift (a prior render that threw mid-batch\n // leaves the binding shorter than the signal expects).\n renderCtx.bindingCounts.set(listSeg.id, binding.items.length);\n // KF-388: record WHICH list this id now holds, so the next render can\n // tell a genuine continuation from an id reused by a different list.\n renderCtx.bindingSources.set(listSeg.id, listSeg.source);\n // KF-416: a granular segment carries no items but its source (an\n // arraySignal) knows the count; a snapshot segment's `items` ARE the\n // count. Duck-typed on the granular case so mount never hard-imports\n // ArraySignal (which would pull it into the main bundle — KF-95).\n expectedCounts?.set(\n listSeg.id,\n listSeg.patches && listSeg.source\n ? (listSeg.source as { value: readonly unknown[] }).value.length\n : listSeg.items.length,\n );\n }\n renderCtx.previousCallCount = renderCtx.counter;\n\n // Opt-in structural audit of every list binding against the live DOM\n // (KERF_DEV_INVARIANTS). Placed after the reconcile loop so it sees the\n // render's final state; a no-op, with no DOM walking at all, when unset.\n devHooks.listInvariants?.(rootEl, bindings, expectedCounts || undefined);\n }\n\n const disposeEffect = effect(() => {\n reconcileAndCommitListPhase(renderStaticPhase());\n });\n\n return () => {\n disposeEffect();\n for (const d of bindingDisposers) d();\n bindingDisposers = [];\n // KF-294: tear down every list row's fine-grained binding effects too.\n for (const b of bindings.values()) {\n for (const item of b.items) disposeRowBindings(item.bindingDisposers);\n }\n listenerWarnObserver?.disconnect();\n // Clear the mounted marker so `mount(sameEl, ...)` after dispose works.\n setMounted(rootEl, false);\n };\n}\n\n/**\n * First render of a mount: bulk-flatten the segment (items inlined, markers\n * around each list) into `rootEl.innerHTML`, then walk the markers to\n * register a `ListBinding` per list. The subsequent `reconcileList` pass is\n * a no-op (every row's a cache hit on the just-bound items).\n */\nfunction runFirstRender(\n rootEl: HTMLElement,\n segment: Segment,\n bindings: Map<string, ListBinding>,\n): void {\n rootEl.innerHTML = flatten(segment, true);\n bindListsFromMarkers(rootEl, segment, bindings, true);\n}\n\n/**\n * Subsequent render of a mount. Returns the new `prevStaticHtml` so the\n * caller can carry it forward.\n *\n * Two paths:\n *\n * - **KF-88 fast path**: when the static-surrounds string didn't change\n * byte-for-byte, `bindListsFromMarkers` has nothing to discover and the\n * diff would short-circuit on `isEqualNode` for every element it visited —\n * but the visit itself isn't free. Skip both to save ~8 ms per partial-\n * update / select-row / swap-rows render against the krausest harness.\n *\n * Trade-off (KF-117, documented in `docs/4-render.md` §4.4.2): any\n * attribute or child set imperatively on a kerf-managed element (e.g.\n * `el.setAttribute(...)`) survives across no-op re-renders because the\n * diff doesn't run to wipe it. When the surrounds DO change, the diff\n * runs and `morphAttributes` removes anything the JSX didn't authorise.\n * This matches the framework's \"smallest cut\" model: don't touch what\n * JSX didn't change.\n *\n * - **Surrounds-changed path**: clean up orphan bindings (lists that\n * disappeared from this render's segment), build a template from the\n * static-only HTML, run `morph()` over the surrounds with the\n * list-owned items as `ownedItems` (KF-102 round 2 — the morph skips\n * owned items individually but still walks every parent so non-list\n * siblings around an each() reconcile correctly), then bind any\n * newly-appearing lists.\n */\nfunction runSubsequentRender(\n rootEl: HTMLElement,\n segment: Segment,\n bindings: Map<string, ListBinding>,\n renderCtx: RenderContext,\n prevStaticHtml: string,\n valueOnlyWarnCtx: WarnOnceContext,\n): string {\n // KF-411: reflects only this bind pass. Cleared here — before the fast-path\n // early return — so the surrounds-unchanged path leaves it empty (no morph,\n // no bind, no self-heal to record) rather than carrying a stale set forward.\n renderCtx.rebuiltLists.clear();\n const currentStaticHtml = flattenWithoutListItems(segment);\n if (currentStaticHtml === prevStaticHtml) {\n return prevStaticHtml;\n }\n // Opt-in dev diagnostic (KERF_DEV_WARN_VALUE_ONLY_RERENDER=1): if this\n // changed render is confined to text/attribute values, every changed hole\n // could have been a fine-grained binding — surface the bound-first guidance\n // once per mount. Gate short-circuits before any parsing.\n devHooks.valueOnlyRerender?.(prevStaticHtml, currentStaticHtml, valueOnlyWarnCtx);\n cleanupOrphanBindings(segment, bindings, renderCtx);\n const template = rootEl.cloneNode(false) as HTMLElement;\n template.innerHTML = currentStaticHtml;\n morph(rootEl, template, collectOwnedItems(bindings));\n bindListsFromMarkers(rootEl, segment, bindings, false, renderCtx.rebuiltLists);\n return currentStaticHtml;\n}\n\n/**\n * Coerce a non-`SafeHtml` render result to a safe HTML string. Nullish\n * values and booleans become `''` (render nothing) — matches the React /\n * Solid convention so `{cond ? <jsx/> : null}` and `{cond && <jsx/>}`\n * patterns work without each consumer adding a sentinel. Everything else\n * is stringified (numbers → `\"42\"`, strings pass through).\n */\nfunction coerceRenderResult(result: unknown): string {\n if (result == null || typeof result === 'boolean') return '';\n return String(result);\n}\n\n/**\n * A render result → the `Segment` the pipeline consumes. `SafeHtml` carries its\n * structured segment (or a plain `__html` for a cross-bundle shim); everything\n * else is coerced to a static-html segment.\n */\nfunction resultToSegment(result: MountResult): Segment {\n return isSafeHtml(result)\n ? (result.__segment ?? { kind: 'static', html: result.__html })\n : { kind: 'static', html: coerceRenderResult(result) };\n}\n\n/**\n * KF-411: did the morph rebuild a list's container whose `each()` emitted a\n * GRANULAR segment this render? Such a segment carries `items: []`, so the\n * freshly self-healed (empty) binding would reconcile the live rows to zero.\n * `mount()` re-renders those lists onto the snapshot path when this is true.\n */\nfunction anyRebuiltListIsGranular(segment: Segment, rebuilt: ReadonlySet<string>): boolean {\n if (!rebuilt.size) return false;\n const lists = collectLists(segment);\n for (const id of rebuilt) {\n if (lists.get(id)?.patches) return true;\n }\n return false;\n}\n\n/**\n * Walk the live tree's comment nodes; every `<!--kf-list:{id}-->` marker\n * is the start anchor of a list inside `liveParent`. Bind the list (parent +\n * already-rendered item nodes between the marker and the tail). The marker\n * stays in the live DOM (KF-102 round 2): keeping it as a permanent\n * comment-node anchor lets the static-surrounds diff insert/remove/morph\n * non-list siblings around the list without needing to re-establish the\n * list's begin position.\n *\n * `inlinedItems` distinguishes the first-render path (where `flatten(seg,\n * true)` inlines item HTML right after the marker, so the marker's element\n * siblings *are* the list rows) from subsequent renders that newly\n * introduce a list (where `flattenWithoutListItems` emits only the marker\n * and the list reconciler populates items afterwards).\n *\n * Existing bindings whose marker is still in the DOM are left intact —\n * `bindings.has(id)` skips re-binding so the prior render's item nodes\n * survive across static-surrounds diffs.\n */\nfunction bindListsFromMarkers(\n rootEl: Element,\n segment: Segment,\n bindings: Map<string, ListBinding>,\n inlinedItems: boolean,\n rebuiltLists?: Set<string>,\n): void {\n const lists = collectLists(segment);\n const found: Comment[] = [];\n collectComments(rootEl, found);\n for (const marker of found) {\n if (!marker.data.startsWith(LIST_MARKER_PREFIX)) continue;\n const id = marker.data.slice(LIST_MARKER_PREFIX.length);\n const existing = bindings.get(id);\n if (existing) {\n // Existing binding survives the diff — the prior render's item nodes stay\n // bound — but only when this id is still carried by the SAME marker node.\n //\n // Identity of the node, not merely \"a marker with this id is somewhere in\n // the tree\": a call-order id can be handed to a different list when the\n // number of unkeyed `each()` calls changes, and the departed list's own\n // marker is typically still live under its new id. Accepting that binding\n // would point the arriving list at the previous occupant's parent and\n // anchor, so its rows land inside the wrong container.\n if (existing.marker === marker && rootEl.contains(existing.marker)) continue;\n // KF-377 self-heal: the marker we found is a fresh clone — the list's\n // container was rebuilt by the morph (e.g. an ancestor's tag changed,\n // so replaceChild swapped the whole subtree). The old binding points at\n // a detached tree; keeping it would make every future reconcile mutate\n // that detached parent, permanently rendering zero rows. Drop it\n // (disposing the dead rows' fine-grained binding effects) and fall\n // through to re-bind against the live marker, so the next reconcile\n // repopulates the list from scratch.\n for (const item of existing.items) {\n disposeRowBindings(item.bindingDisposers);\n // KF-381: the morph can separate the marker comment from its owned\n // rows while leaving those rows attached to the LIVE tree — a\n // conditional sibling that shifted the marker (rows stranded next to\n // the clone), or a same-tag sibling that positionally hijacked the\n // container (rows stranded inside it). Those survivors aren't removed\n // by the trailing pass (owned items are protected), so the reconcile\n // that repopulates the re-bound list would render a SECOND copy beside\n // them. Remove any still-live row here so recovery replaces rather than\n // duplicates. Rows already gone with a replaced subtree (the ancestor-\n // tag-swap case) fail the containment check and are left untouched.\n if (rootEl.contains(item.node)) {\n item.node.parentElement?.removeChild(item.node);\n }\n }\n bindings.delete(id);\n // KF-411: record the rebuild so `mount()` can re-render if this list\n // emitted a granular segment (which carries no items and would otherwise\n // reconcile the fresh empty binding straight back to zero rows).\n rebuiltLists?.add(id);\n // Opt-in dev warning (KERF_DEV_WARN_LIST_REBIND=1): the recovery is\n // correct but lossy — row DOM state is discarded — so surface it.\n devHooks.listRebind?.(id, marker.parentElement as Element);\n }\n const listSeg = lists.get(id) as ListSegment;\n const liveParent = marker.parentElement as Element;\n const items: BoundItem[] = [];\n if (inlinedItems) {\n // KF-103: enforce the \"exactly one top-level element per row\" contract\n // on first render too. Without this check, a multi-root row inlined\n // via `flatten(seg, true)` would silently misalign the binding (each\n // bound item.node points at only the first of a row's 2+ elements,\n // and the leftover elements are picked up as \"next\" rows). The check\n // is per-row so we can pinpoint the offender by index.\n let next: Element | null = marker.nextElementSibling;\n for (let i = 0; i < listSeg.items.length && next !== null; i++) {\n validateInlinedRowMatch(listSeg.items[i].html, i, next, liveParent);\n const rowBindings = listSeg.items[i].bindings;\n const bound: BoundItem = {\n ref: listSeg.items[i].ref,\n cacheKey: listSeg.items[i].cacheKey,\n html: listSeg.items[i].html,\n node: next,\n bindings: rowBindings,\n };\n // KF-294: wire this inlined first-render row's fine-grained bindings.\n if (rowBindings?.length) {\n bound.bindingDisposers = wireRowBindings(next, rowBindings);\n }\n items.push(bound);\n next = next.nextElementSibling;\n }\n }\n const binding: ListBinding = { liveParent, items, marker };\n // KF-173: dev-only one-shot warning if the first row has no id/data-key.\n if (items.length > 0) {\n devHooks.missingRowKey?.(items[0].node, items[0].html, binding);\n }\n // Dev-mode: warn when an each() list is inside a data-morph-skip subtree\n // (list rows still update; static reactive siblings are frozen).\n devHooks.eachInMorphSkip?.(id, liveParent, rootEl);\n bindings.set(id, binding);\n }\n}\n\n/**\n * KF-103: validate that `expectedHtml` (one row's render output) matches\n * the live `boundEl`'s `outerHTML` — confirming the row produced exactly\n * one top-level element. If they differ, parse the row in isolation and\n * throw a precise error mentioning the row index and the actual count.\n *\n * Fast path: outerHTML compare is a string equality check (zero allocs in\n * happy-dom; one alloc in V8). Only when they DON'T match (multi-root or\n * subtle browser-normalized single-root case) do we fall back to a full\n * per-row parse for the precise count.\n */\nfunction validateInlinedRowMatch(\n expectedHtml: string,\n index: number,\n boundEl: Element,\n liveParent: Element,\n): void {\n if (boundEl.outerHTML === expectedHtml) return;\n // The bound element's outerHTML differs from what we emitted. Parse the\n // expected html in isolation; if it's still single-root the difference\n // is whitespace / browser-normalization (e.g. `<br/>` → `<br>`) and\n // we proceed silently. Otherwise build the precise contract-violation\n // error from the shared helper.\n // KF-396: parse in the LIVE PARENT's namespace. Without it an SVG row\n // (`<circle/>`) parses HTML and comes back `tagName === 'CIRCLE'` while the\n // live element is a real SVG `circle` — and the tag comparison below, being\n // case-sensitive, then rejected a perfectly good list. The everyday trigger\n // was an apostrophe in any attribute (kerf emits `'`, serializers emit\n // `'`), which is what makes the outerHTML compare miss and reach here at all.\n const { content, count } = parseRowTemplate(expectedHtml, liveParent);\n if (count !== 1) throw rowContractError(index, expectedHtml, liveParent);\n // KF-391: single-root, but is it the SAME root? The HTML parser restructures\n // some markup — most commonly `<tr>` directly under `<table>`, where it\n // inserts an implicit `<tbody>` around the whole row run. The binding walk\n // then takes that wrapper as row 0 and never finds the real rows, the\n // reconcile re-inserts them outside the wrapper (visible duplicates), and\n // the missing-row-key warning fires falsely against the wrapper. Comparing\n // tags catches it: this is the same \"the parse can't line up one row per\n // element\" class the row contract exists to reject, so reject it loudly\n // rather than binding to the wrong node.\n const expectedTag = (content.firstElementChild as Element).tagName;\n if (boundEl.tagName !== expectedTag) throw rowStructureError(index, boundEl.tagName, expectedTag);\n}\n\n/**\n * KF-391: the author's row markup parsed into a different element than the row\n * itself, because the HTML parser restructured it. Names both tags and points\n * at the fix — the shape kerf supports (and that the benchmark entry uses) is\n * an explicit sectioning element around the list.\n */\nfunction rowStructureError(index: number, gotTag: string, wantTag: string): Error {\n const got = gotTag.toLowerCase();\n const want = wantTag.toLowerCase();\n return new Error(\n `each(): row ${index} renders <${want}>, but the HTML parser wrapped the rows in `\n + `<${got}> — so kerf cannot bind one row per element. This happens when an each() of `\n + `<${want}> sits directly inside a table: the parser inserts <${got}> around the whole run. `\n + `Put the each() inside an explicit <${got}> (e.g. <table><${got}>{each(...)}</${got}></table>) `\n + 'so the rows are the direct children kerf binds.',\n );\n}\n\n/**\n * Build the set of element nodes owned by `each()` list reconcilers, the\n * union of every binding's `items[].node`. The static-surrounds diff\n * skips these so list rows are invisible to the parent walk while\n * sibling reconciliation continues normally (KF-102 round 2).\n */\nfunction collectOwnedItems(bindings: Map<string, ListBinding>): Set<Element> {\n const owned = new Set<Element>();\n for (const b of bindings.values()) {\n for (const item of b.items) owned.add(item.node);\n }\n return owned;\n}\n\n/**\n * Remove items + binding entries for any list that's no longer present in\n * the new segment. The diff's trailing-removal pass would have removed the\n * marker (since the new template no longer emits one for this id), but\n * items are owned and stay protected from removal — so we drop them\n * explicitly here before the diff runs.\n */\nfunction cleanupOrphanBindings(\n segment: Segment,\n bindings: Map<string, ListBinding>,\n renderCtx: RenderContext,\n): void {\n const liveIds = collectLists(segment);\n for (const [id, binding] of bindings) {\n if (liveIds.has(id)) continue;\n for (const item of binding.items) {\n // KF-294: dispose the removed list's row binding effects.\n disposeRowBindings(item.bindingDisposers);\n item.node.remove();\n }\n binding.marker.remove();\n bindings.delete(id);\n renderCtx.bindingCounts.delete(id);\n renderCtx.bindingSources.delete(id);\n renderCtx.caches.delete(id);\n }\n}\n\n/**\n * Recursive collector for comment nodes — happy-dom's `TreeWalker` doesn't\n * surface `Node.COMMENT_NODE` despite accepting `NodeFilter.SHOW_COMMENT`,\n * so we walk children directly. Cheap (O(elements)) and portable.\n */\nfunction collectComments(node: Node, out: Comment[]): void {\n for (let c: Node | null = node.firstChild; c; c = c.nextSibling) {\n if (c.nodeType === Node.COMMENT_NODE) out.push(c as Comment);\n else if (c.nodeType === Node.ELEMENT_NODE) collectComments(c, out);\n }\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { devHooks } from './chunk-
|
|
1
|
+
import { devHooks } from './chunk-HW7KSM2Y.js';
|
|
2
2
|
import { Signal, signal as signal$1, effect as effect$1 } from '@preact/signals-core';
|
|
3
3
|
export { batch, computed } from '@preact/signals-core';
|
|
4
4
|
|
|
@@ -16,5 +16,5 @@ function effect(fn) {
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
export { effect, isSignal, signal };
|
|
19
|
-
|
|
20
|
-
//# sourceMappingURL=chunk-
|
|
19
|
+
|
|
20
|
+
//# sourceMappingURL=chunk-U6FK33SG.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/reactive.ts"],"names":["coreSignal","coreEffect"],"mappings":";;;;AA0CO,SAAS,SAAS,KAAA,EAA0C;AACjE,EAAA,OAAO,KAAA,YAAiB,MAAA;AAC1B;AAEO,SAAS,OAAU,KAAA,EAAsB;AAC9C,EAAA,MAAM,UAAU,QAAA,CAAS,aAAA;AACzB,EAAA,IAAI,OAAA,EAAS,OAAO,OAAA,CAAW,KAAU,CAAA;AACzC,EAAA,OAAOA,SAAW,KAAU,CAAA;AAC9B;AAEO,SAAS,OAAO,EAAA,EAA2C;AAChE,EAAA,MAAM,OAAO,QAAA,CAAS,UAAA;AACtB,EAAA,OAAOC,QAAA,CAAW,IAAA,GAAO,IAAA,CAAK,EAAE,IAAI,EAAE,CAAA;AACxC","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../src/reactive.ts"],"names":["coreSignal","coreEffect"],"mappings":";;;;AA0CO,SAAS,SAAS,KAAA,EAA0C;AACjE,EAAA,OAAO,KAAA,YAAiB,MAAA;AAC1B;AAEO,SAAS,OAAU,KAAA,EAAsB;AAC9C,EAAA,MAAM,UAAU,QAAA,CAAS,aAAA;AACzB,EAAA,IAAI,OAAA,EAAS,OAAO,OAAA,CAAW,KAAU,CAAA;AACzC,EAAA,OAAOA,SAAW,KAAU,CAAA;AAC9B;AAEO,SAAS,OAAO,EAAA,EAA2C;AAChE,EAAA,MAAM,OAAO,QAAA,CAAS,UAAA;AACtB,EAAA,OAAOC,QAAA,CAAW,IAAA,GAAO,IAAA,CAAK,EAAE,IAAI,EAAE,CAAA;AACxC","file":"chunk-U6FK33SG.js","sourcesContent":["/**\n * Re-exports of `@preact/signals-core`. Lets the rest of the codebase depend\n * on `'./reactive.js'` without naming the underlying lib, so swapping it out\n * later (or fronting it with a hand-rolled implementation) is a one-file\n * change.\n *\n * Two dev hook slots sit in front of the bare re-exports:\n *\n * - `signalFactory` replaces the constructor so writes to never-subscribed\n * signals can warn (`KERF_DEV_WARN_UNTRACKED_SIGNALS=1`).\n *\n * - `wrapEffect` wraps the user body so `delegate()` can detect that it's\n * running inside an effect (`KERF_DEV_WARN_DELEGATE_IN_EFFECT=1`).\n *\n * Both are `undefined` unless the consumer imported `kerfjs/dev`, so production\n * sees the bare `@preact/signals-core` exports behind one property read.\n *\n * ORDERING: `signalFactory` is resolved at signal-CREATION time, so signals\n * created before `kerfjs/dev` is installed stay plain and the untracked-signal\n * warning never sees them. Static imports hoist above a `await import()`, so a\n * module-scope signal in an imported module is created first. See\n * docs/11-dev-warnings.md for the install-ordering rules.\n */\n\nimport { effect as coreEffect,Signal,signal as coreSignal } from '@preact/signals-core';\n\nimport { devHooks } from './dev-hooks.js';\n\nexport {\n batch,\n computed,\n type ReadonlySignal,\n Signal,\n} from '@preact/signals-core';\n\n/**\n * Runtime type guard for a `@preact/signals-core` signal (both `signal()`\n * values and `computed()` values are `Signal` instances). Used by the JSX\n * runtime (KF-294) to detect a signal handed straight into an attribute or\n * text hole — the trigger for a fine-grained binding rather than a snapshot\n * stringify.\n */\nexport function isSignal(value: unknown): value is Signal<unknown> {\n return value instanceof Signal;\n}\n\nexport function signal<T>(value?: T): Signal<T> {\n const factory = devHooks.signalFactory;\n if (factory) return factory<T>(value as T);\n return coreSignal(value as T);\n}\n\nexport function effect(fn: () => void | (() => void)): () => void {\n const wrap = devHooks.wrapEffect;\n return coreEffect(wrap ? wrap(fn) : fn);\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// src/
|
|
1
|
+
// src/attr.ts
|
|
2
2
|
function cssEscapeIdent(value) {
|
|
3
3
|
if (value === "") {
|
|
4
4
|
throw new Error("attr: attribute name must not be empty");
|
|
@@ -70,5 +70,5 @@ function attr(name, value) {
|
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
export { attr };
|
|
73
|
-
|
|
74
|
-
//# sourceMappingURL=chunk-
|
|
73
|
+
|
|
74
|
+
//# sourceMappingURL=chunk-UZJ6I4T6.js.map
|