feat: add Value.Diff granular prop payloads for commitUpdate
Value.Diff produces property-level diff payloads instead of relying solely on prepareUpdate. Function-valued props are stripped before diffing; ValueDiffError is caught and falls back to prepareUpdate. Value.Equal and Value.Clone now safely handle function-valued props with try-catch fallbacks.
This commit is contained in:
@@ -137,32 +137,32 @@ describe("Value.Hash O(1) change detection", () => {
|
||||
});
|
||||
|
||||
describe("hash mismatch falls through to Value.Equal / reconciliation", () => {
|
||||
it("hash mismatch with changed prop triggers prepareUpdate", () => {
|
||||
const { host, prepareUpdateCalls } = makeTrackingHost();
|
||||
it("hash mismatch with changed prop triggers commitUpdate", () => {
|
||||
const { host, commitUpdateCalls } = makeTrackingHost();
|
||||
const root = createHostRoot(host, {});
|
||||
root.render(h("div", { color: "red" }));
|
||||
|
||||
commitHashes(root.rootFiber!);
|
||||
|
||||
prepareUpdateCalls.length = 0;
|
||||
commitUpdateCalls.length = 0;
|
||||
|
||||
root.render(h("div", { color: "blue" }));
|
||||
|
||||
expect(prepareUpdateCalls.length).toBeGreaterThanOrEqual(1);
|
||||
expect(commitUpdateCalls.length).toBeGreaterThanOrEqual(1);
|
||||
});
|
||||
|
||||
it("hash mismatch for child triggers prepareUpdate for child only", () => {
|
||||
const { host, prepareUpdateCalls } = makeTrackingHost();
|
||||
it("hash mismatch for child triggers commitUpdate for child only", () => {
|
||||
const { host, commitUpdateCalls } = makeTrackingHost();
|
||||
const root = createHostRoot(host, {});
|
||||
root.render(h("div", { color: "red" }, h("span", { label: "a" })));
|
||||
|
||||
commitHashes(root.rootFiber!);
|
||||
|
||||
prepareUpdateCalls.length = 0;
|
||||
commitUpdateCalls.length = 0;
|
||||
|
||||
root.render(h("div", { color: "red" }, h("span", { label: "b" })));
|
||||
|
||||
const spanCalls = prepareUpdateCalls.filter((c) => c.tag === "span");
|
||||
const spanCalls = commitUpdateCalls.filter((c) => c.tag === "span");
|
||||
expect(spanCalls.length).toBe(1);
|
||||
expect(spanCalls[0]!.prevProps.label).toBe("a");
|
||||
expect(spanCalls[0]!.nextProps.label).toBe("b");
|
||||
@@ -171,7 +171,7 @@ describe("Value.Hash O(1) change detection", () => {
|
||||
|
||||
describe("hash is computed outside reactive computations", () => {
|
||||
it("Value.Hash is never called from within a computed or effect callback", async () => {
|
||||
const { host, prepareUpdateCalls, commitUpdateCalls } = makeTrackingHost();
|
||||
const { host, commitUpdateCalls } = makeTrackingHost();
|
||||
const s = signal("red");
|
||||
|
||||
const root = createHostRoot(host, {});
|
||||
@@ -187,7 +187,6 @@ describe("Value.Hash O(1) change detection", () => {
|
||||
{},
|
||||
);
|
||||
|
||||
prepareUpdateCalls.length = 0;
|
||||
commitUpdateCalls.length = 0;
|
||||
|
||||
s.value = "blue";
|
||||
@@ -196,13 +195,12 @@ describe("Value.Hash O(1) change detection", () => {
|
||||
queueMicrotask(() => resolve());
|
||||
});
|
||||
|
||||
expect(prepareUpdateCalls.length).toBeGreaterThanOrEqual(1);
|
||||
expect(commitUpdateCalls.length).toBeGreaterThanOrEqual(1);
|
||||
expect(divFiber.props.color).toBe("blue");
|
||||
|
||||
const newHash = divFiber.hash;
|
||||
expect(newHash).not.toBeNull();
|
||||
|
||||
prepareUpdateCalls.length = 0;
|
||||
commitUpdateCalls.length = 0;
|
||||
|
||||
s.value = "blue";
|
||||
@@ -211,7 +209,6 @@ describe("Value.Hash O(1) change detection", () => {
|
||||
queueMicrotask(() => resolve());
|
||||
});
|
||||
|
||||
expect(prepareUpdateCalls.length).toBe(0);
|
||||
expect(commitUpdateCalls.length).toBe(0);
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user