Preserve complete rows when realtime events race refetches - #129
Conversation
|
Follow-up pushed in Approach:
The regression matrix now runs created, patched, and removed races against both explicit refetch and Verification: |
|
Implemented the revised approach in
Regression coverage verifies that neither built-in ID-only nor adapter-classified invalidations ever publish or cache incomplete entities. Full project verification passes: typecheck, lint, formatting, and all 366 tests. |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Want higher recall? High effort reviews run extra passes and find more bugs. A team admin can switch effort levels in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 31f4222. Configure here.
| force: request.force, | ||
| ...(request.causes ? { causes: request.causes } : {}), | ||
| }) | ||
| } |
There was a problem hiding this comment.
Invalidations reuse stale local cache
Medium Severity
ID-only invalidations keep the previous complete entity in cache, then ask reconciliation.request to refresh. That path still allows local answers: #prepareReconcile can reselect a materialized find from the unchanged table, and a follow-up get fetch can return via #tryLocalGet. When a snapshot or already-evicted .all() left service.materialized set, nothing hits the server and live queries keep publishing pre-invalidation rows.
Additional Locations (2)
Reviewed by Cursor Bugbot for commit 31f4222. Configure here.
Risk: medium. Dismissed the prior approval because Cursor Bugbot completed as skipped on the current head, so that approval is stale. Human review is needed.
|
Thermo-nuclear follow-up applied in
Verification remains clean: typecheck, lint, formatting, coverage, and all 366 tests pass. |
|
After release:
In short: complete realtime payloads remain useful data; incomplete notifications trigger safe refetches without corrupting the cache. |




A partial realtime notification arriving during a
realtime: 'refetch'request could replace a complete server response row with an ID-only cached record. Consumers then rendered incomplete data; in Humaans this caused the task decoder to throw when performance-cycle tasks arrived.Refetch queries now retain their fetched values and treat realtime notifications as invalidations during response rebasing and replay. The trailing reconciliation still runs, while mutation acknowledgements and optimistic overlays keep their existing handling.
Extended the existing fetch-race test to cover partial create, patch, and remove notifications. The reproduction failed before the fix. All 365 tests, type checking, lint, formatting, and the packaged ESM/CommonJS/declaration checks pass.