fix: resolve async completion in ConditionalBindingHandler#376
fix: resolve async completion in ConditionalBindingHandler#376phillipc wants to merge 1 commit intoknockout:mainfrom
Conversation
Two bugs in ConditionalBindingHandler caused async binding promises to misbehave: 1. Non-rendering branches (if: false, ifnot: true, with: null) never called completeBinding(), leaving the AsyncBindingHandler promise permanently unresolved. 2. renderAndApplyBindings awaited applyBindingsToDescendants() directly, but that function returns a BindingResult synchronously — not a Promise. The await resolved immediately without waiting for async descendants. Fix mirrors DescendantBindingHandler: use bindingResult.completionPromise when !isSync, and short-circuit with this.bindingCompletion = bound for the sync case. Regression tests added for if: false, ifnot: true, with: null (unresolved promise), and if: true with async descendants (premature completion).
|
Warning Rate limit exceeded
To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (6)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Review rate limit: 0/1 reviews remaining, refill in 21 minutes and 2 seconds.Comment |
Adversarial reviewFix is faithful to the canonical Worth verifying while here:
Out of scope (notes for the record):
LGTM modulo the optional else-chain test. |
Summary
Fixes two bugs in
ConditionalBindingHandleridentified in typescript-code-review-findings-5.md (Critical Finding 1).Non-rendering branches never resolved:
if: false,ifnot: true, andwith: nullall hit the empty-branch path inrender()without callingcompleteBinding(), leaving theAsyncBindingHandlerpromise permanently unresolved. Anyawait applyBindings(...)would hang indefinitely.Premature completion with async descendants:
renderAndApplyBindingsusedawait applyBindingsToDescendants(...), but that function returns aBindingResultsynchronously — not a Promise. Theawaitresolved immediately without waiting for async child bindings to finish. Fix follows theDescendantBindingHandlerpattern: call withoutawait, usebound.completionPromisewhen!bound.isSync, and short-circuitthis.bindingCompletion = boundfor the sync case so the binding isn't unnecessarily tracked as async.Test plan
bun run buildpassesbunx vitest run packages/binding.if— new regression tests forif: false,ifnot: true,with: nullcompletionbunx vitest run packages/bind/spec/bindingCompletionPromiseBehavior.ts— new test forif: truewith async descendantsbunx vitest run— full suite (290 files, no regressions)