mirror of
https://github.com/morluto/rea
synced 2026-10-27 14:42:18 -04:00
fix(javascript): bound member-mutation paths through reassignment loops
Fixes #1401. Refs #1065. Preserve exact member facts and equal-depth write effects while bounding the observed reassignment-loop expansion. Validated with the JavaScript semantic/application suite, focused alias regressions, full static checks, real compiled CLI and SDK MCP Notion workflows, and all 20 checks on the final PR head. Co-Authored-By: Marnix Pluim <286664873+marnixpluim@users.noreply.github.com> Co-Authored-By: N0zoM1z0 <161784452+N0zoM1z0@users.noreply.github.com> Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -211,12 +211,17 @@ const evaluateBinding = (
|
||||
if (isPrimitive(captured)) value = captured;
|
||||
}
|
||||
}
|
||||
const mutated = binding.mutatedPaths.reduce(
|
||||
invalidateSemanticMutationPath,
|
||||
value,
|
||||
);
|
||||
const projected = binding.escapedPaths.reduce(
|
||||
(value, escape) =>
|
||||
let projected = value;
|
||||
for (const path of binding.mutatedPaths) {
|
||||
projected = invalidateSemanticMutationPath(projected, path);
|
||||
// Every subsequent write returns this same root unknown. Replaying those
|
||||
// paths at every newly collected effect otherwise becomes quadratic.
|
||||
if (projected.status === "unknown") break;
|
||||
}
|
||||
for (const escape of binding.escapedPaths) {
|
||||
// Escapes only invalidate object references; other lattice values survive.
|
||||
if (projected.status !== "object" && projected.status !== "array") break;
|
||||
if (
|
||||
context.capturePoint !== undefined &&
|
||||
semanticEscapeFollowsCapture(
|
||||
binding,
|
||||
@@ -224,10 +229,10 @@ const evaluateBinding = (
|
||||
escape.node,
|
||||
context.state.parentsByNode,
|
||||
)
|
||||
? value
|
||||
: invalidateSemanticEscapedPath(value, escape.path),
|
||||
mutated,
|
||||
);
|
||||
)
|
||||
continue;
|
||||
projected = invalidateSemanticEscapedPath(projected, escape.path);
|
||||
}
|
||||
// Point-local memoization also bounds failed speculative captures. Only a
|
||||
// primitive result is allowed back into ordinary value evaluation.
|
||||
if (
|
||||
|
||||
Reference in New Issue
Block a user