Merge feat/value-hash-detection: add Value.Hash O(1) change detection with commitHashes (clean merge, no Value.Diff overlap)

This commit is contained in:
2026-05-18 17:40:13 +00:00
parent 6d704f59e0
commit 27c1f2671b
4 changed files with 36 additions and 50 deletions

View File

@@ -88,33 +88,33 @@ describe("Value.Equal bail-out", () => {
});
});
describe("changed prop still triggers prepareUpdate", () => {
it("changed prop on parent triggers prepareUpdate", () => {
const { host, prepareUpdateCalls } = makeTrackingHost();
describe("changed prop still triggers update", () => {
it("changed prop on parent triggers commitUpdate", () => {
const { host, commitUpdateCalls } = makeTrackingHost();
const root = createHostRoot(host, {});
root.render(h("div", { color: "red" }));
prepareUpdateCalls.length = 0;
commitUpdateCalls.length = 0;
root.render(h("div", { color: "blue" }));
expect(prepareUpdateCalls.length).toBeGreaterThanOrEqual(1);
const divCall = prepareUpdateCalls.find((c) => c.tag === "div");
expect(commitUpdateCalls.length).toBeGreaterThanOrEqual(1);
const divCall = commitUpdateCalls.find((c) => c.tag === "div");
expect(divCall).toBeDefined();
expect(divCall!.prevProps.color).toBe("red");
expect(divCall!.nextProps.color).toBe("blue");
});
it("changed child prop triggers prepareUpdate only for child", () => {
const { host, prepareUpdateCalls } = makeTrackingHost();
it("changed child prop triggers commitUpdate only for child", () => {
const { host, commitUpdateCalls } = makeTrackingHost();
const root = createHostRoot(host, {});
root.render(h("div", { color: "red" }, h("span", { label: "a" })));
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");
@@ -214,17 +214,17 @@ describe("Value.Equal bail-out", () => {
expect(divFiber.effect).toBeNull();
});
it("reconcileProps with changed node calls prepareUpdate", () => {
const { host, prepareUpdateCalls } = makeTrackingHost();
it("reconcileProps with changed node produces an update effect", () => {
const { host } = makeTrackingHost();
const root = createHostRoot(host, {});
root.render(h("div", { color: "red" }));
const divFiber = root.rootFiber!.children[0]!;
prepareUpdateCalls.length = 0;
reconcileProps(divFiber, h("div", { color: "blue" }), host as HostConfig<string, string, unknown>, {});
expect(prepareUpdateCalls.length).toBe(1);
expect(divFiber.effect).not.toBeNull();
expect(divFiber.props.color).toBe("blue");
});
});