Files
ujsx/tasks/lis-move-detection.md
glm-5.1 c9c32a6aa6 decompose reconciler roadmap into 20 implementation tasks across 5 phases
Tasks follow the architecture spec phases:
- Phase 0: key field on UElement (2 tasks + review)
- Phase 1: reactive-host bridge / fiber tree (4 tasks + review)
- Phase 2: key-based children reconciliation (3 tasks + review)
- Phase 3: unmount & dispose support (4 tasks)
- Phase 4: TypeBox value optimizations (4 tasks)

Validated with taskgraph CLI: no cycles, 15 parallel generations,
3 high-risk tasks identified (signal-driven-updates, commit-mutations,
fiber-disposal).
2026-05-18 16:26:52 +00:00

51 lines
2.2 KiB
Markdown

---
id: lis-move-detection
name: LIS-based move detection for children
status: pending
depends_on: [key-matching-algorithm]
created: 2026-05-18T16:22:57.231648316Z
modified: 2026-05-18T16:22:57.231648758Z
scope: narrow
risk: medium
impact: component
level: implementation
---
# Description
Implement the Longest Increasing Subsequence (LIS) algorithm to determine which matched children need to be moved. When the order of keyed children changes between renders, the LIS identifies the largest subset of children that are already in the correct relative order. Only children NOT in the LIS need to be moved via `insertBefore`.
The LIS approach minimizes the number of DOM (or host) operations: instead of removing and re-inserting every child, only the out-of-order children are moved.
Algorithm:
1. Get the old indices for each matched child in the new order
2. Compute LIS of those indices
3. Children whose old index IS in the LIS → stay in place
4. Children whose old index is NOT in the LIS → flag as "move" effects
Open question from reconciler.md: should there be a minimum threshold (e.g., < 5 items) below which positional matching is used instead? This task should document the decision but can start with LIS for all sizes.
## Acceptance Criteria
- [ ] `longestIncreasingSubsequence` function implemented (pure function)
- [ ] Returns the set of indices that form the longest increasing subsequence
- [ ] LIS used in `reconcileChildren` to classify matched children as "stay" vs "move"
- [ ] Children in LIS → no effect needed (staying in place)
- [ ] Children NOT in LIS → flagged with `effect: { type: "move", before }`
- [ ] New test: LIS of [0, 1, 2] → all stay (already ordered)
- [ ] New test: LIS of [2, 0, 1] → index 0 stays, indices 2 and 1 move
- [ ] New test: reversed list [3, 2, 1, 0] → LIS = [0], three moves
- [ ] New test: adding child at start doesn't move existing ones (LIS covers all old)
## References
- docs/architecture/reconciler.md — Step 3 (Reconcile Children), LIS move detection
- docs/architecture/reconciler.md — Open Question 4 (minimum LIS threshold)
## Notes
> To be filled by implementation agent
## Summary
> To be filled on completion