fix: 修复深度 review 确认的 4 个正确性/契约 bug - #11
Draft
sskyy wants to merge 4 commits into
Draft
Conversation
…exes data0's RxList.splice delegates to native Array.prototype.splice (which accepts negative and out-of-range start), but forwards the raw argv in the trigger info. RxListHost used argv[0] as-is, so findAnchor(negative) read hosts[-1], crashed, and the new row was silently degraded to an empty row (data and scene graph diverge); pop()/shift() on an empty list surfaced a framework-internal error. Normalize start against the pre-splice host count with native splice semantics before anchoring. Co-authored-by: Zhenyu Hou <skyking_H@hotmail.com>
renderSource only routed source() evaluation errors to the root error hook;
errors thrown while rendering the returned structure (invalid child, unknown
tag, rethrowing component, ...) escaped as uncaught microtask exceptions and
leaked one placeholder plus a half-rendered subtree per retry.
Reuse the RxListHost row-recovery pattern: destroy the partial host's
bindings (parentHandle mode), remove every node inserted into the
(boundary, placeholder) interval, keep the effect alive so the region can
recover, then dispatch to root.on('error') or rethrow when no hook exists.
Co-authored-by: Zhenyu Hou <skyking_H@hotmail.com>
distanceTo returned -1 for entries no longer in the spatial index, but the unmount queue drains by descending distance, so deleted entries sorted to the back and lingered as ghost rows behind far-away survivors during budget draining - the opposite of the documented priority. Treat missing bounds as infinitely far so they unmount first. Co-authored-by: Zhenyu Hou <skyking_H@hotmail.com>
If the anchor was missing from parent.children, indexOf returned -1 and leafer's add(child, -1) spliced the node into the second-to-last slot - silent misplacement that lets bookkeeping corruption spread. Fail loudly instead. Co-authored-by: Zhenyu Hou <skyking_H@hotmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
深度 review 中逐一复现确认的 4 个 bug 的修复,每个修复都有定向测试锚定(254 → 266 个测试,全绿)。
1.
RxListHost:负索引 / 越界 splice 导致数据与画面静默分叉data0 的
RxList.splice委托原生Array.prototype.splice(支持负start与越界start),但 patch 里的argv是未归一化的原始参数。handleSplice原样使用argv[0]:splice(-1, 0, x)→findAnchor(-1)访问hosts[-1]抛 TypeError,被行级回滚吞掉降级为空行——数据里有该项、画布不渲染,只有一条 console.error;pop()/shift()会向root.on('error')派发一次框架内部错误(本应是 no-op)。修复:按原生 splice 语义、基于 splice 前的
hosts.length归一化start。2.
FunctionHost:结构路径渲染错误逃逸错误契约并泄漏场景图节点renderSource只捕获了source()求值的抛错;返回结构的渲染抛错(非法 child、未知标签、无钩子时组件 rethrow 等)完全没有防护:DeferredBindingEffect的微任务里逃逸成未捕获异常,root.on('error')收不到;innerPlaceholder已插入但this.innerHost未赋值,每次依赖触发重试都泄漏一个占位符和一棵半渲染子树(含未清理的 effect / 事件绑定)。修复:复用
RxListHost.recoverFailedRow的模式——清理半渲染 host 的绑定(parentHandle 模式)、回滚(boundary, placeholder)区间内已插入的节点、保持 effect 活跃(依赖恢复后该区域可重新渲染),再报告给 root error 钩子(无钩子时保持向上抛出,且抛出前已回滚干净)。3.
rxWindowedList:已删除条目最后才被卸载(优先级反转)distanceTo对已不在空间索引里的条目返回-1,而卸载队列按距离降序消化——已删除条目被排到队尾,预算排队期间以"幽灵行"形态滞留在存活条目之后,与注释宣称的"排到队首优先卸载"正好相反。修复:缺失 bounds 视为无穷远。4.
insertBefore:锚点丢失时静默错位锚点不在
parent.children里时indexOf返回 -1,leafer 的add(child, -1)被splice(-1, 0)解释为"插到倒数第二位"——簿记失配会静默扩散。修复:加 assert 响亮失败。测试
test/rx-list.test.tsx:新增 splice 归一化 describe(负索引插入/删除/替换、双向越界 clamp、空列表 pop/shift 为静默 no-op);test/function-host.test.tsx:新增结构路径错误的回滚/上报/恢复/反复失败不泄漏、无钩子时回滚后向上抛、回滚不误伤相邻 sibling 三个用例;test/rx-windowed-list.test.ts:新增"索引删除的条目最先卸载"用例;test/leafer-bridge.test.ts:新增锚点不在父级 children 时响亮失败的用例。npm run check(typecheck + lint + 266 tests + build)全绿。